/* GENERATED by design/ship.py from design/reader/tokens.css -- DO NOT EDIT. That file is the master; run `python3 design/export.py --shell` and this one is rewritten. */
/* ENGINE · the numbers every page spends -- colour, type, the scale, the measured boxes
   · bench: bench-panes.html · mounted by: see MAP.md (generated -- `python3 map.py`) */
/* ============================ FRANK — THE TOKENS =========================
   ONE definition of every measured constant, linked by every pane AND by the
   app. Nothing here is a copy of anything: if a number appears twice in this
   product, one of the two is already wrong, and that is the whole reason this
   file exists. PLAN.md has it as "the mock is a COPY, and that is why it keeps
   drifting" -- benches that hold their own numbers drift within a day.

   Every value was measured off book.stevejobsarchive.com and
   letters.stevejobsarchive.com at 1440 and 2000 and confirmed at both.  */

:root{
  /* --- the paper ------------------------------------------------------- */
  /* WARMTH IS ONE NUMBER. Overriding --warm on <html> shifts ground and ink
     together, so paper and ink never drift apart in temperature.
     0 = the Archive's own near-neutral. Raise it toward candlelight.        */
  --warm: 0;
  /* CONTRAST IS ONE NUMBER TOO (ASKS #172, Osca 30 Sep: "I'd also like a contrast setting in there").
     -2 .. 2, 0 = the page as it has always been (Settings' middle stop). It moves ink and ground APART
     (up) or TOGETHER (down), in both themes, and never their hue -- so warmth and contrast are two
     [D171, Osca 15 Oct: "Contrast should turn the TEXT from sharp black to grey; the background should barely move":
     the INK does the moving -- light theme 0% at Sharp, 3.5% Firm, 7% Book, 24.5% Soft, 42% Faint; dark theme the
     mirror, 94.6% to 60.6% -- and the ground moves a third of a percent a stop]
     independent dials on the same two colours. Written on <html> the way --warm is (settings-look.js;
     EXPORT: prefs.js `contrast` -> cssVars "--contrast", absent at 0). */
  --contrast: 0;
  /* the saturation is CAPPED (30 Sep, ASKS #172): 14 + 9 x warmth passed 100 % at Cream, so Amber and Candle
     clipped to a lemon (255, 255, 190 -- hue 60) and the ink to an orange (98, 65, 0). At 70 % / 45 % the warm
     end is candlelight on cream, hue 48 held; Paper and Ivory are exactly what they were. */
  --ground: hsl(48 min(calc(14% + var(--warm) * 9%), 70%) calc(98.5% - var(--warm) * 0.6% + var(--contrast) * 0.3%));
  --ink:    hsl(42 min(calc(18% + var(--warm) * 6%), 45%) max(calc(7% + var(--warm) * 1% - var(--contrast) * 3.5%), calc(7% + var(--warm) * 1% - var(--contrast) * 17.5%)));
  --dim:    #7a776d;
  --rule:   #dedcd4;

  /* --- the type -------------------------------------------------------- */
  --serif: "Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
  --ui: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --optical: 1.06;         /* the reference is exactly 1.0; 1.06 was chosen */

  /* --- the paragraph ---------------------------------------------------- */
  /* DECLARED, at last (14 Sep, fix lane 96). These two were the whole of the
     typeset rhythm and they were written down NOWHERE: page.css spent them as
     `var(--indent, 1.2em)` and `var(--para-gap, 0)`, so the shipped number was
     the literal inside the fallback and bench-typo.html -- which reads them OFF
     the page with getPropertyValue and writes them back -- read an empty string
     and could never agree with what ships (bench-typo.html:20-22 says it holds
     no constant of its own; it now has one to hold). The values are exactly the
     fallbacks, so nothing moves: a printed book indents and does not gap, so
     the gap is here at 0 for a bench to open, not because anything should.   */
  --indent: 1.2em;         /* p.para + p.para text-indent                    */
  --para-gap: 0;           /* and NO gap as well: a gap AND an indent is a web page */

  /* --- the measure, and the three standard boxes ------------------------ */
  /* 865 @1440 · 1145 @2000. 50vw, NOT 0.5vw -- vw is one PERCENT.          */
  --measure: calc(145px + 50vw);
  --box-lyric: 22rem;      /* ~47ch  short lyric verse                      */
  --box-verse: 28rem;      /* ~60ch  pentameter, hexameter, a speech line   */
                           /* the third box is --measure itself, ~73ch      */

  /* --- the chrome -- every surface's own palette (O22, 25 Sep) ----------- */
  /* These are the colours the Library, Settings, the bar and voiceui share.
     tokens.css is the ONLY home for colour: no shell .css outside this file
     may contain a #hex, rgb() or hsl() literal (test-token-gate.js asserts
     it). The reader's own page colours are --ground/--ink/--dim/--rule above;
     these are the CHROME around it -- the window, the controls, the panels.
     Dark variants follow the same [data-theme] / @media pattern as the
     reader's own colours above. */
  --chrome-bg: #fcfcfb;
  --chrome-fg: #0b0b0b;
  --chrome-fg-dim: #52514f;
  --chrome-accent: #832f2b;
  --chrome-border: #e4e3e0;
  --chrome-panel-bg: #ffffff;
  --chrome-link: #832f2b;
  --chrome-control-bg: #f5f5f3;
  --chrome-ok: #3f7a45;
  --chrome-bad: #a03328;
  --chrome-warn: #b4622a;
  --chrome-ui-font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI Variable Text",
             "Segoe UI", Inter, system-ui, "Helvetica Neue", Arial, sans-serif;

  /* warmth: the library/settings can warm the paper the same way the reader
     does, so these warm-endpoint colours are shared */
  --chrome-paper-warm: #f4e6cb;
  --chrome-ink-warm: #2a2016;

  /* the bar's own chrome colours */
  --bar-ground: #fcfcfb;
  --bar-ink: #17150f;
  --bar-dim: #9c988c;
  --bar-accent: #b3382c;
  --bar-tab-ink: #4a473f;
  --bar-title-bg: rgba(252,252,251,.86);
  --bar-title-bg-solid: rgba(252,252,251,.98);
  --bar-shadow: rgba(0,0,0,.07);

  /* the bar's traffic lights (Mac only, design/reader/bar.css) */
  --bar-close: #FF5F57;
  --bar-close-active: #E0443E;
  --bar-minimise: #FEBC2E;
  --bar-minimise-active: #DEA123;
  --bar-zoom: #28C840;
  --bar-zoom-active: #1AAD2B;
  --bar-dot-off: #D6D6D6;
  --bar-dot-off-active: #BEBEBE;

  /* pbar: the phone bottom bar (design/reader/pbar.css) */
  --pbar-fg: #0b0b0b;
  --pbar-bg: #fcfcfb;
  --pbar-border: #e4e3e0;
  --pbar-dim: #7a776d;
  --pbar-mic: #e0603a;

  /* listen (design/reader/listen.css) */
  --listen-ink: #17150f;
  --listen-ground: #fbfaf7;
  --listen-dim: #7a776d;
  --listen-rule: #dedcd4;

  /* chrome.css: the separator rules */
  --chrome-sep: rgba(11, 11, 11, 0.15);
  --chrome-sep-fg: #0b0b0b;
  --chrome-sep-strong: rgba(11, 11, 11, 0.30);

  /* scrub colours (design/reader/scrub.css) */
  --scrub-accent: #0a84ff;
  --scrub-track: #d9d6d0;
  --scrub-thumb: #ffffff;

  /* marginalia speaker colours (design/reader/marginalia.css) */
  --mg-green: #4a8f3c;
  --mg-gold: #d8b431;
  --mg-red: #c0453a;
  --mg-pink: #c9558f;

  /* wordview colours (design/reader/wordview.css) */
  --wv-accent: #c02c46;
  --wv-accent-light: #e0526a;

  /* surface colours (design/reader/surface.css) */
  --sf-ok: #3f7a4a;
  --sf-warn: #a8532a;
  --sf-hover-light: rgba(127,127,127,.07);
  --sf-hover-mid: rgba(127,127,127,.10);
  --sf-hover-strong: rgba(127,127,127,.12);
  --sf-scrim-light: rgba(0,0,0,.28);
  --sf-scrim-faint: rgba(0,0,0,.10);
  --sf-muted: #888;

  /* page (design/reader/page.css) */
  --page-muted: #999;

  /* lanes strip (bar/lanes.css) */
  --lane-default: #8c2f2f;
  --lane-failed: #b3382c;
  --lane-stripe-light: rgba(255, 255, 255, .45);
  --lane-bg: rgba(128, 128, 128, .16);

  /* shadow tokens: the shadows that appear across surfaces */
  --shadow-light: rgba(0,0,0,.06);
  --shadow-sm: rgba(0,0,0,.07);
  --shadow-md: rgba(0,0,0,.14);
  --shadow-lg: rgba(0,0,0,.25);
  --shadow-xl: rgba(0,0,0,.3);
  --shadow-xxl: rgba(0,0,0,.35);
  --shadow-bench: rgba(0,0,0,.10);

  /* askbar-specific tokens */
  --ask-bg: var(--bar-ground);
  --ask-ink: var(--bar-ink);
  --ask-dim: var(--bar-dim);
  --ask-accent: var(--bar-accent);
  --ask-border: rgba(0, 0, 0, .09);
  --ask-shadow-lg: rgba(0, 0, 0, .17);
  --ask-shadow-sm: rgba(0, 0, 0, .07);
  --ask-hover: rgba(128, 128, 128, .16);
  --ask-rule: rgba(128, 128, 128, .18);
  --ask-control-border: rgba(128, 128, 128, .3);
  --ask-track-bg: rgba(128, 128, 128, .25);
  --ask-band-bg: rgba(128, 128, 128, .18);
  --ask-match-bg: rgba(40, 140, 70, .18);
  --ask-nomatch-bg: rgba(179, 56, 44, .18);
  --ask-nomatch-fg: #b3382c;

  /* askbar dark */
  --ask-dark-bad: #e0736a;
  --ask-dark-bg: #17171a;
  --ask-dark-fg: #e8e7e6;
  --ask-dark-border: #2a2a2e;
  --ask-dark-shadow-lg: rgba(0, 0, 0, .5);
  --ask-dark-shadow-sm: rgba(0, 0, 0, .35);
  --ask-dark-control-bg: rgba(255,255,255,.05);
  --ask-dark-control-border: #33333a;

  /* cursor highlight */
  --cursor-bg: rgba(168, 82, 42, var(--wt-a, .18));

  /* cover pairings: 20 paper/ink pairs for the library covers */
  --cov-p1-paper: #efe7d6;  --cov-p1-ink: #2a2521;
  --cov-p2-paper: #2f3a45;  --cov-p2-ink: #e9e4d8;
  --cov-p3-paper: #7b2d26;  --cov-p3-ink: #f2e8dc;
  --cov-p4-paper: #4f6152;  --cov-p4-ink: #eef0e6;
  --cov-p5-paper: #c9a44a;  --cov-p5-ink: #2b2418;
  --cov-p6-paper: #1e1e1c;  --cov-p6-ink: #e6e1d6;
  --cov-p7-paper: #243f6b;  --cov-p7-ink: #e9ecf3;
  --cov-p8-paper: #5a3557;  --cov-p8-ink: #f1e8f0;
  --cov-p9-paper: #b84a3a;  --cov-p9-ink: #fbeee6;
  --cov-p10-paper: #2f5d5a; --cov-p10-ink: #e6f0ee;
  --cov-p11-paper: #8a6f3c; --cov-p11-ink: #f6efe0;
  --cov-p12-paper: #d9c7a3; --cov-p12-ink: #2b2418;
  --cov-p13-paper: #3b3b6b; --cov-p13-ink: #ecebf5;
  --cov-p14-paper: #6b7b3b; --cov-p14-ink: #f1f3e4;
  --cov-p15-paper: #a3564e; --cov-p15-ink: #f7ebe8;
  --cov-p16-paper: #1f3a2e; --cov-p16-ink: #e4efe8;
  --cov-p17-paper: #e3d5c0; --cov-p17-ink: #3a2f24;
  --cov-p18-paper: #4a4a4a; --cov-p18-ink: #f0ede8;
  --cov-p19-paper: #c76b3b; --cov-p19-ink: #fdf1e6;
  --cov-p20-paper: #6a5a8c; --cov-p20-ink: #f1eef7;

  /* --- the UI furniture, and it is spent by every surface ---------------- */
  /* 14 Sep, fix lane 96. 92's LIST 2: 53 distinct px/ms literals across 13
     reader stylesheets against 16 tokens, and marginalia.css the worst ratio
     in the module at 33 literals to 2 var(). These are the numbers that file
     was spending by hand; each is declared ONCE here, at exactly the value it
     already had, so nothing moves. The ladder is LIST 2's own recommendation
     and the next stylesheet to be folded in takes its names from here rather
     than adding more.                                                       */
  --tap: 44px;             /* the touch floor -- design/phone's own          */
  --hair: 1px;             /* a hairline border                             */
  --rule-dotted: 1.5px;    /* a note is an underline, never a border        */
  --gap: 8px;              /* the spacing unit a row and a stack are built on */
  --gap-hair: 2px;         /* a caption's own optical inset                  */
  --pad: 12px;             /* a bar's side padding                          */
  --r-ui: 10px;            /* the soft corner a field and a button share     */
  --ui-fine: 13px;         /* a caption, secondary to what it names          */
  --ui-act: 15px;          /* a button's label                              */
  --ui-field: 16px;        /* a text field -- 16 or iOS zooms the page       */

  /* --- the wheel ------------------------------------------------------- */
  --pitch: 168px;          /* Letters' landing is 120; scaled with R        */
  /* --radius IS NOT HERE ANY MORE (5 Sep). It was the one number in this
     "the wheel" group that no stylesheet ever read -- --pitch and --axis are
     both used by wheel.css, --radius only by wheel.js -- and it sat here at
     2.6 while shell.html wrote 60 over it, which is this file's own rule
     broken ("if a number appears twice in this product, one of the two is
     already wrong"). It lives in wheel.js's Wheel.DEFAULTS now, once.
     Setting --radius on :root still overrides it live, which is how the
     tuner and bench-wheel.html's slider work; nothing sets it at rest.          */
  --persp: 900px;          /* the barrel's foreshortening. shell.css spent this
                              as a var() fallback and nothing declared it;
                              reader.html's SET block still writes 6000px inline
                              on <html> at start-up and an inline style beats
                              this, so the app is unmoved -- this is the value
                              every page that does NOT run that block (the
                              benches, float.html, probe.html) was already
                              getting out of the fallback.                    */
  --axis: 46vh;            /* the barrel's centre line                      */
  --start: 38vh;           /* the reading line: a piece's first line        */
}

