/*
 * Core Purpose design tokens: the one place a colour, a font, a space or a rule is defined.
 *
 * Consolidated from:
 *   - corePurpose.Tech/frontend/src/index.css   the HSL triplets (shadcn names, so a Tailwind
 *                                                config can keep writing hsl(var(--x)))
 *   - minutes/frontend/src/styles/tokens.css     copper signal, hairlines, surfaces, spacing,
 *                                                and the semantic aliases components use
 *
 * Components use the semantic aliases (--bg, --fg, --hairline, --signal, ...), never the raw
 * triplets and never a literal colour.
 *
 * Dark mode is reachable three ways, because the products already use all three:
 *   <html data-theme="dark">                 minutes, grand-total
 *   <html class="dark">                      corePurpose.Tech (Tailwind darkMode: ["class"])
 *   neither, with the OS set to dark         unless data-theme="light" or class="light" says no
 * The dark block is written twice (selector and media query). scripts/check-tokens.mjs fails
 * the build if the two copies drift apart.
 */

:root {
  color-scheme: light;

  /* --- Raw HSL triplets (from the Core Purpose site) --- */
  --background: 0 0% 100%;
  --foreground: 0 0% 0%;
  --card: 0 0% 100%;
  --card-foreground: 0 0% 0%;
  --popover: 0 0% 100%;
  --popover-foreground: 0 0% 0%;
  --primary: 0 0% 0%;
  --primary-foreground: 0 0% 100%;
  --secondary: 0 0% 96%;
  --secondary-foreground: 0 0% 0%;
  --muted: 0 0% 96%;
  /* Strong secondary ink keeps operational labels and metadata readable on both
     the page and the muted surface. */
  --muted-foreground: 0 0% 30%;
  --accent: 213 75% 15%; /* #0A1C36 */
  --accent-foreground: 0 0% 100%;
  --destructive: 0 84.2% 60.2%;
  --destructive-foreground: 0 0% 100%;
  --border: 0 0% 90%;
  --input: 0 0% 90%;
  --ring: 0 0% 0%;
  --radius: 0rem;

  --sidebar-background: 0 0% 98%;
  --sidebar-foreground: 0 0% 0%;
  --sidebar-primary: 0 0% 0%;
  --sidebar-primary-foreground: 0 0% 100%;
  --sidebar-accent: 0 0% 96%;
  --sidebar-accent-foreground: 0 0% 0%;
  --sidebar-border: 0 0% 90%;
  --sidebar-ring: 0 0% 0%;

  /* --- Semantic colours: what components use --- */
  --bg: hsl(var(--background));
  --fg: hsl(var(--foreground));
  --fg-secondary: hsl(var(--muted-foreground)); /* readable secondary text, 4.5:1 */
  /* Kept for compatibility. It used to be #878787 (3.6:1, which fails AA for 11px labels), so
     it is now an alias of --fg-secondary: every consumer gets readable ink without a rename. */
  --muted-ink: var(--fg-secondary);
  --surface: #f5f5f5; /* something set apart: a panel, a hovered row */
  --hairline: #e5e5e5; /* every rule and divider */
  /* The edge of a control (input, select, checkbox box, popover): 3.7:1 on --bg, as 1.4.11
     needs. A --hairline is a decorative divider only; a control whose sole boundary is a
     border uses this. */
  --field-border: #858585;
  --interactive: hsl(var(--accent)); /* #0A1C36: links on hover, focus, the current item */
  --on-interactive: hsl(var(--accent-foreground));
  /* The single signal colour: the one thing to look at -- new, unsure, needs a decision. */
  --signal: #a85427;
  --on-signal: #ffffff;
  --danger: hsl(var(--destructive));
  /* --danger is 3.8:1 as text on white; error text and danger-button labels use this. */
  --danger-ink: #c62828;
  --on-danger: hsl(var(--destructive-foreground));
  --overlay: rgb(0 0 0 / 0.4); /* behind a dialog */
  /* Shadows are for floating overlays only (popover, drawer, dialog, toast). Cards and the
     tooltip stay flat. Black at low alpha reads on white and, being dark on dark, is
     near-invisible in dark mode, where the overlay's --field-border carries the edge. */
  --shadow-sm: 0 1px 2px rgb(0 0 0 / 0.04);
  --shadow: 0 1px 3px rgb(0 0 0 / 0.06);
  --shadow-md: 0 6px 16px -8px rgb(0 0 0 / 0.14);
  --shadow-lg: 0 16px 40px -16px rgb(0 0 0 / 0.2);

  /* The dark stage: the one black surface, for media (audio, video) in a light page. */
  --stage: #000000;
  --stage-fg: #ffffff;
  --stage-muted: #8a8a8a;
  --stage-line: #2a2a2a;

  /* A page or document surface that is white with black text in both themes: an OCR page
     view, a scanned document, a print preview. Not themed, so it is not in the dark blocks. */
  --canvas: #ffffff;
  --on-canvas: #000000;

  /* Series and confidence colours for drawing on --canvas (OCR overlays, document views).
     The themed --data-* and --conf-* are tuned for the page background, and in the dark
     theme they fail on white. These do not change with the theme, like the canvas. Each is
     >=4.5:1 on --canvas, so it also serves as text; scripts/check-contrast.mjs checks it. */
  --data-1-on-canvas: #27549a; /* 7.44:1 */
  --data-2-on-canvas: #b35f2c; /* 4.58:1 */
  --data-3-on-canvas: #008475; /* 4.61:1 */
  --data-4-on-canvas: #8a5bb3; /* 4.97:1 */
  --data-5-on-canvas: #907200; /* 4.57:1 */
  --data-6-on-canvas: #c14a7c; /* 4.63:1 */
  --data-7-on-canvas: #367ba9; /* 4.60:1 */
  --data-8-on-canvas: #6d7c29; /* 4.60:1 */
  --conf-high-on-canvas: var(--data-1-on-canvas);
  --conf-mid-on-canvas: #707070; /* 4.95:1 */
  --conf-low-on-canvas: #a85427; /* 5.30:1 */

  /* --- Data: categorical series (speakers, chart series), assigned in this order, never
     cycled; a ninth is "Other" or a facet. Muted but distinct, with navy-blue and copper
     among them. Each is >=3:1 on --bg and --surface (non-text graphics) and separates under
     protan/deutan simulation (OKLab dE >= 9 between neighbours). Colour never carries
     identity alone: pair it with a label, a legend or a texture. scripts/check-contrast.mjs
     checks all of this. --- */
  --data-1: #27549a; /* blue */
  --data-2: #b5602c; /* copper */
  --data-3: #008a7a; /* teal */
  --data-4: #8a5bb3; /* violet */
  --data-5: #947500; /* ochre */
  --data-6: #c14a7c; /* rose */
  --data-7: #3f8fc4; /* sky */
  --data-8: #6f7f2a; /* olive */

  /* Confidence bands: high and mid stay quiet, low is the signal (unsure, look here). The
     bands also differ in lightness and must carry a label or value, never colour alone. */
  --conf-high: var(--data-1);
  --conf-mid: var(--fg-secondary);
  --conf-low: var(--signal);

  /* --- Type --- */
  --font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  --font-body: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --text-2xs: 10px; /* tags: mono, uppercase, tracked --tracking-link */
  --text-xs: 12px; /* eyebrows, badges: mono, uppercase, tracked */
  --text-sm: 13px;
  --text-md: 16px; /* body */
  --text-lg: 18px; /* h2 */
  --text-xl: 28px; /* h1 */
  /* Tracking keeps uppercase labels distinct without spreading operational text apart. */
  --tracking-wide: 0.25em;
  --tracking-label: 0.08em; /* the wordmark and every uppercase mono label */
  --tracking-link: 0.06em;
  --tracking-tight: 0.04em;
  --leading: 1.6;

  /* --- Space and measure --- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 16px;
  --space-4: 24px;
  --space-5: 40px;
  --space-6: 64px;
  --space-7: 96px;
  --measure: 68ch;
  --frame: 1120px;
  --control-height: 36px;
  --control-height-sm: 28px;
  --control-height-lg: 44px; /* also the minimum touch target */
  --target-min: 24px; /* WCAG 2.5.8: the smallest a pointer target may be */
  --shell-bar: 56px; /* the app header's height; html scroll-padding-top uses it */

  /* --- Motion and state --- */
  --duration-fast: 120ms;
  --duration: 200ms;
  --duration-slow: 500ms; /* a mark collapsing, a panel revealing */
  --ease: cubic-bezier(0.2, 0, 0, 1);
  /* A control that cannot be used right now, in any style. */
  --disabled-opacity: 0.35; /* 0.55 under prefers-contrast: more */
  /* A region that is busy refreshing (a table reloading) dims to this, never lower: 0.8 keeps
     primary text above 4.5:1. Components use this token rather than their own number. */
  --dim-opacity: 0.8;

  /* --- Focus --- */
  --focus-ring: 2px; /* outline width of every :focus-visible */
  --focus-offset: 2px;

  /* --- Layers ---
     Stacking, lowest to highest: page content < sticky < dropdown < overlay < toast.
     - sticky: a sticky header or action bar. It makes its own stacking context, so a menu
       inside it rises with it, above the page content under it.
     - dropdown: a select list, menu or popover that is not in the top layer, so it clears
       sticky bars and neighbouring content.
     - overlay: a modal's backdrop and panel.
     - toast: status messages, above everything, including a modal.
     <dialog>.showModal() and [popover] use the browser's top layer, which sits above every
     z-index; these numbers only order what is not in the top layer. */
  --z-sticky: 10;
  --z-dropdown: 50;
  --z-overlay: 100;
  --z-toast: 200;
}

