16 KiB
16 KiB
MonacoUSA Portal Design System V2
Professional Neumorphic & Glassmorphic Design Language
Table of Contents
- Design Philosophy
- Color System
- Typography
- Spacing & Layout
- Shadow System
- Component Library
- Morphing Dropdown Specification
- Animation Guidelines
- Responsive Design
- Implementation Examples
Design Philosophy
Core Principles
- Professional & Inviting: Balancing corporate credibility with approachable design
- Neumorphic Foundation: Soft UI with subtle depth and tactile feedback
- Glassmorphic Accents: Strategic use of transparency and blur for interactive elements
- Monaco Heritage: Incorporating national colors while maintaining modern aesthetics
Visual Hierarchy
- Primary Actions: Monaco Red gradient buttons with strong shadows
- Interactive Elements: Blue glassmorphic dropdowns and selects
- Content Cards: Neumorphic white/light gray surfaces
- Navigation: Subtle depth with hover transformations
Color System
Primary Palette - Monaco Red
$primary-50: #FEF2F2; // Lightest tint
$primary-100: #FEE2E2;
$primary-200: #FECACA;
$primary-300: #FCA5A5;
$primary-400: #F87171;
$primary-500: #EF4444;
$primary-600: #CC0000; // Monaco Red (Main)
$primary-700: #990000; // Monaco Dark Red
$primary-800: #660000;
$primary-900: #450A0A; // Darkest shade
Secondary Palette - Interactive Blue
Used exclusively for dropdowns, selects, and interactive overlays:
$blue-50: #EFF6FF;
$blue-100: #DBEAFE;
$blue-200: #BFDBFE;
$blue-300: #93C5FD;
$blue-400: #60A5FA;
$blue-500: #3B82F6;
$blue-600: #2563EB;
$blue-700: #1D4ED8;
$blue-800: #1E40AF;
$blue-900: #1E3A8A;
Neutral Palette
$neutral-50: #F9FAFB;
$neutral-100: #F3F4F6;
$neutral-200: #E5E7EB;
$neutral-300: #D1D5DB;
$neutral-400: #9CA3AF;
$neutral-500: #6B7280;
$neutral-600: #4B5563;
$neutral-700: #374151;
$neutral-800: #1F2937;
$neutral-900: #111827;
Semantic Colors
$success: #10B981; // Green
$warning: #F59E0B; // Amber
$error: #EF4444; // Red
$info: #3B82F6; // Blue
Typography
Font Stack
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Inter', Roboto,
'Helvetica Neue', Arial, sans-serif;
Type Scale
| Name | Size | Line Height | Usage |
|---|---|---|---|
text-xs |
0.75rem (12px) | 1.5 | Labels, captions |
text-sm |
0.875rem (14px) | 1.5 | Body small, form labels |
text-base |
1rem (16px) | 1.5 | Body default |
text-lg |
1.125rem (18px) | 1.625 | Body large |
text-xl |
1.25rem (20px) | 1.625 | H4 |
text-2xl |
1.5rem (24px) | 1.375 | H3 |
text-3xl |
1.875rem (30px) | 1.375 | H2 |
text-4xl |
2.25rem (36px) | 1.25 | H1 |
Font Weights
font-normal: 400 - Body textfont-medium: 500 - Emphasisfont-semibold: 600 - Subheadingsfont-bold: 700 - Headings
Spacing & Layout
Spacing Scale
$space-0: 0;
$space-1: 0.25rem; // 4px
$space-2: 0.5rem; // 8px
$space-3: 0.75rem; // 12px
$space-4: 1rem; // 16px
$space-5: 1.25rem; // 20px
$space-6: 1.5rem; // 24px
$space-8: 2rem; // 32px
$space-10: 2.5rem; // 40px
$space-12: 3rem; // 48px
$space-16: 4rem; // 64px
$space-20: 5rem; // 80px
Border Radius
$radius-sm: 0.375rem; // 6px - Small elements
$radius-md: 0.5rem; // 8px - Buttons
$radius-lg: 0.75rem; // 12px - Cards, dropdowns
$radius-xl: 1rem; // 16px - Large cards
$radius-2xl: 1.5rem; // 24px - Hero sections
$radius-full: 9999px; // Pills, avatars
Shadow System
Neumorphic Shadows
For cards and static elements:
// Soft elevation shadows
$shadow-soft-sm:
4px 4px 8px rgba(0, 0, 0, 0.08),
-4px -4px 8px rgba(255, 255, 255, 0.95);
$shadow-soft-md:
8px 8px 16px rgba(0, 0, 0, 0.1),
-8px -8px 16px rgba(255, 255, 255, 0.95);
$shadow-soft-lg:
12px 12px 24px rgba(0, 0, 0, 0.12),
-12px -12px 24px rgba(255, 255, 255, 0.95);
// Inset shadows for pressed states
$shadow-inset-sm:
inset 4px 4px 8px rgba(0, 0, 0, 0.1),
inset -4px -4px 8px rgba(255, 255, 255, 0.95);
Glassmorphic Shadows
For dropdowns and overlays:
$shadow-morphing:
0 10px 40px rgba(0, 0, 0, 0.12),
0 2px 10px rgba(0, 0, 0, 0.08);
$shadow-glass:
0 8px 32px rgba(0, 0, 0, 0.1),
0 0 0 1px rgba(255, 255, 255, 0.3);
Component Library
1. Buttons
Primary Button
.btn-primary {
background: linear-gradient(135deg, $primary-600, $primary-700);
color: white;
padding: 0.75rem 1.5rem;
border-radius: $radius-lg;
box-shadow:
4px 4px 8px rgba(204, 0, 0, 0.3),
-4px -4px 8px rgba(255, 255, 255, 0.95);
&:hover {
transform: translateY(-2px);
box-shadow:
6px 6px 12px rgba(204, 0, 0, 0.4),
-6px -6px 12px rgba(255, 255, 255, 0.95);
}
&:active {
transform: translateY(0);
box-shadow: $shadow-inset-sm;
}
}
Neumorphic Button
.btn-neumorphic {
background: linear-gradient(145deg, #ffffff, #f0f0f0);
color: $neutral-700;
padding: 0.75rem 1.5rem;
border-radius: $radius-lg;
box-shadow: $shadow-soft-sm;
&:hover {
box-shadow: $shadow-soft-md;
transform: translateY(-1px);
}
}
2. Cards
Neumorphic Card
.card-neumorphic {
background: linear-gradient(145deg, #ffffff, #f0f0f0);
border-radius: $radius-xl;
padding: $space-6;
box-shadow: $shadow-soft-md;
&:hover {
transform: translateY(-4px);
box-shadow: $shadow-soft-lg;
}
}
3. Form Inputs
Neumorphic Input
.input-neumorphic {
background: $neutral-50;
border: none;
border-radius: $radius-lg;
padding: $space-3 $space-4;
box-shadow: $shadow-inset-sm;
&:focus {
outline: none;
box-shadow:
$shadow-inset-md,
0 0 0 3px rgba($primary-500, 0.1);
}
}
Morphing Dropdown Specification
Overview
The morphing dropdown is a signature component that combines glassmorphism with smooth spring animations. It features a blue color scheme distinct from the primary Monaco red, creating clear visual hierarchy for interactive elements.
Visual Characteristics
Trigger State
.morphing-select-trigger {
// Base styling
height: 48px;
padding: 0 1rem;
border-radius: 12px;
// Glassmorphic background
background: rgba(239, 246, 255, 0.3); // blue-50 with 30% opacity
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
border: 1px solid rgba(191, 219, 254, 0.3); // blue-200 with 30% opacity
// Typography
color: #1E3A8A; // blue-900
font-size: 0.875rem;
// Transition
transition: all 0.3s ease;
&:hover {
background: rgba(219, 234, 254, 0.4); // blue-100 with 40% opacity
border-color: rgba(147, 197, 253, 0.4); // blue-300 with 40% opacity
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.1);
}
&.open {
background: rgba(219, 234, 254, 0.5);
border-color: rgba(96, 165, 250, 0.5); // blue-400 with 50% opacity
box-shadow:
0 0 0 3px rgba(59, 130, 246, 0.1),
0 4px 12px rgba(59, 130, 246, 0.15);
}
}
Dropdown Panel
.morphing-select-dropdown {
// Glassmorphic container
background: rgba(239, 246, 255, 0.95); // blue-50 with 95% opacity
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border: 1px solid rgba(191, 219, 254, 0.3);
border-radius: 12px;
// Shadow
box-shadow:
0 10px 40px rgba(0, 0, 0, 0.12),
0 2px 10px rgba(0, 0, 0, 0.08);
// Animation
animation: morphIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
// Layout
max-height: 300px;
overflow: hidden;
}
Option Items
.morphing-select-option {
padding: 0.625rem 0.75rem;
border-radius: 8px;
color: #1E3A8A; // blue-900
font-size: 0.875rem;
transition: all 0.2s ease;
&:hover {
background: rgba(96, 165, 250, 0.2); // blue-400 with 20% opacity
transform: translateX(2px);
}
&.selected {
background: rgba(59, 130, 246, 0.25); // blue-500 with 25% opacity
font-weight: 500;
}
}
Option Groups
.morphing-select-optgroup-label {
padding: 0.5rem 0.75rem 0.25rem;
font-size: 0.75rem;
font-weight: 600;
color: #1D4ED8; // blue-700
text-transform: uppercase;
letter-spacing: 0.05em;
opacity: 0.8;
}
Animation Specifications
Spring Configuration
const TRANSITION = {
type: 'spring',
bounce: 0.05, // Minimal bounce for professional feel
duration: 0.3, // Quick but smooth
};
Animation States
// Opening animation
@keyframes morphIn {
from {
opacity: 0;
transform: scale(0.95) translateY(-10px);
}
to {
opacity: 1;
transform: scale(1) translateY(0);
}
}
// Closing animation (reversed)
@keyframes morphOut {
from {
opacity: 1;
transform: scale(1) translateY(0);
}
to {
opacity: 0;
transform: scale(0.95) translateY(-10px);
}
}
Interaction Patterns
Click Outside
- Clicking anywhere outside the dropdown closes it
- Uses
mousedownevent for immediate response
Keyboard Navigation
Escapekey closes the dropdownTabkey navigates through optionsEnterselects the focused optionSpacetoggles selection in multi-select
Touch Support
- Touch events are handled identically to mouse events
- Larger touch targets on mobile (min 44px)
Multi-Select Variant
Selected Tags
.morphing-select-tag {
display: inline-flex;
align-items: center;
gap: 0.25rem;
padding: 0.25rem 0.5rem;
background: rgba(191, 219, 254, 0.6); // blue-200 with 60% opacity
border-radius: 6px;
font-size: 0.75rem;
// Remove button
.tag-remove {
color: #1D4ED8; // blue-700
cursor: pointer;
&:hover {
color: #1E3A8A; // blue-900
}
}
}
Accessibility Features
- ARIA attributes:
aria-expanded,aria-controls,aria-modal - Role attributes:
role="dialog"for dropdown panel - Keyboard navigation support
- Focus management
- Screen reader announcements
Implementation Guidelines
Vue/React Component Structure
interface SelectOption {
value: string;
label: string;
disabled?: boolean;
}
interface OptionGroup {
label: string;
options: SelectOption[];
}
interface SelectProps {
options?: SelectOption[];
optgroups?: OptionGroup[];
value?: string | string[]; // string[] for multi-select
onValueChange?: (value: string | string[]) => void;
placeholder?: string;
disabled?: boolean;
maxSelected?: number; // For multi-select
className?: string;
}
State Management
// Single Select
const [selectedValue, setSelectedValue] = useState('');
const [isOpen, setIsOpen] = useState(false);
// Multi-Select
const [selectedValues, setSelectedValues] = useState([]);
const [isOpen, setIsOpen] = useState(false);
Animation Guidelines
Timing Functions
$ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);
$ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
$ease-out: cubic-bezier(0, 0, 0.2, 1);
$ease-in-out: cubic-bezier(0.4, 0, 0.6, 1);
Duration Scale
fast: 150ms - Micro interactionsbase: 300ms - Standard transitionsslow: 500ms - Complex animationsslower: 700ms - Page transitions
Animation Principles
- Purpose: Every animation should have a clear purpose
- Performance: Use
transformandopacityfor GPU acceleration - Consistency: Maintain consistent timing across similar interactions
- Subtlety: Animations should enhance, not distract
Responsive Design
Breakpoints
$breakpoint-sm: 640px; // Mobile landscape
$breakpoint-md: 768px; // Tablet portrait
$breakpoint-lg: 1024px; // Tablet landscape
$breakpoint-xl: 1280px; // Desktop
$breakpoint-2xl: 1536px; // Large desktop
Mobile Adaptations
Morphing Dropdown
- Full-width on mobile
- Bottom sheet presentation option
- Larger touch targets (min 44px)
- Reduced blur for performance
Navigation
- Hamburger menu below tablet
- Full-screen overlay navigation
- Swipe gestures for sidebar
Cards
- Single column layout on mobile
- Reduced padding and margins
- Simplified shadows for performance
Implementation Examples
Example 1: Login Form with Morphing Select
<div class="login-form">
<!-- Email Input (Neumorphic) -->
<div class="form-group">
<label class="form-label">Email</label>
<input type="email" class="input-neumorphic" placeholder="you@example.com">
</div>
<!-- Role Selector (Morphing Dropdown) -->
<div class="form-group">
<label class="form-label">Select Role</label>
<div class="morphing-select">
<div class="morphing-select-trigger">
<span>Choose your role...</span>
<svg class="chevron">...</svg>
</div>
<div class="morphing-select-dropdown">
<div class="morphing-select-option">Member</div>
<div class="morphing-select-option">Admin</div>
<div class="morphing-select-option">Board Member</div>
</div>
</div>
</div>
<!-- Submit Button (Primary) -->
<button class="btn-primary">Sign In</button>
</div>
Example 2: Dashboard Stats with Dropdown Filter
<div class="dashboard-header">
<h1 class="page-title">Dashboard</h1>
<!-- Time Period Filter (Morphing Dropdown) -->
<div class="morphing-select">
<div class="morphing-select-trigger">
<span>Last 30 Days</span>
<svg class="chevron">...</svg>
</div>
<div class="morphing-select-dropdown">
<div class="morphing-select-optgroup">
<div class="morphing-select-optgroup-label">Quick Ranges</div>
<div class="morphing-select-option">Today</div>
<div class="morphing-select-option">Last 7 Days</div>
<div class="morphing-select-option selected">Last 30 Days</div>
</div>
<div class="morphing-select-optgroup">
<div class="morphing-select-optgroup-label">Custom</div>
<div class="morphing-select-option">Last Quarter</div>
<div class="morphing-select-option">Last Year</div>
</div>
</div>
</div>
</div>
<!-- Stats Cards (Neumorphic) -->
<div class="stats-grid">
<div class="card-neumorphic stat-card">
<div class="stat-value">2,847</div>
<div class="stat-label">Total Members</div>
<div class="stat-change positive">+12.5%</div>
</div>
<!-- More cards... -->
</div>
Design Tokens
For implementation in code, use these design tokens:
const designTokens = {
colors: {
primary: {
50: '#FEF2F2',
100: '#FEE2E2',
200: '#FECACA',
300: '#FCA5A5',
400: '#F87171',
500: '#EF4444',
600: '#CC0000', // Main brand color
700: '#990000',
800: '#660000',
900: '#450A0A',
},
blue: {
50: '#EFF6FF',
100: '#DBEAFE',
200: '#BFDBFE',
300: '#93C5FD',
400: '#60A5FA',
500: '#3B82F6',
600: '#2563EB',
700: '#1D4ED8',
800: '#1E40AF',
900: '#1E3A8A',
},
// ... other colors
},
shadows: {
'soft-sm': '4px 4px 8px rgba(0, 0, 0, 0.08), -4px -4px 8px rgba(255, 255, 255, 0.95)',
'soft-md': '8px 8px 16px rgba(0, 0, 0, 0.1), -8px -8px 16px rgba(255, 255, 255, 0.95)',
'soft-lg': '12px 12px 24px rgba(0, 0, 0, 0.12), -12px -12px 24px rgba(255, 255, 255, 0.95)',
'morphing': '0 10px 40px rgba(0, 0, 0, 0.12), 0 2px 10px rgba(0, 0, 0, 0.08)',
},
animation: {
duration: {
fast: '150ms',
base: '300ms',
slow: '500ms',
},
ease: {
smooth: 'cubic-bezier(0.4, 0, 0.2, 1)',
bounce: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
},
},
};
Version History
- v2.0.0 - Initial release with Neumorphic & Glassmorphic design system
- v2.0.1 - Added morphing dropdown specifications
- v2.0.2 - Enhanced mobile responsive guidelines
Contact
For questions about implementing this design system, please contact the MonacoUSA Portal development team.