/* סדר יומי — RTL Hebrew, phone-first, quiet. Source text in Taamey D; UI in Frank Ruhl Libre (D-106,
   the system sans is gone).
   Palette rule: every text/background pair is >= 4.5:1 in all three themes. Verified with
   scratchpad/ux-visual/contrast.py — re-run it after any token change. --line stays decorative
   (rules, dividers). Since D-63 (printed-sefer redesign) --ctl is the STRONG RULE colour (band
   edges, empty checkbox) and --faint the ORNAMENT colour (בס״ד, הגדרות, date chevrons): in sepia they
   sit at ~2:1 on the paper BY DESIGN, so neither may ever colour running text, and affordance
   comes from the frame/rules idiom, not from a 3:1 control border.

   This file is part of the version hash (tools/build_dist.py), so editing it produces a new build
   number — the one shown at the bottom of the settings screen. A revert reuses its old number:
   the number identifies the shell's CONTENT, not the number of times we deployed. */
@font-face { font-family:'TaameyD'; src:url('fonts/Taamey_D.woff2') format('woff2'); font-display:swap; }
/* D-68d: Frank Ruhl Libre (OFL) for the home's kicker and the ledger's portion column — the two
   places that were still the system sans. Google's own two subsets, shipped and precached like the
   other faces, never fetched at runtime. Keep the unicode-ranges: the latin file is what carries
   «·», the en dash and digits, and without them Hebrew would pull the larger latin file.
   NOT a fallback for Taamey D anywhere: Frank Ruhl's CLM sibling collides on 4.4% of cantillated
   words, and this is unpointed UI text only. */
@font-face { font-family:'FrankRuhl'; src:url('fonts/FrankRuhlLibre-hebrew.woff2') format('woff2'); font-display:swap;
  unicode-range:U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F; }
@font-face { font-family:'FrankRuhl'; src:url('fonts/FrankRuhlLibre-latin.woff2') format('woff2'); font-display:swap;
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
/* כתב רש״י for רש״י/תוספות text, opt-in (D-53/D-54): Mekorot (Google's 2023 redraw of the classic printed
   Rashi, OFL), chosen from a four-face specimen; precached with the shell, never fetched at runtime */
@font-face { font-family:'RashiScript'; src:url('fonts/Mekorot.woff2') format('woff2'); font-display:swap; unicode-range:U+0590-05FF, U+FB1D-FB4F; }
/* Mekorot's letter body is 1.30x Taamey D's at the same nominal size (median letter height .725 vs
   .558 em; 21 vs 15 px rendered at 20px; 1.4x by canvas measurement). Letter-body parity with the
   square commentary (panes at 90% → .9 / 1.4 ≈ .60) READ TOO SMALL, and .98 read too large — the eye
   wants Rashi a step above parity, so the size is not derived from metrics: default .78, and a dial
   (--rashi-size, 55-110%, set by app.js from the `rashi_size` hint) in Aa + settings so the operator
   settles it (D-55). Keep the measurements; do not re-derive the factor from them. */
html.rashi-font .cmt, html.rashi-font .rashi p { font-family:var(--font-rashi); font-size:var(--fs-rashi); line-height:calc(var(--lh-cmt) * 1.12); }
/* D-192: the switch is labelled «כתב רש״י לרש״י ותוספות» and means exactly that, but the rule above
   reaches EVERY `.cmt` — so with the toggle on, שולחן ערוך's משנה ברורה / מגן אברהם / ט״ז notes were
   being set in כתב רש״י too. Operator, 2026-09-23: «Rama and commentaries for shulhan arukh should
   not use rashi font». The sefer sheets carry `.sefer` and opt back out to the reading face. */
html.rashi-font .sheet-bg.sefer .cmt { font-family:var(--font-src);
  font-size:var(--fs-cmt); line-height:var(--lh-cmt); }

/* ---------- palette: light on :root; dark / sepia swap on [data-theme]; system follows the OS ---------- */
:root {
  --bg:#fbfaf6; --card:#ffffff; --ink:#22242a; --dim:#575651; --mute:#6b6a63;
  --accent:#1a2a4a; --gold:#7e6838; --soft:#f1ece0; --line:#e6e1d4; --ctl:#8a8676;
  --ok:#487448; --onk:#5a6b8a; --stz:#4a5163; --stz-bg:#f6f4ee;
  --btn-bg:#1a2a4a; --btn-ink:#fbfaf6;
  --shadow:rgba(20,24,40,.18); --scrim:rgba(20,24,40,.42);
  --hasc:#2b3a66;                 /* text a commentary speaks to: ink shifted toward the accent */
  /* D-191: the three commentary series — distinct HUES, not three browns. The reasoning and
     the per-book assignment are at `i[data-ly]::after`. */
  --ly-a:#8a6a20; --ly-b:#1f4f8f; --ly-c:#8a2740; --ly-d:#2f6b3a; --ly-e:#6b3f8f; --ly-f:#9a2a78;
  --sheva:#7a1f2b;                /* sheva na: bordeaux — navy read as ink on sepia (operator, 2026-08-30) */
  /* D-63 page frame (theme-neutral structure; the sepia values are the design's, these derive
     from this theme's own rules): frame hairline, corner ticks, ornament glyphs, part-read fill */
  --frame:#d3cdbd; --tick:#7e6838; --faint:#86826f; --fill:#e2ddcf; --okfill:#dde7d7;
  --okwedge:#8fb089; --stripe:#f0f3f8;   /* D-252: the home mark's part-read wedge; the two-column ledger's every other row */
  --okdone:#e2ecdd; --ring:#a19d8f;      /* D-252: the home mark's done disc and its not-yet ring (the canvas's «עיגול ב») */
  --text-size:20px;
  /* D-107 #2 (operator 2026-09-02: «look at the smallest Frank Ruhl size on the screens and
     increase it by 20 %»): the UI floor. It was 12px — the strip cells, the band labels, captions,
     hints, the settings rules, the colophon — and everything that sat on or just above it (12,
     12.5, 13, .75–.85rem) now sits HERE. One value, not a scaled band: the old sub-13px steps were
     width compromises (eight cells in a strip), not hierarchy, and a proportional band would have
     lifted 13px captions over their own 14.4px section heads. The reading text, its verse and
     line numerals and the Taamey D display pieces are not UI and do not move. */
  /* D-203 (operator, 2026-09-24: «16 px should be bare minimum for the app (except footnote
     licenses)» · «go with a low number of tokens to replace all authored values» · for the reader
     «main text size and rashi size and commentary sizes. nothing below 16, and main size a bit
     higher than the others»). The floor is 16 px and EVERY font-size in this file is one of the
     tokens below — 273 declarations had 68 different authored values, 20 of them inside one 4 px
     band (14.0–18.2), and 15px / .95rem were the same size written twice so they could never move
     together. Change a size HERE, never at a rule.
       UI ladder   --fs-floor 16 · --fs-2 18 · --fs-3 21 · --fs-4 26 · --fs-5 34 · --fs-6 60 (clock)
       reader      var(--text-size) = main (the גודל גופן dial, 18–30) · --fs-cmt · --fs-rashi
       exempt      --fs-fine 14.4 — the licence page's fine print and the ✓ glyph in the marks, the
                   only two things the operator allowed under 16
     The home keeps D-68b's one dial: calc(<token> * var(--hs)), so fit8 (--hs:1) lands ON a token
     and the +15% rides above it. Verse numerals (.vn) are no longer exempt — D-107 called them
     ornaments; the operator ruled they go to 16. What is NOT a token, on purpose: `100%` on the
     root, the `1em` <big> neutralisers, D-145's «מתני׳/גמ׳» label (1.18em, the operator's ask),
     D-193's three commentary MARKS (.58/.62/.72em — marks are exempt, and three sizes is the
     design), .rcode's viewport clamp (it keeps a 19-glyph code on one line; bounds are tokens),
     and the daf's inline `button.ln` (.62em): it is an EMPTY tap target since D-82 took the line
     numbers away, so its font-size is geometry, not text — at 16px its .5em raise opened the
     flowing daf's lines by ~1px (measured, D-203), which is what D-145 took pains never to do.
     The reader's commentary ratio is .9 so «main a bit higher»; the size dial starts at 18 (was 16)
     so commentary is never pinned to the floor at the same size as the text above it. */
  --fs-floor:16px; --fs-2:18px; --fs-3:21px; --fs-4:26px; --fs-5:34px; --fs-6:60px;
  --fs-fine:14.4px;
  --fs-cmt: max(var(--fs-floor), calc(var(--text-size) * .9));
  /* D-206 (operator: «the smallest rashi font is too large, why»): because the floor above is NOMINAL
     and Mekorot is not the face it was measured in. Its letter body is 1.304× Taamey D's at the same
     px (median of 20 letters at 100px: 73 vs 56, the real woff2s — D-55 measured the same 1.30), so a
     16px רש״י read as 20.9px of the main text: the dial's BOTTOM was larger than the text it
     comments on. The floor for this one face is therefore 16 × 56/73 = .77 of --fs-floor (12.3px),
     which has exactly the letter height of 16px Taamey D — «nothing below 16», measured by the eye's
     yardstick rather than the font's. The dial starts at 62 % (at the default text size of 20 that
     lands ON this floor, so no stretch of it is dead) and its default is D-55's own 78 again. */
  --fs-rashi: max(calc(var(--fs-floor) * .77), calc(var(--text-size) * var(--rashi-size, .78)));
  /* D-204 (operator: «unify more» · «everything, including spacing, in one go»). Before: 452
     margin/padding and 70 gap declarations carried 281 distinct values written three ways (18 px
     sizes, 23 rem sizes, 26 --sp multipliers); they collapse onto ONE ladder. A spacing that followed
     צפיפות still does (`calc(var(--s-N) * var(--dens))`) and a fixed one stays fixed — D-204 unified
     magnitudes and changed nobody's relationship to the dial — and then D-206 (operator: «spacing
     should follow tsfifut») put EVERY spacing outside the home on the dial: `calc(var(--s-N) *
     var(--dens))`. Kept fixed on purpose: the home (D-168 — it fits itself through fitHome, so a dial
     that grew it would only be compacted back), 1px hairlines, em spacings, and a strip's SIDEWAYS
     padding (a row of 8–9 tabs has a fixed width budget; its cells breathe vertically with the dial).
     Snapped to the nearest step, ties DOWN
     (tighter), so the home only ever gains room: mean move 0.6px, max 4px, 3% moved more than 2px.
     The `em` spacings are typographic (they scale with their text) and stay em. */
  --s-1:1px; --s-2:2px; --s-4:4px; --s-6:6px; --s-8:8px; --s-12:12px; --s-16:16px; --s-24:24px; --s-32:32px; --s-48:48px;
  --font-src:'TaameyD','Taamey Frank CLM','Keter YG',serif;   /* the reading face + the two fallbacks carrying every taam */
  --font-ui:'FrankRuhl','Frank Ruhl Libre',serif;             /* every label, button, control (D-106 #8) */
  --font-rashi:'RashiScript','TaameyD',serif;                  /* כתב רש״י (D-53/D-54) */
  --font-mono:ui-monospace,'Cascadia Mono','Consolas','DejaVu Sans Mono',monospace;
  --tap:44px;                                                  /* the touch target, written once */
  --rule:1px solid var(--line); --rule-strong:1px solid var(--ctl);
  --lh-flat:1; --lh-tight:1.2; --lh-ui:1.5; --lh-prose:1.7;    /* UI leading; the READING leadings stay --lh-src… on the dial */
  --z-drag:3; --z-pkfoot:5; --z-strip-inner:18; --z-strip:19; --z-band:20; --z-findbar:22; --z-menu:25;
  --z-float:30; --z-progress:36; --z-toast:40; --z-sheet:50; --z-veil:9998;
  color-scheme: light;
}
/* ---------- TWO dials, and each owns ONE thing (D-168, operator 2026-09-17: «they seem to do a bit
   the same, and sometimes one setting makes the other do nothing») ----------
   --dens  צפיפות — the space BETWEEN blocks, and nothing else: every gap, padding and margin below
           plus the UI spacing unit --sp, so verses, boxes, headings, settings rows and the Aa panel
           breathe together (0.60–1.30, set by the client from a percent). רגיל=1.00 · צפוף=0.70 ·
           מרווח=1.15 are just named positions on it. It must NEVER touch line-height again: until
           D-168 --lhf multiplied --lsp by (0.7 + 0.3·dens), which made 52–100% of what צפיפות did a
           weaker copy of the other dial (100% on בית יוסף and 90% on שמו״ת, whose block gaps had
           been frozen to fixed px by the D-63/D-154 re-cuts — there, density 60 == line spacing 88).
           **The HOME is deliberately out of its reach** (operator, D-168): the home fits itself to
           the phone through fitHome's ladder, so a dial that grew it would only be compacted back.
           `.lflex` is the home row AND the מסלולים pane's row — one idiom, so neither scales.
   --lsp   ריווח שורות — the space between LINES inside a paragraph, i.e. these line-heights alone
           (0.60–1.30; the clamp lives in app.js LSP_MIN, keep them in step). Its bottom is 0.60 and
           not D-51's 0.40 because below ~0.63 every class is pinned to its floor: at density 100 the
           stops 40·45·50·55·60 rendered identically, and at the operator's density 60 the dead band
           ran 40→65 (0.00% of pixels moved under real slider input). **The floors themselves did NOT
           move** — hard rule 5 still holds and 0.60 lands on exactly the 1.15 the dial reached at
           0.40, so the tightest page is the page it always was.
   Floors: Taamey D's ink band for fully pointed text with taamim is 1.141em, so below ~1.15 marks
   from consecutive lines physically overlap. 1.15 IS that ink band — the operator chose it knowingly
   (D-51) over 1.78 (comfort) and 1.40 (collision margin); do not raise it back without asking, and
   verify any new minimum with the pixel scan on a chok תורה verse, never on unpointed Beit Yosef,
   which passes trivially. */
:root {
  --dens:1; --lsp:1;
  --lhf: var(--lsp);            /* line-height factor — the ריווח שורות dial ALONE (D-168) */
  --sp: calc(var(--s-16) * var(--dens));                                 /* UI spacing unit */
  /* floors lowered on request (D-51): 1.15 is the ink band itself, so at the dial's bottom stacked
     marks CAN touch on a qamats-and-etnachta verse — the operator chose that knowingly */
  --lh-src: max(1.15, calc(1.82 * var(--lhf)));
  --lh-unpointed: max(1.00, calc(1.66 * var(--lhf)));
  --lh-onk: max(1.05, calc(1.74 * var(--lhf)));
  --lh-stz: max(1.05, calc(1.70 * var(--lhf)));
  --lh-cmt: max(1.05, calc(1.76 * var(--lhf)));
  --seg-gap: calc(.70em * var(--dens)); --unit-gap: calc(1.1em * var(--dens));
  --app-pad: calc(var(--s-12) * var(--dens)); --part-gap: calc(var(--s-48) * var(--dens));
  --sec-gap: calc(var(--s-16) * var(--dens)); --stz-gap: calc(var(--s-16) * var(--dens));
  --cap-gap: calc(var(--s-8) * var(--dens)); --onk-gap: calc(var(--s-4) * var(--dens));
  --night:0;                      /* night dimmer, 0–.32, painted by .nightveil over everything */
}
:root[data-theme="dark"] {
  --bg:#171a21; --card:#20242e; --ink:#e8e4d8; --dim:#aaa495; --mute:#a29c8c;
  --accent:#dfe6f5; --gold:#c8ab6e; --soft:#2a2f3c; --line:#333846; --ctl:#727888;
  --ok:#7fb07f; --onk:#a9b8d6; --stz:#b9b3a4; --stz-bg:#1c1f27;
  --btn-bg:#2a2f3c; --btn-ink:#e8e4d8;
  --shadow:rgba(0,0,0,.5); --scrim:rgba(0,0,0,.58);
  --hasc:#cfdcf5;
  --ly-a:#d3b473; --ly-b:#8fb8f0; --ly-c:#e69aa6; --ly-d:#8fd19a; --ly-e:#c9a6ec; --ly-f:#f0a0dc;   /* D-191: the three series; D-222: three more */
  --sheva:#e69aa6;
  --frame:#3f4553; --tick:#c8ab6e; --faint:#8f8a7c; --fill:#3a4152; --okfill:#2b3a2c;   /* D-63 page frame */
  --okwedge:#4f7a4f; --stripe:#1d212a; --okdone:#2b3a2c; --ring:#727888;   /* D-252 */
  color-scheme: dark;
}
/* keep this block byte-identical to [data-theme="dark"] above — it is the "system" path */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not([data-theme="sepia"]) {
    --bg:#171a21; --card:#20242e; --ink:#e8e4d8; --dim:#aaa495; --mute:#a29c8c;
    --accent:#dfe6f5; --gold:#c8ab6e; --soft:#2a2f3c; --line:#333846; --ctl:#727888;
    --ok:#7fb07f; --onk:#a9b8d6; --stz:#b9b3a4; --stz-bg:#1c1f27;
    --btn-bg:#2a2f3c; --btn-ink:#e8e4d8;
    --shadow:rgba(0,0,0,.5); --scrim:rgba(0,0,0,.58);
    --hasc:#cfdcf5;
    --ly-a:#d3b473; --ly-b:#8fb8f0; --ly-c:#e69aa6; --ly-d:#8fd19a; --ly-e:#c9a6ec; --ly-f:#f0a0dc;   /* D-191: the three series; D-222: three more */
    --sheva:#e69aa6;
    --frame:#3f4553; --tick:#c8ab6e; --faint:#8f8a7c; --fill:#3a4152; --okfill:#2b3a2c;   /* D-63 page frame */
  --okwedge:#4f7a4f; --stripe:#1d212a; --okdone:#2b3a2c; --ring:#727888;   /* D-252 */
    color-scheme: dark;
  }
}
:root[data-theme="sepia"] {
  /* D-63 printed-sefer palette (design handoff 2026-08-31, every text colour checked ≥4.5:1 on
     the paper): paper one step warmer, rules lighter, dim ink darker. --ctl and --faint are
     RULE / ORNAMENT colours only (band edges, empty checkbox; בס״ד, הגדרות, date chevrons) — never
     running text: review measured 3.5:1 and 2.0:1 when they were. */
  --bg:#f3ecd9; --card:#fbf6e7; --ink:#392e21; --dim:#594d3d; --mute:#6e5f4a;
  --accent:#493922; --gold:#7c5c28; --soft:#ece0c4; --line:#e3d7bb; --ctl:#b6a67f;
  --frame:#c9b993; --tick:#7c5c28; --faint:#7d6e52; --ok:#5c7550; --fill:#dccdaa;
  --okfill:#d8e0cb;   /* a completed mark fills the whole circle, in a pale sage */
  --okwedge:#9aae8c; --stripe:#ece8de; --okdone:#d8e0cb; --ring:#b6a67f;   /* D-252 */
  --onk:#6a5a3a; --stz:#5d4e3a; --stz-bg:#f0e6cf;
  --btn-bg:#493922; --btn-ink:#f3ecd9;
  --shadow:rgba(60,40,10,.22); --scrim:rgba(60,40,10,.44);
  --hasc:#3c3560;
  --ly-a:#8a5a12; --ly-b:#3c3560; --ly-c:#7a2230; --ly-d:#2e5a28; --ly-e:#5c2e72; --ly-f:#861f63;   /* D-191: the three series; D-222: three more */
  --sheva:#7a2230;
  color-scheme: light;
}

* { box-sizing:border-box; -webkit-tap-highlight-color:rgba(126,104,56,.28); }
html { scrollbar-gutter:stable; }
/* scoped to controls: html-wide `manipulation` also kills double-tap zoom on pointed text.
   D-217 (§30h-8 c): the five tappable READING surfaces all get it, not only חק's `.seg` — a tap on
   `.gl` (the daf), `.lbox` (בית יוסף), `.k-seif` (קיצור) or `.unit` opens a sheet or a gloss, and a
   quick second tap there zoomed the page instead. Pinch-zoom is untouched (`manipulation` keeps it). */
button, a, input, select, .card, .chip, .tab, .nav, .seg, .rchip,
.gl, .lbox, .k-seif, .unit { touch-action:manipulation; }
/* D-106 #8 (operator 2026-09-02: «all buttons, labels to move to Frank Ruhl Libre»): the UI chrome
   — buttons, labels, strips, dials, settings, toasts, the gate — is set in the shipped Frank Ruhl
   face; the system sans is gone from the app. Only unpointed UI text: the reading faces and the
   Taamey D display pieces (mast, date line, home names) are untouched. The fallback stays a generic
   serif so a face that has not arrived still reads as the same family, never as a sans. */
html, body { margin:0; padding:0; background:var(--bg); color:var(--ink);
  font-family:var(--font-ui); font-size:100%; }
body.noscroll { position:fixed; left:0; right:0; overflow:hidden; }   /* top is set by lockScroll() */
#app { max-width:720px; margin:0 auto;
  padding-inline:max(calc(var(--app-pad) + var(--s-4) * var(--dens)), env(safe-area-inset-left), env(safe-area-inset-right));
  padding-block:0 calc(var(--s-24) * var(--dens) + env(safe-area-inset-bottom)); }
@media (max-width:430px) { #app { padding-inline:max(var(--app-pad), env(safe-area-inset-left), env(safe-area-inset-right)); } }
/* night dimming: one veil over EVERYTHING (sheet included), so the effect is uniform and no
   theme path has to be duplicated. A filter on <body> would have re-parented every position:fixed
   descendant — this does not. */
.nightveil { position:fixed; inset:0; z-index:var(--z-veil); pointer-events:none; background:#000;
  opacity:var(--night,0); transition:opacity .25s ease; }
button { font:inherit; color:inherit; background:none; border:none; cursor:pointer; padding:0; }
a { color:var(--accent); }
:focus-visible { outline:3px solid var(--gold); outline-offset:2px; }
/* route() moves focus to the new view's heading so the change is announced; that programmatic
   focus must not paint a ring (nothing is "focused" from the reader's point of view) */
[tabindex="-1"]:focus, [tabindex="-1"]:focus-visible { outline:none; }
.loading, .empty { color:var(--dim); text-align:center; padding:calc(var(--s-32) * var(--dens)) 0; }
.hidden { display:none !important; }
.sr-only { position:absolute; width:1px; height:1px; padding:0; margin:calc(-1 * var(--s-1)); overflow:hidden;
  clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; border:0; }

/* ---------- source text: serif, nikud-safe, NEVER bold — emphasis is colour only ----------
   Rhythm: a paragraph/verse break must read as a break, not as a line wrap. Line gap at 1.9 is
   ~16px, so breaks add ~14px on top of it (4x the intra-paragraph delta).
   Fallbacks are measured, not conventional: 'Frank Ruehl CLM' collides on 4.4% of cantillated
   words and 'David' ships only 1 of the 31 taamim, so neither may sit behind a face chosen FOR
   its cantillation. 'Taamey Frank CLM' and 'Keter YG' both carry the full set. */
.src, .ara, .onk, .stz, .cmt, .rashi p, .intro, .dedication {
  font-family:var(--font-src); }
.src, .ara { font-size:var(--text-size); line-height:var(--lh-src); }
.src { margin:0 0 var(--seg-gap); }
.src.unpointed { line-height:var(--lh-unpointed); }   /* Beit Yosef / Kitzur / Etzot / Middot carry no nikud */
.seg .src { margin:0; }
/* verse number: until D-204 it HUNG in the indent and the text kept one straight edge; since D-204
   only the FIRST line starts after the gutter — every later line runs to the full column */
/* the hang and the number column are the SAME width, so the first line's text starts exactly where
   every wrapped line starts (before: the number box + its margin were narrower than the hang, and
   the first line began 5-12px further in than the rest — operator, 2026-08-30) */
/* --vn-gut is the numeral's gutter AND the verse's start — the two are the same number, which is
   what keeps the first line aligned with every wrapped line. Shrinking it is therefore the only way
   to move the verse toward the margin (operator, 2026-08-31, after the numeral was start-aligned).
   It cannot be one number for every reader: measured widest labels are 14.8px in תיקון (a bare
   numeral) but 28.6px in חק, whose refs carry chapter:verse («מה:יח») — 1.15em would put those
   through the text. So the default stays 1.75em and only the tracks with bare numerals narrow. */
/* D-204 (operator, 2026-09-24: «remove margin starting from second line for paragraph»): the hang is
   gone. The numeral keeps its gutter box on the FIRST line (`.vn` below is still --vn-gut wide), so
   line 1 looks as it did; every line after it runs to the full column instead of stopping at the
   gutter. Measured on חק with long verses: ~7.5% fewer verse lines. The verse button keeps its 56px
   tap area, because the empty gutter it grows into is still there on line 1. */
.src.has-vn { text-indent:0; padding-inline-start:0; }
/* D-146: the SECOND reading of a verse (שניים מקרא). It starts at the verse TEXT's edge like the
   verse's other companions — the numeral belongs to the first reading alone, and there is no
   hanging indent to undo, so `text-indent:0` (D-204: and no padding — it takes the full column, like
   every line after a verse's first). The pair sits close
   together and the targum takes the paragraph gap after them, which is what groups them on the
   page as מקרא · מקרא · תרגום rather than as three separate paragraphs. */
.src.dup { text-indent:0; padding-inline-start:0;
  margin-top:calc(var(--s-2) * var(--dens)); }
/* the render hint (§0f): «מקרא פעמיים» off = read it once. Both are always in the DOM inside ONE
   `.seg`, so the flip is instant and moves no reading position. */
.body.once .src.dup { display:none; }
/* D-242: זכירות ומצוות תמידיות. A part heading opens each of its two lists with the same air as
   ליל שישי (`.part`), less of it. The kavana line under each verse sits one step below the verse,
   at the commentary size, so the eye reads it as the gloss and not as more of the verse. */
.zk-part { font-size:var(--fs-3); padding-top:calc(var(--s-16) * var(--dens)); }
.item.zk-kav .src { font-size:var(--fs-cmt); line-height:var(--lh-src); }
.item.zk-kav .cap { margin-top:calc(var(--s-2) * var(--dens)); }
/* D-241: חק's aliyah header — a quiet gold word over the verse that opens an aliyah, the way a
   chumash marks שני / שלישי in its margin; the continuation of an aliyah begun the day before is
   dimmer («· המשך»). UI face (unpointed label, never bold — rule 5 is about pointed text, and this
   is not bold anyway). */
.aly { font-size:var(--fs-floor); line-height:var(--lh-flat); color:var(--gold); letter-spacing:.04em;
  margin:calc(var(--s-12) * var(--dens)) 0 calc(var(--s-4) * var(--dens)); }
.aly.cont { color:var(--dim); }
/* the verse's companions (Onkelos, the ref caption, the section intro, the רש״י panel) start at the
   verse TEXT's edge, not at the paragraph edge: one text column, the number alone in the gutter
   (measured 2026-08-30: text at 352, everything else at 380 — a 28px stagger on every verse) */
.item .onk, .sec .intro { padding-inline-start:0; }   /* D-204: the full column, like the verse's lines 2+ */
/* the caption's link has .3rem of inline padding of its own (for its tap area): subtract it, or
   the ref text sits 5px inside the column everything else shares (measured 336 vs 341) */
.item .cap { padding-inline-start:0; margin-inline-start:calc(-1 * var(--s-4) * var(--dens)); }   /* D-204: the link's own .3rem, taken back */
.item .rashi { margin-inline-start:0; }
.gtxt .ara { margin:0 0 calc(var(--s-4) * var(--dens)); }
.src b, .ara b, .onk b, .stz b, .cmt b, .rashi b, .intro b { font-weight:normal; color:var(--gold); }
.src big, .ara big { font-size:1em; }
/* D-145: the daf's passage labels — «מתני׳» and «גמ׳» — set as a printed daf sets them: heavier and
   larger than the text they head. `big.glbl` (0,1,2) outranks `.ara big` (0,1,1) whatever the order,
   which is what the rule above needs it to do. The class is put on by `markLabels()` AFTER
   sanitisation and is blocked in both sanitisers, so no payload can wear it.
   **This is the SECOND deliberate exception to hard rule 5** (never bold pointed Hebrew), asked for
   by the operator; the first is תיקון's `.sn`. It is safe for the same reason: Taamey D's synthetic
   bold keeps its marks, and these two words carry nikud but no taamim — the deepest mark either
   takes is a sheva or a qamats. Do NOT generalise it to running text.
   The line-height is divided by the same scale it multiplies the size by, so the label's used
   line-height in px equals the surrounding text's: without that, a 1.18em inline box on a unitless
   line-height silently opens the line it sits on — visible as a ragged gap in the continuous
   («טקסט בלבד» / «וילנא») layers, where the whole daf is one flowing paragraph. */
.ara big.glbl { --glbl: 1.18; font-size:calc(1em * var(--glbl)); font-weight:700;
  line-height:calc(var(--lh-src) / var(--glbl)); }
/* the Steinsaltz <b> is the quoted Talmud lemma — it must not be fainter than the gloss around it */
.stz b { color:var(--ink); }
.stz small { color:var(--dim); }
.stz big { font-size:1em; color:var(--gold); }
/* source citations inside the text (Kitzur [ילקו"י …], Sefaria footnote smalls): quieter, never bold */
.src small, .ara small, .stz small, .cmt small, .onk small, .rashi small { font-size:var(--fs-cmt); color:var(--dim); }
/* D-192 — «the rama commentary still has very large line spacing compared to rest of text».
   MEASURED, and the first explanation was wrong: `line-height` IS inherited correctly here as the
   number 1.66, and `getComputedStyle` on the `<small>` duly reports 25.9px against its 15.6px type.
   The LINE BOXES are 33px all the same. That is the strut: every line box in a block also contains
   an imaginary inline box carrying the BLOCK's font and line-height, so an inline run can never be
   set tighter than the paragraph it sits in — 33.2px against 15.6px type is a ratio of 2.13, which
   is what he was seeing. No line-height on the `<small>` can fix it; only closing the size gap can.
   The printed page's own answer is כתב רש״י, and the OPERATOR RULED THAT OUT for this screen
   («Rama and commentaries for shulhan arukh should not use rashi font», 2026-09-23). It was tried
   first, and his instruction also happens to settle it on its own merits: in או״ח א:א almost the
   whole se'if IS a הגה, so at full size the רמ״א took the page over and the two voices inverted.
   Without the font lever there is exactly one way to give this run its own leading — give it its
   own STRUT, which means its own block. So the הגה becomes a block, at a line-height proportional
   to its own type, and keeps its size step: the voices stay ordered and the airiness goes.
   It is NOT only the הגה that is wrapped in `<small>`: measured over 186 runs in 44 simanim of
   או״ח, 61% open with «הגה» and the rest are later editors' parenthetical glosses and source
   references («פי' …», «וע"ל סי' מ"ז»). Those are short, usually inside a single line, where a
   line-box mismatch does not show — so they stay inline, and only the long one is blocked out. */
/* D-193 — «still Rama line spacing issue», and the fault was a HARDCODED 1.55 here.
   Every line-height in this file is derived from `--lhf`, the reader's own ריווח שורות dial, whose
   range is 60–130%. A fixed 1.55 ignores it, so below a dial setting of 94% the body drops under
   1.55 and the הגה becomes LOOSER than the text around it — which is the operator's complaint
   exactly, and he had every reason to be on a low setting, having opened this whole thread by
   saying שולחן ערוך was too loose. Derived now, at 0.8 of the body's factor, so the gloss is
   always tighter than the text and follows his dial wherever he puts it. The sibling idiom was
   three lines away the whole time (`--lh-src`, `--lh-unpointed`, `--lh-onk`, `--lh-stz`). */
#rbody[data-track="shulchan"] .src small.hagah,
#rbody[data-track="rambam"] .src small.hagah {
  display:block; font-size:var(--fs-cmt); line-height:max(1.00, calc(1.34 * var(--lhf)));
  margin:calc(var(--s-6) * var(--dens)) 0 0; }