/* THE FLUID SIZE GOES ON <html>. Every rem in this product resolves against
   it. Put it on <body> and 1rem silently becomes the browser's 16px -- which
   has now cost two days, twice. */
html{ font-size: calc((14.5px + 0.75vw) * var(--optical)); }

/* the reading page's own furniture, measured off the reference at 1440 */
:root{
  --scrub-w:150px; --label-w:190px; --label-h:29px; --label-fs:14.67px;
  --head-w:288px;  --head-h:70px;
}
/* DARK IS A PALETTE SWAP AND NOTHING ELSE. Same measures, same rhythm, same
   boxes -- only the four colours move, which is why it lives beside them.
   WARMTH REACHES DARK TOO (3 Sep, Osca: "Yes" to wiring it up) -- the same
   --warm scalar, so the big slider never goes dead just because dark is on.
   At --warm:0 this is pixel-identical to the hand-picked #131316/#e8e7e6 it
   replaces (solved for exactly, not eyeballed); the cool end (-2) settles to
   a slightly deeper, fully neutral near-black -- there is no "whiter" a dark
   ground can go, so cool reads as the most NEUTRAL black rather than the
   brightest; the warm end (18) swings the hue itself, 240 (blue-black) down
   toward 48 (the paper's own amber), the way the light ground never needs
   to -- a dark ground starts on the opposite side of the wheel from
   candlelight, so warming it is a hue turn, not just a saturation push. */
