/* =====================================================================================================
   yfile — tokens.css. Lift step 3 (SHELL). Three sections, deliberately kept apart:

     §1  THE 11 INHERITED TOKENS. The nine vault stylesheets USE these and never DEFINE them; in the
         estate the host defined them (chrome.css / mobile.css). Their values are COPIED VERBATIM from
         C:/Users/y/transcribe/gateway/pwa/chrome.css:14-36,236 and mobile.css:45-48, read 2026-08-26.
         They are NOT design choices yfile is free to retune — vault.css computes against them
         (vault.css:631 --vlt-reach-top, :1010/:1153/:1425 the tap targets) — so re-tuning them here
         would silently move geometry inside 110 KB of stylesheet nobody re-measured. All eleven
         declarations below are byte-verbatim, --chrome-h included. That last one is ALSO measured at
         runtime by app.js, because in the estate its CSS number is only a fallback — see its own note.

     §2  THE 7 @font-face RULES for the 7 captured woff2 in fonts/. Verbatim from chrome.css:796-806.

     §3  THE SHELL'S OWN CHROME — the page frame and the 3-control toolbar. This is the only part of
         this file yfile AUTHORS, so it is the only part the golden-ratio palette governs. Every colour
         below is a value emitted by C:/Users/y/yfile-work/gauntlet/seam/palette.py (selftest PASS,
         run 2026-08-26): the 8-step grey ladder 255/158/97/60/37/23/14/0, the core colours whose RGB
         components come from {0,97,158,255}, and the alpha ladder 0.618^n for tints. Sizes and spacing
         step by 1.618 (palette.py scale(16) = 6.111 / 9.889 / 16 / 25.889).

   No inline <style> and no style="" in the shell's MARKUP: it is authored to survive step 7's
   `style-src 'self'` unchanged. The one thing yfile sets at runtime — app.js's measured --chrome-h —
   goes through CSSOM (element.style.setProperty), which is the estate's own CSP-safe idiom and is
   stated as such at chrome-metrics.js:1-2. Measured under `style-src 'self'`, not assumed.
   ===================================================================================================== */

/* -- §1 INHERITED TOKENS — verbatim host values, not yfile's to retune ------------------------------ */
:root {
  color-scheme: light dark;

  /* chrome.css:15-17 */
  --muted: color-mix(in oklch, var(--ink), transparent 45%);
  --edge:  color-mix(in oklch, var(--ink), transparent 86%);
  --font:  ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* chrome.css:20-22 — DARK is the default surface set, as it is in the estate */
  --paper: #0b0d12;
  --ink:   #eef1f6;
  --accent: oklch(0.72 0.17 275);

  /* chrome.css:25-26 — the pre-JS env() fallback; the estate hydrates these to px, yfile does not yet */
  --sat: env(safe-area-inset-top, 0px);
  --sab: env(safe-area-inset-bottom, 0px);

  /* mobile.css:46-47 */
  --ytx-tap-ico:  32px;
  --ytx-tap-ceil: 44px;   /* the ceiling, for reference — never assigned to a control */

  /* chrome.css:236 — copied verbatim like the ten above, and, like the ten above, NOT retuned.
     RULING (round 2, on gap C6). This token is the one whose estate value is not a number but a
     MEASUREMENT, and the estate says so itself:
       · chrome-metrics.js:5-8 — "Publish the REAL base height of the fixed #chrome bar … the 60/78px
         in CSS is only the pre-JS fallback";
       · chrome-metrics.js:39-43 — setProperty("--chrome-h", measured + "px") at boot, refreshed on
         fonts.ready, at 120/400/1000ms, on a ResizeObserver, on resize and on rotate;
       · and the estate declares THREE different CSS values for it — 60px here, 56px at chrome.css:295
         (@media max-width:820px), and 56px at vplayer.css:15, a SECOND estate page that copies this
         same inherited token set verbatim and then gives --chrome-h its own bar's height.
     So "the host's real value" for this token is "the height of THIS page's own chrome", and its one
     consumer in the nine captured sheets — vault.css:631 --vlt-reach-top — reads it exactly that way.
     Both halves are therefore carried here and nowhere else: the verbatim fallback is this line, and
     app.js's measureChromeH() is the host's own mechanism, publishing the measured px over it. The
     previous round carried only the second half (`var(--yf-bar-h)`), which was geometrically right and
     textually not a copy; the fallback alone would be textually right and 3.2px wrong on this page. */
  --chrome-h: 60px;
}
html[data-scheme="light"] {
  color-scheme: light;
  /* chrome.css:32-35 */
  --paper: #f6f7fb;
  --ink:   #12141a;
  --accent: oklch(0.58 0.2 275);
}
html[data-scheme="dark"] { color-scheme: dark; }

