/* The single source of truth for every repeated constant
   (05-design-system.md §3). No selector here styles anything.

   Two rules decide what is here: a ramp ships whole (a hole in a scale
   invites the ad-hoc value the scale exists to prevent), and everything
   outside a ramp names a consumer — §3's table, or `/_styleguide`, which
   shows every token there is and is what makes "does this have a consumer"
   a question someone can answer by looking.

   Nothing is deferred: every token §3 lists is declared here, and the last
   one to arrive was --font-mono, with the step editor's tasks textarea. */

:root {
  color-scheme: light dark;

  /* ink & ground — paper, not screen (plans/deviations.md). Paper is never
     pure white and ink is never pure black, so the ground is warm and the
     recess below it is a real step rather than the 1.02:1 #fbfbfa was.

     That recess is what forced the intent hues: on this surface v0's
     --color-danger was 4.26:1 and its --color-success 4.41:1, both under
     §12's AA floor, and its --color-danger-weak was 1.071:1 against the dark
     ground — .strip--error invisible. Every hue below was measured against
     both grounds before it was written; the tightest pair in either palette
     is light warning-weak against bg, at 1.106. */
  --color-bg:           #faf9f5;
  /* The one recessed ground, and since r12-5 it has ONE consumer: the open nav
     panel on a phone (base.css's `.nav` popover). §3's table gives it two and
     §8 sets the empty state on it; `.empty` is an outline now and the
     departure is filed in plans/deviations.md. Kept rather than deleted
     because the panel is a real recess — it lies over the page — and because
     §12's contrast figures for --color-text and --color-accent are measured
     against it. */
  --color-surface:      #f2f0ea;
  --color-fg:           #1a1815;
  /* The running text's ink, one step softer than --color-fg (r12-2). Its
     consumer is base.css's `body` rule and nothing else, so everything that
     inherits gets it and the three things that re-assert --color-fg —
     h1/h2/h3, `strong`, and every control in components.css — are what stands
     out of a page of it. A separate token and not a softened --color-fg,
     because that one is also the primary button's FILL, the focus ring and
     every hover border, and softening those makes the chrome recede with the
     prose. 11.54:1 on --color-bg and 10.67:1 on --color-surface, against §12's
     4.5 floor. */
  --color-text:         #3a352d;
  --color-muted:        #6f6a60;
  --color-line:         #e0ddd3;
  --color-line-strong:  #c2bdb0;

  /* intent */
  /* The product's ONE accent, warm because the ground is (r12-5). Terracotta
     rather than the ochre --color-warning already owns or the red
     --color-danger does: the ground is #faf9f5, and a warm ground wants a warm
     mark. The chrome — the primary button and the focus ring — still spends
     --color-fg and never this.

     It marks where colour MEANS something: a revealed exercise answer and the
     one openable row in a curriculum (both /app), and — on a landing alone —
     the hairline that opens a section, the hanging numeral above it, the
     charged price on a plan card, that card's discount badge and the mid-page
     link out to the band. `.checkbox` in components.css is the fourth kind of
     consumer and is chrome, not meaning: the platform control tinted.

     Nothing enforces the paragraph above.
     `test_every_token_is_a_ramp_step_or_names_a_consumer` checks that a token
     is registered, never who spends it, so this comment is the whole of r12-1's
     "colour survives where it means something" rule.

     r12-2 pass B's --color-mark was this same hue under a second name; the two
     collapsed here and this is the name §3's registry uses.
     6.22:1 on --color-bg and 5.75:1 on --color-surface. */
  --color-accent:       #a13d20;
  --color-danger:       #bd2a22;
  --color-danger-weak:  #f7e6e2;
  --color-success:      #15683d;
  --color-warning:      #7a5500;
  --color-warning-weak: #f5eddb;

  /* space — `rem`, so the whole page follows a reader who sets a larger root
     font size. A px ramp grows the text and leaves the gaps around it, which
     is the layout getting tighter exactly when somebody asked for more room.
     Every step below is the px value it replaced divided by 16, so at the
     browser default nothing moves. */
  --space-1: 0.25rem; --space-2: 0.5rem; --space-3: 0.75rem; --space-4: 1rem;
  --space-6: 1.5rem;  --space-8: 2.5rem; --space-12: 4.5rem;

  /* type */
  /* "Roboto" is quoted because `value-keyword-case` reads a bare family
     name inside a custom property as a keyword and demands lower case.
     05-design-system.md §3 writes it unquoted; no semantic difference.
     §3's stack is kept whole BEHIND Inter (plans/deviations.md): the
     @font-face blocks in base.css are `font-display: swap`, so this is what
     the first paint uses and what a browser that fails to fetch keeps. */
  --font-body: "Inter", system-ui, -apple-system, "Segoe UI", "Roboto", sans-serif;
  /* §3's stack verbatim. Its one consumer is `.textarea--code` in admin.css:
     the step editor edits a JSON document, where alignment is what makes the
     nesting readable. */
  --font-mono: ui-monospace, sfmono-regular, menlo, monospace;
  /* The heading face (plans/deviations.md). Its consumers are base.css's
     h1/h2/h3 rule and `.topbar__brand`; the body, the controls and the tables
     stay --font-body, because a serif UI at 16px is not modern. */
  --font-serif: "Source Serif 4", ui-serif, georgia, "Times New Roman", serif;
  /* --text-2xl is the marketing masthead's and nothing else's (§2 budgets
     two sizes above body; plans/deviations.md). It is the one step here that
     is not a conversion. */
  --text-sm: 0.8125rem; --text-base: 1rem; --text-lg: 1.25rem;
  --text-xl: 1.75rem;   --text-2xl: 2.75rem;
  --leading-body: 1.6; --leading-tight: 1.25;
  --weight-normal: 400; --weight-medium: 600;

  /* form & motion */
  --radius: 3px;
  /* px, not rem: a hairline and a focus ring are device marks. They are what
     the screen can draw, not something a reader asked to be bigger, and a
     1px rule that becomes 1.25px at a 20px root is a blurred one. */
  --border-width: 1px;
  --focus-ring: 2px;
  --control-height: 2.25rem;
  --topbar-height: 3.5rem;
  --measure: 68ch;
  --duration: 120ms;

  /* breakpoint: 700px — cannot be a custom property, media queries do not
     resolve them. Written literally, and only ever as `min-width`. */
}