/* AND WHAT SWITCHES IT IS prefs/, ONLY (Osca, 6 Sep: *"I do NOT want a button
   for light/dark. Settings drives it."*). The three selectors below are the
   ones settings/settings.js already writes against, so one store paints every
   surface with no reload and no second copy of the value: an explicit choice
   stamps html[data-theme="dark"] or ="light", and "system" -- prefs's own
   default -- stamps nothing at all and leaves the media query in charge.
   `html[data-dark]` is kept in the first list and NOWHERE ELSE, because
   bench-panes.html, bench-wheel.html, bench-library.html and bench-page.html still carry
   their own dark buttons and this pass is not about them; shell.html's own
   toggle is gone and nothing in the app has ever written that attribute.
   Note what the media query means for those benches on a machine set to dark:
   they now open dark, the way the app does. That is the point of it. */
html[data-theme="dark"], html[data-dark]{
  --ground: hsl(240 calc(7.3% - var(--warm) * 0.4%) calc(8.04% + var(--warm) * 0.28% - var(--contrast) * 0.4%));
  --ink:    hsl(30 calc(4.17% + var(--warm) * 2.2%) min(calc(90.59% - var(--warm) * 0.25% + var(--contrast) * 2%), calc(90.59% - var(--warm) * 0.25% + var(--contrast) * 15%)));
  --dim:#8c8a83; --rule:#2e2e33;

  /* chrome dark */
  --chrome-bg: #131316; --chrome-fg: #e8e7e6; --chrome-fg-dim: #98979b;
  --chrome-accent: #d9736a; --chrome-border: #2c2c32; --chrome-panel-bg: #1a1a1f;
  --chrome-link: #c9c4bb; --chrome-control-bg: #1a1a1f;
  --chrome-ok: #7fc08a; --chrome-bad: #d98a7a;
  --chrome-paper-warm: #1b1610; --chrome-ink-warm: #efe6d5;
  --ask-dark-bad: #e0736a;
  --ask-dark-bg: #17171a; --ask-dark-fg: #e8e7e6; --ask-dark-border: #2a2a2e;
}
@media (prefers-color-scheme: dark){
  html:not([data-theme="light"]){
    --ground: hsl(240 calc(7.3% - var(--warm) * 0.4%) calc(8.04% + var(--warm) * 0.28% - var(--contrast) * 0.4%));
    --ink:    hsl(30 calc(4.17% + var(--warm) * 2.2%) min(calc(90.59% - var(--warm) * 0.25% + var(--contrast) * 2%), calc(90.59% - var(--warm) * 0.25% + var(--contrast) * 15%)));
    --dim:#8c8a83; --rule:#2e2e33;

    /* chrome dark */
    --chrome-bg: #131316; --chrome-fg: #e8e7e6; --chrome-fg-dim: #98979b;
    --chrome-accent: #d9736a; --chrome-border: #2c2c32; --chrome-panel-bg: #1a1a1f;
    --chrome-link: #c9c4bb; --chrome-control-bg: #1a1a1f;
    --chrome-ok: #7fc08a; --chrome-bad: #d98a7a;
    --chrome-paper-warm: #1b1610; --chrome-ink-warm: #efe6d5;
    --ask-dark-bad: #e0736a;
    --ask-dark-bg: #17171a; --ask-dark-fg: #e8e7e6; --ask-dark-border: #2a2a2e;
  }
}