.onk { font-size:var(--fs-cmt); line-height:var(--lh-onk); color:var(--onk); margin:var(--onk-gap) 0 0; }
.glines.no-onk .onk, .item.no-onk .onk, .body.no-onk .onk { display:none; }
.stz { font-size:var(--fs-cmt); line-height:var(--lh-stz); color:var(--stz); background:var(--stz-bg);
  border-inline-start:3px solid var(--ctl);
  border-start-start-radius:0; border-end-start-radius:0;
  border-start-end-radius:0; border-end-end-radius:0;
  padding-block:calc(var(--s-6) * var(--dens)) calc(var(--s-8) * var(--dens)); padding-inline:calc(var(--s-12) * var(--dens)) calc(var(--s-4) * var(--dens)); margin:var(--onk-gap) 0 var(--stz-gap); }
.glines.plain .stz { display:none; }
/* the daf keeps both renderings of every line; CSS shows one, so the toggle never moves the scroll */
/* D-71: the words a רש״י / תוספות comment opens on. The dotted rule is deliberately quiet — it
   marks only the dibur ha-matchil (2-4 words of a line, not the line), so it reads as «there is a
   comment on these words» rather than as decoration. `.on` is the answer to «which words was that
   about», set when the sheet opens and left in place after it closes. */
/* D-82: a word (or the gap inside a phrase) that opens a commentary. רש״י and תוספות are told
   apart by BOTH colour and line style, never colour alone, so the distinction survives a
   colour-blind reader and the high-contrast print sheet. The `.sep` gaps carry the same classes,
   which is what makes a five-word anchor read as one underline instead of five. */
/* The rule is drawn with text-decoration, NOT border-bottom. A border sits at the foot of the
   inline BOX, which on pointed Hebrew is a long way under the letters once the nikud and the line's
   leading are counted, and it read as floating free of the word. `text-underline-offset` measures
   from the BASELINE, so the rule sits just clear of the vowel points instead.
   `skip-ink:none` keeps it unbroken under descenders, which is what lets a phrase read as one mark. */
.w.dh, .sep.dh { cursor:pointer; }
/* D-90 (amends D-89 after a zoomed phone screenshot):
   רש״י = a clipped BAND of colour, not a filled box. An inline background paints the font's whole
   content box — measured 1.24em against 0.71-0.91em of ink — so at large sizes adjacent lines'
   washes fused into blobs. The gradient stripe is 1.04em tall, centred, which covers the tallest
   measured ink with margin and keeps a clear channel between lines. Colour comes from --hasc (the
   «ink shifted toward accent» token): 16% reads blue on the sepia paper where 12% accent read grey.
   תוספות = spaced dots whose thickness FOLLOWS the type — max(2px, .09em) — because fixed 2px
   dots vanished at 5× zoom (Chromium scales the dot gap with the thickness, so spacing holds).
   The offset stays bigger on the vocalized rendering, clearing the nikud.
   LIT (.on) = the same band, twice as strong — one convention, intensified, instead of the old
   beige fill + gold dots that produced mixed-colour dot rows and three unrelated tints. */
/* D-92: the marker is drawn ONCE per comment, by its `.dh-run` wrapper, as a text-decoration —
   continuous across words and gaps, and anchored to the BASELINE (the content-box centring of
   D-90 sat differently on every platform's font: high on the phone, low on desktop). The wash is
   a thick translucent underline raised above the baseline; Chromium paints underlines BEHIND the
   glyphs (probed: banded ink as dark as plain ink). The vocalized rendering reaches a little
   lower for the nikud. Per-SPAN rules below survive only as the fallback for the rare range that
   cannot be wrapped (crosses an element boundary or overlaps an earlier wrap); a span inside a
   run carries `inrun-*` and draws nothing itself. */
.dh-run { text-decoration-skip-ink:none; cursor:pointer; }
.dh-run.dh-t {
  text-decoration-line:underline; text-decoration-style:dotted;
  text-decoration-thickness:max(2px, .09em); text-decoration-color:var(--hasc);
  text-underline-offset:.22em;
}
.ara.std .dh-run.dh-t { text-underline-offset:.34em; }
.dh-run.dh-r {
  text-decoration-line:underline; text-decoration-style:solid;
  text-decoration-thickness:1.12em; text-underline-offset:-.84em;  /* measured: 28px above ink, 27px below at 96px */
  text-decoration-color:color-mix(in srgb, var(--hasc) 16%, transparent);
}
.ara.std .dh-run.dh-r { text-decoration-thickness:1.16em; text-underline-offset:-.78em; }  /* nikud hangs lower: shifted down for clearance under the deepest vowel row */
.dh-run.dh-r.on { text-decoration-color:color-mix(in srgb, var(--hasc) 34%, transparent); }
/* the per-span FALLBACK (unwrappable ranges) — D-90 geometry, unchanged */
.w.dh-t, .sep.dh-t {
  text-decoration-line:underline; text-decoration-style:dotted;
  text-decoration-thickness:max(2px, .09em);
  text-decoration-color:var(--hasc); text-underline-offset:.22em; text-decoration-skip-ink:none;
}
.ara.std .w.dh-t, .ara.std .sep.dh-t { text-underline-offset:.34em; }
.w.dh-r, .sep.dh-r, .w.dh.on, .sep.dh.on {
  background-image:linear-gradient(var(--dh-band, transparent), var(--dh-band, transparent));
  background-repeat:no-repeat; background-size:100% 1.04em; background-position:center;
}
.w.dh-r, .sep.dh-r { --dh-band:color-mix(in srgb, var(--hasc) 16%, transparent); }
.w.dh.on, .sep.dh.on { --dh-band:color-mix(in srgb, var(--hasc) 34%, transparent); border-radius:0; }
/* a sep bridging two RUNS carries the run geometry itself, so the three bands join seamlessly */
.sep.dh-br {
  background-image:none;
  text-decoration-line:underline; text-decoration-style:solid; text-decoration-skip-ink:none;
  text-decoration-thickness:1.12em; text-underline-offset:-.84em;
  text-decoration-color:color-mix(in srgb, var(--hasc) 16%, transparent);
}
.ara.std .sep.dh-br { text-decoration-thickness:1.16em; text-underline-offset:-.78em; }
.sep.dh-br.on { background-image:none; text-decoration-color:color-mix(in srgb, var(--hasc) 34%, transparent); }
/* wrapped spans draw nothing — the run draws for them */
.inrun-t { text-decoration-line:none !important; }
.inrun-r { background-image:none !important; }
/* D-93/D-94: the lit wash for ANY תוספות run is drawn by its `.dh-glow` carrier as a
   text-decoration — baseline-anchored like the רש״י band, stacking BEHIND the run's own dots.
   (D-93 first drew it as a content-box-centred background, the one lit visual left with the
   platform skew D-92 removed everywhere else.) The span-layer .on wash stays suppressed inside
   dh-t runs — flattened runs have no spans, partial ones would light striped. */
.dh-glow { text-decoration-skip-ink:none; }
.dh-glow:has(> .dh-run.on) {
  text-decoration-line:underline; text-decoration-style:solid;
  text-decoration-thickness:1.12em; text-underline-offset:-.84em;
  text-decoration-color:color-mix(in srgb, var(--hasc) 34%, transparent);
}
.ara.std .dh-glow:has(> .dh-run.on) { text-decoration-thickness:1.16em; text-underline-offset:-.78em; }
.dh-run.dh-t .w.dh.on, .dh-run.dh-t .sep.dh.on { background-image:none; }
/* inside a רש״י run the RUN's decoration is the lit wash — the span layer must not add a second,
   content-box-centred band on top. Inside a תוספות run the span layer still provides the lit wash
   (a dotted run cannot carry two decorations), and contiguous span bands join seamlessly. */
.dh-run.dh-r .w.dh.on, .dh-run.dh-r .sep.dh.on { background-image:none; }
.cmt.on { background:var(--soft); }
.ara.vil { display:none; }
.glines.vilna .ara.std { display:none; }
.glines.vilna .ara.vil { display:block; }
/* a line that carries a comment: the TEXT is tinted, quietly, in addition to the number's hairline */
.gl.has-cmt .ara { color:var(--hasc); }
/* «ביאור בלבד»: the Aramaic hides, the gloss stays — and with nothing above it the block no longer
   needs the quotation rule or the indent that separated it from the line it explains */
.glines.stzonly .ara { display:none; }
.glines.stzonly .stz { background:none; border-inline-start:none; padding-inline:0; margin-block:calc(var(--s-2) * var(--dens)) calc(var(--s-8) * var(--dens));
  color:var(--ink); font-size:var(--text-size); line-height:var(--lh-src); }
.cmt, .rashi p { font-size:var(--fs-cmt); line-height:var(--lh-cmt); margin:var(--cap-gap) 0; }
/* D-148 (operator): the רש״י switch no longer HIDES anything. «On» means every verse's panel
   renders open; «off» means it renders closed and the verse number opens it. So the old
   `.body.no-rashi` rule is gone — it also removed the numeral's hairline, which is the very
   affordance the «off» state now depends on. The open/closed state is the panel's own `hidden`
   attribute, set at render time, which is also what keeps find-in-page honest. */
.intro { font-size:var(--fs-cmt); color:var(--dim); line-height:var(--lh-unpointed); margin:var(--onk-gap) 0 var(--cap-gap); }

/* ---------- offline bar + toast ---------- */
.offbar { position:sticky; top:0; z-index:var(--z-float); text-align:center; font-size:var(--fs-floor); padding:calc(var(--s-4) * var(--dens)) calc(var(--s-8) * var(--dens));
  background:var(--soft); color:var(--dim); border-bottom:var(--rule);
  padding-top:calc(var(--s-4) * var(--dens) + env(safe-area-inset-top)); display:none; }
.offbar.on { display:block; }
/* D-258: the filter hint, a second line under «אין חיבור». Quieter by colour only (--mute, ≥4.6:1 on
   --soft in light, dark and sepia) — it cannot be smaller, the bar already sits on the 16 px floor. */
.offbar .offhint { display:block; color:var(--mute); line-height:var(--lh-tight); margin-top:calc(var(--s-2) * var(--dens)); text-wrap:balance; }
.toast { position:fixed; left:50%; bottom:calc(1.6rem + env(safe-area-inset-bottom)); transform:translate(-50%, 1rem);
  background:var(--btn-bg); color:var(--btn-ink); padding:calc(var(--s-8) * var(--dens)) calc(var(--s-16) * var(--dens)); border-radius:0; font-size:var(--fs-floor);
  opacity:0; pointer-events:none; transition:opacity .2s, transform .2s; z-index:var(--z-toast); max-width:90vw; text-align:center; }
.toast.show { opacity:1; transform:translate(-50%, 0); }

/* ---------- home ---------- */
/* ---- D-63 printed-sefer redesign, step 1: the page frame (theme-neutral structure) ----
   The home screen is one printed page: a hairline frame with corner ticks that reaches the foot
   of the sheet. The frame fills the viewport by flex (#app is the flex column, .page flex:1); the
   content must fill the frame by being TALLER, never by auto-margins or spacers — on a printed
   page that reads as an unfinished page (the handoff's most-repeated review finding). Screen
   padding on home is 7px (D-68c; the readers get 8px in step 3). */
/* §26 (D-153): minus the offline bar. The bar is a sticky element IN THE FLOW above this block, so
   a full-viewport min-height put the document 28px over the viewport at every compaction level —
   which is why `fitHome`'s ladder ran to its last rung (fit8: the +15% type given back, details
   hidden) the whole time the app was offline, on any phone. The viewport really is smaller by the
   bar; say so here, and let fitHome's own allowance cover the rest. */
#app.is-home { min-height:100vh; min-height:calc(100dvh - var(--offbar-h, 0px)); display:flex; flex-direction:column;
  /* 7px, was 10 — operator asked for 30% less air between the frame and the screen edge. All four
     sides: a frame inset 7px at the sides and 10px top/bottom reads as a mistake, not a margin. */
  padding-top:calc(var(--s-6) + env(safe-area-inset-top)); padding-bottom:calc(var(--s-6) + env(safe-area-inset-bottom));
  padding-inline:max(var(--s-6), env(safe-area-inset-left), env(safe-area-inset-right)); }
.page { position:relative; flex:1 1 auto; display:flex; flex-direction:column; min-width:0;
  border:1px solid var(--frame); border-radius:0; padding:var(--s-12) var(--s-12) var(--s-12); }
#app.is-home .page { padding-top:var(--s-8); padding-bottom:var(--s-8); }   /* operator: slightly less vertical air */
.page > .tick { position:absolute; width:10px; height:10px; pointer-events:none; }   /* the artboard's 9px content-box ticks render 10px */
.page > .tick:nth-of-type(1) { top:-1px; inset-inline-start:-1px; border-top:1px solid var(--tick); border-inline-start:1px solid var(--tick); }
.page > .tick:nth-of-type(2) { top:-1px; inset-inline-end:-1px;   border-top:1px solid var(--tick); border-inline-end:1px solid var(--tick); }
.page > .tick:nth-of-type(3) { bottom:-1px; inset-inline-start:-1px; border-bottom:1px solid var(--tick); border-inline-start:1px solid var(--tick); }
.page > .tick:nth-of-type(4) { bottom:-1px; inset-inline-end:-1px;   border-bottom:1px solid var(--tick); border-inline-end:1px solid var(--tick); }
/* ---- D-63 step 2: the printed home (#6a) — corner row, masthead, ledger, backlog rule, verse foot.
   Sizes are the handoff's authored values (sepia at 20px text, density 100%): kicker 12/.2em, title
   34/1.15, date 21, name 17/1.25, portion 14/1.3, detail 12/1.45 (the floor), backlog 12.5, verse
   23/1.7, source 12. No radius anywhere in this idiom. --ctl = strong rule, --line = light rule.
   D-203: those are HISTORY now — every home size below is a token (16/18/21/34), the sub-16 ones
   raised to the floor: kicker, corner, detail, backlog and verse source 16 · name 18 · portion 16 ·
   date 21 · verse 21 · title 34. */
/* D-68b: ONE dial for the home screen's type. The operator asked for +15% across the whole
   screen, so every home font-size below is `calc(<token> * var(--hs))` (D-203; it was the
   artboard px until then) — including the
   compaction levels, or fitHome would quietly undo the increase — and the masthead's lozenges
   scale with it, since an ornament that does not grow with its type reads as shrinking. --hs is 1
   everywhere else; nothing outside #app.is-home changes. */
#app.is-home { --hs:1.15; }
.corner { display:flex; align-items:flex-start; }
.corner .bsd { font-family:var(--font-src); font-size:calc(var(--fs-floor) * var(--hs)); color:var(--faint); }
/* D-68: the corner control is the WORD «הגדרות», set to match «בס״ד» exactly — same face, same
   size, same colour: the two corners are one typographic band, which is what the artboard shows.
   The box is the artboard's 44×30 (the corner row is 30px; the masthead overlaps it by 8px) and
   the 44px tap area is the ::before halo. */
.corner .setlink { position:relative; margin-inline-start:auto; min-width:var(--tap); min-height:30px; height:30px;
  align-items:flex-start; justify-content:flex-end;      /* RTL: flex-END is the LEFT edge — the word
     hugs the page margin exactly as בס״ד hugs the opposite one (both 12px in) */
  padding:0; font-family:var(--font-src); font-size:calc(var(--fs-floor) * var(--hs)); color:var(--faint); border-radius:0; }
.corner .setlink::before { content:""; position:absolute; inset:-7px -6px; }
.mast { text-align:center; margin-top:calc(-1 * var(--s-8)); }               /* the artboard's overlap: measured kicker top 34px */
/* Sized to keep the apparent size of the sans it replaces: every size below is the old one × 1.03,
   measured against NOTO SANS HEBREW — what the -apple-system/Roboto stack actually resolves to for
   Hebrew on the operator's Android (Roboto has no Hebrew glyphs). At 100px nominal «פרשת נצבים» is
   60 high in Frank Ruhl against Noto's 62, and a final mem 59 against 60: the letter HEIGHT needs
   1.03. Its WIDTH would want 1.16 (450 vs 524) — Frank Ruhl is a narrow face, and matching the
   advance width would have made the letters 13% taller than the text it replaces. Apparent size
   follows the letter height; the column simply runs shorter, which is the face's character.
   Then ×1.15 again on the operator's word — Frank Ruhl reads small beside Taamey D even at matched
   letter height. So the four sizes below were the face-matching factor (1.03) times that: 12 →
   14.21, 13.7 → 15.76, 11.74 → 13.5. D-203 replaced all four with --fs-floor: the kicker had
   carried a guard against the OLD 12px floor, so at fit8 (--hs 1) it sat at 14.21, under the
   14.4 floor D-107 had since set — the one home size that was actually below the floor. */
.mast .kicker { font-family:var(--font-ui); font-size:calc(var(--fs-floor) * var(--hs)); letter-spacing:.2em; color:var(--gold); }
.mast .mtitle { font-family:var(--font-src); font-size:calc(var(--fs-5) * var(--hs)); line-height:var(--lh-tight); color:var(--accent);
  font-weight:normal; margin:var(--s-2) 0 0; }
.rule { display:flex; align-items:center; gap:var(--s-6); margin:var(--s-8) 0 var(--s-4); }
.rule span { flex:1 1 auto; height:1px; background:var(--frame); }
.rule i { width:5px; height:5px; background:var(--gold); transform:rotate(45deg); }
/* D-68: the masthead rule's ornament is THREE lozenges in a tight cluster — the hairline stands
   off further (the .rule gap, 7) than the lozenges stand from each other (5). The verse foot and
   the colophon keep their single quieter diamond; this is the page's one masthead. */
.rule .loz { display:flex; align-items:center; gap:calc(var(--s-6) * var(--hs)); }
.rule .loz i { width:calc(3.5px * var(--hs)); height:calc(3.5px * var(--hs)); background:var(--ctl); }
.rule .loz i.mid { width:calc(5px * var(--hs)); height:calc(5px * var(--hs)); background:var(--gold); }
.mast .rule { gap:calc(var(--s-6) * var(--hs)); }
.rule.light span { background:var(--line); }
.rule.light i { width:4px; height:4px; background:var(--ctl); }
.daterow { display:flex; align-items:center; justify-content:center; gap:var(--s-2); }
/* The day steppers are DRAWN marks, not the ‹ › glyphs. Measured across the app's whole font
   stack, the guillemet's ink sits 0.086–0.172em BELOW its own em-box centre depending on the face
   (Segoe UI 0.172, Arial 0.086, the Android fallback 0.121) — so no single nudge centres it on
   every device, and the glyph's own size varies by face too. A rotated square with two borders
   rotates about its centre, so it is exactly centred by the row's `align-items:center`, and
   «bigger» and «bold» become the box and the border-width. */
.daterow .dbtn { min-width:var(--tap); min-height:var(--tap); color:var(--faint); border-radius:0; }   /* mock says 42; the checklist's 44 wins */
.daterow .dbtn::after { content:""; display:block; width:calc(10px * var(--hs)); height:calc(10px * var(--hs));
  border-top:calc(2.2px * var(--hs)) solid currentColor; }
/* outward, not inward: #dPrev sits on the RIGHT of the date in RTL and points right, #dNext on
   the left and points left. The ‹ › glyphs they replaced are bidi-MIRRORED, so they rendered
   the opposite way round from how they read in the source — which is what made the drawn
   version look reversed even though it copied the characters faithfully. */
#dPrev::after { border-right:calc(2.2px * var(--hs)) solid currentColor; transform:rotate(45deg); }
#dNext::after { border-left:calc(2.2px * var(--hs)) solid currentColor; transform:rotate(-45deg); }
.daterow .dline { font-family:var(--font-src); font-size:calc(var(--fs-3) * var(--hs)); color:var(--ink); padding-inline:0; }
.btn2 { display:inline-block; margin-top:calc(var(--s-6) * var(--dens)); min-height:42px; min-width:96px; padding:0 calc(var(--s-12) * var(--dens)); font-size:var(--fs-floor);
  color:var(--accent); border:var(--rule-strong); border-radius:0; background:none; }
.btn2:active { background:var(--soft); }
#app.is-home .btn2 { font-size:calc(var(--fs-floor) * var(--hs)); }
.mast .stale, .mast .syncnote { font-size:calc(var(--fs-floor) * var(--hs)); margin:var(--s-4) 0 0; }
/* Operator (2026-08-31, after step 2, twice): the home must fit the screen without scrolling AND
   the rows must be content-tight — "still blank space in the ledger" when they shared the page
   height. So: rows at 12px padding, no growth; the frame still reaches the foot (#app.is-home is
   the flex column) and the verse foot is pinned to the bottom like a colophon, so the page's
   slack sits between the ledger and the verse. (The handoff said no spacers — the operator's
   explicit preference overrides it; recorded in D-63.) */
.ledger { border-top:var(--rule-strong); border-bottom:var(--rule-strong); margin-top:var(--s-6); flex:none; }
.lrow { flex:none; }
.lrow + .lrow { border-top:var(--rule); }
.lflex { display:flex; align-items:center; gap:var(--s-8); padding:var(--s-8) var(--s-2); }   /* name and mark both centred on the row */
.vfoot { margin-top:auto; }
/* Compaction levels, applied by fitHome() (app.js) only while the page would overflow the viewport;
   cumulative (fit2 implies fit1). D-215 (operator, 2026-09-30, many tracks on): «keep size, let home
   scroll» · «only details may shrink» · «nothing: keep all». So the ladder has two rungs and neither
   touches a name, a portion, the masthead or the verse: fit1 tightens SPACING, fit2 takes the grey
   detail lines from the home scale to the plain floor (18.4 → 16 px). If the page still overflows, it
   SCROLLS. The old rungs (D-63/D-68b: smaller masthead and ledger type, details cut or hidden, the
   verse's ornament hidden, the sync notice shed, and fit8's --hs:1 giving back the +15 %) were what
   made a many-track home small; they are gone, not parked. Every target stays 44 px. */
#app.fit1 .lflex { padding:var(--s-6) var(--s-2); }
#app.fit1 .vfoot { padding-top:var(--s-8); }
#app.fit1 .mast .rule { margin:var(--s-4) 0 var(--s-2); }
#app.fit1 .ledger { margin-top:var(--s-2); }
#app.fit2 .lrow .dt { font-size:var(--fs-floor); }
/* ---- D-64 step 3: the readers — page frame (8px screen padding), head band, foot bands ----
   The band keeps .rd-top's sticky/headroom/--rdtop-h machinery; it sticks below the status-bar
   inset (top includes the inset, so the frame's own inset padding is not doubled). */
#app.is-reader, #app.is-page { min-height:100vh; min-height:calc(100dvh - var(--offbar-h, 0px)); display:flex; flex-direction:column;   /* §26: same subtraction as home */
  padding-top:calc(var(--s-8) * var(--dens) + env(safe-area-inset-top)); padding-bottom:calc(var(--s-8) * var(--dens) + env(safe-area-inset-bottom));
  padding-inline:max(var(--s-8) * var(--dens), env(safe-area-inset-left), env(safe-area-inset-right)); }
#app.is-reader .page, #app.is-page .page { padding:0; }                 /* bands/strips are full-bleed to the hairline */
#app.is-reader .body, #app.is-page .body { padding:calc(var(--s-12) * var(--dens)) calc(var(--s-8) * var(--dens)) calc(var(--s-12) * var(--dens)); }    /* only the scrolling body is padded */
/* A `box-shadow:0 -3px 0 var(--bg)` seam cover lived here briefly (D-69) on the theory that the
   band's sticky `top` and #app's padding-top round apart at a non-integer devicePixelRatio. It
   changed nothing on the phone, so the theory was wrong and the rule is gone rather than left as
   a charm. Whatever the 1px is, it is not painted immediately above the band. */
