UNPKG

react-theme-system

Version:

A comprehensive React theme management system that enforces consistency, supports dark/light mode, and eliminates hardcoded styles

256 lines (231 loc) 7.39 kB
/* React Theme System - CSS Variables with Fallbacks */ /* This file provides CSS variables with fallbacks for graceful degradation */ /* System theme detection */ @media (prefers-color-scheme: dark) { :root { /* Dark theme defaults when system prefers dark */ --color-primary: #60a5fa; --color-secondary: #818cf8; --color-accent: #34d399; --color-background: #0f172a; --color-surface: #1e293b; --color-text-primary: #f8fafc; --color-text-secondary: #cbd5e1; --color-text-disabled: #64748b; --color-border: #334155; --color-error: #f87171; --color-warning: #fbbf24; --color-success: #4ade80; --color-info: #60a5fa; } } @media (prefers-color-scheme: light) { :root { /* Light theme defaults when system prefers light */ --color-primary: #4361ee; --color-secondary: #3f37c9; --color-accent: #4895ef; --color-background: #ffffff; --color-surface: #f8f9fa; --color-text-primary: #212529; --color-text-secondary: #6c757d; --color-text-disabled: #adb5bd; --color-border: #dee2e6; --color-error: #dc3545; --color-warning: #ffc107; --color-success: #28a745; --color-info: #17a2b8; } } /* Base fallbacks (light theme) */ :root { /* Colors */ --color-primary: #4361ee; --color-secondary: #3f37c9; --color-accent: #4895ef; --color-background: #ffffff; --color-surface: #f8f9fa; --color-text-primary: #212529; --color-text-secondary: #6c757d; --color-text-disabled: #adb5bd; --color-border: #dee2e6; --color-error: #dc3545; --color-warning: #ffc107; --color-success: #28a745; --color-info: #17a2b8; /* Spacing */ --spacing-xs: 0.25rem; --spacing-sm: 0.5rem; --spacing-md: 1rem; --spacing-lg: 1.5rem; --spacing-xl: 3rem; --spacing-xxl: 4rem; /* Typography */ --font-family-primary: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; --font-family-secondary: Georgia, "Times New Roman", serif; --font-family-mono: SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace; --font-size-xs: 0.75rem; --font-size-sm: 0.875rem; --font-size-base: 1rem; --font-size-lg: 1.125rem; --font-size-xl: 1.25rem; --font-size-2xl: 1.5rem; --font-size-3xl: 1.875rem; --font-size-4xl: 2.25rem; --font-weight-light: 300; --font-weight-normal: 400; --font-weight-medium: 500; --font-weight-semibold: 600; --font-weight-bold: 700; --line-height-tight: 1.25; --line-height-normal: 1.5; --line-height-relaxed: 1.75; /* Shadows */ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05); --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); --shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25); --shadow-inner: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06); --shadow-none: none; /* Border Radius */ --radius-none: 0; --radius-sm: 0.125rem; --radius-md: 0.375rem; --radius-lg: 0.5rem; --radius-xl: 0.75rem; --radius-full: 9999px; /* Breakpoints */ --breakpoint-sm: 640px; --breakpoint-md: 768px; --breakpoint-lg: 1024px; --breakpoint-xl: 1280px; --breakpoint-2xl: 1536px; /* Transitions */ --transition-fast: 150ms ease-in-out; --transition-normal: 300ms ease-in-out; --transition-slow: 500ms ease-in-out; --transition-ease-in: ease-in; --transition-ease-out: ease-out; --transition-ease-in-out: ease-in-out; /* Z-Index */ --z-index-hide: -1; --z-index-auto: 0; --z-index-base: 0; --z-index-docked: 10; --z-index-dropdown: 1000; --z-index-sticky: 1100; --z-index-banner: 1200; --z-index-overlay: 1300; --z-index-modal: 1400; --z-index-popover: 1500; --z-index-skip-link: 1600; --z-index-toast: 1700; --z-index-tooltip: 1800; } /* Dark theme overrides */ [data-theme="dark"] { /* Colors */ --color-primary: #60a5fa; --color-secondary: #818cf8; --color-accent: #34d399; --color-background: #0f172a; --color-surface: #1e293b; --color-text-primary: #f8fafc; --color-text-secondary: #cbd5e1; --color-text-disabled: #64748b; --color-border: #334155; --color-error: #f87171; --color-warning: #fbbf24; --color-success: #4ade80; --color-info: #60a5fa; /* Shadows - darker for dark theme */ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3); --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.3); --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -2px rgba(0, 0, 0, 0.3); --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.4), 0 10px 10px -5px rgba(0, 0, 0, 0.3); --shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.5); --shadow-inner: inset 0 2px 4px 0 rgba(0, 0, 0, 0.3); } /* Light theme explicit override */ [data-theme="light"] { /* Colors */ --color-primary: #4361ee; --color-secondary: #3f37c9; --color-accent: #4895ef; --color-background: #ffffff; --color-surface: #f8f9fa; --color-text-primary: #212529; --color-text-secondary: #6c757d; --color-text-disabled: #adb5bd; --color-border: #dee2e6; --color-error: #dc3545; --color-warning: #ffc107; --color-success: #28a745; --color-info: #17a2b8; /* Shadows - lighter for light theme */ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05); --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); --shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25); --shadow-inner: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06); } /* Utility classes for common theme patterns */ .theme-transition { transition: color var(--transition-normal), background-color var(--transition-normal), border-color var(--transition-normal); } .theme-focus { outline: 2px solid var(--color-primary); outline-offset: 2px; } .theme-focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; } /* High contrast mode support */ @media (prefers-contrast: high) { :root { --color-primary: #0000ff; --color-secondary: #000080; --color-accent: #008000; --color-background: #ffffff; --color-surface: #f0f0f0; --color-text-primary: #000000; --color-text-secondary: #333333; --color-text-disabled: #666666; --color-border: #000000; --color-error: #ff0000; --color-warning: #ff8000; --color-success: #008000; --color-info: #0000ff; } [data-theme="dark"] { --color-primary: #ffff00; --color-secondary: #ffff80; --color-accent: #80ff80; --color-background: #000000; --color-surface: #1a1a1a; --color-text-primary: #ffffff; --color-text-secondary: #cccccc; --color-text-disabled: #999999; --color-border: #ffffff; --color-error: #ff8080; --color-warning: #ffcc80; --color-success: #80ff80; --color-info: #8080ff; } } /* Reduced motion support */ @media (prefers-reduced-motion: reduce) { :root { --transition-fast: 0ms; --transition-normal: 0ms; --transition-slow: 0ms; } * { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } }