
:root{
  color-scheme:dark;
  --bg:#14101b; --bg-2:#1a1522; --panel:#221e29; --panel-2:#2b2832;
  --line:#34303a; --line-2:#56535b;
  --ink:#ece9ef; --ink-2:#b5b4b7; --ink-3:#8f8d94;
  --accent:#ee851e; --accent-2:#fba621; --accent-wash:rgba(238,133,30,.14);
  --gold:#f6ce6c; --gold-wash:rgba(246,206,108,.13);
  /* the colour of fihrist's name in its own script (.wm-ar); the invocation is it at 75%
     (rtk#339, ilmflow/STANDARD.md §2) */
  --name-ar:color-mix(in srgb,var(--gold) 80%,transparent);
  --teal:#90c6b3; --teal-wash:rgba(144,198,179,.13);
  --red:#ef6f79; --red-deep:#cf3b48; --red-wash:rgba(207,59,72,.17);
  --navy:#1e516a; --navy-wash:rgba(30,81,106,.38);
  --radius:12px; --radius-s:8px;
  --sans:-apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI",Roboto,
   "Helvetica Neue",Arial,sans-serif;
  --mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  --arabic:"SF Arabic","Geeza Pro","Noto Naskh Arabic","Amiri",serif;
}
*{box-sizing:border-box}
html{background:var(--bg)}
body{margin:0;min-height:100vh;display:flex;flex-direction:column;background:var(--bg);
 color:var(--ink);font:16px/1.6 var(--sans);-webkit-font-smoothing:antialiased;
 text-rendering:optimizeLegibility}
::selection{background:rgba(238,133,30,.35)}
:focus-visible{outline:2px solid var(--accent-2);outline-offset:2px}
.ar{font-family:var(--arabic);font-size:1.15em;line-height:2;direction:rtl;unicode-bidi:isolate}
a{color:var(--accent-2);text-decoration:none}
a:hover{text-decoration:underline;text-underline-offset:3px}
/* #388 (tpcs-ui FRAME §1): the frame at most 1360px, as Diwan's and Safina's; prose the tool
   writes is capped apart, at 760px (article.pub, .prose-w) */
.wrap{max-width:1360px;margin:0 auto;padding:0 20px;width:100%}

header{position:sticky;top:0;z-index:5;background:rgba(20,16,27,.86);
 backdrop-filter:saturate(1.4) blur(10px);-webkit-backdrop-filter:saturate(1.4) blur(10px);
 border-bottom:1px solid var(--line)}
/* The shell, two rows: the name and who you are; then the menu. */
.topbar{display:flex;align-items:center;gap:12px;padding:14px 0 8px;flex-wrap:wrap;
  row-gap:8px;position:relative}
.topbar .brand{display:inline-flex;align-items:baseline;gap:10px;font-weight:650;font-size:19px;
 letter-spacing:-.01em;color:var(--ink)}
.topbar .brand img{width:30px;height:30px;display:block;align-self:center}
.topbar .brand small{color:var(--ink-3);font-weight:500;font-size:13px;letter-spacing:0}
.topbar .brand:hover{text-decoration:none;color:var(--accent-2)}
.topbar .sp{flex:1}
/* #71: the same name in Arabic/Farsi at the right edge, gold, in the Naskh face; set a little
   larger than the Latin because Arabic reads visually smaller at the same size. */
.wm-ar{font-family:var(--arabic);color:var(--name-ar);font-weight:500;line-height:1;
 user-select:none;white-space:nowrap}
.topbar .wm-ar{font-size:23px;margin-left:10px}
/* #117: in the BAR the Arabic name is a link home, as the Latin one beside it is, so it
   takes the brand's hover above and NOT the page's `a:hover` underline. diwan's rule is
   the same selector. The lockup's `.wm-ar` is a span and is untouched. */
.topbar a.wm-ar:hover{text-decoration:none;color:var(--accent-2)}
.wordmark{display:flex;justify-content:space-between;align-items:baseline;gap:18px}
.wordmark .wm-ar{font-size:1.12em}
/* #80 the public pages; #388 Help and the changelog, the other prose the tool writes */
article.pub,.prose-w{max-width:760px}
article.pub .lede{font-size:1.1em;color:var(--ink-2)}
article.pub h2{margin-top:28px}
dl.bounds dt{font-weight:650;margin-top:14px} dl.bounds dd{margin:4px 0 0;color:var(--ink-2)}
ul.terms li{margin:8px 0;color:var(--ink-2)} ul.terms li b{color:var(--ink)}
table.roles td:first-child{min-width:240px}
.pub-links{margin-top:28px;font-size:13.5px;display:flex;gap:14px;flex-wrap:wrap}
.pub-links a{color:var(--ink-3)} .pub-links a.on{color:var(--accent-2)}
.signin .pub-links{justify-content:center}
/* #79 the Corpus page */
table.corpus td.author{vertical-align:top;border-right:1px solid var(--line);min-width:150px;
  max-width:220px}
table.corpus:not(.filtering) tr.same td.author{color:transparent;border-top-color:transparent}
table.corpus:not(.filtering) tr.same td.author .ar{color:transparent}
.corpus-filter{display:flex;gap:12px;align-items:center;margin:6px 0 22px}
.corpus-filter input[type=search],.review-filter input[type=search]{flex:1;min-width:0;
  height:50px;padding:10px 18px;font-size:17px;font-family:inherit;color:var(--ink);
  background:var(--panel);border:1px solid var(--line-2);border-radius:10px;
  -webkit-appearance:none;appearance:none}
.corpus-filter input[type=search]::placeholder,
.review-filter input[type=search]::placeholder{color:var(--ink-3)}
.corpus-filter input[type=search]:focus,.review-filter input[type=search]:focus{outline:none;
  border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-wash)}
.corpus-filter [data-corpus-count]{flex:none;color:var(--ink-2);font-size:14.5px;
  min-width:9ch;text-align:right}
@media (max-width:600px){.corpus-filter{flex-direction:column;align-items:stretch;gap:6px}
  .corpus-filter [data-corpus-count]{text-align:left}}
/* #300, 13 Oct 2026: the Reviews search box across the whole width, its button at the
   end of that row, and the filters beneath it. */