.rd-top.band { gap:calc(var(--s-4) * var(--dens)); padding:calc(var(--s-2) * var(--dens)) calc(var(--s-4) * var(--dens)); border-bottom:var(--rule-strong); background:var(--bg);
  top:calc(var(--offbar-h, 0px) + env(safe-area-inset-top)); }
/* the artboard's icon boxes are 40×38 (band = 43px); the 44px tap areas are ::before halos */
.rd-top.band .back, .rd-top.band .iconBtn { position:relative; min-width:40px; min-height:38px; padding:0; border-radius:0;
  color:var(--gold); font-size:var(--fs-floor); }
.rd-top.band .back::before, .rd-top.band .iconBtn::before { content:""; position:absolute; inset:-3px -2px; }
/* D-175: the back arrow is FIRST on screen but LAST-but-one in the DOM, so that focusing the
   heading on open still leaves it reachable by a forward Tab. `order` moves the pixels only. */
.rd-top.band .back { font-size:var(--fs-3); order:-1; }
.rd-top.band .rlabel { font-size:var(--fs-floor); letter-spacing:.06em; color:var(--gold); white-space:nowrap; }
.rd-top.band .rref { flex:1 1 auto; min-width:0; text-align:center; margin:0; font-weight:normal;
  font-family:var(--font-src); font-size:var(--fs-floor); line-height:normal; color:var(--accent);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.foot { margin-top:calc(var(--s-24) * var(--dens)); margin-inline:calc(-1 * var(--s-8) * var(--dens)); }   /* bleed past .body's padding */
.foot .band1 { display:flex; align-items:center; gap:calc(var(--s-6) * var(--dens)); border-top:var(--rule-strong); padding:calc(var(--s-4) * var(--dens)) calc(var(--s-8) * var(--dens)); font-size:var(--fs-floor); color:var(--dim); }
/* D-108 #1: the word count is gone (it said nothing the minutes did not); the two outer cells share
   the width so the middle cell is truly centred */
.foot .band1 > span:not(.mid) { flex:1 1 0; white-space:nowrap; }
.foot .band1 > span:last-child { text-align:end; }
.foot .band1 .mid { flex:1 1 auto; text-align:center; font-family:var(--font-src); font-size:var(--fs-floor); color:var(--accent); white-space:nowrap; }
.foot .band2 { display:flex; flex-wrap:wrap; align-items:center; gap:calc(var(--s-6) * var(--dens)); border-top:var(--rule); padding:calc(var(--s-4) * var(--dens)) calc(var(--s-8) * var(--dens)) calc(var(--s-6) * var(--dens)); }
.foot .btn1 { flex:1 1 auto; max-width:none; min-height:var(--tap); padding:0 calc(var(--s-6) * var(--dens)); font-size:var(--fs-floor); color:var(--bg); background:var(--accent);
  border:1px solid var(--accent); border-radius:0; }   /* max-width:none — the legacy .done-btn/.next-btn cap 17rem/16rem */
/* D-108 #1: the hand-off carries its minutes («חק לישראל · כ־11 דק׳ ←»); on a narrow screen it
   takes the band's next line whole rather than squeezing beside the ✓ */
.foot .btn1.next-btn { flex:1 1 170px; }
.foot .btn1 .nm { font-size:var(--fs-floor); opacity:.85; }
/* D-167: `margin:0` is load-bearing — the global `.btn2` carries `margin-top:6px`, which in this
   centred row would drop «עוד קטע» 3 px below «סמן כנלמד». (Until D-167 the button also wore the
   reader's `.sec` class and its `--sec-gap` bottom margin, which lifted it 9.1 px the other way.) */
.foot .btn2 { flex:none; max-width:none; min-height:var(--tap); min-width:78px; margin:0; padding:0 calc(var(--s-8) * var(--dens)); font-size:var(--fs-floor); color:var(--accent); border:var(--rule-strong);
  border-radius:0; background:none; }
/* D-108 #1: the ✓ state is the band's own statement now — bigger than the buttons' text, the time
   a half-step down beside it — and «ביטול» is a text link, not a second button competing with the hand-off */
/* D-167 — the ✓ line sits on the SAME baseline as «ביטול» and the hand-off button.
   `.done-lbl` is a flex container (the global `.done-lbl { display:inline-flex }`), so its words
   and its «· time» span were two flex items aligned by BOX: the 17 px words sat 4.5 px above the
   14.4 px time, and above the buttons' text. Three declarations, each doing one thing:
   `align-items:baseline` puts the label's own two parts on one baseline; `flex-wrap:wrap` +
   `align-content:center` is what centres that single line in the 44 px row (align-content is
   ignored in a nowrap flex container, so the wrap is not decoration); `line-height:1` makes the
   line box the text's own height, which is what a <button>'s native centring does — with it the
   measured baseline difference against ביטול and the chain button is 0.00 at text 20 and 25.
   Measure with a zero-height `vertical-align:baseline` probe, never a Range rect: a Range returns
   the font-METRIC box, so a 17 px run and a 14.4 px run on one baseline already differ by 2.5 px. */
.foot .done-lbl { flex:1 1 auto; font-size:var(--fs-2); color:var(--ok); white-space:nowrap;
  display:flex; flex-wrap:wrap; align-items:baseline; align-content:center; line-height:var(--lh-flat); }
.foot .done-lbl .at { font-size:var(--fs-floor); color:var(--dim); }
.foot .done-lbl.pend { color:var(--dim); font-size:var(--fs-floor); }
.foot .lnk { flex:none; min-height:var(--tap); padding:0 calc(var(--s-8) * var(--dens)); font-size:var(--fs-floor); color:var(--dim); background:none; border:0; border-radius:0;
  text-decoration:underline; text-underline-offset:3px; }
.foot .projnote { flex:1 1 auto; margin:0; text-align:start; }
.foot .btn1:active, .foot .btn2:active { opacity:.85; }
.maint { text-align:center; margin:calc(var(--s-16) * var(--dens)) 0 calc(var(--s-6) * var(--dens)); }
/* the find bar sits flush under the band as a plain strip (no radius, no gap) */
.rd-top.band ~ .findbar { margin-top:0; border-radius:0; border-width:0 0 1px; background:var(--bg); }
.lmain { flex:1 1 auto; min-width:0; display:block; text-align:start; min-height:var(--tap); padding:0;
  -webkit-touch-callout:none; user-select:none; -webkit-user-select:none; touch-action:manipulation; }   /* D-134: long-press opens the sheet */
/* The name column is CENTRED against the whole row (operator, 2026-08-31, twice): first the
   baseline of the portion line, then — since the row is two lines tall — its middle. A full name
   («קיצור ילקוט יוסף») wraps inside the 84px column and stays centred with it. (D-245: on the
   home every row is one line and no name wraps — see `#ledger .lrow .nm` below.) */
.lrow .lin { display:flex; align-items:center; gap:var(--s-8); width:100%; }
.lmain:not(:disabled):active { background:var(--soft); }
.lmain:disabled { cursor:default; }
/* BOLD is safe here and ONLY here in the ledger: the six track names are fixed, UNPOINTED
   strings (TRACK_TITLES), so hard rule 5 — never bold pointed Hebrew, synthetic bold drops
   nikud/taamim — does not apply. Never extend this to .pt/.dt, which carry Sefaria text. */
.lrow .nm { flex:0 0 calc(84px * var(--hs)); font-family:var(--font-src); font-size:calc(var(--fs-2) * var(--hs)); line-height:var(--lh-tight); color:var(--accent); font-weight:700; }
.lrow .lbody { flex:1 1 auto; min-width:0; display:block; }
.lrow .pt { display:block; font-family:var(--font-ui); font-size:calc(var(--fs-floor) * var(--hs)); line-height:var(--lh-tight); color:var(--ink); }
.lrow .pt + .pt { margin-top:var(--s-2); }
/* D-106 #9 (operator 2026-09-02: «limit breslev row to 3»): the ברסלב row is EXACTLY three lines,
   one per book, never wrapping. A long place is ellipsized — it sits LAST on its line, so the cut
   always falls on the place, never on the book name. Only this row: the other tracks' single
   portion line may still wrap (a long סימן range in קיצור has nowhere else to go). */
/* D-243: that three-line row is gone — each book is its own one-line row now, like any track */
/* D-107 #3 (operator 2026-09-02: «the yalkut yossef should be limited to 3 lines»): the קיצור row
   is at most THREE lines in total — its portion line (which may wrap: a סימן title has no short
   form) plus the position detail — and whatever spills is ellipsized on the third line. The clamp
   sits on .lbody, so the cut lands on the detail («סימן ב מתוך טו · סימן תקפב · סעיפים…»), never
   inside the title; the fit rungs' nowrap detail (fit2) and hidden detail (fit5) still apply. */
/* D-245 (operator, 2026-10-11: «each maslul to take not more than one line»): that clamp is gone —
   every home row is ONE line now (below), the קיצור row included. */
/* D-245: ONE line per home row. The name never wraps: its column is as wide as the longest name
   (`--nm-w`, set by fitNames in app.js, capped so the portion keeps room) and a name still too wide
   shrinks there to the 16 px floor; the portion line is cut with «…» where the row ends (operator's
   ruling: cut, not shrink, not wrap). Scoped to the home ledger: מסלולים (.tlist) keeps its own rules. */
#ledger .lrow .nm { flex-basis:var(--nm-w, calc(84px * var(--hs))); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
#ledger .lrow .lbody { overflow:hidden; }
#ledger .lrow .pt { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* D-245, second ruling (operator, the same evening, from a board of four heights — 57 / 49 / 39 /
   33 px — «Middle between c and d»): a home row is 36 px. That is below the --tap guideline, by the
   operator's choice; the row is still full-width, so it is the HEIGHT that shrank, not the target.
   No padding (#app outranks the fit1 rung's padding, which would add it back), the row button 35 px,
   and the mark's tap halo cut to the row's height so a tap can never land on the NEIGHBOUR's mark
   (22 px circle + 6 px each side = 34 px; it keeps its full width). */
#app #ledger .lflex { padding:0 var(--s-2); }
#ledger .lmain { min-height:35px; }
#ledger .mark::before { inset:-6px -11px; }   /* the base rule's 50% radius stays (D-204: the mark's own exception) */
.lrow .pt .frag { color:var(--dim); font-size:calc(var(--fs-floor) * var(--hs)); }   /* the place beside a name reads at the
   detail size, like the second line of every other row (operator, 2026-08-31) */
.lrow .dt { display:block; font-family:var(--font-ui); font-size:calc(var(--fs-floor) * var(--hs)); line-height:var(--lh-ui); color:var(--dim); margin-top:var(--s-1); }
.lrow.done .nm, .lrow.done .pt, .lrow.done .pt .frag { color:var(--mute); }
/* §12d: a row with nothing to open (st-none — rest day; st-unavailable — no source) reads as set
   aside, deader than done: name and portion drop to the ornament grey, while the explanation
   (.dt — «שבת · אין חק היום») keeps the readable detail grey (--dim). These are UI labels
   (TRACK_TITLES, a server note), never running Torah text, so --faint is permitted here (the
   palette rule at the top of this file). The greying is also the missing press feedback: the
   .lmain is disabled on these rows, and a set-aside row invites no press. */
.lrow.st-none .nm, .lrow.st-none .pt, .lrow.st-none .pt .frag,
.lrow.st-unavailable .nm, .lrow.st-unavailable .pt, .lrow.st-unavailable .pt .frag { color:var(--faint); }
.lrow .pickrow { display:block; width:100%; min-height:var(--tap); padding:0 var(--s-2) var(--s-6); margin-top:calc(-1 * var(--s-8)); text-align:start;
  font-size:calc(var(--fs-floor) * var(--hs)); color:var(--gold); border:none; }
/* The mark is ROUND — the one deliberate exception to this direction's "no border-radius
   anywhere" (operator, 2026-08-31: the round progress icon read better than the design's square
   checkbox), kept SMALL AND LIGHT: the same 22px box as the square it replaces, on a 1px hairline
   like the page's own rules. The part-read state is a PIE WEDGE (two radii, growing angle — the
   operator's words), not the old thin arc.
   The fill is a BACKGROUND, not a child: Chrome lays a <button>'s children out in an anonymous,
   vertically-centred inner box, so a ::after or an <i> fill grew the box to 24.4px and shifted it
   down (measured 2026-08-31, five layout variants). --p is the read fraction, set inline. */
.mark { position:relative; flex:none; width:22px; height:22px; border:var(--rule-strong); border-radius:50%;
  display:inline-flex; align-items:center; justify-content:center; font-size:var(--fs-fine); line-height:18px; color:var(--ok);
  background:none; padding:0; }
.mark::before { content:""; position:absolute; inset:-11px; border-radius:50%; }   /* the 44px tap target */
.mark.on { border-color:var(--ok); background:var(--okfill); }
/* state class is .partial — `.part` is the chok reader's PART section (with --part-gap margins) */
.mark.partial { background:conic-gradient(var(--fill) calc(var(--p,0) * 1turn), transparent 0); }
.mark.pend { border-style:dashed; border-color:var(--dim); color:var(--dim); align-items:center; }
.mark.none { border:none; }
.mark:active { transform:scale(.92); }
/* D-252 (operator, 2026-10-13, from the Claude Design canvas: «עיגול ב», «פלח ירוק בהיר»): the HOME
   mark redrawn — markHtml adds `hm`, so the מסלולים switches and the התקדמות cells keep their own.
   A 1.5 px edge; done is the pale --okfill disc on an --ok edge with a drawn tick; part-read is the
   same edge with the wedge in --okwedge over --card (it was --fill over nothing, on the grey edge). */
.mark.hm { border-width:1.5px; border-color:var(--ring); }   /* not yet: the canvas's lighter grey ring */
.mark.hm.on { border-color:var(--ok); background:var(--okdone); color:var(--ok); }
.mark.hm.partial { border-color:var(--ok); background:conic-gradient(var(--okwedge) calc(var(--p,0) * 1turn), var(--card) 0); }
.mark.hm.pend { border-color:var(--dim); }
.mark .ck { width:13px; height:13px; fill:none; stroke:currentColor; stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round; }
/* D-252 (operator, 2026-10-13: «I like 1» · «tracks' vertical height should be the same for all
   tracks, so the buttons are well aligned» · «a bit lighter» blue stripes): the ledger in TWO
   columns when settings › מסך הבית says so (ledgerHtml in app.js). Two flex columns in the learner's
   order, a --frame hairline between them, every row ONE fixed height — name over place, the mark at
   the row's start — so the rows and their rules line up across, and every other row on --stripe. */
#ledger.cols2 { display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); }
#ledger.cols2 .lcol { min-width:0; }
#ledger.cols2 .lcol + .lcol { border-inline-start:1px solid var(--frame); }
#ledger.cols2 .lrow:nth-child(even) { background:var(--stripe); }
#app #ledger.cols2 .lflex { height:calc(56px * var(--hs)); }
#ledger.cols2 .lrow.lgap { height:calc(56px * var(--hs)); }
#ledger.cols2 .lmain { align-self:stretch; display:flex; align-items:center; min-height:0; }
#ledger.cols2 .mark { order:-1; }
#ledger.cols2 .lrow .lin { flex:1 1 auto; min-width:0; flex-direction:column; align-items:stretch; gap:0; }
#ledger.cols2 .lrow .nm { flex:none; width:100%; font-size:var(--fs-2); }       /* the board's 18 / 16 — a half-width */
#ledger.cols2 .lrow .lbody { width:100%; }                                      /* column has no room for the +15 % */
#ledger.cols2 .lrow .pt, #ledger.cols2 .lrow .pt .frag { font-size:var(--fs-floor); }
#app #ledger.cols2 .lflex { padding:0 var(--s-8); }
/* D-252, the rest of the chosen board («1», then «1ד»), on the home in BOTH shapes — the column
   setting changes the ledger only: no page frame and no corner ticks; בס״ד and הגדרות in gold; the
   kicker spaced .4em; the title bold (an unpointed fixed string — rule 5 does not apply); the day's
   chevrons in gold at the row's two edges with the date between them in the accent, upright; the
   backlog line in italic, as drawn. */
#app.is-home .page { border-color:transparent; }
#app.is-home .page > .tick { display:none; }
#app.is-home .corner .bsd, #app.is-home .corner .setlink { color:var(--gold); }
#app.is-home .mast .kicker { letter-spacing:.4em; }
#app.is-home .mast .mtitle { font-weight:700; }
#app.is-home .daterow { justify-content:space-between; }
#app.is-home .daterow .dbtn { color:var(--gold); }
#app.is-home .daterow .dline { color:var(--accent); font-style:normal; }
#app.is-home .blrule { font-style:italic; }
.blrule { display:flex; align-items:center; gap:var(--s-8); width:100%; min-height:var(--tap); font-size:calc(var(--fs-floor) * var(--hs)); color:var(--dim);
  border-bottom:var(--rule); text-align:start; padding:0; }
.blrule:not(:disabled):active { background:var(--soft); }
.blrule:disabled { cursor:default; }
.blrule .tally { margin-inline-start:auto; }
.vfoot { text-align:center; padding-top:var(--s-16); }
.vfoot .rule { margin:0 0 var(--s-6); }
.vfoot .verse { font-family:var(--font-src); font-size:calc(var(--fs-3) * var(--hs)); line-height:var(--lh-prose); color:var(--accent); margin:0; }
.vfoot .vsrc { font-family:var(--font-src); font-size:calc(var(--fs-floor) * var(--hs)); color:var(--dim); margin:var(--s-2) 0 0; }
.home-head { text-align:center; padding:calc(var(--s-6) * var(--dens)) 0 calc(var(--s-4) * var(--dens)); position:relative; }
.home-tools { position:absolute; inset-inline-start:0; top:.3rem; }
.iconBtn { min-width:var(--tap); min-height:var(--tap); display:inline-flex; align-items:center; justify-content:center;
  border-radius:0; font-size:var(--fs-3); color:var(--dim); }
.iconBtn:active { background:var(--soft); }
.home-head h1 { font-family:var(--font-src); font-size:var(--fs-5); margin:calc(var(--s-4) * var(--dens)) 0 calc(var(--s-2) * var(--dens)); color:var(--accent); font-weight:normal; }
.rest { color:var(--gold); font-size:var(--fs-floor); margin:calc(var(--s-2) * var(--dens)) 0 calc(var(--s-4) * var(--dens)); }
.stale { color:var(--gold); font-size:var(--fs-floor); margin:calc(var(--s-4) * var(--dens)) 0 calc(var(--s-2) * var(--dens)); }
/* D-138: the guest's registration line — one quiet line under the ledger, at most three times
   ever (server-counted). Same hand as .stale/.cap; the two links are 44px targets, nothing bold. */
.nudge { font-size:var(--fs-floor); color:var(--dim); line-height:var(--lh-prose); margin:calc(var(--s-6) * var(--dens)) 0 calc(var(--s-2) * var(--dens)); text-align:center; }
.nudge .linkish { min-height:var(--tap); display:inline-flex; align-items:center; padding:0 calc(var(--s-8) * var(--dens)); color:var(--accent); }
/* §13a3 (D-113): «another device synced …». Quieter than .stale on purpose — the dim ink, not the
   gold: nothing is wrong and nothing is owed, the other device is simply the current one. Rule 10:
   no badge, no icon, no border, no colour that reads as an error. It is invisible on a
   single-device install, which is the operator's normal case (see syncStale in app.js). */
.syncnote { color:var(--dim); font-size:var(--fs-floor); margin:calc(var(--s-4) * var(--dens)) 0 calc(var(--s-2) * var(--dens)); }
/* D-47 day navigation: chevrons flank the date; the row is quiet until pressed */
.dnav { display:flex; align-items:center; justify-content:center; gap:calc(var(--s-2) * var(--dens)); margin:var(--s-1) 0 0; }
.dbtn { min-width:var(--tap); min-height:var(--tap); display:inline-flex; align-items:center; justify-content:center;
  border-radius:0; font-size:var(--fs-4); color:var(--dim); line-height:var(--lh-flat); }
.dbtn:active { background:var(--soft); }
.dline { font-size:var(--fs-2); color:var(--ink); padding-inline:calc(var(--s-4) * var(--dens)); }   /* larger on request (D-55); no min-width: the chevrons hug the date */
.dstreak { font-size:var(--fs-floor); color:var(--dim); }
.dstreak .n { color:var(--accent); }
.pill { display:inline-block; margin:calc(var(--s-4) * var(--dens)) auto 0; padding:calc(var(--s-4) * var(--dens)) calc(var(--s-16) * var(--dens)); min-height:36px;
  border:var(--rule); border-radius:0; font-size:var(--fs-floor); color:var(--accent); background:var(--card); }
.pill:active { background:var(--soft); }
.othernote { color:var(--mute); font-size:var(--fs-floor); text-align:center; margin:calc(var(--s-12) * var(--dens)) auto 0; max-width:24rem; }
/* no letter-spacing on pointed Hebrew: tracking drifts nikud off its letters */
/* the dedication verse closes the page now (D-50): under the rows, where it costs nothing above the fold */
/* the verse is fixed (no longer a setting, D-55) and fills 90% of the screen width: measured 17.53px
   of text per font-px, so 5.1vw = 0.9 x viewport on any phone; clamped for tablets/desktops */
.dedication { text-align:center; color:var(--accent); font-size:var(--fs-3);   /* measured: 5.1vw filled 81% on 360/388/412; 5.65vw ~ 90% (D-55) */ margin:calc(var(--s-24) * var(--dens)) auto 0; padding:0;
  max-width:none; white-space:nowrap; line-height:max(1.4, calc(1.75 * var(--lhf))); }
.dedication small { font-family:var(--font-ui); color:var(--dim); font-size:var(--fs-floor); }
.cards { display:grid; gap:calc(var(--s-6) * var(--dens)); margin-top:calc(var(--s-8) * var(--dens)); }
.card { display:block; background:var(--card); border:var(--rule); border-radius:0; }
.card-row { display:flex; align-items:stretch; }
/* the "off" signal is the surface, not unreadable ink (opacity took .sub to 2.35:1) */
.card.muted { background:var(--bg); }
.card.muted .ttl, .card.muted .lbl, .card.muted .sub, .card.muted .mins, .card.muted .note { color:var(--mute); }
.card.st-paused { border-inline-start:3px solid var(--gold); }
.card-main { flex:1 1 auto; min-width:0; display:flex; flex-direction:column; gap:calc(var(--s-2) * var(--dens)); text-align:start;
  padding:calc(var(--s-6) * var(--dens)) calc(var(--s-12) * var(--dens)); min-height:var(--tap); justify-content:center;
  border-start-start-radius:0; border-end-start-radius:0; }
.card-main:not(:disabled):active { background:var(--soft); }
.card-main:disabled { cursor:default; }
/* D-50: ONE line per track — kicker, headline and a folded tail share a baseline; a long line
   may wrap to two (text is shortened first), a note stays its own small line */
/* D-51: the NAME stands out (source face, navy) in a fixed column, so every portion starts at the
   same x; a long name (קיצור ילקוט יוסף) wraps inside its column. Portion + tail: one sans size. */
.card-main .line { display:flex; align-items:baseline; gap:calc(var(--s-8) * var(--dens)); line-height:var(--lh-tight); }
.card-main .ttl { flex:0 0 5.3rem; font-family:var(--font-src); font-size:var(--fs-2); color:var(--accent); line-height:var(--lh-tight); }
.card-main .rest { flex:1 1 auto; min-width:0; }
/* today's portion = headline, in the SOURCE face (operator, 2026-08-30: "I like the font on
   תיקון הכללי, use it for the other cards; keep the first line as is"). The kicker stays sans. */
.card-main .lbl { font-family:var(--font-src); font-family:inherit; font-size:var(--fs-floor); line-height:var(--lh-tight); color:var(--ink); }
.card-main .sub { font-size:var(--fs-floor); color:var(--dim); }
.card-main .sub.blk { display:block; }          /* קיצור: the position on its own line under the heading */
.card-main .note { font-size:var(--fs-floor); color:var(--gold); margin-top:calc(var(--s-2) * var(--dens)); }
.pickrow { display:block; width:100%; min-height:var(--tap); padding:calc(var(--s-8) * var(--dens)) calc(var(--s-16) * var(--dens)) calc(var(--s-12) * var(--dens)); text-align:start;
  font-size:var(--fs-floor); color:var(--gold); border-top:var(--rule); }
.pickrow:active { background:var(--soft); }
.card .side { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:calc(var(--s-4) * var(--dens));
  padding:calc(var(--s-4) * var(--dens)) calc(var(--s-8) * var(--dens)) calc(var(--s-4) * var(--dens)) calc(var(--s-8) * var(--dens)); flex:none; }
.mins { font-size:var(--fs-floor); color:var(--dim); white-space:nowrap; }
.card-main .pos { font-size:var(--fs-floor); color:var(--dim); margin-top:calc(var(--s-2) * var(--dens)); }
/* 36px drawn, 44px tapped: the hit area is a pseudo-element, so the row is only as tall as the ring */
.chk { position:relative; width:36px; height:36px; border-radius:0; border:2px solid var(--ctl); display:flex;
  align-items:center; justify-content:center; font-size:var(--fs-2); color:var(--ok); background:var(--card); }
.chk::before { content:""; position:absolute; inset:-5px; border-radius:0; }
.chk.on { background:var(--soft); border-color:var(--ok); }
/* how far into today's portion you have read — the same number the reader's hairline shows.
   An arc, not a pie: ::after punches the middle back out. --p is a fraction, set inline. */
.chk.prog { background:conic-gradient(var(--gold) calc(var(--p,0) * 1turn), var(--card) 0); }
.chk.prog::after { content:""; position:absolute; inset:3px; border-radius:0; background:var(--card); }
/* a done-mark queued offline (D-57): dashed, dim, with its check — pending, not done */
.chk.pend { border-style:dashed; border-color:var(--dim); color:var(--dim); }
.done-lbl.pend { color:var(--dim); }
/* D-58: the gemara quota's end inside the whole daf, and the projected-portion note */
.quota-mark { text-align:center; color:var(--accent); font-size:var(--fs-floor);
  border-bottom:1px dashed var(--ctl); padding:0 0 calc(var(--s-8) * var(--dens)); margin:calc(var(--s-12) * var(--dens)) 0; }
/* D-172: the control ON the closing marker. The section's last amud runs on past «עד כאן להיום»
   (the daf stays whole, D-58), so the foot bar sits below text the day did not ask for; this is
   the mark where the day's learning actually ends. Empty in every state but the plain markable
   one, and an empty div must take no space — hence :empty, not a class the renderer would have
   to keep in step. */
.qdone { display:flex; justify-content:center; margin:calc(var(--s-12) * var(--dens)) 0 calc(var(--s-24) * var(--dens)); }
.qdone:empty { display:none; }
/* `.btn1` is scoped to `.foot` (the D-169b note on `.hit-btn` says why that bites): outside the
   foot band it styles NOTHING and the control renders as bare text. The mark on the closing
   marker and the read-on question's first answer both live outside it. Quieter than the foot's
   primary - this one sits INSIDE the reading, and must not shout over the daf. */
/* D-217 (§28 / §30b-12): the התבודדות four-hour sheet's «רשום עד השעה הזאת» (`#hitAsk .btn1`) was the
   third sighting of this trap - it LEADS its sheet and drew as bare text, 121x20 px. Same rule. */
.qdone .btn1, #readOn .btn1, #hitAsk .btn1 { min-width:11rem; min-height:var(--tap); padding:0 calc(var(--s-16) * var(--dens)); font-size:var(--fs-floor);
  border-radius:0; color:var(--bg); background:var(--accent); border:1px solid var(--accent);
  font-family:inherit; cursor:pointer; }
.qdone .btn1:active, #readOn .btn1:active, #hitAsk .btn1:active { opacity:.85; }
#readOn .btn2 { min-width:11rem; }
#readOn .nm { font-size:var(--fs-floor); opacity:.85; }
/* D-172: the turn of the amud, inside the section. A centred hairline carrying the amud's name —
   חק's section-rule grammar (`.fh`), quieter: this delimits, it does not introduce. The band can be
   hidden for a whole long scroll (chrome-off), so this is the only thing on the page that says
   where you are. It is NOT a `.sec` and never a heading: the reading runs straight through it. */
