@import "tailwindcss"; /* Drive the `dark:` variant off the same data-theme attribute the toggle sets, instead of Tailwind's default prefers-color-scheme. Without this a stray `dark:` utility would disagree with an explicit light/dark choice. */ @custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *)); @theme { /* ── Fonts ───────────────────────────────────────────────────────────── */ --font-body: "IBM Plex Sans", system-ui, sans-serif; --font-data: "IBM Plex Mono", monospace; /* ── Surfaces ────────────────────────────────────────────────────────── */ --color-background: #F7F4EE; --color-sidebar: #F2EEE6; --color-card: #FDFBF7; --color-fields: #F4F0E8; --color-dropzone: #F9F6EF; /* Letterbox behind video. Dark in both themes — it is a cinema surface, not an ink colour — so `text-on-dark` always reads on top of it. */ --color-media-backdrop: #2B2620; /* ── Ink ─────────────────────────────────────────────────────────────── */ --color-text-primary: #2B2620; --color-text-strong: #35302A; --color-text-body: #554D44; --color-text-secondary: #6E6559; --color-muted: #9A9084; --color-faint-mono: #A79C8E; /* ── Accents ─────────────────────────────────────────────────────────── */ --color-terracotta: #A85A38; --color-terracotta-hover: #94492A; --color-terracotta-light: #C87A52; --color-terracotta-disabled: #C9AE9C; --color-olive: #6E7A50; /* ── Status ──────────────────────────────────────────────────────────── */ --color-live: #B5432E; --color-error: #B5432E; /* ── Ink on dark / accent surfaces ───────────────────────────────────── */ --color-on-dark: #FBF8F2; --color-on-accent: #FDFBF7; /* ── Lines, chips, placeholders ──────────────────────────────────────── */ --color-hairline: #F0EBE2; --color-hover: #E7E0D2; --color-selected: #F6EFE6; --color-ring: #E2DACB; --color-inactive: #DED7CA; --color-inactive-strong: #C4BAA9; } /* Dark mode. Only token values change here: every component already styles itself with the semantic utilities above, so the whole UI follows from this one block. `--color-on-dark` is deliberately absent — it is the ink on the media backdrop, which stays dark in both themes. */ :root[data-theme="dark"] { color-scheme: dark; /* ── Surfaces ── near-black canvas, neutral cards lifting off it ─────── */ --color-background: #0E0E10; --color-sidebar: #09090B; --color-card: #17171A; --color-fields: #121215; --color-dropzone: #141417; --color-media-backdrop: #000000; /* ── Ink ─────────────────────────────────────────────────────────────── */ --color-text-primary: #F4F4F5; --color-text-strong: #E3E3E7; --color-text-body: #BFBFC6; --color-text-secondary: #94949D; --color-muted: #76767F; --color-faint-mono: #6A6A73; /* ── Accents ── brightened to carry on a dark canvas, so hover now lifts rather than deepens ─────────────────────────────────────────────────── */ --color-terracotta: #E07A4C; --color-terracotta-hover: #F08F62; --color-terracotta-light: #F0A177; --color-terracotta-disabled: #5E463A; --color-olive: #A3B678; /* ── Status ──────────────────────────────────────────────────────────── */ --color-live: #F2604A; --color-error: #F2604A; /* ── Ink on accent surfaces ── the accents are light here, so the ink that sits on them flips dark ─────────────────────────────────────────────── */ --color-on-accent: #17100B; /* ── Lines, chips, placeholders ──────────────────────────────────────── */ --color-hairline: #232327; --color-hover: #26262B; --color-selected: #2A1F18; --color-ring: #33333A; --color-inactive: #2C2C32; --color-inactive-strong: #55555E; } :root { font-family: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; line-height: 1.5; font-weight: 400; font-synthesis: none; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; color-scheme: light; } body { background-color: var(--color-background); font-family: "IBM Plex Sans", system-ui, sans-serif; color: var(--color-text-body); } @utility font-heading { font-family: "Newsreader", serif; font-weight: 400; color: var(--color-text-primary); } /* Google Identity Services renders its sign-in button in a cross-origin iframe whose document is light-scheme with a transparent background. Left to inherit our `color-scheme: dark`, Chrome cannot honour dark there and paints an opaque white canvas behind it instead — framing the pill in a white box on every dark page. Pinning the iframe back to light keeps it transparent; the button's own colours come from the `theme` prop in Topbar.tsx. */ iframe[src*="accounts.google.com/gsi/"] { color-scheme: light; } /* Clip trim slider (react-range-slider-input). Its own stylesheet ships blue defaults; the #id beats those class selectors regardless of import order. */ #range-slider { height: 8px; background: var(--color-fields); border-radius: 8px; } #range-slider .range-slider__range { background: var(--color-terracotta-light); } #range-slider .range-slider__thumb { width: 18px; height: 18px; background: var(--color-terracotta); box-shadow: 0 1px 2px rgba(90, 40, 20, 0.2); } #range-slider .range-slider__thumb:focus-visible { box-shadow: 0 0 0 4px color-mix(in oklab, var(--color-terracotta) 35%, transparent); }