/* ============================================================
   blocks — tokens.css
   The single source of truth for how this looks.

   Extracted from app.css so there is one place to repaint, and
   so the reasoning below sits with the values rather than in
   somebody's memory. System fonts, no external assets.

   THEME MODEL
   -----------
   1. :root                      -> LIGHT is the base.
   2. @media (prefers-color-scheme: dark) :root
                                 -> follow the OS when no explicit
                                    choice has been made.
   3. :root[data-theme="dark"]   -> a chosen theme wins over the media
                                    query in BOTH directions. Forcing LIGHT
                                    needs no block of its own: the dark media
                                    query is guarded with
                                    :root:not([data-theme="light"]), so the
                                    light base simply stays. One override
                                    instead of two hand-synced palettes.

   Set data-theme on <html> to pin one; leave it off to follow the
   OS. The snippet in the document head applies the saved choice
   before first paint, because a light flash on a dark screen at
   six in the morning is its own small insult.

   COLOUR SEMANTICS
   ----------------
   There is ONE accent and it means "done". Not headings, not
   links, not section rules — those are all ink or hairline. The
   moment a second thing is red, the red stops meaning anything,
   and this page exists to be read on a bad day.

   --accent   the tick, a filled history cell, a live control
   --bad      a refused write, an invalid field. Same hue as the
              accent on purpose: this palette has one loud colour
              and context, not hue, tells you which it is.
   ============================================================ */

/* ---------------------------------------------------------------
   LIGHT — the base. Cool paper, black ink, one red mark.
   --------------------------------------------------------------- */
:root {
  /* --- Type. A grotesque for display, system for prose, mono for
         anything a machine produced: times, counts, durations. --- */
  --display: 'Helvetica Neue', Inter, system-ui, -apple-system, 'Segoe UI', Arial, sans-serif;
  --sans: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;

  /* --- Paper. Never pure white: it makes the hairlines look like
         artefacts and the black look like a hole. --- */
  --bg: #f7f7f5;
  --panel: #fff;
  --panel2: #f1f1ef;
  --line: #e3e3e0;
  --line2: #c8c8c4;

  /* --- Ink. Near-black, not #000, which vibrates against hairlines. --- */
  --ink: #14140f;
  --muted: #56564f;
  /* Lifted from #8d8d85, for the reason the dark palette below was lifted first
     and light was not: 3.1:1 on this paper, carrying every section heading, the
     durations column, the form labels in the editor and every note on the page,
     at 0.6rem–0.8rem. Quiet is the intent; too faint to read is a bug, and it
     was only ever fixed on one of the two themes. 4.8:1 now, and still three
     clear steps below the ink. */
  --faint: #6e6e67;

  /* --- Syntax, for the code samples on /api. -------------------------------
     Six hues on a page whose whole colour rule is "one loud colour" needs a
     word. The rule is about ATTENTION: the accent means a thing is wrong or a
     thing is the action, and nothing else may compete for that. These do not
     compete — they are low-saturation, they sit at roughly the muted tier, and
     they exist inside one bordered box on one page. Unhighlighted JSON is
     genuinely harder to read, and a key that looks exactly like the string
     beside it is the specific thing that makes it hard.

     None of them is the accent, and none is near it: a red token would read as
     an error in a sample that is showing a success. */
  --tok-key: #2f5d8a;
  --tok-str: #3f6b45;
  --tok-num: #8a5a2f;
  --tok-lit: #8a5a2f;
  --tok-var: #7a4b8f;
  --tok-url: #2f5d8a;
  --tok-flag: #6b5f2f;
  --tok-cmd: #14140f;
  --tok-punct: #9a9a94;

  --accent: #b3261e;
  /* Derived, not repeated: two literals would let a repaint change one and
     silently break the "there is only one loud colour" rule. */
  --bad: var(--accent);
  /* What sits ON the accent. White over the deep red; near-black over the
     lifted dark-mode red, which is light enough that white would smear. */
  --on-accent: #fff;

  /* The two non-palette colours: the lift under a popover and the wash behind
     a modal. Both are the light ink at low alpha, which is where they were
     before — they lived as literals in app.css, the only two in the file, and
     that made "no literal colours" false and made them the two colours a
     repaint here could not reach.

     They are the SAME value in both themes for now, which is honest but not
     finished: a near-black shadow on a near-black ground does almost nothing,
     and a dark theme usually wants a deeper scrim and a real black shadow.
     That is a design decision, not a drift fix, so it is written down here
     rather than made. --shadow-ink is the colour only; the geometry stays with
     the rule that uses it. */
  --shadow-ink: rgb(20 20 15 / 14%);
  --scrim: rgb(20 20 15 / 28%);

  --sheet: 780px;

  /* Native checkboxes, scrollbars and date pickers follow this. Without it a
     forced-light page on a dark OS draws dark form controls on light paper. */
  color-scheme: light;
}

/* ---------------------------------------------------------------
   DARK — follow the OS unless told otherwise.

   Not an inversion. The paper goes to a cool near-black and the
   ink to a warm off-white, but the hairlines stay hairlines and
   the accent lifts just enough to hold its contrast on a dark
   ground — #b3261e on near-black is a bruise, not a mark.
   --------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --bg: #131315;
    --panel: #1a1a1d;
    --panel2: #212125;
    --line: #303036;
    --line2: #4d4d56;

    --ink: #eeeee9;
    --muted: #adada6;
    /* Lifted from #74747c: on dark paper the faint tier was carrying real
       information — a staple's duration, "1h left" on a continuation, the
       whole block meta line — below the point where it could be read. Quiet is
       the intent; invisible is a bug. */
    --faint: #8f8f97;

    --tok-key: #8ab4dd;
  --tok-str: #9ccf9c;
  --tok-num: #e0b080;
  --tok-lit: #e0b080;
  --tok-var: #c9a4e0;
  --tok-url: #8ab4dd;
  --tok-flag: #d8c07a;
  --tok-cmd: #eeeee9;
  --tok-punct: #6a6a72;

  --accent: #e0564c;
    --on-accent: #131315;

    /* Deliberately the same as light for now. See the note beside them above. */
    --shadow-ink: rgb(20 20 15 / 14%);
    --scrim: rgb(20 20 15 / 28%);
    color-scheme: dark;
  }
}

/* A chosen theme wins over the media query, in both directions. */
:root[data-theme='dark'] {
  --bg: #131315;
  --panel: #1a1a1d;
  --panel2: #212125;
  --line: #303036;
  --line2: #4d4d56;

  --ink: #eeeee9;
  --muted: #adada6;
  --faint: #8f8f97;

  --tok-key: #8ab4dd;
  --tok-str: #9ccf9c;
  --tok-num: #e0b080;
  --tok-lit: #e0b080;
  --tok-var: #c9a4e0;
  --tok-url: #8ab4dd;
  --tok-flag: #d8c07a;
  --tok-cmd: #eeeee9;
  --tok-punct: #6a6a72;

  --accent: #e0564c;
  --on-accent: #131315;

  /* Deliberately the same as light for now. See the note beside them above. */
  --shadow-ink: rgb(20 20 15 / 14%);
  --scrim: rgb(20 20 15 / 28%);
  color-scheme: dark;
}