.amudrule { display:flex; align-items:center; gap:calc(var(--s-8) * var(--dens)); color:var(--dim);
  font-size:var(--fs-floor); margin:calc(var(--s-24) * var(--dens)) 0 calc(var(--s-16) * var(--dens)); }
.amudrule::before, .amudrule::after { content:""; flex:1 1 0; height:1px; background:var(--line); }
.amudrule span { flex:none; letter-spacing:.06em; }
/* D-145: the same marker turned over for the day's START — the rule sits UNDER the words, since
   what it delimits is below it, not above. Same dash, same colour: one convention, two ends. */
.quota-mark.start { border-bottom:0; border-top:1px dashed var(--ctl);
  padding:calc(var(--s-8) * var(--dens)) 0 0; }
.projnote { display:block; color:var(--dim); font-size:var(--fs-floor); text-align:center; margin-bottom:calc(var(--s-8) * var(--dens)); }
.chk:active { transform:scale(.92); }
.sect { font-size:var(--fs-floor); color:var(--dim); margin:calc(var(--s-24) * var(--dens)) 0 calc(var(--s-8) * var(--dens)); border-bottom:var(--rule); padding-bottom:calc(var(--s-4) * var(--dens)); font-weight:normal; }
.sect small { color:var(--dim); font-size:var(--fs-floor); }
/* Backlog is secondary by definition (auto-drops after 7 days) and is not shown at all until
   today's חק is done — an unfinished today with a list of unfinished yesterdays under it is the
   one thing on this screen that could read as reproach. Collapsed it is ONE line. */
.blline { display:flex; align-items:center; gap:calc(var(--s-8) * var(--dens)); width:100%; min-height:var(--tap); margin-top:calc(var(--s-24) * var(--dens));
  padding:calc(var(--s-4) * var(--dens)) calc(var(--s-4) * var(--dens)); border-top:var(--rule); text-align:start;
  color:var(--dim); font-size:var(--fs-floor); }
.blline:active { background:var(--soft); }
.blline .chev { margin-inline-start:auto; color:var(--faint); }   /* --ctl is a rule colour, never a glyph (D-63) */
.backlog { gap:0; margin-top:calc(var(--s-4) * var(--dens)); }
.backlog .card { background:none; border:none; border-radius:0; border-bottom:var(--rule); }
.backlog .card:last-child { border-bottom:none; }
.backlog .card-main { padding:calc(var(--s-8) * var(--dens)) calc(var(--s-4) * var(--dens)); }
#blMore { min-width:var(--tap); padding-inline:calc(var(--s-8) * var(--dens)); }   /* "עוד N" is short; keep the target full size */
.backlog .lbl { font-size:var(--fs-floor); color:var(--accent); }
.backlog .sub { font-size:var(--fs-floor); }
/* An author `display` rule outranks the UA's [hidden]{display:none} regardless of specificity, so
   every element the JS hides with .hidden=true needs its own [hidden] rule (2026-08-28). */
.iconBtn[hidden], .card[hidden], .cards[hidden], .backlog[hidden] { display:none; }
/* D-169: and the same for the ruled strip and its label — `.rstrip` is `display:flex`, so the
   weekday picker of אגרת הרמב״ן stayed on screen under «כל יום» even though its `hidden` property
   was true. A test that asserts `el.hidden` passes blind here; assert `getClientRects()`. */
.rstrip[hidden], .slabel[hidden] { display:none; }
/* ---------- תיקון הכללי: one quiet section under the five, set apart by TYPE, not by colour.
   A gold hairline on top, the title in the source face, the ten psalm numbers as small gematria
   chips. Everything else is the ordinary card, so density, themes and the done ring all apply. */
/* the תיקון row is the plain sixth row (D-50): no hairline, no gap of its own */
/* in the reader each psalm gets a centred heading in the source face with a short gold rule under
   it — a page turn, not a section label */
/* D-52: ONE heading per psalm, right-aligned with the text (no centred rule, no caption under it),
   carrying the Sefaria link itself; the short gold hairline sits under the heading's start edge */
.tk-body .sec-h { font-family:var(--font-src); font-size:var(--fs-3); letter-spacing:0;
  color:var(--accent); text-align:start; border-bottom:none; padding-bottom:0;
  margin:calc(var(--s-24) * var(--dens)) 0 calc(var(--s-6) * var(--dens)); }
.tk-body .sec-h a { color:inherit; text-decoration:none; }
.tk-body .sec-h .ext { font-family:var(--font-ui); font-size:var(--fs-floor); color:var(--dim); vertical-align:super; margin-inline-start:calc(var(--s-2) * var(--dens)); }
.tk-body .sec-h::after { content:""; display:block; width:2.75rem; height:1px; background:var(--gold); opacity:.7; margin:calc(var(--s-6) * var(--dens)) 0 0; }
/* the jump rail as text chips: 34px, no border — a row of numbers, not ten buttons */
.tk-rail .rchip { min-height:34px; border:none; background:none; color:var(--gold); padding:0 calc(var(--s-8) * var(--dens));
  font-family:var(--font-src); font-size:var(--fs-floor); }
.tk-rail .rchip:active { background:var(--soft); }
/* שווא נע: the letter+sheva cluster is tinted (same quiet shift as commented daf text); off via Aa */
.sn { color:var(--sheva); font-weight:bold; }   /* bold on request (D-55): Taamey D has no bold face, so this is a synthetic bold and the marks stay */
.body.no-sheva .sn { color:inherit; }
.tk-body .sec:first-of-type .sec-h { margin-top:calc(var(--s-8) * var(--dens)); }
/* D-156: the one practice line at the foot of the תיקון — set like a caption, not like text */
.tk-body .tk-foot { font-size:var(--fs-floor); color:var(--dim); line-height:var(--lh-unpointed); margin:calc(var(--s-24) * var(--dens)) 0 0; }
/* D-157: a collapsible piece's title IS the control — the heading's own face, a drawn chevron after
   it (D-68c: a shape, never a glyph), 44px tall to be a target. A shut piece's title reads in --dim
   and sits closer to its neighbour, so a run of shut titles is a quiet list, not a page of headings. */
.tk-body .sec-h .tk-tt { all:unset; display:inline-flex; align-items:center; gap:calc(var(--s-8) * var(--dens)); min-height:var(--tap); cursor:pointer;
  color:inherit; font:inherit; -webkit-tap-highlight-color:transparent; }
.tk-body .sec-h .tk-tt::after { content:""; flex:none; width:7px; height:7px; border:solid var(--ctl); border-width:0 0 1.5px 1.5px;
  transform:translateY(-2px) rotate(-45deg); transition:transform .18s; }
.tk-body .sec-h .tk-tt[aria-expanded="true"]::after { transform:translateY(2px) rotate(135deg); }
.tk-body .tk-fold.shut { margin-bottom:0; }                     /* D-158: no section gap under a shut title */
.tk-body .tk-fold.shut .sec-h { color:var(--dim); margin:0; }    /* the 44px control is the whole row */
.tk-body .tk-fold.shut .sec-h::after { display:none; }
.tk-body .tk-fold.shut + .sec .sec-h { margin-top:calc(var(--s-16) * var(--dens)); }   /* an open section after the list breathes */
.tk-body .tk-fold.shut + .tk-fold.shut .sec-h { margin-top:0; }
/* D-158: the תיקון's one-row strip sizes its cells to their labels (13 cells at 384px: a numeral's cell
   narrow, «פסוקים» wide, nothing clipped); the wrapped strip keeps equal cells so its columns align */
.lstrip.tk:not(.rows) .cell { flex:1 1 auto; padding-inline:var(--s-2); }
.streak { text-align:center; color:var(--dim); font-size:var(--fs-floor); margin:calc(var(--s-32) * var(--dens)) 0 calc(var(--s-8) * var(--dens)); }
.streak .n { color:var(--accent); font-size:var(--fs-2); }
.closed { text-align:center; color:var(--ok); font-size:var(--fs-floor); margin:calc(var(--s-24) * var(--dens)) 0 0; }

/* ---------- reader header + menu ---------- */
.rd-top { position:sticky; top:var(--offbar-h, 0px); z-index:var(--z-band); background:var(--bg); display:flex; align-items:center; gap:calc(var(--s-6) * var(--dens));
  padding:calc(var(--s-6) * var(--dens) + max(0px, env(safe-area-inset-top) - var(--offbar-h, 0px))) 0 calc(var(--s-6) * var(--dens)); border-bottom:var(--rule);
  transition:transform .22s ease, opacity .22s ease; }
/* Headroom pattern: scrolling down gives the page back to the text, scrolling up (or reaching the
   end, or focusing anything in it) brings the header back. Never hidden when a popover is open —
   that would take the menu with it. */
body.chrome-off .rd-top { transform:translateY(-115%); opacity:0; }
@media (prefers-reduced-motion: reduce) { .rd-top { transition:none; } }
/* reading progress: a 4px hairline at the very top, and nothing else (2px → 3px D-106 → 4px D-107,
   operator 2026-09-02 both times) */
.rdprog { position:fixed; top:env(safe-area-inset-top); inset-inline-start:0; height:4px; width:0;
  background:var(--gold); opacity:.75; z-index:var(--z-progress); pointer-events:none;
  /* D-169e: no width transition. The width is rewritten every scroll frame, so a 120 ms
     interpolation was cancelled and restarted on each one — a live animation for the whole of
     every scroll, arriving nowhere the per-frame write had not already gone. */
  transition:opacity .2s; }
.rd-top h1 { font-size:var(--fs-floor); margin:0; flex:1 1 auto; min-width:0; line-height:var(--lh-tight); font-weight:normal; color:var(--accent);
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.back { min-width:var(--tap); min-height:var(--tap); font-size:var(--fs-4); display:inline-flex; align-items:center; justify-content:center; border-radius:0; }
.back:active, .iconBtn:active { background:var(--soft); }
.menu { position:absolute; top:100%; inset-inline-end:0; margin-top:calc(var(--s-4) * var(--dens)); width:min(20rem, 92vw); background:var(--card);
  border:var(--rule); border-radius:0; box-shadow:0 8px 28px var(--shadow); padding:calc(var(--s-6) * var(--dens)); z-index:var(--z-menu); }
.menu[hidden] { display:none; }
.mrow { display:flex; align-items:center; gap:calc(var(--s-8) * var(--dens)); width:100%; min-height:var(--tap); padding:calc(var(--s-6) * var(--dens)) calc(var(--s-12) * var(--dens)); border-radius:0;
  text-align:start; font-size:var(--fs-floor); text-decoration:none; color:var(--ink); }
.mrow:active { background:var(--soft); }
.mrow input[type=range] { flex:1 1 auto; min-width:0; accent-color:var(--gold); height:var(--tap); }
.mrow output { min-width:2ch; text-align:center; color:var(--dim); font-size:var(--fs-floor); }
.mrow select { flex:1 1 auto; font:inherit; color:var(--ink); background:var(--bg); border:var(--rule-strong);
  border-radius:0; padding:calc(var(--s-6) * var(--dens)) calc(var(--s-8) * var(--dens)); min-height:var(--tap); }
.mrow .k { color:var(--dim); font-size:var(--fs-floor); flex:none; }
.mrow.stack { flex-direction:column; align-items:stretch; gap:calc(var(--s-4) * var(--dens)); padding-block:calc(var(--s-8) * var(--dens)); }
.mrow.stack .k { align-self:flex-start; }
.mrow.stack input[type=range] { width:100%; }
.mhead { color:var(--gold); font-size:var(--fs-floor); padding:calc(var(--s-8) * var(--dens)) calc(var(--s-12) * var(--dens)) calc(var(--s-2) * var(--dens)); letter-spacing:.03em; }
.mhead:first-child { padding-top:calc(var(--s-4) * var(--dens)); }
/* segmented control: density, night stops, gemara layers — one row, one choice, no dropdown */
.segbar { display:flex; gap:calc(var(--s-4) * var(--dens)); }
.segbar button { flex:1 1 0; min-height:var(--tap); padding:0 calc(var(--s-6) * var(--dens)); border-radius:0; border:var(--rule-strong);
  background:var(--card); color:var(--dim); font-size:var(--fs-floor); white-space:nowrap; }
.segbar button[aria-pressed="true"] { background:var(--soft); color:var(--accent); border-color:var(--gold); }
.segbar button:active { background:var(--soft); }
/* layer switches: built from what the payload actually carries, never a fixed list */
.swrow { display:flex; align-items:center; justify-content:space-between; gap:calc(var(--s-8) * var(--dens)); width:100%;
  min-height:var(--tap); padding:calc(var(--s-4) * var(--dens)) calc(var(--s-12) * var(--dens)); border-radius:0; text-align:start; font-size:var(--fs-floor); color:var(--ink); }
.swrow:active { background:var(--soft); }
.sw { flex:none; width:2.6rem; height:1.5rem; border-radius:0; background:var(--line);
  border:var(--rule-strong); position:relative; transition:background .18s; }
.sw::after { content:""; position:absolute; top:1px; inset-inline-start:1px; width:1.15rem; height:1.15rem;
  border-radius:0; background:var(--card); box-shadow:0 1px 3px var(--shadow); transition:transform .18s; }
.swrow[aria-pressed="true"] .sw { background:var(--gold); border-color:var(--gold); }
.swrow[aria-pressed="true"] .sw::after { transform:translateX(calc(-1 * (2.6rem - 1.15rem - 4px))); }
@media (prefers-reduced-motion: reduce) { .sw, .sw::after { transition:none; } }

/* ---------- find within the portion ---------- */
/* Pinned BELOW the header, not on top of it. Both are sticky; with the same `top` the find bar
   won on z-index and covered Back / Aa / ⋯ completely while a search was open. --rdtop-h is
   measured by the client, since the header's height includes the safe-area inset.
   D-164 (CUI-03): under the BAND, not under the strip. The bar precedes #rbody in the DOM and the
   strip lives inside it, so a `top` below the strip's put the bar over the strip's cells at the
   top of the page (the strip still in flow, the bar already stuck; z 22 over 19 — every cell dead).
   The strip now sticks under the bar by the measured --findbar-h (0 while closed), and so does
   everything that already stacked past --lstrip-h. D-87/D-88 hold: both ride the same -rdtop-h. */
.findbar { position:sticky; top:calc(var(--offbar-h, 0px) + env(safe-area-inset-top) + var(--rdtop-h, 3.2rem)); z-index:var(--z-findbar);
  transition:transform .22s ease; }
/* D-87: the strip no longer leaves — the find bar shifts with it so no gap opens over the page */
body.chrome-off .findbar { transform:translateY(calc(-1 * var(--rdtop-h, 3.2rem))); }
.findbar { 
  display:flex; align-items:center; gap:calc(var(--s-6) * var(--dens)); background:var(--card); border:var(--rule);
  border-radius:0; padding:calc(var(--s-4) * var(--dens)) calc(var(--s-8) * var(--dens)); margin:calc(var(--s-6) * var(--dens)) 0 calc(var(--s-4) * var(--dens)); }
.findbar[hidden] { display:none; }
.findbar input { flex:1 1 auto; min-width:0; font:inherit; font-size:var(--fs-floor); color:var(--ink);
  background:var(--bg); border:var(--rule-strong); border-radius:0; padding:calc(var(--s-6) * var(--dens)) calc(var(--s-8) * var(--dens)); min-height:var(--tap); }
.findbar .fcount { color:var(--dim); font-size:var(--fs-floor); min-width:4.5ch; text-align:center; white-space:nowrap; }
.findbar .fbtn { min-width:var(--tap); min-height:var(--tap); border-radius:0; color:var(--accent); font-size:var(--fs-2);
  display:inline-flex; align-items:center; justify-content:center; }
.findbar .fbtn:disabled { color:var(--dim); opacity:.5; }
.findbar .fbtn:active { background:var(--soft); }
/* never bold, never a colour that fights nikud: a tint plus a hairline is enough */
mark.hit { background:var(--soft); color:inherit; font-weight:inherit; border-radius:0;
  box-shadow:inset 0 -2px 0 var(--ctl); }
mark.hit.on { background:var(--gold); color:var(--btn-ink); box-shadow:none; }

/* ---------- reader body ---------- */
.body { padding:calc(var(--s-8) * var(--dens)) 0 calc(var(--s-16) * var(--dens) + env(safe-area-inset-bottom)); }
/* D-86 #1: 4rem cleared only the header; with the section strip stuck under it, an UPWARD jump
   landed the heading 24px beneath the strip (measured: heading top 64, strip bottom 88). The
   heights are already measured into --rdtop-h/--lstrip-h, so the margin uses them and cannot drift
   when either bar changes. */
.sec { margin:0 0 var(--sec-gap);
  scroll-margin-top:calc(var(--offbar-h, 0px) + env(safe-area-inset-top) + var(--rdtop-h, 3rem) + var(--findbar-h, 0px) + var(--lstrip-h, 0px) + 12px); }
/* D-106 #3: with the band hidden (chrome-off) the strip sits --rdtop-h higher, but the margin above
   still cleared the band — a jump landed the heading 55px under the strip (measured: heading top
   100, strip bottom 45) with the previous section's last line showing above it. D-88 keeps the
   band hidden across a jump, so the margin must follow the band's state, not its height. */
body.chrome-off .sec {
  scroll-margin-top:calc(var(--offbar-h, 0px) + env(safe-area-inset-top) + var(--findbar-h, 0px) + var(--lstrip-h, 0px) + 12px); }
/* D-222 (§32 item 3): a seif is a jump target too — the same measured stack as `.sec`'s landing */
.seif { scroll-margin-top:calc(var(--offbar-h, 0px) + env(safe-area-inset-top) + var(--rdtop-h, 3rem) + var(--findbar-h, 0px) + var(--lstrip-h, 0px) + 12px); }
body.chrome-off .seif {
  scroll-margin-top:calc(var(--offbar-h, 0px) + env(safe-area-inset-top) + var(--findbar-h, 0px) + var(--lstrip-h, 0px) + 12px); }
/* D-86 #5: on the chok page — 14 screens, eight sections — the section title is the ONLY
   boundary marker, and at .9rem it was smaller than the body text it labels. Chok alone gets a
   larger title over a full-width hairline; the first section skips the rule (it sits right under
   the strip). Scoped by data-track so the sheet's pane labels, breslev and tikkun keep theirs. */
#rbody[data-track="chok"] section.sec > .sec-h { font-size:var(--fs-2); border-top:var(--rule);
  padding-top:calc(var(--s-8) * var(--dens)); margin-top:calc(var(--sec-gap) * 1.2); }
#rbody[data-track="chok"] section.sec:first-of-type > .sec-h { border-top:0; padding-top:0; }
/* D-146: שניים מקרא reads as a series of aliyot, which is the same shape as חק's parts, so it takes
   the same section heading. Scoped separately rather than by a shared selector list so either can
   move without the other. */
#rbody[data-track="shnayim"] section.sec > .sec-h { font-size:var(--fs-2); border-top:var(--rule);
  padding-top:calc(var(--s-8) * var(--dens)); margin-top:calc(var(--sec-gap) * 1.2); }
#rbody[data-track="shnayim"] section.sec:first-of-type > .sec-h { border-top:0; padding-top:0; }
.sec-h { font-size:var(--fs-floor); color:var(--gold); margin:var(--sec-gap) 0 calc(var(--s-4) * var(--dens)); font-weight:normal; letter-spacing:.04em;
  border-bottom:var(--rule); padding-bottom:calc(var(--s-4) * var(--dens)); }
/* a whole-unit boundary (ליל שישי) needs clearly more air than a section heading */
.part { font-family:var(--font-src); font-size:var(--fs-4); color:var(--accent); font-weight:normal; text-align:center;
  margin:var(--part-gap) 0 calc(var(--s-4) * var(--dens)); padding-top:calc(var(--s-24) * var(--dens)); border-top:var(--rule); }
.pt-lbl { color:var(--dim); font-size:var(--fs-floor); margin:calc(var(--s-4) * var(--dens)) 0 calc(var(--s-2) * var(--dens)); }
/* D-222: דף היומי's «N ימים להשלמה · <the oldest daf> ›» — a quiet text link in the label's own face and
   colour (hard rule 10: no guilt colour), a real button so it is reachable by keyboard */
.pt-lbl .lnk { background:none; border:0; padding:0; margin:0; font:inherit; color:inherit; text-decoration:underline; text-underline-offset:.2em; cursor:pointer; }
.hint { font-size:var(--fs-floor); color:var(--dim); text-align:center; margin:0 0 calc(var(--s-8) * var(--dens)); }
.rail { display:flex; gap:calc(var(--s-6) * var(--dens)); overflow-x:auto; padding:calc(var(--s-4) * var(--dens)) 0 calc(var(--s-8) * var(--dens)); scrollbar-width:none; -webkit-overflow-scrolling:touch; }
.rail::-webkit-scrollbar { display:none; }
.rchip { flex:none; min-height:var(--tap); padding:0 calc(var(--s-12) * var(--dens)); border-radius:0; border:var(--rule-strong);
  background:var(--card); color:var(--dim); font-size:var(--fs-floor); white-space:nowrap; }
.rchip:active { background:var(--soft); }
.cap { font-size:var(--fs-floor); color:var(--dim); margin:var(--cap-gap) 0 calc(var(--s-2) * var(--dens)); }   /* D-86 #8: 12px → 13px; D-107 #2: the floor */
/* the 44px target is a pseudo-element, not 44px of blank line: a Kitzur page carries ~16 captions,
   and `line-height:44px` on each spent ~480px of scroll on nothing but hit area */
.cap a, .attrib a { color:var(--dim); display:inline-block; position:relative; padding-inline:calc(var(--s-4) * var(--dens)); }
.cap a::before, .attrib a::before { content:""; position:absolute; inset:-.85rem -.35rem; }
.item { margin:0 0 var(--unit-gap); }
/* scroll-margin clears the sticky header (and the offline bar above it) when a restored reading
   position or a rail jump scrolls one of these into view — otherwise it lands underneath it */
.seg { margin:0 0 var(--seg-gap); scroll-margin-top:5.5rem; border-radius:0; transition:background 1.2s ease; }
.unit { margin:0 0 var(--unit-gap); scroll-margin-top:5.5rem; border-radius:0; transition:background 1.2s ease; }
/* where you left off: the line is tinted for a moment, no words. Same signal as .gl.resumed. */
.resumed { background:var(--soft); }
/* text-indent:0 is the fix for a clipped number: `.src.has-vn` hung its first line (until D-204) with a NEGATIVE
   text-indent, and text-indent INHERITS into this inline-block — so the digit was pushed 40px out
   of its own box, past the screen edge, on every pointed reader (measured 2026-08-30: box at
   x 359–380, glyph at 385–393 on a 388px viewport). */
/* text-align:START, not center (operator, 2026-08-31: «the verse letter is too far from right
   screen edge»). The gutter's WIDTH is load-bearing — it equals the negative hang, so the first
   line starts where every wrapped line starts — so the number moves inside its box rather than the
   box getting narrower, which would drag the whole text column with it. Centred left ~14px of air
   between the numeral and the column edge; start-aligned it reads against the margin. */
.vn { font-size:var(--fs-floor); color:var(--gold); margin:0; user-select:none; display:inline-block;
  width:calc(var(--text-size) * var(--vn-gut, 1.75)); text-align:start; text-indent:0; }
/* תיקון numbers a single chapter, so its labels are one or two letters (widest 14.8px);
   חק and גמרא carry chapter:verse and keep the full gutter */
#rbody[data-track="tikkun"] { --vn-gut:1.15; }
/* D-108 #4: ברסלב's gutter carries the paragraph's own אות («נז», and «קנג» deep in a long section
   of ליקוטי עצות — three letters), so it gets the קיצור width, not תיקון's */
#rbody[data-track="likutei_tefilot"], #rbody[data-track="likutei_etzot"], #rbody[data-track="sefer_hamiddot"],
#rbody[data-track="hishtapchut_hanefesh"], #rbody[data-track="meshivat_nefesh"], #rbody[data-track="kitzur_likutei_moharan"] { --vn-gut:1.6; }   /* D-243: every ברסלב book */
/* D-191: שולחן ערוך numbers a סעיף, so its label is one or two letters — never «chapter:verse»,
   which is the shape the 1.75 default is sized for. At 1.75 the א sat in a 35px box and opened a
   conspicuous hole before the first word of every se'if (operator's phone). רמב״ם numbers a הלכה
   and has the same shape.
   MEASURED, not guessed: across 589 se'ifim in 67 simanim of אורח חיים the label is one character
   385 times and two characters 204 times, and NEVER three — the widest («יא», «כא») renders 13.6px
   against a 20px box. So 1.0 fits every real label with room to spare, where 1.75 was sized for a
   «chapter:verse» that this track cannot produce. */
#rbody[data-track="shulchan"], #rbody[data-track="rambam"] { --vn-gut:1.0; }
/* D-108 #4: ברסלב sub-heading — the part / section name at its own place inside the book's run
   («אכילה · חלק שני», «חלק א · תפילה ד׳»). Between the book title (gold, ruled) and a caption in
   weight: the reading serif in the accent colour, no rule, a little air above; none right under
   the title. */
.sub-h { font-family:var(--font-src); font-size:var(--fs-2); line-height:var(--lh-ui); color:var(--accent); font-weight:normal;
  margin:calc(var(--sec-gap) * .7) 0 calc(var(--s-4) * var(--dens)); }
.sec-h + .cap + .unit > .sub-h, .sec-h + .unit > .sub-h { margin-top:calc(var(--s-2) * var(--dens)); }
/* The verse NUMBER is the way into רש״י — a 44px "רש״י" chip under every verse was a whole extra
   row per verse (~24 rows on a chok page). The mark is one hairline under the number; the touch
   target is a pseudo-element, so the text rhythm is untouched. */
button.vn { position:relative; color:var(--gold); }
/* The number itself is ~18x25px. The hit area grows ASYMMETRICALLY: far into the first line's
   gutter, which is empty, and only ~4px toward the text, so tapping a word never opens רש״י. Measured
   39x45px — the gutter is what caps the width, and a wider target would have to steal from the
   verse. (The 44px chip this replaced cost an entire row per verse.) D-204: the gutter now exists on
   line 1 only, and line 2 runs under the number — the .62rem reach below stops short of line 2's
   glyphs (measured 1.6px into the line box, the same as before), so the target did not change. */
button.vn::before { content:""; position:absolute; inset:-.62rem -1.05rem -.62rem -.25rem; }
button.vn::after { content:""; position:absolute; inset-inline:.15em; bottom:.05em; height:1px;
  background:var(--gold); opacity:.6; }
button.vn[aria-expanded="true"]::after { opacity:1; height:2px; }
button.vn[aria-expanded="true"] { color:var(--accent); }
.chip { display:inline-flex; align-items:center; min-height:var(--tap); padding:0 calc(var(--s-16) * var(--dens)); border-radius:0;
  border:var(--rule-strong); color:var(--dim); font-size:var(--fs-floor); margin:var(--s-1) 0 calc(var(--s-4) * var(--dens)); background:var(--card); }
