/* External @imports must come first per CSS spec. */ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&display=swap'); @import "tailwindcss"; @import "tw-animate-css"; /* ============================================================================ THEME SYSTEM ---------------------------------------------------------------------------- Every color is a semantic CSS variable declared per theme below. The `@theme inline` block points Tailwind's color utilities (bg-*, text-*, border-*, ring-*, …) directly at those variables, so switching the `data-theme` attribute on reskins the whole UI at runtime with no rebuild. Four themes ship: two light-neutral surfaces and status families for OK / warning / caution / danger / info that adapt to each surface. Semantic status vocabulary (use these, NOT raw palette colors): success — worked / confirmed / data / OK (was emerald) warning — new-band / attention (was amber) caution — new-mode / new-slot / lighter alert (was yellow) danger — new / split / negative (was rose) info — informational (was sky/blue) destructive — hard errors / live REC / delete (was red) Each family has: base (dots/bars/solid), -foreground (text on base), -muted (soft pill fill), -muted-foreground (text on pill), -border. ========================================================================= */ /* ---- Theme 1: Warm light (default) — warm taupe & burnt orange ---------- */ :root, [data-theme="light-warm"] { --background: #e8dfc9; /* warm taupe — deeper than cream */ --foreground: #1c1917; /* stone-900 */ --card: #faf6ea; /* lifted off-white cream */ --card-foreground: #1c1917; --popover: #faf6ea; --popover-foreground: #1c1917; --primary: #b8410c; /* burnt orange, slightly deeper */ --primary-foreground: #fff7ed; --secondary: #ddd2b8; --secondary-foreground: #1c1917; --muted: #ddd2b8; /* toolbars / table headers */ --muted-foreground: #44403c; /* stone-700 — readable on muted */ --accent: #f8d6a9; /* warm amber-cream */ --accent-foreground: #7c2d12; /* orange-900 */ --destructive: #a51c1c; --destructive-foreground: #ffffff; --destructive-muted: #fef2f2; --destructive-muted-foreground: #b91c1c; --border: #c8b994; /* deeper warm beige border */ --input: #c8b994; --ring: #d97706; /* amber-600 focus ring */ --success: #16a34a; --success-foreground: #ffffff; --success-muted: #dcfce7; --success-muted-foreground: #166534; --success-border: #86efac; --warning: #d97706; --warning-foreground: #ffffff; --warning-muted: #fef3c7; --warning-muted-foreground: #92400e; --warning-border: #fcd34d; --caution: #ca8a04; --caution-foreground: #1c1917; --caution-muted: #fef9c3; --caution-muted-foreground: #854d0e; --caution-border: #fde047; --danger: #e11d48; --danger-foreground: #ffffff; --danger-muted: #ffe4e6; --danger-muted-foreground: #9f1239; --danger-border: #fda4af; --info: #0284c7; --info-foreground: #ffffff; --info-muted: #e0f2fe; --info-muted-foreground: #075985; --info-border: #7dd3fc; /* Band/mode matrix (BandSlotGrid) — original emerald/indigo/stone ramp. */ --mx-call-conf: #15803d; /* call confirmed */ --mx-call-work: #6ee7b7; /* call worked */ --mx-dx-conf: #3730a3; /* entity confirmed*/ --mx-dx-work: #a5b4fc; /* entity worked */ --mx-none: #e7e5e4; /* never worked */ --scrollbar-thumb: #b8a880; --scrollbar-thumb-hover: #968455; --card-shadow: 0 1px 2px rgba(28, 25, 23, 0.05), 0 0 0 1px rgba(28, 25, 23, 0.02); color-scheme: light; } /* ---- Theme 2: Warm dark (espresso) — same soul, night mode ------------- */ [data-theme="dark-warm"] { --background: #221d18; --foreground: #ede6d8; --card: #2e2820; --card-foreground: #ede6d8; --popover: #2e2820; --popover-foreground: #ede6d8; --primary: #e07a2e; /* brighter burnt orange for dark */ --primary-foreground: #1a1512; --secondary: #3a3229; --secondary-foreground: #ede6d8; --muted: #352e26; --muted-foreground: #bcae9a; --accent: #4a3a28; --accent-foreground: #f8d6a9; --destructive: #e5484d; --destructive-foreground: #1a1512; --destructive-muted: #3a1414; --destructive-muted-foreground: #fca5a5; --border: #473e33; --input: #473e33; --ring: #e8853a; --success: #34d399; --success-foreground: #0e2a20; --success-muted: #123024; --success-muted-foreground: #6ee7b7; --success-border: #1e5540; --warning: #fbbf24; --warning-foreground: #2a1f08; --warning-muted: #3a2e10; --warning-muted-foreground: #fcd34d; --warning-border: #5c4a18; --caution: #facc15; --caution-foreground: #2a2607; --caution-muted: #38330f; --caution-muted-foreground: #fde047; --caution-border: #574f18; --danger: #fb7185; --danger-foreground: #2a0d13; --danger-muted: #3a1720; --danger-muted-foreground: #fda4af; --danger-border: #5c2530; --info: #38bdf8; --info-foreground: #08222e; --info-muted: #0c2a3a; --info-muted-foreground: #7dd3fc; --info-border: #164a5c; /* Matrix: bright confirmed, medium-solid worked (clearly visible on dark), warm-gray not-worked lifted off the card. */ --mx-call-conf: #22c55e; --mx-call-work: #2f7d55; --mx-dx-conf: #6366f1; --mx-dx-work: #3f3f8a; --mx-none: #453d33; --scrollbar-thumb: #5c5044; --scrollbar-thumb-hover: #7a6a58; --card-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 0 0 1px rgba(255, 240, 220, 0.04); color-scheme: dark; } /* ---- Theme 3: Graphite dark — cool slate, technical look --------------- */ [data-theme="dark-graphite"] { --background: #16181d; --foreground: #e6e8ec; --card: #1f232b; --card-foreground: #e6e8ec; --popover: #1f232b; --popover-foreground: #e6e8ec; --primary: #f97316; /* orange-500 pops on slate */ --primary-foreground: #0a0c10; --secondary: #272c35; --secondary-foreground: #e6e8ec; --muted: #232830; --muted-foreground: #9aa2b1; --accent: #2a3240; --accent-foreground: #cbd5e5; --destructive: #ef4444; --destructive-foreground: #0a0c10; --destructive-muted: #331414; --destructive-muted-foreground: #fca5a5; --border: #2e343f; --input: #2e343f; --ring: #fb8c3c; --success: #34d399; --success-foreground: #06231a; --success-muted: #0f2e26; --success-muted-foreground: #6ee7b7; --success-border: #17513f; --warning: #fbbf24; --warning-foreground: #241a06; --warning-muted: #33290f; --warning-muted-foreground: #fcd34d; --warning-border: #4f3f16; --caution: #facc15; --caution-foreground: #242006; --caution-muted: #322e0e; --caution-muted-foreground: #fde047; --caution-border: #4c4416; --danger: #fb7185; --danger-foreground: #260a11; --danger-muted: #34141d; --danger-muted-foreground: #fda4af; --danger-border: #532430; --info: #38bdf8; --info-foreground: #061f2b; --info-muted: #0b2938; --info-muted-foreground: #7dd3fc; --info-border: #124659; /* Matrix: bright confirmed, medium-solid worked, cool-gray not-worked. */ --mx-call-conf: #22c55e; --mx-call-work: #2f7d55; --mx-dx-conf: #6366f1; --mx-dx-work: #3f3f8a; --mx-none: #333a45; --scrollbar-thumb: #3a4150; --scrollbar-thumb-hover: #4e5768; --card-shadow: 0 1px 2px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(230, 232, 236, 0.04); color-scheme: dark; } /* ---- Theme 4: High contrast — pure black / white, max legibility ------- */ [data-theme="high-contrast"] { --background: #000000; --foreground: #ffffff; --card: #0d0d0d; --card-foreground: #ffffff; --popover: #0d0d0d; --popover-foreground: #ffffff; --primary: #ff7a1a; --primary-foreground: #000000; --secondary: #1a1a1a; --secondary-foreground: #ffffff; --muted: #141414; --muted-foreground: #d4d4d4; --accent: #262626; --accent-foreground: #ffffff; --destructive: #ff4d4d; --destructive-foreground: #000000; --destructive-muted: #2a0808; --destructive-muted-foreground: #ff9999; --border: #3f3f3f; --input: #3f3f3f; --ring: #ffab5e; --success: #22e37a; --success-foreground: #002313; --success-muted: #06231a; --success-muted-foreground: #6affb0; --success-border: #0f6b4a; --warning: #ffcc33; --warning-foreground: #201900; --warning-muted: #2a2205; --warning-muted-foreground: #ffe08a; --warning-border: #6b5510; --caution: #ffe14d; --caution-foreground: #201d00; --caution-muted: #2a2705; --caution-muted-foreground: #fff08a; --caution-border: #6b6210; --danger: #ff6b7d; --danger-foreground: #23000a; --danger-muted: #2a0a12; --danger-muted-foreground: #ffb3bd; --danger-border: #6b1f2c; --info: #4dc4ff; --info-foreground: #001a26; --info-muted: #052330; --info-muted-foreground: #a3e0ff; --info-border: #0f5a6b; /* Matrix: max-contrast ramp on pure black. */ --mx-call-conf: #2ee87f; --mx-call-work: #17a85a; --mx-dx-conf: #7d97ff; --mx-dx-work: #3646b0; --mx-none: #3a3a3a; --scrollbar-thumb: #4a4a4a; --scrollbar-thumb-hover: #666666; --card-shadow: 0 0 0 1px rgba(255, 255, 255, 0.12); color-scheme: dark; } /* Map Tailwind's color utilities onto the semantic vars above. `inline` makes the generated utilities reference var(--…) directly, so overriding a var in a [data-theme] block re-skins every utility at runtime. */ @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); --color-card: var(--card); --color-card-foreground: var(--card-foreground); --color-popover: var(--popover); --color-popover-foreground: var(--popover-foreground); --color-primary: var(--primary); --color-primary-foreground: var(--primary-foreground); --color-secondary: var(--secondary); --color-secondary-foreground: var(--secondary-foreground); --color-muted: var(--muted); --color-muted-foreground: var(--muted-foreground); --color-accent: var(--accent); --color-accent-foreground: var(--accent-foreground); --color-destructive: var(--destructive); --color-destructive-foreground: var(--destructive-foreground); --color-destructive-muted: var(--destructive-muted); --color-destructive-muted-foreground: var(--destructive-muted-foreground); --color-border: var(--border); --color-input: var(--input); --color-ring: var(--ring); --color-success: var(--success); --color-success-foreground: var(--success-foreground); --color-success-muted: var(--success-muted); --color-success-muted-foreground: var(--success-muted-foreground); --color-success-border: var(--success-border); --color-warning: var(--warning); --color-warning-foreground: var(--warning-foreground); --color-warning-muted: var(--warning-muted); --color-warning-muted-foreground: var(--warning-muted-foreground); --color-warning-border: var(--warning-border); --color-caution: var(--caution); --color-caution-foreground: var(--caution-foreground); --color-caution-muted: var(--caution-muted); --color-caution-muted-foreground: var(--caution-muted-foreground); --color-caution-border: var(--caution-border); --color-danger: var(--danger); --color-danger-foreground: var(--danger-foreground); --color-danger-muted: var(--danger-muted); --color-danger-muted-foreground: var(--danger-muted-foreground); --color-danger-border: var(--danger-border); --color-info: var(--info); --color-info-foreground: var(--info-foreground); --color-info-muted: var(--info-muted); --color-info-muted-foreground: var(--info-muted-foreground); --color-info-border: var(--info-border); --color-mx-call-conf: var(--mx-call-conf); --color-mx-call-work: var(--mx-call-work); --color-mx-dx-conf: var(--mx-dx-conf); --color-mx-dx-work: var(--mx-dx-work); --color-mx-none: var(--mx-none); --radius: 0.5rem; --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; --font-mono: 'JetBrains Mono', 'Cascadia Mono', Consolas, 'Courier New', monospace; } @layer base { * { @apply border-border; } html, body, #root { height: 100%; } /* Root rem base. Tailwind sizing (text/heights/padding/gaps) is in rem, so this is the single global density knob — shrinks the whole UI uniformly while Leaflet maps (px-based) stay correct. Default browser base is 16px. */ html { font-size: 13px; } body { @apply bg-background text-foreground; font-family: var(--font-sans); font-size: 0.95rem; line-height: 1.4; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; } } /* Subtle elevation on every Card-styled surface so cards visibly sit on top of the background — paper-on-paper feel, tuned per theme. */ .bg-card { box-shadow: var(--card-shadow); } /* Scrollbar tuned to each theme's surface */ ::-webkit-scrollbar { width: 10px; height: 10px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); border-radius: 5px; border: 2px solid var(--background); } ::-webkit-scrollbar-thumb:hover { background: var(--scrollbar-thumb-hover); }