/* ─────────────────────────────
   BRAND THEME: BlackDoctor
   ─────────────────────────────

   The design system (design-system.css) ships neutral defaults on real token
   names. This file is the brand: it loads AFTER the engine CSS, so its values
   win through the cascade on source order alone; nothing here is marked
   important.

     <link rel="stylesheet" href="assets/css/design-system.css">
     <link rel="stylesheet" href="assets/css/theme.css">     ← this file

   SOURCE. BlackDoctor's Figma file (Black Doctor | Design System,
   yENntRnHC7qid6cSo3P5lC), read 2026-09-15. The variable-by-variable mapping,
   every value rejected on contrast and the reasons live in
   docs/figma-mapping.md — change that file first, then this one. The Figma
   file also carries iOS community-kit residue (Color/text, Color 6, Labels -
   Vibrant, SF Pro …); none of it is brand and none of it is here.

   SCOPE. §1/§2 primitives — the neutral and gold ramps, the ink primitive,
   the yellow hue, the font slots — plus the few §2 semantics the engine's
   defaults get wrong for this palette: the accent fill, the control
   boundaries, selection, the dropdown ground. Spacing, radius, the type scale
   and the breakpoints are engine rhythm, not brand expression, and buttons
   derive from --text-primary / --text-inverted at component scope, so they
   re-skin on their own. None of them are restated here.

   FONTS. A token names a family; something else must load it. Inter arrives
   through googleFontsUrl in cms/blackdoctor/brand.json, which the generator
   emits into every page head. Erode is self-hosted: the @font-face rules
   below point at assets/fonts/, and brand.json lists the upright file under
   fontPreload so it is fetched before the stylesheet asks for it. Change a
   family here and that file together, or the page silently falls back with
   no error anywhere. The Erode files are Fontshare's build of the face
   (Indian Type Foundry, ITF Free Font Licence) — a stand-in until the owner
   supplies BlackDoctor's own; replace the files, keep the names. Only two
   slots are brand: --font-primary and --font-secondary. Quaternary, display,
   playful and script are not used and stay at the engine defaults (owner
   decision, 2026-09-15); tertiary follows primary because the badge reads it.

   THE NEUTRAL RAMP IS A LAW, NOT A LIST. Figma's neutrals are pure black at
   alpha (step − 100) / 1000 over the paper colour #f4f1ed: 150 is 5 %, 500
   is 40 %, 800 is 70 %. Figma authors seven steps; the other six are computed
   from the same law and say so. Two authored steps sit off the law: 50
   (lighter than paper) and 950 (#181818). Regenerate from the law, never
   re-interpolate.

   THE GOLD RAMP IS A STAND-IN. The owner asked for a 50–950 gold scale and
   will supply the values. Until then every step holds the hue and saturation
   of the brand gold #efb14d (HSL 37°, 83.5 %) at a stepped lightness. 500 is
   the real gold; 800 is the light-mode accent ink. Replace the values, keep
   the names, re-run the contrast check.

   DARK MODE is written twice: [data-theme="dark"] for an explicit choice, and
   an identical mirror inside @media (prefers-color-scheme: dark) for visitors
   without JavaScript. Drift between the two is a known failure mode — keep
   them byte-identical. The media block stays scoped to :root:not([data-theme])
   so a saved light choice beats a dark OS setting.

   THE CASCADE TRAP. This :root block is (0,1,0). It beats the engine's
   [data-theme="dark"] block (same specificity, later source) but LOSES to the
   engine's :root:not([data-theme]) no-JS mirror (0,2,0). So a semantic token
   set here that the engine's dark blocks also define renders one way under
   the toggle and another under an OS dark preference, unless both dark
   blocks below answer it. Every such token is answered there — even when the
   answer is the engine's own value. The ramps, the hue primitives and the
   font slots are mode-independent and exempt.
   ───────────────────────────── */


/* ── Erode Variable ───────────────────────────
   One file per style, the weight axis 300–700 declared as a range so every
   weight in between resolves from the same file. Paths are relative to this
   stylesheet, so they hold from every page depth. swap, not optional: a
   heading in the fallback serif for one frame beats one that never becomes
   the brand face. */
@font-face {
  font-family: "Erode";
  src: url("../fonts/erode-variable.woff2") format("woff2");
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Erode";
  src: url("../fonts/erode-variable-italic.woff2") format("woff2");
  font-weight: 300 700;
  font-style: italic;
  font-display: swap;
}


