Files
thrillwiki_django_no_react/static/css/design-tokens.css

1130 lines
36 KiB
CSS

/**
* ThrillWiki Design Tokens
*
* This is the single source of truth for all design tokens in the application.
* All CSS files should reference these variables instead of hardcoding values.
*
* Token Naming Convention:
* - Color scales: --color-{name}-{shade} (e.g., --color-primary-500)
* - Semantic colors: --color-{semantic} (e.g., --color-background, --color-foreground)
* - Typography: --font-{property}-{value} (e.g., --font-size-lg)
* - Spacing: --spacing-{size} (e.g., --spacing-4)
* - Shadows: --shadow-{size} (e.g., --shadow-md)
* - Radius: --radius-{size} (e.g., --radius-lg)
* - Transitions: --transition-{type} (e.g., --transition-all)
* - Z-index: --z-{level} (e.g., --z-50)
*
* Responsive Breakpoints (Tailwind defaults):
* - sm: 640px - Small devices (landscape phones)
* - md: 768px - Medium devices (tablets)
* - lg: 1024px - Large devices (desktops)
* - xl: 1280px - Extra large devices
* - 2xl: 1536px - 2X Extra large devices
*/
@layer tokens, base, components, utilities, overrides;
@layer tokens {
:root {
/* =================================================================
Color Scales - Base Palette
================================================================= */
/* Primary Colors - Blue */
--color-primary-50: #eff6ff;
--color-primary-100: #dbeafe;
--color-primary-200: #bfdbfe;
--color-primary-300: #93c5fd;
--color-primary-400: #60a5fa;
--color-primary-500: #3b82f6;
--color-primary-600: #2563eb;
--color-primary-700: #1d4ed8;
--color-primary-800: #1e40af;
--color-primary-900: #1e3a8a;
--color-primary-950: #172554;
/* Secondary Colors - Slate */
--color-secondary-50: #f8fafc;
--color-secondary-100: #f1f5f9;
--color-secondary-200: #e2e8f0;
--color-secondary-300: #cbd5e1;
--color-secondary-400: #94a3b8;
--color-secondary-500: #64748b;
--color-secondary-600: #475569;
--color-secondary-700: #334155;
--color-secondary-800: #1e293b;
--color-secondary-900: #0f172a;
--color-secondary-950: #020617;
/* Accent Colors - Red */
--color-accent-50: #fef2f2;
--color-accent-100: #fee2e2;
--color-accent-200: #fecaca;
--color-accent-300: #fca5a5;
--color-accent-400: #f87171;
--color-accent-500: #ef4444;
--color-accent-600: #dc2626;
--color-accent-700: #b91c1c;
--color-accent-800: #991b1b;
--color-accent-900: #7f1d1d;
--color-accent-950: #450a0a;
/* Success Colors - Green */
--color-success-50: #f0fdf4;
--color-success-100: #dcfce7;
--color-success-200: #bbf7d0;
--color-success-300: #86efac;
--color-success-400: #4ade80;
--color-success-500: #22c55e;
--color-success-600: #16a34a;
--color-success-700: #15803d;
--color-success-800: #166534;
--color-success-900: #14532d;
--color-success-950: #052e16;
/* Warning Colors - Amber */
--color-warning-50: #fffbeb;
--color-warning-100: #fef3c7;
--color-warning-200: #fde68a;
--color-warning-300: #fcd34d;
--color-warning-400: #fbbf24;
--color-warning-500: #f59e0b;
--color-warning-600: #d97706;
--color-warning-700: #b45309;
--color-warning-800: #92400e;
--color-warning-900: #78350f;
--color-warning-950: #451a03;
/* Error Colors - Red */
--color-error-50: #fef2f2;
--color-error-100: #fee2e2;
--color-error-200: #fecaca;
--color-error-300: #fca5a5;
--color-error-400: #f87171;
--color-error-500: #ef4444;
--color-error-600: #dc2626;
--color-error-700: #b91c1c;
--color-error-800: #991b1b;
--color-error-900: #7f1d1d;
--color-error-950: #450a0a;
/* Info Colors - Sky */
--color-info-50: #f0f9ff;
--color-info-100: #e0f2fe;
--color-info-200: #bae6fd;
--color-info-300: #7dd3fc;
--color-info-400: #38bdf8;
--color-info-500: #0ea5e9;
--color-info-600: #0284c7;
--color-info-700: #0369a1;
--color-info-800: #075985;
--color-info-900: #0c4a6e;
--color-info-950: #082f49;
/* =================================================================
Typography
================================================================= */
/* Font Families */
--font-family-sans: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
--font-family-serif: 'Playfair Display', Georgia, Cambria, 'Times New Roman', Times, serif;
--font-family-mono: 'JetBrains Mono', 'Fira Code', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
/* Font Sizes */
--font-size-xs: 0.75rem; /* 12px */
--font-size-sm: 0.875rem; /* 14px */
--font-size-base: 1rem; /* 16px */
--font-size-lg: 1.125rem; /* 18px */
--font-size-xl: 1.25rem; /* 20px */
--font-size-2xl: 1.5rem; /* 24px */
--font-size-3xl: 1.875rem; /* 30px */
--font-size-4xl: 2.25rem; /* 36px */
--font-size-5xl: 3rem; /* 48px */
--font-size-6xl: 3.75rem; /* 60px */
--font-size-7xl: 4.5rem; /* 72px */
--font-size-8xl: 6rem; /* 96px */
--font-size-9xl: 8rem; /* 128px */
/* Font Weights */
--font-weight-thin: 100;
--font-weight-extralight: 200;
--font-weight-light: 300;
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--font-weight-extrabold: 800;
--font-weight-black: 900;
/* Line Heights */
--line-height-none: 1;
--line-height-tight: 1.25;
--line-height-snug: 1.375;
--line-height-normal: 1.5;
--line-height-relaxed: 1.625;
--line-height-loose: 2;
/* Letter Spacing */
--letter-spacing-tighter: -0.05em;
--letter-spacing-tight: -0.025em;
--letter-spacing-normal: 0em;
--letter-spacing-wide: 0.025em;
--letter-spacing-wider: 0.05em;
--letter-spacing-widest: 0.1em;
/* =================================================================
Spacing Scale
================================================================= */
--spacing-px: 1px;
--spacing-0: 0;
--spacing-0-5: 0.125rem; /* 2px */
--spacing-1: 0.25rem; /* 4px */
--spacing-1-5: 0.375rem; /* 6px */
--spacing-2: 0.5rem; /* 8px */
--spacing-2-5: 0.625rem; /* 10px */
--spacing-3: 0.75rem; /* 12px */
--spacing-3-5: 0.875rem; /* 14px */
--spacing-4: 1rem; /* 16px */
--spacing-5: 1.25rem; /* 20px */
--spacing-6: 1.5rem; /* 24px */
--spacing-7: 1.75rem; /* 28px */
--spacing-8: 2rem; /* 32px */
--spacing-9: 2.25rem; /* 36px */
--spacing-10: 2.5rem; /* 40px */
--spacing-11: 2.75rem; /* 44px */
--spacing-12: 3rem; /* 48px */
--spacing-14: 3.5rem; /* 56px */
--spacing-16: 4rem; /* 64px */
--spacing-20: 5rem; /* 80px */
--spacing-24: 6rem; /* 96px */
--spacing-28: 7rem; /* 112px */
--spacing-32: 8rem; /* 128px */
--spacing-36: 9rem; /* 144px */
--spacing-40: 10rem; /* 160px */
--spacing-44: 11rem; /* 176px */
--spacing-48: 12rem; /* 192px */
--spacing-52: 13rem; /* 208px */
--spacing-56: 14rem; /* 224px */
--spacing-60: 15rem; /* 240px */
--spacing-64: 16rem; /* 256px */
--spacing-72: 18rem; /* 288px */
--spacing-80: 20rem; /* 320px */
--spacing-96: 24rem; /* 384px */
/* =================================================================
Shadows
================================================================= */
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--shadow-base: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
--shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / 0.25);
--shadow-inner: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
--shadow-none: 0 0 #0000;
/* =================================================================
Border Radius
================================================================= */
--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;
/* =================================================================
Transitions & Animations
================================================================= */
/* Transition Durations */
--duration-75: 75ms;
--duration-100: 100ms;
--duration-150: 150ms;
--duration-200: 200ms;
--duration-300: 300ms;
--duration-500: 500ms;
--duration-700: 700ms;
--duration-1000: 1000ms;
/* Transition Timing Functions */
--ease-linear: linear;
--ease-in: cubic-bezier(0.4, 0, 1, 1);
--ease-out: cubic-bezier(0, 0, 0.2, 1);
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
--ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
/* Transition Presets */
--transition-none: none;
--transition-all: all 150ms cubic-bezier(0.4, 0, 0.2, 1);
--transition-colors: color 150ms cubic-bezier(0.4, 0, 0.2, 1), background-color 150ms cubic-bezier(0.4, 0, 0.2, 1), border-color 150ms cubic-bezier(0.4, 0, 0.2, 1), text-decoration-color 150ms cubic-bezier(0.4, 0, 0.2, 1), fill 150ms cubic-bezier(0.4, 0, 0.2, 1), stroke 150ms cubic-bezier(0.4, 0, 0.2, 1);
--transition-opacity: opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);
--transition-shadow: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1);
--transition-transform: transform 150ms cubic-bezier(0.4, 0, 0.2, 1);
/* =================================================================
Responsive Breakpoints
Use with CSS media queries: @media (min-width: var(--breakpoint-sm))
Note: CSS custom properties in media queries require JavaScript workarounds
These are documented here for reference; use Tailwind classes for responsive design
================================================================= */
--breakpoint-sm: 640px; /* Small devices (landscape phones) */
--breakpoint-md: 768px; /* Medium devices (tablets) */
--breakpoint-lg: 1024px; /* Large devices (desktops) */
--breakpoint-xl: 1280px; /* Extra large devices */
--breakpoint-2xl: 1536px; /* 2X Extra large devices */
/* Container Max-Widths at Breakpoints */
--container-sm: 640px;
--container-md: 768px;
--container-lg: 1024px;
--container-xl: 1280px;
--container-2xl: 1536px;
/* =================================================================
Z-Index Scale
================================================================= */
--z-0: 0;
--z-10: 10;
--z-20: 20;
--z-30: 30;
--z-40: 40;
--z-50: 50;
--z-auto: auto;
--z-dropdown: 100;
--z-sticky: 200;
--z-fixed: 300;
--z-modal-backdrop: 400;
--z-modal: 500;
--z-popover: 600;
--z-tooltip: 700;
--z-toast: 800;
/* =================================================================
Semantic Colors - Light Mode
================================================================= */
/* Background & Foreground */
--color-background: var(--color-secondary-50);
--color-foreground: var(--color-secondary-900);
/* Muted */
--color-muted: var(--color-secondary-100);
--color-muted-foreground: var(--color-secondary-500);
/* Border & Input */
--color-border: var(--color-secondary-200);
--color-input: var(--color-secondary-50);
/* Card */
--color-card: var(--color-secondary-50);
--color-card-foreground: var(--color-secondary-900);
/* Popover */
--color-popover: var(--color-secondary-50);
--color-popover-foreground: var(--color-secondary-900);
/* Primary */
--color-primary: var(--color-primary-600);
--color-primary-foreground: var(--color-primary-50);
/* Secondary */
--color-secondary: var(--color-secondary-100);
--color-secondary-foreground: var(--color-secondary-900);
/* Accent */
--color-accent: var(--color-accent-100);
--color-accent-foreground: var(--color-accent-900);
/* Destructive */
--color-destructive: var(--color-error-600);
--color-destructive-foreground: var(--color-error-50);
/* Default Border Radius */
--radius: var(--radius-md);
}
/* =================================================================
Dark Mode Override
================================================================= */
.dark {
/* Background & Foreground */
--color-background: var(--color-secondary-900);
--color-foreground: var(--color-secondary-50);
/* Muted */
--color-muted: var(--color-secondary-800);
--color-muted-foreground: var(--color-secondary-400);
/* Border & Input */
--color-border: var(--color-secondary-700);
--color-input: var(--color-secondary-800);
/* Card */
--color-card: var(--color-secondary-800);
--color-card-foreground: var(--color-secondary-50);
/* Popover */
--color-popover: var(--color-secondary-800);
--color-popover-foreground: var(--color-secondary-50);
/* Primary */
--color-primary: var(--color-primary-500);
--color-primary-foreground: var(--color-primary-950);
/* Secondary */
--color-secondary: var(--color-secondary-800);
--color-secondary-foreground: var(--color-secondary-50);
/* Accent */
--color-accent: var(--color-accent-900);
--color-accent-foreground: var(--color-accent-100);
/* Destructive */
--color-destructive: var(--color-error-900);
--color-destructive-foreground: var(--color-error-200);
/* Dark mode shadow adjustments */
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.2);
--shadow-base: 0 1px 3px 0 rgb(0 0 0 / 0.3), 0 1px 2px -1px rgb(0 0 0 / 0.2);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.3), 0 2px 4px -2px rgb(0 0 0 / 0.2);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.3), 0 4px 6px -4px rgb(0 0 0 / 0.2);
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.3), 0 8px 10px -6px rgb(0 0 0 / 0.2);
--shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / 0.5);
}
}
@layer base {
/* =================================================================
Base Element Styles
================================================================= */
* {
@apply border-border;
}
body {
@apply font-sans antialiased bg-background text-foreground;
font-feature-settings: "rlig" 1, "calt" 1;
}
/* Typography */
h1, h2, h3, h4, h5, h6 {
@apply font-semibold tracking-tight;
}
h1 { @apply text-4xl lg:text-5xl; }
h2 { @apply text-3xl lg:text-4xl; }
h3 { @apply text-2xl lg:text-3xl; }
h4 { @apply text-xl lg:text-2xl; }
h5 { @apply text-lg lg:text-xl; }
h6 { @apply text-base lg:text-lg; }
/* Links */
a {
color: var(--color-primary);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
/* =================================================================
Accessibility - Focus Indicators (WCAG 2.1 AA Compliant)
================================================================= */
/* Default focus-visible style for all interactive elements */
:focus-visible {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
}
/* Enhanced focus for buttons and interactive elements */
button:focus-visible,
[role="button"]:focus-visible,
input[type="submit"]:focus-visible,
input[type="button"]:focus-visible,
input[type="reset"]:focus-visible {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.2);
}
/* Form field focus states */
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
outline: 2px solid var(--color-primary);
outline-offset: 0;
border-color: var(--color-primary);
}
/* Link focus state */
a:focus-visible {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
border-radius: var(--radius-sm);
}
/* Focus within for composite components */
[tabindex]:focus-visible {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
}
/* =================================================================
Accessibility - Reduced Motion Support
================================================================= */
@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;
}
}
/* =================================================================
Accessibility - High Contrast Support
================================================================= */
@media (prefers-contrast: high) {
:root {
--color-border: var(--color-secondary-700);
}
.dark {
--color-border: var(--color-secondary-300);
}
button,
input,
select,
textarea {
border-width: 2px;
}
}
/* =================================================================
Accessibility - Screen Reader Utilities
================================================================= */
/* Visually hidden but accessible to screen readers */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
/* Make sr-only visible on focus (for skip links) */
.sr-only-focusable:focus,
.sr-only-focusable:focus-within {
position: static;
width: auto;
height: auto;
padding: inherit;
margin: inherit;
overflow: visible;
clip: auto;
white-space: normal;
}
/* Not screen reader only - visible to all */
.not-sr-only {
position: static;
width: auto;
height: auto;
padding: 0;
margin: 0;
overflow: visible;
clip: auto;
white-space: normal;
}
}
@layer components {
/* =================================================================
HTMX Loading States
================================================================= */
.htmx-indicator {
opacity: 0;
transition: opacity 200ms ease-in;
}
.htmx-request .htmx-indicator {
opacity: 1;
}
.htmx-request.htmx-indicator {
opacity: 1;
}
/* =================================================================
Container
================================================================= */
.container {
@apply px-4 mx-auto md:px-6 lg:px-8;
max-width: 80rem; /* 1280px */
}
.container-sm {
@apply px-4 mx-auto md:px-6;
max-width: 40rem; /* 640px */
}
.container-md {
@apply px-4 mx-auto md:px-6;
max-width: 48rem; /* 768px */
}
.container-lg {
@apply px-4 mx-auto md:px-6 lg:px-8;
max-width: 64rem; /* 1024px */
}
.container-xl {
@apply px-4 mx-auto md:px-6 lg:px-8;
max-width: 80rem; /* 1280px */
}
.container-2xl {
@apply px-4 mx-auto md:px-6 lg:px-8;
max-width: 96rem; /* 1536px */
}
}
@layer utilities {
/* =================================================================
Spacing Utilities
================================================================= */
.p-token-1 { padding: var(--spacing-1); }
.p-token-2 { padding: var(--spacing-2); }
.p-token-3 { padding: var(--spacing-3); }
.p-token-4 { padding: var(--spacing-4); }
.p-token-6 { padding: var(--spacing-6); }
.p-token-8 { padding: var(--spacing-8); }
.m-token-1 { margin: var(--spacing-1); }
.m-token-2 { margin: var(--spacing-2); }
.m-token-3 { margin: var(--spacing-3); }
.m-token-4 { margin: var(--spacing-4); }
.m-token-6 { margin: var(--spacing-6); }
.m-token-8 { margin: var(--spacing-8); }
.gap-token-1 { gap: var(--spacing-1); }
.gap-token-2 { gap: var(--spacing-2); }
.gap-token-3 { gap: var(--spacing-3); }
.gap-token-4 { gap: var(--spacing-4); }
.gap-token-6 { gap: var(--spacing-6); }
.gap-token-8 { gap: var(--spacing-8); }
/* =================================================================
Transition Utilities
================================================================= */
.transition-token-all { transition: var(--transition-all); }
.transition-token-colors { transition: var(--transition-colors); }
.transition-token-opacity { transition: var(--transition-opacity); }
.transition-token-shadow { transition: var(--transition-shadow); }
.transition-token-transform { transition: var(--transition-transform); }
.duration-token-75 { transition-duration: var(--duration-75); }
.duration-token-100 { transition-duration: var(--duration-100); }
.duration-token-150 { transition-duration: var(--duration-150); }
.duration-token-200 { transition-duration: var(--duration-200); }
.duration-token-300 { transition-duration: var(--duration-300); }
.duration-token-500 { transition-duration: var(--duration-500); }
.ease-token-linear { transition-timing-function: var(--ease-linear); }
.ease-token-in { transition-timing-function: var(--ease-in); }
.ease-token-out { transition-timing-function: var(--ease-out); }
.ease-token-in-out { transition-timing-function: var(--ease-in-out); }
.ease-token-bounce { transition-timing-function: var(--ease-bounce); }
/* =================================================================
Z-Index Utilities
================================================================= */
.z-token-0 { z-index: var(--z-0); }
.z-token-10 { z-index: var(--z-10); }
.z-token-20 { z-index: var(--z-20); }
.z-token-30 { z-index: var(--z-30); }
.z-token-40 { z-index: var(--z-40); }
.z-token-50 { z-index: var(--z-50); }
.z-token-dropdown { z-index: var(--z-dropdown); }
.z-token-sticky { z-index: var(--z-sticky); }
.z-token-fixed { z-index: var(--z-fixed); }
.z-token-modal-backdrop { z-index: var(--z-modal-backdrop); }
.z-token-modal { z-index: var(--z-modal); }
.z-token-popover { z-index: var(--z-popover); }
.z-token-tooltip { z-index: var(--z-tooltip); }
.z-token-toast { z-index: var(--z-toast); }
/* =================================================================
Shadow Utilities
================================================================= */
.shadow-token-sm { box-shadow: var(--shadow-sm); }
.shadow-token-base { box-shadow: var(--shadow-base); }
.shadow-token-md { box-shadow: var(--shadow-md); }
.shadow-token-lg { box-shadow: var(--shadow-lg); }
.shadow-token-xl { box-shadow: var(--shadow-xl); }
.shadow-token-2xl { box-shadow: var(--shadow-2xl); }
.shadow-token-inner { box-shadow: var(--shadow-inner); }
.shadow-token-none { box-shadow: var(--shadow-none); }
/* =================================================================
Border Radius Utilities
================================================================= */
.rounded-token-none { border-radius: var(--radius-none); }
.rounded-token-sm { border-radius: var(--radius-sm); }
.rounded-token-base { border-radius: var(--radius-base); }
.rounded-token-md { border-radius: var(--radius-md); }
.rounded-token-lg { border-radius: var(--radius-lg); }
.rounded-token-xl { border-radius: var(--radius-xl); }
.rounded-token-2xl { border-radius: var(--radius-2xl); }
.rounded-token-3xl { border-radius: var(--radius-3xl); }
.rounded-token-full { border-radius: var(--radius-full); }
/* =================================================================
Typography Utilities
================================================================= */
.font-token-sans { font-family: var(--font-family-sans); }
.font-token-serif { font-family: var(--font-family-serif); }
.font-token-mono { font-family: var(--font-family-mono); }
.text-token-xs { font-size: var(--font-size-xs); }
.text-token-sm { font-size: var(--font-size-sm); }
.text-token-base { font-size: var(--font-size-base); }
.text-token-lg { font-size: var(--font-size-lg); }
.text-token-xl { font-size: var(--font-size-xl); }
.text-token-2xl { font-size: var(--font-size-2xl); }
.text-token-3xl { font-size: var(--font-size-3xl); }
.text-token-4xl { font-size: var(--font-size-4xl); }
/* =================================================================
Responsive Visibility Utilities
================================================================= */
/* Hide at specific breakpoints */
@media (max-width: 639px) {
.hidden-mobile { display: none !important; }
}
@media (min-width: 640px) and (max-width: 767px) {
.hidden-sm { display: none !important; }
}
@media (min-width: 768px) and (max-width: 1023px) {
.hidden-md { display: none !important; }
}
@media (min-width: 1024px) and (max-width: 1279px) {
.hidden-lg { display: none !important; }
}
@media (min-width: 1280px) {
.hidden-xl { display: none !important; }
}
/* Show only at specific breakpoints */
.show-mobile { display: none !important; }
.show-sm { display: none !important; }
.show-md { display: none !important; }
.show-lg { display: none !important; }
.show-xl { display: none !important; }
@media (max-width: 639px) {
.show-mobile { display: block !important; }
}
@media (min-width: 640px) and (max-width: 767px) {
.show-sm { display: block !important; }
}
@media (min-width: 768px) and (max-width: 1023px) {
.show-md { display: block !important; }
}
@media (min-width: 1024px) and (max-width: 1279px) {
.show-lg { display: block !important; }
}
@media (min-width: 1280px) {
.show-xl { display: block !important; }
}
/* =================================================================
Responsive Stack/Flex Utilities
================================================================= */
/* Stack on mobile, row on larger screens */
.stack-to-row {
display: flex;
flex-direction: column;
gap: var(--spacing-4);
}
@media (min-width: 640px) {
.stack-to-row {
flex-direction: row;
}
}
/* Stack on mobile/tablet, row on desktop */
.stack-to-row-lg {
display: flex;
flex-direction: column;
gap: var(--spacing-4);
}
@media (min-width: 1024px) {
.stack-to-row-lg {
flex-direction: row;
}
}
/* =================================================================
Responsive Grid Utilities
================================================================= */
/* Auto-fit grid that adapts to content */
.grid-auto-fit {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
gap: var(--spacing-6);
}
.grid-auto-fit-sm {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
gap: var(--spacing-4);
}
.grid-auto-fit-lg {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 400px), 1fr));
gap: var(--spacing-8);
}
/* Responsive column grids */
.grid-responsive-2 {
display: grid;
grid-template-columns: 1fr;
gap: var(--spacing-4);
}
@media (min-width: 640px) {
.grid-responsive-2 {
grid-template-columns: repeat(2, 1fr);
}
}
.grid-responsive-3 {
display: grid;
grid-template-columns: 1fr;
gap: var(--spacing-4);
}
@media (min-width: 640px) {
.grid-responsive-3 {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 1024px) {
.grid-responsive-3 {
grid-template-columns: repeat(3, 1fr);
}
}
.grid-responsive-4 {
display: grid;
grid-template-columns: 1fr;
gap: var(--spacing-4);
}
@media (min-width: 640px) {
.grid-responsive-4 {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 1024px) {
.grid-responsive-4 {
grid-template-columns: repeat(4, 1fr);
}
}
/* =================================================================
Responsive Text Size Utilities
================================================================= */
.text-responsive-sm {
font-size: var(--font-size-sm);
}
@media (min-width: 1024px) {
.text-responsive-sm {
font-size: var(--font-size-base);
}
}
.text-responsive-base {
font-size: var(--font-size-base);
}
@media (min-width: 1024px) {
.text-responsive-base {
font-size: var(--font-size-lg);
}
}
.text-responsive-lg {
font-size: var(--font-size-lg);
}
@media (min-width: 1024px) {
.text-responsive-lg {
font-size: var(--font-size-xl);
}
}
.text-responsive-xl {
font-size: var(--font-size-xl);
}
@media (min-width: 1024px) {
.text-responsive-xl {
font-size: var(--font-size-2xl);
}
}
.text-responsive-2xl {
font-size: var(--font-size-2xl);
}
@media (min-width: 1024px) {
.text-responsive-2xl {
font-size: var(--font-size-3xl);
}
}
/* =================================================================
Responsive Spacing Utilities
================================================================= */
.py-responsive {
padding-top: var(--spacing-4);
padding-bottom: var(--spacing-4);
}
@media (min-width: 640px) {
.py-responsive {
padding-top: var(--spacing-6);
padding-bottom: var(--spacing-6);
}
}
@media (min-width: 1024px) {
.py-responsive {
padding-top: var(--spacing-8);
padding-bottom: var(--spacing-8);
}
}
.px-responsive {
padding-left: var(--spacing-4);
padding-right: var(--spacing-4);
}
@media (min-width: 640px) {
.px-responsive {
padding-left: var(--spacing-6);
padding-right: var(--spacing-6);
}
}
@media (min-width: 1024px) {
.px-responsive {
padding-left: var(--spacing-8);
padding-right: var(--spacing-8);
}
}
.gap-responsive {
gap: var(--spacing-4);
}
@media (min-width: 640px) {
.gap-responsive {
gap: var(--spacing-6);
}
}
@media (min-width: 1024px) {
.gap-responsive {
gap: var(--spacing-8);
}
}
/* =================================================================
Accessibility Utilities
================================================================= */
/* Focus ring utilities */
.focus-ring {
outline: 2px solid transparent;
outline-offset: 2px;
}
.focus-ring:focus-visible {
outline: 2px solid var(--color-primary);
}
.focus-ring-inset:focus-visible {
outline: 2px solid var(--color-primary);
outline-offset: -2px;
}
/* Skip link styling */
.skip-link {
position: absolute;
top: -100%;
left: 0;
padding: var(--spacing-2) var(--spacing-4);
background: var(--color-primary);
color: var(--color-primary-foreground);
z-index: var(--z-toast);
transition: top 0.2s;
border-radius: 0 0 var(--radius-md) 0;
}
.skip-link:focus {
top: 0;
outline: none;
}
/* Disable outline when not using keyboard */
[data-focus-visible-added] {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
}
/* Improve touch target size for accessibility (minimum 44x44px) */
.touch-target {
min-width: 44px;
min-height: 44px;
display: inline-flex;
align-items: center;
justify-content: center;
}
/* Color contrast utilities */
.text-high-contrast {
color: var(--color-foreground);
}
.bg-high-contrast {
background-color: var(--color-background);
}
/* Announcement region for screen readers */
.aria-live-region {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* Make element focusable for keyboard users */
.focusable {
tabindex: 0;
}
.focusable:focus-visible {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
}
/* Interactive state indicators */
.interactive {
cursor: pointer;
user-select: none;
}
.interactive:hover {
opacity: 0.9;
}
.interactive:active {
transform: scale(0.98);
}
/* Disabled state */
.disabled,
[disabled],
[aria-disabled="true"] {
opacity: 0.5;
pointer-events: none;
cursor: not-allowed;
}
/* Loading state - reduces motion for those who prefer it */
.loading {
position: relative;
pointer-events: none;
}
.loading::after {
content: '';
position: absolute;
inset: 0;
background: rgba(255, 255, 255, 0.5);
}
@media (prefers-reduced-motion: no-preference) {
.loading::after {
animation: pulse 1.5s ease-in-out infinite;
}
}
@keyframes pulse {
0%, 100% {
opacity: 0.5;
}
50% {
opacity: 0.3;
}
}
}