/* ==========================================================================
   Design tokens -- the single source of colour, type, space, radius and line.
   ==========================================================================

   Every other stylesheet in this repo reads from here and declares NO raw hex
   and NO raw px for anything a token covers. A literal elsewhere is a defect,
   not a shortcut: it is the one thing that makes a palette impossible to change
   later, because the values stop being findable.

   The VALUES are styling intent, taken from the design reference held outside
   this repo. Nothing else was: this file's structure, naming and theme strategy
   are authored here, against how this site actually renders.

   Theme strategy -- read before adding a token
   -------------------------------------------
   Light is the base and lives on bare `:root`, so a browser that supports no
   media query and runs no JS still gets a complete, deliberate palette.
   Dark then overrides ONLY what changes, in two places:

     1. `@media (prefers-color-scheme: dark)` guarded by `:root:not([data-theme="light"])`
        -- the OS preference, honoured with no JavaScript at all.
     2. `:root[data-theme="dark"]` -- an explicit choice, which must beat the OS
        preference in BOTH directions.

   Both are required. With only the media query, a visitor on a dark OS cannot
   choose light. With only the attribute, dark depends on JavaScript, and this
   site is required to work without it.

   Consequence worth stating: never give a colour its ONLY definition inside the
   media query or the attribute block. A token defined only there is undefined in
   the other theme, and an undefined custom property does not fall back -- it
   makes the property invalid at computed-value time, which usually renders as
   black-on-black or transparent. Define on `:root` first, always.
*/

:root {
  /* --- surface + ink ---------------------------------------------------- */
  /* Warm-tinted neutrals, not pure grey. The page is off-white so that a true
     white --surface reads as a raised card without needing a shadow. */
  --bg:            #fbfbfa;
  --surface:       #ffffff;
  --surface-2:     #f3f3f1;
  --surface-3:     #eaeae7;
  --border:        #e2e2de;
  --border-strong: #cfcfc9;
  --text:          #17171a;
  --text-muted:    #62626b;
  --text-faint:    #8d8d95;

  /* --- accent ----------------------------------------------------------- */
  /* Exactly one accent hue, and the design budgets it at roughly one
     accent-FILLED element per viewport. Everything else that needs emphasis
     uses --accent-line or --accent-soft. Adding a second accent hue is a design
     change, not a CSS change. */
  --accent:        #d1490f;
  --accent-hover:  #b23d0b;
  --accent-ink:    #ffffff;  /* text ON an accent fill -- never --text */
  --accent-soft:   rgba(209, 73, 15, 0.10);
  --accent-line:   rgba(209, 73, 15, 0.28);

  /* --- state ------------------------------------------------------------ */
  --danger:        #b4241f;
  --danger-soft:   rgba(180, 36, 31, 0.10);
  --ok:            #1c6b45;
  --ok-soft:       rgba(28, 107, 69, 0.10);

  /* --- type ------------------------------------------------------------- */
  /* System stacks only. This site ships no webfont and makes no external asset
     request, so a design needing a hosted face would be undeliverable here by
     construction -- that constraint is upstream in the design, not a compromise
     made in this file. */
  --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
               Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
               "Liberation Mono", monospace;

  /* rem-based, so the scale honours the reader's browser font size. */
  --fs-xs:   0.75rem;    /* 12 -- metadata, tags, dates: always mono */
  --fs-sm:   0.875rem;   /* 14 */
  --fs-base: 1rem;       /* 16 */
  --fs-md:   1.125rem;   /* 18 -- lead paragraphs */
  --fs-lg:   1.3125rem;  /* 21 */
  --fs-xl:   1.75rem;    /* 28 */
  --fs-2xl:  2.375rem;   /* 38 */
  --fs-3xl:  3.25rem;    /* 52 -- display only */

  --lh-tight: 1.15;      /* display headings */
  --lh-snug:  1.35;      /* sub-headings, card titles */
  --lh-body:  1.65;      /* running prose */

  --tracking-tight: -0.02em;  /* large type only; it is a size correction */
  --tracking-wide:   0.08em;  /* small caps / eyebrow labels only */

  /* --- space (4pt ramp) -------------------------------------------------- */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;
  --s-8: 64px;
  --s-9: 96px;

  /* --- radius + line ----------------------------------------------------- */
  --r-sm:   4px;
  --r-md:   8px;
  --r-lg:   14px;
  --r-full: 999px;
  --hairline: 1px solid var(--border);

  /* --- elevation --------------------------------------------------------- */
  /* Deliberately restrained: this design separates surfaces with hairlines and
     reserves shadow for things that genuinely float. */
  --shadow-1: 0 1px 2px rgba(20, 20, 25, .06);
  --shadow-2: 0 6px 24px -8px rgba(20, 20, 25, .18);

  /* --- measure ----------------------------------------------------------- */
  --measure:  68ch;    /* max line length for running prose */
  --page-max: 1120px;  /* max width of the page gutter container */

  /* --- motion ------------------------------------------------------------ */
  --ease:     cubic-bezier(.2, .6, .3, 1);
  --dur-fast: 120ms;
  --dur:      200ms;
}

/* Dark via OS preference. Guarded so an explicit light choice still wins. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:            #0e0e10;
    --surface:       #16161a;
    --surface-2:     #1c1c21;
    --surface-3:     #24242b;
    --border:        #2a2a32;
    --border-strong: #3a3a45;
    --text:          #ececed;
    --text-muted:    #9c9ca6;
    --text-faint:    #74747f;

    /* Brighter and less saturated than the light accent: the light value is
       chosen for contrast against white and goes muddy on a dark surface. */
    --accent:        #ff6b35;
    --accent-hover:  #ff8455;
    --accent-ink:    #16100c;
    --accent-soft:   rgba(255, 107, 53, 0.13);
    --accent-line:   rgba(255, 107, 53, 0.34);

    --danger:        #ff6b64;
    --danger-soft:   rgba(255, 107, 100, 0.12);
    --ok:            #56c98d;
    --ok-soft:       rgba(86, 201, 141, 0.12);

    --shadow-1: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow-2: 0 8px 30px -10px rgba(0, 0, 0, .6);
  }
}

/* Dark via explicit choice. Same values -- duplicated on purpose, because CSS
   has no way to apply one declaration block to two different selectors without
   a preprocessor, and this repo has no build step. If you change a value above,
   change it here too; they are meant to be identical. */
:root[data-theme="dark"] {
  --bg:            #0e0e10;
  --surface:       #16161a;
  --surface-2:     #1c1c21;
  --surface-3:     #24242b;
  --border:        #2a2a32;
  --border-strong: #3a3a45;
  --text:          #ececed;
  --text-muted:    #9c9ca6;
  --text-faint:    #74747f;

  --accent:        #ff6b35;
  --accent-hover:  #ff8455;
  --accent-ink:    #16100c;
  --accent-soft:   rgba(255, 107, 53, 0.13);
  --accent-line:   rgba(255, 107, 53, 0.34);

  --danger:        #ff6b64;
  --danger-soft:   rgba(255, 107, 100, 0.12);
  --ok:            #56c98d;
  --ok-soft:       rgba(86, 201, 141, 0.12);

  --shadow-1: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow-2: 0 8px 30px -10px rgba(0, 0, 0, .6);
}
