@tailwind base; @tailwind components; @tailwind utilities; /* ─── Accent Color CSS Variables ──────────────────────────────────────────── Each data-accent value sets the --accent-* RGB triplets consumed by Tailwind brand-* classes. The format is "R G B" (no commas) for Tailwind opacity support. */ /* Sky Blue (default) */ :root, [data-accent="sky"] { --accent-50: 240 249 255; --accent-100: 224 242 254; --accent-200: 186 230 253; --accent-300: 125 211 252; --accent-400: 56 189 248; --accent-500: 14 165 233; --accent-600: 2 132 199; --accent-700: 3 105 161; --accent-800: 7 89 133; --accent-900: 12 74 110; } [data-accent="indigo"] { --accent-50: 238 242 255; --accent-100: 224 231 255; --accent-200: 199 210 254; --accent-300: 165 180 252; --accent-400: 129 140 248; --accent-500: 99 102 241; --accent-600: 79 70 229; --accent-700: 67 56 202; --accent-800: 55 48 163; --accent-900: 49 46 129; } [data-accent="violet"] { --accent-50: 245 243 255; --accent-100: 237 233 254; --accent-200: 221 214 254; --accent-300: 196 181 253; --accent-400: 167 139 250; --accent-500: 139 92 246; --accent-600: 124 58 237; --accent-700: 109 40 217; --accent-800: 91 33 182; --accent-900: 76 29 149; } [data-accent="emerald"] { --accent-50: 236 253 245; --accent-100: 209 250 229; --accent-200: 167 243 208; --accent-300: 110 231 183; --accent-400: 52 211 153; --accent-500: 16 185 129; --accent-600: 5 150 105; --accent-700: 4 120 87; --accent-800: 6 95 70; --accent-900: 6 78 59; } [data-accent="rose"] { --accent-50: 255 241 242; --accent-100: 255 228 230; --accent-200: 254 205 211; --accent-300: 253 164 175; --accent-400: 251 113 133; --accent-500: 244 63 94; --accent-600: 225 29 72; --accent-700: 190 18 60; --accent-800: 159 18 57; --accent-900: 136 19 55; } [data-accent="amber"] { --accent-50: 255 251 235; --accent-100: 254 243 199; --accent-200: 253 230 138; --accent-300: 252 211 77; --accent-400: 251 191 36; --accent-500: 245 158 11; --accent-600: 217 119 6; --accent-700: 180 83 9; --accent-800: 146 64 14; --accent-900: 120 53 15; } /* ─── Light Theme Surface Variables ─────────────────────────────────────── */ :root { --surface-page: 246 247 251; --surface-card: 255 255 255; --surface-elevated: 249 250 252; --surface-input: 255 255 255; --border-subtle: 219 224 232; --border-input: 197 205 218; --text-primary: 18 24 38; --text-secondary: 71 85 105; --text-muted: 100 116 139; --text-very-muted: 148 163 184; --shadow-soft: 15 23 42 / 0.05; --shadow-strong: 15 23 42 / 0.12; } /* ─── Dark Theme Surface Variables ──────────────────────────────────────── */ .dark { color-scheme: dark; --surface-page: 12 17 29; --surface-card: 16 23 38; --surface-elevated: 24 33 52; --surface-input: 18 28 45; --border-subtle: 41 55 78; --border-input: 61 79 110; --text-primary: 237 242 247; --text-secondary: 196 207 223; --text-muted: 147 161 185; --text-very-muted: 118 133 161; --shadow-soft: 2 6 23 / 0.38; --shadow-strong: 2 6 23 / 0.65; } /* ─── Base Layer: Apply variables to body ────────────────────────────────── */ @layer base { body { background-color: rgb(var(--surface-page)); color: rgb(var(--text-primary)); transition: background-color 0.15s ease, color 0.15s ease; background-image: radial-gradient(ellipse at 0% 0%, rgb(var(--accent-50) / 0.15), transparent 50%), radial-gradient(ellipse at 100% 100%, rgb(var(--accent-100) / 0.08), transparent 50%), radial-gradient(circle at top left, rgb(var(--accent-100) / 0.32), transparent 24rem), linear-gradient(180deg, rgb(255 255 255 / 0.72), transparent 24rem); text-rendering: optimizeLegibility; } .dark body { background-image: radial-gradient(circle at top left, rgb(var(--accent-600) / 0.16), transparent 26rem), linear-gradient(180deg, rgb(15 23 42 / 0.35), transparent 28rem); } h1, h2, h3, h4, [data-page-title="true"] { font-family: var(--font-display), system-ui, sans-serif; letter-spacing: -0.025em; } /* Smooth transition for theme changes */ *, *::before, *::after { transition-property: background-color, border-color, color; transition-duration: 0.1s; transition-timing-function: ease; } input, select, textarea, button { font: inherit; } :focus-visible { outline: 2px solid rgb(var(--accent-500)); outline-offset: 2px; border-radius: inherit; } button:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 2px solid rgb(var(--accent-500)); outline-offset: 2px; box-shadow: 0 0 0 3px rgb(var(--accent-500) / 0.12); } /* Scrollbar styling for dark mode */ .dark ::-webkit-scrollbar { width: 8px; height: 8px; } .dark ::-webkit-scrollbar-track { background: rgb(var(--surface-card)); } .dark ::-webkit-scrollbar-thumb { background: rgb(var(--border-subtle)); border-radius: 4px; } } /* ─── Dark Mode Overrides for Common Tailwind Patterns ──────────────────── */ /* These override the most commonly used utility classes in the app */ .dark .bg-white { background-color: rgb(var(--surface-card)) !important; } .bg-white { box-shadow: 0 18px 42px -28px rgb(var(--shadow-strong)); } .dark .bg-gray-50 { background-color: rgb(var(--surface-elevated)) !important; } .dark .bg-gray-100 { background-color: rgb(45 51 71) !important; } .dark .border-gray-100 { border-color: rgb(var(--border-subtle)) !important; } .dark .border-gray-200 { border-color: rgb(var(--border-subtle)) !important; } .dark .border-gray-300 { border-color: rgb(var(--border-input)) !important; } .dark .text-gray-900 { color: rgb(var(--text-primary)) !important; } .dark .text-gray-800 { color: rgb(var(--text-primary)) !important; } .dark .text-gray-700 { color: rgb(var(--text-secondary)) !important; } .dark .text-gray-600 { color: rgb(var(--text-secondary)) !important; } .dark .text-gray-500 { color: rgb(var(--text-muted)) !important; } .dark .text-gray-400 { color: rgb(var(--text-very-muted)) !important; } .text-gray-900 { color: rgb(var(--text-primary)) !important; } .text-gray-800, .text-gray-700 { color: rgb(var(--text-secondary)) !important; } .text-gray-600, .text-gray-500 { color: rgb(var(--text-muted)) !important; } .text-gray-400 { color: rgb(var(--text-very-muted)) !important; } .border-gray-200 { border-color: rgb(var(--border-subtle)) !important; } .border-gray-300 { border-color: rgb(var(--border-input)) !important; } .dark input, .dark select, .dark textarea { background-color: rgb(var(--surface-input)); border-color: rgb(var(--border-input)); color: rgb(var(--text-primary)); } .dark input::placeholder, .dark textarea::placeholder { color: rgb(var(--text-muted)); } /* Table alternating / hover */ .dark .hover\:bg-gray-50:hover { background-color: rgb(var(--surface-elevated)) !important; } .dark .divide-gray-100 > * + * { border-color: rgb(var(--border-subtle)) !important; } /* Status badge adjustments in dark mode - keep them readable */ .dark .bg-green-100 { background-color: rgb(6 78 59 / 0.4) !important; } .dark .text-green-700 { color: rgb(52 211 153) !important; } .dark .bg-yellow-100 { background-color: rgb(120 53 15 / 0.4) !important; } .dark .text-yellow-700 { color: rgb(251 191 36) !important; } .dark .bg-blue-100 { background-color: rgb(30 58 138 / 0.4) !important; } .dark .text-blue-700 { color: rgb(96 165 250) !important; } .dark .bg-red-100 { background-color: rgb(127 29 29 / 0.4) !important; } .dark .text-red-600 { color: rgb(248 113 113) !important; } .dark .text-red-700 { color: rgb(248 113 113) !important; } .dark .bg-gray-100 { background-color: rgb(var(--surface-elevated)) !important; } .dark .text-gray-700 { color: rgb(var(--text-secondary)) !important; } .dark .bg-purple-100 { background-color: rgb(76 29 149 / 0.4) !important; } .dark .text-purple-700 { color: rgb(196 181 253) !important; } .dark .bg-amber-50 { background-color: rgb(120 53 15) !important; } /* Modal / overlay */ .dark .shadow-2xl { box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.6) !important; } @layer components { .app-surface { @apply rounded-2xl border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-900/90; --tw-shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 4px 12px rgba(0, 0, 0, 0.03); box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } :is(.dark) .app-surface { --tw-shadow: 0 1px 3px rgba(0, 0, 0, 0.2), 0 4px 12px rgba(0, 0, 0, 0.15); } .app-surface-strong { @apply rounded-3xl border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-900; --tw-shadow: 0 2px 8px rgba(0, 0, 0, 0.06), 0 8px 24px rgba(0, 0, 0, 0.04); box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } :is(.dark) .app-surface-strong { --tw-shadow: 0 2px 8px rgba(0, 0, 0, 0.3), 0 8px 24px rgba(0, 0, 0, 0.2); } .app-toolbar { @apply sticky top-0 z-10 rounded-2xl border border-gray-200 bg-white/80 p-4 shadow-sm backdrop-blur-sm; @apply dark:border-gray-700 dark:bg-gray-900/80 dark:shadow-black/20; } .app-input { @apply w-full rounded-xl border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 outline-none transition; @apply focus:border-brand-500 focus:ring-4 focus:ring-brand-100/80; @apply dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100 dark:focus:ring-brand-900/50; } .app-select { @apply rounded-xl border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 outline-none transition; @apply focus:border-brand-500 focus:ring-4 focus:ring-brand-100/80; @apply dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100 dark:focus:ring-brand-900/50; } .app-label { @apply mb-1.5 block text-[11px] font-semibold uppercase tracking-[0.18em] text-gray-500 dark:text-gray-400; } .app-page { @apply p-6 md:p-8; } .app-page-header { @apply flex flex-col gap-2 md:flex-row md:items-end md:justify-between; } .app-page-title { @apply font-display text-3xl font-semibold text-gray-900 dark:text-gray-100; } .app-page-subtitle { @apply text-sm text-gray-500 dark:text-gray-400; } .app-data-table { @apply overflow-hidden rounded-2xl border border-gray-200 bg-white shadow-sm dark:border-gray-700 dark:bg-gray-900/95; } .app-data-table table { @apply min-w-full text-sm; } .app-data-table thead tr { @apply bg-gray-50/90 dark:bg-gray-800/80; } .app-data-table th { @apply text-[11px] font-semibold uppercase tracking-[0.16em] text-gray-500 dark:text-gray-400; } } /* ─── Timeline utilities (unchanged) ────────────────────────────────────── */ @layer utilities { .timeline-row { @apply flex border-b border-gray-100 hover:bg-gray-50/50; min-height: 48px; } .allocation-block { @apply absolute rounded-md text-xs font-medium px-2 py-1 cursor-pointer select-none; transition: transform 0.1s ease-out, box-shadow 0.1s ease-out, opacity 0.15s ease-in-out; } .allocation-block:hover { @apply ring-2 ring-white ring-offset-1 shadow-md; transform: scale(1.02); } .allocation-block.dragging { @apply opacity-75 shadow-lg scale-105; } } /* ─── Overbooking blink animation ──────────────────────────────────────────── */ @keyframes overbooking-blink { 0%, 100% { background-color: rgba(239, 68, 68, 0); } 50% { background-color: rgba(239, 68, 68, 0.18); } } .dark .animate-overbooking-blink { animation: overbooking-blink-dark 2s ease-in-out infinite; } @keyframes overbooking-blink-dark { 0%, 100% { background-color: rgba(239, 68, 68, 0); } 50% { background-color: rgba(239, 68, 68, 0.25); } } .animate-overbooking-blink { animation: overbooking-blink 2s ease-in-out infinite; } /* ─── Shimmer skeleton animation ─────────────────────────────────────────── */ @keyframes shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } } .shimmer-skeleton { background: linear-gradient( 90deg, var(--surface-card) 25%, color-mix(in srgb, var(--text-very-muted) 8%, var(--surface-card)) 50%, var(--surface-card) 75% ); background-size: 200% 100%; animation: shimmer 1.8s ease-in-out infinite; } /* ─── Table row stagger entrance ─────────────────────────────────────────── */ @keyframes fadeSlideIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } } .animate-row-enter { animation: fadeSlideIn 0.25s ease-out both; } /* ─── Subtle hover lift for cards and table rows ─────────────────────────── */ .hover-lift { transition: transform 0.15s ease-out, box-shadow 0.15s ease-out; } .hover-lift:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06); } :is(.dark) .hover-lift:hover { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25); } /* ─── Smooth scroll + reduced-motion accessibility ────────────────────────── */ html { scroll-behavior: smooth; } @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } } /* ─── Table row hover accent border ──────────────────────────────────────── */ .table-row-hover { border-left: 2px solid transparent; transition: border-color 0.15s ease-out, background-color 0.15s ease-out, transform 0.15s ease-out, box-shadow 0.15s ease-out; } .table-row-hover:hover { border-left-color: rgb(var(--accent-400)); } /* ─── Animated underline for action links ─────────────────────────────────── */ .link-hover-underline { position: relative; } .link-hover-underline::after { content: ''; position: absolute; bottom: -1px; left: 0; width: 0; height: 1px; background: currentColor; transition: width 0.2s ease-out; } .link-hover-underline:hover::after { width: 100%; }