:root {

  /* ── Typography ────────────────────────────
     Inter carries text and interface; Erode carries the headings. h1–h6
     read --title-family (the engine's only role-family token), which is why
     it is set here and nothing else in the role layer is. Sizes, leading and
     the breakpoint steps are the engine's. */
  --font-primary: "Inter", system-ui, -apple-system, "Helvetica Neue", sans-serif;
  --font-secondary: "Erode", Georgia, "Times New Roman", serif;
  --font-tertiary: var(--font-primary);   /* the badge reads it; keep it Inter */
  --title-family: var(--font-secondary);


  /* ── Neutral ramp ───────────────────────────
     Black at alpha (step − 100) / 1000 over paper — see the header. Ratios
     are against paper. */
  --neutral-50:  #f9f8f6;   /* authored — lighter than paper */
  --neutral-100: #f4f1ed;   /* paper — α 0 */
  --neutral-150: #e8e5e1;   /* α 5 %  — Figma Background Secondary */
  --neutral-200: #dcd9d5;   /* α 10 % — computed */
  --neutral-300: #c3c1be;   /* α 20 % */
  --neutral-400: #aba9a6;   /* α 30 % — 2.08, decorative rules only */
  --neutral-500: #92918e;   /* α 40 % — 2.79, below every bar */
  --neutral-600: #7a7977;   /* α 50 % — computed — 3.86, the control-boundary step */
  --neutral-700: #62605f;   /* α 60 % — computed — 5.55; Figma's dark Border Secondary */
  --neutral-800: #494847;   /* α 70 % — 8.10 */
  --neutral-900: #31302f;   /* α 80 % */
  --neutral-950: #181818;   /* authored — the law would give #252424 */
  --neutral-990: #000000;   /* the ink */


  /* ── Gold ramp — STAND-IN ───────────────────
     HSL 37° / 83.5 % held, lightness stepped. Owner-supplied values replace
     these; see the header. */
  --gold-50:  #fdf7ec;
  --gold-100: #fcefda;
  --gold-150: #fae6c7;
  --gold-200: #f7daab;
  --gold-300: #f4cc8a;
  --gold-400: #f2bd69;
  --gold-500: #efb14d;   /* the brand gold — 1.68 on paper, 11.06 on black */
  --gold-600: #ea9815;
  --gold-700: #bb7a11;   /* 3.15 on paper — large text and graphics only */
  --gold-800: #83550c;   /* 5.70 on paper — the light-mode accent ink */
  --gold-900: #543708;
  --gold-950: #2f1e04;


  /* ── Palette hooks ──────────────────────────
     The engine's ink is neutral-900; BlackDoctor's is true black, and
     --text-primary, --border-primary, --button-color and
     --selected-background all resolve through this one primitive. The yellow
     hue is re-pointed onto the gold ramp so [data-color="yellow"], <mark>,
     rating stars and the warning status all carry brand gold. One consumer
     the re-point leaves short: the engine's dark <mark> mixes --yellow to
     60 % and inks it off-white, which with this gold is 4.03 — latent, no
     page renders a <mark>; recorded in the mapping doc. Brown is the brand's
     warm grey: 2.65 on paper, a surface and graphic colour, never ink.
     --brown-lighter/-light/-dark stay on the neutral ramp. */
  --off-black: var(--neutral-990);
  --brown: #9d9488;
  --yellow-lighter: var(--gold-100);
  --yellow-light: #fae6cc;             /* Figma Background Highlighter 2 — what <mark> paints; a literal, deliberately off the gold ramp */
  --yellow: var(--gold-500);
  --yellow-dark: var(--gold-900);


  /* ── Text ──────────────────────────────────
     --text-primary, --text-link, --text-faded and --text-inverted resolve to
     the Figma values through the ramp and are not restated. Figma's Text
     Faded (40 % black, 2.79) and Text Tertiary (#9d9488, 2.65) fail AA and
     are not ink; the engine's 60 % faded (5.55) stays. The brand gold cannot
     carry text on paper (1.68), so the accent ink is the ramp's 800 step:
     5.70 paper · 5.11 secondary · 6.05 dropdown · 4.60 mint · 5.27 peach. */
  --text-secondary: var(--neutral-800);   /* 8.10 paper · 7.26 secondary */
  --text-accent: var(--gold-800);


  /* ── Backgrounds ─────────────────────────────
     The engine aliases --background-accent to --text-accent; here the fill
     is the true gold and the ink is not, so both are declared. The dropdown
     ground is Figma's Navigation/Background: the mega-menu panel one step
     lighter than paper. The header and sidebar chrome sit on paper through
     the engine's own aliases. */
  --background-primary: var(--neutral-100);
  --background-secondary: var(--neutral-150);
  --background-accent: var(--yellow);
  --dropdown-background: var(--neutral-50);


  /* ── Borders ─────────────────────────────────
     A decorative rule can sit at 2:1; a control boundary needs 3:1 (WCAG
     1.4.11). The engine's --border-control default is neutral-500, which this
     ramp puts at 2.79, and --input-border aliases the 2.08 decorative rule —
     both take the 600 step: 3.86 on paper, 3.46 on the secondary ground.
     Aliased, not repeated as hex, so a regenerated ramp carries them. */
  --border-secondary: var(--neutral-400);   /* Figma Border Secondary — decorative */
  --border-faded: var(--black-alpha-10);    /* Figma Border Faded; the engine default is 15 % */
  --border-control: var(--neutral-600);
  --input-border: var(--neutral-600);


  /* ── Forms ───────────────────────────────────
     Figma fills the selected checkbox with gold. On paper that fill is 1.68
     against its surroundings and the box border is the faded rule, so it has
     no 3:1 boundary; the accent ink fills it instead (5.70), and the engine's
     off-white tick reads at 6.05 on it. Dark mode uses the real gold. */
  --checkbox-selected: var(--text-accent);


  /* ── Selection ───────────────────────────────
     The engine's --selection-text is --background-primary, which would put
     paper on gold at 1.68. Black on gold is 11.06. */
  --selection-background: var(--yellow);
  --selection-text: var(--black);
}