/* -- §2 FONTS — the 7 captured faces, verbatim from chrome.css:796-806 ------------------------------ */
@font-face { font-family:'Comfortaa'; src:url('fonts/comfortaa-400.woff2') format('woff2'); font-weight:400; font-display:swap; }
@font-face { font-family:'Comfortaa'; src:url('fonts/comfortaa-700.woff2') format('woff2'); font-weight:700; font-display:swap; }
@font-face { font-family:'Atkinson Hyperlegible'; src:url('fonts/atkinson-400.woff2') format('woff2'); font-weight:400; font-display:swap; }
@font-face { font-family:'Archivo'; src:url('fonts/archivo.woff2') format('woff2'); font-weight:400; font-display:swap; }
@font-face { font-family:'Archivo Narrow'; src:url('fonts/archivo-narrow.woff2') format('woff2'); font-weight:400; font-display:swap; }
@font-face { font-family:'JetBrains Mono'; src:url('fonts/jetbrains-mono.woff2') format('woff2'); font-weight:400; font-display:swap; }
@font-face { font-family:'Inter'; src:url('fonts/inter-var.woff2') format('woff2'); font-weight:100 900; font-display:swap; }

/* -- §3 THE SHELL — golden-ratio palette (palette.py), yfile's own ---------------------------------- */
:root {
  /* MEASURE — palette.py scale(16), the 1.618 modular scale. */
  --yf-s0: 6.111px;
  --yf-s1: 9.889px;
  --yf-s2: 16px;
  --yf-s3: 25.889px;
  --yf-fs: 16px;          /* one size for the whole shell: the scale's next step down is 9.889px, which
                             is not a readable UI size, and 16px is also the threshold below which iOS
                             Safari zooms a focused input. Density comes from colour and weight, not size. */
  --yf-ctl: 36px;         /* control height. Matches mobile.css's --ytx-tap floor; --ytx-tap-ico (32px)
                             is the icon-only square inside it; --ytx-tap-ceil (44px) is never exceeded. */
  --yf-bar-h: calc(var(--yf-ctl) + var(--yf-s1) * 2 + 1px);   /* control + padding + the 1px hairline */
  --yf-shell-h: calc(var(--yf-bar-h) + var(--yf-s1) + var(--sat) + var(--sab));
  --yf-r1: 9.889px;       /* control radius */
  --yf-r2: 16px;          /* frame radius */

  /* HUE — core colours, RGB components drawn from {0, 97, 158, 255}. */
  --yf-accent:  #0061ff;  /* palette.py SEMANTIC.accent  (0, 97, 255) */
  --yf-accent2: #619eff;  /* palette.py SEMANTIC.accent2 (97, 158, 255) — the dark-surface accent */
  --yf-fail:    #ff6161;  /* palette.py SEMANTIC.fail    (255, 97, 97) */

  /* SURFACE, dark. Greys are ladder steps; tints are alpha = 0.618^n. */
  --yf-bar:      #171717;                  /* grey ladder step 6 (23) */
  --yf-bar-edge: rgb(255 255 255 / .0901); /* alpha ladder step 5 */
  --yf-ctl-bg:   rgb(255 255 255 / .0557); /* alpha ladder step 6 */
  --yf-ctl-edge: rgb(255 255 255 / .1459); /* alpha ladder step 4 */
  --yf-ctl-hov:  rgb(255 255 255 / .1459);
  --yf-ctl-ink:  #ffffff;                  /* grey ladder step 1 (255) */
  --yf-dim:      #9e9e9e;                  /* grey ladder step 2 (158) — 6.6:1 on #171717 */
  --yf-focus:    var(--yf-accent2);
  --yf-panel:    #252525;                  /* grey ladder step 5 (37) */
}
html[data-scheme="light"] {
  --yf-bar:      #ffffff;
  --yf-bar-edge: rgb(97 97 97 / .236);     /* alpha ladder step 3 */
  --yf-ctl-bg:   rgb(14 14 14 / .0557);    /* alpha ladder step 6 — one step up from 7, which read as
                                              no affordance at all against a white bar (seen in the
                                              light-scheme capture, not guessed) */
  --yf-ctl-edge: rgb(14 14 14 / .1459);    /* alpha ladder step 4 */
  --yf-ctl-hov:  rgb(14 14 14 / .0901);    /* alpha ladder step 5 */
  --yf-ctl-ink:  #0e0e0e;                  /* grey ladder step 7 (14) — 18.9:1 on #ffffff */
  --yf-dim:      #616161;                  /* grey ladder step 3 (97) — 5.9:1 on #ffffff */
  --yf-focus:    var(--yf-accent);
  --yf-panel:    #ffffff;
}