/* WARMTH IN DARK NEVER PASSES THROUGH GREEN, AND THE CHROME WEARS THE PAPER (ASKS #172 + #179, Osca 30 Sep:
   "if you do want to use colours in dark mode, it'd only either be from warmth inverted OR from the frank red";
   "the reading settings etc, aren't effecting settings either, they should"; "the general settings aren't
   effecting library really, but they should").
   1. THE DARK GROUND. It used to TURN its hue 240 -> 48 with warmth, a straight line round the wheel (the note
      above the dark block) -- and the stops between were cyan (Ivory, 192), GREEN (Cream, 144) and
      yellow-green (Amber, 96): three of the five papers were green-black. Now it is a MIX, in oklab, of the
      neutral blue-black (#131316 at warmth 0, exactly as before) and a brown-black (warmth 18): a straight
      line in a perceptual space from a near-grey to a brown crosses no green. The whites warm the way they
      always did (ink, hue 30). An engine without color-mix keeps the hsl above: the same blue-black, going
      greyer with warmth, never green.
   2. THE CHROME IS THE PAPER. --chrome-bg / --chrome-fg ARE --ground / --ink, and the other chrome colours
      are mixed from those two -- so every page drawn in the chrome palette (Settings, the Library, the band,
      the Surface) takes warmth, contrast and light/dark from the same numbers as the page of a book. At
      warmth 0 and contrast 0 each lands within a few units of the literal it replaces.
   3. THE ACCENT IN DARK IS FRANK'S RED (ASKS #7, e752409 -- #d9736a, held till now only in tokens.design.json).
   Behind @supports for the reason library.css gives: a custom property takes any tokens, and an engine that
   cannot compute color-mix would otherwise paint `unset`. */