.review-filter{display:flex;flex-direction:column;gap:10px;margin:6px 0 22px}
.review-filter .row{display:flex;gap:10px;align-items:center}
.review-filter .row button{flex:none;height:50px;padding:0 24px}
.review-filter .selects{flex-wrap:wrap}
.review-filter .selects select{flex:1 1 170px;min-width:0}
table.corpus td.kind{white-space:nowrap}
table.corpus td{vertical-align:top}
table.corpus .ttl-ar{font-size:1.2em}
details.vols{margin-top:4px} details.vols summary{cursor:pointer;font-size:12.5px}
details.vols a.vol{display:inline-block;margin:2px 6px 0 0;font-size:12.5px}
.warn-t{color:var(--gold)}
.signin .wordmark{text-align:left}
nav{display:flex;gap:4px;align-items:center;flex-wrap:wrap;padding:0 0 8px}
nav a{color:var(--ink-2);font-size:14.5px;font-weight:500;padding:6px 10px;
 border-radius:var(--radius-s)}
nav a:hover{color:var(--ink);background:var(--panel);text-decoration:none}
nav a.on{color:var(--accent-2);background:var(--accent-wash)}
nav a.on:hover{color:var(--accent-2);background:var(--accent-wash)}
/* The generic `details` below is the collapsed 🔴 snippet's (dashed rule, small grey
   summary); the menu is a `details` too and must not inherit that dress. */
details.menu{position:relative;margin:0;border:0;padding:0}
details.menu summary{list-style:none;cursor:pointer;color:var(--ink-2);font-size:14.5px;
 font-weight:500;padding:6px 10px;border-radius:var(--radius-s);user-select:none}
details.menu summary::-webkit-details-marker{display:none}
details.menu summary::after{content:" ▾";color:var(--ink-3);font-size:12px}
details.menu summary:hover,details.menu[open] summary{color:var(--ink);background:var(--panel)}
details.menu.on summary{color:var(--accent-2);background:var(--accent-wash)}
details.menu .dd{position:absolute;top:calc(100% + 4px);left:0;min-width:200px;z-index:6;
 display:flex;flex-direction:column;gap:2px;padding:6px;background:var(--panel);
 border:1px solid var(--line-2);border-radius:12px;box-shadow:0 10px 28px rgba(0,0,0,.4)}
details.menu .dd a{display:block}

main{flex:1;padding:30px 0 60px}
/* rtk#339 (ilmflow/STANDARD.md §2): the invocation, the first line under the header. English:
   14px, medium, letter-spaced, in the colour of the tool's name IN ITS OWN SCRIPT (.wm-ar, the
   token --name-ar) at 75%. Shabbir, 16 Oct 2026: not the Latin name's white. */
.invocation{margin:0 0 18px;font-size:14px;font-weight:500;letter-spacing:.06em;
  color:color-mix(in srgb,var(--name-ar) 75%,transparent)}
h1{font-size:28px;line-height:1.2;margin:0 0 6px;font-weight:650;letter-spacing:-.015em}
h2{font-size:19px;margin:30px 0 12px;font-weight:600;letter-spacing:-.01em}
.sub{color:var(--ink-3);font-size:14.5px;margin:0 0 22px;max-width:70ch}
.crumbs{font-size:13.5px;color:var(--ink-3);margin:0 0 10px}
.crumbs a{color:var(--ink-2)} .crumbs a:hover{color:var(--accent-2)}
.crumbs span{color:var(--ink-3)}
.muted{color:var(--ink-3)}
.mono{font-family:var(--mono);font-size:13px}
/* #337: a command or a config is copied exactly, so it is never wrapped: on a phone it scrolls
   inside its own box rather than widening the page (630px at 390, measured by #334). */
pre.mono{overflow-x:auto;max-width:100%}

form.q{display:flex;gap:10px;flex-wrap:wrap;margin:0 0 20px}
input[type=text],select,form.rec-form textarea{padding:11px 14px;border:1px solid var(--line-2);
 border-radius:10px;background:var(--bg-2);color:var(--ink);font-size:15.5px;font-family:inherit}
input[type=text]{flex:1;min-width:240px}
input[type=text]::placeholder{color:var(--ink-3)}
input[type=text]:focus,select:focus,form.rec-form textarea:focus{border-color:var(--accent);
 outline:none;box-shadow:0 0 0 3px var(--accent-wash)}
label.file{display:inline-flex;align-items:center;padding:11px 18px;border-radius:10px;
 border:1px solid var(--accent);color:var(--accent-2);font-weight:600;font-size:14.5px;
 cursor:pointer;background:transparent}
label.file:hover{background:var(--accent-wash)}
label.file:focus-within{outline:2px solid var(--accent-2);outline-offset:2px}
label.file input{position:absolute;width:1px;height:1px;opacity:0;overflow:hidden}
.file-names{align-self:center;font-size:14px;max-width:48ch;overflow:hidden;
 text-overflow:ellipsis;white-space:nowrap}
select{cursor:pointer}
button{padding:11px 18px;border:0;border-radius:10px;background:var(--accent);color:#1a1208;
 font-size:14.5px;font-weight:650;cursor:pointer;font-family:inherit;letter-spacing:.005em}
button:hover{background:var(--accent-2)}
button.cite{background:transparent;border:1px solid var(--line-2);color:var(--ink-2);
 font-family:var(--mono);font-size:12.5px;font-weight:500;padding:5px 11px;border-radius:7px}
button.cite:hover{border-color:var(--ink-3);color:var(--ink);background:var(--panel-2)}

.controls{display:flex;gap:8px;flex-wrap:wrap;font:12.5px var(--mono);padding:10px 14px;
 background:var(--panel);border:1px solid var(--line);border-radius:var(--radius-s);
 margin:0 0 18px;align-items:center}
.controls b{font-weight:600;color:var(--ink-3);text-transform:uppercase;letter-spacing:.08em;
 font-size:10.5px}
.pill{display:inline-block;padding:2px 9px;border-radius:20px;font-size:12px;font-weight:600;
 border:1px solid transparent;line-height:1.5;white-space:nowrap}
.ok{background:var(--teal-wash);color:var(--teal);border-color:rgba(144,198,179,.35)}
.bad{background:var(--red-wash);color:var(--red);border-color:rgba(207,59,72,.4)}
.warn{background:var(--gold-wash);color:var(--gold);border-color:rgba(246,206,108,.35)}

.hit{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
 padding:15px 18px;margin:0 0 12px}