/* ── Dark mode ───────────────────────────────
   Paper's dark counterpart is neutral-950 (#181818), with the true gold as the
   accent: 9.35 on the page, where it cannot work on paper. Figma designs no
   dark page; its dark values come from the footer and cover, and the two
   surfaces it does not define are white at 5 % and 10 % over the page. */

[data-theme="dark"] {
  --text-primary: var(--white);           /* Figma dark Text Primary */
  --text-secondary: #e2dcd6;              /* Figma dark Text Secondary — paper warmed, 13.05 */
  --text-accent: var(--gold-500);

  --background-primary: var(--neutral-950);
  --background-secondary: #242424;        /* white 5 % over the page — no Figma value */
  --background-plain: #2f2f2f;            /* white 10 % over the page — no Figma value */
  --dropdown-background: var(--background-plain);   /* the engine's own dark value, restated: cascade trap */

  --border-primary: var(--text-primary);  /* the engine's dark value is a literal off-white; border stays ink */
  --border-secondary: var(--neutral-700); /* Figma dark Border Secondary — 2.83, decorative */
  --border-faded: var(--white-alpha-20);  /* Figma dark Border Faded = the engine value, restated: cascade trap */
  --border-control: var(--neutral-500);   /* 5.63 on the page */
  --input-border: var(--neutral-500);     /* the engine's dark #3a3a3a is 1.56 */
  --input-placeholder: var(--text-faded); /* the engine's dark 45 % white is 4.49; 50 % is 5.28 */

  --checkbox-selected: var(--text-accent); /* gold box; the engine's #1a1a1a tick is 9.17 on it */
}


/* ── System preference fallback (no-JS) ───────
   Mirror of [data-theme="dark"] above. Keep in sync.
   Scoped to :root:not([data-theme]) so a stored light choice wins. */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --text-primary: var(--white);
    --text-secondary: #e2dcd6;
    --text-accent: var(--gold-500);

    --background-primary: var(--neutral-950);
    --background-secondary: #242424;
    --background-plain: #2f2f2f;
    --dropdown-background: var(--background-plain);

    --border-primary: var(--text-primary);
    --border-secondary: var(--neutral-700);
    --border-faded: var(--white-alpha-20);
    --border-control: var(--neutral-500);
    --input-border: var(--neutral-500);
    --input-placeholder: var(--text-faded);

    --checkbox-selected: var(--text-accent);
  }
}