@supports (color: color-mix(in oklab, #000, #fff 50%)){
  :root{
    --chrome-bg: var(--ground);
    --chrome-fg: var(--ink);
    --chrome-fg-dim: color-mix(in oklab, var(--ink) 70%, var(--ground));
    --chrome-panel-bg: color-mix(in oklab, var(--ground), #fff 70%);
    --chrome-control-bg: color-mix(in oklab, var(--ground) 96%, var(--ink));
    --chrome-border: color-mix(in oklab, var(--ground) 88%, var(--ink));
  }
  html[data-theme="dark"], html[data-dark]{
    --ground: color-mix(in oklab, hsl(240 7.3% calc(8.04% - var(--contrast) * 0.4%)),
      hsl(30 38% calc(12% - var(--contrast) * 0.4%)) calc(var(--warm) * 5.5556%));
    --chrome-bg: var(--ground);
    --chrome-fg: var(--ink);
    --chrome-fg-dim: color-mix(in oklab, var(--ink) 62%, var(--ground));
    --chrome-panel-bg: color-mix(in oklab, var(--ground) 95%, var(--ink));
    --chrome-control-bg: color-mix(in oklab, var(--ground) 95%, var(--ink));
    --chrome-border: color-mix(in oklab, var(--ground) 86%, var(--ink));
  }
  @media (prefers-color-scheme: dark){
    html:not([data-theme="light"]){
      --ground: color-mix(in oklab, hsl(240 7.3% calc(8.04% - var(--contrast) * 0.4%)),
        hsl(30 38% calc(12% - var(--contrast) * 0.4%)) calc(var(--warm) * 5.5556%));
      --chrome-bg: var(--ground);
      --chrome-fg: var(--ink);
      --chrome-fg-dim: color-mix(in oklab, var(--ink) 62%, var(--ground));
      --chrome-panel-bg: color-mix(in oklab, var(--ground) 95%, var(--ink));
      --chrome-control-bg: color-mix(in oklab, var(--ground) 95%, var(--ink));
      --chrome-border: color-mix(in oklab, var(--ground) 86%, var(--ink));
    }
  }
}