.hit .locus{display:flex;gap:12px;align-items:baseline;flex-wrap:wrap}
.hit .bk{font-weight:600;font-size:16px}
.hit .meta{font:12.5px var(--mono);color:var(--ink-3)}
.hit .acts{margin-top:10px;display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.hit a.read{font-size:13.5px;font-weight:600;padding:5px 12px;border:1px solid var(--accent);
 border-radius:7px;color:var(--accent-2)}
.hit a.read:hover{background:var(--accent-wash);text-decoration:none}
details{margin-top:12px;border-top:1px dashed var(--line-2);padding-top:10px}
summary{cursor:pointer;font-size:12.5px;color:var(--ink-3)}
summary:hover{color:var(--ink-2)}
details .snip{margin-top:10px;padding:12px 14px;background:var(--red-wash);
 border-left:3px solid var(--red-deep);border-radius:0 var(--radius-s) var(--radius-s) 0}
details .snip.snip-clean{background:var(--teal-wash);border-left-color:var(--teal)}
.zero{background:var(--panel);border:1px solid rgba(207,59,72,.45);
 border-left:4px solid var(--red-deep);
 border-radius:0 var(--radius) var(--radius) 0;padding:18px 20px}
.zero h2{margin:0 0 8px;color:var(--red);font-size:17px}
.zero code{background:var(--red-wash);padding:1px 6px;border-radius:4px;font-size:13px}

.tw{overflow-x:auto;border-radius:var(--radius)}
table{border-collapse:separate;border-spacing:0;width:100%;background:var(--panel);
 border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;font-size:14px}
th,td{text-align:left;padding:10px 14px;border-bottom:1px solid var(--line);vertical-align:top;
 overflow-wrap:anywhere}
th{font:600 10.5px var(--mono);text-transform:uppercase;letter-spacing:.08em;color:var(--ink-3);
 background:var(--bg-2);white-space:nowrap}
tr:last-child td{border-bottom:0}
td.n{text-align:right;font-family:var(--mono);font-variant-numeric:tabular-nums;
 white-space:nowrap}
.page-img{max-width:100%;height:auto;border:1px solid var(--line-2);border-radius:var(--radius);
 background:#fff;display:block;margin:0 auto;box-shadow:0 10px 40px rgba(0,0,0,.45)}
.pager{display:flex;gap:14px;align-items:center;justify-content:center;margin:18px 0;flex-wrap:wrap}
/* #364: a line boxed on the page image, and the words chosen to correct */
.box-host{position:relative;width:fit-content;max-width:100%;margin:0 auto}
.box-host .page-img{touch-action:none;user-select:none;-webkit-user-drag:none;cursor:crosshair}
.box-mark{position:absolute;border:2px solid var(--accent);background:var(--accent-wash);
 pointer-events:none;border-radius:2px}
details.correct{margin:18px 0;border:1px solid var(--line);border-radius:var(--radius);
 padding:10px 14px}
details.correct summary{cursor:pointer;font-weight:600}
.record-notes{margin-top:18px;padding-top:6px;border-top:1px solid var(--line)}
.record-notes h2{font-size:.85em;color:var(--muted,inherit);margin:0 0 6px}
.correct-words{line-height:2.1;font-size:1.1em;margin:10px 0}
.correct-words p{margin:0 0 4px}
.correct-words button.cw{font:inherit;color:inherit;background:none;border:0;padding:0 2px;
 border-radius:3px;cursor:pointer}
.correct-words button.cw:hover{background:var(--line)}
.correct-words button.cw.fixed{background:var(--teal-wash)}
.correct-words button.cw.chosen{background:var(--accent-wash);outline:1px solid var(--accent)}
.inline-form{display:inline-flex;gap:6px;align-items:center;margin-inline-start:8px}
/* #220: image and text side by side, to compare line by line before promoting */
.compare-text mark.disputed{background:var(--accent-wash);color:var(--ink);
 border-bottom:2px solid var(--accent);padding:0 2px;border-radius:3px}
/* #321: a word a person corrected against the page image */
.compare-text mark.corrected{background:var(--teal-wash);color:var(--ink);
 border-bottom:2px solid var(--teal);padding:0 2px;border-radius:3px}
.compare{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:18px;align-items:start}
.compare .page-img{width:100%;margin:0}
/* The header is sticky too, and as tall as its rows wrap to: the shell's script measures it
   into --head-h, and the fallback errs LOW on the page, never under the header. */
.compare-text{position:sticky;top:calc(var(--head-h,130px) + 12px)}
pre.page-text .ln{display:block;min-height:1lh}
pre.page-text:not(.ar){font-family:var(--sans)}
.compare-text pre{white-space:pre-wrap;overflow-wrap:anywhere;
 max-height:calc(100vh - var(--head-h,130px) - 64px);
 overflow:auto;margin:6px 0 0;padding:14px;font-size:1.12rem;line-height:1.95;
 border:1px solid var(--line-2);border-radius:var(--radius)}
@media (max-width:900px){.compare{grid-template-columns:1fr}.compare-text{position:static}
 .compare-text pre{max-height:none}}
/* #203: the pager's box -- type a number, inside the book */
.pager form.goto{display:flex;gap:8px;align-items:center;margin:0}
.pager form.goto label{display:flex;gap:8px;align-items:center;color:var(--ink-2)}
.pager input[type=number],.pager form.goto input[type=text]{flex:none;min-width:0;width:6.5em;
 padding:8px 10px;border:1px solid var(--line-2);border-radius:10px;background:var(--bg-2);
 color:var(--ink);font:15px var(--mono)}
.pager input[type=number]:focus,.pager form.goto input[type=text]:focus{border-color:var(--accent);
 outline:none;box-shadow:0 0 0 3px var(--accent-wash)}
.pager form.goto button{padding:8px 14px}
/* #129: the honorific review -- the page beside the sentence, the model's glyph marked */
.hon-work{margin:26px 0}
.hon-page{border:1px solid var(--line);border-radius:var(--radius);background:var(--panel);
 padding:14px 16px;margin:14px 0;display:grid;gap:10px}
.hon-page.done{border-color:var(--line-2)}
.hon-excerpt{font-size:1.15rem;line-height:2;background:var(--bg-2);border-radius:8px;
 padding:10px 14px}
.hon-excerpt mark{background:var(--accent-wash);color:var(--accent);padding:0 4px;
 border-radius:4px;font-weight:600}
.hon-decide{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.hon-decide button.quiet{background:transparent;border:1px solid var(--line-2);color:var(--ink-2)}
.hon-decide input[type=text]{flex:1;min-width:180px}
.release{border-top:1px solid var(--line);padding:18px 0 6px;margin-top:10px}
.release-head{display:flex;gap:12px;align-items:center;flex-wrap:wrap}
.release-head h2{margin:0}
.release h3{margin:18px 0 6px;font-size:16px;color:var(--ink-2)}
.changes{margin:6px 0 10px;padding-left:22px}
.changes li{margin:6px 0;line-height:1.55}
.release.unreleased{opacity:.85}
.note{padding:13px 16px;border-radius:0 var(--radius-s) var(--radius-s) 0;margin:0 0 18px;
 font-size:14.5px;border-left:3px solid}
.note.r{background:var(--red-wash);border-color:var(--red-deep)}
.note.a{background:var(--gold-wash);border-color:var(--gold)}
.note.g{background:var(--teal-wash);border-color:var(--teal)}
.note.i{background:var(--navy-wash);border-color:var(--navy)}

.hero{display:flex;gap:28px;align-items:center;margin:6px 0 30px;flex-wrap:wrap}
.hero img{width:104px;height:104px;flex:none;filter:drop-shadow(0 8px 24px rgba(238,133,30,.25))}
.hero h1{font-size:34px;margin:0 0 4px}
.hero .sub{margin:0 0 16px}
.hero form.q{margin:0}
.hero > div{flex:1;min-width:280px}
.tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;
 margin:0 0 22px}
.tile{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
 padding:14px 16px;display:flex;flex-direction:column;gap:2px}
.tile b{font-size:26px;font-weight:650;letter-spacing:-.02em;font-variant-numeric:tabular-nums;
 line-height:1.15}
.tile span{font-size:12.5px;color:var(--ink-3)}
.tile.ok b{color:var(--teal)} .tile.degraded b{color:var(--gold)} .tile.down b{color:var(--red)}
.cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:12px}
.col{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
 padding:14px 16px}
.col .ttl{display:flex;justify-content:space-between;gap:10px;align-items:baseline}
.col .ttl b{font-size:15.5px;font-weight:600}
.col .ttl span{font:12px var(--mono);color:var(--ink-3)}
.col.empty{opacity:.6}
.bar{height:8px;background:var(--bg-2);border:1px solid var(--line);border-radius:6px;
 overflow:hidden;margin:10px 0 8px}
.bar i{display:block;height:100%;background:linear-gradient(90deg,var(--accent),var(--accent-2));
 border-radius:6px}
.chips{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px}
.chip{font-size:11.5px;padding:2px 8px;border-radius:20px;background:var(--bg-2);
 border:1px solid var(--line);color:var(--ink-2)}
.grades{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px}
.grade{display:flex;gap:12px;background:var(--panel);border:1px solid var(--line);
 border-radius:var(--radius);padding:14px 16px;align-items:flex-start}
.grade .mk{font-size:22px;line-height:1.1}
.grade b{display:block;font-size:15px}
.grade .n{font:600 20px var(--sans);letter-spacing:-.02em;margin-left:auto;
 font-variant-numeric:tabular-nums;color:var(--ink-2)}
.grade p{margin:3px 0 0;font-size:13px;color:var(--ink-3)}
.kv{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:10px 24px;
 font-size:14px}
.kv div{display:flex;justify-content:space-between;gap:12px;padding:8px 0;
 border-bottom:1px solid var(--line)}
.kv div span:first-child{color:var(--ink-3)}
.shelf{margin:26px 0 0}
.shelf-head{display:flex;justify-content:space-between;gap:16px;align-items:flex-end;flex-wrap:wrap}
.shelf-head h2{margin:0 0 4px}
.shelf .bar{margin:10px 0 12px}
table.books td:first-child{max-width:520px}
.dot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:6px;
 vertical-align:middle;background:var(--ink-3)}
