1136 lines
22 KiB
Markdown
1136 lines
22 KiB
Markdown
# MonacoUSA Portal Design System v2.0
|
|
|
|
## Overview
|
|
The MonacoUSA Portal design system represents a premium, modern approach to web application interfaces, combining cutting-edge UI patterns with sophisticated animations and interactions. This system prioritizes beauty, functionality, and user engagement through carefully crafted visual experiences.
|
|
|
|
## Design Philosophy
|
|
|
|
### Core Principles
|
|
|
|
#### 1. **Visual Elegance**
|
|
- Premium aesthetics that reflect Monaco's luxury and sophistication
|
|
- Beautiful, engaging interfaces that delight users
|
|
- Attention to detail in every interaction
|
|
|
|
#### 2. **Motion & Life**
|
|
- Smooth, purposeful animations that guide user attention
|
|
- Micro-interactions that provide feedback and enhance usability
|
|
- Transitions that create seamless navigation experiences
|
|
|
|
#### 3. **Modern Architecture**
|
|
- Bento grid layouts for flexible content organization
|
|
- Component-based design for consistency and maintainability
|
|
- Responsive patterns that adapt beautifully across devices
|
|
|
|
#### 4. **Interactive Engagement**
|
|
- Customizable interfaces that users can personalize
|
|
- Draggable and reorderable components
|
|
- Real-time updates with smooth animations
|
|
|
|
## 🎨 Visual Identity
|
|
|
|
### Brand Colors
|
|
|
|
#### Primary Palette
|
|
```scss
|
|
// Monaco Red Spectrum
|
|
$monaco-red-50: #fef2f2;
|
|
$monaco-red-100: #fee2e2;
|
|
$monaco-red-200: #fecaca;
|
|
$monaco-red-300: #fca5a5;
|
|
$monaco-red-400: #f87171;
|
|
$monaco-red-500: #ef4444;
|
|
$monaco-red-600: #dc2626; // Primary Brand Color
|
|
$monaco-red-700: #b91c1c;
|
|
$monaco-red-800: #991b1b;
|
|
$monaco-red-900: #7f1d1d;
|
|
|
|
// Neutral Palette
|
|
$gray-50: #fafafa;
|
|
$gray-100: #f4f4f5;
|
|
$gray-200: #e4e4e7;
|
|
$gray-300: #d4d4d8;
|
|
$gray-400: #a1a1aa;
|
|
$gray-500: #71717a;
|
|
$gray-600: #52525b;
|
|
$gray-700: #3f3f46;
|
|
$gray-800: #27272a;
|
|
$gray-900: #18181b;
|
|
```
|
|
|
|
#### Gradient Definitions
|
|
```scss
|
|
// Primary Gradients
|
|
$gradient-monaco: linear-gradient(135deg, #dc2626 0%, #b91c1c 100%);
|
|
$gradient-monaco-light: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
|
|
$gradient-monaco-dark: linear-gradient(135deg, #b91c1c 0%, #991b1b 100%);
|
|
|
|
// Accent Gradients
|
|
$gradient-sunset: linear-gradient(135deg, #dc2626 0%, #f59e0b 100%);
|
|
$gradient-wine: linear-gradient(135deg, #991b1b 0%, #4c1d95 100%);
|
|
$gradient-royal: linear-gradient(135deg, #dc2626 0%, #1e40af 100%);
|
|
|
|
// Glass Gradients
|
|
$gradient-glass-light: linear-gradient(135deg, rgba(255,255,255,0.8) 0%, rgba(255,255,255,0.4) 100%);
|
|
$gradient-glass-dark: linear-gradient(135deg, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0.4) 100%);
|
|
```
|
|
|
|
### Typography
|
|
|
|
#### Font Stack
|
|
```scss
|
|
// Primary Font Family
|
|
$font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
|
|
// Monospace Font Family
|
|
$font-mono: 'Fira Code', 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', monospace;
|
|
|
|
// Display Font (for headers)
|
|
$font-display: 'Poppins', $font-sans;
|
|
```
|
|
|
|
#### Type Scale
|
|
```scss
|
|
// Font Sizes
|
|
$text-xs: 0.75rem; // 12px
|
|
$text-sm: 0.875rem; // 14px
|
|
$text-base: 1rem; // 16px
|
|
$text-lg: 1.125rem; // 18px
|
|
$text-xl: 1.25rem; // 20px
|
|
$text-2xl: 1.5rem; // 24px
|
|
$text-3xl: 1.875rem; // 30px
|
|
$text-4xl: 2.25rem; // 36px
|
|
$text-5xl: 3rem; // 48px
|
|
$text-6xl: 3.75rem; // 60px
|
|
$text-7xl: 4.5rem; // 72px
|
|
|
|
// Line Heights
|
|
$leading-none: 1;
|
|
$leading-tight: 1.25;
|
|
$leading-snug: 1.375;
|
|
$leading-normal: 1.5;
|
|
$leading-relaxed: 1.625;
|
|
$leading-loose: 2;
|
|
|
|
// Font Weights
|
|
$font-thin: 100;
|
|
$font-light: 300;
|
|
$font-normal: 400;
|
|
$font-medium: 500;
|
|
$font-semibold: 600;
|
|
$font-bold: 700;
|
|
$font-extrabold: 800;
|
|
$font-black: 900;
|
|
```
|
|
|
|
### Spacing System
|
|
|
|
```scss
|
|
// Based on 4px grid
|
|
$space-0: 0; // 0px
|
|
$space-px: 1px; // 1px
|
|
$space-0_5: 0.125rem; // 2px
|
|
$space-1: 0.25rem; // 4px
|
|
$space-1_5: 0.375rem; // 6px
|
|
$space-2: 0.5rem; // 8px
|
|
$space-2_5: 0.625rem; // 10px
|
|
$space-3: 0.75rem; // 12px
|
|
$space-3_5: 0.875rem; // 14px
|
|
$space-4: 1rem; // 16px
|
|
$space-5: 1.25rem; // 20px
|
|
$space-6: 1.5rem; // 24px
|
|
$space-7: 1.75rem; // 28px
|
|
$space-8: 2rem; // 32px
|
|
$space-9: 2.25rem; // 36px
|
|
$space-10: 2.5rem; // 40px
|
|
$space-12: 3rem; // 48px
|
|
$space-14: 3.5rem; // 56px
|
|
$space-16: 4rem; // 64px
|
|
$space-20: 5rem; // 80px
|
|
$space-24: 6rem; // 96px
|
|
$space-28: 7rem; // 112px
|
|
$space-32: 8rem; // 128px
|
|
```
|
|
|
|
### Border Radius
|
|
|
|
```scss
|
|
$radius-none: 0;
|
|
$radius-sm: 0.125rem; // 2px
|
|
$radius-base: 0.25rem; // 4px
|
|
$radius-md: 0.375rem; // 6px
|
|
$radius-lg: 0.5rem; // 8px
|
|
$radius-xl: 0.75rem; // 12px
|
|
$radius-2xl: 1rem; // 16px
|
|
$radius-3xl: 1.5rem; // 24px
|
|
$radius-full: 9999px; // Pill shape
|
|
```
|
|
|
|
### Shadows
|
|
|
|
```scss
|
|
// Elevation Shadows
|
|
$shadow-xs: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
$shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1);
|
|
$shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
|
|
$shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
|
|
$shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
|
|
$shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
|
|
|
// Glass Shadows
|
|
$shadow-glass: 0 8px 32px rgba(0, 0, 0, 0.1);
|
|
$shadow-glass-hover: 0 12px 40px rgba(0, 0, 0, 0.15);
|
|
|
|
// Monaco Brand Shadows
|
|
$shadow-monaco: 0 10px 40px rgba(220, 38, 38, 0.15);
|
|
$shadow-monaco-intense: 0 20px 60px rgba(220, 38, 38, 0.25);
|
|
```
|
|
|
|
## 🎯 Component Patterns
|
|
|
|
### Glass Morphism
|
|
|
|
```scss
|
|
@mixin glass-effect($bg-opacity: 0.7, $blur: 20px) {
|
|
background: rgba(255, 255, 255, $bg-opacity);
|
|
backdrop-filter: blur($blur);
|
|
-webkit-backdrop-filter: blur($blur);
|
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
box-shadow: $shadow-glass;
|
|
}
|
|
|
|
@mixin glass-dark($bg-opacity: 0.7, $blur: 20px) {
|
|
background: rgba(0, 0, 0, $bg-opacity);
|
|
backdrop-filter: blur($blur);
|
|
-webkit-backdrop-filter: blur($blur);
|
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
box-shadow: $shadow-glass;
|
|
}
|
|
|
|
@mixin glass-colored($color: $monaco-red-600, $opacity: 0.1, $blur: 20px) {
|
|
background: rgba($color, $opacity);
|
|
backdrop-filter: blur($blur);
|
|
-webkit-backdrop-filter: blur($blur);
|
|
border: 1px solid rgba($color, 0.2);
|
|
box-shadow: 0 8px 32px rgba($color, 0.1);
|
|
}
|
|
```
|
|
|
|
### Animation Patterns
|
|
|
|
```scss
|
|
// Timing Functions
|
|
$ease-in-out-smooth: cubic-bezier(0.4, 0, 0.2, 1);
|
|
$ease-out-back: cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
$ease-in-out-elastic: cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
|
|
|
// Duration Scale
|
|
$duration-instant: 0ms;
|
|
$duration-fast: 150ms;
|
|
$duration-base: 300ms;
|
|
$duration-slow: 500ms;
|
|
$duration-slower: 700ms;
|
|
$duration-slowest: 1000ms;
|
|
|
|
// Animation Mixins
|
|
@mixin hover-lift($distance: -2px, $duration: $duration-base) {
|
|
transition: transform $duration $ease-in-out-smooth;
|
|
|
|
&:hover {
|
|
transform: translateY($distance);
|
|
}
|
|
}
|
|
|
|
@mixin hover-scale($scale: 1.05, $duration: $duration-base) {
|
|
transition: transform $duration $ease-in-out-smooth;
|
|
|
|
&:hover {
|
|
transform: scale($scale);
|
|
}
|
|
}
|
|
|
|
@mixin pulse-animation($scale: 1.05, $duration: 2s) {
|
|
animation: pulse $duration infinite;
|
|
|
|
@keyframes pulse {
|
|
0%, 100% {
|
|
transform: scale(1);
|
|
opacity: 1;
|
|
}
|
|
50% {
|
|
transform: scale($scale);
|
|
opacity: 0.8;
|
|
}
|
|
}
|
|
}
|
|
|
|
@mixin float-animation($distance: 10px, $duration: 3s) {
|
|
animation: float $duration ease-in-out infinite;
|
|
|
|
@keyframes float {
|
|
0%, 100% {
|
|
transform: translateY(0);
|
|
}
|
|
50% {
|
|
transform: translateY(-$distance);
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Button Variants
|
|
|
|
```scss
|
|
// Base Button
|
|
@mixin button-base {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: $space-2_5 $space-5;
|
|
font-weight: $font-medium;
|
|
font-size: $text-sm;
|
|
line-height: $leading-tight;
|
|
border-radius: $radius-xl;
|
|
transition: all $duration-base $ease-in-out-smooth;
|
|
cursor: pointer;
|
|
user-select: none;
|
|
|
|
&:disabled {
|
|
opacity: 0.5;
|
|
cursor: not-allowed;
|
|
}
|
|
}
|
|
|
|
// Primary Button
|
|
@mixin button-primary {
|
|
@include button-base;
|
|
background: $gradient-monaco;
|
|
color: white;
|
|
border: none;
|
|
box-shadow: $shadow-md;
|
|
|
|
&:hover:not(:disabled) {
|
|
box-shadow: $shadow-monaco;
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
&:active:not(:disabled) {
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
// Glass Button
|
|
@mixin button-glass {
|
|
@include button-base;
|
|
@include glass-effect(0.8, 10px);
|
|
color: $monaco-red-600;
|
|
|
|
&:hover:not(:disabled) {
|
|
background: rgba(255, 255, 255, 0.9);
|
|
box-shadow: $shadow-glass-hover;
|
|
transform: translateY(-1px);
|
|
}
|
|
}
|
|
|
|
// Ghost Button
|
|
@mixin button-ghost {
|
|
@include button-base;
|
|
background: transparent;
|
|
color: $monaco-red-600;
|
|
border: 2px solid $monaco-red-600;
|
|
|
|
&:hover:not(:disabled) {
|
|
background: rgba($monaco-red-600, 0.1);
|
|
border-color: $monaco-red-700;
|
|
}
|
|
}
|
|
```
|
|
|
|
### Card Patterns
|
|
|
|
```scss
|
|
// Base Card
|
|
@mixin card-base {
|
|
border-radius: $radius-2xl;
|
|
padding: $space-6;
|
|
transition: all $duration-base $ease-in-out-smooth;
|
|
}
|
|
|
|
// Glass Card
|
|
@mixin card-glass {
|
|
@include card-base;
|
|
@include glass-effect;
|
|
|
|
&:hover {
|
|
@include hover-lift(-4px);
|
|
box-shadow: $shadow-glass-hover;
|
|
}
|
|
}
|
|
|
|
// Gradient Card
|
|
@mixin card-gradient {
|
|
@include card-base;
|
|
background: $gradient-monaco;
|
|
color: white;
|
|
box-shadow: $shadow-monaco;
|
|
|
|
&:hover {
|
|
@include hover-lift(-4px);
|
|
box-shadow: $shadow-monaco-intense;
|
|
}
|
|
}
|
|
|
|
// Floating Card
|
|
@mixin card-floating {
|
|
@include card-base;
|
|
background: white;
|
|
box-shadow: $shadow-lg;
|
|
@include float-animation(5px, 4s);
|
|
|
|
&:hover {
|
|
animation-play-state: paused;
|
|
box-shadow: $shadow-xl;
|
|
}
|
|
}
|
|
```
|
|
|
|
### Form Elements
|
|
|
|
```scss
|
|
// Input Base
|
|
@mixin input-base {
|
|
width: 100%;
|
|
padding: $space-3 $space-4;
|
|
font-size: $text-base;
|
|
border-radius: $radius-xl;
|
|
transition: all $duration-base $ease-in-out-smooth;
|
|
|
|
&:focus {
|
|
outline: none;
|
|
}
|
|
|
|
&::placeholder {
|
|
color: $gray-400;
|
|
}
|
|
}
|
|
|
|
// Glass Input
|
|
@mixin input-glass {
|
|
@include input-base;
|
|
@include glass-effect(0.6, 10px);
|
|
border: 2px solid transparent;
|
|
|
|
&:focus {
|
|
border-color: $monaco-red-600;
|
|
background: rgba(255, 255, 255, 0.8);
|
|
box-shadow: 0 0 0 3px rgba($monaco-red-600, 0.1);
|
|
}
|
|
}
|
|
|
|
// Floating Label
|
|
@mixin floating-label {
|
|
position: relative;
|
|
|
|
label {
|
|
position: absolute;
|
|
left: $space-4;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
transition: all $duration-base $ease-in-out-smooth;
|
|
pointer-events: none;
|
|
color: $gray-500;
|
|
font-size: $text-base;
|
|
}
|
|
|
|
input:focus + label,
|
|
input:not(:placeholder-shown) + label {
|
|
top: 0;
|
|
transform: translateY(-50%) scale(0.8);
|
|
background: white;
|
|
padding: 0 $space-2;
|
|
color: $monaco-red-600;
|
|
}
|
|
}
|
|
```
|
|
|
|
## 🎭 Animation Library
|
|
|
|
### Entrance Animations
|
|
|
|
```scss
|
|
@keyframes fade-in {
|
|
from {
|
|
opacity: 0;
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@keyframes slide-up {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(20px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
@keyframes scale-in {
|
|
from {
|
|
opacity: 0;
|
|
transform: scale(0.9);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
|
|
@keyframes rotate-in {
|
|
from {
|
|
opacity: 0;
|
|
transform: rotate(-10deg) scale(0.9);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: rotate(0) scale(1);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Interaction Animations
|
|
|
|
```scss
|
|
@keyframes bounce {
|
|
0%, 100% {
|
|
transform: translateY(0);
|
|
}
|
|
50% {
|
|
transform: translateY(-10px);
|
|
}
|
|
}
|
|
|
|
@keyframes shake {
|
|
0%, 100% {
|
|
transform: translateX(0);
|
|
}
|
|
25% {
|
|
transform: translateX(-5px);
|
|
}
|
|
75% {
|
|
transform: translateX(5px);
|
|
}
|
|
}
|
|
|
|
@keyframes wiggle {
|
|
0%, 100% {
|
|
transform: rotate(0deg);
|
|
}
|
|
25% {
|
|
transform: rotate(-3deg);
|
|
}
|
|
75% {
|
|
transform: rotate(3deg);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Loading Animations
|
|
|
|
```scss
|
|
@keyframes spin {
|
|
from {
|
|
transform: rotate(0deg);
|
|
}
|
|
to {
|
|
transform: rotate(360deg);
|
|
}
|
|
}
|
|
|
|
@keyframes pulse-ring {
|
|
0% {
|
|
transform: scale(0.5);
|
|
opacity: 1;
|
|
}
|
|
80%, 100% {
|
|
transform: scale(1.5);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@keyframes shimmer {
|
|
0% {
|
|
background-position: -200% 0;
|
|
}
|
|
100% {
|
|
background-position: 200% 0;
|
|
}
|
|
}
|
|
|
|
.shimmer-effect {
|
|
background: linear-gradient(
|
|
90deg,
|
|
rgba(255, 255, 255, 0) 0%,
|
|
rgba(255, 255, 255, 0.3) 50%,
|
|
rgba(255, 255, 255, 0) 100%
|
|
);
|
|
background-size: 200% 100%;
|
|
animation: shimmer 1.5s infinite;
|
|
}
|
|
```
|
|
|
|
## 📱 Responsive Design
|
|
|
|
### Breakpoints
|
|
|
|
```scss
|
|
// Mobile First Breakpoints
|
|
$screen-sm: 640px; // Small devices
|
|
$screen-md: 768px; // Medium devices
|
|
$screen-lg: 1024px; // Large devices
|
|
$screen-xl: 1280px; // Extra large devices
|
|
$screen-2xl: 1536px; // 2X Extra large devices
|
|
|
|
// Mixins
|
|
@mixin sm {
|
|
@media (min-width: $screen-sm) {
|
|
@content;
|
|
}
|
|
}
|
|
|
|
@mixin md {
|
|
@media (min-width: $screen-md) {
|
|
@content;
|
|
}
|
|
}
|
|
|
|
@mixin lg {
|
|
@media (min-width: $screen-lg) {
|
|
@content;
|
|
}
|
|
}
|
|
|
|
@mixin xl {
|
|
@media (min-width: $screen-xl) {
|
|
@content;
|
|
}
|
|
}
|
|
|
|
@mixin 2xl {
|
|
@media (min-width: $screen-2xl) {
|
|
@content;
|
|
}
|
|
}
|
|
```
|
|
|
|
### Container Widths
|
|
|
|
```scss
|
|
.container {
|
|
width: 100%;
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
padding-left: $space-4;
|
|
padding-right: $space-4;
|
|
|
|
@include sm {
|
|
max-width: $screen-sm;
|
|
}
|
|
|
|
@include md {
|
|
max-width: $screen-md;
|
|
}
|
|
|
|
@include lg {
|
|
max-width: $screen-lg;
|
|
}
|
|
|
|
@include xl {
|
|
max-width: $screen-xl;
|
|
}
|
|
|
|
@include 2xl {
|
|
max-width: $screen-2xl;
|
|
}
|
|
}
|
|
```
|
|
|
|
## 🎪 Motion Preferences
|
|
|
|
```scss
|
|
// Respect user's motion preferences
|
|
@media (prefers-reduced-motion: reduce) {
|
|
*,
|
|
*::before,
|
|
*::after {
|
|
animation-duration: 0.01ms !important;
|
|
animation-iteration-count: 1 !important;
|
|
transition-duration: 0.01ms !important;
|
|
scroll-behavior: auto !important;
|
|
}
|
|
}
|
|
|
|
// Dark mode support
|
|
@media (prefers-color-scheme: dark) {
|
|
:root {
|
|
--bg-primary: #{$gray-900};
|
|
--text-primary: #{$gray-50};
|
|
--glass-bg: rgba(0, 0, 0, 0.7);
|
|
--glass-border: rgba(255, 255, 255, 0.1);
|
|
}
|
|
}
|
|
```
|
|
|
|
## 🔧 Utility Classes
|
|
|
|
### Display Utilities
|
|
|
|
```scss
|
|
.hidden { display: none; }
|
|
.block { display: block; }
|
|
.inline-block { display: inline-block; }
|
|
.inline { display: inline; }
|
|
.flex { display: flex; }
|
|
.inline-flex { display: inline-flex; }
|
|
.grid { display: grid; }
|
|
|
|
// Flexbox Utilities
|
|
.items-start { align-items: flex-start; }
|
|
.items-center { align-items: center; }
|
|
.items-end { align-items: flex-end; }
|
|
.justify-start { justify-content: flex-start; }
|
|
.justify-center { justify-content: center; }
|
|
.justify-end { justify-content: flex-end; }
|
|
.justify-between { justify-content: space-between; }
|
|
.flex-row { flex-direction: row; }
|
|
.flex-col { flex-direction: column; }
|
|
.flex-wrap { flex-wrap: wrap; }
|
|
.flex-1 { flex: 1 1 0%; }
|
|
.flex-auto { flex: 1 1 auto; }
|
|
```
|
|
|
|
### Spacing Utilities
|
|
|
|
```scss
|
|
// Margin
|
|
@each $name, $size in (
|
|
'0': $space-0,
|
|
'1': $space-1,
|
|
'2': $space-2,
|
|
'3': $space-3,
|
|
'4': $space-4,
|
|
'5': $space-5,
|
|
'6': $space-6,
|
|
'8': $space-8,
|
|
'10': $space-10,
|
|
'12': $space-12,
|
|
'16': $space-16
|
|
) {
|
|
.m-#{$name} { margin: $size; }
|
|
.mt-#{$name} { margin-top: $size; }
|
|
.mr-#{$name} { margin-right: $size; }
|
|
.mb-#{$name} { margin-bottom: $size; }
|
|
.ml-#{$name} { margin-left: $size; }
|
|
.mx-#{$name} {
|
|
margin-left: $size;
|
|
margin-right: $size;
|
|
}
|
|
.my-#{$name} {
|
|
margin-top: $size;
|
|
margin-bottom: $size;
|
|
}
|
|
}
|
|
|
|
// Padding (same pattern as margin)
|
|
```
|
|
|
|
### Text Utilities
|
|
|
|
```scss
|
|
// Font Size
|
|
.text-xs { font-size: $text-xs; }
|
|
.text-sm { font-size: $text-sm; }
|
|
.text-base { font-size: $text-base; }
|
|
.text-lg { font-size: $text-lg; }
|
|
.text-xl { font-size: $text-xl; }
|
|
.text-2xl { font-size: $text-2xl; }
|
|
.text-3xl { font-size: $text-3xl; }
|
|
.text-4xl { font-size: $text-4xl; }
|
|
|
|
// Font Weight
|
|
.font-thin { font-weight: $font-thin; }
|
|
.font-light { font-weight: $font-light; }
|
|
.font-normal { font-weight: $font-normal; }
|
|
.font-medium { font-weight: $font-medium; }
|
|
.font-semibold { font-weight: $font-semibold; }
|
|
.font-bold { font-weight: $font-bold; }
|
|
|
|
// Text Alignment
|
|
.text-left { text-align: left; }
|
|
.text-center { text-align: center; }
|
|
.text-right { text-align: right; }
|
|
.text-justify { text-align: justify; }
|
|
```
|
|
|
|
## 🎯 Dashboard Patterns
|
|
|
|
### Bento Grid Layout
|
|
Modern dashboard layout using CSS Grid with flexible item placement:
|
|
|
|
```scss
|
|
.bento-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(12, 1fr);
|
|
gap: 1.5rem;
|
|
|
|
.bento-item {
|
|
@include glass-premium;
|
|
border-radius: $radius-2xl;
|
|
padding: $space-6;
|
|
transition: all $duration-base $ease-in-out-smooth;
|
|
|
|
&--small { grid-column: span 3; }
|
|
&--medium { grid-column: span 4; }
|
|
&--large { grid-column: span 6; }
|
|
&--xlarge { grid-column: span 8; }
|
|
&--full { grid-column: span 12; }
|
|
|
|
&--tall { grid-row: span 2; }
|
|
|
|
&:hover {
|
|
transform: translateY(-4px);
|
|
box-shadow: $shadow-glass-hover;
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Widget Components
|
|
|
|
#### Statistics Card
|
|
```scss
|
|
.stat-card {
|
|
@include glass-premium(0.8, 25px);
|
|
position: relative;
|
|
overflow: hidden;
|
|
|
|
.stat-value {
|
|
font-size: $text-4xl;
|
|
font-weight: $font-bold;
|
|
background: $gradient-monaco;
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
}
|
|
|
|
.stat-change {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
padding: $space-1 $space-2;
|
|
border-radius: $radius-full;
|
|
font-size: $text-sm;
|
|
font-weight: $font-semibold;
|
|
|
|
&--positive {
|
|
background: rgba($success-500, 0.1);
|
|
color: $success-600;
|
|
}
|
|
|
|
&--negative {
|
|
background: rgba($monaco-red-500, 0.1);
|
|
color: $monaco-red-600;
|
|
}
|
|
}
|
|
|
|
.stat-chart {
|
|
position: absolute;
|
|
bottom: 0;
|
|
right: 0;
|
|
opacity: 0.2;
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Activity Timeline
|
|
```scss
|
|
.timeline {
|
|
position: relative;
|
|
|
|
&::before {
|
|
content: '';
|
|
position: absolute;
|
|
left: 20px;
|
|
top: 0;
|
|
bottom: 0;
|
|
width: 2px;
|
|
background: $gradient-monaco;
|
|
opacity: 0.2;
|
|
}
|
|
|
|
.timeline-item {
|
|
position: relative;
|
|
padding-left: 50px;
|
|
margin-bottom: $space-6;
|
|
animation: slide-up $duration-base $ease-in-out-smooth;
|
|
animation-fill-mode: both;
|
|
|
|
@for $i from 1 through 10 {
|
|
&:nth-child(#{$i}) {
|
|
animation-delay: #{$i * 50}ms;
|
|
}
|
|
}
|
|
|
|
.timeline-marker {
|
|
position: absolute;
|
|
left: 10px;
|
|
top: 0;
|
|
width: 20px;
|
|
height: 20px;
|
|
border-radius: $radius-full;
|
|
background: white;
|
|
border: 3px solid $monaco-red-600;
|
|
z-index: 1;
|
|
|
|
&.pulse {
|
|
&::after {
|
|
content: '';
|
|
position: absolute;
|
|
inset: -5px;
|
|
border-radius: $radius-full;
|
|
border: 2px solid $monaco-red-600;
|
|
animation: pulse-ring 2s infinite;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Draggable Dashboard
|
|
```scss
|
|
.draggable-grid {
|
|
.drag-handle {
|
|
position: absolute;
|
|
top: $space-4;
|
|
right: $space-4;
|
|
cursor: grab;
|
|
opacity: 0;
|
|
transition: opacity $duration-base;
|
|
|
|
&:active {
|
|
cursor: grabbing;
|
|
}
|
|
}
|
|
|
|
.draggable-item {
|
|
&:hover .drag-handle {
|
|
opacity: 0.5;
|
|
}
|
|
|
|
&.dragging {
|
|
opacity: 0.5;
|
|
transform: scale(1.05);
|
|
z-index: 1000;
|
|
}
|
|
|
|
&.drag-over {
|
|
background: rgba($monaco-red-600, 0.05);
|
|
border: 2px dashed $monaco-red-600;
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Enhanced Glass Effects
|
|
|
|
```scss
|
|
@mixin glass-premium($opacity: 0.7, $blur: 30px) {
|
|
background: linear-gradient(135deg,
|
|
rgba(255, 255, 255, $opacity),
|
|
rgba(255, 255, 255, $opacity * 0.6)
|
|
);
|
|
backdrop-filter: blur($blur) saturate(180%);
|
|
-webkit-backdrop-filter: blur($blur) saturate(180%);
|
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
box-shadow:
|
|
0 8px 32px rgba(0, 0, 0, 0.1),
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.5),
|
|
inset 0 -1px 0 rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
@mixin glass-frosted($color: white, $opacity: 0.1) {
|
|
background: rgba($color, $opacity);
|
|
backdrop-filter: blur(40px) saturate(200%) contrast(120%);
|
|
-webkit-backdrop-filter: blur(40px) saturate(200%) contrast(120%);
|
|
border: 1px solid rgba($color, 0.2);
|
|
box-shadow:
|
|
0 20px 40px rgba(0, 0, 0, 0.1),
|
|
inset 0 0 0 1px rgba(255, 255, 255, 0.1);
|
|
}
|
|
```
|
|
|
|
### Animation Patterns for Dashboard
|
|
|
|
#### Number Counter Animation
|
|
```scss
|
|
@keyframes count-up {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(20px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.counter {
|
|
display: inline-block;
|
|
animation: count-up $duration-slow $ease-out-back;
|
|
|
|
.digit {
|
|
display: inline-block;
|
|
animation: count-up $duration-slow $ease-out-back;
|
|
animation-fill-mode: both;
|
|
|
|
@for $i from 1 through 10 {
|
|
&:nth-child(#{$i}) {
|
|
animation-delay: #{$i * 50}ms;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Progress Ring
|
|
```scss
|
|
.progress-ring {
|
|
position: relative;
|
|
width: 120px;
|
|
height: 120px;
|
|
|
|
svg {
|
|
transform: rotate(-90deg);
|
|
}
|
|
|
|
.progress-ring-circle {
|
|
fill: none;
|
|
stroke-width: 8;
|
|
|
|
&--bg {
|
|
stroke: rgba($gray-300, 0.3);
|
|
}
|
|
|
|
&--fill {
|
|
stroke: url(#gradient-monaco);
|
|
stroke-linecap: round;
|
|
transition: stroke-dashoffset $duration-slow $ease-in-out-smooth;
|
|
}
|
|
}
|
|
|
|
.progress-value {
|
|
position: absolute;
|
|
inset: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: $text-2xl;
|
|
font-weight: $font-bold;
|
|
}
|
|
}
|
|
```
|
|
|
|
### VueUse Motion Integration
|
|
|
|
#### Configuration
|
|
```javascript
|
|
// Motion variants for dashboard components
|
|
export const dashboardMotions = {
|
|
// Card entrance
|
|
cardEnter: {
|
|
initial: { opacity: 0, scale: 0.9 },
|
|
enter: {
|
|
opacity: 1,
|
|
scale: 1,
|
|
transition: {
|
|
type: 'spring',
|
|
stiffness: 200,
|
|
damping: 20
|
|
}
|
|
}
|
|
},
|
|
|
|
// Statistics counter
|
|
statCounter: {
|
|
initial: { opacity: 0, y: 20 },
|
|
visible: {
|
|
opacity: 1,
|
|
y: 0,
|
|
transition: {
|
|
duration: 600,
|
|
ease: 'easeOut'
|
|
}
|
|
}
|
|
},
|
|
|
|
// Timeline item
|
|
timelineItem: {
|
|
initial: { opacity: 0, x: -20 },
|
|
visibleOnce: {
|
|
opacity: 1,
|
|
x: 0,
|
|
transition: {
|
|
duration: 500,
|
|
delay: 100
|
|
}
|
|
}
|
|
},
|
|
|
|
// Hover lift
|
|
hoverLift: {
|
|
initial: { scale: 1 },
|
|
hovered: {
|
|
scale: 1.02,
|
|
y: -4,
|
|
transition: {
|
|
type: 'spring',
|
|
stiffness: 400,
|
|
damping: 10
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Usage Example
|
|
```vue
|
|
<template>
|
|
<div class="bento-grid">
|
|
<div
|
|
v-motion="'statsCard'"
|
|
:initial="{ opacity: 0, y: 20 }"
|
|
:enter="{
|
|
opacity: 1,
|
|
y: 0,
|
|
transition: {
|
|
delay: index * 100,
|
|
duration: 500
|
|
}
|
|
}"
|
|
:hovered="{
|
|
scale: 1.02,
|
|
y: -4
|
|
}"
|
|
class="bento-item bento-item--medium stat-card"
|
|
>
|
|
<!-- Card content -->
|
|
</div>
|
|
</div>
|
|
</template>
|
|
```
|
|
|
|
---
|
|
|
|
*MonacoUSA Portal Design System v2.0 - Premium Design for Premium Experiences* |