d3760cccb5
**Design System (Phase 1 completion):** - tokens.ts: 12-category token system (colors, typography, spacing, shadows, etc.) - tokens.css: CSS variables with light/dark theme support - App.vue: Integrated token system app-wide **Shared Components (Phase 2):** - SkeletonLoader.vue: 5 loader types (text, card, avatar, table, list) - ErrorBoundary.vue: Error state recovery with retry - ToastNotification.vue: Toast alerts with 4 types + auto-dismiss - ToastContainer.vue: Toast provider with fixed positioning - Modal.vue: Animated modal with 4 size variants **Page Enhancements:** - ShadowRunQueue.vue: Loading → Skeleton + Error → ErrorBoundary + Normal states - ModelList.vue: Loading → Skeleton + Error → ErrorBoundary + Normal states - ApprovalQueue.vue: Loading → Skeleton + Error → ErrorBoundary + Normal states **Testing:** - All 3 pages: ✅ 100% PASS (12/12 selectors) - Playwright tests verify: loading, error, normal states - All states render correctly with token-based styling **Next: Phase 3 (2-4h)** - Layout unification (sidebar, header, footer) - Complete dark theme implementation - Mobile responsiveness & navigation Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
352 lines
7.9 KiB
TypeScript
352 lines
7.9 KiB
TypeScript
/**
|
|
* Design System Tokens v1.0
|
|
* Comprehensive design token definitions for production-level UI
|
|
*/
|
|
|
|
// ============================================================================
|
|
// COLOR PALETTE
|
|
// ============================================================================
|
|
|
|
export const colors = {
|
|
// Primary (Blue - Information, Action)
|
|
primary: {
|
|
50: '#eff6ff',
|
|
100: '#dbeafe',
|
|
200: '#bfdbfe',
|
|
300: '#93c5fd',
|
|
400: '#60a5fa',
|
|
500: '#3b82f6', // Primary
|
|
600: '#2563eb',
|
|
700: '#1d4ed8',
|
|
800: '#1e40af',
|
|
900: '#1e3a8a',
|
|
},
|
|
|
|
// Secondary (Purple - Emphasis)
|
|
secondary: {
|
|
50: '#faf5ff',
|
|
100: '#f3e8ff',
|
|
200: '#e9d5ff',
|
|
300: '#d8b4fe',
|
|
400: '#c084fc',
|
|
500: '#a855f7', // Secondary
|
|
600: '#9333ea',
|
|
700: '#7e22ce',
|
|
800: '#6b21a8',
|
|
900: '#581c87',
|
|
},
|
|
|
|
// Success (Green - Positive, Complete)
|
|
success: {
|
|
50: '#f0fdf4',
|
|
100: '#dcfce7',
|
|
200: '#bbf7d0',
|
|
300: '#86efac',
|
|
400: '#4ade80',
|
|
500: '#22c55e', // Success
|
|
600: '#16a34a',
|
|
700: '#15803d',
|
|
800: '#166534',
|
|
900: '#145231',
|
|
},
|
|
|
|
// Warning (Amber - Caution, Pending)
|
|
warning: {
|
|
50: '#fffbeb',
|
|
100: '#fef3c7',
|
|
200: '#fde68a',
|
|
300: '#fcd34d',
|
|
400: '#fbbf24',
|
|
500: '#f59e0b', // Warning
|
|
600: '#d97706',
|
|
700: '#b45309',
|
|
800: '#92400e',
|
|
900: '#78350f',
|
|
},
|
|
|
|
// Danger (Red - Error, Destructive)
|
|
danger: {
|
|
50: '#fef2f2',
|
|
100: '#fee2e2',
|
|
200: '#fecaca',
|
|
300: '#fca5a5',
|
|
400: '#f87171',
|
|
500: '#ef4444', // Danger
|
|
600: '#dc2626',
|
|
700: '#b91c1c',
|
|
800: '#991b1b',
|
|
900: '#7f1d1d',
|
|
},
|
|
|
|
// Neutral (Gray - Text, Backgrounds)
|
|
neutral: {
|
|
50: '#fafafa',
|
|
100: '#f5f5f5',
|
|
200: '#eeeeee',
|
|
300: '#e0e0e0',
|
|
400: '#bdbdbd',
|
|
500: '#9e9e9e',
|
|
600: '#757575',
|
|
700: '#616161',
|
|
800: '#424242',
|
|
900: '#212121',
|
|
},
|
|
|
|
// Module Colors
|
|
module: {
|
|
oms: '#3b82f6', // OMS - Blue
|
|
erp: '#a855f7', // ERP - Purple
|
|
wms: '#14b8a6', // WMS - Teal
|
|
common: '#6b7280', // COMMON - Gray
|
|
},
|
|
|
|
// Special
|
|
white: '#ffffff',
|
|
black: '#000000',
|
|
transparent: 'transparent',
|
|
}
|
|
|
|
// ============================================================================
|
|
// TYPOGRAPHY
|
|
// ============================================================================
|
|
|
|
export const typography = {
|
|
// Font Families
|
|
family: {
|
|
sans: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
|
|
mono: '"SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, "Courier New", monospace',
|
|
},
|
|
|
|
// Font Sizes
|
|
size: {
|
|
xs: '12px', // Captions, helpers
|
|
sm: '14px', // Small text
|
|
base: '16px', // Body text
|
|
lg: '18px', // Larger body
|
|
xl: '20px', // Headings
|
|
'2xl': '24px', // Section headings
|
|
'3xl': '30px', // Page headings
|
|
'4xl': '36px', // Hero
|
|
},
|
|
|
|
// Line Heights
|
|
lineHeight: {
|
|
tight: '1.2',
|
|
normal: '1.5',
|
|
relaxed: '1.75',
|
|
loose: '2',
|
|
},
|
|
|
|
// Font Weights
|
|
weight: {
|
|
light: 300,
|
|
normal: 400,
|
|
medium: 500,
|
|
semibold: 600,
|
|
bold: 700,
|
|
},
|
|
}
|
|
|
|
// ============================================================================
|
|
// SPACING
|
|
// ============================================================================
|
|
|
|
export const spacing = {
|
|
0: '0px',
|
|
1: '4px',
|
|
2: '8px',
|
|
3: '12px',
|
|
4: '16px',
|
|
5: '20px',
|
|
6: '24px',
|
|
8: '32px',
|
|
10: '40px',
|
|
12: '48px',
|
|
16: '64px',
|
|
20: '80px',
|
|
24: '96px',
|
|
}
|
|
|
|
// ============================================================================
|
|
// SHADOWS
|
|
// ============================================================================
|
|
|
|
export const shadows = {
|
|
none: 'none',
|
|
xs: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
|
|
sm: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
|
|
md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
|
|
lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
|
|
xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
|
|
'2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
|
|
}
|
|
|
|
// ============================================================================
|
|
// BORDERS
|
|
// ============================================================================
|
|
|
|
export const borders = {
|
|
radius: {
|
|
none: '0px',
|
|
sm: '2px',
|
|
base: '4px',
|
|
md: '6px',
|
|
lg: '8px',
|
|
xl: '12px',
|
|
full: '9999px',
|
|
},
|
|
|
|
width: {
|
|
0: '0px',
|
|
1: '1px',
|
|
2: '2px',
|
|
},
|
|
}
|
|
|
|
// ============================================================================
|
|
// TRANSITIONS
|
|
// ============================================================================
|
|
|
|
export const transitions = {
|
|
fast: '150ms cubic-bezier(0.4, 0, 0.2, 1)',
|
|
base: '200ms cubic-bezier(0.4, 0, 0.2, 1)',
|
|
slow: '300ms cubic-bezier(0.4, 0, 0.2, 1)',
|
|
slower: '500ms cubic-bezier(0.4, 0, 0.2, 1)',
|
|
}
|
|
|
|
// ============================================================================
|
|
// Z-INDEX
|
|
// ============================================================================
|
|
|
|
export const zIndex = {
|
|
hide: -1,
|
|
base: 0,
|
|
dropdown: 1000,
|
|
sticky: 1020,
|
|
fixed: 1030,
|
|
modalBackdrop: 1040,
|
|
modal: 1050,
|
|
popover: 1060,
|
|
tooltip: 1070,
|
|
}
|
|
|
|
// ============================================================================
|
|
// COMPONENT SIZES
|
|
// ============================================================================
|
|
|
|
export const componentSizes = {
|
|
// Input Heights
|
|
inputSm: '32px',
|
|
inputBase: '36px',
|
|
inputLg: '44px',
|
|
|
|
// Button Heights
|
|
buttonSm: '32px',
|
|
buttonBase: '36px',
|
|
buttonLg: '44px',
|
|
|
|
// Icon Sizes
|
|
iconXs: '16px',
|
|
iconSm: '20px',
|
|
iconBase: '24px',
|
|
iconLg: '32px',
|
|
iconXl: '48px',
|
|
|
|
// Grid Row Heights
|
|
gridRowCompact: '32px',
|
|
gridRowBase: '36px',
|
|
gridRowComfortable: '44px',
|
|
gridRowTouch: '52px',
|
|
|
|
// Sidebar Widths
|
|
sidebarCompact: '64px',
|
|
sidebarBase: '256px',
|
|
sidebarWide: '320px',
|
|
}
|
|
|
|
// ============================================================================
|
|
// BREAKPOINTS (CSS Media Queries)
|
|
// ============================================================================
|
|
|
|
export const breakpoints = {
|
|
xs: '320px',
|
|
sm: '640px',
|
|
md: '768px',
|
|
lg: '1024px',
|
|
xl: '1280px',
|
|
'2xl': '1536px',
|
|
}
|
|
|
|
// ============================================================================
|
|
// OPACITY
|
|
// ============================================================================
|
|
|
|
export const opacity = {
|
|
0: '0',
|
|
5: '0.05',
|
|
10: '0.1',
|
|
20: '0.2',
|
|
30: '0.3',
|
|
40: '0.4',
|
|
50: '0.5',
|
|
60: '0.6',
|
|
70: '0.7',
|
|
80: '0.8',
|
|
90: '0.9',
|
|
100: '1',
|
|
}
|
|
|
|
// ============================================================================
|
|
// SEMANTIC COLORS (Context-aware, used with tokens above)
|
|
// ============================================================================
|
|
|
|
export const semantic = {
|
|
light: {
|
|
text: {
|
|
primary: colors.neutral[900],
|
|
secondary: colors.neutral[700],
|
|
tertiary: colors.neutral[500],
|
|
inverse: colors.white,
|
|
},
|
|
background: {
|
|
primary: colors.white,
|
|
secondary: colors.neutral[50],
|
|
tertiary: colors.neutral[100],
|
|
hover: colors.neutral[100],
|
|
},
|
|
border: {
|
|
primary: colors.neutral[300],
|
|
secondary: colors.neutral[200],
|
|
},
|
|
input: {
|
|
background: colors.white,
|
|
border: colors.neutral[300],
|
|
hover: colors.neutral[200],
|
|
},
|
|
},
|
|
|
|
dark: {
|
|
text: {
|
|
primary: colors.white,
|
|
secondary: colors.neutral[300],
|
|
tertiary: colors.neutral[500],
|
|
inverse: colors.neutral[900],
|
|
},
|
|
background: {
|
|
primary: colors.neutral[900],
|
|
secondary: colors.neutral[800],
|
|
tertiary: colors.neutral[700],
|
|
hover: colors.neutral[700],
|
|
},
|
|
border: {
|
|
primary: colors.neutral[700],
|
|
secondary: colors.neutral[600],
|
|
},
|
|
input: {
|
|
background: colors.neutral[800],
|
|
border: colors.neutral[700],
|
|
hover: colors.neutral[600],
|
|
},
|
|
},
|
|
}
|