/* Breakpoints cannot be custom properties inside a media query. They are, by name:
     tablet 834px · desktop 1512px · xl-desktop 1920px (the site's Tailwind screens)
     handset < 600px (where frames drop to --space-3 gutters) */

/* @dark-begin -- scripts/check-tokens.mjs compares this block with the media copy below */
:root[data-theme='dark'],
:root.dark {
  color-scheme: dark;
  --background: 0 0% 0%;
  --foreground: 0 0% 100%;
  --card: 0 0% 2%;
  --card-foreground: 0 0% 100%;
  --popover: 0 0% 2%;
  --popover-foreground: 0 0% 100%;
  --primary: 0 0% 100%;
  --primary-foreground: 0 0% 0%;
  --secondary: 0 0% 9%;
  --secondary-foreground: 0 0% 100%;
  --muted: 0 0% 9%;
  --muted-foreground: 0 0% 70%;
  --accent: 213 75% 15%;
  --accent-foreground: 0 0% 100%;
  --destructive: 0 62.8% 30.6%;
  --destructive-foreground: 0 0% 100%;
  --border: 0 0% 25%;
  --input: 0 0% 25%;
  --ring: 0 0% 100%;
  --sidebar-background: 0 0% 2%;
  --sidebar-foreground: 0 0% 100%;
  --sidebar-primary: 0 0% 100%;
  --sidebar-primary-foreground: 0 0% 0%;
  --sidebar-accent: 0 0% 9%;
  --sidebar-accent-foreground: 0 0% 100%;
  --sidebar-border: 0 0% 25%;
  --sidebar-ring: 0 0% 100%;

  --surface: #111111;
  --hairline: #2e2e2e;
  --field-border: #6b6b6b; /* 3.9:1 on --bg */
  /* Navy on black disappears; in the dark the interactive colour is the foreground. */
  --interactive: #ffffff;
  --on-interactive: #000000;
  --signal: #c8693a;
  --on-signal: #000000;
  --danger: #e5484d;
  --danger-ink: #ff6b6b;
  --on-danger: #000000;
  --overlay: rgb(0 0 0 / 0.7);
  --stage: #0d0d0d;
  --stage-line: #333333;
  --data-1: #5f8fd0;
  --data-2: #d27a3c;
  --data-3: #1fa898;
  --data-4: #a07ad8;
  --data-5: #b09020;
  --data-6: #d4608f;
  --data-7: #3f9ed4;
  --data-8: #7f9e34;
}
/* @dark-end */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']):not(.light) {
    color-scheme: dark;
    --background: 0 0% 0%;
    --foreground: 0 0% 100%;
    --card: 0 0% 2%;
    --card-foreground: 0 0% 100%;
    --popover: 0 0% 2%;
    --popover-foreground: 0 0% 100%;
    --primary: 0 0% 100%;
    --primary-foreground: 0 0% 0%;
    --secondary: 0 0% 9%;
    --secondary-foreground: 0 0% 100%;
    --muted: 0 0% 9%;
    --muted-foreground: 0 0% 70%;
    --accent: 213 75% 15%;
    --accent-foreground: 0 0% 100%;
    --destructive: 0 62.8% 30.6%;
    --destructive-foreground: 0 0% 100%;
    --border: 0 0% 25%;
    --input: 0 0% 25%;
    --ring: 0 0% 100%;
    --sidebar-background: 0 0% 2%;
    --sidebar-foreground: 0 0% 100%;
    --sidebar-primary: 0 0% 100%;
    --sidebar-primary-foreground: 0 0% 0%;
    --sidebar-accent: 0 0% 9%;
    --sidebar-accent-foreground: 0 0% 100%;
    --sidebar-border: 0 0% 25%;
    --sidebar-ring: 0 0% 100%;

      --surface: #111111;
    --hairline: #2e2e2e;
    --field-border: #6b6b6b; /* 3.9:1 on --bg */
    /* Navy on black disappears; in the dark the interactive colour is the foreground. */
    --interactive: #ffffff;
    --on-interactive: #000000;
    --signal: #c8693a;
    --on-signal: #000000;
    --danger: #e5484d;
    --danger-ink: #ff6b6b;
    --on-danger: #000000;
    --overlay: rgb(0 0 0 / 0.7);
    --stage: #0d0d0d;
    --stage-line: #333333;
    --data-1: #5f8fd0;
    --data-2: #d27a3c;
    --data-3: #1fa898;
    --data-4: #a07ad8;
    --data-5: #b09020;
    --data-6: #d4608f;
    --data-7: #3f9ed4;
    --data-8: #7f9e34;
  }
}