*, *::before, *::after { box-sizing: border-box; }
html { block-size: 100%; background: var(--paper); overscroll-behavior: none; }
body {
  margin: 0; min-block-size: 100dvh;
  padding-block: var(--sat) var(--sab);
  display: flex; flex-direction: column;
  background: var(--paper); color: var(--ink);
  font-family: var(--font); font-size: var(--yf-fs);
  overscroll-behavior: none;
  -webkit-font-smoothing: antialiased;
}
.yf-sr { position: absolute; inline-size: 1px; block-size: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* --- the bar --------------------------------------------------------------------------------------- */
.yf-bar {
  flex: 0 0 auto; block-size: var(--yf-bar-h);
  display: flex; align-items: center; gap: var(--yf-s1);
  padding-inline: var(--yf-s1);
  background: var(--yf-bar);
  border-block-end: 1px solid var(--yf-bar-edge);
}
.yf-brand { display: flex; align-items: center; gap: var(--yf-s0); flex: none; text-decoration: none; color: inherit; }
.yf-brand__mark {
  inline-size: 18px; block-size: 18px; border-radius: var(--yf-s0); flex: none;
  /* the one place the brand colour is stated: core colour (0, 97, 255) into (97, 158, 255) */
  background: linear-gradient(135deg, var(--yf-accent), var(--yf-accent2));
}
.yf-brand__txt { font-family: 'Comfortaa', ui-rounded, var(--font); font-weight: 700; letter-spacing: .01em; }

.yf-tools { flex: 1 1 auto; min-inline-size: 0; display: flex; align-items: center; gap: var(--yf-s1); justify-content: flex-end; }

.yf-btn {
  flex: none; display: inline-flex; align-items: center; justify-content: center; gap: var(--yf-s0);
  block-size: var(--yf-ctl); min-inline-size: var(--yf-ctl);
  padding-inline: var(--yf-s1);
  font: inherit; color: var(--yf-ctl-ink);
  background: var(--yf-ctl-bg); border: 1px solid var(--yf-ctl-edge); border-radius: var(--yf-r1);
  cursor: pointer;
}
.yf-btn:hover { background: var(--yf-ctl-hov); }
.yf-btn:active { transform: translateY(1px); }
.yf-btn--ico { padding-inline: 0; inline-size: var(--yf-ctl); }
.yf-btn .ico, .yf-search__ic .ico { inline-size: 1em; block-size: 1em; flex: none; vertical-align: -.125em; }

.yf-search { position: relative; flex: 1 1 auto; min-inline-size: 0; max-inline-size: 420px; }
.yf-search__ic {
  position: absolute; inset-block: 0; inset-inline-start: var(--yf-s1);
  display: grid; place-items: center; pointer-events: none; color: var(--yf-dim);
}
.yf-field {
  inline-size: 100%; block-size: var(--yf-ctl);
  padding-inline: calc(var(--yf-s1) * 2 + 1em) var(--yf-s1);
  font: inherit; color: var(--yf-ctl-ink);
  background: var(--yf-ctl-bg); border: 1px solid var(--yf-ctl-edge); border-radius: var(--yf-r1);
}
.yf-field::placeholder { color: var(--yf-dim); }

:where(.yf-btn, .yf-field, .yf-brand):focus-visible { outline: 2px solid var(--yf-focus); outline-offset: 2px; }

/* --- the search result panel (shell-owned; see app.js for what it deliberately does NOT do) --------- */
.yf-results {
  position: absolute; inset-inline: 0; inset-block-start: calc(var(--yf-ctl) + var(--yf-s0));
  z-index: 40; max-block-size: min(60dvh, 420px); overflow-y: auto;
  padding: var(--yf-s0);
  background: var(--yf-panel); color: var(--yf-ctl-ink);
  border: 1px solid var(--yf-ctl-edge); border-radius: var(--yf-r1);
  box-shadow: 0 var(--yf-s3) calc(var(--yf-s3) * 1.618) calc(var(--yf-s1) * -1) rgb(0 0 0 / .3819);
}
.yf-results[hidden] { display: none; }
.yf-results__head { margin: 0; padding: var(--yf-s0) var(--yf-s1); color: var(--yf-dim); }
.yf-results__list { list-style: none; margin: 0; padding: 0; }
.yf-results__i { padding: var(--yf-s0) var(--yf-s1); border-block-start: 1px solid var(--yf-ctl-edge); }
.yf-results__n { display: block; overflow-wrap: anywhere; }
.yf-results__m { display: block; color: var(--yf-dim); overflow-wrap: anywhere; }
.yf-results__i mark { background: color-mix(in oklch, var(--yf-focus), transparent 62%); color: var(--yf-ctl-ink); border-radius: 3px; padding-inline: 1px; }

/* --- the vault's host box --------------------------------------------------------------------------
   .vlt is `block-size: 100%` (vault.css:113), so this box MUST resolve a height or nothing paints.
   The estate's own clamp is library.css:573 `clamp(300px, calc(100dvh - 28rem), 900px)`, where 28rem
   measures the ESTATE's accordion chrome. yfile has no accordion, so the subtrahend is DERIVED from
   this shell's own bar instead of copied. The 336px floor IS copied, deliberately: it is R289/§282
   wave-2 FINDING-1's measured minimum (dock 50 + menubar 47 + toolbar 97 + status 44 = 238px of
   permanent vault chrome, plus two rows), and below it the vault's own list body goes unusable.
   Below the floor the PAGE scrolls — an unusable list is worse than a scrolled page. */
.yf-main { flex: 1 1 auto; min-block-size: 0; display: flex; padding: 0 var(--yf-s1) var(--yf-s1); }
.lib-vault {
  position: relative; flex: 1 1 auto; min-inline-size: 0;
  block-size: clamp(336px, calc(100dvh - var(--yf-shell-h)), 100dvh);
  border: 1px solid var(--edge); border-radius: var(--yf-r2); overflow: hidden;
}
.lib-vault[data-yf="booting"]::before,
.lib-vault[data-yf="failed"]::before {
  content: "Opening your library…"; position: absolute; inset: 0; z-index: 1;
  display: grid; place-items: center; padding: var(--yf-s2); text-align: center;
  background: var(--paper); color: var(--yf-dim);
}
.lib-vault[data-yf="failed"]::before { content: "Your library did not open. Reload the page to try again."; color: var(--yf-fail); }

/* --- narrow: the labels go, the controls stay ------------------------------------------------------- */
@media (max-width: 640px) {
  .yf-brand__txt { display: none; }
  .yf-btn__lbl { display: none; }
  .yf-btn { padding-inline: 0; inline-size: var(--yf-ctl); }
  .lib-vault { border-radius: 12px; }
}
@media (pointer: coarse) {
  /* THE FLOOR, NOT THE CEILING, and min- not a fixed size. Corrected 2026-08-27 (R310).
     This block previously read `block-size: var(--ytx-tap-ceil)`, which contradicted the token's own
     comment copied verbatim 191 lines above at :48 — "the ceiling, for reference — never assigned to a
     control" — and inverted the estate's pattern. mobile.css:49-62 assigns `min-block-size:
     var(--ytx-tap)`, the 36px FLOOR, to every actionable control and never spends the ceiling. A fixed
     `block-size` at the ceiling is worse than the wrong token alone: it PINS every button and the search
     field at exactly 44px on a touch device instead of letting them grow past it, so a control whose
     content needs more room gets clipped rather than floored.
     --ytx-tap (36px) is not one of the eleven inherited tokens, so the floor is spent as --yf-ctl, which
     :96 already records as matching it. Nothing here is retuned; the values are the estate's.
     NOT GATED, and said so rather than left implied: boot-check and behaviour-check both run desktop
     Chromium at `pointer: fine`, so no check in this repo executes this branch. It is verified by
     reading it against mobile.css:49-62, not by a run. */
  .yf-btn, .yf-field { min-block-size: var(--yf-ctl); }
  /* .yf-results__i deliberately carries NO tap floor. app.js:150-155 states the results panel is a
     readout and its rows are not clickable, because no reveal verb is reachable from outside the vault
     (VAULT_CMD_API carries no navigate/reveal/open — measured at vault.js:3462). Spending a tap-target
     token on a non-target is the same error in miniature; its height comes from the padding at :204. */
}
@media (prefers-reduced-motion: reduce) { .yf-btn:active { transform: none; } }