.chip[aria-expanded="true"] { background:var(--soft); color:var(--accent); border-color:var(--gold); }
.rashi { border-inline-start:3px solid var(--soft); padding:calc(var(--s-2) * var(--dens)) calc(var(--s-12) * var(--dens)); margin:calc(var(--s-2) * var(--dens)) 0 calc(var(--s-8) * var(--dens)); }
.rashi[hidden] { display:none; }
.attrib { font-size:var(--fs-floor); color:var(--dim); text-align:center; margin:calc(var(--s-24) * var(--dens)) 0 calc(var(--s-8) * var(--dens)); line-height:var(--lh-prose); }
.attrib bdi { unicode-bidi:isolate; }
.more-wrap { text-align:center; margin:calc(var(--s-16) * var(--dens)) 0; }
.err { text-align:center; color:var(--dim); padding:calc(var(--s-32) * var(--dens)) calc(var(--s-8) * var(--dens)); }
.err p { margin:calc(var(--s-6) * var(--dens)) 0; }
.btn { display:inline-flex; align-items:center; justify-content:center; min-height:var(--tap); padding:0 calc(var(--s-16) * var(--dens)); border-radius:0;
  border:var(--rule-strong); background:var(--card); color:var(--accent); font-size:var(--fs-floor); }
.btn:active { background:var(--soft); }
.btn.primary { background:var(--btn-bg); color:var(--btn-ink); border-color:var(--btn-bg); }

/* gemara */
.dafnav { display:flex; align-items:center; justify-content:space-between; gap:calc(var(--s-8) * var(--dens)); margin:calc(var(--s-6) * var(--dens)) 0 calc(var(--s-8) * var(--dens)); }
.dafnav .nav { min-height:var(--tap); min-width:var(--tap); padding:0 calc(var(--s-12) * var(--dens)); border-radius:0; border:var(--rule-strong);
  color:var(--accent); background:var(--card); font-size:var(--fs-floor); white-space:nowrap; }
.dafnav .nav:active { background:var(--soft); }
/* margin:0 — .seg is also the chok verse-block class (`.seg { margin:0 0 .7em }`), which pushed
   this pill ~5px above the ‹ / › buttons in the flex row */
.dafnav .seg { min-height:var(--tap); margin:0; padding:0 calc(var(--s-16) * var(--dens)); border-radius:0; border:var(--rule-strong);
  background:var(--card); color:var(--dim); font-size:var(--fs-floor); white-space:nowrap; }
.dafnav .seg[aria-pressed="true"] { color:var(--accent); background:var(--soft); border-color:var(--gold); }
/* The line number HANGS in the page gutter instead of holding a 44px column inside the measure.
   Measured on a 388px viewport at 20px: 40.6 -> ~45 characters per line, ~11% fewer lines per daf.
   The negative margin lets the number use the page padding; the text column is what grows. */
.glines { margin-inline-start:calc(-1 * var(--app-pad)); }
.gl { display:flex; align-items:flex-start; gap:calc(var(--s-2) * var(--dens)); margin:calc(var(--s-2) * var(--dens)) 0; scroll-margin-top:calc(var(--offbar-h, 0px) + env(safe-area-inset-top) + var(--rdtop-h, 3rem) + var(--findbar-h, 0px) + var(--lstrip-h, 0px) + 3.5rem)  /* CD-3 (D-91): was a 9rem literal — 3.5rem of prior-line context past the MEASURED chrome stack, so the D-60 landing keeps its context when the stack grows (offline bar, wrapped title) instead of silently eating it; equals the old 144px on a normal phone stack */;
  border-radius:0; transition:background 1.2s ease; }
.gl.resumed { background:var(--soft); }
.gl .gtxt { flex:1 1 auto; min-width:0; }
.ln { flex:none; width:1.4rem; min-height:1.5rem; display:inline-flex; align-items:flex-start; justify-content:center;
  padding-top:calc(var(--s-6) * var(--dens)); font-size:var(--fs-floor); color:var(--dim); border-radius:0; }
/* the 44px target is a pseudo-element: the gutter stays 1.4rem wide, the tap area does not */
button.ln { color:var(--gold); position:relative; }
button.ln::before { content:""; position:absolute; inset:-.35rem -.6rem -.7rem -.6rem; }
button.ln::after { content:""; position:absolute; inset-inline:.15rem; bottom:.15rem; height:1px;
  background:var(--gold); opacity:.55; }
button.ln:active { background:var(--soft); }
.ln.plain { border:none; background:none; color:var(--mute); }

/* ---- D-82: no line numbers anywhere in the daf ------------------------------------------------
   A printed daf carries none, and they are no longer load-bearing: a line with commentary is
   already marked by the has-cmt tint, a tap anywhere on such a line opens the sheet, and since
   D-71 a tap on an anchored WORD opens the comment that discusses it. The button stays in the DOM
   as the keyboard/screen-reader route to the sheet (it keeps its aria-label) but renders nothing.
   The gutter goes with them — `.glines`'s negative inline-start margin existed only to let the
   numerals hang outside the text column, and left as-is it would pull the text off-screen. */
.ln.plain { display:none; }
/* visually hidden, NOT display:none — the button is the keyboard and screen-reader route to the
   sheet, and display:none would take it out of the accessibility tree and out of tab order */
button.ln { display:inline-block; position:absolute; width:1px; height:1px; min-height:0;
            overflow:hidden; clip-path:inset(50%); padding:0; margin:0; border:0; }
button.ln:focus-visible { position:static; width:auto; height:auto; clip-path:none;
                          outline:2px solid var(--gold); }
.glines { margin-inline-start:0; }

/* ---- D-79: continuous daf, whenever a single text is shown ---------------------------------
   `.plain` covers the Aramaic-only states (וילנא is `plain vilna`); `.stzonly` is ביאור alone.
   The paired state has neither class and keeps the aligned block layout on purpose. */
.glines.plain, .glines.stzonly {
  margin-inline-start:0; text-align:justify; text-justify:inter-word;
}
.glines.plain .gl, .glines.stzonly .gl { display:inline; margin:0; }
/* the lines are joined with no whitespace between them, so without this the last word of one line
   and the first of the next run together into one token */
.glines.plain .gl::after, .glines.stzonly .gl::after { content:" "; }
.glines.plain .gtxt, .glines.stzonly .gtxt { display:inline; }
.glines.plain .ara.std { display:inline; margin:0; }
.glines.plain.vilna .ara.std { display:none; }
.glines.plain.vilna .ara.vil { display:inline; margin:0; }
.glines.stzonly .stz {
  display:inline; margin:0; padding:0; background:none; border:none;
  /* D-89: `inherit` resolved to the page chrome size, so the ביאור-בלבד layer read far smaller
     than every other layer — it is a READING surface and gets the reading size */
  font-size:var(--text-size); line-height:var(--lh-src); color:var(--ink);
}
/* a running daf does not carry a numeral on every line — only where there is something to open */
.glines.plain .ln.plain, .glines.stzonly .ln.plain { display:none; }
.glines.plain button.ln, .glines.stzonly button.ln {
  display:inline; width:auto; min-height:0; padding:0; border:none; background:none;
  font-size:.62em; vertical-align:.5em; margin-inline-end:.12em; color:var(--gold);
}
.glines.plain button.ln::after, .glines.stzonly button.ln::after { content:none; }
/* keep the tap target reachable without letting it swallow the neighbouring words */
.glines.plain button.ln::before, .glines.stzonly button.ln::before { inset:-.5rem -.25rem; }
/* the quota marker is a real break in the reading, so it stays a block and splits the flow */
.glines.plain .quota-mark, .glines.stzonly .quota-mark { display:block; }


/* bottom sheet */
.sheet-bg { position:fixed; inset:0; background:var(--scrim); z-index:var(--z-sheet); display:flex; align-items:flex-end; }
/* D-191: a sheet whose whole purpose is to be read against the page it covers cannot wash that
   page out. The note sheet marks words in the text above it, and at the full 44% scrim the mark
   was gone. Derived from the theme's own scrim, so every theme follows without a new value. */
.sheet-bg.soft { background:color-mix(in srgb, var(--scrim) 45%, transparent); }
.sheet { width:100%; max-width:720px; margin:0 auto; min-height:48vh; max-height:82vh; background:var(--card); color:var(--ink);
  border-radius:0; display:flex; flex-direction:column; box-shadow:0 -6px 30px var(--shadow);
  padding-bottom:env(safe-area-inset-bottom); }
.sheet::before { content:""; flex:none; width:2.25rem; height:.25rem; border-radius:0;
  background:var(--ctl); margin:calc(var(--s-8) * var(--dens)) auto calc(var(--s-2) * var(--dens)); }