/* --- More contrast: the OS asks for it (prefers-contrast: more) ---
   Darker rules and field edges, darker secondary ink, and a disabled state that is still
   readable. The dark copies are written twice, like the dark palette above, and
   scripts/check-tokens.mjs keeps the two in step. These blocks come last so they win over the
   palette blocks above at equal specificity. */
@media (prefers-contrast: more) {
  :root {
    --muted-foreground: 0 0% 30%;
    --hairline: #767676;
    --field-border: #595959;
    --disabled-opacity: 0.55;
  }
}

/* @dark-more-begin -- scripts/check-tokens.mjs compares this block with the media copy below */
@media (prefers-contrast: more) {
  :root[data-theme='dark'],
  :root.dark {
    --muted-foreground: 0 0% 86%;
    --hairline: #8a8a8a;
    --field-border: #9a9a9a;
    --disabled-opacity: 0.55;
  }
}
/* @dark-more-end */

@media (prefers-color-scheme: dark) and (prefers-contrast: more) {
  :root:not([data-theme='light']):not(.light) {
    --muted-foreground: 0 0% 86%;
    --hairline: #8a8a8a;
    --field-border: #9a9a9a;
    --disabled-opacity: 0.55;
  }
}

/* The stage: the black media surface (recording, playback) in either theme. A `.cp-stage`
   element re-points the page tokens at it, so core-design controls drawn inside take the
   stage's colours: the dark palette's control edge, interactive and signal, on --stage. */
.cp-stage {
  color-scheme: dark;
  --bg: var(--stage);
  --fg: var(--stage-fg);
  --fg-secondary: var(--stage-muted);
  --muted-ink: var(--stage-muted);
  --hairline: var(--stage-line);
  --surface: #161616;
  --field-border: #6b6b6b; /* 3.9:1 on --stage */
  --interactive: var(--stage-fg);
  --on-interactive: var(--stage);
  --signal: #c8693a;
  --on-signal: #000000;
}