/* Dark is a complete second palette, not two overrides: every token that
   carries colour has a dark value, and the accent and danger hues are
   lightened rather than reused, so contrast meets AA in both themes. */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-bg:           #161512;
    --color-surface:      #1e1c18;
    --color-fg:           #eae7e0;
    --color-text:         #c6c1b6;   /* 10.18:1 on bg, 9.48:1 on surface */
    --color-muted:        #a09a8e;
    --color-line:         #302d27;
    --color-line-strong:  #46423a;
    --color-accent:       #e08a5f;   /* 6.93:1 on bg, 6.46:1 on surface */
    --color-danger:       #ff8078;
    --color-danger-weak:  #3a201c;
    --color-success:      #5fd396;
    --color-warning:      #e0b249;
    --color-warning-weak: #372e1c;
  }
}

/* The reader's explicit choice, honoured regardless of the system preference.
   The attribute is written by r2-4's bootstrap; the selector is here because
   the two theme selectors belong to the palette, not to the script. */
:root[data-theme="dark"] {
  --color-bg:           #161512;
  --color-surface:      #1e1c18;
  --color-fg:           #eae7e0;
  --color-text:         #c6c1b6;   /* 10.18:1 on bg, 9.48:1 on surface */
  --color-muted:        #a09a8e;
  --color-line:         #302d27;
  --color-line-strong:  #46423a;
  --color-accent:       #e08a5f;   /* 6.93:1 on bg, 6.46:1 on surface */
  --color-danger:       #ff8078;
  --color-danger-weak:  #3a201c;
  --color-success:      #5fd396;
  --color-warning:      #e0b249;
  --color-warning-weak: #372e1c;
}