.dot.ok{background:var(--teal)} .dot.bad{background:var(--red-deep)}
.group{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
 margin:0 0 14px;overflow:hidden}
.group-head{padding:12px 18px;border-bottom:1px solid var(--line);display:flex;
 justify-content:space-between;gap:12px;flex-wrap:wrap;align-items:baseline;
 background:var(--bg-2)}
.group-head .locus{display:flex;gap:12px;align-items:baseline;flex-wrap:wrap}
.group-head a.bk{font-weight:600;font-size:16px;color:var(--ink)}
.group-head a.bk:hover{color:var(--accent-2)}
.group-head .meta{font:12.5px var(--mono);color:var(--ink-3)}
.group-body .hit{border:0;border-radius:0;border-top:1px solid var(--line);margin:0;
 background:transparent;padding:12px 18px}
.group-body .hit:first-child{border-top:0}
ol.steps{padding-left:22px;display:grid;gap:14px;max-width:80ch}
ol.steps li{padding-left:6px}
ol.steps ul{margin:8px 0 0;padding-left:18px;color:var(--ink-2)}
ol.steps ul li{margin:4px 0}
table.help td:first-child{max-width:320px;color:var(--ink-2)}
code{font-family:var(--mono);font-size:.92em;background:var(--bg-2);padding:1px 5px;
 border-radius:4px}
.ttl-ar{font-size:1.05em;color:var(--gold);line-height:1.6}
.ttl-ar.big{font-size:26px;line-height:1.7;margin:2px 0 6px}
.ttl-en-ai{font-size:.9em;color:var(--ink-3);margin-top:2px}
.rec-form .confirm{display:block;font-size:12px;color:var(--ink-3);margin-top:2px}
.ttl-en-ai .ai-tag{font-size:11px;border:1px solid var(--line);border-radius:4px;padding:0 4px;
  margin-inline-start:6px;white-space:nowrap}
.titles{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
 padding:14px 18px;margin:8px 0 16px}
.titles .about{margin:8px 0;color:var(--ink-2);max-width:80ch}
.ttl-lines{display:grid;gap:4px;font-size:15px}
/* #301: a book's record, edited on its page. The fields in columns that fold to one on a phone.
   Its own class names: `.record` is the reading surface of a digital record (pre-wrap, padded). */
details.rec-edit{margin:0 0 16px;border:1px solid var(--line);border-radius:var(--radius);
 padding:12px 16px;background:var(--panel)}
details.rec-edit summary{font-size:14.5px;color:var(--accent-2);font-weight:600}
.rec-say{font-size:13px;margin:10px 0 0;max-width:80ch}
form.rec-form{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,260px),1fr));
 gap:12px 16px;margin-top:12px}
form.rec-form label{display:grid;gap:5px;font-size:13px;color:var(--ink-2);min-width:0}
form.rec-form input[type=text]{min-width:0;width:100%;box-sizing:border-box}
form.rec-form label > select{min-width:0;width:100%;box-sizing:border-box}
form.rec-form textarea{min-width:0;width:100%;box-sizing:border-box;line-height:1.5;resize:vertical}
.titles .about-by{display:block;font-size:12px;color:var(--ink-3);margin-top:4px}
form.rec-form .year{display:flex;gap:8px;min-width:0}
/* #388: at 1360px the form takes a fourth column, and the year box fell to 118px: never below
   the frame's 120 (FRAME §11's BOX) */