.sheet-h { display:flex; align-items:center; justify-content:space-between; gap:calc(var(--s-8) * var(--dens)); padding:calc(var(--s-4) * var(--dens)) calc(var(--s-8) * var(--dens)) calc(var(--s-4) * var(--dens)) calc(var(--s-16) * var(--dens)); flex:none; }
.sheet-t { color:var(--dim); font-size:var(--fs-floor); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
.tabs { display:flex; gap:calc(var(--s-6) * var(--dens)); padding:calc(var(--s-4) * var(--dens)) calc(var(--s-16) * var(--dens)) calc(var(--s-6) * var(--dens)); border-bottom:var(--rule); flex:none; }
.tab { min-height:var(--tap); padding:0 calc(var(--s-16) * var(--dens)); border-radius:0; color:var(--dim); font-size:var(--fs-floor); border:1px solid transparent; }
.tab.on { color:var(--accent); background:var(--soft); border-color:var(--ctl); }
.pane { flex:1 1 auto; min-height:0; overflow-y:auto; padding:calc(var(--s-6) * var(--dens)) calc(var(--s-16) * var(--dens)) calc(var(--s-16) * var(--dens)); -webkit-overflow-scrolling:touch; }
.pane[hidden] { display:none; }

/* Done block — at the END of the text, not a fixed bar over it. It reclaimed ~80px of every
   screen, and "I finished" is a thing you say when you have actually reached the end. */
.donebar { margin:calc(var(--s-32) * var(--dens)) 0 calc(var(--s-8) * var(--dens)); padding:calc(var(--s-16) * var(--dens)) 0 calc(var(--s-4) * var(--dens)); border-top:var(--rule); }
.donebar .in { max-width:720px; margin:0 auto; display:flex; align-items:center; justify-content:center;
  gap:calc(var(--s-12) * var(--dens)); flex-wrap:wrap; }
.done-btn { flex:1 1 auto; max-width:17rem; min-height:48px; border-radius:0; background:var(--btn-bg); color:var(--btn-ink); font-size:var(--fs-2); }
.done-btn:active { opacity:.85; }
.done-btn:disabled { opacity:.55; cursor:default; }
.done-lbl { color:var(--ok); font-size:var(--fs-floor); display:inline-flex; align-items:center; min-height:var(--tap); }
.undo { min-height:var(--tap); padding:0 calc(var(--s-16) * var(--dens)); border-radius:0; border:var(--rule-strong); color:var(--dim); font-size:var(--fs-floor); }
.next-btn { flex:1 1 auto; max-width:16rem; min-height:var(--tap); padding:0 calc(var(--s-16) * var(--dens)); border-radius:0;
  border:var(--rule-strong); background:var(--card); color:var(--accent); font-size:var(--fs-floor); }
.next-btn:active { background:var(--soft); }

/* ---------- picker + settings forms ---------- */
.form { display:grid; gap:calc(var(--s-6) * var(--dens)); padding:calc(var(--s-4) * var(--dens)) 0 calc(var(--s-12) * var(--dens)); }
/* D-51: reading rate + minutes as ONE table, a row per track */
.ftab { width:100%; border-collapse:collapse; background:var(--card); border:var(--rule); border-radius:0; overflow:hidden; }
.ftab th, .ftab td { padding:calc(var(--s-4) * var(--dens)) calc(var(--s-8) * var(--dens)); text-align:center; font-weight:normal; }
.ftab thead th { font-size:var(--fs-floor); color:var(--dim); padding-top:calc(var(--s-6) * var(--dens)); }
.ftab tbody th { text-align:start; font-size:var(--fs-floor); color:var(--ink); }
.ftab tbody tr + tr { border-top:var(--rule); }
.ftab input[type=number] { width:4.6rem; min-height:38px; }
/* a four-way control (גמרא: עם ביאור · טקסט בלבד · וילנא · ביאור בלבד) is wider than a 66% slot on a
   phone: let it take the room and WRAP rather than spill past the card edge */
.frow .segbar { flex:1 1 auto; min-width:0; max-width:78%; flex-wrap:wrap; }
.frow .segbar button { flex:1 1 auto; min-height:34px; font-size:var(--fs-floor); padding:0 calc(var(--s-4) * var(--dens)); white-space:nowrap; }
.fg { border:0; padding:0; margin:0; display:contents; }
.frow { display:flex; align-items:center; justify-content:space-between; gap:calc(var(--s-12) * var(--dens)); min-height:var(--tap);
  background:var(--card); border:var(--rule); border-radius:0; padding:calc(var(--s-4) * var(--dens)) calc(var(--s-12) * var(--dens)); }
.frow .k { color:var(--ink); font-size:var(--fs-floor); }
.frow .k small { display:inline; margin-inline-start:calc(var(--s-6) * var(--dens)); color:var(--dim); font-size:var(--fs-floor); }   /* value beside the label, not under it */
.frow input[type=number], .frow input[type=text] { font:inherit; color:var(--ink); background:var(--bg); border:var(--rule-strong);
  border-radius:0; padding:calc(var(--s-6) * var(--dens)) calc(var(--s-8) * var(--dens)); min-height:var(--tap); width:6.5rem; text-align:center; }
.frow input[type=text] { width:min(66%, 18rem); text-align:start; min-height:38px; }
.frow input[type=range] { flex:1 1 auto; max-width:60%; accent-color:var(--gold); height:var(--tap); }
.frow select { font:inherit; color:var(--ink); background:var(--bg); border:var(--rule-strong); border-radius:0; padding:calc(var(--s-6) * var(--dens)) calc(var(--s-8) * var(--dens)); min-height:var(--tap); }
.frow.col { flex-direction:column; align-items:stretch; }
.frow.col input[type=text] { width:100%; }
.fh { font-size:var(--fs-floor); color:var(--gold); margin:calc(var(--s-8) * var(--dens)) 0 0; }
.actions { display:flex; justify-content:center; padding:calc(var(--s-8) * var(--dens)) 0; }
.ver { text-align:center; color:var(--dim); font-size:var(--fs-floor); margin:calc(var(--s-16) * var(--dens)) 0 calc(var(--s-8) * var(--dens)); line-height:var(--lh-prose); }
.ver .btn { margin-inline-start:calc(var(--s-8) * var(--dens)); font-size:var(--fs-floor); min-height:var(--tap); }

/* ---------- D-255: the identity pages — the install gate (the landing page), the who-screen and
   its modes. One head on every page (icon · name · one line); then ONE thing asked. The gate's
   install button sits in the middle of the screen, the sample day under it; the who-pages flow
   top-down with the button right under the fields (no auto-margins — rule 19). The CTA is the
   accent on the paper in every theme: dark's --btn-bg is a quiet grey, wrong for the one action. */
.idp { display:flex; flex-direction:column; max-width:26rem; width:100%; box-sizing:border-box; margin:0 auto;
  padding:calc(var(--s-12) * var(--dens)) calc(var(--s-16) * var(--dens)) calc(var(--s-24) * var(--dens) + env(safe-area-inset-bottom)); }
.gbsd { font-family:var(--font-src); font-size:var(--fs-floor); line-height:var(--lh-ui); color:var(--faint); }
.idhead { display:flex; flex-direction:column; align-items:center; gap:calc(var(--s-8) * var(--dens)); text-align:center; }
.gate .idhead { padding-top:calc(var(--s-24) * var(--dens)); }
.idicon { display:block; width:76px; height:76px; }
.idname { margin:0; font-family:var(--font-src); font-weight:normal; font-size:var(--fs-5); line-height:var(--lh-tight); color:var(--accent); }
.idsub { margin:0; font-size:var(--fs-2); line-height:var(--lh-prose); color:var(--dim); }
.gate .idsub { color:var(--ink); }
.idlead { margin:calc(var(--s-24) * var(--dens)) 0 0; font-size:var(--fs-2); line-height:var(--lh-prose); color:var(--ink); text-align:center; }
.idcap { margin:0; font-size:var(--fs-floor); line-height:var(--lh-prose); color:var(--dim); }
.gate .idcap { text-align:center; }
.gact { display:flex; flex-direction:column; gap:calc(var(--s-8) * var(--dens)); margin-top:calc(var(--s-32) * var(--dens)); }
.idp .linkish { color:var(--accent); }
.gact .linkish { align-self:center; color:var(--dim); }
.idcta { width:100%; min-height:calc(var(--tap) + var(--s-8)); gap:calc(var(--s-12) * var(--dens));
  background:var(--accent); color:var(--bg); border-color:var(--accent); font-size:var(--fs-2); }
.idcta.big { min-height:calc(var(--tap) + var(--s-24)); font-size:var(--fs-3); }
.idcta:active { background:var(--accent); opacity:.85; }
.idcta:disabled { opacity:.6; }
.idsec { width:100%; min-height:calc(var(--tap) + var(--s-8)); border-color:var(--accent); font-size:var(--fs-2); }
.idico { width:24px; height:24px; flex:none; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.gbox { margin:0; padding:calc(var(--s-16) * var(--dens)); background:var(--soft); border:1px solid var(--frame);
  font-size:var(--fs-2); line-height:var(--lh-prose); color:var(--ink); }
.gbox p { margin:0; }
.gbox .gbox-t { color:var(--accent); }
.gsample { margin-top:calc(var(--s-48) * var(--dens)); padding:calc(var(--s-12) * var(--dens)) calc(var(--s-16) * var(--dens)) 0;
  background:var(--card); border:1px solid var(--frame); }
.gs-h { display:flex; justify-content:space-between; align-items:baseline; margin:0; padding-bottom:calc(var(--s-8) * var(--dens));
  border-bottom:var(--rule); font-family:var(--font-src); font-size:var(--fs-2); line-height:var(--lh-tight); color:var(--accent); }
.gs-ex { font-family:var(--font-ui); font-size:var(--fs-floor); color:var(--dim); }
.gs-row { display:flex; align-items:center; gap:calc(var(--s-12) * var(--dens)); margin:0; min-height:calc(var(--tap) + var(--s-8)); border-bottom:var(--rule); }
.gs-row:last-child { border-bottom:0; }
.gs-t { flex:1 1 auto; min-width:0; display:flex; flex-direction:column; }
.gs-t b { font-family:var(--font-src); font-weight:700; font-size:var(--fs-2); line-height:var(--lh-tight); color:var(--accent); }
.gs-t span { font-size:var(--fs-floor); line-height:var(--lh-ui); color:var(--dim); }
.gsmark { width:24px; height:24px; flex:none; fill:none; stroke:var(--ring); stroke-width:1.3; }
.gsmark .d { fill:var(--okdone); stroke:var(--ok); }
.gsmark path { stroke:var(--ok); stroke-width:1.9; stroke-linecap:round; stroke-linejoin:round; }
.gver { margin-top:calc(var(--s-16) * var(--dens)); }
.gsheet { position:fixed; inset:0; z-index:var(--z-sheet); background:var(--scrim); display:flex; flex-direction:column; justify-content:flex-end; }
.gsheet[hidden], .gclosed[hidden], .gact .linkish[hidden] { display:none; }
.gsheet-in { max-width:26rem; width:100%; box-sizing:border-box; margin:0 auto; background:var(--bg); border-top:1px solid var(--frame);
  padding:calc(var(--s-24) * var(--dens)) calc(var(--s-24) * var(--dens)) calc(var(--s-24) * var(--dens) + env(safe-area-inset-bottom)); }
.gsheet-in h2 { margin:0 0 calc(var(--s-8) * var(--dens)); font-family:var(--font-src); font-weight:normal; font-size:var(--fs-4); line-height:var(--lh-tight); color:var(--accent); }
.gsheet-in ol { list-style:none; margin:0 0 calc(var(--s-16) * var(--dens)); padding:0; }
.gsheet-in li { display:flex; align-items:center; gap:calc(var(--s-12) * var(--dens)); min-height:calc(var(--tap) + var(--s-12)); border-bottom:var(--rule);
  font-size:var(--fs-2); line-height:var(--lh-ui); color:var(--ink); }
.gsheet-in li:last-child { border-bottom:0; }
.gsheet-in li > span:nth-child(2) { flex:1 1 auto; }
.gsheet-in .gn { flex:none; width:28px; text-align:center; color:var(--gold); }
.gsheet-in .idico { color:var(--accent); }
.gsheet-in img { flex:none; width:28px; height:28px; }
.who2 { flex:1 1 auto; }
.idh { margin:calc(var(--s-24) * var(--dens)) 0 0; padding-top:calc(var(--s-16) * var(--dens)); border-top:var(--rule);
  font-family:var(--font-src); font-weight:normal; font-size:var(--fs-4); line-height:var(--lh-tight); color:var(--accent); }
.who2 .wnote, .who2 .idlede { margin-top:calc(var(--s-8) * var(--dens)); color:var(--ink); }
.idform { display:flex; flex-direction:column; gap:calc(var(--s-12) * var(--dens)); margin-top:calc(var(--s-16) * var(--dens)); }
.idform .idcap { color:var(--dim); }
.ifield { display:flex; flex-direction:column; gap:calc(var(--s-6) * var(--dens)); }
.ifield > span:first-child, .ifield > label { font-size:var(--fs-floor); line-height:var(--lh-ui); color:var(--dim); }
.ifield input { width:100%; min-height:calc(var(--tap) + var(--s-6)); box-sizing:border-box; padding:0 calc(var(--s-12) * var(--dens));
  background:var(--card); border:1px solid var(--frame); border-radius:0; font:inherit; font-size:var(--fs-2); color:var(--ink); }
.ifield input[dir="ltr"] { text-align:right; }
.ifield input:focus { outline:none; border-color:var(--gold); box-shadow:0 0 0 1px var(--gold); }
.ifield input.icode { text-align:center; font-family:var(--font-mono); letter-spacing:.2em; }
.ihint { font-size:var(--fs-floor); line-height:var(--lh-ui); color:var(--dim); }
.ipin { display:flex; }
.ipin input { flex:1 1 auto; min-width:0; letter-spacing:.2em; }
.ieye { flex:none; width:calc(var(--tap) + var(--s-6)); display:flex; align-items:center; justify-content:center;
  background:var(--card); border:1px solid var(--frame); border-inline-start:0; color:var(--dim); }
.ieye[aria-pressed="true"] { color:var(--accent); }
.idforgot { align-self:flex-start; }
.who2 .werr { margin:0; padding:0; min-height:1.6em; font-size:var(--fs-floor); line-height:var(--lh-prose); color:var(--ink); }
.idlinks { display:flex; justify-content:center; flex-wrap:wrap; gap:0 calc(var(--s-16) * var(--dens)); margin:calc(var(--s-8) * var(--dens)) 0 0; }
.idlinks .linkish, .idlinks .idcap { display:inline-flex; align-items:center; min-height:var(--tap); }
.linkish { color:var(--dim); font-size:var(--fs-floor); text-decoration:underline; min-height:var(--tap); padding:0 calc(var(--s-8) * var(--dens)); }
/* in the picker the BOOK NAME is the headline — the home cards' kicker/headline inversion
   (track name small, today's portion large) would bury it */
.bk .ttl { font-size:var(--fs-2); color:var(--accent); }
.bk .sub { direction:rtl; font-size:var(--fs-floor); }
.amud { display:flex; gap:calc(var(--s-6) * var(--dens)); }
.amud .tab { min-width:var(--tap); }        /* "א"/"ב" are one glyph wide; keep the target square */

@media (prefers-reduced-motion: reduce) {
  .toast { transition:none; }
  .gl { transition:none; }
  .chk:active, .card-main:active, .back:active { transform:none; }
}
@media (prefers-contrast: more) {
  :root { --dim:#4a4943; --gold:#6f5928; --line:#9a958a; --ctl:#5d5a51; }
  :focus-visible { outline-width:4px; }
}
/* Per-element measure, UNCONDITIONAL. The old rule only applied over 700px and set 32em = 76
   characters per line — nearly double the 40-50 that Hebrew reads best at. 21em is ~50 cpl at any
   size, and because each layer resolves em against ITS OWN font-size, they all clamp to the same
   character count rather than the same pixels. On a phone this never binds; on a desktop it does. */
.src, .ara, .onk, .stz, .cmt, .rashi p, .intro { max-inline-size:21em; }
@media print {
  :root, :root[data-theme] { --bg:#fff; --card:#fff; --ink:#000; --dim:#444; --mute:#444; --accent:#000;
    --gold:#333; --soft:#fff; --line:#999; --ctl:#999; --stz:#222; --stz-bg:#fff; --hasc:#000; --sheva:#000; color-scheme:light; }
  .rd-top, .donebar, .toast, .offbar, .dafnav, .chk, .chip, .home-tools, .rail, .hint, .more-wrap,
  .attrib a, .rdprog, .nightveil, .findbar { display:none !important; }
  .rashi[hidden] { display:block !important; }
  .body { padding:0; } #app { max-width:none; padding:0; }
  .glines { margin-inline-start:0; }
  .src, .ara { font-size:var(--fs-floor); line-height:var(--lh-prose); max-inline-size:none; }
  .onk, .stz, .cmt, .rashi p, .intro { max-inline-size:none; }
  .sec, .item, .unit { break-inside:avoid; }
}

/* ================= D-65 step 4: the reader bodies (printed-sefer) =================
   The artboards' absolute px are authored at --text-size:20px, so BODY text is expressed as
   RATIOS of the size dial (source 20 = 1.0 · טור 19 = .95 · בית יוסף 17.5 = .875 · תרגום/ביאור
   16.5 = .825 · the verse gutter 35px = 1.75, which the app already used · קיצור's 32px = 1.6).
   Chrome (strips, legends, labels) stays fixed px like the rest of the UI, so it does not grow
   with the reading size. Appended at the END of the file on purpose: these rules retire the
   rounded/tinted forms defined above (.rashi rail, .stz block, .rchip pills). */
.lstrip { display:flex; border-bottom:var(--rule); background:var(--bg); }
#lstrip, .body > .tblock:first-child { margin:calc(-1 * var(--s-12) * var(--dens)) calc(-1 * var(--s-8) * var(--dens)) calc(var(--s-12) * var(--dens)); }
/* D-191: the -11px above pulls the strip flush under the sticky head, which is right only when the
   strip IS the first thing in the body. With a portion label before it (`.pt-lbl`, «רביעי …») the
   strip's opaque background and z-index 19 painted over the label's lower half and left it
   unreadable on the operator's phone. */
.pt-lbl + #lstrip { margin-top:calc(var(--s-6) * var(--dens)); }
/* The strip belongs to the page's chrome, not to its text: it sticks under the head band.
   D-87 (operator, 2026-09-01, amending the 2026-08-31 headroom rule): the strip is PERMANENT —
   when the band hides on a down-scroll the strip slides up into the band's place and stays
   usable; only the title band follows the headroom rule. The find bar rides along under it. */
#lstrip { position:sticky; z-index:var(--z-strip);
  top:calc(var(--offbar-h, 0px) + env(safe-area-inset-top) + var(--rdtop-h, 3rem) + var(--findbar-h, 0px));   /* D-164 (CUI-03): under the open find bar */
  transition:transform .22s ease; }
body.chrome-off #lstrip { transform:translateY(calc(-1 * var(--rdtop-h, 3rem))); }
/* D-106 #1: the INNER strips — the zohar's זוהר/תרגום tabs (D-85) and chok's gemara layer tabs
   (D-84) — stick right under the section strip while their own section scrolls. Sticky is bounded
   by the containing block (the .sec / the gemara .item), so each rides only its section and
   scrolls away when the next one begins; same headroom slide as #lstrip. Below the open find bar
   by its measured height (D-164, CUI-03), like every strip that stacks past --lstrip-h. */
.sec .lstrip:not(#lstrip) { position:sticky; z-index:var(--z-strip-inner);
  top:calc(var(--offbar-h, 0px) + env(safe-area-inset-top) + var(--rdtop-h, 3rem) + var(--findbar-h, 0px) + var(--lstrip-h, 0px));
  transition:transform .22s ease; }
body.chrome-off .sec .lstrip:not(#lstrip) { transform:translateY(calc(-1 * var(--rdtop-h, 3rem))); }
.lstrip .cell { flex:1 1 0; min-width:0; min-height:var(--tap); display:inline-flex; align-items:center; justify-content:center;
  padding:calc(var(--s-4) * var(--dens)) var(--s-2); font-size:var(--fs-floor); line-height:var(--lh-tight); color:var(--dim); background:none;
  border:0; border-inline-end:var(--rule); border-radius:0; }
.lstrip .cell:last-child { border-inline-end:0; }
.lstrip .cell.on { background:var(--soft); color:var(--accent); }
.lstrip .cell.off { color:var(--mute); }       /* a ברסלב book that ended — still reachable. D-221 (§30b-9): --mute, not --ctl — a live jump target is running text, and --ctl measured 2.04:1 on sepia's --bg (--mute: 5.24 sepia · 5.20 light · 6.36 dark) */
.lstrip .cell:active { background:var(--soft); }
.lstrip.wide .cell { font-size:var(--fs-floor); padding-inline:var(--s-1); }          /* חק: eight (Friday: nine) cells */
/* D-203: at 16px «כתובים» (42px) no longer fits an equal ninth of a 384px strip (40px), so חק's
   strip sizes its cells to their labels exactly as D-158's תיקון one-row strip does: «תורה» and
   «זוהר» hand their spare width to «נביאים» and «כתובים», nothing clipped at 384. At 320 nine labels
   need more than the row holds — they were already clipped there at 14.4px (measured, D-203). */
.lstrip.wide:not(.tk) .cell { flex:1 1 auto; }
/* D-157: a strip with more cells than a row can carry WRAPS into equal rows (`--cols` per row, set by
   the renderer; the תיקון with every piece on is 22 cells). Cells keep one width across the rows so
   the columns align; each cell carries the rule below it, and the strip's own bottom rule steps
   aside so the last row is not doubled. */
.lstrip.rows { flex-wrap:wrap; border-bottom:0; }
/* `1 1`, not `0 0`: a short last row stretches its cells to the edge (a keyboard's last row), so no
   blank corner sits under the strip with nothing ruling it off from the text */
.lstrip.rows .cell { flex:1 1 calc(100% / var(--cols, 8)); border-bottom:var(--rule); border-inline-end:var(--rule); }
.lstrip.rows .cell:nth-child(n) { border-inline-end:var(--rule); }   /* the last cell too: the grid keeps its rule */
/* D-85: the zohar/translation tabs — one pane in the DOM per text, the section's class picks one */
.sec.ztab-ara .zpane.z-trans, .sec.ztab-trans .zpane.z-ara { display:none; }
/* D-178: the same, for חק's משנה — but ADDITIVE, not exclusive: the mishnah itself is always on the
   page and the tab picks which perush, if any, sits under it. «משנה» is the first cell and hides
   both. The box keeps `.lbox`'s look and deliberately not its `ly-` name (POS_BLOCKS). */
.sec.mtab-none .cbox, .sec.mtab-bartenura .cbox.mc-rambam, .sec.mtab-rambam .cbox.mc-bartenura { display:none; }
/* D-123: the same idiom on a בית יוסף box — «מקור» / «תרגום» — the BOX's class picks the pane. The strip
   sticks inside its box like the zohar's inside its section (same headroom slide); the box is the
   containing block, so it rides only its own text. Pulled to the box's edges so the tabs read as the
   box's own rule, and the legend keeps its notch above it. The rendering pane is pointed text, so it
   sets at the source line-height, one step down in size like the ביאור (the .825 of the dial). */
/* D-168: the negative top margin pulls the strip over the box's own top padding, so it must scale by
   the SAME factor the padding does, or the strip drifts off the box edge as צפיפות moves. */
.lbox .bystrip { position:sticky; z-index:var(--z-strip-inner); margin:calc(-1 * var(--s-4) * var(--dens)) calc(-1 * var(--s-8) * var(--dens)) calc(var(--s-8) * var(--dens));
  top:calc(var(--offbar-h, 0px) + env(safe-area-inset-top) + var(--rdtop-h, 3rem) + var(--findbar-h, 0px) + var(--lstrip-h, 0px));   /* D-164 (CUI-03) */
  transition:transform .22s ease; }
body.chrome-off .lbox .bystrip { transform:translateY(calc(-1 * var(--rdtop-h, 3rem))); }
.bypane { display:none; }
.lbox.bytab-src .bypane.by-src, .lbox.bytab-trans .bypane.by-trans, .lbox.bytab-mix .bypane.by-mix { display:block; }
.bypane > p { margin:0; }
.bypane > p + p { margin-top:calc(var(--seg-gap) * .8); }
.lbox .src.by-tr { font-size:var(--fs-cmt); }
/* PILOT — «משולב»: a row or two of the source, the rendering of exactly those words under it. The
   treatment is the גמרא's ביאור (`.stz`) rather than חק's quieter `.onk`, because here BOTH sides
   are Hebrew and the tinted band with its start rule is what tells the eye where the source
   resumes. The rendering keeps the .875 size the «תרגום» tab already gives it. */
.by-mx-p + .by-mx-p { margin-top:var(--seg-gap); }
.lbox .src.by-mx-s { margin:0; }
.lbox .src.by-mx-t + .src.by-mx-s { margin-top:calc(var(--seg-gap) * .75); }
.lbox .src.by-mx-t { color:var(--stz); background:var(--stz-bg); line-height:var(--lh-stz);
  border-inline-start:3px solid var(--ctl);
  border-start-start-radius:0; border-end-start-radius:0;
  border-start-end-radius:0; border-end-end-radius:0;
  padding-block:calc(var(--s-6) * var(--dens)) calc(var(--s-8) * var(--dens)); padding-inline:calc(var(--s-12) * var(--dens)) calc(var(--s-4) * var(--dens));
  margin:calc(var(--s-6) * var(--dens)) 0 0; }
.lstrip .step { flex:0 0 46px; font-family:var(--font-src); font-size:var(--fs-floor); color:var(--gold); }
.lstrip.foot-nav { border-top:var(--rule); border-bottom:0; margin-top:calc(var(--s-12) * var(--dens)); }
.lstrip.foot-nav .step { flex:1 1 0; }
/* D-222 (§32 item 1): the sefer reader's commentary strip — a second, NON-sticky strip under the
   jump strip (`#lstrip` stays the one sticky, measured strip). Cells size to their names and wrap
   onto a second row rather than clip at 384px (או״ח with באר היטב and שערי תשובה is five names);
   the ✓ mark is the Aa panel's own `.pmark`, so «on» reads the same in both places — and NOT the
   `.on` fill, which on the strip above means «the siman you are in». */
.lstrip.lystrip { flex-wrap:wrap; margin:0 calc(-1 * var(--s-8) * var(--dens)) calc(var(--s-12) * var(--dens)); }
.body > .lstrip.lystrip:first-child { margin-top:calc(-1 * var(--s-12) * var(--dens)); }
.pt-lbl + .lstrip.lystrip { margin-top:calc(var(--s-6) * var(--dens)); }
#lstrip + .lstrip.lystrip { margin-top:calc(-1 * var(--s-12) * var(--dens)); }
.lstrip.lystrip .cell { flex:1 1 auto; gap:calc(var(--s-6) * var(--dens)); padding-inline:var(--s-4); }
.lstrip.lystrip .cell[aria-pressed="true"] { color:var(--ink); }
.lstrip.lystrip .pmark { width:16px; height:16px; }
/* D-222 (§32 item 3): the cell of the siman you are in carries a small fold mark on a seif_nav strip —
   its tap opens that siman's seifim (the picker fold's chevron, drawn from borders) */
#lstrip.sfnav .cell.on, #lstrip.sfnav .cell[aria-expanded="true"] { position:relative; }
#lstrip.sfnav .cell.on::after, #lstrip.sfnav .cell[aria-expanded="true"]::after { content:""; position:absolute; inset-inline-end:6px; top:50%;
  width:5px; height:5px; border:solid var(--ctl); border-width:0 0 1.5px 1.5px; transform:translateY(-70%) rotate(-45deg); }
#lstrip.sfnav .cell[aria-expanded="true"]::after { transform:translateY(-30%) rotate(135deg); }
#lstrip.sfopen { flex-wrap:wrap; }
#lstrip .sfrow { flex:1 0 100%; display:flex; flex-wrap:wrap; border-top:var(--rule); }
#lstrip .sfrow .cell { flex:0 0 calc(100% / 8); border-bottom:var(--rule); }
#lstrip .sfrow .cell:nth-child(8n) { border-inline-end:0; }

/* D-168: the box's own breathing is BLOCK spacing, so it rides צפיפות like every other gap. It was
   fixed px from D-63 on, which is why the dial did nothing at all on a בית יוסף page (0.0%). */
.lbox { position:relative; border:var(--rule); border-radius:0;
  padding:calc(var(--s-12) * var(--dens)) calc(var(--s-8) * var(--dens)) calc(var(--s-8) * var(--dens)); margin:0 0 calc(var(--s-12) * var(--dens)); }
/* D-150: the משנה commentaries. ברטנורא is vocalised and reads as a companion to the mishnah, so it
   keeps the reading face at a step down; רמב״ם's is unpointed prose and takes the quieter treatment
   already used for a gloss. Each box is `lbox ly-<layer>`, which is what puts it in POS_BLOCKS — the
   selector's guard is the ` ly-` in the class list — so a layer switched off cannot lose the place. */
#rbody[data-track="mishna"] .lbox { margin:calc(var(--s-6) * var(--dens)) 0 calc(var(--s-12) * var(--dens)); }
/* D-241 (operator: «investigate, cause it is very tiny on my screen, weird»): these two rules were
   scoped to `#rbody[data-track="mishna"]` and named only the SIZE, so (a) the face fell through to
   the UI's Frank Ruhl on the משנה track itself — never the reading face the note above promises —
   and (b) the same boxes on every other reader matched nothing at all: חק's «ברטנורא» tab
   (`.cbox.mc-*`, D-178) and דף היומי's קינים/מדות rendered at the bare 16 px UI floor, in the UI
   face, at line-height normal. Measured on the mock at the operator's text size 25: the mishnah 25 px
   TaameyD, ברטנורא on the משנה track 22.5 px Frank Ruhl, ברטנורא in חק 16 px Frank Ruhl. Now the rule
   is keyed on the BOX, wherever it is drawn, and sets the face as well as the size. */
.lbox.ly-bartenura .src, .lbox.ly-bartenura p, .cbox.mc-bartenura p {
  font-family:var(--font-src); font-size:var(--fs-cmt); line-height:var(--lh-src); }
.lbox.ly-rambam p, .cbox.mc-rambam p { font-family:var(--font-src); font-size:var(--fs-cmt);
  line-height:var(--lh-unpointed); color:var(--stz); }
#rbody[data-track="mishna"] .item { margin-bottom:calc(var(--s-16) * var(--dens)); }
.lbox > .lg { position:absolute; top:-8px; inset-inline-start:10px; background:var(--bg); padding:0 calc(var(--s-4) * var(--dens));
  font-family:var(--font-src); font-size:var(--fs-floor); line-height:var(--lh-flat); color:var(--gold); }
.lbox.heavy { border-color:var(--ctl); background:var(--card); }
.lbox > p { margin:0; }
.lbox > p + p { margin-top:calc(var(--seg-gap) * .8); }
/* בית יוסף: טור/שולחן ערוך are source-sized, the בית יוסף body a step down, its dibur hamatchil gold */
.lbox .src { font-size:var(--text-size); }
/* D-67: טור and בית יוסף read at the SAME weight (operator). The בית יוסף used to be stepped down
   to .875 and --onk, the commentary treatment of #6b — right when a siman was one Tur box above one
   commentary box, wrong once they alternate down the page and the בית יוסף is 85% of the reading.
   The legend on each box, and the שולחן ערוך's heavy frame, carry the distinction now. */

.tblock { text-align:center; padding:calc(var(--s-8) * var(--dens)) calc(var(--s-8) * var(--dens)) calc(var(--s-6) * var(--dens)); border-bottom:var(--rule); }
.tblock .t { font-family:var(--font-src); font-size:var(--fs-3); color:var(--accent); line-height:var(--lh-tight); }
.tblock .s { font-size:var(--fs-floor); color:var(--dim); margin-top:calc(var(--s-2) * var(--dens)); }
/* D-248: the same block where a קיצור portion enters a new סימן mid-page — the seif above already
   leaves its s-12 gap, this adds one more so the break reads, and keeps the head block's gap below */
.tblock.k-siman { margin:calc(var(--s-12) * var(--dens)) 0 calc(var(--s-12) * var(--dens)); }
/* קיצור: the seif numeral hangs in a 1.6em gutter, exactly like a verse number */
.k-seif { font-size:var(--text-size); margin:0 0 calc(var(--s-12) * var(--dens)); }   /* D-168: the seif gap is the קיצור's only block gap */
.k-seif.has-vn { text-indent:0; padding-inline-start:0; }   /* D-204: gutter on line 1 only */
.k-seif .vn { width:calc(1.6 * var(--text-size)); }

/* the artboard's 9.5px תרגום/ביאור label breaks the UI floor (12px then, --fs-floor since D-107) and colours text with --ctl (a rule
   colour) — kept as a label at the floor, in --dim */
.ilbl { font-size:var(--fs-floor); letter-spacing:.06em; color:var(--dim); margin-inline-end:.35em; white-space:nowrap; }
.onk { font-size:var(--fs-cmt); }
/* חק: the לשם יחוד intro is centred over a light rule */
.sec .intro { font-family:var(--font-src); font-size:var(--fs-cmt);
  color:var(--dim); text-align:center; padding-inline-start:0;
  padding-bottom:calc(var(--s-8) * var(--dens)); margin:0 0 calc(var(--s-8) * var(--dens));
  border-bottom:var(--rule); }
/* רש״י under a verse: a legend box indented from the start edge (the tinted rail is retired) */
.item .rashi.lbox { border:var(--rule); border-radius:0;
  padding:calc(var(--s-12) * var(--dens)) calc(var(--s-8) * var(--dens)) calc(var(--s-8) * var(--dens));
  margin:calc(var(--s-8) * var(--dens)) 0 calc(var(--s-12) * var(--dens)); margin-inline-start:calc(var(--s-16) * var(--dens)); }
/* גמרא: the ביאור is a labelled paragraph under the line, not a tinted block */
.stz { background:none; border-inline-start:0; border-radius:0; padding-inline:0;
  font-size:var(--fs-cmt); }
.glines.stzonly .stz { margin-block:calc(var(--s-2) * var(--dens)) calc(var(--s-8) * var(--dens)); }
/* the daf's line number sits in a ruled margin that runs the FULL height of its line block
   (the artboard's margin column stretches; a flex-start row left the rule a stub), and the numeral
   is Hebrew like everywhere else in the app — the home row already says «סימנייה בשורה ג׳» */
.gl { gap:calc(var(--s-6) * var(--dens)); align-items:stretch; }
.gl .ln { width:24px; align-self:stretch; align-items:flex-start; border-inline-end:var(--rule);
  border-radius:0; font-size:var(--fs-floor); color:var(--gold); }
.gl .ln.plain { color:var(--dim); }
/* no border-radius anywhere in this direction: the remaining rounded chrome (תיקון's psalm rail,
   the commentary sheet's tabs) is squared to match */
.rchip, .tab { border-radius:0; }

/* ================= step 5: settings · Aa panel · picker inherit the frame =================
   They get the page frame with no other change (the handoff's own words), and the last rounded
   chrome in the app is squared so every screen reads as the same printed page. Two deliberate
   exceptions stay round: the home MARK (operator's choice) and the switch knob — a switch that is
   not a switch shape is a worse control, not a more consistent one. */
.btn, .iconBtn, .dbtn, .back, .pill, .chip, .menu, .mrow, .segbar button, .findbar, .findbar .fbtn,
.frow, .frow input, .frow select, .ftab, .gate-manual, .sheet, .tab, .card, .seg, .unit, .swrow, select,
.done-btn, .undo, .next-btn, mark.hit { border-radius:0; }
.menu { border-color:var(--ctl); box-shadow:0 6px 22px var(--shadow); }
/* native checkboxes were the one bit of system blue on the paper */
input[type="checkbox"], input[type="radio"] { accent-color:var(--accent); }
input[type="range"] { accent-color:var(--accent); }

/* ================= settings & Aa handoff — step 1: the three shared patterns =================
   Both screens are assembled from these; step 1 applies only the DIAL, to the Aa panel's three
   dials. The strip and the mark are defined here so steps 2–4 have them, and because they are the
   same objects the readers already use (the strip is the layer strip, the mark is the ledger's).
   Appended at the end so they retire the rounded .mrow/.segbar/.sw forms defined above. */

/* 1. one-line dial — label · 44px range · value. Replaces every label-above-slider stack. */
.dial { display:flex; align-items:center; gap:calc(var(--s-8) * var(--dens)); width:100%; margin:calc(-1 * var(--s-2) * var(--dens)) 0; padding:0 calc(var(--s-12) * var(--dens)); min-height:var(--tap); }
.dial .k { flex:none; font-size:var(--fs-floor); color:var(--ink); }
.dial input[type="range"] { flex:1 1 auto; min-width:0; height:var(--tap); accent-color:var(--gold); }
.dial output { flex:none; min-width:4ch; text-align:end; font-family:var(--font-src);
  font-size:var(--fs-floor); color:var(--gold); }
.dial + .dial { border-top:var(--rule); }

/* 2. ruled strip — the reader's layer strip, bounded: for ערכה / בהירות לילה / תצוגת הדף (step 2+) */
.rstrip { display:flex; border:var(--rule-strong); }
.rstrip button { flex:1 1 0; min-width:0; min-height:var(--tap); display:inline-flex; align-items:center;
  justify-content:center; padding:0 calc(var(--s-2) * var(--dens)); font-size:var(--fs-floor); line-height:var(--lh-tight); color:var(--dim);
  background:none; border:0; border-inline-end:var(--rule); border-radius:0; white-space:nowrap; }
.rstrip button:last-child { border-inline-end:0; }
.rstrip button[aria-pressed="true"] { background:var(--soft); color:var(--accent); }
.rstrip button:active { background:var(--soft); }
.rstrip.sm button { font-size:var(--fs-floor); }

/* 3. printed mark — the ledger's square, as the switch (step 2+). The ✓ is a pseudo-element so the
   existing .swrow markup and its aria-pressed semantics do not change. */
.pmark { flex:none; width:20px; height:20px; border:var(--rule-strong); border-radius:0;
  display:inline-flex; align-items:center; justify-content:center; font-size:var(--fs-fine); line-height:var(--lh-flat); color:var(--ok); }
.pmark::after { content:"✓"; opacity:0; }
[aria-pressed="true"] .pmark { border-color:var(--ok); }
[aria-pressed="true"] .pmark::after { opacity:1; }

/* ---- settings & Aa handoff, step 2: the rest of the Aa panel (#7c/#7d) ---- */
.menu { width:min(322px, 92vw); padding:0; border-color:var(--ctl); background:var(--bg);
  box-shadow:0 10px 26px rgba(60,40,10,.20);
  /* the panel runs ~694px on חק and grows with the size dial (its specimen is live), so it must
     scroll on a short screen — it never had a max-height, it was simply shorter than the phone */
  max-height:calc(100dvh - var(--rdtop-h, 3rem) - env(safe-area-inset-top) - 18px);
  overflow-y:auto; overscroll-behavior:contain; -webkit-overflow-scrolling:touch; }
/* the specimen header: the track's own text, in the live dial values */
/* D-168: the specimen's own gaps ride צפיפות, so the preview shows what that dial does — until
   now it previewed only the line dial, which is part of why the two read as one control. */
.spec { background:var(--card); border-bottom:var(--rule);
  padding:calc(var(--s-8) * var(--dens)) calc(var(--s-12) * var(--dens)) calc(var(--s-8) * var(--dens)); }
.spec p { margin:0; max-inline-size:21em; font-family:var(--font-src); }
.spec .s1 { font-size:var(--text-size); line-height:var(--lh-src); color:var(--ink); }
.spec .s2 { font-size:var(--fs-cmt); line-height:var(--lh-onk); color:var(--onk); margin-top:calc(var(--s-2) * var(--dens)); }
/* D-155: the רש״י line is the header's LAST line (the separate .rashi-spec block at the foot is gone) */
.spec .sr { font-family:var(--font-rashi); font-size:var(--fs-rashi);
  /* D-168: the רש״י line previews the LINE dial like the reader's own רש״י text does
     (html.rashi-font .cmt), instead of sitting at a literal 1.9 that followed neither dial */
  line-height:calc(var(--lh-cmt) * 1.12); color:var(--onk); margin-top:calc(var(--s-4) * var(--dens)); }
.dials { padding:calc(var(--s-6) * var(--dens)) calc(var(--s-12) * var(--dens)) calc(var(--s-6) * var(--dens)); }
/* group label + rule, above each strip */
.grule { display:flex; align-items:center; gap:calc(var(--s-8) * var(--dens)); padding:calc(var(--s-8) * var(--dens)) calc(var(--s-12) * var(--dens)) calc(var(--s-6) * var(--dens)); }
.grule span { font-size:var(--fs-floor); letter-spacing:.14em; color:var(--gold); }
.grule i { flex:1 1 auto; height:1px; background:var(--line); }
/* the panel's strips run edge to edge, ruled top and bottom only */
.rstrip.edge { border-inline:0; border-block:var(--rule-strong); font-size:var(--fs-floor); }
.rstrip.edge button { font-size:var(--fs-floor); }
/* the switch rows: 44px, label at the start, printed mark at the end, --line between */
.menu .swrow { justify-content:flex-start; min-height:var(--tap); padding:0 calc(var(--s-12) * var(--dens)); font-size:var(--fs-floor); color:var(--ink);
  border-bottom:var(--rule); border-radius:0; }
.menu .swrow:last-of-type { border-bottom:0; }
.menu .swrow .pmark { margin-inline-start:auto; }

/* ---- settings & Aa handoff, step 3: settings — ruled table, specimen box, dials (#7a) ---- */
#app.is-page .body { padding:calc(var(--s-8) * var(--dens)) calc(var(--s-12) * var(--dens)) calc(var(--s-12) * var(--dens)); }              /* the settings sheet's own measure */
.rd-top.band .bal { flex:0 0 40px; }                        /* balances the back arrow: the title is optically centred */
.rd-top.band .rref { font-size:var(--fs-2); }                      /* #7a: הגדרות at 19px */
/* section rule: a gold label and a hairline running to the edge — replaces the quiet .fh */
.srule { display:flex; align-items:center; gap:calc(var(--s-8) * var(--dens)); margin:calc(var(--s-12) * var(--dens)) 0 calc(var(--s-8) * var(--dens)); }
.srule:first-child { margin-top:0; }
.srule span { font-size:var(--fs-floor); letter-spacing:.16em; color:var(--gold); }
.srule i { flex:1 1 auto; height:1px; background:var(--frame); }
/* קצב ומשך: a plain ruled table — no fill, no radius; each value sits ON its own rule */
.ftab { width:100%; border-collapse:collapse; background:none; border:0; }
.ftab thead tr { border-bottom:var(--rule-strong); }
.ftab th, .ftab td { font-weight:normal; padding:calc(var(--s-2) * var(--dens)) calc(var(--s-2) * var(--dens)); }
.ftab thead th { font-size:var(--fs-floor); color:var(--dim); padding:0 calc(var(--s-2) * var(--dens)) calc(var(--s-4) * var(--dens)); text-align:center; }
.ftab thead th:first-child { text-align:start; }
.ftab tbody tr { border-bottom:var(--rule); }
.ftab tbody th { text-align:start; }
.ftab .tn { font-family:var(--font-src); font-size:var(--fs-2); color:var(--accent); }
.ftab td { text-align:center; }
/* [type=number] to outrank the old `.ftab input[type=number] { width:4.6rem; min-height:38px }` */
.ftab input[type="number"] { width:62px; min-height:var(--tap); font:inherit; font-size:var(--fs-floor); color:var(--ink);
  background:transparent; border:0; border-bottom:var(--rule-strong); border-radius:0;
  text-align:center; padding:0; }
.fnote { font-size:var(--fs-floor); color:var(--dim); line-height:var(--lh-ui); margin:calc(var(--s-4) * var(--dens)) calc(var(--s-2) * var(--dens)) 0; }
/* תצוגה: the specimen box — a legend box carrying a real verse at the live dial values */
.spec-box { padding:calc(var(--s-8) * var(--dens)) calc(var(--s-12) * var(--dens)) calc(var(--s-12) * var(--dens)); background:var(--card); margin:0; }
/* the verse is the LIVE reading size (the .lbox rule would step it down to .95, which is the
   בית יוסף box's ratio, not a specimen's) */
.spec-box .src { margin:0; font-size:var(--text-size); }
.spec-box .onk { margin:calc(var(--s-4) * var(--dens)) 0 0; font-size:var(--fs-cmt); }

/* ---- settings & Aa handoff, step 4: settings continued (#7b) ---- */
/* each strip is introduced by a plain 15px label; the gold section rule stays for real groups */
.slabel { font-size:var(--fs-floor); color:var(--ink); margin:calc(var(--s-12) * var(--dens)) calc(var(--s-2) * var(--dens)) calc(var(--s-4) * var(--dens)); }
#sform .rstrip button { font-size:var(--fs-floor); }
#sform .rstrip.sm button { font-size:var(--fs-floor); }
/* the two switches: 44px rows with the printed mark, ruled between */
#sform .swrow { display:flex; align-items:center; gap:calc(var(--s-8) * var(--dens)); width:100%; min-height:var(--tap); padding:0;
  border-bottom:var(--rule); border-radius:0; font-size:var(--fs-floor); color:var(--ink); text-align:start; }
#sform .swrow .pmark { margin-inline-start:auto; }
/* the רש״י dial's specimen, in the face it sizes — since D-154 the LAST line of the דוגמה box, so
   the one specimen is a printed leaf (verse · targum · רש״י) and previews every dial */
.rspec { font-family:var(--font-rashi); font-size:var(--fs-rashi);
  line-height:calc(var(--lh-cmt) * 1.12); color:var(--onk); margin:calc(var(--s-2) * var(--dens)) 0 0; max-inline-size:21em; }   /* D-168: previews the line dial */
.rspec .dh { color:var(--gold); }
.spec-box .rspec { margin:calc(var(--s-6) * var(--dens)) 0 0; }
/* ---- D-154: the הגדרות pane re-cut (operator, 2026-09-16: «more logical … less blank areas») ----
   .srow — a strip on ONE LINE with its label, the dial's own grammar: label at the start, the strip
   filling the rest. Rows are ruled on top like the dial stack; a switch already rules its bottom. */
#sform.form { gap:0; }
.srow { display:flex; align-items:center; gap:calc(var(--s-8) * var(--dens)); min-height:46px; border-top:var(--rule); }
.srow > .k { flex:none; font-size:var(--fs-floor); color:var(--ink); }
.srow > .rstrip { flex:1 1 auto; min-width:0; }
#sform .swrow + .srow { border-top:0; }
/* D-207: ערכה and בהירות לילה open the group now, so the first .srow sits directly under the gold
   section rule — its own hairline would double it — and the דוגמה box, which carries no top border
   of its own, needs one where it follows a strip row instead of that rule. */
#sform .srule + .srow { border-top:0; }
#sform .srow + .spec-box { border-top:var(--rule); }
/* the two actions on one row, two outline buttons — not two centred islands */
.sacts { display:flex; gap:calc(var(--s-8) * var(--dens)); padding:calc(var(--s-12) * var(--dens)) 0 0; }
.sacts .btn2 { flex:1 1 0; min-width:0; margin:0; min-height:var(--tap); padding:0 calc(var(--s-8) * var(--dens)); font-size:var(--fs-floor); }
/* the colophon closes the sheet: rule–diamond–rule, the app's name, then version · theme · credit */
.colophon { text-align:center; padding-top:calc(var(--s-12) * var(--dens)); }
.colophon .rule { margin:0 0 calc(var(--s-6) * var(--dens)); }
.colophon .cname { font-family:var(--font-src); font-size:var(--fs-floor); color:var(--accent); }
.colophon .cmeta { font-size:var(--fs-floor); color:var(--dim); margin:var(--s-1) 0 0; line-height:var(--lh-ui); }
/* the "update now" button only exists when a newer build is waiting — it gets its own line under
   the colophon rather than breaking the version · theme · credit line in three */
.colophon .cmeta .btn { display:block; margin:calc(var(--s-6) * var(--dens)) auto 0; font-size:var(--fs-floor); min-height:var(--tap);
  padding:0 calc(var(--s-12) * var(--dens)); border:var(--rule-strong); color:var(--accent); }

/* ---------- D-141: «רישיונות ומקורות» ----------
   A reference page, not a reading page: quiet, ruled, one block per source. Everything is at or
   above --fs-floor, nothing is bold on pointed Hebrew, and no rule here is a link — licence URLs
   are printed as plain text (D-55), so they must READ as text and never as something tappable. */
.licbody { padding-bottom:calc(var(--s-32) * var(--dens)); }
.licintro { font-size:var(--fs-fine); color:var(--dim); line-height:var(--lh-prose); margin:0 0 calc(var(--s-8) * var(--dens)); }
.licmod { font-size:var(--fs-fine); color:var(--dim); line-height:var(--lh-prose); margin:0 0 var(--sp);
  padding-bottom:var(--sp); border-bottom:var(--rule); }
.licb { padding:calc(var(--s-12) * var(--dens)) 0; border-bottom:var(--rule); }
.licb:last-child { border-bottom:0; }
.licttl { font-family:var(--font-src); font-size:var(--fs-2); font-weight:normal;
  color:var(--accent); margin:0 0 calc(var(--s-2) * var(--dens)); }
.licwho { font-size:var(--fs-fine); color:var(--ink); margin:0 0 var(--s-1); line-height:var(--lh-ui); }
.licwhere { font-size:var(--fs-fine); color:var(--mute); margin:0 0 calc(var(--s-6) * var(--dens)); line-height:var(--lh-ui); }
/* the licence's own name stays in English — it is what the licence is filed under — with the
   Hebrew gloss beside it, never instead of it */
.licl { display:flex; align-items:baseline; gap:calc(var(--s-8) * var(--dens)); flex-wrap:wrap; margin-top:calc(var(--s-4) * var(--dens)); }
.licn { font-size:var(--fs-fine); color:var(--gold); letter-spacing:.02em; }
.lich { font-size:var(--fs-fine); color:var(--dim); }
.licc { font-size:var(--fs-fine); color:var(--mute); }
.licnote { font-size:var(--fs-fine); color:var(--dim); margin:var(--s-1) 0 0; line-height:var(--lh-prose); }
.licurl { font-size:var(--fs-fine); color:var(--mute); margin:var(--s-1) 0 0; line-height:var(--lh-prose);
  direction:ltr; text-align:right; unicode-bidi:isolate; }
.licextra { font-size:var(--fs-fine); color:var(--ink); margin:calc(var(--s-6) * var(--dens)) 0 0; line-height:var(--lh-prose);
  padding-inline-start:calc(var(--s-8) * var(--dens)); border-inline-start:2px solid var(--line); }
.licf .licttl { font-family:inherit; font-size:var(--fs-floor); }

/* ---------- auto-scroll pill (D-105) ----------
   Fixed at the bottom-left corner (RTL line ends are ragged on the left, so it covers the least
   text there). z-index 30: over the reader chrome (20), under the sheet scrim (50) and toast (40).
   No border-radius (printed-sefer frame rules); 44px targets; while running it fades so the page
   stays a page — opacity only, never pointer-events, or the pause control would stop working. */
/* --asp-lift (D-167) is set by aspFloat: how far the pill must rise so the done bar's controls
   («סמן כנלמד», then «ביטול» and the chain) are never under it. No transition — it tracks the
   scroll, and an eased `bottom` would lag the page it is riding. */
#asp { position:fixed; left:10px; bottom:calc(12px + env(safe-area-inset-bottom, 0px) + var(--asp-lift, 0px)); z-index:var(--z-float);
  display:flex; align-items:stretch; border:1px solid var(--frame); background:var(--card);
  box-shadow:0 1px 5px var(--shadow); transition:opacity .5s; }
#asp.dim { opacity:.45; }
/* D-184: the voice's transport takes the running pill from 180 to 312 px (measured, 384×751). That
   is 81% of the operator's phone and fits; on a 320 it would run off the screen edge, so the frame
   wraps to a second row instead — every control keeps its 44 px target, which shrinking them would
   not. `max-width` is what forces the wrap; without it flex-wrap never triggers. */
#asp { flex-wrap:wrap; max-width:calc(100vw - 20px); }
#asp.run.voice { row-gap:0; }
#asp button { min-width:var(--tap); min-height:var(--tap); padding:0 calc(var(--s-8) * var(--dens)); border:0; background:none;
  color:var(--dim); font-size:var(--fs-floor); line-height:var(--lh-flat); cursor:pointer; font-family:inherit; }
