160 lines
6.8 KiB
CSS
160 lines
6.8 KiB
CSS
@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);
|
|
}
|