form.rec-form .year input{flex:1 1 6em;min-width:120px}
form.rec-form .year select{flex:1 1 9em;min-width:0}
form.rec-form .wide,form.rec-form .acts{grid-column:1/-1}
form.rec-form .acts{display:flex;gap:12px;align-items:center;flex-wrap:wrap}
details.record-hist{margin:0 0 16px}
details.record-hist ol{margin:8px 0 0;padding-left:22px;font-size:13.5px}
details.record-hist li{margin:5px 0}
details.record-hist .was{color:var(--ink-3);text-decoration:line-through}
form.inline{display:inline;margin:0}
form.notepick{align-items:center;gap:10px}
form.notepick select{flex:1;min-width:240px;max-width:520px}
form.notenew input[type=date]{color-scheme:dark}
input[type=date]{padding:10px 12px;border:1px solid var(--line-2);border-radius:10px;
 background:var(--bg-2);color:var(--ink);font-family:inherit;font-size:14.5px}
.editor{display:grid;gap:10px;margin:0 0 8px}
.editor .row{display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.editor .row input[type=text]{flex:1;min-width:160px}
.editor textarea{width:100%;min-height:46vh;padding:14px 16px;border:1px solid var(--line-2);
 border-radius:10px;background:var(--bg-2);color:var(--ink);font:15.5px/1.65 var(--sans);
 resize:vertical}
.editor textarea:focus{border-color:var(--accent);outline:none;
 box-shadow:0 0 0 3px var(--accent-wash)}
.note-body{white-space:pre-wrap;background:var(--panel);border:1px solid var(--line);
 border-radius:var(--radius);padding:18px 20px;line-height:1.7;font-size:15.5px;max-width:80ch}
.snip-note{font-size:14px;color:var(--ink-2)}
button[disabled]{opacity:.45;cursor:not-allowed}
.glyph{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
 padding:16px 18px;margin:0 0 14px}
.glyph.done{border-color:rgba(144,198,179,.45)}
.glyph-head{display:flex;gap:26px;align-items:center;flex-wrap:wrap}
.glyph-img{image-rendering:pixelated;background:var(--bg);border:1px solid var(--line-2);
 border-radius:8px;padding:8px;max-width:220px;height:auto}
.big-char{font-size:64px;line-height:1.1;color:var(--gold)}
.glyph-assigned{min-width:120px;text-align:center}
.glyph-stats{display:grid;gap:4px;font-size:14px}
.strip{margin:12px 0 0;padding:8px 0 0;border-top:1px dashed var(--line)}
.strip img{image-rendering:pixelated;max-width:100%;height:auto;background:var(--bg);
 border-radius:6px;padding:4px}
.strip-meta{font-size:13px;margin-top:4px;color:var(--ink-2)}
form.decide{display:flex;gap:14px;flex-wrap:wrap;align-items:center;margin-top:12px;
 padding-top:12px;border-top:1px solid var(--line)}
form.decide label{display:inline-flex;flex-wrap:wrap;gap:6px;align-items:center;font-size:14.5px;
 max-width:100%}
form.decide .charbox{width:5em;padding:6px 8px;font-size:20px;text-align:center}
form.decide .note{flex:1;min-width:min(160px,100%)}
/* #84 the reading surface for digital text: the record by its structure */
@font-face{font-family:"Amiri";src:url(/static/Amiri-Regular.ttf?v=ab391c4147d0) format("truetype");
  font-weight:400;font-display:swap}
@font-face{font-family:"Amiri";src:url(/static/Amiri-Bold.ttf?v=cfccb794268e) format("truetype");
  font-weight:700;font-display:swap}
@font-face{font-family:"Amiri Quran";src:url(/static/AmiriQuran-Regular.ttf?v=e2a47644762d) format("truetype");
  font-display:swap}
@font-face{font-family:"Vazirmatn";src:url(/static/Vazirmatn.ttf?v=696249a2c74b) format("truetype");
  font-weight:100 900;font-display:swap}
.reading{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:26px 32px 30px;max-width:1080px;margin:0 auto 16px}
@media (max-width:600px){.reading{padding:16px 14px 20px}}
.reading .rec-head{display:flex;gap:10px;flex-wrap:wrap;align-items:center;
  margin:0 0 18px;padding-bottom:12px;border-bottom:1px solid var(--line);font-size:13.5px;
  color:var(--ink-2)}
.reading .crumb+.crumb::before{content:"›";margin-right:10px;color:var(--ink-3)}
.reading .pill.grading{background:var(--accent-wash);color:var(--accent-2)}
.reading .verses{font-family:"Amiri Quran","Amiri",var(--arabic);font-size:26px;line-height:2.3;
  text-align:justify;text-align-last:right;margin:6px 0 22px;color:var(--ink)}
.reading .verses .ayah{color:var(--accent-2);font-size:.85em}
.reading .verses .cont{display:inline-block;font-family:"Amiri",var(--arabic);font-size:14px;
  color:var(--ink-3);border:1px solid var(--line);border-radius:6px;padding:0 8px;
  margin-left:12px;vertical-align:middle;line-height:1.8}
.reading .rec-title{margin:6px 0 14px;font-size:22px;line-height:1.7}
.reading .rec-title.ar,.reading .rec-title.fa{font-family:"Amiri",var(--arabic);font-size:26px}
.reading .rec-title.fa{font-family:"Vazirmatn","Amiri",var(--arabic)}
.reading .rec-sub{margin:18px 0 8px;font-size:16px;color:var(--ink-2)}
.reading .pair{display:grid;gap:22px 36px;margin:0 0 18px;grid-template-columns:1fr}
@media (min-width:900px){.reading .pair.cols-2{grid-template-columns:1.15fr 1fr}
  .reading .pair.cols-3{grid-template-columns:1.15fr 1fr 1fr}
  .reading .pair.cols-4,.reading .pair.cols-5,.reading .pair.cols-6{
    grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}}
.reading .col p{margin:0 0 .9em}
.reading .col.arabic{font-family:"Amiri",var(--arabic);font-size:21px;line-height:2.05;
  text-align:justify}
.reading .col.persian{font-family:"Vazirmatn","Amiri",var(--arabic);font-size:19px;
  line-height:2.05;text-align:justify}
.reading .col.english,.reading .col.translation,.reading .col.transliteration{font-size:16.5px;
  line-height:1.75;color:var(--ink-2)}
.reading .col.english p{color:var(--ink)}
.reading .col.transliteration{font-style:italic}
.reading .col .sec{font-family:"Amiri",var(--arabic);font-size:19px;color:var(--accent-2);
  margin:4px 0 10px;font-weight:700}
.reading .col .who{display:inline-block;font-size:12px;color:var(--ink-3);
  text-transform:uppercase;letter-spacing:.06em;margin-bottom:4px}
.record{white-space:pre-wrap;background:var(--panel);border:1px solid var(--line);
 border-radius:var(--radius);padding:22px 26px;font-size:17px;line-height:1.9;max-width:90ch;
 margin:0 auto 16px;unicode-bidi:plaintext}
footer{border-top:1px solid var(--line);background:var(--bg-2);padding:26px 0 30px;
 font-size:14px;color:var(--ink-2)}
footer .foot-row{display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;
 align-items:center}
footer .foot-who{display:flex;gap:10px;flex-wrap:wrap;align-items:center}
footer .foot-dev,footer .foot-dev a{display:inline-flex;align-items:center;gap:8px}
footer .foot-dev img{width:20px;height:20px;border-radius:4px;display:block}
footer a{color:var(--ink-2)}
footer a b{color:var(--ink);font-weight:600}
footer a:hover{color:var(--accent-2);text-decoration:none}
footer a:hover b{color:var(--accent-2)}
footer .foot-line{display:flex;gap:10px;flex-wrap:wrap;margin-top:14px;font-size:12.5px;
 color:var(--ink-3);align-items:center}
footer .foot-line a{color:var(--ink-3)}
@media (max-width:600px){
  h1{font-size:24px} main{padding:22px 0 44px}
  nav .brand span{display:none}
  footer .foot-row{flex-direction:column;align-items:flex-start}
}
/* sign-in (#57) */
.topbar form.signout{display:inline;margin:0}
.topbar form.signout button{padding:6px 12px;font-size:.85rem;background:transparent;
  border:1px solid var(--line-2);color:var(--ink-2);border-radius:8px}
.topbar form.signout button:hover{border-color:var(--ink-3);color:var(--ink);
  background:var(--panel-2)}
.topbar .who{color:var(--ink-3);font-size:.85rem;margin-right:6px}
.topbar .who b{color:var(--ink-2);font-weight:500}

/* ------------------------------------------- #120: the DEVELOPMENT mark, one family spec.
   Built to match diwan PR #21 so fihrist, daftar, diwan and the website wear one mark: amber
   #f59e0b on #1a1204, the bar tinted dark amber with an amber hairline, and the warning on
   its OWN ROW under the brand -- inline it wrapped badly at middle widths.
   🔴 It shows for `development` AND `unknown` (labels.environment). A production box wearing
   the badge is embarrassing and safe; a dev box that looks like production is how a wrong
   citation gets copied -- and dev's index carries an invented folio on all 69,160 hawza
   pages, measured 25 Sep 2026. */
header.dev{background:rgba(41,29,12,.9);border-bottom-color:rgba(245,158,11,.42)}
.devbadge{display:inline-block;background:#f59e0b;color:#1a1204;font:700 11px/1 var(--mono);
  letter-spacing:.08em;padding:5px 8px;border-radius:6px;white-space:nowrap}
.devline{color:#f7b955;font-size:12.5px;line-height:1.4;padding:0 0 8px}
.noticebar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin:0 0 8px;
  padding:8px 12px;border:1px solid var(--red);border-radius:10px;background:var(--red-wash);
  color:var(--ink);font-size:14px}
.noticebar p{margin:0;flex:1 1 20ch;min-width:0;overflow-wrap:anywhere}
.noticebar form{margin:0}
.others{margin:22px 0 0}
.others>summary{cursor:pointer;font-weight:650;font-size:17px}
.others .warn-admin{color:var(--red);font-size:13px}
.revoke-other{display:grid;gap:6px;min-width:0}
.revoke-other input[type=text]{width:100%}

/* ------------------------------------------- #121: the phone menu, ≤640px.
   📏 At 360px the signed-in header was 205px -- 26% of the screen -- with the bar wrapped to
   FOUR rows, and the Admin dropdown opened at right:438 on a 360px viewport, putting five
   links off the side where nothing said they were there. One row and one panel fixes both.
   `<details>` because the Admin menu is already one: no script, keyboard-operable free. */
/* 🔴 The panel anchors to the BAR, not to the button. Measured at 360px with the
   button relative: the panel is 280px wide but the ☰ sits at right:274 because the
   Arabic name follows it, so `right:0` put the panel's LEFT edge at -6 -- six pixels
   off the screen. That is the same fault this ticket exists to fix, reintroduced one
   element along. `.topbar` is the containing block, so right:0 is the bar's edge. */
.mnav{display:none;position:static;margin:0;border:0;padding:0}
.mnav>summary{list-style:none;cursor:pointer;width:40px;height:40px;display:flex;
  align-items:center;justify-content:center;border:1px solid var(--line-2);
  border-radius:10px;color:var(--ink-2)}
.mnav>summary::-webkit-details-marker{display:none}
.mnav>summary:hover,.mnav[open]>summary{color:var(--ink);background:var(--panel)}
.mnav .panel{position:absolute;right:0;top:calc(100% + 4px);width:min(280px,100%);z-index:7;
  background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:8px;
  box-shadow:0 12px 32px rgba(0,0,0,.45)}
.mnav .panel a{display:block;padding:10px 12px;border-radius:var(--radius-s);
  color:var(--ink-2);font-size:15px}
.mnav .panel a:hover{color:var(--ink);background:var(--panel-2);text-decoration:none}
.mnav .panel a.on{color:var(--accent-2);background:var(--accent-wash)}
.mnav .panel .grp{display:block;color:var(--ink-3);font-size:12px;letter-spacing:.04em;
  padding:10px 12px 2px}
.mnav .panel hr{border:0;border-top:1px solid var(--line);margin:8px 0}
/* ⚠️ An email address is one unbroken word. Measured at 360px, a 17-character one was
   137px wide and ran 43px past the 280px panel -- invisible only because the panel was
   shut. `anywhere` also shrinks the min-content width, which is what stops it.
   🔴 And note what caught the first draft of THIS COMMENT: it quoted the address, and the
   stylesheet is inlined into every page, so a public page suddenly "named a member" --
   `test_the_public_pages_answer_a_stranger_and_give_nothing_away` failed on a comment.
   Whatever is written here SHIPS. No addresses, no names, no hosts. */
.mnav .panel .who{display:block;margin:0;padding:2px 12px 10px;font-size:.85rem;
  overflow-wrap:anywhere}
/* ⚠️ the BAR's Sign out is `display:inline`; the panel's copy must be a block or the button
   spills out of the panel. Same trap diwan hit -- its PR flags it for exactly this reason. */
.mnav .panel form.signout{display:block;margin:0}
.mnav .panel form.signout button{width:100%}

/* #388 (tpcs-ui FRAME §3, Shabbir 15 Oct 2026): the menu button at 900px and below, as Diwan's and
   Safina's. 📏 22 Oct 2026, at 640: with Connect your AI and Review ▾ in the row, an admin's row 2
   wrapped at 768 and spilled to 852px. */
@media (max-width:900px){
  /* one row, no wrapping: brand · badge · spacer · ☰ · the Arabic name, still hard right */
  .topbar{flex-wrap:nowrap;gap:8px}
  .topbar .brand small{display:none}
  /* 🔴 `span.who` and the sign-out FORM only. A stranger's Sign in is `a.who` and must
     stay -- there is no menu for them to find it in, because the menu needs a member. */
  .topbar span.who,.topbar form.signout{display:none}
  header nav{display:none}
  .mnav{display:block}
}
.signin{max-width:520px;margin:8vh auto 0;text-align:center}
.signin img{width:72px;height:72px;margin-bottom:12px}
.signin h1{margin:0 0 6px}
.signin p{color:var(--ink-2)}
.signin .go,article.pub .go{display:inline-block;margin-top:18px;padding:13px 24px;
  border-radius:12px;background:var(--accent);color:#1a1208;font-weight:600;
  text-decoration:none}
.signin .go:hover,article.pub .go:hover{background:var(--accent-2)}
.signin .fine,article.pub .fine{color:var(--ink-3);font-size:.9rem;margin-top:22px}
table.people{width:100%;border-collapse:collapse;margin:14px 0}
table.people th,table.people td{padding:9px 10px;border-bottom:1px solid var(--line);
  text-align:left;vertical-align:middle;font-size:.95rem}
table.people th{color:var(--ink-3);font-weight:500}
/* #349: the reading queue, one card a book, so a phone never squeezes a title */
ol.queue{list-style:none;padding:0;margin:14px 0}
ol.queue li{border:1px solid var(--line);border-radius:var(--radius);padding:12px 14px;
  margin:0 0 10px}
.qh{display:flex;gap:10px;align-items:baseline}
.qh a{overflow-wrap:anywhere}
.qn{font-weight:600;min-width:1.5em}
.qm{color:var(--ink-3);font-size:.9rem;margin:6px 0 0;overflow-wrap:anywhere}
.moves{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
details.backlog{margin:22px 0}details.backlog>summary{cursor:pointer;font-weight:600;padding:6px 0}
table.people tr.off td{color:var(--ink-3)}
table.people form{display:inline;margin:0 4px 0 0}
table.people form button,table.people form select{padding:6px 10px;font-size:.85rem}
table.people form button.quiet{background:transparent;border:1px solid var(--line-2);
  color:var(--ink-2)}
/* #119: THE ACTION CELL TAKES THE WIDTH ITS BUTTON NEEDS AND NEVER WRAPS. The table is
   `width:100%` with seven auto columns, so a long name in the first one starves the last:
   📏 measured on a hostile token name, "Revoke" broke across TWO lines at 1280px and SIX at
   360px, in a 35px-wide button. `width:1%` is the table-layout idiom for shrink-to-fit --
   the row's other columns absorb the rest. */
table.people td.act{white-space:nowrap;width:1%;text-align:right}
/* ...and a long UNBROKEN name (a pasted id) breaks inside its own cell instead of widening
   the table past the screen. 📏 #120 settled this as `break-word` and not `anywhere` for the
   whole family: `anywhere` also shrinks the cell's min-content width, which reads as an
   over-eager break on ordinary text, and the card layout below is what actually keeps a
   phone honest. The `.tw` wrapper carries the rest. */
table.people td{overflow-wrap:break-word}
/* #205: THE JOBS TABLE, the same starvation. 📏 Seen on prod at ~1,565px, 2 Oct 2026: "nightly"
   broken into two-letter lines and the start date over three, while the progress column, empty
   on most rows, took half the width -- the global `overflow-wrap:anywhere` lets every cell
   shrink to a character. The short columns keep their words and shrink to fit; the collection
   and the progress share the rest. */
table.jobs td{overflow-wrap:break-word}
table.jobs td.id,table.jobs td.k,table.jobs td.st,table.jobs td.t{white-space:nowrap;width:1%}
table.jobs td.prog{white-space:normal}   /* an OCR job's activity may wrap */

/* ------------------------------------------- #120: a token is a CARD on a phone.
   🔴 WHY CARDS AND NOT A SCROLLING TABLE, which is what #119 shipped and measured working:
   in a table that scrolls sideways the column that falls off-screen is the LAST one, and
   here that column is **Revoke**. Revoking is the phone case above all -- a lost laptop, a
   token pasted where it should not be -- and a control behind a horizontal scroll that
   nothing signals is one a person can fail to find at the moment they need it. #119's
   measurement stands; this is a change of approach, not a finding against it.
   The pattern is diwan 0.3.0's, so someone moving between the three sites meets one shape. */
table.tokens td.name{width:99%}
table.tokens td.mono,table.tokens td[data-label="made"],
table.tokens td[data-label="last used"]{white-space:nowrap}

@media (max-width:640px){
  /* the header row goes: a card carries its own captions, one per value */
  table.tokens tr:first-child{position:absolute;width:1px;height:1px;overflow:hidden;
    clip-path:inset(50%);white-space:nowrap}
  table.tokens tr{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:2px 10px;
    padding:12px 0;border-bottom:1px solid var(--line)}
  table.tokens td{border:0;padding:2px 0}
  /* the name and the button share the first line, so Revoke is never below the fold of a
     card and never off the side of one */
  table.tokens td.name{grid-row:1;grid-column:1;width:auto}
  table.tokens td.act{grid-row:1;grid-column:2;text-align:right;width:auto}
  table.tokens td:not(.name):not(.act){grid-column:1/-1;white-space:normal}
  table.tokens td:not(.name):not(.act)::before{content:attr(data-label);display:block;
    font:10.5px/1.6 var(--mono);text-transform:uppercase;letter-spacing:.06em;
    color:var(--ink-3)}
}
form.addmember{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin:10px 0 22px}
form.addmember input[type=text]{min-width:280px}
form.secfilter{display:flex;flex-wrap:wrap;gap:8px 16px;align-items:center;margin:12px 0}
table.security td{vertical-align:top}
table.security td.mono{white-space:nowrap;color:var(--ink-3)}

/* #335 (tpcs-ui FRAME §5): the security policy forbids style attributes, so what were inline
   styles are these classes. `!important` keeps exactly the priority an inline style had. */
.u-dinline{display:inline !important}
.u-fs_95em{font-size:.95em !important}
.u-fs11_5{font-size:11.5px !important}
.u-fs12_5{font-size:12.5px !important}
.u-fs12{font-size:12px !important}
.u-fs13_5{font-size:13.5px !important}
.u-fs13{font-size:13px !important}
.u-fs13-mt6{font-size:13px !important;margin-top:6px !important}
.u-fs16{font-size:16px !important}
.u-mt20{margin-top:20px !important}
.u-mt5{margin-top:5px !important}
.u-mt6{margin-top:6px !important}
.u-mt7{margin-top:7px !important}
.u-mt9{margin-top:9px !important}
.u-m0{margin:0 !important}
.u-m10-0-0{margin:10px 0 0 !important}
.u-m6-0-0-pl20{margin:6px 0 0 !important;padding-left:20px !important}
.u-m6-0-14{margin:6px 0 14px !important}
.u-minw96-fs12_5{min-width:96px !important;font-size:12.5px !important}
/* #257: the partners' book finder, moved out of its own <style> block (#335) */
.find-q{width:100%;max-width:680px;font-size:17px;padding:12px 14px;border-radius:var(--radius);
  border:1px solid var(--line-2);background:var(--panel);color:var(--ink)}
.find-q:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.fw{display:grid;gap:12px;margin:16px 0 28px}
.fw article{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:14px 16px;display:grid;gap:6px;min-width:0}
.fw .who{color:var(--ink-2)}
.fw .vols{display:flex;flex-wrap:wrap;gap:6px 16px;font-size:14px}
.fw .vols span{display:inline-flex;gap:6px;align-items:center}
.lv{display:inline-grid;place-items:center;min-width:1.6em;height:1.6em;padding:0 5px;
  border-radius:5px;font-weight:700;font-size:12px}
.lv-A{background:var(--teal-wash);color:var(--teal)}
.lv-B{background:var(--gold-wash);color:var(--gold)}
.lv-C{background:var(--red-wash);color:var(--red)}
.lv-D{background:var(--accent-wash);color:var(--accent)}
.lv-digital,.lv-unchecked{background:var(--bg-2);color:var(--ink-3)}
.fa{font-family:var(--arabic);direction:rtl}
.legend td{vertical-align:top}
/* #516: the uploads not yet filed, listed inside their one Home card */
details.uploads summary{cursor:pointer;color:var(--ink-2)}
details.uploads ul{margin:6px 0 8px;padding-left:18px}
details.uploads li{margin:2px 0}
/* #513: the page asked for is on its way (fihrist.js). A bar along the top, a line saying what
   is loading, and the page it is leaving dimmed, so a long wait never looks like a frozen site. */
.busy-bar{position:fixed;top:0;left:0;right:0;height:3px;z-index:20;overflow:hidden;
  background:var(--accent-wash)}
.busy-bar::before{content:"";position:absolute;top:0;bottom:0;width:40%;
  background:linear-gradient(90deg,transparent,var(--accent-2),transparent);
  animation:busy-slide 1.1s ease-in-out infinite}
@keyframes busy-slide{from{left:-40%}to{left:100%}}
/* centred by margins, not `left:50%` + a transform, which caps it at HALF a phone's width */
.busy-say{position:fixed;left:0;right:0;bottom:22px;margin:0 auto;z-index:20;
  width:max-content;max-width:calc(100% - 32px);display:flex;flex-wrap:wrap;gap:4px 10px;
  align-items:center;padding:10px 16px;
  background:var(--panel-2);border:1px solid var(--line-2);border-radius:18px;
  box-shadow:0 10px 28px rgba(0,0,0,.45);color:var(--ink);font-size:14.5px}
.busy-say::before{content:"";flex:none;width:14px;height:14px;border-radius:50%;
  border:2px solid var(--line-2);border-top-color:var(--accent-2);
  animation:busy-spin .8s linear infinite}
.busy-say small{color:var(--ink-3);font-size:13px}
@keyframes busy-spin{to{transform:rotate(360deg)}}
body.busy main{opacity:.55;transition:opacity .2s}
@media (prefers-reduced-motion:reduce){
  .busy-bar::before{animation:none;left:0;width:100%;opacity:.6}
  .busy-say::before{animation:none}
}
.w-0{width:0%}.w-1{width:1%}.w-2{width:2%}.w-3{width:3%}.w-4{width:4%}.w-5{width:5%}.w-6{width:6%}.w-7{width:7%}.w-8{width:8%}.w-9{width:9%}.w-10{width:10%}.w-11{width:11%}.w-12{width:12%}.w-13{width:13%}.w-14{width:14%}.w-15{width:15%}.w-16{width:16%}.w-17{width:17%}.w-18{width:18%}.w-19{width:19%}.w-20{width:20%}.w-21{width:21%}.w-22{width:22%}.w-23{width:23%}.w-24{width:24%}.w-25{width:25%}.w-26{width:26%}.w-27{width:27%}.w-28{width:28%}.w-29{width:29%}.w-30{width:30%}.w-31{width:31%}.w-32{width:32%}.w-33{width:33%}.w-34{width:34%}.w-35{width:35%}.w-36{width:36%}.w-37{width:37%}.w-38{width:38%}.w-39{width:39%}.w-40{width:40%}.w-41{width:41%}.w-42{width:42%}.w-43{width:43%}.w-44{width:44%}.w-45{width:45%}.w-46{width:46%}.w-47{width:47%}.w-48{width:48%}.w-49{width:49%}.w-50{width:50%}.w-51{width:51%}.w-52{width:52%}.w-53{width:53%}.w-54{width:54%}.w-55{width:55%}.w-56{width:56%}.w-57{width:57%}.w-58{width:58%}.w-59{width:59%}.w-60{width:60%}.w-61{width:61%}.w-62{width:62%}.w-63{width:63%}.w-64{width:64%}.w-65{width:65%}.w-66{width:66%}.w-67{width:67%}.w-68{width:68%}.w-69{width:69%}.w-70{width:70%}.w-71{width:71%}.w-72{width:72%}.w-73{width:73%}.w-74{width:74%}.w-75{width:75%}.w-76{width:76%}.w-77{width:77%}.w-78{width:78%}.w-79{width:79%}.w-80{width:80%}.w-81{width:81%}.w-82{width:82%}.w-83{width:83%}.w-84{width:84%}.w-85{width:85%}.w-86{width:86%}.w-87{width:87%}.w-88{width:88%}.w-89{width:89%}.w-90{width:90%}.w-91{width:91%}.w-92{width:92%}.w-93{width:93%}.w-94{width:94%}.w-95{width:95%}.w-96{width:96%}.w-97{width:97%}.w-98{width:98%}.w-99{width:99%}.w-100{width:100%}