/* D-167: two controls in one frame — the speaker starts the reading, the triangle the scroll, and
   a hairline divides them (the same rule colour the bands use). The marks are drawn svg, so the
   buttons are flex boxes; `[hidden]` must therefore be restated, or an author `display` would
   outrank the UA's `display:none` and a hidden control would still take its 44px. */
#asp button { display:inline-flex; align-items:center; justify-content:center; }
#asp [hidden] { display:none !important; }
#asp .sep { width:1px; align-self:stretch; margin:calc(var(--s-8) * var(--dens)) 0; background:var(--ctl); }
#asp #aspGo, #asp #aspSpk { color:var(--accent); }
#asp svg { display:block; }
/* the block being read carries the same quiet tint the daf uses for a commented line */
#asp.busy #aspGo { color:var(--dim); }
#rbody .speaking { background:var(--soft); box-shadow:0 0 0 4px var(--soft); }
/* D-184: only what is actually SPOKEN wears the tint. `itemHtml` hangs the speech on the whole
   `.seg`, and the panels that are never read live INSIDE it — רש״י, the אונקלוס line, and D-178's
   ברטנורא/רמב״ם — so the tint claimed them: the page said «this is being read» over text the voice
   does not say. Punched back to the page's own background rather than pulled out of the block,
   because the block is the right unit to speak; it was the CLAIM that was wrong. */
#rbody .speaking .lbox, #rbody .speaking .onk { background:var(--bg); box-shadow:none; }
/* while reading, a block is a target, not text to select: the long-press and the tap belong to the
   voice (Android starts a word selection on the same long-press otherwise); selection returns the
   moment reading stops, so copying from the page is untouched */
body.speaking-on #rbody [data-ipa] { user-select:none; -webkit-user-select:none; -webkit-touch-callout:none; }
#rbody [data-ipa] { -webkit-touch-callout:none; }
/* the value cell carries its mode's small mark beside the number (D-167): a percentage is the
   voice's rate, a bare number the scroll's lines per minute — the mark repeats which is which */
#asp .v { align-self:center; display:inline-flex; align-items:center; gap:calc(var(--s-4) * var(--dens)); min-width:22px; padding-inline:calc(var(--s-4) * var(--dens));
  justify-content:center; white-space:nowrap; font-size:var(--fs-floor); color:var(--dim);
  font-variant-numeric:tabular-nums; }
/* D-257: while the voice downloads, the value cell's speaker mark sits on a pie that fills with the
   download (--vp, set by aspPaint) — the one round thing here, like the home mark's wedge, because a
   fill that grows around a point reads as «in progress» at a glance where a number has to be read */
#asp.busy .v [data-mark="spks"] { box-sizing:content-box; padding:calc(var(--s-4) * var(--dens)); border-radius:50%; color:var(--accent);
  background:conic-gradient(var(--okwedge) calc(var(--vp, 0) * 1%), var(--fill) 0); }

/* ---------- D-257: the first read-aloud download's sheet ----------
   Built and redrawn by speech.js `spkSheetSync` from `spk` alone. Above the pill (30) and the toast
   (40), at the sheets' own layer. Square, ≥16 px, 44 px targets (rule 19); the bar is a background fill. */
.vsh-bg { position:fixed; inset:0; z-index:var(--z-sheet); display:flex; align-items:flex-end;
  background:color-mix(in srgb, var(--scrim) 45%, transparent); }
.vsh { width:100%; max-width:720px; margin:0 auto; box-sizing:border-box; background:var(--card); color:var(--ink);
  border-top:1px solid var(--frame); box-shadow:0 -6px 22px var(--shadow);
  padding:calc(var(--s-24) * var(--dens)) calc(var(--s-16) * var(--dens)) calc(var(--s-16) * var(--dens) + env(safe-area-inset-bottom, 0px));
  font-family:var(--font-ui); }
.vsh-t { margin:0 0 calc(var(--s-6) * var(--dens)); font-size:var(--fs-4); line-height:var(--lh-tight); color:var(--accent); }
.vsh-s { margin:0 0 calc(var(--s-16) * var(--dens)); font-size:var(--fs-floor); line-height:var(--lh-ui); color:var(--dim); }
.vsh-bar { position:relative; height:10px; background:var(--fill); margin:0 0 calc(var(--s-8) * var(--dens)); overflow:hidden; }
.vsh-bar i { position:absolute; top:0; bottom:0; right:0; width:0; background:var(--accent); transition:width .3s linear; }
.vsh-row { display:flex; justify-content:space-between; gap:calc(var(--s-12) * var(--dens)); margin:0 0 calc(var(--s-16) * var(--dens)); font-size:var(--fs-floor);
  line-height:var(--lh-ui); color:var(--ink); font-variant-numeric:tabular-nums; }
.vsh-row .vsh-mb { color:var(--dim); }
.vsh-btns { display:flex; gap:calc(var(--s-12) * var(--dens)); }
.vsh-b { flex:1; min-height:var(--tap); font:inherit; font-size:var(--fs-2); border:1px solid var(--ctl);
  background:transparent; color:var(--ink); cursor:pointer; }
.vsh-b.p { background:var(--btn-bg); color:var(--btn-ink); border-color:var(--btn-bg); }

/* ---------- D-169: התבודדות, the timer page ----------
   A printed page like settings, not a reader: no band chrome beyond the ←, no strip, no foot bands.
   The clock is the screen's one statement — Taamey D, tabular figures so the digits do not dance
   as the seconds run — and everything else is quiet under it (hard rule 10: no target, no badge,
   no colour that praises or blames). */
.hitbody { padding:calc(var(--s-16) * var(--dens)) calc(var(--s-12) * var(--dens)) calc(var(--s-16) * var(--dens) + env(safe-area-inset-bottom));
  display:flex; flex-direction:column; min-height:calc(100dvh - var(--rdtop-h, 3rem) - 42px); }
.hit-grow { flex:1 1 auto; min-height:calc(var(--sp) * 1.5); }   /* honest slack, not a stretched row */
/* the masthead's own grammar: a letterspaced kicker over a hairline carrying the lozenge cluster.
   NO USER since 2026-09-19 — the operator had the «ברסלב» kicker taken off the timer page and the
   rule now sits alone. Kept (nothing is deleted unasked) so a kicker is one line of markup away. */
.hit-kick { text-align:center; font-family:var(--font-ui); font-size:var(--fs-floor);
  letter-spacing:.2em; color:var(--gold); margin:calc(var(--s-2) * var(--dens)) 0 0; }
.hit-rule { display:flex; align-items:center; justify-content:center; gap:calc(var(--s-6) * var(--dens)); margin:calc(var(--s-8) * var(--dens)) 0 0; }
.hit-rule .hair { flex:1 1 auto; height:1px; background:var(--line); }
.hit-rule .loz { display:flex; align-items:center; gap:calc(var(--s-6) * var(--dens)); flex:0 0 auto; }
.hit-rule .loz i { width:4px; height:4px; background:var(--ctl); transform:rotate(45deg); }
.hit-rule .loz i.mid { width:5.5px; height:5.5px; background:var(--gold); }
.hit-clock { font-family:var(--font-src); font-size:var(--fs-6); line-height:var(--lh-tight); color:var(--accent);
  text-align:center; margin:calc(var(--s-24) * var(--dens)) 0 0; font-variant-numeric:tabular-nums; direction:ltr; }
.hit-state { text-align:center; font-size:var(--fs-floor); color:var(--dim); margin:calc(var(--s-8) * var(--dens)) 0 0; }
.hit-act { display:flex; justify-content:center; margin:calc(var(--s-16) * var(--dens)) 0 0; }
/* the ledger of recent days, and the verse the page rests on */
.hit-led { margin:calc(var(--s-16) * var(--dens)) 0 0; }
.hit-verse { text-align:center; margin:calc(var(--s-24) * var(--dens)) 0 0; }
.hit-verse .vtx { font-family:var(--font-src); font-size:var(--fs-2); line-height:var(--lh-prose);
  color:var(--accent); margin:0; }
.hit-verse .vsrc { display:block; font-size:var(--fs-floor); color:var(--dim); margin-top:calc(var(--s-4) * var(--dens)); }
/* the page's one action. `.btn1` is scoped to `.foot`, so outside the foot band it styles nothing
   and the control rendered as bare text — this carries the same printed shape itself. Starting is
   the filled button; stopping is the quiet one, because a running timer needs no persuasion. */
.hit-btn { min-width:11rem; min-height:48px; padding:0 calc(var(--s-24) * var(--dens)); font-size:var(--fs-2); border-radius:0;
  color:var(--bg); background:var(--accent); border:1px solid var(--accent); font-family:inherit; cursor:pointer; }
.hit-btn.run { color:var(--accent); background:none; border:var(--rule-strong); }
.hit-btn:active { opacity:.85; }
.hit-today { text-align:center; font-size:var(--fs-2); color:var(--ink); margin:calc(var(--s-6) * var(--dens)) 0 0; }
.hit-mark { display:flex; align-items:center; justify-content:center; gap:calc(var(--s-8) * var(--dens)); margin:calc(var(--s-16) * var(--dens)) 0 0; }
.hit-mlbl { font-size:var(--fs-floor); color:var(--dim); }
.hit-note { text-align:center; font-size:var(--fs-floor); color:var(--dim); margin:calc(var(--s-16) * var(--dens)) 0 0; line-height:var(--lh-prose); }
/* every row is a button: tapping it corrects that day, or enters a sitting done without the phone */
.hit-row { display:flex; width:100%; justify-content:space-between; align-items:center; gap:calc(var(--s-12) * var(--dens)); margin:0;
  padding:calc(var(--s-8) * var(--dens)) calc(var(--s-2) * var(--dens)); min-height:38px; border:0; border-bottom:var(--rule); border-radius:0;
  background:none; font-family:inherit; font-size:var(--fs-floor); color:var(--ink); text-align:start; cursor:pointer; }
.hit-row.head { color:var(--dim); border-bottom-color:var(--ctl); }
.hit-row:last-child { border-bottom:0; }
.hit-row:active { background:var(--soft); }
.hit-ed { font-style:normal; font-size:var(--fs-floor); color:var(--dim); }
.hit-queued { text-align:center; font-size:var(--fs-floor); color:var(--dim); margin:calc(var(--s-6) * var(--dens)) 0 0; }
/* D-217 (§39(d), operator: «Name the day on screen»): the timer page viewed on another day */
.hit-day { text-align:center; font-size:var(--fs-floor); color:var(--dim); margin:calc(var(--s-6) * var(--dens)) 0 0; }
/* the clock is tappable: it hides itself while the session runs (checking the time is the
   distraction a timer exists to remove) */
#hitClockEl { border:0; background:none; font-family:inherit; cursor:pointer; }
#hitClockEl.hidden-n { color:var(--mute); letter-spacing:.12em; }   /* D-221 (§30b-9): --ctl was 2.04:1 on sepia */
/* while a session runs the page recedes after a few still seconds — further after dark, since
   this practice is traditionally done at night. Any touch brings it back (hitDimArm). */
.hitbody.dim { transition:opacity 1.2s; opacity:.55; }
.hitbody.dim-night { transition:opacity 1.2s, filter 1.2s; opacity:.38; filter:brightness(.75); }
.hitbody.dim .hit-clock, .hitbody.dim-night .hit-clock { opacity:1; }
/* D-169: the weekday strip of אגרת הרמב״ן's sheet — seven short cells, the only strip in the app
   that may wrap (a seven-cell row cannot hold 44px targets at 320px) */
.rstrip.igdays { flex-wrap:wrap; }
.rstrip.igdays button { flex:1 1 4.2rem; min-width:3.4rem; }

/* ---------- identity (§16c): who-screen, recovery code, onboarding placeholder, «חשבון» ---------- */
/* the same printed page as settings (frame, ticks, 8px inset); the body is a short ruled form */
#app.is-who, #app.is-onboard { min-height:100vh; min-height:100dvh; display:flex; flex-direction:column;
  padding-top:calc(var(--s-8) * var(--dens) + env(safe-area-inset-top)); padding-bottom:calc(var(--s-8) * var(--dens) + env(safe-area-inset-bottom));
  padding-inline:max(var(--s-8) * var(--dens), env(safe-area-inset-left), env(safe-area-inset-right)); }
#app.is-who .page, #app.is-onboard .page { padding:0; }
.who { flex:1 1 auto; padding:calc(var(--s-24) * var(--dens)) calc(var(--s-16) * var(--dens)) calc(var(--s-16) * var(--dens) + env(safe-area-inset-bottom)); max-width:26rem; width:100%; box-sizing:border-box; margin:0 auto; }
.who .wtitle { font-family:var(--font-src); font-size:var(--fs-5); font-weight:normal; color:var(--accent);
  text-align:center; margin:0 0 calc(var(--s-16) * var(--dens)); line-height:var(--lh-tight); }
.who .lead { font-size:var(--fs-2); color:var(--ink); margin:0 0 calc(var(--s-6) * var(--dens)); line-height:var(--lh-prose); text-align:center; }
.who .cap { font-size:var(--fs-floor); color:var(--dim); line-height:var(--lh-prose); margin:calc(var(--s-4) * var(--dens)) 0; text-align:center; }
.who .wnote { color:var(--ink); }
.wform { margin:calc(var(--s-12) * var(--dens)) 0 0; }
/* a field is a label over a rule; the value sits ON the rule (the ftab idiom), no box, no radius.
   16px keeps iOS from zooming the page on focus; phone/PIN/code are Latin runs and stay LTR
   inside the RTL page (dir on the input, text-align from it). */
.wfield { display:block; margin:0 0 calc(var(--s-8) * var(--dens)); }
.wfield span { display:block; font-size:var(--fs-floor); color:var(--dim); margin:0 calc(var(--s-2) * var(--dens)) var(--s-1); }
.wfield input { display:block; width:100%; box-sizing:border-box; min-height:var(--tap); font:inherit; font-size:var(--fs-floor); color:var(--ink);
  background:transparent; border:0; border-bottom:var(--rule-strong); border-radius:0; padding:0 calc(var(--s-2) * var(--dens));
  letter-spacing:.04em; }
.wfield input:focus { outline:none; border-bottom-color:var(--gold); }
.wfield input[type=password] { letter-spacing:.2em; }
.who .werr { padding:0; min-height:1.6em; margin:calc(var(--s-8) * var(--dens)) 0 0; font-size:var(--fs-floor); color:var(--dim); text-align:center; line-height:var(--lh-prose); }
.wact { display:flex; justify-content:center; margin:calc(var(--s-12) * var(--dens)) 0 0; }
.who .btn, .acct .btn { border-radius:0; min-height:var(--tap); min-width:9rem; padding:0 calc(var(--s-16) * var(--dens)); font-size:var(--fs-floor); }
.wlinks { display:flex; justify-content:center; flex-wrap:wrap; gap:0 calc(var(--s-8) * var(--dens)); margin:calc(var(--s-16) * var(--dens)) 0 0; }
.wlinks .linkish { min-height:var(--tap); display:inline-flex; align-items:center; }
.wlinks .cap { display:inline-flex; align-items:center; min-height:var(--tap); margin:0; }   /* the generic .cap top margin would drop it below the links' baseline */
/* the recovery code: a Latin run, large, in the tabular hand — the one thing here to be copied out */
.rcode { font-family:var(--font-mono); font-size:clamp(var(--fs-floor), 5vw, var(--fs-4)); letter-spacing:.14em;   /* 19 glyphs at .74em advance: follows the viewport so the four groups stay on ONE line down to 320px */
  color:var(--accent); text-align:center; margin:calc(var(--s-16) * var(--dens)) 0; padding:calc(var(--s-12) * var(--dens)) calc(var(--s-6) * var(--dens)); border-top:var(--rule-strong); border-bottom:var(--rule-strong);
  overflow-wrap:anywhere; user-select:all; -webkit-user-select:all; }
/* §16d onboarding: the same ruled form — a track a 44px row with the printed mark, its name in the
   ledger hand, one quiet line under it; the starting point folds under the row as plain picker
   rows (no card box here: the page is the box). Existing tokens only, nothing rounded. */
.onb { margin-top:calc(var(--s-12) * var(--dens)); }
.onb .onb-t { border-bottom:var(--rule); }
.onb .onb-row { display:flex; align-items:center; gap:calc(var(--s-12) * var(--dens)); width:100%; min-height:var(--tap); padding:calc(var(--s-6) * var(--dens)) 0; border-radius:0;
  font-size:var(--fs-floor); color:var(--ink); text-align:start; }
.onb .onb-tt { flex:1 1 auto; min-width:0; display:flex; flex-direction:column; gap:var(--s-1); }
.onb .onb-name { font-family:var(--font-src); font-size:var(--fs-2); color:var(--accent); line-height:var(--lh-tight); }
.onb .onb-row[aria-pressed="false"] .onb-name { color:var(--dim); }
.onb .onb-sub { font-size:var(--fs-floor); color:var(--dim); line-height:var(--lh-ui); }
.onb .onb-row .pmark { margin-inline-start:auto; }
.onb .onb-more { padding:0 0 calc(var(--s-8) * var(--dens)); }
.onb .onb-more[hidden] { display:none; }
.onb .onb-more .frow { background:none; border:0; border-radius:0; padding:0 calc(var(--s-2) * var(--dens)); min-height:var(--tap); gap:calc(var(--s-8) * var(--dens)); }
.onb .onb-more .frow .k { font-size:var(--fs-floor); }
.onb .onb-more .frow input[type=number] { border-radius:0; } /* the generic .frow input[type=number] rule (0,2,1) out-specifies the radius reset */
.onb .onb-more select { flex:0 1 auto; min-width:0; max-width:58%; text-overflow:ellipsis; }
.onb .onb-more .loading { padding:calc(var(--s-8) * var(--dens)) calc(var(--s-2) * var(--dens)); text-align:start; font-size:var(--fs-floor); }
.onb .onb-err { font-size:var(--fs-floor); color:var(--dim); line-height:var(--lh-ui); margin:calc(var(--s-8) * var(--dens)) calc(var(--s-2) * var(--dens)) calc(var(--s-2) * var(--dens)); }
.onb .onb-act { margin:0 calc(var(--s-2) * var(--dens)) calc(var(--s-4) * var(--dens)); }
.onb .onb-act .btn2 { min-height:var(--tap); margin-top:0; }
.onb .werr { margin-top:calc(var(--s-12) * var(--dens)); }
/* settings «חשבון»: name and the masked number on one rule, the PIN form folded under a 44px row,
   the device list ruled like the switches, the way out as an outline button */
.acct { margin:0 0 calc(var(--s-4) * var(--dens)); }
.acct .cap { font-size:var(--fs-floor); color:var(--dim); line-height:var(--lh-prose); margin:calc(var(--s-6) * var(--dens)) calc(var(--s-2) * var(--dens)) calc(var(--s-4) * var(--dens)); }   /* D-138: the guest block's one line */
.acct .rcode { margin:calc(var(--s-8) * var(--dens)) 0 calc(var(--s-6) * var(--dens)); }                                                                  /* the transfer code, inside the block */
.who .wguest { margin:calc(var(--s-24) * var(--dens)) 0 0; }                                                                    /* D-138: the guest door under the links */
.who .wguest .rule { margin:0 0 calc(var(--s-12) * var(--dens)); }
.acct .arow { display:flex; align-items:baseline; justify-content:space-between; gap:calc(var(--s-8) * var(--dens)); min-height:var(--tap); margin:0;
  border-bottom:var(--rule); flex-wrap:wrap; padding:calc(var(--s-6) * var(--dens)) 0; box-sizing:border-box; }
.acct .ak { font-family:var(--font-src); font-size:var(--fs-2); color:var(--accent); }
.acct .av { font-size:var(--fs-floor); color:var(--dim); letter-spacing:.04em; }
.acct .arow-btn { display:flex; align-items:center; width:100%; min-height:var(--tap); padding:0; border:0; border-bottom:var(--rule);
  border-radius:0; background:none; font:inherit; font-size:var(--fs-floor); color:var(--ink); text-align:start; cursor:pointer; }
.acct .arow-btn:active { background:var(--soft); }
.acct .apin { margin:calc(var(--s-8) * var(--dens)) 0 calc(var(--s-4) * var(--dens)); }
.acct .werr { padding:0; min-height:1.4em; margin:calc(var(--s-6) * var(--dens)) 0 0; font-size:var(--fs-floor); color:var(--dim); line-height:var(--lh-ui); }
.acct .wact { margin:calc(var(--s-8) * var(--dens)) 0 calc(var(--s-6) * var(--dens)); }
/* ---- D-155: the חשבון block — a row says what it does before it is tapped, and what it opens is boxed ----
   .fold rows carry a drawn chevron (a rotated square, two borders — D-68c's glyph-as-shape rule; it
   turns when `aria-expanded` flips); .inset is the card-filled box under an opened row, the lbox
   idiom; the PIN and its repeat sit side by side; the action sits at the END of its form; the way
   out is .quiet (--dim ink, ≥7:1 in every theme) and behind a confirm. */
.acct .arow-btn.fold { justify-content:space-between; }
.acct .arow-btn.fold::after { content:""; flex:none; width:7px; height:7px; margin-inline-end:calc(var(--s-8) * var(--dens));
  border:solid var(--ctl); border-width:0 0 1.5px 1.5px; transform:translateY(-2px) rotate(-45deg); transition:transform .18s; }
.acct .arow-btn.fold[aria-expanded="true"]::after { transform:translateY(2px) rotate(135deg); }
.acct .inset { background:var(--card); border:var(--rule); padding:calc(var(--s-8) * var(--dens)) calc(var(--s-8) * var(--dens)) calc(var(--s-8) * var(--dens)); margin:0 0 calc(var(--s-6) * var(--dens)); }
.acct .inset[hidden] { display:none; }
.acct .wform.inset { margin:0 0 calc(var(--s-6) * var(--dens)); }
.acct .wpair { display:flex; gap:calc(var(--s-12) * var(--dens)); }
.acct .wpair .wfield { flex:1 1 0; min-width:0; }
.acct .inset .wact { margin:calc(var(--s-6) * var(--dens)) 0 0; justify-content:flex-end; }
.acct .inset .rcode { margin:calc(var(--s-4) * var(--dens)) 0 calc(var(--s-8) * var(--dens)); }
.acct .arow-btn.quiet { color:var(--dim); }
.devs .drow { display:flex; align-items:center; gap:calc(var(--s-8) * var(--dens)); min-height:var(--tap); border-bottom:var(--rule); padding:calc(var(--s-2) * var(--dens)) 0; }
.devs.inset .drow:last-child { border-bottom:0; }
/* the current device has no «הסר»: an empty cell of the same width keeps the dates in one column */
.devs .drm, .devs .drm-sp { flex:none; min-width:52px; text-align:center; }
.devs .dk { flex:1 1 auto; min-width:0; font-size:var(--fs-floor); color:var(--ink); overflow-wrap:anywhere; }
.devs .drow.cur .dk { color:var(--accent); }
.devs .dv { flex:none; font-size:var(--fs-floor); color:var(--dim); font-variant-numeric:tabular-nums; }
.devs .drm { flex:none; min-height:var(--tap); padding:0 calc(var(--s-6) * var(--dens)); }
.devs .cap { font-size:var(--fs-floor); color:var(--dim); margin:calc(var(--s-6) * var(--dens)) calc(var(--s-2) * var(--dens)); }

/* ---------- D-132: settings tabs · מסלולים · התקדמות ---------- */
/* the strip spans the page like the reader's #lstrip; three panes in the DOM, the body's class picks one */
.body > .stabs { margin:calc(-1 * var(--s-12) * var(--dens)) calc(-1 * var(--s-8) * var(--dens)) calc(var(--s-12) * var(--dens)); }
.stabs .cell { font-size:var(--fs-floor); min-height:var(--tap); }
.spane { display:none; }
#sbody.tab-set .p-set, #sbody.tab-tracks .p-tracks, #sbody.tab-stats .p-stats { display:block; }
/* מסלולים (D-133, take 2): the home ledger's rows VERBATIM — .lrow/.lflex/.lmain/.nm/.lbody/.pt/.frag/.mark —
   one status line per track, the round mark at the row end = «in the daily seder»; a bottom sheet per track
   (the reader's sheet idiom) carries the dials as the Aa panel's sliders. --hs is the home's type scale
   (undefined here), pinned to 1. NOT the .form grid: a grid track sizes to its item's min-content and a
   nowrap line inside a flex row contributes its full width — the page grew to 690px on the mock once. */
.tlist { --hs:1; display:block; }
.tledger { border-top:var(--rule-strong); border-bottom:var(--rule-strong); min-width:0; max-width:100%; }
/* D-135: rows are drag handles under a long-press — the browser must not take the touch as a scroll */
/* D-169: `pan-y`, NOT `none`. `none` told the browser the row handles every gesture itself, so a
   finger starting anywhere in this list could not scroll the page — invisible while the eleven rows
   fitted a phone, and a dead end the moment D-169's twelfth and thirteenth rows pushed the list
   past the fold (operator: «I don't see hitbodedut in maslulim, I think because the screen cannot
   scroll down»). With `pan-y` a swipe scrolls and a still 500 ms hold still starts the drag: the
   move that would scroll is over the 10 px slop, which cancels the pending drag anyway. While a
   drag IS running the list takes the gesture back (`.drag-on`), since reordering is vertical too. */
.tlist .lrow { position:relative; touch-action:pan-y; background:var(--bg); }
.tlist.drag-on .lrow { touch-action:none; }
.tlist .lrow.dragging { z-index:var(--z-drag); background:var(--soft); box-shadow:0 4px 14px var(--shadow); }
.tlist .lmain.noopen { cursor:default; }
.tlist .lmain.noopen:active { background:none; }
.tlist .lflex { padding:var(--s-2) var(--s-2); }
.tlist .lrow .lbody { overflow:hidden; }
.tlist .lrow .pt, .tlist .lrow .dt { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }   /* place, then pace: one line each */
.tlist .lrow .pt:empty, .tlist .lrow .dt:empty { display:none; }
.tlist .lmain.noopen .nm { color:var(--accent); }                                        /* חק / תיקון: nothing to open, still live */
.tlist .lrow.off .nm, .tlist .lrow.off .pt, .tlist .lrow.off .dt { color:var(--mute); }
.tlist .lrow.off .mark { border-color:var(--ctl); background:none; }
/* the track sheet: short (no 48vh floor), the name in the title face, the dials exactly as in settings */
.tsheet { min-height:0; }
.tsheet .sheet-t { font-family:var(--font-src); font-size:var(--fs-2); color:var(--accent); white-space:normal; line-height:var(--lh-tight); }
.tsheet .sheet-t .frag { font-family:var(--font-ui); font-size:var(--fs-floor); color:var(--dim); }
.tsheet .pane { flex:none; padding:calc(var(--s-4) * var(--dens)) calc(var(--s-8) * var(--dens)) calc(var(--s-16) * var(--dens)); }
.tsheet .fnote { margin:calc(var(--s-8) * var(--dens)) calc(var(--s-12) * var(--dens)) 0; }
.tsh-days { margin:calc(var(--s-6) * var(--dens)) calc(var(--s-12) * var(--dens)) 0; font-family:var(--font-ui); font-size:var(--fs-floor); color:var(--accent); line-height:var(--lh-ui); }
.tsh-days[hidden] { display:none; }
/* (the sheet's totals block was removed on 2026-09-06 — operator) */
.tsheet .wact { margin:calc(var(--s-12) * var(--dens)) 0 0; text-align:center; }
.tsheet .btn2 { min-width:12rem; }
/* התקדמות — the D-132 pane's rules (.stk*, .stab, .prow*, .cal*, .cc*, .hrow*) were retired by D-165;
   the re-cut pane's pg- block sits at the end of this file */

/* ---------- D-136: the starting-point pages ---------- */
/* the page: heading, «כעת» line, ledger-like rows grouped under gold rules, a sticky foot bar */
.pkbody { padding-bottom:calc(var(--s-6) * var(--dens)); }
.pk-h { margin-top:0; }
.pk-now { margin:0 0 calc(var(--s-4) * var(--dens)); font-size:var(--fs-floor); color:var(--dim); }
.pk-now:empty { display:none; }
.pklist { border-top:var(--rule); }
.pkrow { display:flex; align-items:center; gap:calc(var(--s-8) * var(--dens)); width:100%; min-height:var(--tap); padding:calc(var(--s-4) * var(--dens)) calc(var(--s-8) * var(--dens)) calc(var(--s-4) * var(--dens)) calc(var(--s-6) * var(--dens)); text-align:start;
  border-bottom:var(--rule); background:none; border-radius:0; box-shadow:inset 3px 0 0 transparent; }
.pkrow .nm { flex:1 1 auto; min-width:0; font-family:var(--font-src); font-size:var(--fs-2); color:var(--accent); line-height:var(--lh-tight); }
.pkrow .now { flex:none; font-size:var(--fs-floor); color:var(--gold); letter-spacing:.08em; }
.pkrow .cnt { flex:none; font-size:var(--fs-floor); color:var(--dim); font-variant-numeric:tabular-nums; }
.pkrow:active { background:var(--soft); }
.pkrow[aria-pressed="true"] { background:var(--soft); box-shadow:inset 3px 0 0 var(--gold); }
.pkrow[aria-pressed="true"] .nm { color:var(--ink); }
.pkrow.cur .nm { text-decoration:underline; text-decoration-color:var(--gold); text-underline-offset:.22em; text-decoration-thickness:1px; }
/* the foot bar: sticks to the bottom of the screen while the list scrolls; the reader's band idiom */
.pkfoot { position:sticky; bottom:0; z-index:var(--z-pkfoot); display:flex; align-items:center; gap:calc(var(--s-8) * var(--dens)); flex-wrap:wrap;
  margin-top:auto; padding:calc(var(--s-6) * var(--dens)) calc(var(--s-8) * var(--dens)) calc(var(--s-6) * var(--dens) + env(safe-area-inset-bottom)); background:var(--bg); border-top:var(--rule-strong); }
.pkfoot[hidden] { display:none; }
.pkfoot .pkf { display:flex; align-items:center; gap:calc(var(--s-6) * var(--dens)); font-size:var(--fs-floor); color:var(--ink); }
.pkfoot .pkf input[type=number] { width:3.6rem; min-height:var(--tap); text-align:center; font-variant-numeric:tabular-nums; }
.pkfoot .amud { display:inline-flex; gap:calc(var(--s-4) * var(--dens)); }
.pkfoot .amud .tab { min-width:var(--tap); min-height:var(--tap); padding:0 calc(var(--s-8) * var(--dens)); }
.pkgo { flex:1 1 150px; min-height:var(--tap); padding:0 calc(var(--s-8) * var(--dens)); border-radius:0; background:var(--accent); color:var(--bg); font-size:var(--fs-floor); }
.pkgo:disabled { opacity:.45; cursor:default; }
.pkgo:not(:disabled):active { opacity:.85; }

/* ---------- D-136b: the option rows ---------- */
.pkrow.pkq .cnt { color:var(--accent); }
.pkrow:disabled { opacity:.5; cursor:default; }
.pkrow:disabled .nm { color:var(--mute); }
.pksearch { display:flex; align-items:center; gap:calc(var(--s-8) * var(--dens)); padding:calc(var(--s-4) * var(--dens)) 0 calc(var(--s-6) * var(--dens)); }
.pksearch input[type=search] { flex:1 1 auto; min-width:0; min-height:var(--tap); padding:0 calc(var(--s-8) * var(--dens)); font-size:var(--fs-floor); }
.pksearch .pkscope { flex:none; font-size:var(--fs-floor); color:var(--gold); }
.pkrow .cnt.hd { flex:1 1 auto; min-width:0; text-align:end; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.pkrow.pkhit .nm { flex:none; }
#pkHits { max-height:40vh; overflow-y:auto; }
.pkr { display:flex; align-items:stretch; border-bottom:var(--rule); }
.pkr .pkrow { flex:1 1 auto; min-width:0; border-bottom:0; }
.pkmore { flex:none; min-width:64px; min-height:var(--tap); padding:0 calc(var(--s-8) * var(--dens)); font-size:var(--fs-floor); color:var(--gold); border-inline-start:var(--rule); }
.pkmore[aria-expanded="true"] { background:var(--soft); }
.pknest { padding:0 0 calc(var(--s-4) * var(--dens)) 0; border-bottom:var(--rule); }
.pknest[hidden] { display:none; }
.pknest .pksub .pkrow { padding-inline-start:calc(var(--s-24) * var(--dens)); min-height:40px; }
.pknest .pksub .pkrow .nm { font-size:var(--fs-floor); }
.pkrep { display:flex; flex-wrap:wrap; align-items:center; gap:calc(var(--s-6) * var(--dens)); padding:calc(var(--s-6) * var(--dens)) calc(var(--s-8) * var(--dens)); }
.pkrep .k { font-size:var(--fs-floor); color:var(--dim); margin-inline-end:calc(var(--s-4) * var(--dens)); }
.pkrep .tab { min-height:40px; }

/* ---------- D-165: התקדמות re-cut (design/progress-pane/README.md) ---------- */
/* Every class is pg- (red team finding 11: bare .foot/.src/.fold/.nm/.sub/.pos/.dh already mean
   something else in this file). The day cell is the home's .mark inside a BUTTON — the button is the
   tap target (36 px rows: the operator's logged exemption from the 44 px rule, drag-scrub as the
   corrective), so the mark's own 44 px halo is switched off here and the fill stays a background
   (D-64 burn). Spacing rides --sp; every small text is the floor; nothing below it. */
.form.pg { gap:0; }
.pg-kick { font-size:var(--fs-floor); letter-spacing:.06em; color:var(--gold); margin:0; }
.pg-head { font-family:var(--font-src); font-size:var(--fs-3); line-height:var(--lh-tight); color:var(--accent); margin:calc(var(--s-2) * var(--dens)) 0 0; }
.pg-head b { font-weight:normal; font-size:var(--fs-4); }
.pg-sub { font-size:var(--fs-floor); color:var(--ink); margin:calc(var(--s-4) * var(--dens)) 0 0; line-height:var(--lh-ui); }
.pg-luach { display:grid; grid-template-columns:repeat(7, 1fr); column-gap:calc(var(--s-2) * var(--dens)); align-items:center; touch-action:pan-y; margin:calc(var(--s-4) * var(--dens)) 0 0; }
.pg-mh { grid-column:1 / -1; display:flex; align-items:center; gap:calc(var(--s-8) * var(--dens)); font-size:var(--fs-floor); color:var(--gold); margin:calc(var(--s-4) * var(--dens)) 0 0; }
.pg-mh i { flex:1 1 auto; height:1px; background:var(--line); }
.pg-dh { text-align:center; font-size:var(--fs-floor); color:var(--dim); padding:calc(var(--s-2) * var(--dens)) 0; }
.pg-dh.sh { color:var(--gold); }
.pg-day { position:relative; display:flex; align-items:center; justify-content:center; min-height:36px; width:100%; padding:0; border:0; border-radius:0; background:none; font:inherit; }
.pg-day.pg-blank { visibility:hidden; }
.pg-day .mark.pg::before { content:none; }
.pg-day .mark.pg { width:22px; height:22px; }
.pg-day .mark.pg-t { border-color:var(--gold); border-width:2px; }
.pg-day.rc::after { content:""; position:absolute; top:2px; inset-inline-start:2px; width:5px; height:5px; background:var(--gold); }   /* the first of the month */
.pg-rest { display:inline-block; width:9px; height:9px; background:var(--ctl); transform:rotate(45deg); }
.pg-rest.f { width:11px; height:11px; background:var(--ok); }
.pg-legend { display:flex; flex-wrap:wrap; gap:calc(var(--s-4) * var(--dens)) calc(var(--s-12) * var(--dens)); align-items:center; font-size:var(--fs-floor); color:var(--dim); margin:calc(var(--s-6) * var(--dens)) 0 0; }
.pg-legend .mark { width:13px; height:13px; }
.pg-legend .mark::before { content:none; }
.pg-legend .pg-rest { width:7px; height:7px; margin-inline:calc(var(--s-2) * var(--dens)); }
/* D-249: the pane's day states, legible. A sign and its word wrap as one (.pg-lg). The part-learned
   wedge was --fill on the page (1.3:1 light, 1.7:1 dark) and a full day's pale fill sat 1.07:1 from
   it: here a day is FILLED by how much of it was learned — the wedge and the full disc in --ok. A
   day with nothing due draws a short dash instead of an empty space that read as a missing cell. */
.pg-lg { display:inline-flex; align-items:center; gap:calc(var(--s-4) * var(--dens)); white-space:nowrap; }
.pg-day .mark.pg.on, .pg-legend .mark.pg.on { background:var(--ok); }
.pg-day .mark.pg.partial, .pg-legend .mark.pg.partial { background:conic-gradient(var(--ok) calc(var(--p,0) * 1turn), transparent 0); }
.pg-day .mark.pg.none::after, .pg-legend .mark.pg.none::after { content:""; width:8px; height:2px; background:var(--ctl); }
.pg-legend .mark.pg-t { border-color:var(--gold); border-width:2px; }
.pg-sub .nw { white-space:nowrap; }
/* D-251: «איפה אני עומד» — name · place · days left on one line, a thin bar under it (the per-track
   ratio rows, masechet map, bars and foot of D-165 were retired with the readout; their rules went too) */
.pg-plh { margin:calc(var(--s-4) * var(--dens)) 0 0; font-size:var(--fs-floor); color:var(--mute); text-align:end; }
.pg-pl { display:flex; flex-direction:column; gap:calc(var(--s-4) * var(--dens)); width:100%; padding:calc(var(--s-6) * var(--dens)) 0; border:0; border-radius:0; background:none; font:inherit; color:inherit; text-align:start; }
button.pg-pl { min-height:var(--tap); }
button.pg-pl:active { background:var(--soft); }
.pg-pl1 { display:flex; align-items:baseline; gap:calc(var(--s-8) * var(--dens)); min-width:0; }
.pg-nm { font-family:var(--font-src); font-size:var(--fs-2); color:var(--accent); flex:none; }
.pg-plc { flex:1 1 auto; min-width:0; font-size:var(--fs-floor); color:var(--dim); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.pg-left { flex:none; font-size:var(--fs-floor); color:var(--ink); white-space:nowrap; font-variant-numeric:tabular-nums; }
.pg-thin { display:block; height:3px; background:var(--line); }
.pg-thin > span { display:block; height:3px; background:var(--ok); }
/* D-251: the milestones fold as rulers — marks at PG_MS_AT, the reached ones filled */
.pg-rl { display:grid; grid-template-columns:minmax(0, 7.2rem) minmax(8rem, 1fr) 2rem; gap:calc(var(--s-8) * var(--dens)); align-items:center; min-height:30px; }
.pg-rn { font-size:var(--fs-floor); color:var(--accent); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.pg-rb { position:relative; height:12px; }
.pg-rb::before { content:""; position:absolute; top:5px; left:0; right:0; height:2px; background:var(--line); }
.pg-rb .f { position:absolute; top:4px; inset-inline-start:0; height:4px; background:var(--ok); }
.pg-rb .mark { position:absolute; top:1px; width:10px; height:10px; box-sizing:border-box; border:1px solid var(--ctl); background:var(--bg); transform:translateX(50%); }   /* round: the .mark exception (D-63) */
.pg-rb .mark::before { content:none; }
.pg-rb .mark:active { transform:translateX(50%); }
.pg-rb .mark.on { background:var(--ok); border-color:var(--ok); }
.pg-rc { font-size:var(--fs-floor); text-align:end; font-variant-numeric:tabular-nums; }
.pg-rn.sub { color:var(--dim); padding-inline-start:calc(var(--s-12) * var(--dens)); }
.pg-rh { min-height:0; }
.pg-rh .pg-rn { color:var(--mute); }
.pg-rh .pg-rb { height:18px; }
.pg-rh .pg-rb::before { content:none; }
.pg-rb em { position:absolute; top:0; transform:translateX(50%); font-style:normal; font-size:var(--fs-floor); line-height:var(--lh-tight); color:var(--mute); }
.pg-sy { display:flex; justify-content:space-between; align-items:baseline; gap:calc(var(--s-8) * var(--dens)); padding:calc(var(--s-4) * var(--dens)) calc(var(--s-2) * var(--dens)); margin:0; font-size:var(--fs-floor); }
.pg-sy .t { font-family:var(--font-src); color:var(--accent); font-size:var(--fs-floor); }
.pg-sy .d { color:var(--dim); font-size:var(--fs-floor); white-space:nowrap; }
.pg-fold { position:relative; display:flex; align-items:center; min-height:var(--tap); width:100%; border:0; border-top:var(--rule); border-radius:0; background:none; font:inherit; font-size:var(--fs-floor); color:var(--dim); padding:0 calc(var(--s-2) * var(--dens)) 0 calc(var(--s-24) * var(--dens)); text-align:start; }
.pg-fold::after { content:""; position:absolute; inset-inline-end:8px; top:50%; width:7px; height:7px; border:solid var(--ctl); border-width:0 0 1.5px 1.5px; transform:translateY(-70%) rotate(-45deg); transition:transform .18s; }
.pg-fold[aria-expanded="true"]::after { transform:translateY(-30%) rotate(135deg); }
.pg-fold:active { background:var(--soft); }
.pg-ms { margin:0; padding:calc(var(--s-2) * var(--dens)) calc(var(--s-2) * var(--dens)) calc(var(--s-6) * var(--dens)); }
.pg-ms[hidden] { display:none; }

/* ============ D-187: the commentary anchor, and the se'if it belongs to ============
   Sefaria's שו״ע / רמב״ם text carries the printed page's own superscripts — an <i> sitting in the
   text at the exact word a note discusses, naming its commentator and its ס״ק. `sanitize` was
   dropping the attributes, so the app rendered 441 empty tags on one day's page and the linkage
   was simply gone. The server now resolves each marker to a layer key and a note index; these
   rules are what makes it visible, and `::after` draws the letter from the attribute so the
   marker carries no text of its own and can never be selected, spoken or counted as a word. */
.src i[data-ly] { font-style:normal; user-select:none; }
/* D-193 (operator: «make letter links bold»). Faithful as well as legible: on a printed מ״ב page
   the se'if letter and the מ״ב's ס״ק letter are both BOLD, and only שער הציון's Rashi-script letter
   is not. At 12px a superscript needs the weight to read as a control rather than as a speck. */
.src i[data-ly]::after { content:"(" attr(data-sk) ")"; font-size:.62em; vertical-align:.45em;
  color:var(--ly-a); padding-inline:.06em; line-height:0; font-weight:700; }
.src i[data-ly]:not([data-sk])::after { content:"*"; }
/* one tap target per marker without moving the text a pixel */
.src i[data-ly]::before { content:""; position:absolute; inset:-.55rem -.4rem; }
.src i[data-ly] { position:relative; }
/* D-192 — HOW A PRINTED שולחן ערוך ACTUALLY DOES IT, which is what the operator asked me to go
   and look at. The page separates its apparatus on three axes at once, not on colour (it has none):
     * משנה ברורה  — a BLOCK letter in CURVED brackets: «(א)».
     * שער הציון / באר היטב — a RASHI-SCRIPT letter in curved brackets, not bold.
     * באר הגולה   — a small superscript BLOCK letter with NO brackets at all.
   and the se'if number itself is a bold block letter with no brackets, which is what `.vn` already
   is. So: bracket shape, letterform and weight, with size following from them. Sources: the Mishnah
   Berurah's own front matter («the notes to the Mishnah Berurah are cited by block letters in curved
   brackets… the Baer HaGola is cited by a small superscript block letter»), and the standard-edition
   description of the three letters on a מ״ב page.
   Mapped onto this app's three series, keeping משנה ברורה on its own real mark:
     A  «(א)»  block, curved brackets   — מ״ב · ש״ך · בית שמואל · מצודת דוד · כסף משנה
     B  «[א]»  block, square brackets   — מג״א · פתחי תשובה · מצודת ציון
     C  « א »  RASHI script, no bracket — ט״ז · רש״י
   Colour still carries too, because it is free and helps at a glance — but the page no longer
   depends on it, which was the operator's point: on his phone the three browns read as one.

   The layers read as three series, as they do in print — but the colours have to SURVIVE the
   theme. D-191 (operator, from his own phone): --gold #7c5c28, --accent #493922 and --onk #6a5a3a
   are ALL browns in the parchment theme, so at a 12.4px superscript the three series were one, and
   a line carrying (א) from משנה ברורה beside (א) from ט״ז said nothing about which was which.
   Every חלק ships exactly three layers (`sefer.py` `_SA_LAYERS`) and ט״ז is in all four of them, so
   the assignment is by SERIES, not by book: A gold, B blue, C red, chosen so that no חלק ever pairs
   two of its own keys on one hue — או״ח mb/ma/taz, יו״ד and חו״מ shach/taz/pitchei, אה״ע
   beit_shmuel/taz/pitchei, נ״ך metzudat_david/metzudat_zion/rashi. */
.src i[data-ly="shach"]::after,
.src i[data-ly="beit_shmuel"]::after,
.src i[data-ly="metzudat_david"]::after,
.src i[data-ly="kesef"]::after { color:var(--ly-a); }
.src i[data-ly="magen_avraham"]::after,
.src i[data-ly="pitchei"]::after,
.src i[data-ly="metzudat_zion"]::after {
  content:"[" attr(data-sk) "]"; color:var(--ly-b); font-size:.58em; vertical-align:.5em; }
/* No bracket at all — the third treatment the printed page uses (it is באר הגולה's). It carries the
   most size, because a bare letter has no brackets to give it width or to say it is a mark.
   OPERATOR, 2026-09-23: «Rama and commentaries for shulhan arukh should not use rashi font» — so
   this series is NOT set in כתב רש״י, which the printed page would have used here. Block face, and
   the bracket shape and the size do the work that the letterform would have. */
.src i[data-ly="taz"]::after,
.src i[data-ly="rashi"]::after {
  content:attr(data-sk); color:var(--ly-c); font-size:.72em; vertical-align:.42em;
  padding-inline:.14em; }
/* D-222 — the two layers that ship OFF, so a page carries at most five series (או״ח with both on).
   D  באר היטב — the printed page's own mark is a Rashi-script letter in CURVED brackets, not bold
      (the comment above). Two operator rulings take both of those away — no Rashi script in this
      reader (D-192), every letter link bold (D-193) — so what is left to tell it from משנה ברורה's
      «(א)» is a smaller size and a fifth hue. Both ship OFF, and with both on a line reads «(א)» gold
      beside «(א)» green, smaller.
   E  שערי תשובה — sits right after the באר היטב mark it shares a letter with (its notes are
      numbered by באר היטב's ס״ק), so it gets the most distinct shape: CURLY brackets, written as
      escapes so no literal brace sits inside a rule. A default the operator may want to revisit; no
      printed convention was checked for it. */
.src i[data-ly="beer_heitev"]::after {
  content:"(" attr(data-sk) ")"; color:var(--ly-d); font-size:.58em; vertical-align:.5em; }
.src i[data-ly="shaarei_teshuva_sa"]::after {
  content:"\7B" attr(data-sk) "\7D"; color:var(--ly-e); font-size:.58em; vertical-align:.5em; }
/* F  סמ״ע (D-222, operator decision 5; OFF like every שו״ע layer) — חו״מ's sixth series beside
      ש״ך (A gold), פתחי תשובה (B blue), ט״ז (C red) and באר היטב (D green): single ANGLE quotes
      and a sixth hue, magenta, so no two keys of one חלק share a shape or a hue. No printed
      convention was checked for it — a default the operator may want to revisit. */
.src i[data-ly="sma"]::after {
  content:"\2039" attr(data-sk) "\203A"; color:var(--ly-f); font-size:.58em; vertical-align:.5em; }

/* D-189: a se'if is now just its own text — the commentary moved into the sheet, so the block
   spacing is the paragraph's, not a container's. */
.seif + .seif { margin-top:calc(var(--s-6) * var(--dens)); }

/* D-189: the words a note is about, marked in the text when its superscript is tapped. Painted
   like the app's own selection rather than a highlighter: this sits under a sheet covering the
   lower half of the screen and has to read as emphasis, not as a hit. It outlives the sheet. */
/* D-191: this shipped as `background:var(--sel, …)` and **--sel is defined nowhere in this
   file**, so every device took the fallback — a 24% gold on a gold page, under a 44% scrim. On the
   operator's phone it was invisible. It is now גמרא's own band: `--hasc` at 34%, painted as a
   1.04em gradient strip rather than a padded box, which is what «as we do for the gmara» meant and
   what survives the parchment theme. */
.src .cmhit { --cm-band:color-mix(in srgb, var(--hasc) 34%, transparent);
  background-image:linear-gradient(var(--cm-band), var(--cm-band));
  background-repeat:no-repeat; background-size:100% 1.04em; background-position:center;
  box-decoration-break:clone; -webkit-box-decoration-break:clone; }

/* D-189: the notes a siman's text never pointed at (3.5% of them — no ט״ז is anchored in חושן
   משפט at all). One control, and only on the simanim that have any. */
/* D-191: which סימן and which סעיף this note belongs to — «ס״ק א» alone never said of what. */
.note-ctx { margin:0 0 calc(var(--s-6) * var(--dens)); color:var(--dim); font-size:var(--fs-floor); }
.si-more { margin:calc(var(--s-8) * var(--dens)) 0 0; text-align:center; }
.si-more .btn2 { font-size:var(--fs-cmt); }

/* D-187: the siman's own heading («דין השכמת הבוקר. ובו ט סעיפים:»), which used to render inside
   סעיף א beside its numeral as though it were part of the first se'if. */
.si-head { margin:0 0 calc(var(--s-6) * var(--dens)); font-family:var(--font-src);
  font-size:var(--fs-cmt); color:var(--gold); line-height:var(--lh-ui); }

/* D-219 (TEXT-21, operator 2026-09-30): a ketiv/qere pair as printed chumashim set it - the QERE in
   the line at full size (app.js `sanWalk` drops its [brackets]), the KETIV small and faint beside
   it, keeping its (parentheses). Small = the 16 px floor token: D-203 lets only licences and marks go
   under it, and the ketiv is text a learner reads. The pair is one inline box so the qere always reads first, whatever
   order the Masorah edition's markup has (in some pairs the qere comes first). Colour from the
   token, so every theme follows. */
.mam-kq { display:inline-flex; align-items:baseline; column-gap:.22em; }
.mam-kq-q { order:0; }
.mam-kq-k { order:1; font-size:var(--fs-floor); color:var(--dim); }
