/* g-kit */
:root[data-ui-g] .g-zone{background:linear-gradient(165deg,var(--bg-2),var(--bg-1) 62%);
  border:1px solid var(--line);border-radius:var(--r-card);overflow:hidden;margin-bottom:var(--sp-5);position:relative}
:root[data-ui-g] .g-zone::before{content:"";position:absolute;inset:0 auto auto 0;width:44px;height:2px;
  background:linear-gradient(90deg,var(--accent-hi),transparent)}
:root[data-ui-g] .g-zone-h{display:flex;align-items:center;gap:var(--sp-4);padding:var(--sp-4) calc(var(--sp-5) + var(--sp-6)) var(--sp-3) var(--sp-5);flex-wrap:wrap}
:root[data-ui-g] .g-zone-h h2{margin:0;font-size:var(--fs-head);font-weight:700}
/* The provenance chip hugs the RIGHT edge whether it shares the title's line or takes its
   own. In the 452px rail, title + subtitle + chip needs ~459px, so it wraps — measured, not
   guessed — and an unaligned wrap reads as an accident. This makes the two-line case look
   like the one-line case, which is what it is: the same header, one line shorter of room. */
:root[data-ui-g] .g-zone-h .g-prov{margin-left:auto}
:root[data-ui-g] .g-sub{font-size:var(--fs-body);color:var(--ink-3)}
:root[data-ui-g] .g-zone-b{padding:var(--sp-1) var(--sp-5) var(--sp-4)}
:root[data-ui-g] .g-prov{margin-left:auto;font:500 var(--fs-fine)/var(--lh-tight) var(--font);color:var(--ink-3);background:transparent;
  border:0;border-radius:0;padding:0;display:inline-flex;align-items:center;gap:0;white-space:nowrap;max-width:100%}
@media(max-width:700px){
  :root[data-ui-g] .g-prov,:root[data-ui-g] .g-prov-u{white-space:normal}
}
:root[data-ui-g] .g-prov::before{content:none;display:none}
/* Register §12 T-02/T-08: the four failure modes must be VISIBLY DISTINCT — a missing table, a
   thrown read, an empty result and a stale one are four different truths, and collapsing them
   into a single grey chip is the whole defect. Colour is the second channel; each chip also
   says its own name in words, because colour alone is not an accessible signal. */
:root[data-ui-g] .g-prov.stale{color:var(--warn)}
:root[data-ui-g] .g-prov.missing{color:var(--warn)}
:root[data-ui-g] .g-prov.error{color:var(--down)}
:root[data-ui-g] .g-prov.empty{color:var(--ink-3)}
:root[data-ui-g] .g-prov.sample{color:var(--warn)}
:root[data-ui-g] .g-prov-u{font:600 var(--fs-fine)/var(--lh-tight) var(--mono);color:var(--ink-3);margin-left:var(--sp-3);white-space:nowrap}
:root[data-ui-g] .g-prov-m{font:600 var(--fs-fine)/var(--lh-tight) var(--mono);color:var(--ink-3);margin-left:var(--sp-3);text-decoration:underline}
:root[data-ui-g] .g-card{background:var(--bg-2);border:1px solid var(--line);border-radius:var(--r-card);padding:var(--sp-5) var(--sp-5)}
:root[data-ui-g] .g-card-h{font-weight:700;margin-bottom:var(--sp-3)}
:root[data-ui-g] .g-empty,
:root[data-ui-g] .g-absent{color:var(--ink-3);font-size:var(--fs-read);margin:var(--sp-3) 0}
:root[data-ui-g] .g-empty-alt{color:var(--ink-2);font-size:var(--fs-read);margin:var(--sp-3) 0}
:root[data-ui-g] .g-fence-top{font-size:var(--fs-body);color:var(--ink-2);margin:0 0 var(--sp-5);padding:var(--sp-3) var(--sp-4);
  border:1px solid var(--line-2);border-left:2px solid var(--accent);border-radius:0 var(--r-card) var(--r-card) 0;background:var(--acc-dim)}
:root[data-ui-g] .g-tile{background:var(--bg-0);border:1px solid var(--line);border-radius:var(--r-card);
  padding:var(--sp-4) var(--sp-5);display:flex;flex-direction:column;gap:var(--sp-2)}
/* §16: a tile that carries its own way in. The FACE is unchanged in every variant — only a
   small "N names ›" affordance is added, so a wired tile still reads as the same tile. */
:root[data-ui-g] a.g-tile-go{color:inherit;text-decoration:none}
:root[data-ui-g] a.g-tile-go:hover,:root[data-ui-g] .g-tile-drill:hover{border-color:var(--accent)}
:root[data-ui-g] .g-tile-drill{cursor:pointer}
:root[data-ui-g] .g-tile-drill summary{list-style:none;display:flex;flex-direction:column;gap:var(--sp-2)}
:root[data-ui-g] .g-tile-drill summary::-webkit-details-marker{display:none}
:root[data-ui-g] .g-tdw{font:600 var(--fs-fine) var(--font);color:var(--accent);letter-spacing:var(--ls-caps)}
:root[data-ui-g] .g-tdl{list-style:none;margin:var(--sp-4) 0 0;padding:var(--sp-4) 0 0;border-top:1px solid var(--line);
  display:flex;flex-direction:column;gap:var(--sp-3);max-height:280px;overflow-y:auto}
:root[data-ui-g] .g-tdl li{display:flex;justify-content:space-between;gap:var(--sp-4);font-size:var(--fs-body)}
:root[data-ui-g] .g-tdn{color:var(--ink-3);font:600 var(--fs-label) var(--mono)}
/* §18: the constituent list inside a pulse-deck panel */
:root[data-ui-g] .g-nl-h{font:600 var(--fs-fine) var(--font);letter-spacing:var(--ls-caps);text-transform:uppercase;
  color:var(--ink-3);margin-top:var(--sp-4)}
:root[data-ui-g] .g-nl{columns:2;column-gap:var(--sp-5);max-height:300px}
@media(max-width:560px){:root[data-ui-g] .g-nl{columns:1}}
:root[data-ui-g] .g-tdmore{color:var(--ink-3);font-size:var(--fs-label);font-style:italic}
:root[data-ui-g] .g-lab{font:600 var(--fs-fine)/var(--lh-tight) var(--font);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--ink-3)}
:root[data-ui-g] .g-big{font-size:var(--fs-display);font-weight:700;line-height:var(--lh-tight)}
:root[data-ui-g] .g-chip{display:inline-flex;align-items:center;gap:var(--sp-3);background:var(--bg-3);border:1px solid var(--line-2);
  border-radius:var(--r-round);padding:var(--sp-2) var(--sp-3) var(--sp-2) var(--sp-4);font-size:var(--fs-body);color:var(--ink)}
:root[data-ui-g] .g-chip b{font:600 var(--fs-fine)/var(--lh-tight) var(--mono);color:var(--accent);background:var(--acc-dim);border-radius:var(--r-round);padding:var(--sp-2) var(--sp-3)}
/* .g-count is an <a> when it drills (§15 L-01). `color:inherit;text-decoration:none` keeps the
   rendered look byte-identical to the inert div it replaced — the estate's `.g-syma` idiom. */
:root[data-ui-g] .g-count{display:block;background:var(--bg-0);border:1px solid var(--line);border-radius:var(--r-card);padding:var(--sp-3) var(--sp-4);color:inherit;text-decoration:none}
:root[data-ui-g] a.g-count:hover{border-color:var(--accent)}
:root[data-ui-g] .g-n{font-size:var(--fs-display);font-weight:700;line-height:var(--lh-tight)}
:root[data-ui-g] .g-k{font-size:var(--fs-label);color:var(--ink-3);margin-top:var(--sp-2)}
/* §19b: the activity line under the open count */
:root[data-ui-g] .g-cf{font:600 var(--fs-fine) var(--mono);color:var(--ink-3);margin-top:var(--sp-2);opacity:.85}
:root[data-ui-g] .g-dot{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--accent);margin-right:var(--sp-2);vertical-align:middle}
:root[data-ui-g] .g-dot.warn{background:var(--warn)}
:root[data-ui-g] .g-pulse{display:flex;flex-direction:column;gap:var(--sp-5)}
:root[data-ui-g] .g-icards{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:var(--sp-4)}
:root[data-ui-g] .g-icard{background:var(--bg-0);border:1px solid var(--line);border-radius:var(--r-card);padding:var(--sp-4)}
:root[data-ui-g] .g-nm{font:700 var(--fs-label) var(--font);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--ink-3)}
:root[data-ui-g] .g-lv{font-size:var(--fs-display);font-weight:700;line-height:var(--lh-tight)}
:root[data-ui-g] .g-ch{font-weight:700;font-size:var(--fs-body)}
:root[data-ui-g] .g-ch.up,:root[data-ui-g] .up{color:var(--up)}
:root[data-ui-g] .g-ch.dn,:root[data-ui-g] .dn{color:var(--down)}
:root[data-ui-g] .g-mood{display:flex;align-items:baseline;gap:var(--sp-3);font-size:var(--fs-read);flex-wrap:wrap}
:root[data-ui-g] .g-mood .g-sub{flex-basis:100%;color:var(--ink-2)}
:root[data-ui-g] .g-split{height:12px;border-radius:var(--r-round);overflow:hidden;background:var(--bg-3);display:flex}
:root[data-ui-g] .g-split-up{height:100%;width:0;background:var(--up);transition:width 1s cubic-bezier(.2,.7,.2,1)}
:root[data-ui-g] .g-split-lab{display:flex;justify-content:space-between;margin-top:var(--sp-2);font:600 var(--fs-label) var(--mono)}
:root[data-ui-g] .g-as{font-size:var(--fs-fine);color:var(--ink-3);margin-top:var(--sp-2)}
:root[data-ui-g] .g-btn{background:var(--bg-3);border:1px solid var(--line-2);color:var(--ink);border-radius:var(--r-card);
  padding:var(--sp-3) var(--sp-5);font:600 var(--fs-read) var(--font);cursor:pointer;margin-top:var(--sp-3)}
:root[data-ui-g] .g-btn:hover{border-color:var(--accent)}
/* The "where this goes" note on a door out of this experience (`classic_exit`). Quieter and smaller
   than its label so it reads as a qualifier, not a second label, and it WRAPS rather than stretching
   a button or a pill off the edge on a narrow screen. */
:root[data-ui-g] .g-cx-note{display:block;font-weight:400;font-size:var(--fs-fine);line-height:var(--lh-body);
  color:var(--ink-3);margin-top:var(--sp-1);white-space:normal;max-width:26em}
:root[data-ui-g] .g-sbadge .g-cx-note{font-size:var(--fs-fine);max-width:18em}
:root[data-ui-g] .g-count-band{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-4)}
@media(max-width:560px){:root[data-ui-g] .g-count-band{grid-template-columns:repeat(2,1fr)}}
:root[data-ui-g] .g-changed{display:flex;flex-direction:column;margin-top:var(--sp-5)}
:root[data-ui-g] .g-chrow{display:grid;grid-template-columns:74px 1fr auto;gap:var(--sp-4);align-items:center;padding:var(--sp-3) var(--sp-1);border-bottom:1px solid var(--line);font-size:var(--fs-body)}
:root[data-ui-g] .g-chrow:last-child{border-bottom:0}
:root[data-ui-g] .g-sym{font-weight:700;font-size:var(--fs-body)}
:root[data-ui-g] .g-what{color:var(--ink-2)}
:root[data-ui-g] .g-code{font:600 var(--fs-micro)/var(--lh-tight) var(--mono);color:var(--accent);background:var(--acc-dim);border-radius:var(--r-round);padding:var(--sp-1) var(--sp-3);margin-left:var(--sp-2)}
:root[data-ui-g] .g-when{font-size:var(--fs-label);color:var(--ink-3);text-align:right}
:root[data-ui-g] .g-flow{display:grid;grid-template-columns:auto minmax(0,1fr) auto;column-gap:var(--sp-4);row-gap:var(--sp-3);align-items:center;margin-top:var(--sp-2)}
/* 🔴 EVERY non-row child SPANS, and this rule replaced two that named children by hand.
   `.g-frow{display:contents}` promotes the row's three cells to grid items, which is the point —
   but it also means any OTHER child of `.g-flow` becomes an item in column 1. I enumerated the two
   children I could see (`.g-flow-foot`, `.g-fd`) and shipped it; the LIVE page carries a third,
   `.g-proad`, which my demo data does not render. It landed in the `auto` first column, widened it,
   and `minmax(0,1fr)` — the bar track — collapsed to ZERO. Deployed, seen in the screenshot,
   rolled back within minutes.
   The lesson is the rule's shape, not the missing name: a layout that enumerates its children is
   wrong the first time one is added, and a `:not()` over the one child that IS special is right
   forever. `minmax(0,1fr)` stays because it is what lets the track shrink rather than overflow. */
:root[data-ui-g] .g-frow{display:contents}
:root[data-ui-g] .g-flow>*:not(.g-frow){grid-column:1/-1}
:root[data-ui-g] .g-fnm{font-weight:700;font-size:var(--fs-body);color:var(--ink-2)}
:root[data-ui-g] .g-divtrack{position:relative;height:18px;background:var(--bg-0);border:1px solid var(--line);border-radius:var(--r-control);overflow:hidden}
:root[data-ui-g] .g-mid{position:absolute;left:50%;top:0;bottom:0;width:1px;background:var(--line-2)}
:root[data-ui-g] .g-fbar{position:absolute;top:2px;bottom:2px;width:0;border-radius:var(--r-control);transition:width 1s cubic-bezier(.2,.7,.2,1)}
:root[data-ui-g] .g-fbar.up{background:var(--up)}
:root[data-ui-g] .g-fbar.dn{background:var(--down)}
:root[data-ui-g] .g-fval{font-family:var(--mono);font-weight:700;font-size:var(--fs-body);text-align:right}
:root[data-ui-g] .g-fval.up{color:var(--up)}
:root[data-ui-g] .g-fval.dn{color:var(--down)}
:root[data-ui-g] .g-flow-foot{display:flex;justify-content:space-between;gap:var(--sp-4);font-size:var(--fs-label);color:var(--ink-3);margin-top:var(--sp-1);flex-wrap:wrap}
/* FII/DII Pro 'go deeper' block */
:root[data-ui-g] .g-fd{display:flex;flex-direction:column;gap:var(--sp-4)}
:root[data-ui-g] .g-fd-row{display:flex;flex-direction:column;gap:var(--sp-1)}
:root[data-ui-g] .g-fd-top{display:flex;justify-content:space-between;align-items:baseline;gap:var(--sp-4)}
:root[data-ui-g] .g-fd-nm{font:700 var(--fs-body) var(--mono);letter-spacing:var(--ls-caps);color:var(--ink-2)}
:root[data-ui-g] .g-fd-net{font-weight:800;font-size:var(--fs-read)}
:root[data-ui-g] .g-fd-net.up{color:var(--up)} :root[data-ui-g] .g-fd-net.dn{color:var(--down)}
:root[data-ui-g] .g-fd-gross{font-size:var(--fs-label);color:var(--ink-3)}
:root[data-ui-g] .g-fd-meta{font-size:var(--fs-label);color:var(--ink-2)}
/* settled-history context under the provisional headline (D189) */
:root[data-ui-g] .g-fd-settled{font-size:var(--fs-label);color:var(--ink-2);margin-top:var(--sp-1)}
:root[data-ui-g] .g-fd-src{display:inline-block;font:700 var(--fs-micro)/var(--lh-body) var(--mono);letter-spacing:var(--ls-caps);
  text-transform:uppercase;color:var(--accent);border:1px solid var(--line-2);border-radius:var(--r-round);
  padding:var(--sp-1) var(--sp-3);margin-right:var(--sp-2);vertical-align:1px}
:root[data-ui-g] .g-fd-note{font-size:var(--fs-fine);color:var(--ink-3);line-height:var(--lh-body);margin:var(--sp-3) 0 0}
/* ── charts.py: the shared honest-chart primitive (strip · overlay · glyph) ──
   The caption is NOT decoration — it carries the domain, the reference, the span and the
   last value, which is what makes the picture quotable. Do not hide it to save space. */
:root[data-ui-g] .g-ch{margin:var(--sp-3) 0 var(--sp-4)}
:root[data-ui-g] .g-ch-svg{width:100%;height:auto;display:block;background:var(--bg-0);
  border:1px solid var(--line);border-radius:var(--r-card)}
:root[data-ui-g] .g-ch-cap{margin-top:var(--sp-2);font-size:var(--fs-label);color:var(--ink-2);line-height:var(--lh-body)}
:root[data-ui-g] .g-ch-cap b{color:var(--ink);font-variant-numeric:tabular-nums}
/* 🔴 The +/− marks are LITERAL CHARACTERS, never CSS escapes — and this comment may not spell
   one out either, which is the joke that cost a second commit. A CSS escape written as
   backslash-002B inside this NON-raw Python string is read as an OCTAL escape by PYTHON before
   CSS ever sees it: it emitted U+0002 followed by the letter B, and backslash-2212 emitted
   U+0091 followed by 2, so the browser would have shown a control character where the plus sign
   belongs. `test_no_control_chars_in_source_literals` caught the rule — then caught the comment
   explaining the rule, because a comment inside a triple-quoted string is not a comment, it is
   string content, and Python parses escapes there exactly the same way.
   The sibling disclosure at `.g-hm-resid` has always used literal glyphs (`▸`/`▾`); this now
   matches the convention that was already in the file.
   H-4 — the data view every chart in `charts.py` now carries. Closed by default: the
   picture stays the page's shape and the numbers are one click away, which is what an analyst
   asked for and what a scanning reader is not made to scroll past. Existing tokens only. */
:root[data-ui-g] .g-ch-data{margin-top:var(--sp-2)}
:root[data-ui-g] .g-ch-data > summary{display:inline-block;cursor:pointer;
  font:600 var(--fs-label) var(--font);color:var(--accent);padding:var(--sp-1) 0;list-style:none}
:root[data-ui-g] .g-ch-data > summary::-webkit-details-marker{display:none}
:root[data-ui-g] .g-ch-data > summary::before{content:"+  ";font-variant-numeric:tabular-nums}
:root[data-ui-g] .g-ch-data[open] > summary::before{content:"−  "}
:root[data-ui-g] .g-ch-data > summary:hover{color:var(--ink)}
:root[data-ui-g] .g-ch-note{margin:var(--sp-2) 0 0;font-size:var(--fs-fine);color:var(--ink-2);
  line-height:var(--lh-body)}
:root[data-ui-g] .g-ch-note b{color:var(--ink);font-variant-numeric:tabular-nums}
/* The transform line is the one a reader MUST not skim past — it is what stops the table being
   read as a contradiction of the picture — so it carries the warn ink the estate already uses
   for "read this before you trust the thing beside it". */
:root[data-ui-g] .g-ch-tx{color:var(--warn,#c69316)}
/* The grid itself scrolls INSIDE the disclosure. A 900-row table that pushed the page sideways
   would trade one honesty defect for the sideways-scroll defect the estate fixed in August. */
:root[data-ui-g] .g-ch-data table{margin-top:var(--sp-3);max-height:340px;display:block;
  overflow:auto;border-collapse:collapse;width:100%;font-variant-numeric:tabular-nums}
:root[data-ui-g] .g-ch-data th, :root[data-ui-g] .g-ch-data td{
  padding:var(--sp-1) var(--sp-4) var(--sp-1) 0;text-align:right;font-size:var(--fs-fine);
  white-space:nowrap;border-bottom:1px solid var(--line-2)}
:root[data-ui-g] .g-ch-data th:first-child, :root[data-ui-g] .g-ch-data td:first-child{
  text-align:left;position:sticky;left:0;background:var(--bg-0)}
:root[data-ui-g] .g-ch-data thead th{position:sticky;top:0;background:var(--bg-0);
  font-size:var(--fs-label);opacity:.8}
:root[data-ui-g] .g-ch-leg{display:flex;flex-wrap:wrap;gap:var(--sp-5);margin-top:var(--sp-3);
  font-size:var(--fs-fine);color:var(--ink-2)}
:root[data-ui-g] .g-ch-lg{display:inline-flex;align-items:center;gap:var(--sp-2)}
:root[data-ui-g] .g-ch-lg i{width:9px;height:2.5px;border-radius:var(--r-hair);display:inline-block}
:root[data-ui-g] .g-ch-lg b{color:var(--ink);font-variant-numeric:tabular-nums}
:root[data-ui-g] .g-ch-empty{font-size:var(--fs-label);color:var(--ink-3);margin:var(--sp-3) 0}
:root[data-ui-g] .g-spark{height:38px;margin-top:var(--sp-1);color:var(--accent)}
:root[data-ui-g] .g-spark.up{color:var(--up)}
:root[data-ui-g] .g-spark.dn{color:var(--down)}
:root[data-ui-g] .g-spark svg{width:100%;height:38px;display:block}
:root[data-ui-g] .g-agenda{display:flex;flex-direction:column}
:root[data-ui-g] .g-ag{display:flex;align-items:baseline;gap:var(--sp-4);padding:var(--sp-3) var(--sp-1);border-bottom:1px solid var(--line)}
:root[data-ui-g] .g-date-cont{border-color:transparent!important;background:transparent!important;color:transparent}
:root[data-ui-g] .g-ag:last-child{border-bottom:0}
:root[data-ui-g] .g-date{font:700 var(--fs-label)/var(--lh-body) var(--mono);color:var(--ink);background:var(--bg-0);border:1px solid var(--line-2);border-radius:var(--r-control);padding:var(--sp-2) var(--sp-3);text-align:center;min-width:54px}
:root[data-ui-g] .g-date small{display:block;font-size:var(--fs-micro);color:var(--ink-3);font-weight:500}
:root[data-ui-g] .g-ag-b{min-width:0;font-size:var(--fs-read)}
:root[data-ui-g] .g-ag-s{font-weight:700;font-size:var(--fs-body)}
:root[data-ui-g] .g-ag-d{color:var(--ink-2)}
:root[data-ui-g] .g-kind{font:600 var(--fs-fine)/var(--lh-tight) var(--mono);color:var(--ink-3);border:1px solid var(--line-2);border-radius:var(--r-round);padding:var(--sp-2) var(--sp-3);white-space:nowrap}
:root[data-ui-g] .g-wire{display:flex;flex-direction:column}
:root[data-ui-g] .g-wrow{padding:var(--sp-3) var(--sp-1);border-bottom:1px solid var(--line)}
:root[data-ui-g] .g-wrow:last-child{border-bottom:0}
:root[data-ui-g] .g-wh{font-size:var(--fs-read);color:var(--ink);line-height:var(--lh-body)}
:root[data-ui-g] .g-wm{display:flex;gap:var(--sp-3);margin-top:var(--sp-2);font-size:var(--fs-label);color:var(--ink-3);flex-wrap:wrap}
:root[data-ui-g] .g-wsrc{font-weight:600;color:var(--ink-2)}
/* H-20/U-10: the symbol tags this zone always claimed to have ("headlines, symbol-tagged"). */
:root[data-ui-g] .g-wtags{display:inline-flex;gap:var(--sp-3);flex-wrap:wrap;margin-left:var(--sp-1)}
:root[data-ui-g] .g-drawer{background:var(--bg-2);border:1px solid var(--line);border-radius:var(--r-card);overflow:hidden;margin-bottom:var(--sp-4)}
:root[data-ui-g] .g-drawer summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:var(--sp-4);padding:var(--sp-4) var(--sp-5)}
:root[data-ui-g] .g-drawer summary::-webkit-details-marker{display:none}
:root[data-ui-g] .g-dw-t{font-weight:700;font-size:var(--fs-read)}
:root[data-ui-g] .g-dw-s{font-size:var(--fs-body);color:var(--ink-3)}
:root[data-ui-g] .g-chev{margin-left:auto;width:20px;height:20px;color:var(--ink-3);transition:transform .2s ease}
:root[data-ui-g] .g-drawer[open] .g-chev{transform:rotate(180deg)}
:root[data-ui-g] .g-dw-b{padding:var(--sp-1) var(--sp-5) var(--sp-5);border-top:1px solid var(--line)}
:root[data-ui-g] .g-rowbars{display:flex;flex-direction:column;gap:var(--sp-3);margin-top:var(--sp-4)}
:root[data-ui-g] .g-rowbar{display:grid;grid-template-columns:104px 1fr 56px;gap:var(--sp-4);align-items:center;font-size:var(--fs-body)}
:root[data-ui-g] .g-rb-n{font-weight:600;color:var(--ink-2)}
:root[data-ui-g] .g-rb-t{height:9px;background:var(--bg-3);border-radius:var(--r-round);overflow:hidden}
:root[data-ui-g] .g-rb-f{display:block;height:100%;width:0;border-radius:var(--r-round);background:linear-gradient(90deg,var(--accent),var(--accent-hi));transition:width 1s cubic-bezier(.2,.7,.2,1)}
:root[data-ui-g] .g-rb-v{font-family:var(--mono);text-align:right;color:var(--ink-2)}
:root[data-ui-g] .g-note{font-size:var(--fs-body);color:var(--ink-3);margin-top:var(--sp-4);line-height:var(--lh-body)}
:root[data-ui-g] .g-learn{font-size:var(--fs-body);color:var(--ink-2);margin-top:var(--sp-3);line-height:var(--lh-body);padding:var(--sp-3) var(--sp-4);background:var(--acc-dim);border-left:2px solid var(--accent);border-radius:0 var(--r-card) var(--r-card) 0}
:root[data-ui-g] .g-learn b{color:var(--ink)}
:root[data-ui-g] .g-concl{font-size:var(--fs-body);color:var(--ink);margin:0 0 var(--sp-4);padding:var(--sp-3) var(--sp-4);line-height:var(--lh-body);background:var(--acc-dim);border-left:var(--band-lead) solid var(--accent);border-radius:0 var(--r-card) var(--r-card) 0}
:root[data-ui-g] .g-concl b{color:var(--ink)}
:root[data-ui-g] .g-pulse2{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);gap:var(--sp-5)}
@media(max-width:720px){:root[data-ui-g] .g-pulse2{grid-template-columns:minmax(0,1fr)}}
:root[data-ui-g] .g-pl-l{display:flex;flex-direction:column;gap:var(--sp-4)}
:root[data-ui-g] .g-pl-r{display:grid;grid-template-rows:1fr 1fr;gap:var(--sp-4)}
:root[data-ui-g] .g-mtile{background:var(--bg-0);border:1px solid var(--line);border-radius:var(--r-card);padding:var(--sp-4);display:flex;flex-direction:column;gap:var(--sp-3)}
:root[data-ui-g] .g-mtile .g-sub{color:var(--ink-2)}
:root[data-ui-g] .g-gauge{position:relative;width:100%;max-width:170px;margin:var(--sp-1) auto 0}
:root[data-ui-g] .g-gauge svg{width:100%;height:auto;display:block}
:root[data-ui-g] .g-gtrack{stroke:var(--bg-3)}
:root[data-ui-g] .g-gfill{stroke:var(--accent)}
:root[data-ui-g] .g-gword{position:absolute;left:0;right:0;bottom:6px;text-align:center;font-weight:700;font-size:var(--fs-head);color:var(--ink);text-shadow:0 0 16px var(--glow)}
:root[data-ui-g] .g-row2{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-5);margin-bottom:var(--sp-5);align-items:start}
@media(max-width:820px){:root[data-ui-g] .g-row2{grid-template-columns:1fr}}
:root[data-ui-g] .g-row2 .g-zone{margin-bottom:0}
/* ── the table_kit scroll box, on THIS estate (owner-reported regression, 2026-07-30) ──────
   `table_kit.frame` wraps its grid in `div.g-mscroll` with an INLINE `max-height` and ships no
   CSS for the class — it expects the host page to own the overflow. Classic defines it; Graphite
   never did. So the drill rendered `max-height:300px` with NO `overflow`, which CLIPS the rows
   instead of scrolling them: the old flex list had `max-height:280px;overflow-y:auto` and the
   scrollbar the owner was used to disappeared the moment the grid replaced it. A height without
   an overflow is a truncation, and a silent one.
   `position:sticky` on the header is the other half — a 44-row grid whose column labels scroll
   away is a grid you have to re-learn on every screenful, which is the opposite of the point. */
/* the onward door under a capped drill — a link, styled as one, not a dim footnote */
:root[data-ui-g] .g-tdlink{display:inline-block;margin:var(--sp-3) 0 var(--sp-5);font:600 var(--fs-label) var(--font);
  color:var(--accent);text-decoration:none;border-bottom:1px solid transparent}
:root[data-ui-g] .g-tdlink:hover,:root[data-ui-g] .g-tdlink:focus-visible{border-bottom-color:var(--accent)}
:root[data-ui-g] .g-mscroll{overflow:auto;scrollbar-width:thin;scrollbar-color:var(--line-2) transparent}
:root[data-ui-g] .g-mscroll::-webkit-scrollbar{width:8px;height:8px}
:root[data-ui-g] .g-mscroll::-webkit-scrollbar-thumb{background:var(--line-2);border-radius:var(--r-card)}
:root[data-ui-g] .g-mscroll table[data-gtk] thead th{position:sticky;top:0;z-index:2;background:var(--bg-1)}
:root[data-ui-g] .g-mscroll table[data-gtk]{width:100%;border-collapse:collapse;font-size:var(--fs-body)}
:root[data-ui-g] .g-mscroll table[data-gtk] td{padding:var(--sp-2) var(--sp-3);border-top:1px solid var(--line);white-space:nowrap}
:root[data-ui-g] .g-mscroll table[data-gtk] th{padding:var(--sp-2) var(--sp-3);text-align:left;white-space:nowrap;
  font:600 var(--fs-fine) var(--font);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--ink-3)}
/* numeric columns right-align and use tabular figures so a column of prices reads as a column —
   ₹1,34,200 over ₹59.38 only lines up if the digits are the same width. */
:root[data-ui-g] .g-mscroll table[data-gtk] td.num,:root[data-ui-g] .g-mscroll table[data-gtk] th[data-gtk-num]{
  text-align:right;font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}
/* fixed-size boxes that scroll internally (owner directive) — never a flat endless page */
:root[data-ui-g] .g-agenda,:root[data-ui-g] .g-wire,:root[data-ui-g] .g-changed{max-height:300px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--line-2) transparent;padding-right:var(--sp-2)}
:root[data-ui-g] .g-agenda::-webkit-scrollbar,:root[data-ui-g] .g-wire::-webkit-scrollbar,:root[data-ui-g] .g-changed::-webkit-scrollbar{width:8px}
:root[data-ui-g] .g-agenda::-webkit-scrollbar-thumb,:root[data-ui-g] .g-wire::-webkit-scrollbar-thumb,:root[data-ui-g] .g-changed::-webkit-scrollbar-thumb{background:var(--line-2);border-radius:var(--r-card)}
:root[data-ui-g] .g-agenda::-webkit-scrollbar-track,:root[data-ui-g] .g-wire::-webkit-scrollbar-track,:root[data-ui-g] .g-changed::-webkit-scrollbar-track{background:transparent}
/* ── PHONE: the agenda row goes two-line, for the reason the filings row did ─────────────────
   MEASURED at 375 on LIVE data: `.g-ag-b` (symbol + inline detail) needs **286-288px** and gets
   **173-216px**, so EVERY row wraps — 14 of 14 on Going ex, 7 of 7 on Results calendar — and the
   heights go 37 / 38 / 58 / 80px. A list whose rows range from one line to three has no rhythm to
   read down, which is what "cramped" looks like from the outside.
   The chip SPANS BOTH LINES of its own column rather than sitting on the first, and that is the
   difference between a fix and a regression: the chip is a two-line block (`20 Aug` over `Thu`),
   so putting it on line 1 alone made EVERY row as tall as the chip — measured 83-84px, worse
   than the ragged 37-80 it replaced. Spanning it, the row is as tall as the taller of the chip
   and the two text lines, and the date still reads once per day with continuation rows aligned
   under it (that collapse is deliberate — see `agenda()`).
   `.g-ag-b` becomes `display:contents` so its two children join the row's grid. The whitespace text
   node between them generates NO anonymous grid item — a run that is entirely white space is not
   rendered — which is asserted in the test rather than assumed.
   The internal cap is RAISED to `50vh`, not removed — and that is a correction of my own first
   instinct. I reasoned that a nested scroll on a touch screen is bad and dropped the bound; the
   estate has already ratified the opposite, with numbers: `vnav.py` measured `.g-vn-more` at
   **2,417px** on a 390px phone and took `max-height:50vh` — cap-and-scroll, not uncap, because
   an unbounded list pushes everything after it below four screens. 14 two-line rows would have
   added ~870px here. Bounded, everything stays reachable and the partial row cues the rest.
   🔴 AND THIS BLOCK SITS AFTER THAT `max-height` RULE ON PURPOSE. The two selectors are
   equal-specificity, so source order alone decides; placed earlier — where it reads better — the
   override silently lost and the nested scroll survived a green check. Measured, not assumed.
   Desktop is untouched: every rule here is inside the phone breakpoint. */
@media(max-width:560px){
:root[data-ui-g] .g-ag{display:grid;grid-template-columns:auto minmax(0,1fr);
  grid-template-areas:"chip sym" "chip det";column-gap:var(--sp-3);row-gap:var(--sp-1)}
:root[data-ui-g] .g-ag>.g-date{grid-area:chip}
:root[data-ui-g] .g-ag-b{display:contents}
:root[data-ui-g] .g-ag-s{grid-area:sym}
:root[data-ui-g] .g-ag-d{grid-area:det}
:root[data-ui-g] .g-agenda{max-height:50vh}
}
/* the 2-region dashboard: main column (pulse + news hero) | sidebar of widgets */
:root[data-ui-g] .g-ribbon{display:flex;align-items:center;gap:var(--sp-5);padding:var(--sp-3) var(--sp-5);background:var(--bg-1);border:1px solid var(--line);border-radius:var(--r-card);margin-bottom:var(--sp-5)}
:root[data-ui-g] .g-rib-live{font:700 var(--fs-fine)/var(--lh-tight) var(--font);letter-spacing:var(--ls-caps);color:var(--accent);flex:none}
:root[data-ui-g] .g-rib-scroll{display:flex;gap:var(--sp-6);overflow-x:auto;scrollbar-width:none;min-width:0}
/* The feed picker's JS sets `g.hidden = true` (see the g-feedpick script), but an author rule that
   sets `display` OUTRANKS the user-agent's `[hidden]{display:none}` — so every one of the five
   feeds painted at once and the picker changed nothing visible. That is why a `sample` marker sat
   next to the `LIVE` badge on the front door: the sample feeds were never hidden. Specificity
   (0,2,0) beats the (0,1,0) above, so this restores what `hidden` is supposed to mean. Any future
   rule that sets `display` on a JS-toggled element needs the same twin — `tests/test_hidden_
   toggle_contract.py` fails the build if one goes missing. */
:root[data-ui-g] .g-rib-scroll[hidden]{display:none}
:root[data-ui-g] .g-rib-scroll::-webkit-scrollbar{display:none}
:root[data-ui-g] .g-rib{display:inline-flex;align-items:baseline;gap:var(--sp-3);font-size:var(--fs-body);white-space:nowrap}
:root[data-ui-g] .g-rib b{font-weight:700}
:root[data-ui-g] .g-rib .g-num{color:var(--ink-2)}
:root[data-ui-g] .g-rib .up{color:var(--up)}
:root[data-ui-g] .g-rib .dn{color:var(--down)}
:root[data-ui-g] .g-dash{display:grid;grid-template-columns:minmax(0,2fr) minmax(0,1fr);gap:var(--sp-5);align-items:start}
@media(max-width:860px){:root[data-ui-g] .g-dash{grid-template-columns:minmax(0,1fr)}}
:root[data-ui-g] .g-main,:root[data-ui-g] .g-side{display:flex;flex-direction:column;gap:var(--sp-5);min-width:0}
:root[data-ui-g] .g-main>.g-zone,:root[data-ui-g] .g-side>.g-zone{margin-bottom:0}
:root[data-ui-g] .g-main .g-wire{max-height:440px}
:root[data-ui-g] .g-syma{color:inherit;text-decoration:none}
:root[data-ui-g] .g-syma:hover{color:var(--accent);text-decoration:underline}
/* A COLUMN HEADER IS A HEADER, NOT A CALL TO ACTION (D536). The token layer paints every bare
   <a> in the accent, and a sortable header IS a bare <a> - so the only headers drawn in the
   site's look-here colour were the SORTABLE ones. On the patterns board that put the FALSIFIED
   rank score in the brightest colour on the row, while Side - the column the page tells you to
   read first, and the only one its out-of-sample test supports - sat in plain grey.
   This is the .g-syma idiom directly above, applied to header links.
   IT LIVES HERE AND NOT IN tokens.py BECAUSE THIS BLOCK IS HOISTED into the cacheable bundle,
   while the token block is 3,040 B and sits under classic_assets._MIN_RUN (4,096 B). The same
   three rules cost 225 B on EVERY page there and 0 B here; the page-weight redundancy gate
   caught it at +900 B across the walk and was right to.
   Specificity (0,2,2) beats the bare-a rule's (0,2,1), so this wins wherever it lands in the
   cascade and does not depend on the bundle loading after the inline block. */
:root[data-ui-g] th a{color:inherit;text-decoration:none}
:root[data-ui-g] th a:hover,:root[data-ui-g] th a:focus-visible{color:var(--accent);text-decoration:underline}
:root[data-ui-g] th a[data-sorted]{color:var(--accent)}
/* ── E-2: THE LIGHT THEME FAILED AA ON THE CHIPS THAT CARRY THE VERDICT ────────────────────────
   Measured with data-theme="light", computed foreground on computed background: the sector phase
   pills ran 1.82-2.52:1 against a 4.5 floor, the 92 "?" scan triggers 2.24:1, the evidence chips
   2.24-2.73:1. The same values measure 5.97-10.08:1 in DARK, which is the whole story — they are
   dark-theme literals with no light rule anywhere, and light is one click away on every screen.

   Each replacement KEEPS ITS OWN HUE and is darkened only until it clears 4.6:1 on BOTH light
   surfaces (#ffffff and --bg-0 #eef2f5), solved rather than eyeballed.

   🔴 THE ROTATION PILLS HAVE LEFT THIS BLOCK (R-10, settled). This is the collision the note
   here predicted and deliberately left open: those four light values were the AA fix, and they
   still borrowed nothing — but the DARK side was painted straight out of `--accent-hi`,
   `--candle-up` and `--warn` at dE 0.00, so "Weakening" and "not a live measurement" were one
   colour. The scale now owns `--rot-lead/impr/weak/lag` in `tokens.py`, which is theme-aware, so
   these eight light rules are gone rather than duplicated. Their AA is preserved by construction:
   the replacements were searched against a 5.0 floor, above the 4.6 this block solved for.

   The byte argument this note made was real and is now paid: the token block sits under
   `classic_assets._MIN_RUN` and cannot be hoisted, so the scale costs per-page bytes where it used
   to cost none. Measured and banked in this commit rather than assumed — a semantic collision in
   the estate's primary colour language is worth more than the bytes, but only the measurement can
   say how much it cost. */
/* Darker than the other blues on purpose. These sit on a 14%-grey pill, and a translucent
   background COMPOSITES: the real backdrop is rgb(223,226,229), not the page's #eef2f5. Solved
   against the composited value it clears 4.60:1 there, 5.32 on the page and 5.98 on white.
   The accessibility report measured these against #eef2f5 and so set the bar slightly too low —
   its 2.24:1 was right about the failure and optimistic about the remedy. `getComputedStyle`
   hands you the declared rgba, never the blend, so a checker that does not composite will call
   this fixed while it is still failing. */
/* The evidence chips write their colour INLINE, which no stylesheet rule can override — so the
   inline value is now `var(--epi-c, <dark hex>)` and these set the variable. A custom property
   DOES cascade into an inline var(), so this needs no !important, and the fallback keeps the chip
   self-contained if the bundle never loads. */
:root[data-ui-g][data-theme="light"] .epi-observed{--epi-c:#2a7c36}
:root[data-ui-g][data-theme="light"] .epi-derived{--epi-c:#0068df}
:root[data-ui-g][data-theme="light"] .epi-inferred{--epi-c:#8c6617}
:root[data-ui-g][data-theme="light"] .epi-unknowable{--epi-c:#656e78}
/* The doubled attribute is a SPECIFICITY device, not a typo. The rule it must beat is
   `:root[data-ui-g] table.g-scr th` at (0,3,2); a single attribute gives only (0,3,1) and
   LOSES — measured, twice, by watching the promoted cell keep its header styling while the
   neutraliser sat correctly in the served bytes. Repeating the attribute takes it to (0,4,2).
   This is not the equal-specificity/document-order trap: here the competitor genuinely
   outranked it, and no amount of ordering would have helped. */
/* `position:static` is the ONE place this rule overreaches on purpose: the estate's `th` rules
   pin `position:sticky;top:0` for the HEAD, and inheriting that would glue every row label to the
   top of the scroll box. A first column that is sticky by its OWN class (the screener's
   `.g-scr-sp`) re-declares it at higher specificity and is unaffected — verified by measuring
   `position` before and after on /stocks, where it stays `sticky`. */
:root[data-ui-g] .g-pl-head{display:flex;align-items:baseline;gap:var(--sp-4)}
:root[data-ui-g] .g-pl-nm{font:700 var(--fs-body) var(--font);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--ink-3)}
:root[data-ui-g] .g-pl-lv{font-size:var(--fs-display);font-weight:700;text-shadow:0 0 18px var(--glow)}
:root[data-ui-g] .g-pl-chart .g-spark{height:96px}
/* ── featured card + chooser ── */
:root[data-ui-g] .g-feat{border-color:color-mix(in srgb,var(--accent) 40%,var(--line));background:linear-gradient(165deg,color-mix(in srgb,var(--accent) 7%,var(--bg-2)),var(--bg-1) 66%);box-shadow:0 0 34px -18px var(--glow)}
:root[data-ui-g] .g-feat::before{width:100%;background:linear-gradient(90deg,var(--accent-hi),transparent 60%)}
:root[data-ui-g] .g-feat-h{display:flex;align-items:center;gap:var(--sp-4) var(--sp-5);padding:var(--sp-4) var(--sp-5) var(--sp-4);flex-wrap:wrap}
:root[data-ui-g] .g-feat-ttl{display:flex;flex-direction:column;gap:var(--sp-1);margin-right:auto;min-width:0}
:root[data-ui-g] .g-eyebrow{font:700 var(--fs-micro)/var(--lh-tight) var(--mono);letter-spacing:var(--ls-caps);color:var(--accent);text-transform:uppercase}
:root[data-ui-g] .g-feat-ttl h2{margin:0;font-size:var(--fs-head);font-weight:800}
:root[data-ui-g] .g-featbar{display:inline-flex;align-items:center;gap:var(--sp-1);background:var(--bg-0);border:1px solid var(--line-2);border-radius:var(--r-round);padding:var(--sp-2)}
:root[data-ui-g] .g-fb{border:0;background:transparent;color:var(--ink-3);font:700 var(--fs-label) var(--font);padding:var(--sp-3) var(--sp-4);border-radius:var(--r-round);cursor:pointer;white-space:nowrap}
:root[data-ui-g] .g-fb[aria-pressed="true"]{color:var(--on-accent);background:linear-gradient(120deg,var(--accent),var(--accent-hi))}
:root[data-ui-g] .g-fb:hover:not([aria-pressed="true"]){color:var(--ink)}
:root[data-ui-g] .g-star{border:0;background:transparent;color:var(--ink-3);cursor:pointer;font-size:var(--fs-head);line-height:var(--lh-tight);padding:var(--sp-2) var(--sp-3);border-radius:var(--r-round)}
:root[data-ui-g] .g-star.set{color:var(--warn)}
:root[data-ui-g] .g-featv{display:none}
:root[data-ui-g] .g-featv.on{display:block}
:root[data-ui-g] .g-pnl{display:flex;gap:var(--sp-4);flex-wrap:wrap;margin-bottom:var(--sp-4)}
:root[data-ui-g] .g-pnl .g-cell{flex:1;min-width:120px}
/* ── watchlist / portfolio rows ──
   Audit class B — density. This grid was four columns at 13px with 9px of vertical padding, and
   two of the four were spent on ONE field (delivery OR the RS rank, whichever happened to exist)
   while the last price — already read — was not shown at all. Seven columns now fit in LESS
   height: 12px type, 5px padding, tabular numerals so the digits line up in a column instead of
   dancing, and the whole thing still scrolls inside its own box. A research surface earns its
   vertical space with fields, not with air. */
:root[data-ui-g] .g-watch{display:flex;flex-direction:column;max-height:352px;overflow-y:auto;scrollbar-width:thin}
:root[data-ui-g] .g-wl{display:grid;
  grid-template-columns:minmax(66px,1.35fr) minmax(52px,.9fr) minmax(50px,.85fr) 40px 46px 52px minmax(58px,.95fr);
  gap:var(--sp-3);align-items:center;padding:var(--sp-2) var(--sp-2);border-bottom:1px solid var(--line);font-size:var(--fs-body);
  font-variant-numeric:tabular-nums}
:root[data-ui-g] .g-wl:last-child{border-bottom:0}
:root[data-ui-g] .g-wl-h{position:sticky;top:0;z-index:1;background:var(--bg-1);padding:var(--sp-2) var(--sp-2);
  font:700 var(--fs-micro)/var(--lh-body) var(--mono);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--ink-3);
  border-bottom:1px solid var(--line-2)}
:root[data-ui-g] .g-wl-h span{text-align:right}
:root[data-ui-g] .g-wl-h span:first-child{text-align:left}
:root[data-ui-g] .g-wl-h span:last-child{text-align:center}
/* the holdings grid is eight columns of the same row furniture — name, then seven numbers */
:root[data-ui-g] .g-wl.g-pf{grid-template-columns:minmax(62px,1.2fr) 44px 56px 56px 50px 48px minmax(58px,.9fr) 34px}
:root[data-ui-g] .g-wl.g-pf.g-wl-h span:last-child{text-align:right}
:root[data-ui-g] .g-wl-px,:root[data-ui-g] .g-wl-rs,:root[data-ui-g] .g-wl-dv,
:root[data-ui-g] .g-wl-fh{text-align:right;color:var(--ink-2)}
:root[data-ui-g] .g-wl-rs,:root[data-ui-g] .g-wl-dv,:root[data-ui-g] .g-wl-fh{font-size:var(--fs-label);color:var(--ink-3)}
/* delivery running a quarter above this name's OWN one-month normal — a self-relative mark, which
   is the only kind that means anything: 45% is high for one stock and unremarkable for another. */
:root[data-ui-g] .g-wl-dv.hot{color:var(--accent);font-weight:700}
:root[data-ui-g] .g-wl-chg{font-weight:700;text-align:right}
:root[data-ui-g] .g-phase{font:600 var(--fs-micro)/var(--lh-tight) var(--mono);letter-spacing:var(--ls-caps);border-radius:var(--r-round);padding:var(--sp-2) var(--sp-3);white-space:nowrap;border:1px solid var(--line-2);color:var(--ink-2);text-align:center}
:root[data-ui-g] .g-phase.lead{color:var(--up);border-color:color-mix(in srgb,var(--up) 45%,transparent)}
:root[data-ui-g] .g-phase.weak{color:var(--down);border-color:color-mix(in srgb,var(--down) 45%,transparent)}
:root[data-ui-g] .g-wl-ev{font-size:var(--fs-label);color:var(--ink-3);text-align:right}
:root[data-ui-g] .g-wl-add{margin:var(--sp-4) 0 0;padding-top:var(--sp-4);border-top:1px dashed var(--line-2)}
/* watchlist Pro per-name reference (add-date · RS rank · standout) — spans the whole row */
:root[data-ui-g] .g-wl-pro{grid-column:1/-1;font-size:var(--fs-fine);color:var(--ink-3);margin:-2px 0 var(--sp-1);letter-spacing:var(--ls-caps)}
:root[data-ui-g] .g-wl-star{color:var(--accent);font-weight:700}
/* the add-a-name affordance */
:root[data-ui-g] .g-wl-addform{display:flex;gap:var(--sp-3);margin:var(--sp-4) 0 0;padding-top:var(--sp-4);border-top:1px dashed var(--line-2)}
:root[data-ui-g] .g-wl-in{flex:1;min-width:0;background:var(--bg-2);border:1px solid var(--line-2);border-radius:var(--r-card);
  padding:var(--sp-3) var(--sp-4);color:var(--ink);font:500 var(--fs-body) var(--font);text-transform:uppercase}
:root[data-ui-g] .g-wl-in::placeholder{color:var(--ink-3);text-transform:none;letter-spacing:0}
:root[data-ui-g] .g-wl-in:focus{outline:2px solid color-mix(in srgb,var(--accent) 55%,transparent);outline-offset:1px;border-color:var(--accent)}
/* the add success/error toast (rendered by the GET from ?msg=) */
:root[data-ui-g] .g-toast{display:flex;align-items:center;gap:var(--sp-3);margin:0 0 var(--sp-5);padding:var(--sp-4) var(--sp-5);border-radius:var(--r-card);
  font-size:var(--fs-read);border:1px solid var(--line-2);background:var(--bg-2)}
:root[data-ui-g] .g-toast.ok{border-color:color-mix(in srgb,var(--up) 50%,var(--line-2));background:color-mix(in srgb,var(--up) 9%,var(--bg-1))}
:root[data-ui-g] .g-toast.err{border-color:color-mix(in srgb,var(--warn) 50%,var(--line-2));background:color-mix(in srgb,var(--warn) 9%,var(--bg-1))}
:root[data-ui-g] .g-toast b{color:var(--ink)}
/* ── index focus ── */
:root[data-ui-g] .g-idx-head{display:flex;align-items:baseline;gap:var(--sp-4);flex-wrap:wrap;margin-bottom:var(--sp-3)}
:root[data-ui-g] .g-idx-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-4);margin-top:var(--sp-4)}
@media(max-width:620px){:root[data-ui-g] .g-idx-stats{grid-template-columns:repeat(2,1fr)}}
/* ── pulse deck ── */
:root[data-ui-g] .g-deck{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--sp-4);margin-top:var(--sp-4)}
@media(max-width:1150px){:root[data-ui-g] .g-deck{grid-template-columns:repeat(2,minmax(0,1fr))}}
:root[data-ui-g] .g-cell{background:var(--bg-0);border:1px solid var(--line);border-radius:var(--r-card);padding:var(--sp-4);display:flex;flex-direction:column;gap:var(--sp-3);position:relative;transition:border-color .18s,transform .18s}
:root[data-ui-g] .g-cell.click{cursor:pointer}
:root[data-ui-g] .g-cell.click:hover{border-color:var(--accent);transform:translateY(-1px)}
:root[data-ui-g] .g-cell.wide{grid-column:1/-1}
:root[data-ui-g] .g-cell .g-big{font-size:var(--fs-display)}
:root[data-ui-g] .g-cell .g-sub{font-size:var(--fs-label);color:var(--ink-2)}
/* The tile's small drill-in phrase sits at the FOOT of the tile, in flow and right-aligned, the
   way every other tile family already places the same invitation. It was pinned to the top-right
   corner out of flow, and the tile's own title ran underneath it. Reasoning, measurements and the
   two rejected alternatives: see the commit that changed this line. Nothing here may name a class,
   attribute or flag — this comment is served to the browser and a gate that greps the page for a
   marker string would match the prose instead of the markup. */
:root[data-ui-g] .g-hint{font:600 var(--fs-micro)/var(--lh-tight) var(--mono);letter-spacing:var(--ls-caps);color:var(--ink-3);order:9;align-self:flex-end;margin-top:auto;padding-top:var(--sp-1);text-transform:uppercase;opacity:.7}
:root[data-ui-g] .g-tspark{height:26px;margin-top:var(--sp-1);color:var(--accent)}
:root[data-ui-g] .g-bigspark{height:70px;margin:var(--sp-3) 0 var(--sp-2);color:var(--accent)}
:root[data-ui-g] .g-pl-spark{flex:1;min-width:120px;height:34px;color:var(--candle-up)}
:root[data-ui-g] .g-tspark.up,:root[data-ui-g] .g-bigspark.up,:root[data-ui-g] .g-pl-spark.up{color:var(--up)}
:root[data-ui-g] .g-tspark.dn,:root[data-ui-g] .g-bigspark.dn,:root[data-ui-g] .g-pl-spark.dn{color:var(--down)}
:root[data-ui-g] .g-tspark svg,:root[data-ui-g] .g-bigspark svg,:root[data-ui-g] .g-pl-spark svg{width:100%;display:block}
:root[data-ui-g] .g-expand{grid-column:1/-1;background:var(--bg-0);border:1px solid var(--accent);border-radius:var(--r-card);padding:var(--sp-4) var(--sp-5);margin-top:var(--sp-1);display:none}
:root[data-ui-g] .g-expand.on{display:block}
:root[data-ui-g] .g-expand h4{margin:0 0 var(--sp-2);font-size:var(--fs-read)}
:root[data-ui-g] .g-expand p{margin:0;font-size:var(--fs-body);color:var(--ink-2);line-height:var(--lh-body)}
:root[data-ui-g] .g-heat{display:flex;flex-wrap:wrap;gap:var(--sp-3);margin-top:var(--sp-2)}
:root[data-ui-g] .g-sec{display:inline-flex;flex-direction:column;gap:var(--sp-1);padding:var(--sp-3) var(--sp-4);border-radius:var(--r-card);border:1px solid var(--line);min-width:74px;max-width:100%;background:var(--bg-0)}
:root[data-ui-g] a.g-sec{color:inherit;text-decoration:none;cursor:pointer}
:root[data-ui-g] a.g-sec:hover,:root[data-ui-g] a.g-sec:focus-visible{border-color:var(--accent)}
:root[data-ui-g] .g-sec b{font-size:var(--fs-label);font-weight:700}
:root[data-ui-g] .g-sec span{font:700 var(--fs-body) var(--mono)}
/* ── ribbon feed picker + sample marks ── */
:root[data-ui-g] .g-feedpick{background:var(--bg-0);color:var(--ink);border:1px solid var(--line-2);border-radius:var(--r-round);padding:var(--sp-2) var(--sp-4);font:700 var(--fs-label) var(--font);cursor:pointer;flex:none}
:root[data-ui-g] .g-feedpick:hover{border-color:var(--accent)}
:root[data-ui-g] .g-rib b.acc{color:var(--accent)}
:root[data-ui-g] .g-smp{font:600 var(--fs-micro)/var(--lh-tight) var(--mono);letter-spacing:var(--ls-caps);color:var(--warn);border:1px solid color-mix(in srgb,var(--warn) 55%,transparent);border-radius:var(--r-round);padding:var(--sp-1) var(--sp-2);text-transform:uppercase;flex:none;align-self:center}
:root[data-ui-g] .g-prov.sample{color:var(--warn)}
/* ── arrange (pin / collapse / hide) ── */
:root[data-ui-g] .g-zone-b.collapsed{display:none}
:root[data-ui-g] .g-zone.hidden{display:none}
/* ── the phone disclosure (see `_zc_head` / `_zc_decide` for the whole design record) ──
   🔴 THE HIDE RULE IS NOT INSIDE THE MEDIA QUERY, ON PURPOSE. `g-zc-off` is a fact about the
   ZONE ("this one is collapsed"), not about the viewport; only the DEFAULT is width-dependent, and
   that default is decided once, by the inline script, at parse time. Media-scoping the hide would
   have quietly broken the arrange menu's Collapse action on a desktop, because that action now
   drives this same single owner. Keyed on a CLASS and never `:has()` - vnav records that a selector
   list containing an unsupported `:has()` drops the WHOLE rule. */
:root[data-ui-g] .g-zone.g-zc-off .g-zone-b{display:none}
:root[data-ui-g] .g-zone.g-zc-off .g-zone-h{padding-bottom:var(--sp-4)}
/* The control is absent above 560px unless the zone is actually collapsed. `display:none` is the
   deliberate form: it takes the button out of the layout AND out of the tab order, so a desktop
   reader who never collapses anything gets a page that is geometrically and behaviourally
   identical to the one before this change. The second rule is what stops that from becoming a trap
   door: a zone collapsed on a phone and then re-opened on a desktop would otherwise carry a stored
   "0" with no visible way back.

   🔴 PINNED OUT OF FLOW, AND THAT IS D585 REPEATING ITSELF. As a 24px flex ITEM in a header that
   already wraps at 375px, the chevron cost **82px of page height** across the two zones the moment
   a reader expanded them - `Market pulse`'s header went 86 -> 142px and `Market map`'s 104 -> 130,
   because a 24px box plus a 12px gap is enough to push the provenance chip onto one more line. That
   is precisely the defect D585 fixed for the arrange `⋮` on 7 of 9 zones, re-introduced on the
   opposite side of the same header. So it mirrors D585's remedy exactly: absolute inside the zone
   (`.g-zone` is already `position:relative`), with the header reserving the same left inset the
   `⋮` reserves on the right. Measured after pinning: header heights back to 86 / 104, page height
   when expanded back to the pre-change 8,891px.

   `z-index:10` is copied from `.g-arr` and is copied WITH ITS REASON: taken out of flow the control
   competes with the zone's own chart, and at 375px `Market map` IS a chart - hit-tested at its
   centre without this, the SVG wins and the button is visible, hover-looking and dead (the
   S-UX-DEADZONE shape). Below `.g-arr-m`'s 20 so an open arrange menu still stacks over everything.

   🔴 THE RESERVE IS 32px AND THAT NUMBER IS MEASURED, NOT CHOSEN. The first version mirrored the
   `⋮`'s right inset (`--sp-5 + --sp-6` = 40px) on the reasoning that two insets which match cannot
   drift. Symmetry was the wrong objective: at 375px the left and right reserves come out of the
   SAME 343px header, and 40px on both sides left `Market pulse`'s title, subtitle and provenance
   chip 263px where they had had 303 - so the chip wrapped and the header went 86 -> 116px. Swept
   the reserve 16 / 24 / 28 / 32 / 36 / 40: every value up to 32 gives 104 / 86 and a page of
   8,891px, byte-for-byte the pre-change geometry; 36 and above give 104 / 116 and 8,920. The wrap
   threshold is between 32 and 36, so the reserve is 32 - `--sp-5 + --sp-4 + --sp-2`, the widest
   inset that costs the reader nothing. The chevron is 24px at `left:--sp-3`, so it ends exactly at
   32 and the glyph's own centring supplies the visual gap. */
/* No `height` here on purpose: the estate's touch-target floor already gives every control
   `min-height:44px` (`.g-arr-b` measures 44px for the same reason), so a `height:24px` would have
   been a declaration that never won and a comment's worth of wrong information for the next reader.
   `width` IS declared, because 24px is what the 32px reserve above was measured against. */
:root[data-ui-g] .g-zc-tg{display:none;position:absolute;left:var(--sp-3);top:var(--sp-3);z-index:10;
  width:24px;padding:0;margin:0;background:none;border:0;
  border-radius:var(--r-control);color:var(--ink-3);cursor:pointer;font:inherit;line-height:var(--lh-tight);
  align-items:center;justify-content:center}
:root[data-ui-g] .g-zone.g-zc-off .g-zc-tg{display:inline-flex}
:root[data-ui-g] .g-zone.g-zc-off .g-zone-h{padding-left:calc(var(--sp-5) + var(--sp-4) + var(--sp-2))}
@media(max-width:560px){
  :root[data-ui-g] .g-zone[data-zc] .g-zc-tg{display:inline-flex}
  :root[data-ui-g] .g-zone[data-zc] .g-zone-h{padding-left:calc(var(--sp-5) + var(--sp-4) + var(--sp-2))}
}
:root[data-ui-g] .g-zc-tg:hover{color:var(--accent);background:var(--bg-2)}
:root[data-ui-g] .g-zc-tg:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
:root[data-ui-g] .g-zc-cr{display:block;transition:transform .15s ease}
:root[data-ui-g] .g-zc-tg[aria-expanded="false"] .g-zc-cr{transform:rotate(-90deg)}
@media(prefers-reduced-motion:reduce){:root[data-ui-g] .g-zc-cr{transition:none}}
/* 🔴 z-index IS LOAD-BEARING, and leaving it out was a regression this change introduced.
   In flow, the control painted after the zone's body by document order. Taken OUT of flow it
   competes with the zone's CHART, and at 375px the chart's SVG won: hit-tested at its own
   centre, `.g-arr-b` on `Market map` and on `FII / DII flows` returned `svg` and `circle`
   instead of the button. Visible, hover-looking, not clickable — the S-UX-DEADZONE shape,
   caught by a pre-commit sweep rather than by a reader. Below `.g-arr-m`'s 20 so the open
   menu still stacks over its own trigger. */
:root[data-ui-g] .g-arr{position:absolute;top:var(--sp-3);right:var(--sp-3);margin-left:0;z-index:10}
:root[data-ui-g] .g-arr-b{border:0;background:transparent;color:var(--ink-3);cursor:pointer;font-size:var(--fs-head);line-height:var(--lh-tight);padding:var(--sp-1) var(--sp-3);border-radius:var(--r-control)}
:root[data-ui-g] .g-arr-b:hover{color:var(--ink);background:var(--bg-3)}
:root[data-ui-g] .g-arr-m{position:absolute;right:0;top:26px;z-index:20;background:var(--bg-3);border:1px solid var(--line-2);border-radius:var(--r-card);padding:var(--sp-2);min-width:140px;box-shadow:var(--shadow-popover);display:none}
:root[data-ui-g] .g-arr-m.on{display:block}
:root[data-ui-g] .g-arr-m button{display:block;width:100%;text-align:left;border:0;background:transparent;color:var(--ink-2);font:600 var(--fs-body) var(--font);padding:var(--sp-3) var(--sp-3);border-radius:var(--r-control);cursor:pointer}
:root[data-ui-g] .g-arr-m button:hover{background:var(--bg-0);color:var(--ink)}
:root[data-ui-g] .g-hidden-tray{display:flex;flex-wrap:wrap;gap:var(--sp-3);align-items:center;padding:var(--sp-4) var(--sp-5);background:var(--bg-1);border:1px dashed var(--line-2);border-radius:var(--r-card);margin-bottom:var(--sp-5);font-size:var(--fs-body);color:var(--ink-3)}
:root[data-ui-g] .g-hidden-tray:empty{display:none}
:root[data-ui-g] .g-restore{background:var(--bg-3);border:1px solid var(--line-2);color:var(--ink-2);border-radius:var(--r-round);padding:var(--sp-2) var(--sp-4);font:600 var(--fs-label) var(--font);cursor:pointer}
/* ── regime one-liner (very top) ── */
:root[data-ui-g] .g-regime{display:flex;align-items:center;gap:var(--sp-4);padding:var(--sp-4) var(--sp-5);margin-bottom:var(--sp-5);
  background:linear-gradient(100deg,var(--acc-dim),transparent 72%),var(--bg-1);border:1px solid var(--line);
  border-left:3px solid var(--accent);border-radius:var(--r-card);font-size:var(--fs-read);color:var(--ink-2);line-height:var(--lh-body)}
:root[data-ui-g] .g-regime-dot{width:8px;height:8px;border-radius:50%;background:var(--accent);flex:none;box-shadow:0 0 10px var(--glow)}
:root[data-ui-g] .g-regime-t b{color:var(--ink)}
/* ── conviction shortlist ── */
:root[data-ui-g] .g-cv-count{font-size:var(--fs-body);color:var(--ink-3);margin:0 0 var(--sp-3)}
:root[data-ui-g] .g-cv-count b{color:var(--accent)}
:root[data-ui-g] .g-convw{display:flex;flex-direction:column}
:root[data-ui-g] .g-cv{display:grid;grid-template-columns:112px 1fr auto;gap:var(--sp-4);align-items:center;padding:var(--sp-3) var(--sp-1);border-bottom:1px solid var(--line);font-size:var(--fs-read)}
:root[data-ui-g] .g-cv:last-child{border-bottom:0}
:root[data-ui-g] .g-cv-meta{color:var(--ink-3);font-size:var(--fs-body)}
:root[data-ui-g] .g-cv-tags{display:flex;gap:var(--sp-3);flex-wrap:wrap;justify-content:flex-end}
:root[data-ui-g] .g-cv-tag{font:600 var(--fs-micro)/var(--lh-tight) var(--mono);border-radius:var(--r-round);padding:var(--sp-2) var(--sp-3);white-space:nowrap;border:1px solid var(--line-2);color:var(--ink-2)}
:root[data-ui-g] .g-cv-tag.near{color:var(--up);border-color:color-mix(in srgb,var(--up) 45%,transparent)}
:root[data-ui-g] .g-cv-tag.q{color:var(--accent);border-color:color-mix(in srgb,var(--accent) 45%,transparent)}
/* ── filings & ownership feed ── */
:root[data-ui-g] .g-filings{display:flex;flex-direction:column;max-height:260px;overflow-y:auto;scrollbar-width:thin}
:root[data-ui-g] .g-fl{display:grid;grid-template-columns:11px 92px 1fr auto;gap:var(--sp-3);align-items:center;padding:var(--sp-3) var(--sp-1);border-bottom:1px solid var(--line);font-size:var(--fs-body)}
:root[data-ui-g] .g-fl-info summary{list-style:none;display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:var(--sp-1);min-height:44px;cursor:pointer}
:root[data-ui-g] .g-fl-info summary::-webkit-details-marker{display:none}
:root[data-ui-g] .g-fl-info summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
:root[data-ui-g] .g-fl-info-icon{display:inline-grid;place-items:center;min-width:44px;min-height:44px;border:1px solid var(--line-2);border-radius:var(--r-control);color:var(--ink-2);background:var(--bg-1)}
:root[data-ui-g] .g-fl-info-body{padding:var(--sp-3);border:1px solid var(--line-2);border-radius:var(--r-card);background:var(--bg-2);color:var(--ink-2);text-align:left;overflow-wrap:anywhere}
:root[data-ui-g] .g-fl-info-body p{margin:0 0 var(--sp-2)}
:root[data-ui-g] .g-fl-info-body p:last-child{margin-bottom:0}
:root[data-ui-g] .g-fl-date{white-space:nowrap}
@media(max-width:360px){:root[data-ui-g] .g-fl-date{white-space:normal}}
/* ── PHONE: the row becomes TWO LINES, because four columns provably do not fit ──────────────
   MEASURED at 375 on live data, card 293px: the detail — the part carrying the information —
   needs **141px** and was getting **92px**, so 8 of 12 rows wrapped and row heights went ragged
   (37 / 56 / 57px). And the squeeze cannot be solved by reclaiming the fixed columns the way the
   FII/DII block's was: the symbol column needs all 92px (THANGAMAYL) and the date needs all 70px,
   so there is **nothing to reclaim** — 11 + 92 + 70 + gaps leaves 96px for a 141px need.
   So the row stops pretending to be one line: identity and date on top, the detail beneath at the
   card's full width, where every one of them fits on a single line. Rows become uniform instead of
   ragged, which is what "cramped" was.
   The internal cap is RAISED to 50vh rather than removed: a 260px box was too tight for two-line
   rows, but `vnav` has already ratified cap-and-scroll on a phone (it measured 2,417px of
   filters and capped at 50vh) and an unbounded 12-row list adds ~700px to the page.
   Desktop is untouched: every rule here is inside the phone breakpoint. */
@media(max-width:560px){
:root[data-ui-g] .g-fl{grid-template-columns:11px minmax(0,1fr) auto;
  grid-template-areas:"dot sym when" "det det det";row-gap:var(--sp-1);align-items:baseline}
:root[data-ui-g] .g-fl-dot{grid-area:dot}
:root[data-ui-g] .g-fl-s{grid-area:sym}
:root[data-ui-g] .g-fl-d{grid-area:det}
:root[data-ui-g] .g-fl-when{grid-area:when}
:root[data-ui-g] .g-fl.has-context{grid-template-areas:"dot sym sym" "det det det" "when when when"}
:root[data-ui-g] .g-fl.has-context .g-fl-when{justify-self:end}
:root[data-ui-g] .g-filings{max-height:50vh}  /* 50vh, not none — see the agenda note below: `vnav` ratified cap-and-scroll on a phone
     with measurements, and I shipped `none` here before re-reading it. Corrected. */
}
:root[data-ui-g] .g-fl:last-child{border-bottom:0}
:root[data-ui-g] .g-fl-dot{width:7px;height:7px;border-radius:50%;background:var(--ink-3)}
:root[data-ui-g] .g-fl-dot.pos{background:var(--up)}
:root[data-ui-g] .g-fl-dot.warn{background:var(--warn)}
:root[data-ui-g] .g-fl-d{color:var(--ink-2)}
:root[data-ui-g] .g-fl-when{font-size:var(--fs-label);color:var(--ink-3);text-align:right}
/* ── market heatmap (squarified treemap) ── */
:root[data-ui-g] .g-hm{position:relative;width:100%;aspect-ratio:1000/525;min-height:300px;border-radius:var(--r-card);overflow:hidden;background:var(--bg-0);border:1px solid var(--line)}
/* E-4(a): the direction caret. Sized under the symbol so it reads as a sign, not a bullet. */
:root[data-ui-g] .g-hm-d{font-size:.8em;opacity:.9;margin-right:.15em}
:root[data-ui-g] .g-hm-t{position:absolute;overflow:hidden;display:flex;align-items:center;justify-content:center;
  border:1px solid color-mix(in srgb,var(--bg-0) 55%,transparent);text-decoration:none;transition:filter .12s,outline-color .12s;outline:1px solid transparent}
/* clean single-hue ramps (dark-muted -> vivid by move size); mixing the signed hue with the BLUE-GREY
   bg muddied small moves into brown — fixed by ramping within one hue. bigger move = more vivid. */
:root[data-ui-g] .g-hm-t.up{background:color-mix(in srgb,#3ee38a calc(var(--i,.3)*100%),#163a2b)}
:root[data-ui-g] .g-hm-t.dn{background:color-mix(in srgb,#ff5a72 calc(var(--i,.3)*100%),#3a1820)}
:root[data-ui-g][data-theme="light"] .g-hm-t.up{background:color-mix(in srgb,#0e8a57 calc(var(--i,.3)*100%),#c7ead7)}
:root[data-ui-g][data-theme="light"] .g-hm-t.dn{background:color-mix(in srgb,#d13a52 calc(var(--i,.3)*100%),#f4ccd3)}
/* colour-by-DELIVERY mode: an UNSIGNED conviction ramp (cyan), distinct from the signed move hues —
   overrides .up/.dn by higher specificity (attr + descendant). --d = the delivery intensity. */
:root[data-ui-g] .g-hm[data-mode="deliv"] .g-hm-t{background:color-mix(in srgb,#38bdf8 calc(var(--d,.15)*100%),#0b2733)}
:root[data-ui-g][data-theme="light"] .g-hm[data-mode="deliv"] .g-hm-t{background:color-mix(in srgb,#0284c7 calc(var(--d,.15)*100%),#d8ecf7)}
:root[data-ui-g] .g-hm-t:hover{filter:brightness(1.28);z-index:3;outline-color:var(--ink)}
/* heatmap controls: colour-by toggle + size selector (larger universes Pro-gated) */
:root[data-ui-g] .g-hm-ctrl{display:flex;justify-content:space-between;gap:var(--sp-4);flex-wrap:wrap;margin:var(--sp-1) 0 var(--sp-4)}
:root[data-ui-g] .g-hm-modes,:root[data-ui-g] .g-hm-sizes{display:inline-flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
:root[data-ui-g] .g-hm-ml{font-size:var(--fs-label);color:var(--ink-3);margin-right:var(--sp-2)}
:root[data-ui-g] .g-hm-mb{border:1px solid var(--line-2);background:var(--bg-2);color:var(--ink-2);font:600 var(--fs-label) var(--font);padding:var(--sp-2) var(--sp-4);border-radius:var(--r-round);cursor:pointer}
:root[data-ui-g] .g-hm-mb.on{color:var(--on-accent);background:linear-gradient(120deg,var(--accent),var(--accent-hi));border-color:transparent}
:root[data-ui-g] .g-hm-sb{font:600 var(--fs-label) var(--font);color:var(--ink-2);text-decoration:none;padding:var(--sp-2) var(--sp-4);border:1px solid var(--line-2);border-radius:var(--r-round);background:var(--bg-2);display:inline-flex;align-items:center;gap:var(--sp-2)}
:root[data-ui-g] .g-hm-sb.on{color:var(--on-accent);background:linear-gradient(120deg,var(--accent),var(--accent-hi));border-color:transparent}
:root[data-ui-g] .g-hm-prob{font:800 var(--fs-micro)/var(--lh-tight) var(--mono);letter-spacing:var(--ls-caps);padding:var(--sp-1) var(--sp-2);border-radius:var(--r-hair);background:color-mix(in srgb,var(--accent) 20%,transparent);color:var(--accent)}
:root[data-ui-g] .g-hm-sb.on .g-hm-prob{background:color-mix(in srgb,var(--on-accent) 26%,transparent);color:var(--on-accent)}
:root[data-ui-g][data-tier="free"] .g-hm-sb.g-hm-pro{pointer-events:none;opacity:.5;cursor:not-allowed}
:root[data-ui-g] .g-hm-tip-u{color:var(--accent);font-weight:700} :root[data-ui-g] .g-hm-tip-hd{margin-top:var(--sp-2);padding-top:var(--sp-2);border-top:1px solid var(--line);font:700 var(--fs-micro)/var(--lh-tight) var(--mono);letter-spacing:var(--ls-caps);color:var(--accent);text-transform:uppercase}
/* legend follows the mode (CSS sibling toggle — no JS innerHTML) */
:root[data-ui-g] .g-hm-legmode.deliv{display:none}
:root[data-ui-g] .g-hm[data-mode="deliv"] ~ .g-hm-leg .g-hm-legmode.move{display:none}
:root[data-ui-g] .g-hm[data-mode="deliv"] ~ .g-hm-leg .g-hm-legmode.deliv{display:inline}
/* The PLATE (see `_HM_PLATE`). The label's ratio must not depend on where the tile happens to sit
   on its ramp, so the label brings its own surface and the pair becomes `--ink` on `--bg-0` — a
   token pair, i.e. one the AA gate can already see. A text-shadow cannot do this job: WCAG does
   not count shadows, so a shadow makes text look legible while measuring exactly as it did. */
:root[data-ui-g] .g-hm-l{padding:0 var(--sp-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;font:700 var(--fs-micro)/var(--lh-tight) var(--font);letter-spacing:var(--ls-caps);color:var(--ink);border-radius:var(--r-hair);background:color-mix(in srgb,var(--bg-0) 82%,transparent)}
:root[data-ui-g][data-theme="light"] .g-hm-l{background:color-mix(in srgb,var(--bg-1) 82%,transparent)}
:root[data-ui-g] .g-hm-leg{display:flex;flex-wrap:wrap;gap:var(--sp-5);align-items:center;margin-top:var(--sp-3);font-size:var(--fs-label);color:var(--ink-3)}
:root[data-ui-g] .g-hm-leg i{display:inline-block;width:10px;height:10px;border-radius:var(--r-hair);margin-right:var(--sp-2);vertical-align:middle}
:root[data-ui-g] .g-hm-leg i.up{background:var(--up)} :root[data-ui-g] .g-hm-leg i.dn{background:var(--down)}
/* the residue drawers (Unclassified · ETFs & funds): open INLINE under the map, never a page jump */
:root[data-ui-g] .g-hm-resid{margin-top:var(--sp-3);border:1px solid var(--line);border-radius:var(--r-control);background:var(--bg-2)}
:root[data-ui-g] .g-hm-resid>summary{cursor:pointer;padding:var(--sp-3) var(--sp-4);font-size:var(--fs-label);color:var(--ink-2);list-style:none}
:root[data-ui-g] .g-hm-resid>summary::-webkit-details-marker{display:none}
:root[data-ui-g] .g-hm-resid>summary::before{content:"▸ ";color:var(--accent)}
:root[data-ui-g] .g-hm-resid[open]>summary::before{content:"▾ "}
:root[data-ui-g] .g-hm-resid>summary:hover{background:var(--bg-3)}
:root[data-ui-g] .g-hm-residwhy{margin:0;padding:0 var(--sp-4) var(--sp-3);font-size:var(--fs-label);line-height:var(--lh-body);color:var(--ink-3)}
:root[data-ui-g] .g-hm-residsyms{padding:0 var(--sp-4) var(--sp-3);max-height:132px;overflow:auto;font-size:var(--fs-label);line-height:var(--lh-read)}
:root[data-ui-g] .g-hm-sec{position:absolute;z-index:2;pointer-events:none;font:800 var(--fs-micro)/var(--lh-tight) var(--font);letter-spacing:var(--ls-caps);
  text-transform:uppercase;color:rgba(255,255,255,.92);text-shadow:0 1px 3px rgba(0,0,0,.78);padding:var(--sp-2) var(--sp-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
:root[data-ui-g][data-theme="light"] .g-hm-sec{color:rgba(10,20,15,.82);text-shadow:0 1px 2px rgba(255,255,255,.6)}
:root[data-ui-g] .g-hm-tip{position:absolute;z-index:10;pointer-events:none;background:var(--bg-2);border:1px solid var(--line-2);
  border-radius:var(--r-card);padding:var(--sp-3) var(--sp-4);box-shadow:var(--shadow-popover);min-width:132px;font-size:var(--fs-body)}
:root[data-ui-g] .g-hm-tip-s{font-weight:800;font-size:var(--fs-read);color:var(--ink);margin-bottom:var(--sp-2)}
:root[data-ui-g] .g-hm-tip-r{display:flex;justify-content:space-between;gap:var(--sp-5);color:var(--ink-3);padding:var(--sp-1) 0}
:root[data-ui-g] .g-hm-tip-r b{color:var(--ink-2);font-family:var(--mono);font-variant-numeric:tabular-nums}
/* ── regime band (below the today-core): rotation + breadth divergence ── */

:root[data-ui-g] .g-rband{margin-top:var(--sp-6);background:linear-gradient(165deg,var(--bg-2),var(--bg-1) 66%);border:1px solid var(--line);border-radius:var(--r-card);padding:var(--sp-5) var(--sp-5) var(--sp-5);position:relative;overflow:hidden}
:root[data-ui-g] .g-rband::before{content:"";position:absolute;inset:0 auto auto 0;width:60px;height:2px;background:linear-gradient(90deg,var(--accent-hi),transparent)}
:root[data-ui-g] .g-rband-h{display:flex;align-items:baseline;gap:var(--sp-4);flex-wrap:wrap;margin-bottom:var(--sp-4)}
:root[data-ui-g] .g-rband-h h2{margin:0;font-size:var(--fs-head);font-weight:800}
:root[data-ui-g] .g-rband-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-5)}
@media(max-width:820px){:root[data-ui-g] .g-rband-grid{grid-template-columns:1fr}}
:root[data-ui-g] .g-rband-card{background:var(--bg-0);border:1px solid var(--line);border-radius:var(--r-card);padding:var(--sp-4) var(--sp-5)}
:root[data-ui-g] .g-rband-ch{display:flex;align-items:center;gap:var(--sp-4);margin-bottom:var(--sp-3)}
:root[data-ui-g] .g-rband-ch h3{margin:0;font-size:var(--fs-read);font-weight:700}
:root[data-ui-g] .g-rband-ch .g-prov{margin-left:auto}
/* quadrant hue vars (a 4-hue palette, NOT the signed up/down) */
/* 🔴 R-10 — THIS IS WHERE THE SCALE HAD NO COLOURS OF ITS OWN. Every one of these four was a
   reserved token at dE 0.00: Leading WAS the accent, Improving WAS the up-candle, Weakening WAS
   the not-a-live-measurement amber. And Lagging was GREY here while its own pill was RED, so one
   quadrant had two colours depending on which component drew it. Now one scale, one source. */
:root[data-ui-g] .q-lead{--qc:var(--rot-lead)} :root[data-ui-g] .q-impr{--qc:var(--rot-impr)}
:root[data-ui-g] .q-weak{--qc:var(--rot-weak)} :root[data-ui-g] .q-lag{--qc:var(--rot-lag)}
:root[data-ui-g] .g-rrg{width:100%;aspect-ratio:460/380}
:root[data-ui-g] .g-rrg svg{width:100%;height:100%;display:block}
:root[data-ui-g] .g-rrg rect{fill:color-mix(in srgb,var(--qc) 9%,transparent)}
:root[data-ui-g] .g-rrg-ax{stroke:var(--line-2);stroke-width:1;stroke-dasharray:3 3}
:root[data-ui-g] .g-rrg-q{fill:var(--ink-3);font:700 var(--fs-micro) var(--font);letter-spacing:var(--ls-caps)}
/* register §11 I-07 — the axis furniture the map never had */
/* E-2, and this one no browser checker can see. `--ink-3` was solved to clear 4.5 with a worst
   case of 4.64, so multiplying it by an 0.85 opacity dropped the composited result to 3.95:1 in
   light and 4.32:1 in dark — at 9px, on the rotation map's axis ticks. `getComputedStyle` reports the
   UN-composited colour, so every automated contrast tool reads 4.64 and passes it; the failure is
   arithmetic on the declared values, not anything the DOM will tell you.
   The opacity is dropped rather than the colour re-solved: 0.85 of a token that was fitted to sit
   exactly on the floor is a second, invisible axis on top of a solved scale — the fix is to stop
   multiplying it, not to re-solve the token for a multiplier only this rule applies. */
:root[data-ui-g] .g-rrg-t{fill:var(--ink-3);font:500 var(--fs-micro) var(--font)}
:root[data-ui-g] .g-rrg-an{fill:var(--ink-3);font:600 var(--fs-micro) var(--font);letter-spacing:var(--ls-caps);opacity:.9}
:root[data-ui-g] .g-rot-tbl{width:100%;border-collapse:collapse;font-size:var(--fs-body)}
:root[data-ui-g] .g-rot-tbl th{position:sticky;top:0;z-index:1;background:var(--bg-2);
  color:var(--ink-3);font-weight:600;text-align:left;padding:var(--sp-3) var(--sp-3);white-space:nowrap;
  border-bottom:1px solid var(--line)}
:root[data-ui-g] .g-rot-tbl td{padding:var(--sp-3) var(--sp-3);border-bottom:1px solid var(--line);
  color:var(--ink-2);vertical-align:middle}
:root[data-ui-g] .g-rot-tbl th.r,:root[data-ui-g] .g-rot-tbl td.r{text-align:right}
:root[data-ui-g] .g-rot-tbl tr:last-child td{border-bottom:0}
:root[data-ui-g] .g-rot-fl{display:inline-block;font-size:var(--fs-fine);line-height:var(--lh-body);padding:0 var(--sp-3);
  margin:var(--sp-1) var(--sp-2) var(--sp-1) 0;border:1px solid var(--line-2);border-radius:var(--r-round);color:var(--ink-3);
  white-space:nowrap;cursor:help}
:root[data-ui-g] .g-rot-fl.up{color:var(--up);border-color:var(--up)}
:root[data-ui-g] .g-rot-fl.dn{color:var(--down);border-color:var(--down)}
:root[data-ui-g] .g-rot-none{color:var(--ink-3);opacity:.6}
:root[data-ui-g] .g-rrg-ax-note{margin:var(--sp-2) 0 0;font-size:var(--fs-label);color:var(--ink-3);line-height:var(--lh-body)}
:root[data-ui-g] .g-rrg-s{transition:opacity .15s;cursor:pointer;outline:none}
:root[data-ui-g] .g-rrg.iso .g-rrg-s{opacity:.09}
:root[data-ui-g] .g-rrg.iso .g-rrg-s.on{opacity:1}
:root[data-ui-g] .g-rrg-seg{fill:none;stroke:var(--qc);stroke-linecap:round}
:root[data-ui-g] .g-rrg-seg.last{filter:drop-shadow(0 0 3px var(--qc))}
:root[data-ui-g] .g-rrg-head{fill:var(--qc);stroke:var(--bg-0);stroke-width:1}
:root[data-ui-g] .g-rrg-s:focus-visible .g-rrg-head{stroke:var(--accent-hi);stroke-width:2.4}
:root[data-ui-g] .g-rrg-lbl{fill:var(--ink);font:700 var(--fs-micro) var(--font);paint-order:stroke;stroke:var(--bg-0);stroke-width:2.4px}
:root[data-ui-g] .g-rrg-leg{display:flex;flex-wrap:wrap;gap:var(--sp-4);align-items:center;margin-top:var(--sp-3);font-size:var(--fs-fine);color:var(--ink-2)}
:root[data-ui-g] .g-rrg-leg span{display:inline-flex;align-items:center;gap:var(--sp-2)}
:root[data-ui-g] .g-rrg-leg span::before{content:"";width:9px;height:9px;border-radius:50%;background:var(--qc)}
:root[data-ui-g] .g-rrg-note{color:var(--ink-3)} :root[data-ui-g] .g-rrg-note::before{display:none!important}
/* "see the full rotation" deep-link on the Today rotation card */
:root[data-ui-g] .g-rot-more{display:inline-block;margin-top:var(--sp-4);font-size:var(--fs-body);font-weight:600;color:var(--accent);text-decoration:none}
:root[data-ui-g] .g-rot-more:hover{text-decoration:underline}
/* ── the Markets rotation page ── */
:root[data-ui-g] .g-rot-sel{display:inline-flex;gap:var(--sp-2);background:var(--bg-2);border:1px solid var(--line-2);border-radius:var(--r-round);padding:var(--sp-2);margin:var(--sp-1) 0 var(--sp-5)}
:root[data-ui-g] .g-rot-pb{border:0;background:transparent;color:var(--ink-2);font:700 var(--fs-body) var(--font);padding:var(--sp-3) var(--sp-5);border-radius:var(--r-round);cursor:pointer;display:inline-flex;align-items:center;gap:var(--sp-3)}
:root[data-ui-g] .g-rot-pb.on{color:var(--on-accent);background:linear-gradient(120deg,var(--accent),var(--accent-hi))}
:root[data-ui-g] .g-rot-prob{font:800 var(--fs-micro)/var(--lh-tight) var(--mono);letter-spacing:var(--ls-caps);padding:var(--sp-1) var(--sp-2);border-radius:var(--r-control);background:color-mix(in srgb,var(--accent) 22%,transparent);color:var(--accent)}
:root[data-ui-g] .g-rot-pb.on .g-rot-prob{background:color-mix(in srgb,var(--on-accent) 26%,transparent);color:var(--on-accent)}
:root[data-ui-g] .g-rot-maps{position:relative}
:root[data-ui-g] .g-rot-map{display:none;max-width:560px;margin:0 auto}
:root[data-ui-g] .g-rot-map.on{display:block}
:root[data-ui-g] .g-rot-sum{display:flex;flex-wrap:wrap;gap:var(--sp-3);justify-content:center;margin:var(--sp-5) 0 var(--sp-2)}
:root[data-ui-g] .g-rot-sc{font-size:var(--fs-body);color:var(--ink-2);display:inline-flex;align-items:center;gap:var(--sp-2);background:var(--bg-2);border:1px solid var(--line);border-radius:var(--r-round);padding:var(--sp-2) var(--sp-4)}
:root[data-ui-g] .g-rot-sc::before{content:"";width:9px;height:9px;border-radius:50%;background:var(--qc)}
:root[data-ui-g] .g-rot-sc b{color:var(--ink);font-weight:800}
:root[data-ui-g] .g-rot-h{margin:var(--sp-6) 0 var(--sp-3);font-size:var(--fs-read)}
:root[data-ui-g] .g-rot-tbl{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:var(--r-card);overflow:hidden}
:root[data-ui-g] .g-rot-row{display:grid;grid-template-columns:1fr auto auto;gap:var(--sp-4);align-items:center;padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--line);font-size:var(--fs-read)}
:root[data-ui-g] .g-rot-row:last-child{border-bottom:0}
:root[data-ui-g] .g-rot-hd{background:var(--bg-2);font:700 var(--fs-fine) var(--font);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--ink-3)}
:root[data-ui-g] .g-rot-nm{font-weight:600}
:root[data-ui-g] .g-rot-q{font:600 var(--fs-fine)/var(--lh-tight) var(--mono);letter-spacing:var(--ls-caps);border-radius:var(--r-round);padding:var(--sp-2) var(--sp-3);text-align:center;white-space:nowrap;
  color:var(--qc);border:1px solid color-mix(in srgb,var(--qc) 45%,var(--line-2))}
:root[data-ui-g] .g-rot-v{font:500 var(--fs-label) var(--mono);color:var(--ink-3)} :root[data-ui-g] .g-rot-v b{color:var(--ink-2)}
/* breadth divergence chart */
:root[data-ui-g] .g-bd{width:100%;aspect-ratio:460/200}
:root[data-ui-g] .g-bd svg{width:100%;height:100%;display:block}
:root[data-ui-g] .g-bd-gap{fill:var(--acc-dim)}
:root[data-ui-g] .g-bd-mid{stroke:var(--line-2);stroke-width:1;stroke-dasharray:3 3}
:root[data-ui-g] .g-bd-price{fill:none;stroke:var(--accent);stroke-width:2;stroke-linejoin:round}
:root[data-ui-g] .g-bd-eff{fill:none;stroke:var(--candle-up);stroke-width:2;stroke-linejoin:round;opacity:.9}
:root[data-ui-g] .g-bd-dot{stroke:var(--bg-0);stroke-width:1.5}
:root[data-ui-g] .g-bd-dot.price{fill:var(--accent)} :root[data-ui-g] .g-bd-dot.eff{fill:var(--candle-up)}
:root[data-ui-g] .g-bd-leg{display:flex;flex-wrap:wrap;gap:var(--sp-5);margin-top:var(--sp-3);font-size:var(--fs-fine);color:var(--ink-2)}
:root[data-ui-g] .g-bd-leg span{display:inline-flex;align-items:center;gap:var(--sp-2)}
:root[data-ui-g] .g-bd-leg span::before{content:"";width:12px;height:3px;border-radius:var(--r-hair)}
:root[data-ui-g] .g-bd-leg .price::before{background:var(--accent)} :root[data-ui-g] .g-bd-leg .eff::before{background:var(--candle-up)}
:root[data-ui-g] .g-bd-read{font-size:var(--fs-body);color:var(--ink-2);margin:var(--sp-3) 0 0}
:root[data-ui-g] .g-bd-read b{color:var(--ink)}
/* breadth two-gauge read (the clear 'today' version) */
:root[data-ui-g] .g-bg{display:flex;flex-direction:column;gap:var(--sp-4)}
:root[data-ui-g] .g-bg-top{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:var(--sp-2)}
:root[data-ui-g] .g-bg-lab{font-size:var(--fs-body);color:var(--ink-2)}
:root[data-ui-g] .g-bg-val{font-weight:800;font-size:var(--fs-head)}
:root[data-ui-g] .g-bg-val.price{color:var(--accent)} :root[data-ui-g] .g-bg-val.eff{color:var(--candle-up)}
:root[data-ui-g] .g-bg-track{height:13px;background:var(--bg-3);border-radius:var(--r-round);overflow:hidden}
:root[data-ui-g] .g-bg-fill{display:block;height:100%;width:0;border-radius:var(--r-round);transition:width 1s cubic-bezier(.2,.7,.2,1)}
:root[data-ui-g] .g-bg-fill.price{background:linear-gradient(90deg,var(--accent),var(--accent-hi))}
:root[data-ui-g] .g-bg-fill.eff{background:var(--candle-up)}
:root[data-ui-g] .g-bg-read{font-size:var(--fs-body);color:var(--ink-2);margin:var(--sp-2) 0 0;line-height:var(--lh-body)}
:root[data-ui-g] .g-bg-read b.warn{color:var(--warn)} :root[data-ui-g] .g-bg-read b.ok{color:var(--up)} :root[data-ui-g] .g-bg-read b.acc{color:var(--candle-up)}
/* premium (Pro) relative-context block */
:root[data-ui-g] .g-pro-more{margin-top:var(--sp-4);padding:var(--sp-4) var(--sp-4) var(--sp-4);border:1px solid color-mix(in srgb,var(--accent) 34%,var(--line-2));
  border-radius:var(--r-card);background:color-mix(in srgb,var(--accent) 6%,var(--bg-0));position:relative}
:root[data-ui-g] .g-pro-more::before{content:"PRO";position:absolute;top:-8px;left:12px;font:800 var(--fs-micro)/var(--lh-tight) var(--mono);letter-spacing:var(--ls-caps);
  color:var(--on-accent);background:linear-gradient(120deg,var(--accent),var(--accent-hi));padding:var(--sp-2) var(--sp-3);border-radius:var(--r-control)}
/* S-BADGE 2026-08-05 (owner ruling): the ribbon is an UPGRADE PROMPT, so it is shown to the people
   who could upgrade and hidden from the ones who already did. Six ribbons on one page, while the
   header toggle already read "Pro", was six pieces of pure noise — the label answered a question
   the reader had settled. The BLOCK still renders in Pro (that is what was paid for); only the
   sales tag goes. In Free it is untouched: that is the one place it does its job. */
/* SUPERSEDED 2026-08-18 (owner ruling "comprehension should be free"): the block is no longer gated
   at all (`shell.py` .pro-more), so there is nothing left to upgrade TO and the ribbon advertised a
   gate that no longer exists. It now never renders, and the neutral treatment that used to be
   Pro-only is unconditional. `.free-only` is the only live tier-conditional that remains. */
:root[data-ui-g] .g-pro-more::before{content:none}
:root[data-ui-g] .g-pro-more{border-color:var(--line-2);
  background:var(--bg-0);margin-top:var(--sp-3)}
:root[data-ui-g] .g-ctx{display:flex;flex-direction:column;gap:var(--sp-2);font-size:var(--fs-body);color:var(--ink-2);margin-top:var(--sp-1)}
:root[data-ui-g] .g-ctx-row{display:flex;justify-content:space-between;gap:var(--sp-4)}
:root[data-ui-g] .g-ctx b{color:var(--ink)}
:root[data-ui-g] .g-ctx .warn{color:var(--warn)} :root[data-ui-g] .g-ctx .ok{color:var(--up)}
/* the reference chip — the ONE grammar on every Free number (Pro-only). Compact, muted, extremity is
   the only emphasis (a self-relative percentile is descriptive context, never good/bad). */
:root[data-ui-g] .g-refchip{margin-top:var(--sp-3);padding:var(--sp-3) var(--sp-3) var(--sp-3);border-radius:var(--r-card);
  border:1px solid color-mix(in srgb,var(--accent) 26%,var(--line-2));
  background:color-mix(in srgb,var(--accent) 5%,var(--bg-0));position:relative}
:root[data-ui-g] .g-refchip::before{content:"PRO";position:absolute;top:-7px;right:9px;
  font:800 var(--fs-micro)/var(--lh-tight) var(--mono);letter-spacing:var(--ls-caps);color:var(--on-accent);
  background:linear-gradient(120deg,var(--accent),var(--accent-hi));padding:var(--sp-1) var(--sp-2);border-radius:var(--r-control)}
:root[data-ui-g] .g-rc-1{display:flex;align-items:baseline;gap:var(--sp-3);flex-wrap:wrap}
:root[data-ui-g] .g-rc-p{font:800 var(--fs-body) var(--mono);color:var(--ink-2);letter-spacing:var(--ls-caps)}
:root[data-ui-g] .g-rc-p.hi{color:var(--accent)}
:root[data-ui-g] .g-rc-b{font-size:var(--fs-fine);color:var(--ink-3)}
:root[data-ui-g] .g-rc-2{margin-top:var(--sp-1);font-size:var(--fs-fine);color:var(--ink-3);display:flex;gap:var(--sp-1);flex-wrap:wrap}
:root[data-ui-g] .g-rc-tr{color:var(--ink-2)}
/* H-1 — the pool a placement was measured in. Deliberately quiet: the group size is the
   QUALIFIER on the rank, never a second number competing with it. Tokens only (a raw colour
   here renders as `inherit` on a Graphite page and the eye reads it as 'the chart is grey' —
   the defect `tests/test_graphite_token_closure.py` exists to catch). */
:root[data-ui-g] .g-pool-n{font-size:var(--fs-fine);color:var(--ink-3);white-space:nowrap}
:root[data-ui-g] .g-pool.mut{font-size:var(--fs-fine);color:var(--ink-3)}
/* Pro-Ads — a locked teaser (blurred real Pro block + 'See what Pro shows' CTA) shown to FREE users;
   clean in Pro (advertise=false) or gone in Pro (advertise=true / .free-only). Static blur (RM-safe). */
:root[data-ui-g] .g-proad{position:relative;overflow:hidden;border-radius:var(--r-card);margin-top:var(--sp-4)}
:root[data-ui-g][data-tier="free"] .g-proad .g-proad-body{filter:blur(5px);opacity:.5;pointer-events:none;user-select:none}
:root[data-ui-g] .g-proad-lock{display:none}
:root[data-ui-g][data-tier="free"] .g-proad-lock{display:flex;position:absolute;inset:0;flex-direction:column;
  align-items:center;justify-content:center;gap:var(--sp-2);text-align:center;padding:var(--sp-4);
  background:linear-gradient(180deg,color-mix(in srgb,var(--bg-0) 26%,transparent),color-mix(in srgb,var(--bg-0) 60%,transparent))}
:root[data-ui-g] .g-proad-cta{font:800 var(--fs-body) var(--font);letter-spacing:var(--ls-caps);color:var(--on-accent);border:0;cursor:pointer;
  background:linear-gradient(120deg,var(--accent),var(--accent-hi));padding:var(--sp-3) var(--sp-5);border-radius:var(--r-round);
  box-shadow:0 7px 20px -7px var(--accent)}
:root[data-ui-g] .g-proad-cta:hover{filter:brightness(1.08)}
:root[data-ui-g] .g-proad-cta:focus-visible{outline:2px solid var(--on-accent);outline-offset:2px}
:root[data-ui-g] .g-proad-sub{font-size:var(--fs-fine);color:var(--ink-2);max-width:290px;line-height:var(--lh-body)}

/* g-shell */
/* 🔴 THE CHROME IS ONE STICKY UNIT, and it is one because the old arrangement was MEASURED
   broken. `.g-top` was sticky at `top:0` and `.g-destbar` sticky at `top:52px` — two elements
   pinning themselves independently against a hard-coded guess at the other's height. The guess
   went stale (the header is 69px once the reading-mode control is in it, not 52), so at every
   scroll position past the top of the page the header sat over the TOP 17px OF EVERY NAV TAB:
   walked in Chrome at 1280, `.g-top` occupied 0-69 while the destbar pinned at 52-91. That is the
   S-UX-DEADZONE class this estate has paid for twice — a sticky thing sitting on controls.
   A wrapper cannot get this wrong: the bars stack in normal flow inside ONE sticky box, so the
   destbar sits under the header at whatever height the header happens to be, forever. It also
   means the chrome's bottom is a single number for the two sticky COLUMNS below to clear. */
:root[data-ui-g] .g-chrome{position:sticky;top:0;z-index:40}
/* R03: account/admin/feedback controls vary by audience. Wrap at any width when
   their actual content needs another row, including enlarged text on desktop. */
:root[data-ui-g] .g-top{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-5);
  padding:var(--sp-4) var(--sp-6);background:color-mix(in srgb,var(--bg-1) 84%,transparent);
  border-bottom:1px solid var(--line);backdrop-filter:blur(12px)}
@media(prefers-reduced-transparency:reduce),(prefers-contrast:more){
:root[data-ui-g] .g-top{background:var(--bg-1);backdrop-filter:none;border-bottom-color:var(--ink-3)}}
/* THE WORDMARK IS THE HOME BUTTON (S-NAVREFACTOR 2026-08-20). It was a `<span>`; it is now an
   `<a href="/dash/home">`, so every rule here is written to make an anchor look like the wordmark
   did — `text-decoration:none` and `color:inherit` are the whole diff, not a restyle. The tagline
   `<small>` is gone with its rule; nothing else in the estate emitted `.g-brand small`.
   On the home page itself the wordmark is wrapped in the page's `<h1>` (see `shell()`): `.g-brandh`
   exists only to stop a heading's UA margins and 2em type scale from moving the bar. The header's
   height is no longer a number anything else depends on — `.g-chrome` above made that structural —
   but it still sets where the destinations row begins, so a heading must not silently change it. */
:root[data-ui-g] .g-brand{font-weight:800;font-size:var(--fs-head);letter-spacing:.3px;text-shadow:0 0 22px var(--glow);
  color:inherit;text-decoration:none;display:inline-flex;align-items:center;flex:none;
  padding:var(--sp-1) var(--sp-2);margin-left:calc(var(--sp-2) * -1);border-radius:var(--r-control)}
:root[data-ui-g] .g-brand:hover{color:var(--accent);text-decoration:none}
:root[data-ui-g] .g-brand:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
:root[data-ui-g] .brand-tld{font-size:var(--fs-micro);font-weight:600;opacity:.78;vertical-align:baseline}
:root[data-ui-g] .brand-e{color:var(--accent)}
:root[data-ui-g] .g-brandh{margin:0;display:inline-flex;align-items:center;flex:none}
:root[data-ui-g] .g-badge{font:600 var(--fs-micro)/var(--lh-tight) var(--mono);letter-spacing:var(--ls-caps);color:var(--accent);
  background:var(--acc-dim);border:1px solid var(--accent);border-radius:var(--r-round);padding:var(--sp-2) var(--sp-3)}
:root[data-ui-g] .g-destbar{display:flex;padding:0 var(--sp-6);background:var(--bg-1);border-bottom:1px solid var(--line);overflow-x:auto;scrollbar-width:none}
:root[data-ui-g] .g-destbar::-webkit-scrollbar{display:none}
:root[data-ui-g] .g-dests{display:flex;gap:var(--sp-1);align-items:stretch}
/* 🔴 THE VERTICAL PADDING IS A FIXED POINT, and only the horizontal half is free. This row's
   height is half of the chrome's 108px, and TWO sticky columns — `.g-rail` in this file and
   `.g-vn-left` in `vnav.py` — clear that chrome at a MEASURED `top:112px`. Grow this row and both
   columns park their first rows underneath it: the S-UX-DEADZONE defect (visible, hover-looking,
   not clickable). So the S-NAVREFACTOR spacing pass widens the targets SIDEWAYS (`--sp-4` ->
   `--sp-5`) and leaves the row's height byte-identical. Five doors instead of six wins the room. */
:root[data-ui-g] .g-dests a{font:600 var(--fs-label)/var(--lh-tight) var(--font);letter-spacing:var(--ls-caps);text-transform:uppercase;
  color:var(--ink-2);padding:var(--sp-4) var(--sp-5);white-space:nowrap;border-bottom:2px solid transparent;text-decoration:none;
  display:inline-flex;align-items:center}
:root[data-ui-g] .g-dests a[aria-current]{color:var(--ink);border-bottom-color:var(--accent)}
:root[data-ui-g] .g-dests a:hover{color:var(--ink)}
:root[data-ui-g] .g-sp{flex:1}
:root[data-ui-g] .g-wrap{max-width:var(--pg-app);margin:0 auto;padding:var(--sp-6) var(--sp-6) 90px}
:root[data-ui-g] .g-grid{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--sp-5)}
@media(min-width:1200px){ :root[data-ui-g] .g-grid.has-rail{grid-template-columns:minmax(0,1fr) 320px} }
:root[data-ui-g] .g-rail{display:flex;flex-direction:column;gap:var(--sp-5)}
/* D312: a grid child is `stretch` until told otherwise, so a rail shorter than the page was a dead
   column by default (left panel 98.7% blank, Context rail 79%, both 7,882px tall). Full measurements
   and the four general laws are in PROJECT_STATE D312 — kept there, not here, because this file ships.
   `top:112px` clears the pinned chrome, RE-MEASURED at 108px (header 69 + destbar 39); the old 96
   was fitted to a 91.1px chrome and had silently drifted 12px UNDER the bars it exists to clear.
   `>*{flex:0 0 auto}` is LOAD-BEARING: the
   rail is a flex column, so bounding its height makes children SHRINK — it clipped a news headline
   while every metric read green. Scoped to >=1200px: below that, rails are not columns. */
:root[data-ui-g] .g-grid{align-items:start}
@media(min-width:1200px){
:root[data-ui-g] .g-rail{position:sticky;top:112px;max-height:calc(100vh - 124px);
  overflow-y:auto;overscroll-behavior:contain}
:root[data-ui-g] .g-rail>*{flex:0 0 auto}
}
/* B1b/C — the collapsible Context rail. The state class goes on the GRID, put there by JS from
   inside the same subtree, so none of this needs `:has()`; the vnav needed it only because its
   state had to travel from a button up to a sibling column. No-JS readers keep the expanded
   default, which is also the server default — the button is inert without a script and the rail
   simply stays open. */
:root[data-ui-g] .g-rail-tg{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);
  width:100%;font:600 var(--fs-label)/var(--lh-tight) var(--font);letter-spacing:var(--ls-caps);
  text-transform:uppercase;color:var(--ink-3);background:var(--bg-2);border:1px solid var(--line-2);
  border-radius:var(--r-control);padding:var(--sp-3) var(--sp-4);cursor:pointer}
:root[data-ui-g] .g-rail-tg:hover{color:var(--ink)}
:root[data-ui-g] .g-rail-ic{transition:transform .12s ease;transform:rotate(90deg)}
:root[data-ui-g] #g-rail-tg[aria-expanded="false"] .g-rail-ic{transform:rotate(-90deg)}
:root[data-ui-g] #g-rail-tg[aria-expanded="false"]+.g-rail-body{display:none}
@media(min-width:1200px){
/* collapsed: the column shrinks to the width of its own reopen affordance, exactly as the vnav
   does — the label turns vertical so the control stays legible and stays ON SCREEN. */
:root[data-ui-g] #g-rail-tg[aria-expanded="false"]{flex-direction:column;width:34px;margin:0 auto;
  padding:var(--sp-4) 0;justify-content:flex-start}
:root[data-ui-g] #g-rail-tg[aria-expanded="false"] .g-rail-lbl{writing-mode:vertical-rl;flex:none}
:root[data-ui-g] .g-grid.has-rail.g-rail-off{grid-template-columns:minmax(0,1fr) 46px}
:root[data-ui-g] .g-grid.g-vnav.has-rail.g-rail-off{grid-template-columns:max-content minmax(0,1fr) 46px}
:root[data-ui-g] body.g-vn-off .g-grid.g-vnav.has-rail.g-rail-off{grid-template-columns:46px minmax(0,1fr) 46px}
:root[data-ui-g] body:has(#g-vn-tg[aria-expanded="false"]) .g-grid.g-vnav.has-rail.g-rail-off{grid-template-columns:46px minmax(0,1fr) 46px}
}
:root[data-ui-g] .g-foot{max-width:var(--pg-app);margin:0 auto;padding:var(--sp-5) var(--sp-6);border-top:1px solid var(--line);
  color:var(--ink-3);font-size:var(--fs-label);text-align:center}
:root[data-ui-g]{--g-fab-clear:88px}
:root[data-ui-g] .g-foot{padding-bottom:calc(var(--sp-5) + var(--g-fab-clear))}
:root[data-ui-g] .g-seg{display:inline-flex;background:var(--bg-2);border:1px solid var(--line-2);border-radius:var(--r-round);padding:var(--sp-2);gap:var(--sp-1)}
/* "preview" tag on the Pro button: the switch is free, and the chrome must say so at a glance. */
:root[data-ui-g] .g-seg-tag{font:700 var(--fs-micro)/1 var(--mono);letter-spacing:var(--ls-caps);text-transform:uppercase;opacity:.72;margin-left:var(--sp-2)}
:root[data-ui-g] .g-seg button{border:0;background:transparent;color:var(--ink-3);font:700 var(--fs-label) var(--font);padding:var(--sp-3) var(--sp-4);border-radius:var(--r-round);cursor:pointer}
:root[data-ui-g] .g-seg button[aria-pressed="true"]{color:var(--on-accent);background:linear-gradient(120deg,var(--accent),var(--accent-hi))}
/* Reading density controls explanation visibility only; data-tier remains server-owned. */
:root[data-ui-g] .free-only{display:none}
:root[data-ui-g]:not([data-density="compact"]) .free-only{display:revert}
/* OWNER RULING 2026-08-18 — "comprehension should be free". `.pro-more` is, by its own definition
   (`components.pro_more`), the REFERENCE layer: "where a bare number gains its reference (average ·
   percentile · trend) so it becomes decision-useful". A percentile is what makes a raw number mean
   anything, so gating it made the Free tier less READABLE than free Trendlyne — the opposite of the
   positioning — and contradicted `/proof`'s published promise that evidence is never gated (§J).
   The reference layer is therefore always shown. Breadth (map size, `home/__init__.py:54`) stays
   the Pro lever: coverage is not comprehension. `.free-only` is untouched — Pro still reads denser. */
:root[data-ui-g] .pro-more{display:revert}
/* the classic-site directory (top-right dropdown) */
:root[data-ui-g] .g-classic{position:relative}
:root[data-ui-g] .g-classic>summary{list-style:none;cursor:pointer}
:root[data-ui-g] .g-classic>summary::-webkit-details-marker{display:none}
:root[data-ui-g] .g-classic-menu{position:absolute;right:0;top:calc(100% + 8px);z-index:50;width:min(780px,92vw);
  max-height:min(70vh,540px);overflow-y:auto;background:linear-gradient(165deg,var(--bg-2),var(--bg-1));
  border:1px solid var(--line-2);border-radius:var(--r-card);box-shadow:var(--shadow-modal);padding:var(--sp-5) var(--sp-5);scrollbar-width:thin}
:root[data-ui-g] .g-cl-head{font-size:var(--fs-body);color:var(--ink-3);margin-bottom:var(--sp-4);line-height:var(--lh-body)}
:root[data-ui-g] .g-cl-head b{color:var(--ink)}
:root[data-ui-g] .g-cl-home{margin-left:var(--sp-3);color:var(--accent);font-weight:600;white-space:nowrap;text-decoration:none}
:root[data-ui-g] .g-cl-home:hover{text-decoration:underline}
:root[data-ui-g] .g-cl-cols{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:var(--sp-5) var(--sp-5)}
:root[data-ui-g] .g-cl-col h4{margin:0 0 var(--sp-3);font:700 var(--fs-fine) var(--font);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--accent);border-bottom:1px solid var(--line);padding-bottom:var(--sp-2)}
:root[data-ui-g] .g-cl-col a{display:block;font-size:var(--fs-body);color:var(--ink-2);text-decoration:none;padding:var(--sp-2) 0;line-height:var(--lh-body)}
:root[data-ui-g] .g-cl-col a:hover{color:var(--accent)}
:root[data-ui-g] .g-cl-sub{font:600 var(--fs-micro)/var(--lh-tight) var(--mono);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--ink-3);margin:var(--sp-3) 0 var(--sp-2)}
/* ── accessibility primitives (register T-18/T-20) ──────────────────────────────────
   `.g-sr` is the clip pattern, ported verbatim from classic's `.uk-sr-only`
   (`ui_tokens.py:116-117`) — restore-don't-replace, and it keeps the two estates'
   a11y furniture identical while both are served.
   `.g-skip` is classic's `.uk-skip` (`ui_tokens.py:118-120`) with Graphite tokens: it
   parks off-screen and flies in on :focus, so it costs a keyboard user one Tab and a
   mouse user nothing. T-20 recorded that the redesign DROPPED this — it was present on
   6/6 classic doors and 0/46 Graphite ones. */
:root[data-ui-g] .g-sr{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
/* The page's own identity, ABOVE the fence — the first thing in `<main>`, so "which page am I
   on" is answered before the legal sentence and before any number. Owner ruling 2026-08-05. */
:root[data-ui-g] .g-crumb{display:flex;flex-wrap:wrap;align-items:center;
  font:500 var(--fs-label)/var(--lh-body) var(--font);color:var(--ink-3);margin:0 0 var(--sp-2)}
:root[data-ui-g] .g-crumb a{color:var(--ink-3);text-decoration:none}
:root[data-ui-g] .g-crumb a:hover{color:var(--ink);text-decoration:underline}
:root[data-ui-g] .g-crumb>*+*::before{content:"\203A";margin:0 var(--sp-3);color:var(--line-2)}
:root[data-ui-g] .g-crumb span[aria-current]{color:var(--ink-2);font-weight:600}
:root[data-ui-g] .g-h1{font:700 var(--fs-display)/var(--lh-body) var(--font);color:var(--ink);
  letter-spacing:-.01em;margin:0 0 var(--sp-4)}
/* ── S-PILLS (owner, 2026-08-05): THREE control families, each meaning ONE thing ───────────────
   The estate had five control classes drawn as two looks, so one shape carried three unrelated
   meanings and a reader had to click to find out what a control did:
     · g-dests / g-subbar  (navigate)          underline tabs
     · g-mtabs             (switch VIEW)       underline tabs  <- read as navigation
     · gw2-seg             (FILTER this page)  pill row
     · g-seg               (change PLAN)       pill row        <- a filter looked like an account switch
   The rule now: TABS mean "where you are". THIS box means "what you are looking at" — squared,
   bordered, and LABELLED, because an unlabelled row of choices states no function. The gradient
   pill is reserved for the one control that changes who you are, and it lives in the header.
   A label is not decoration here: it is the difference between a place and a setting. */
:root[data-ui-g] .g-ctl{display:inline-flex;align-items:center;gap:var(--sp-3);margin:0 var(--sp-4) var(--sp-4) 0;vertical-align:top}
:root[data-ui-g] .g-ctl-l{font:600 var(--fs-micro)/var(--lh-tight) var(--mono);letter-spacing:var(--ls-caps);text-transform:uppercase;
  color:var(--ink-3);white-space:nowrap}
:root[data-ui-g] .g-ctl-g{display:inline-flex;gap:var(--sp-1);background:var(--bg-0);
  border:1px solid var(--line);border-radius:var(--r-card);padding:var(--sp-1)}
:root[data-ui-g] .g-ctl-g a{font:600 var(--fs-label)/var(--lh-tight) var(--font);color:var(--ink-3);padding:var(--sp-3) var(--sp-4);
  border-radius:calc(var(--r-card) - var(--r-hair));text-decoration:none;white-space:nowrap}
:root[data-ui-g] .g-ctl-g a:hover{color:var(--ink);background:var(--bg-2);text-decoration:none}
:root[data-ui-g] .g-ctl-g a.on{color:var(--ink);background:var(--bg-3);box-shadow:inset 0 0 0 1px var(--line-2)}
:root[data-ui-g] .g-skip{position:fixed;left:-999px;top:0;z-index:100;background:var(--accent);
  color:var(--on-accent);font:600 var(--fs-read) var(--font);padding:var(--sp-3) var(--sp-5);border-radius:0 0 var(--r-card) 0;text-decoration:none}
:root[data-ui-g] .g-skip:focus{left:0}
:root[data-ui-g] .g-wrap:focus{outline:none}
/* H-7 (audit 2026-07-29, corrected): .g-top's ~489px intrinsic width set the ROOT scrollWidth on
   every Graphite page, so Blink shrink-to-fit rendered the whole document at 0.768x on <=488px
   phones (15px text at ~11.5px). The header WRAPS at phone widths instead. overflow-x:auto (the
   destbar's own pattern) was rejected here: the classic-site dropdown is an absolutely-positioned
   descendant of .g-top, and an overflow container — plus backdrop-filter's containing block —
   would clip the only directory to the ~80 classic routes. The destbar drops sticky at the same
   width so a two-row header can never bury the nav while scrolled. */
@media(max-width:560px){:root[data-ui-g] .g-classic-menu{position:fixed;left:2vw;right:2vw;width:96vw}
:root[data-ui-g] .g-top{flex-wrap:wrap}
/* the destbar used to drop sticky here on its own so "a two-row header can never bury the
   nav while scrolled". With one sticky unit that burial is impossible at any width, and the
   thing actually worth avoiding on a phone is a wrapped header PLUS a nav row pinning ~150px
   of a small viewport. So the unit unpins instead of one half of it.
   MEASURED at 375: the header wraps to 199px (brand+search / reading-mode+theme / directory) and
   the destbar scrolls sideways with all five tabs. Its height is a property of the header's CONTROL
   SET, not of this nav — hiding the `flex:1` spacer was tried here and moved it by exactly 0px,
   because 71+81+190 cannot share a 327px line whatever the spacer does. What this rule does fix is
   that those 199px now SCROLL AWAY: before it, `.g-top` was sticky at every width and a phone
   reader carried a 199px header over the page for its whole length. */
:root[data-ui-g] .g-chrome{position:static}}

/* Stacked navigation and enlarged owner controls need the same scrolling space
   as phones. Keep the full header accessible, then let it scroll off the content. */
@media(max-width:1199px){:root[data-ui-g] .g-chrome{position:static}}

/* ── REVEAL: a click must show its own result, at eye level ──────────────────────────────────
   ONE sticky unit owns the top 108px of every Graphite page (.g-chrome = .g-top 69px +
   .g-destbar 39px). Anchored
   navigation lands the target UNDER them, so a reader who clicks "Results" or a section link sees
   the row ABOVE the one they asked for — the click looks broken. Only stock_page had ever set a
   scroll margin (:1212); this sets it for every id-bearing target in the estate, once.
   The :target ring is the second half: on a long dense board, landing correctly is not enough —
   the eye needs to be told WHICH row answered. Both are inert when nothing is targeted. */
:root[data-ui-g] [id]{scroll-margin-top:120px}
:root[data-ui-g] :target{animation:g-reveal 1.9s ease-out 1}
:root[data-ui-g] .g-revealed{animation:g-reveal 1.9s ease-out 1}
@keyframes g-reveal{
  0%{box-shadow:0 0 0 3px var(--accent);border-radius:var(--r-card)}
  70%{box-shadow:0 0 0 3px var(--accent);border-radius:var(--r-card)}
  100%{box-shadow:0 0 0 0 transparent;border-radius:var(--r-card)}}
@media(prefers-reduced-motion:reduce){
  :root[data-ui-g] :target,:root[data-ui-g] .g-revealed{animation:none;outline:2px solid var(--accent);outline-offset:2px}}
/* g-conclusion — O-D2, owner 2026-09-06. Existing steps only. */
:root[data-ui-g] .g-regime-t{font-size:var(--fs-head);line-height:var(--lh-body);color:var(--ink-2)}
:root[data-ui-g] .g-regime-t b{color:var(--ink);font-size:var(--fs-display);line-height:var(--lh-tight)}
:root[data-ui-g] .g-side>.g-zone{max-block-size:26rem;display:flex;flex-direction:column}
:root[data-ui-g] .g-side>.g-zone>.g-zone-h{flex:none}
:root[data-ui-g] .g-side>.g-zone>.g-zone-b{min-height:0;overflow-y:auto;overscroll-behavior:auto;scrollbar-gutter:stable;scrollbar-color:var(--ink-3) var(--bg-1);scrollbar-width:thin}
@media(max-width:700px){:root[data-ui-g] .g-side>.g-zone{max-block-size:none}:root[data-ui-g] .g-side>.g-zone>.g-zone-b{overflow:visible;scrollbar-gutter:auto}:root[data-ui-g] .g-side .g-agenda,:root[data-ui-g] .g-side .g-filings,:root[data-ui-g] .g-side .g-wire,:root[data-ui-g] .g-side .g-changed{max-height:none;overflow:visible;scrollbar-gutter:auto}}
:root[data-ui-g] .g-side>.g-zone .g-zone-h h2{font-size:var(--fs-head);line-height:var(--lh-body)}
@media(min-width:1200px){:root[data-ui-g] .g-dash{grid-template-columns:minmax(0,1fr) 360px}}
/* g-home-craft — meetup-57d D0-2 / D0-4 / D0-5. Existing tokens only. */
:root[data-ui-g] .g-phase.lead{color:var(--rot-lead);border-color:color-mix(in srgb,var(--rot-lead) 45%,transparent)}
:root[data-ui-g] .g-phase.weak{color:var(--rot-weak);border-color:color-mix(in srgb,var(--rot-weak) 45%,transparent)}
:root[data-ui-g] .g-cv-tag.near{color:var(--rot-lead);border-color:color-mix(in srgb,var(--rot-lead) 45%,transparent)}
:root[data-ui-g] .g-cv-count b{color:var(--ink)}
:root[data-ui-g] .g-cv-tag.q{color:var(--ink);border-color:color-mix(in srgb,var(--ink-3) 55%,transparent)}
@media (max-width:560px){
:root[data-ui-g] .g-syma{position:relative}
:root[data-ui-g] .g-syma::after{content:"";position:absolute;left:0;right:0;top:50%;height:44px;transform:translateY(-50%);min-width:44px}
:root[data-ui-g] .g-syma:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
}
/* g-home-doors — a card must lead somewhere, and a paid door must say so. */
:root[data-ui-g] .g-absent{color:var(--ink-3);font-size:var(--fs-read);margin:var(--sp-3) 0}
:root[data-ui-g] .g-hd-strip{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin:var(--sp-3) 0 0}
:root[data-ui-g] .g-hd-door{display:inline-flex;align-items:center;flex-wrap:wrap;gap:var(--sp-2);min-height:44px;padding:var(--sp-1) var(--sp-3);border:1px solid var(--line);border-radius:var(--r-control);color:var(--accent);text-decoration:none;font-size:var(--fs-fine)}
:root[data-ui-g] .g-hd-door:hover,:root[data-ui-g] .g-hd-door:focus-visible{border-color:var(--accent);text-decoration:underline}
:root[data-ui-g] .g-hd-w{color:var(--ink-3)}
:root[data-ui-g] .g-hd-lock{border:1px solid var(--warn);border-radius:var(--r-round);color:var(--warn);font-size:var(--fs-micro);letter-spacing:var(--ls-caps);text-transform:uppercase;padding:0 var(--sp-2)}
@media (max-width:560px){:root[data-ui-g] .g-hd-door{width:100%}}
/* g-home-read — The Read + weakest-today. Existing tokens only; no new step. */
:root[data-ui-g] .g-hr-lead{font-size:var(--fs-head);line-height:var(--lh-read);color:var(--ink-2);margin:0 0 var(--sp-4)}
:root[data-ui-g] .g-hr-lead b{color:var(--ink);font-size:var(--fs-display);line-height:var(--lh-tight)}
:root[data-ui-g] .g-hr-v{color:var(--ink);font-family:var(--mono)}
:root[data-ui-g] .g-hr-why{color:var(--ink-3);font-size:var(--fs-micro)}
:root[data-ui-g] .g-hr-rows,:root[data-ui-g] .g-hr-ws{list-style:none;margin:0 0 var(--sp-4);padding:0;display:grid;gap:var(--sp-2)}
:root[data-ui-g] .g-hr-r,:root[data-ui-g] .g-hr-w{display:grid;grid-template-columns:minmax(9rem,1fr) auto minmax(0,1.4fr);gap:var(--sp-3);align-items:baseline;padding:var(--sp-2) 0;border-top:1px solid var(--line)}
:root[data-ui-g] .g-hr-rl,:root[data-ui-g] .g-hr-wl{color:var(--ink-2);font-size:var(--fs-read)}
:root[data-ui-g] .g-hr-rv{text-align:right}
:root[data-ui-g] .g-hr-rd,:root[data-ui-g] .g-hr-wy,:root[data-ui-g] .g-hr-wa{color:var(--ink-3);font-size:var(--fs-fine)}
:root[data-ui-g] .g-hr-place{display:block;color:var(--ink-2)}
:root[data-ui-g] .g-hr-doors{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin:0 0 var(--sp-4)}
:root[data-ui-g] .g-hr-door{display:inline-flex;align-items:center;min-height:44px;padding:0 var(--sp-3);border:1px solid var(--line);border-radius:var(--r-control);color:var(--accent);font-size:var(--fs-fine);text-decoration:none}
:root[data-ui-g] .g-hr-door:hover,:root[data-ui-g] .g-hr-door:focus-visible{border-color:var(--accent);text-decoration:underline}
:root[data-ui-g] .g-hr-weak{border-top:1px solid var(--line-2);padding-top:var(--sp-4)}
:root[data-ui-g] .g-hr-p{font-size:var(--fs-read);line-height:var(--lh-read);color:var(--ink-2);margin:0 0 var(--sp-3)}
:root[data-ui-g] .g-hr-foot{margin:0 0 var(--sp-3)}
:root[data-ui-g] .g-hr-fd>summary{cursor:pointer;color:var(--ink-3);font-size:var(--fs-fine);min-height:44px;display:flex;align-items:center}
:root[data-ui-g] .g-hr-fl{list-style:none;margin:var(--sp-2) 0;padding:0;display:grid;gap:var(--sp-1)}
:root[data-ui-g] .g-hr-f{display:grid;grid-template-columns:minmax(10rem,1fr) minmax(0,1.6fr);gap:var(--sp-3);padding:var(--sp-1) 0;border-top:1px solid var(--line);font-size:var(--fs-fine)}
:root[data-ui-g] .g-hr-fc{color:var(--ink-2)}
:root[data-ui-g] .g-hr-ok{color:var(--ink-3)}
:root[data-ui-g] .g-hr-late{color:var(--warn)}
:root[data-ui-g] .g-hr-miss{color:var(--ink-3);font-style:italic}
:root[data-ui-g] .g-hr-fn{color:var(--ink-3);font-size:var(--fs-micro);margin:var(--sp-2) 0 0}
@media (max-width:560px){:root[data-ui-g] .g-hr-f{grid-template-columns:1fr;row-gap:var(--sp-1)}}
@media (max-width:560px){:root[data-ui-g] .g-hr-r,:root[data-ui-g] .g-hr-w{grid-template-columns:1fr auto;row-gap:var(--sp-1)}
:root[data-ui-g] .g-hr-rd,:root[data-ui-g] .g-hr-wy{grid-column:1/-1}}

:root[data-ui-g] .g-zone[data-name="The read"]{position:relative}
:root[data-ui-g] .g-zone[data-name="The read"]>.g-zone-h{position:relative}
:root[data-ui-g] .g-hr-asof{font-size:var(--fs-label);color:var(--ink-2);margin:0 0 var(--sp-2)}
:root[data-ui-g] .g-hr-takeaway{font-size:var(--fs-head);line-height:var(--lh-body);margin:0 0 var(--sp-3)}
:root[data-ui-g] .g-hr-cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--sp-2)}
:root[data-ui-g] .g-hr-card{display:flex;flex-direction:column;min-width:0;background:var(--bg-1);border:1px solid var(--line);border-radius:var(--r-card);padding:var(--sp-3);color:var(--ink);text-decoration:none}
:root[data-ui-g] .g-hr-card:hover{border-color:var(--accent);text-decoration:none}
:root[data-ui-g] .g-hr-card h3{display:flex;justify-content:space-between;gap:var(--sp-2);font-size:var(--fs-read);font-weight:600;line-height:var(--lh-body);color:var(--ink-2);margin:0 0 var(--sp-2)}
:root[data-ui-g] .g-hr-amount{font-size:var(--fs-display);line-height:var(--lh-tight)}
:root[data-ui-g] .g-hr-caption,:root[data-ui-g] .g-hr-context{font-size:var(--fs-read);line-height:var(--lh-body);color:var(--ink-2);margin:var(--sp-2) 0}
:root[data-ui-g] .g-hr-graphic{margin-top:var(--sp-2)}
:root[data-ui-g] .g-hr-graphic svg{display:block;width:100%;height:var(--sp-5)}
:root[data-ui-g] .g-hr-track{fill:var(--bg-3)}
:root[data-ui-g] .g-hr-fill{fill:var(--accent)}
:root[data-ui-g] .g-hr-median{stroke:var(--ink);stroke-width:1;vector-effect:non-scaling-stroke}
:root[data-ui-g] .g-hr-state{font-size:var(--fs-label);line-height:var(--lh-body);color:var(--warn);margin:var(--sp-2) 0 0}
:root[data-ui-g] .g-hr-open{color:var(--accent)}
:root[data-ui-g] .g-hr-info{margin-left:auto;z-index:var(--z-float)}
:root[data-ui-g] .g-hr-info>summary{display:grid;place-items:center;width:44px;height:44px;border-radius:50%;cursor:pointer;color:var(--ink-2);font-weight:700;list-style:none}
:root[data-ui-g] .g-hr-info>summary::-webkit-details-marker{display:none}
:root[data-ui-g] .g-hr-info>summary:hover,:root[data-ui-g] .g-hr-info>summary:focus-visible{background:var(--bg-3);color:var(--accent)}
:root[data-ui-g] .g-hr-pop{position:absolute;z-index:var(--z-float);top:100%;right:0;width:min(32rem,calc(100% - var(--sp-6)));max-height:min(70vh,36rem);overflow:auto;padding:var(--sp-4);border:1px solid var(--line);border-radius:var(--r-card);background:var(--bg-2);box-shadow:var(--shadow-popover);font-size:var(--fs-read)}
:root[data-ui-g] .g-hr-meaning{margin-top:var(--sp-3)}
@media(max-width:700px){
:root[data-ui-g] .g-hr-cards{grid-template-columns:minmax(0,1fr)}
:root[data-ui-g] .g-hr-card{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:var(--sp-3);padding:var(--sp-4)}
:root[data-ui-g] .g-hr-card h3{align-self:center;margin:0}
:root[data-ui-g] .g-hr-caption,:root[data-ui-g] .g-hr-graphic,:root[data-ui-g] .g-hr-context{grid-column:1/-1;margin-block:var(--sp-2)}
:root[data-ui-g] .g-hr-graphic{margin-top:var(--sp-3)}
:root[data-ui-g] .g-hr-state{grid-column:1/-1;margin:var(--sp-1) 0}
}
/* g-home-datenav — a chosen day, and a strip that says what it covers. */
.g-dn>.g-zone-h{position:relative}
:root[data-ui-g] .g-side>.g-zone.g-dn{max-block-size:none}
:root[data-ui-g] .g-side>.g-zone.g-dn>.g-zone-b{overflow:visible;scrollbar-gutter:auto}
.g-dn>.g-zone-b{display:flex;flex-direction:column;gap:var(--sp-3);min-height:0;padding:var(--sp-3)}
.g-dn-bar{display:grid;gap:var(--sp-2);min-width:0;margin:0}
.g-dn-tools{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:0;min-width:0;border:1px solid var(--line);border-radius:var(--r-control);overflow:hidden;background:var(--bg-0)}
.g-dn-strip{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:2px;padding-block:var(--sp-1)}
.g-dn-step{display:inline-flex;align-items:center;justify-content:center;min-width:0;min-height:44px;padding:0 var(--sp-1);border:0;border-left:1px solid var(--line);border-radius:0;color:var(--accent);background:transparent;text-decoration:none;font-size:var(--fs-label);font-weight:600;white-space:nowrap}
.g-dn-step:first-child{border-left:0}
:root[data-ui-g] .g-dn .g-dn-picker{display:flex;justify-content:center;margin:0}
:root[data-ui-g] .g-dn .g-dn-picker input{width:min(100%,11rem);min-height:44px;padding:0 var(--sp-3);border:1px solid var(--line);border-radius:var(--r-control);background:var(--bg-2);color:var(--ink);font:inherit;text-align:center}
.g-dn-day{display:inline-flex;flex-direction:column;align-items:center;justify-content:center;min-width:0;min-height:44px;height:64px;padding:var(--sp-1) 2px;border:1px solid var(--line);border-radius:var(--r-control);color:var(--ink);background:var(--bg-1);text-decoration:none;line-height:var(--lh-tight)}
.g-dn-date{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:0;min-width:0;white-space:nowrap}
.g-dn-countline{display:flex;align-items:center;justify-content:center;min-width:0;white-space:nowrap}
.g-dn-day .g-dn-dow{max-width:100%;overflow:hidden;text-overflow:ellipsis;color:var(--ink-3);font-size:var(--fs-micro);letter-spacing:var(--ls-caps);text-transform:uppercase}
.g-dn-day .g-dn-dom{font-size:var(--fs-read);font-weight:700;color:var(--ink)}
.g-dn-day .g-dn-n{font-size:var(--fs-micro);font-weight:600;color:var(--ink-2)}
.g-dn-day.on .g-dn-dom{color:var(--accent)}
.g-dn-day:focus-visible,.g-dn-step:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.g-dn-step:hover{background:var(--bg-3);text-decoration:none}
.g-dn-day:hover{background:var(--bg-3);border-color:var(--accent);text-decoration:none}
.g-dn-day.none{color:var(--ink-3)}
.g-dn-day.uncovered{color:var(--ink-3);border-style:dashed}
.g-dn-day.on{border-color:var(--accent);background:var(--acc-dim);box-shadow:inset 0 -2px var(--accent);color:var(--accent);font-weight:600}
.g-dn-h3{font-size:var(--fs-read);margin:var(--sp-4) 0 var(--sp-3)}
.g-dn-table{width:100%;border-collapse:collapse;font-size:var(--fs-read);table-layout:fixed}
.g-dn-table th,.g-dn-table td{text-align:left;padding:var(--sp-3) var(--sp-2);border-bottom:1px solid var(--line);overflow-wrap:anywhere}
.g-dn-table thead th{font-size:var(--fs-label);color:var(--ink-2);font-weight:600;background:var(--bg-1)}
.g-dn-table th:first-child{width:40%}
.g-dn-count{font-size:var(--fs-read);color:var(--ink-2);margin:var(--sp-3) 0}
.g-dn-summary{display:flex;align-items:baseline;justify-content:space-between;gap:var(--sp-2) var(--sp-4);flex-wrap:wrap}
.g-dn-summary h3{margin:0;font-size:var(--fs-head)}
.g-dn-stats{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;color:var(--ink-3);font-size:var(--fs-label)}
.g-dn-stats b{color:var(--ink-2);font-weight:700}
.g-dn-events{list-style:none;margin:0;padding:0;border-top:1px solid var(--line)}
.g-dn-events li{display:grid;grid-template-columns:minmax(4.5rem,max-content) minmax(0,1fr);gap:var(--sp-2);align-items:center;padding:var(--sp-1) 0;border-bottom:1px solid var(--line)}
.g-dn-symbol{font-weight:600;min-width:0;max-width:9rem;overflow-wrap:anywhere}
.g-dn-event{display:flex;align-items:baseline;gap:var(--sp-2);min-width:0}
.g-dn-what{flex:1 1 auto;min-width:0;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow-wrap:anywhere}
.g-dn-event small{flex:none;white-space:nowrap;color:var(--ink-2);font-size:var(--fs-label)}
.g-dn-sel{font-weight:700}
.g-dn-tot{color:var(--ink-2);font-size:var(--fs-label);font-weight:400}
.g-dn-win{margin:0;color:var(--ink-2);font-size:var(--fs-label)}
.g-dn-next{margin:0;font-size:var(--fs-label);color:var(--ink-2)}
.g-dn-next a{display:block;min-height:44px;padding-block:var(--sp-2);box-sizing:border-box;color:var(--accent);font-weight:600;text-decoration:none}
.g-dn-next-none{padding-block:var(--sp-2)}
.g-dn-list{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:var(--sp-2)}
.g-dn-list li{display:inline-flex;align-items:center;gap:var(--sp-1)}
.g-dn-d{color:var(--ink-3);font-size:var(--fs-fine)}
.g-dn-info summary{display:grid;place-items:center;width:44px;height:44px;border-radius:50%;color:var(--ink-2);cursor:pointer;font-weight:700;list-style:none}
.g-dn-info summary::-webkit-details-marker{display:none}
.g-dn-info summary:hover,.g-dn-info summary:focus-visible{background:var(--bg-3);color:var(--accent)}
.g-dn-pop{position:absolute;z-index:var(--z-float);top:calc(100% - var(--sp-2));right:var(--sp-3);width:min(24rem,calc(100% - var(--sp-6)));padding:var(--sp-3);border:1px solid var(--line);border-radius:var(--r-control);background:var(--bg-2);box-shadow:var(--shadow-popover);font-size:var(--fs-fine)}
.g-dn-pop .g-prov{margin-bottom:var(--sp-2)}
.g-dn-cov{font-size:var(--fs-fine)}
.g-dn-cov ul{margin:var(--sp-1) 0 0;padding-left:var(--sp-4)}
.g-dn-foot{flex:none;display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);min-height:44px;padding:var(--sp-2) var(--sp-4);border-top:1px solid var(--line);background:var(--bg-1);font-size:var(--fs-label);color:var(--ink-2)}
.g-dn-foot a{margin-left:auto;color:var(--accent);font-weight:600;text-decoration:none}
:root[data-ui-g] .g-side>.g-zone.g-dn .g-dn-foot{padding-right:calc(64px + var(--sp-4))}
@media(max-width:700px){.g-dn-day{height:60px}.g-dn-foot,:root[data-ui-g] .g-side>.g-zone.g-dn .g-dn-foot{padding-inline:var(--sp-3)}}
/* g-home-personal — the reader's own intersection. Existing tokens only. */
:root[data-ui-g] .g-hp-p{font-size:var(--fs-read);line-height:var(--lh-read);color:var(--ink-2);margin:0 0 var(--sp-3)}
:root[data-ui-g] .g-hp-h{font-size:var(--fs-read);color:var(--ink-2);margin:0 0 var(--sp-2)}
:root[data-ui-g] .g-hp-h b{color:var(--ink);font-size:var(--fs-head)}
:root[data-ui-g] .g-hp-syms{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin:0 0 var(--sp-2)}
:root[data-ui-g] .g-hp-i{display:inline-flex;align-items:center;gap:var(--sp-1)}
:root[data-ui-g] .g-hp-sym,:root[data-ui-g] .g-hp-more{display:inline-flex;align-items:center;min-height:44px;padding:0 var(--sp-2)}
:root[data-ui-g] .g-hp-x{color:var(--ink-3);font-size:var(--fs-micro)}
:root[data-ui-g] .g-hp-row+.g-hp-row{border-top:1px solid var(--line);padding-top:var(--sp-3);margin-top:var(--sp-3)}

:root[data-ui-g] .g-record-table{width:100%;table-layout:auto}
:root[data-ui-g] .g-record-table :is(th,td){vertical-align:top}
:root[data-ui-g] .g-record-delivery :is(th,td):first-child{width:6%}
:root[data-ui-g] .g-record-delivery :is(th,td):nth-child(2){width:34%}
:root[data-ui-g] .g-record-delivery :is(th,td):nth-child(n+3){text-align:right;font-variant-numeric:tabular-nums}
:root[data-ui-g] .g-record-table .g-btn{display:inline-block;text-align:left;white-space:normal}
:root[data-ui-g] .g-zone-b{padding:var(--sp-5)}
:root[data-ui-g] :is(.g-btn,.g-chip,.g-dn-step){line-height:var(--lh-body)}
:root[data-ui-g] :is(input,select,textarea){font-size:var(--fs-read)}
:root[data-ui-g] :is(.g-scr,.g-dn-table,.g-tbl) :is(td,th){padding-block:var(--sp-3);line-height:var(--lh-body)}
:root[data-ui-g] .g-sector-window{margin-top:var(--sp-3)}
:root[data-ui-g] .g-sector-window summary{cursor:pointer;font-size:var(--fs-body)}
:root[data-ui-g] .g-sec{flex-wrap:wrap;gap:var(--sp-2);min-width:0}
:root[data-ui-g] .g-sec small{display:block;font-size:var(--fs-micro);color:var(--ink-2)}
:root[data-ui-g] .g-table-wrap{overflow:auto;max-width:100%}
:root[data-ui-g] :is(.g-dn-picker,.g-record-picker){display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-3);margin-block:var(--sp-3)}
:root[data-ui-g] :is(.g-dn-picker,.g-record-picker) :is(input,select){background:var(--bg-2);color:var(--ink);border:1px solid var(--line);padding:var(--sp-3)}
:root[data-ui-g] .g-map-dialog{background:var(--bg-1);color:var(--ink);border:1px solid var(--line);border-radius:var(--r-card);width:96vw;max-width:none;height:94vh;padding:var(--sp-5)}
:root[data-ui-g] .g-map-dialog::backdrop{background:var(--bg-0);opacity:.9}
:root[data-ui-g] .g-map-dialog .g-hm{height:68vh;min-height:360px}
:root[data-ui-g] .g-map-close{position:sticky;top:0;float:right;z-index:var(--z-float)}
:root[data-ui-g] .g-map-dialog .g-hm-ctrl{padding-right:var(--sp-6);flex-wrap:wrap}
:root[data-ui-g] .g-dn[aria-busy="true"]{opacity:.65}

:root[data-ui-g] .g-hi{margin-left:auto;position:relative;z-index:18}
:root[data-ui-g] .g-hi>summary{list-style:none;width:24px;height:24px;border:1px solid var(--line-2);border-radius:50%;display:grid;place-items:center;color:var(--ink-3);font:700 var(--fs-label) var(--font);cursor:pointer;background:var(--bg-1)}
:root[data-ui-g] .g-hi>summary::-webkit-details-marker{display:none}
:root[data-ui-g] .g-hi[open]>summary{color:var(--accent);border-color:var(--accent)}
:root[data-ui-g] .g-hi-pop{position:absolute;right:0;top:32px;width:min(310px,80vw);padding:var(--sp-4);border:1px solid var(--line-2);border-radius:var(--r-card);background:var(--bg-2);box-shadow:var(--shadow-popover);color:var(--ink-2);font-size:var(--fs-body);line-height:var(--lh-body)}
:root[data-ui-g] .g-hi-pop p{margin:0}
:root[data-ui-g] .g-hi.g-hq>summary{position:relative;width:15px;height:15px;border:1px solid var(--line);background:transparent;color:var(--ink-3);font:600 9px/1 var(--font);opacity:.5;transition:opacity .15s}
:root[data-ui-g] .g-hi.g-hq>summary::after{content:"";position:absolute;inset:-7px}
:root[data-ui-g] .g-hi.g-hq>summary:hover,:root[data-ui-g] .g-hi.g-hq>summary:focus-visible,:root[data-ui-g] .g-hi.g-hq[open]>summary{opacity:1;color:var(--ink-2);border-color:var(--line-2)}
:root[data-ui-g] .g-hi.g-hq .g-hi-pop{top:22px;z-index:30;text-align:left;font-weight:400;max-height:min(60vh,440px);overflow:auto}
:root[data-ui-g] .g-hi.g-hq .g-hi-pop p+p{margin-top:var(--sp-2)}
:root[data-ui-g] .g-deck>.g-cell>.g-hi{position:static;margin:0}
:root[data-ui-g] .g-deck>.g-cell>.g-hi>summary{position:absolute;top:var(--sp-2);left:var(--sp-2)}
:root[data-ui-g] .g-deck>.g-cell>.g-hi .g-hi-pop{left:var(--sp-2);right:auto;top:calc(var(--sp-2) + 22px);width:min(320px,calc(100% - 2*var(--sp-2)))}
:root[data-ui-g] .g-deck>.g-cell:has(>.g-hi[open]){z-index:31}
:root[data-ui-g] .g-deck>.g-cell>.g-lab{padding-left:var(--sp-5)}
:root[data-ui-g] .g-pl-asof{font:500 var(--fs-fine)/var(--lh-tight) var(--mono);color:var(--ink-3);white-space:nowrap}
:root[data-ui-g] .g-asof{display:inline-block;margin-left:var(--sp-2);padding:0 var(--sp-1);border:1px solid var(--line-2);border-radius:var(--r-control);font:600 var(--fs-micro)/var(--lh-tight) var(--mono);letter-spacing:0;text-transform:none;color:var(--ink-2);white-space:nowrap}
:root[data-ui-g] .g-hc-counts{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));border:1px solid var(--line);border-radius:var(--r-control);overflow:hidden;margin-bottom:var(--sp-3)}
:root[data-ui-g] .g-hc-count{display:flex;gap:var(--sp-2);align-items:baseline;padding:var(--sp-3);color:var(--ink-2);text-decoration:none;border-right:1px solid var(--line);min-width:0}
:root[data-ui-g] .g-hc-count:last-child{border-right:0}
:root[data-ui-g] .g-hc-count b{font-size:var(--fs-head);color:var(--ink)}
:root[data-ui-g] .g-hc-count span{font-size:var(--fs-micro);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
:root[data-ui-g] .g-hc-flowvals{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-3)}
:root[data-ui-g] .g-hc-flowvals>span{display:flex;justify-content:space-between;align-items:baseline;padding:var(--sp-3);border:1px solid var(--line);border-radius:var(--r-control)}
:root[data-ui-g] .g-hc-flowvals small{color:var(--ink-3);font-weight:700}
:root[data-ui-g] .g-hc-zero{height:8px;margin:var(--sp-4) var(--sp-2) var(--sp-2);position:relative;border-radius:99px;background:var(--line-2)}
:root[data-ui-g] .g-hc-zero>span{position:absolute;left:50%;top:-4px;width:1px;height:16px;background:var(--ink-3)}
:root[data-ui-g] .g-hc-zero>i{position:absolute;top:-3px;width:14px;height:14px;border-radius:50%;transform:translateX(-50%);background:var(--accent)}
:root[data-ui-g] .g-hc-zero>i.dn{background:var(--down)}
:root[data-ui-g] .g-hc-flowfoot{margin:0;color:var(--ink-3);font-size:var(--fs-fine);text-align:center}
:root[data-ui-g] .g-hc-regime{font-size:var(--fs-read);color:var(--ink);margin:0 0 var(--sp-3)}
:root[data-ui-g] .g-hc-links{display:flex;gap:var(--sp-5);flex-wrap:wrap;margin:0}
:root[data-ui-g] .g-hc-wrong{display:flex;align-items:baseline;gap:var(--sp-3)}
:root[data-ui-g] .g-hc-wrong b{font-size:var(--fs-display);color:var(--accent)}
:root[data-ui-g] .g-hc-wrong span{color:var(--ink-2)}
:root[data-ui-g] .g-dv-head,:root[data-ui-g] .g-dv-row{display:grid;grid-template-columns:1.75rem minmax(0,1fr) 5.25rem 3rem;align-items:center;gap:var(--sp-2)}
:root[data-ui-g] .g-dv-head{padding:0 var(--sp-2) var(--sp-2);color:var(--ink-3);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:var(--ls-caps)}
:root[data-ui-g] .g-dv-head span:nth-child(n+3){text-align:right;text-transform:none;letter-spacing:0;line-height:var(--lh-tight)}
:root[data-ui-g] .g-dv-meta{display:flex;align-items:center;gap:var(--sp-2);min-height:44px;color:var(--ink-2);font-size:var(--fs-label)}
:root[data-ui-g] .g-dv-meta .g-hi{margin-left:0}
:root[data-ui-g] .g-dv-meta .g-hi-pop{left:0;right:auto}
:root[data-ui-g] .g-dv-meta-t{min-width:0;overflow-wrap:anywhere}
:root[data-ui-g] .g-dv-today{text-align:right;white-space:nowrap;color:var(--ink-2)}
:root[data-ui-g] .g-dv-row{min-height:44px;padding:var(--sp-2);border-top:1px solid var(--line)}
:root[data-ui-g] .g-dv-rank{color:var(--ink-3);text-align:center}
:root[data-ui-g] .g-dv-sym{font-weight:700;color:var(--accent);text-decoration:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
:root[data-ui-g] .g-dv-val{text-align:right;font-weight:700;white-space:nowrap}
:root[data-ui-g] .g-dv-card .g-hd-strip{position:sticky;bottom:0;justify-content:flex-end;background:linear-gradient(0deg,var(--bg-1) 72%,transparent);padding-top:var(--sp-3)}
:root[data-ui-g] .g-map-content.compact .g-hm{height:320px}
:root[data-ui-g] .g-hm-brief{margin:var(--sp-2) 0;color:var(--ink-3);font-size:var(--fs-fine)}
/* Long truth-state text must wrap inside Home's narrow desktop rail. */
:root[data-ui-g] .g-side .g-prov{white-space:normal;min-width:0;overflow-wrap:anywhere}
@media(max-width:560px){
  /* The picker stays visible; ticker chips keep their own horizontal scroller. */
  :root[data-ui-g] .g-ribbon{flex-wrap:wrap;min-width:0}
  :root[data-ui-g] .g-rib-scroll{flex:1 1 100%;max-width:100%}
  :root[data-ui-g] .g-feedpick{min-width:0}
  :root[data-ui-g] .g-regime{flex-wrap:wrap;align-items:flex-start}
  :root[data-ui-g] .g-regime-dot{margin-top:var(--sp-3)}
  :root[data-ui-g] .g-regime-t{flex:1 1 80%;min-width:0;overflow-wrap:break-word}
  :root[data-ui-g] .g-hc-counts{grid-template-columns:repeat(2,minmax(0,1fr))}
  :root[data-ui-g] .g-hc-count:nth-child(2){border-right:0}
  :root[data-ui-g] .g-hc-count:nth-child(-n+2){border-bottom:1px solid var(--line)}
  :root[data-ui-g] .g-hc-flowvals{grid-template-columns:1fr}
  :root[data-ui-g] .g-map-content.compact .g-hm{height:260px}
}
@font-face{font-family:'Patearn Display';src:url('/static/fonts/display-700.b27da29ede.woff2') format('woff2');font-weight:700;font-style:normal;font-display:optional;unicode-range:U+0020-007E,U+00A0-00FF,U+2013-2014,U+2018-201D,U+2022,U+2026,U+20B9}:root[data-ui-g]{--font-display:'Patearn Display',Georgia,'Times New Roman',serif}:root[data-ui-g] .g-h1{font-family:var(--font-display);font-synthesis:none}/* g-phone-fit: existing roles only, phone widths only */
@media(max-width:600px){
:root[data-ui-g] .g-dests{flex:1 1 auto;min-width:0;flex-wrap:wrap}
:root[data-ui-g] .g-dests a{flex:1 1 auto}
:root[data-ui-g] .g-top{row-gap:var(--sp-3)}
:root[data-ui-g] .g-top .g-btn{margin-top:0}
:root[data-ui-g] :is(.g-zone-h,.g-feat-h){row-gap:var(--sp-2)}
:root[data-ui-g] .g-zone[data-name="Strength"]>.g-zone-b>.g-ctl{display:flex;flex-wrap:wrap;max-width:100%;row-gap:var(--sp-2)}
:root[data-ui-g] .g-zone[data-name="Strength"]>.g-zone-b>.g-ctl>.g-ctl-g{display:flex;flex:1 1 100%;flex-wrap:wrap;min-width:0;max-width:100%;box-sizing:border-box}
:root[data-ui-g] .g-zone[data-name="Strength"]>.g-zone-b>.g-ctl>.g-ctl-g>a{display:inline-flex;align-items:center;justify-content:center;flex:1 1 auto;min-height:44px;box-sizing:border-box}
:root[data-ui-g] .g-wrap{padding-bottom:var(--sp-6)}
:root[data-ui-g] .g-scr-sort{display:inline-block;min-width:24px}
:root[data-ui-g] :is(.g-crumb a,.g-scr-sort,.g-scr-q,.g-tk-q,.g-nudge-x,.g-featv>p>a){position:relative}
:root[data-ui-g] :is(.g-crumb a,.g-scr-sort,.g-scr-q,.g-tk-q,.g-nudge-x,.g-featv>p>a)::after{content:"";position:absolute;left:50%;top:50%;width:max(100%,24px);height:max(100%,24px);transform:translate(-50%,-50%)}
}
:root[data-ui-g] .g-datechip{display:inline-flex;align-items:center;gap:var(--sp-2);padding:var(--sp-1) var(--sp-3);border:1px solid var(--line);border-radius:var(--r-round);font:500 var(--fs-micro) var(--mono);color:var(--ink-2);white-space:nowrap}
:root[data-ui-g] .g-datechip[data-state="stale"],:root[data-ui-g] .g-datechip[data-state="sample"]{color:var(--warn)}
:root[data-ui-g] .g-datechip .g-measure-info button{color:inherit;border:0;background:transparent;padding:0;min-width:24px;min-height:24px}
@media(max-width:600px){:root[data-ui-g] .g-top{flex-wrap:wrap}:root[data-ui-g] .g-top .g-datechip{order:99;flex:1 0 100%;justify-content:flex-start;border:0;border-radius:0;padding:0}}

/* g-table-kit — register X-1 */
:root[data-ui-g] .g-tk-bar{display:flex;align-items:center;gap:var(--sp-3);margin:0 0 var(--sp-3);flex-wrap:wrap}
:root[data-ui-g] .g-tk-f{flex:0 1 200px;min-width:120px;font:inherit;font-size:var(--fs-body);
  padding:var(--sp-2) var(--sp-3);border:1px solid var(--line-2);border-radius:var(--r-control);background:var(--bg-2);
  color:var(--ink)}
:root[data-ui-g] .g-tk-f:focus{outline:2px solid var(--accent);outline-offset:1px}
:root[data-ui-g] .g-tk-n{font-size:var(--fs-label);color:var(--ink-3);white-space:nowrap}
:root[data-ui-g] .g-tk-cap{font-size:var(--fs-label);color:var(--ink-3);white-space:nowrap;
  border-left:1px solid var(--line-2);padding-left:var(--sp-3)}
:root[data-ui-g] .g-tk-csv,:root[data-ui-g] .g-tk-pick>summary,
:root[data-ui-g] .g-tk-reset{font:inherit;font-size:var(--fs-label);color:var(--ink-3);cursor:pointer;
  border:1px solid var(--line-2);border-radius:var(--r-control);padding:var(--sp-1) var(--sp-3);background:var(--bg-2);
  user-select:none;list-style:none}
:root[data-ui-g] .g-tk-csv:hover,:root[data-ui-g] .g-tk-pick>summary:hover,
:root[data-ui-g] .g-tk-reset:hover{color:var(--ink);border-color:var(--ink-3)}
:root[data-ui-g] .g-tk-pick{position:relative;margin-left:auto}
:root[data-ui-g] .g-tk-pick>summary::-webkit-details-marker{display:none}
:root[data-ui-g] .g-tk-menu{position:absolute;right:0;top:calc(100% + 4px);z-index:30;
  min-width:170px;max-height:280px;overflow:auto;padding:var(--sp-3);border:1px solid var(--line-2);
  border-radius:var(--r-card);background:var(--bg-1);box-shadow:var(--shadow-raised)}
:root[data-ui-g] .g-tk-menu label{display:flex;align-items:center;gap:var(--sp-3);font-size:var(--fs-label);
  color:var(--ink-2);padding:var(--sp-1) 0;cursor:pointer;white-space:nowrap}
:root[data-ui-g] .g-tk-reset{display:block;width:100%;margin-top:var(--sp-3);text-align:center}
:root[data-ui-g] .g-tk-filters{position:relative}
:root[data-ui-g] .g-tk-filters>summary,:root[data-ui-g] .g-tk-clear,
:root[data-ui-g] .g-tk-apply{font:inherit;font-size:var(--fs-label);color:var(--ink);cursor:pointer;
  border:1px solid var(--line-2);border-radius:var(--r-control);padding:var(--sp-2) var(--sp-3);
  background:var(--bg-2);min-height:24px}
:root[data-ui-g] .g-tk-filters>summary{list-style:none;user-select:none}
:root[data-ui-g] .g-tk-filters>summary::-webkit-details-marker{display:none}
:root[data-ui-g] .g-tk-filters>summary:focus-visible,:root[data-ui-g] .g-tk-clear:focus-visible,
:root[data-ui-g] .g-tk-apply:focus-visible,:root[data-ui-g] .g-tk-filter-field :focus-visible{
  outline:2px solid var(--accent);outline-offset:1px}
:root[data-ui-g] .g-tk-filter-panel{position:absolute;top:calc(100% + 4px);right:0;z-index:32;
  box-sizing:border-box;width:min(620px,90vw);max-height:min(70vh,520px);overflow:auto;padding:var(--sp-3);
  border:1px solid var(--line-2);border-radius:var(--r-card);background:var(--bg-1);
  box-shadow:var(--shadow-raised)}
:root[data-ui-g] .g-tk-filters:not([open])>.g-tk-filter-panel{display:none}
:root[data-ui-g] .g-tk-filter-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:var(--sp-3)}
:root[data-ui-g] .g-tk-filter-field{display:flex;flex-direction:column;gap:var(--sp-1);
  color:var(--ink-2);font-size:var(--fs-label);min-width:0}
:root[data-ui-g] .g-tk-filter-field input,:root[data-ui-g] .g-tk-filter-field select{
  font:inherit;color:var(--ink);background:var(--bg-2);border:1px solid var(--line-2);
  border-radius:var(--r-control);padding:var(--sp-2);min-width:0;width:100%}
:root[data-ui-g] .g-tk-filter-field [aria-invalid="true"]{border-color:var(--accent)}
:root[data-ui-g] .g-tk-filter-error{color:var(--ink-2);font-size:var(--fs-label);margin:var(--sp-2) 0}
:root[data-ui-g] .g-tk-filter-error:empty{display:none}
:root[data-ui-g] .g-tk-coverage{font-size:var(--fs-label);color:var(--ink-3)}
:root[data-ui-g] .g-tk-empty{flex-basis:100%;font-size:var(--fs-label);color:var(--ink-2)}
:root[data-ui-g] .g-tk-empty[hidden]{display:none}
:root[data-ui-g] .g-tk-clear[hidden]{display:none}
@media(max-width:900px){:root[data-ui-g] .g-tk-filters{flex:1 0 100%;min-width:0}
  :root[data-ui-g] .g-tk-filter-panel{position:static;width:100%}}
@media(max-width:600px){
  :root[data-ui-g] .g-tk-filter-grid{grid-template-columns:minmax(0,1fr)}
  :root[data-ui-g] .g-tk-filters>summary,:root[data-ui-g] .g-tk-clear,
  :root[data-ui-g] .g-tk-apply,:root[data-ui-g] .g-tk-filter-field input,
  :root[data-ui-g] .g-tk-filter-field select{min-height:44px}}
:root[data-ui-g] table[data-gtk] th{cursor:pointer;user-select:none}
:root[data-ui-g] table[data-gtk] th:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
:root[data-ui-g] table[data-gtk] th[aria-sort]{color:var(--ink)}
:root[data-ui-g] table[data-gtk] th[aria-sort]::after{font-size:var(--fs-micro);margin-left:var(--sp-2)}
:root[data-ui-g] table[data-gtk] th[aria-sort="ascending"]::after{content:"\25B2"}
:root[data-ui-g] table[data-gtk] th[aria-sort="descending"]::after{content:"\25BC"}
/* The `?` is a real <button> now (register T-11) — but it must render EXACTLY as the old
   <span> did. Everything below the first line is button-chrome reset; the second line is the
   old rule, byte-for-byte. This lane is structural: the mark keeps its 9px super size, its
   colour and its spacing, and T-14 (the 24x24 touch-target row) is deliberately NOT
   pre-empted here — resizing it is a density change and belongs to the owner's opt-in. */
/* D168-a: the affordance is a lowercase `i`, not `?`. A page carrying hundreds of question marks
   reads as interrogative and competes with the data; the mark should be available, not loud.
   Quiet at rest — no fill, no border, muted ink — and it earns a hairline ring and the accent
   only on hover / focus / open. Fixed 14px box inside a ~20px line, so adding it to 58 row labels
   cannot shift a single row's height. It stays a real <button> (T-11): the previous <span>+title
   reached a hovering mouse user and nobody else. */
:root[data-ui-g] .g-tk-q{appearance:none;background:none;border:0;padding:0;font-family:var(--font);
  line-height:var(--lh-tight)}
:root[data-ui-g] .g-tk-q{display:inline-flex;align-items:center;justify-content:center;
  width:14px;height:14px;margin-left:var(--sp-3);font-size:var(--fs-label);font-style:italic;
  color:var(--ink-3);cursor:help;border-radius:50%;vertical-align:-2px}
:root[data-ui-g] .g-tk-q:hover{color:var(--accent);box-shadow:0 0 0 1px var(--line-2)}
:root[data-ui-g] .g-tk-q:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
:root[data-ui-g] .g-tk-q[aria-expanded="true"]{color:var(--accent);box-shadow:0 0 0 1px var(--accent)}
/* The definition, once disclosed. `hidden` while closed, so it stays out of innerText — the
   CSV export and the sort comparator both read that. */
:root[data-ui-g] .g-tk-def{display:block;font-weight:400;font-size:var(--fs-label);line-height:var(--lh-body);
  color:var(--ink-2);background:var(--bg-1);border:1px solid var(--line-2);border-radius:var(--r-control);
  padding:var(--sp-3) var(--sp-3);margin-top:var(--sp-2);max-width:280px;white-space:normal;text-align:left;
  text-transform:none;letter-spacing:normal}
:root[data-ui-g] .g-tk-def[hidden]{display:none}
/* The shell owns `.g-sr`, but a framed table can be rendered in a test or a fragment with no
   shell around it — the caption must be invisible there too, never a stray line of text. */
:root[data-ui-g] caption.g-sr,caption.g-sr{position:absolute!important;width:1px;height:1px;
  padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
:root[data-ui-g] tr.g-tk-hide,:root[data-ui-g] tr.g-tk-filter-hide,
:root[data-ui-g] tr[hidden],:root[data-ui-g] .g-tk-coff{display:none}
@media (prefers-reduced-motion:reduce){:root[data-ui-g] .g-tk-menu{box-shadow:none}}

/* g-rotation-play — register §1a */
:root[data-ui-g] .g-rp-bar{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;margin:var(--sp-3) 0 var(--sp-2)}
:root[data-ui-g] .g-rp-play{font:inherit;font-size:var(--fs-body);font-weight:600;cursor:pointer;
  border:1px solid var(--accent);border-radius:var(--r-control);padding:var(--sp-2) var(--sp-4);background:var(--bg-2);
  color:var(--accent)}
:root[data-ui-g] .g-rp-play:hover{background:var(--accent);color:var(--bg-1)}
:root[data-ui-g] .g-rp-play:focus-visible,:root[data-ui-g] .g-rp-sp:focus-visible,
:root[data-ui-g] .g-rp-scrub:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
:root[data-ui-g] .g-rp-spd{display:inline-flex;border:1px solid var(--line-2);border-radius:var(--r-control);
  overflow:hidden}
:root[data-ui-g] .g-rp-sp{font:inherit;font-size:var(--fs-label);cursor:pointer;border:0;padding:var(--sp-2) var(--sp-3);
  background:transparent;color:var(--ink-3)}
:root[data-ui-g] .g-rp-sp.on{background:var(--accent);color:var(--bg-1)}
:root[data-ui-g] .g-rp-month{font-size:var(--fs-label);font-weight:600;color:var(--ink);min-width:62px;
  text-align:center;border:1px solid var(--line-2);border-radius:var(--r-control);padding:var(--sp-2) var(--sp-3)}
:root[data-ui-g] .g-rp-scrub{flex:1 1 160px;min-width:120px;accent-color:var(--accent)}
:root[data-ui-g] .g-rp-read{margin:var(--sp-1) 0 0;font-size:var(--fs-label);color:var(--ink-3);min-height:16px}
:root[data-ui-g] .g-rp-read b{color:var(--ink)}
:root[data-ui-g] .g-rp-tip{position:absolute;z-index:40;display:none;pointer-events:none;
  max-width:230px;font-size:var(--fs-label);line-height:var(--lh-body);padding:var(--sp-3) var(--sp-3);border:1px solid var(--line-2);
  border-radius:var(--r-card);background:var(--bg-1);color:var(--ink-2);box-shadow:var(--shadow-raised)}
:root[data-ui-g] .g-rp-wrap{position:relative}
:root[data-ui-g] .g-rp-values{margin:var(--sp-3) 0;color:var(--ink-2);font-size:var(--fs-label)}
:root[data-ui-g] .g-rp-values summary{cursor:pointer;min-height:44px;display:flex;align-items:center;
  color:var(--accent);font-weight:600}
:root[data-ui-g] .g-rp-values summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
:root[data-ui-g] .g-rp-values p{margin:var(--sp-2) 0}
:root[data-ui-g] .g-rp-values-scroll{max-width:100%;overflow-x:auto}
:root[data-ui-g] .g-rp-values table{border-collapse:collapse;font-variant-numeric:tabular-nums}
:root[data-ui-g] .g-rp-values th,:root[data-ui-g] .g-rp-values td{padding:var(--sp-2);
  border-bottom:1px solid var(--line-2);text-align:left;white-space:nowrap}
:root[data-ui-g] .g-rp-leader{stroke:var(--ink-3);stroke-width:.8;stroke-opacity:.7;pointer-events:none}
@media (prefers-reduced-motion:reduce){
  :root[data-ui-g] .g-rp-play{transition:none}
}

/* g-charts positional family — register §2d · §1c (S-P3) */
:root[data-ui-g] .g-ch-sc,:root[data-ui-g] .g-ch-ln,:root[data-ui-g] .g-ch-rd{
  width:100%;height:auto;display:block;background:var(--bg-0);border:1px solid var(--line);
  border-radius:var(--r-card)}
:root[data-ui-g] .g-ch-t{fill:var(--ink-3);font:500 var(--fs-micro) var(--font);opacity:.9}
:root[data-ui-g] .g-ch-ax{fill:var(--ink-3);font:600 var(--fs-micro) var(--font);letter-spacing:var(--ls-caps)}
:root[data-ui-g] .g-ch-ax.lo{fill:var(--up)}
:root[data-ui-g] .g-ch-ax.hi{fill:var(--warn)}
:root[data-ui-g] .g-ch-q{font:700 var(--fs-micro) var(--font);letter-spacing:var(--ls-caps);opacity:.85}
:root[data-ui-g] .g-ch-q.up{fill:var(--up)} :root[data-ui-g] .g-ch-q.down{fill:var(--down)}
:root[data-ui-g] .g-ch-q.warn{fill:var(--warn)} :root[data-ui-g] .g-ch-q.accent{fill:var(--accent)}
/* overlay(end_labels=True) — the name in the right gutter, on the line's own last y. The two
   text rows stay in the ink ramp rather than the series colour: a 2px line has no contrast
   floor to meet, an 11px label does, and the same AA measurement that demoted --accent-hi in
   compare_ux applies to every saturated hue in LINE_12. The LEADER carries the colour. */
:root[data-ui-g] .g-ch-en{fill:var(--ink);font:700 var(--fs-micro) var(--font)}
:root[data-ui-g] .g-ch-ev{fill:var(--ink-3);font:500 var(--fs-micro) var(--font);
  font-variant-numeric:tabular-nums}
/* the gutter swatch — a graphic carrying the line's colour, so the label text does not have to */
:root[data-ui-g] .g-ch-esw{stroke:var(--bg-0);stroke-width:.5}
/* overlay(focus=True) — hold one line, drop the rest to the 0.20 the rotation apparatus uses.
   Driven from the line itself AND from its legend chip; `:has` scopes both to this one figure,
   and a browser without `:has` simply never dims, which is the pre-2026-08-23 picture. */
:root[data-ui-g] .g-ch-foc .g-ch-s{transition:opacity .12s ease}
:root[data-ui-g] .g-ch-foc .g-ch-lg{cursor:default}
:root[data-ui-g] .g-ch-foc button.g-ch-lg{font:inherit;color:inherit;background:none;border:0;
  padding:var(--sp-2) var(--sp-3);cursor:pointer}
:root[data-ui-g] .g-ch-foc button.g-ch-lg:focus-visible{outline:2px solid var(--accent);
  outline-offset:2px;border-radius:var(--r-control)}
:root[data-ui-g] .g-ch-foc:not(:has(.g-ch-lg:focus)):has(.g-ch-s:hover) .g-ch-s{opacity:.2}
:root[data-ui-g] .g-ch-foc:not(:has(.g-ch-lg:focus)):has(.g-ch-s:hover) .g-ch-s:hover{opacity:1}
:root[data-ui-g] .g-ch-foc:not(:has(.g-ch-lg:focus)):has(.g-ch-lg:hover) .g-ch-lg{opacity:.45}
:root[data-ui-g] .g-ch-foc:not(:has(.g-ch-lg:focus)):has(.g-ch-lg:hover) .g-ch-lg:hover{opacity:1}
:root[data-ui-g] .g-ch-foc:has(.g-ch-lg:focus) .g-ch-lg{opacity:.45}
:root[data-ui-g] .g-ch-foc:has(.g-ch-lg:focus) .g-ch-lg:focus{opacity:1}
@media (prefers-reduced-motion:reduce){
  :root[data-ui-g] .g-ch-foc .g-ch-s{transition:none}
}
:root[data-ui-g] .g-ch-ref{stroke:var(--line-2);stroke-width:1;stroke-dasharray:4 3}
:root[data-ui-g] .g-ch-diag{stroke:var(--line-2);stroke-width:1}
:root[data-ui-g] .g-ch-dot{fill:var(--ink-2);fill-opacity:.8;stroke:var(--bg-0);stroke-width:1}
:root[data-ui-g] .g-ch-dot.up{fill:var(--up)} :root[data-ui-g] .g-ch-dot.down{fill:var(--down)}
:root[data-ui-g] .g-ch-dot.warn{fill:var(--warn)} :root[data-ui-g] .g-ch-dot.accent{fill:var(--accent)}
:root[data-ui-g] .g-ch-dl{fill:var(--ink-2);font:600 var(--fs-micro) var(--font);paint-order:stroke;
  stroke:var(--bg-0);stroke-width:2.4px}
:root[data-ui-g] .g-ch-pt{cursor:default}
:root[data-ui-g] a .g-ch-pt,:root[data-ui-g] a .g-ch-lane,:root[data-ui-g] a .g-ch-spoke{cursor:pointer}
:root[data-ui-g] a:hover .g-ch-dot,:root[data-ui-g] a:focus-visible .g-ch-dot{stroke:var(--accent);stroke-width:2}
/* lanes */
:root[data-ui-g] .g-ch-zlo{fill:var(--up);opacity:.07}
:root[data-ui-g] .g-ch-zhi{fill:var(--warn);opacity:.07}
:root[data-ui-g] .g-ch-zbrk{fill:var(--down);opacity:.09}
:root[data-ui-g] .g-ch-grid{stroke:var(--line);stroke-width:1;stroke-dasharray:3 4}
:root[data-ui-g] .g-ch-grid.mid{stroke-dasharray:1 5}
/* strip(axis=True) furniture — the scale drawn inside the picture instead of described under
   it. The tick text scales with the viewBox, so a 900-unit box shrunk onto a phone would put
   a ~4px glyph on screen: the media query raises the USER-UNIT size only where the container
   is small, which is the one place CSS can see what SVG coordinates cannot. */
:root[data-ui-g] .g-ch-wash{fill:var(--down);opacity:.1}
:root[data-ui-g] .g-ch-mark{stroke:var(--ink-3);stroke-width:1;stroke-dasharray:2 3;opacity:.75}
:root[data-ui-g] .g-ch-mt{font-weight:600}
:root[data-ui-g] .g-ch-now{font-weight:700;fill:var(--ink)}
@media (max-width:760px){
  /* `--fs-micro` (the axis-tick role) is 12 USER UNITS here since D1087 (0.75rem; it was 9), and
     a 958-unit box on a 375px phone scales by 0.39 — so the tick that reads 12px on a laptop
     renders at 4.7px on a handset. The step up to `--fs-display` (28 units) is not a display
     claim, it is roughly the laptop's 12px arriving on screen (28 x 0.39 = 10.9px). */
  :root[data-ui-g] .g-ch-t{font-size:var(--fs-display)}
  :root[data-ui-g] .g-ch-rb{min-height:52px}
}
:root[data-ui-g] .g-ch-trk{stroke:var(--line-2);stroke-width:1}
:root[data-ui-g] .g-ch-lnm{fill:var(--ink);font:600 var(--fs-fine) var(--font)}
:root[data-ui-g] .g-ch-lv{fill:var(--ink);font:700 var(--fs-fine) var(--mono)}
:root[data-ui-g] .g-ch-lr{fill:var(--ink-3);font:500 var(--fs-micro) var(--font)}
:root[data-ui-g] .g-ch-poc{fill:none;stroke:var(--accent);stroke-width:1.2}
:root[data-ui-g] .g-ch-reg.mr{fill:var(--accent)} :root[data-ui-g] .g-ch-reg.trend{fill:var(--warn)}
:root[data-ui-g] .g-ch-path{fill:none;stroke:var(--ink-3);stroke-width:2;stroke-opacity:.55}
:root[data-ui-g] .g-ch-was{fill:var(--bg-0);stroke:var(--ink-3);stroke-width:1.4}
:root[data-ui-g] circle.g-ch-now{fill:var(--ink-2);stroke:var(--bg-0);stroke-width:1.2}
:root[data-ui-g] .g-ch-lane.up .g-ch-path,:root[data-ui-g] .g-ch-spoke.up line{stroke:var(--up)}
:root[data-ui-g] .g-ch-lane.dn .g-ch-path,:root[data-ui-g] .g-ch-spoke.dn line{stroke:var(--down)}
:root[data-ui-g] .g-ch-lane.up .g-ch-now,:root[data-ui-g] .g-ch-spoke.up .g-ch-sd{fill:var(--up)}
:root[data-ui-g] .g-ch-lane.dn .g-ch-now,:root[data-ui-g] .g-ch-spoke.dn .g-ch-sd{fill:var(--down)}
:root[data-ui-g] a:hover .g-ch-lnm{fill:var(--accent)}
/* radial */
:root[data-ui-g] .g-ch-ring{fill:none;stroke:var(--line-2);stroke-width:1;stroke-opacity:.7}
:root[data-ui-g] .g-ch-ring.in{stroke:var(--up);stroke-dasharray:2 6}
:root[data-ui-g] .g-ch-ring.mid{stroke-dasharray:2 6}
:root[data-ui-g] .g-ch-ring.out{stroke:var(--warn);stroke-dasharray:4 4}
:root[data-ui-g] .g-ch-spoke line{stroke:var(--ink-3);stroke-width:2;stroke-opacity:.6}
:root[data-ui-g] .g-ch-sd{fill:var(--ink-2)}
:root[data-ui-g] .g-ch-brk{fill:none;stroke:var(--down);stroke-width:2}
/* channel */
:root[data-ui-g] .g-ch-cn{width:100%;height:auto;display:block;background:var(--bg-0);
  border:1px solid var(--line);border-radius:var(--r-card)}
:root[data-ui-g] .g-ch-band{fill:var(--accent);opacity:.08}
/* the detected structure (`wave`): the legs read as the CLAIM, so they are the strongest line on
   the figure, while the price it was detected in stays the quiet one underneath. */
:root[data-ui-g] .g-ch-wave{stroke:var(--accent);stroke-width:2;stroke-linejoin:round}
:root[data-ui-g] .g-ch-wpt{fill:var(--accent);stroke:var(--bg-0);stroke-width:1.5}
:root[data-ui-g] .g-ch-wlab{fill:var(--accent);font:700 var(--fs-fine) var(--mono)}
:root[data-ui-g] .g-ch-cref{stroke:var(--line-2);stroke-width:1;stroke-dasharray:4 4}
:root[data-ui-g] .g-ch-cref.up{stroke:var(--up)} :root[data-ui-g] .g-ch-cref.warn{stroke:var(--warn)}
:root[data-ui-g] .g-ch-cref.accent{stroke:var(--accent);stroke-dasharray:2 3}
:root[data-ui-g] .g-ch-cline{stroke:var(--accent);stroke-width:1.6}
:root[data-ui-g] .g-ch-travel{stroke-width:2.4;stroke-linejoin:round;stroke-linecap:round;opacity:.92}
:root[data-ui-g] .g-ch-travel-dot{stroke:var(--bg-0);stroke-width:1.2}
/* ribbon() — register §3a (S-P4): the per-session drill strip */
:root[data-ui-g] .g-ch-rb{width:100%;height:auto;display:block;background:var(--bg-0);
  border:1px solid var(--line);border-radius:var(--r-card)}
:root[data-ui-g] .g-ch-rb-c.up{fill:var(--up)} :root[data-ui-g] .g-ch-rb-c.dn{fill:var(--down)}
:root[data-ui-g] .g-ch-rb-c:hover{opacity:1 !important}
:root[data-ui-g] .g-ch-rb-on{stroke:var(--ink);stroke-width:1.2}
:root[data-ui-g] .g-ch-rb-mid{stroke:var(--line-2);stroke-width:.6;stroke-dasharray:3 3}
:root[data-ui-g] .g-ch-sw{display:inline-block;width:14px;height:9px;border-radius:var(--r-hair);
  margin-right:var(--sp-3);vertical-align:middle}
:root[data-ui-g] .g-ch-sw.dn{background:var(--down)} :root[data-ui-g] .g-ch-sw.up{background:var(--up)}
:root[data-ui-g] .g-ch-sw.md{background:var(--line-2)}
/* rulers() — several measures on one pinned 0-100 axis, with historic days marked on the same
   ruler. Everything here reuses the lanes/strip vocabulary; only the mark is new, and it is a
   quiet tick because the thing being compared to today must not out-shout today. */
:root[data-ui-g] .g-ch-rl{width:100%;height:auto;display:block;background:var(--bg-0);
  border:1px solid var(--line);border-radius:var(--r-card)}
:root[data-ui-g] .g-ch-rk{stroke:var(--ink-3);stroke-width:1.4;opacity:.8}
:root[data-ui-g] .g-ch-rkl{opacity:.75}
/* stack_grid — value in the cell, colour only ranks it (register §4b, S-P6) */
:root[data-ui-g] .g-ch-sg{width:100%;height:auto;display:block;background:var(--bg-0);
  border:1px solid var(--line);border-radius:var(--r-card)}
:root[data-ui-g] .g-ch-sg-h{fill:var(--ink-3);font:600 var(--fs-micro) var(--font)}
:root[data-ui-g] .g-ch-sg-r{fill:var(--ink-2);font:500 var(--fs-micro) var(--font)}
:root[data-ui-g] .g-ch-sg-c.up{fill:var(--up)} :root[data-ui-g] .g-ch-sg-c.dn{fill:var(--down)}
:root[data-ui-g] .g-ch-sg-c:hover{opacity:1 !important}
:root[data-ui-g] .g-ch-sg-na{fill:var(--bg-3);opacity:.38}
:root[data-ui-g] .g-ch-sg-v{fill:var(--ink);font:600 var(--fs-micro) var(--mono);
  font-variant-numeric:tabular-nums;pointer-events:none}
/* fan() — register §3f (S-P4): event-time cohort paths + IQR band */
:root[data-ui-g] .g-ch-fan{width:100%;height:auto;display:block;background:var(--bg-0);
  border:1px solid var(--line);border-radius:var(--r-card)}
:root[data-ui-g] .g-ch-fan-zero{stroke:var(--line-2);stroke-width:1}
:root[data-ui-g] .g-ch-fan-t{fill:var(--ink-3);font:var(--fs-fine) var(--mono)}
:root[data-ui-g] .g-ch-fan-band{fill:var(--accent);opacity:.16}
:root[data-ui-g] .g-ch-fan-ln{stroke-width:2.4}
:root[data-ui-g] .g-ch-fan-a{stroke:var(--accent)} :root[data-ui-g] i.g-ch-fan-a{background:var(--accent)}
:root[data-ui-g] .g-ch-fan-b{stroke:var(--ink-3);stroke-width:1.5} :root[data-ui-g] i.g-ch-fan-b{background:var(--ink-3)}
:root[data-ui-g] .g-ch-fan-c{stroke:var(--up);stroke-width:1.6} :root[data-ui-g] i.g-ch-fan-c{background:var(--up)}
:root[data-ui-g] .g-ch-fan-d{stroke:var(--down);stroke-width:1.6} :root[data-ui-g] i.g-ch-fan-d{background:var(--down)}
:root[data-ui-g] .g-ch-fan-dot{fill:var(--warn);opacity:.85}
:root[data-ui-g] .g-ch-foc:not(:has(.g-ch-lg:focus)):has(.g-ch-lg[data-i="0"]:hover) .g-ch-s:not([data-i="0"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:has(.g-ch-lg[data-i="0"]:focus) .g-ch-s:not([data-i="0"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:not(:has(.g-ch-lg:focus)):has(.g-ch-lg[data-i="1"]:hover) .g-ch-s:not([data-i="1"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:has(.g-ch-lg[data-i="1"]:focus) .g-ch-s:not([data-i="1"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:not(:has(.g-ch-lg:focus)):has(.g-ch-lg[data-i="2"]:hover) .g-ch-s:not([data-i="2"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:has(.g-ch-lg[data-i="2"]:focus) .g-ch-s:not([data-i="2"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:not(:has(.g-ch-lg:focus)):has(.g-ch-lg[data-i="3"]:hover) .g-ch-s:not([data-i="3"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:has(.g-ch-lg[data-i="3"]:focus) .g-ch-s:not([data-i="3"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:not(:has(.g-ch-lg:focus)):has(.g-ch-lg[data-i="4"]:hover) .g-ch-s:not([data-i="4"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:has(.g-ch-lg[data-i="4"]:focus) .g-ch-s:not([data-i="4"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:not(:has(.g-ch-lg:focus)):has(.g-ch-lg[data-i="5"]:hover) .g-ch-s:not([data-i="5"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:has(.g-ch-lg[data-i="5"]:focus) .g-ch-s:not([data-i="5"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:not(:has(.g-ch-lg:focus)):has(.g-ch-lg[data-i="6"]:hover) .g-ch-s:not([data-i="6"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:has(.g-ch-lg[data-i="6"]:focus) .g-ch-s:not([data-i="6"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:not(:has(.g-ch-lg:focus)):has(.g-ch-lg[data-i="7"]:hover) .g-ch-s:not([data-i="7"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:has(.g-ch-lg[data-i="7"]:focus) .g-ch-s:not([data-i="7"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:not(:has(.g-ch-lg:focus)):has(.g-ch-lg[data-i="8"]:hover) .g-ch-s:not([data-i="8"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:has(.g-ch-lg[data-i="8"]:focus) .g-ch-s:not([data-i="8"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:not(:has(.g-ch-lg:focus)):has(.g-ch-lg[data-i="9"]:hover) .g-ch-s:not([data-i="9"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:has(.g-ch-lg[data-i="9"]:focus) .g-ch-s:not([data-i="9"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:not(:has(.g-ch-lg:focus)):has(.g-ch-lg[data-i="10"]:hover) .g-ch-s:not([data-i="10"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:has(.g-ch-lg[data-i="10"]:focus) .g-ch-s:not([data-i="10"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:not(:has(.g-ch-lg:focus)):has(.g-ch-lg[data-i="11"]:hover) .g-ch-s:not([data-i="11"]){opacity:.2}
:root[data-ui-g] .g-ch-foc:has(.g-ch-lg[data-i="11"]:focus) .g-ch-s:not([data-i="11"]){opacity:.2}

:root[data-ui-g] .g-ch-sp{width:100%;height:auto;display:block;background:var(--bg-0);
  border:1px solid var(--line);border-radius:var(--r-card)}
:root[data-ui-g] .g-ch-sp-ax{stroke:var(--line);stroke-width:2}
:root[data-ui-g] .g-ch-sp-iqr{fill:var(--ink);opacity:.06}
:root[data-ui-g] .g-ch-sp-tk{stroke:var(--ink-3);stroke-width:1.5;opacity:.55}
:root[data-ui-g] .g-ch-sp-med{stroke:var(--ink-2);stroke-width:1.5;stroke-dasharray:5 3}
:root[data-ui-g] .g-ch-sp-hist{fill:none;stroke:var(--ink-3);stroke-width:1.2}
:root[data-ui-g] .g-ch-sp-me line{stroke:var(--accent);stroke-width:3.5;stroke-linecap:round}
:root[data-ui-g] .g-ch-sp-lab{fill:var(--ink);font:700 var(--fs-micro) var(--font);
  font-variant-numeric:tabular-nums}
:root[data-ui-g] .g-ch-sp-me:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* g-band-play — register §1c (S-P3) */
:root[data-ui-g] .g-bp-wrap{position:relative}
:root[data-ui-g] .g-bp-bar{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;margin:var(--sp-3) 0 var(--sp-2)}
:root[data-ui-g] .g-bp-lab{font-size:var(--fs-label);color:var(--ink-3)}
:root[data-ui-g] .g-bp-seg,:root[data-ui-g] .g-bp-spd{display:inline-flex;
  border:1px solid var(--line-2);border-radius:var(--r-control);overflow:hidden}
:root[data-ui-g] .g-bp-h,:root[data-ui-g] .g-bp-sp{font:inherit;font-size:var(--fs-label);cursor:pointer;
  border:0;padding:var(--sp-2) var(--sp-3);background:transparent;color:var(--ink-3)}
:root[data-ui-g] .g-bp-h.on,:root[data-ui-g] .g-bp-sp.on{background:var(--accent);color:var(--bg-1)}
:root[data-ui-g] .g-bp-play{font:inherit;font-size:var(--fs-body);font-weight:600;cursor:pointer;
  border:1px solid var(--accent);border-radius:var(--r-control);padding:var(--sp-2) var(--sp-4);background:var(--bg-2);
  color:var(--accent)}
:root[data-ui-g] .g-bp-play:hover{background:var(--accent);color:var(--bg-1)}
:root[data-ui-g] .g-bp-play:focus-visible,:root[data-ui-g] .g-bp-h:focus-visible,
:root[data-ui-g] .g-bp-sp:focus-visible,:root[data-ui-g] .g-bp-scrub:focus-visible{
  outline:2px solid var(--accent);outline-offset:2px}
:root[data-ui-g] .g-bp-month{font-size:var(--fs-label);font-weight:600;color:var(--ink);min-width:62px;
  text-align:center;border:1px solid var(--line-2);border-radius:var(--r-control);padding:var(--sp-2) var(--sp-3)}
:root[data-ui-g] .g-bp-scrub{flex:1 1 160px;min-width:120px;accent-color:var(--accent)}
:root[data-ui-g] .g-bp-mov{margin:var(--sp-1) 0 0;font-size:var(--fs-label);color:var(--ink-3);min-height:16px}
:root[data-ui-g] .g-bp-mov b{color:var(--ink)}
:root[data-ui-g] .g-bp-mov .up{color:var(--up)} :root[data-ui-g] .g-bp-mov .dn{color:var(--down)}
:root[data-ui-g] .g-bp-tip{position:absolute;z-index:40;display:none;pointer-events:none;
  max-width:250px;font-size:var(--fs-label);line-height:var(--lh-body);padding:var(--sp-3) var(--sp-3);border:1px solid var(--line-2);
  border-radius:var(--r-card);background:var(--bg-1);color:var(--ink-2);box-shadow:var(--shadow-raised)}
:root[data-ui-g] .g-bp-tip b{color:var(--ink)}
@media (prefers-reduced-motion:reduce){:root[data-ui-g] .g-bp-play{transition:none}}

/* g-cmdk */
/* `flex:0 0 auto` + `white-space:nowrap` are LOad-bearing, not tidiness: `.g-top` is a flex row,
   so without them the trigger is the flexible item and every other control in the header shrinks
   it — measured 26px wide on first render, i.e. an icon-sized stub where a labelled control was
   specified. A header control has to declare that it does not shrink. */
:root[data-ui-g] .g-k-open{display:inline-flex;align-items:center;gap:var(--sp-3);min-height:44px;
  padding:var(--sp-2) var(--sp-4);border:1px solid var(--line-2);border-radius:var(--r-control);
  background:var(--bg-2);color:var(--ink-2);font:500 var(--fs-body) var(--font);cursor:pointer;
  flex:0 0 auto;white-space:nowrap}
:root[data-ui-g] .g-k-open:hover{border-color:var(--accent);color:var(--ink)}
:root[data-ui-g] .g-k-open kbd{font:600 var(--fs-fine) var(--mono);color:var(--ink-3);
  border:1px solid var(--line-2);border-radius:var(--r-hair);padding:0 var(--sp-2);
  background:var(--bg-1)}
:root[data-ui-g] .g-k-lab{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
:root[data-ui-g] .g-k-wrap[hidden]{display:none}
:root[data-ui-g] .g-k-wrap{position:fixed;inset:0;z-index:80;display:flex;align-items:flex-start;
  justify-content:center;padding:10vh var(--sp-5) var(--sp-5);
  background:color-mix(in srgb,var(--bg-0) 72%,transparent)}
:root[data-ui-g] .g-k-panel{width:min(620px,96vw);max-height:76vh;display:flex;flex-direction:column;
  background:var(--bg-1);border:1px solid var(--line-2);border-radius:var(--r-card);
  box-shadow:var(--shadow-modal);overflow:hidden}
:root[data-ui-g] .g-k-in{width:100%;min-height:52px;border:0;border-bottom:1px solid var(--line);
  background:transparent;color:var(--ink);font:500 var(--fs-head) var(--font);
  padding:var(--sp-4) var(--sp-5);outline:none}
:root[data-ui-g] .g-k-in::placeholder{color:var(--ink-3)}
:root[data-ui-g] .g-k-list{overflow-y:auto;padding:var(--sp-2) 0;margin:0;list-style:none}
:root[data-ui-g] .g-k-grp{font:700 var(--fs-fine)/var(--lh-tight) var(--mono);
  letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--ink-3);
  padding:var(--sp-4) var(--sp-5) var(--sp-2)}
:root[data-ui-g] .g-k-row{display:flex;align-items:center;gap:var(--sp-4);min-height:44px;
  padding:var(--sp-2) var(--sp-5);color:var(--ink);text-decoration:none;cursor:pointer}
:root[data-ui-g] .g-k-row[aria-selected="true"]{background:var(--bg-3);
  box-shadow:inset 3px 0 0 var(--accent)}
:root[data-ui-g] .g-k-row:hover{background:var(--bg-2)}
:root[data-ui-g] .g-k-sym{font:700 var(--fs-body) var(--mono);flex:0 0 auto}
:root[data-ui-g] .g-k-name{color:var(--ink-2);font-size:var(--fs-body);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
:root[data-ui-g] .g-k-tag{margin-left:auto;flex:0 0 auto;font:600 var(--fs-fine) var(--mono);
  letter-spacing:var(--ls-caps);color:var(--ink-3);text-transform:uppercase}
:root[data-ui-g] .g-k-note{padding:var(--sp-4) var(--sp-5);color:var(--ink-3);
  font-size:var(--fs-body)}
:root[data-ui-g] .g-k-foot{border-top:1px solid var(--line);padding:var(--sp-3) var(--sp-5);
  display:flex;gap:var(--sp-5);color:var(--ink-3);font-size:var(--fs-fine)}
@media(max-width:560px){
  :root[data-ui-g] .g-k-open kbd{display:none}
  :root[data-ui-g] .g-k-wrap{padding:0}
  :root[data-ui-g] .g-k-panel{width:100vw;max-height:100vh;height:100vh;border-radius:0}
}


/* ── destinations bar: the reference's active mark (owner ruling 2026-08-19) ──────────────── */
/* Rhythm. The reference separates its destinations clearly; --sp-1 read as a single block. */
:root[data-ui-g] .g-dests{gap:var(--sp-2)}

/* The pill shape is declared on every destination so hover and current share one geometry and
   nothing reflows when the current item changes. --r-control (6px) is Graphite's scale for
   "buttons, inputs, cells, chips"; --r-card (10px) would read as a panel, not a nav chip.
   NOTE: the first draft used --r-sm, which is a CLASSIC token. Graphite's tokens.py asserts
   --r-sm is absent, so the declaration was valid CSS that silently computed to 0px. The
   selftest below now resolves every token against the emitted Graphite set. */
:root[data-ui-g] .g-dests a{border-radius:var(--r-control)}
:root[data-ui-g] .g-dests a:hover{background:var(--bg-2)}

/* THE MARK, top bar only. The underline is retired HERE and only here: the accent moves from a
   2px bottom edge into a filled pill. The border itself stays in the box model at 2px
   transparent, so the bar's height is unchanged. */
:root[data-ui-g] .g-dests a[aria-current]{
  background:var(--bg-3);border-bottom-color:transparent}

/* Keyboard parity: a focus ring must survive the new fill. Uses the estate's own accent. */
:root[data-ui-g] .g-dests a:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}


/* g-cursor */
:root[data-ui-g] body{cursor:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%2724%27%20height%3D%2724%27%20viewBox%3D%270%200%2024%2024%27%3E%3Ccircle%20cx%3D%2712%27%20cy%3D%2712%27%20r%3D%277.4%27%20fill%3D%27%2304211f%27%20fill-opacity%3D%27.16%27%2F%3E%3Ccircle%20cx%3D%2712%27%20cy%3D%2712%27%20r%3D%277%27%20fill%3D%27%232fe6da%27%20fill-opacity%3D%27.28%27%20stroke%3D%27%232fe6da%27%20stroke-opacity%3D%27.85%27%20stroke-width%3D%271.1%27%2F%3E%3Ccircle%20cx%3D%2712%27%20cy%3D%2712%27%20r%3D%271.15%27%20fill%3D%27%232fe6da%27%2F%3E%3C%2Fsvg%3E") 12 12,auto}
:root[data-ui-g] a[href],
:root[data-ui-g] button,
:root[data-ui-g] summary,
:root[data-ui-g] label[for],
:root[data-ui-g] select,
:root[data-ui-g] [role="button"],
:root[data-ui-g] [role="tab"],
:root[data-ui-g] [role="link"],
:root[data-ui-g] input[type="checkbox"],
:root[data-ui-g] input[type="radio"],
:root[data-ui-g] input[type="submit"],
:root[data-ui-g] input[type="button"],
:root[data-ui-g] .g-dests a,
:root[data-ui-g] .g-subbar a,
:root[data-ui-g] .g-btn,
:root[data-ui-g] .g-seg button,
:root[data-ui-g] .g-rail-tg,
:root[data-ui-g] .g-brand,
:root[data-ui-g] [data-gtk] th[data-sort],
:root[data-ui-g] .gtk-th,
:root[data-ui-g] .g-chip,
:root[data-ui-g] .g-tab,
:root[data-ui-g] .g-mtabs a,
:root[data-ui-g] .gw2-seg button,
:root[data-ui-g] .g-k-open{cursor:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%2724%27%20height%3D%2724%27%20viewBox%3D%270%200%2024%2024%27%3E%3Ccircle%20cx%3D%2712%27%20cy%3D%2712%27%20r%3D%279.5%27%20fill%3D%27%2304211f%27%20fill-opacity%3D%27.16%27%2F%3E%3Ccircle%20cx%3D%2712%27%20cy%3D%2712%27%20r%3D%279%27%20fill%3D%27%232fe6da%27%20fill-opacity%3D%27.42%27%20stroke%3D%27%232fe6da%27%20stroke-opacity%3D%27.95%27%20stroke-width%3D%271.3%27%2F%3E%3Ccircle%20cx%3D%2712%27%20cy%3D%2712%27%20r%3D%271.3%27%20fill%3D%27%232fe6da%27%2F%3E%3C%2Fsvg%3E") 12 12,pointer}
:root[data-ui-g] input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]),
:root[data-ui-g] textarea,
:root[data-ui-g] [contenteditable="true"]{cursor:text}
:root[data-ui-g] [disabled],
:root[data-ui-g] [aria-disabled="true"]{cursor:not-allowed}
:root[data-ui-g][data-theme="light"] body{cursor:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%2724%27%20height%3D%2724%27%20viewBox%3D%270%200%2024%2024%27%3E%3Ccircle%20cx%3D%2712%27%20cy%3D%2712%27%20r%3D%277.4%27%20fill%3D%27%23ffffff%27%20fill-opacity%3D%27.16%27%2F%3E%3Ccircle%20cx%3D%2712%27%20cy%3D%2712%27%20r%3D%277%27%20fill%3D%27%23096b65%27%20fill-opacity%3D%27.28%27%20stroke%3D%27%23096b65%27%20stroke-opacity%3D%27.85%27%20stroke-width%3D%271.1%27%2F%3E%3Ccircle%20cx%3D%2712%27%20cy%3D%2712%27%20r%3D%271.15%27%20fill%3D%27%23096b65%27%2F%3E%3C%2Fsvg%3E") 12 12,auto}
:root[data-ui-g][data-theme="light"] a[href],
:root[data-ui-g][data-theme="light"] button,
:root[data-ui-g][data-theme="light"] summary,
:root[data-ui-g][data-theme="light"] label[for],
:root[data-ui-g][data-theme="light"] select,
:root[data-ui-g][data-theme="light"] [role="button"],
:root[data-ui-g][data-theme="light"] [role="tab"],
:root[data-ui-g][data-theme="light"] [role="link"],
:root[data-ui-g][data-theme="light"] input[type="checkbox"],
:root[data-ui-g][data-theme="light"] input[type="radio"],
:root[data-ui-g][data-theme="light"] input[type="submit"],
:root[data-ui-g][data-theme="light"] input[type="button"],
:root[data-ui-g][data-theme="light"] .g-dests a,
:root[data-ui-g][data-theme="light"] .g-subbar a,
:root[data-ui-g][data-theme="light"] .g-btn,
:root[data-ui-g][data-theme="light"] .g-seg button,
:root[data-ui-g][data-theme="light"] .g-rail-tg,
:root[data-ui-g][data-theme="light"] .g-brand,
:root[data-ui-g][data-theme="light"] [data-gtk] th[data-sort],
:root[data-ui-g][data-theme="light"] .gtk-th,
:root[data-ui-g][data-theme="light"] .g-chip,
:root[data-ui-g][data-theme="light"] .g-tab,
:root[data-ui-g][data-theme="light"] .g-mtabs a,
:root[data-ui-g][data-theme="light"] .gw2-seg button,
:root[data-ui-g][data-theme="light"] .g-k-open{cursor:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%2724%27%20height%3D%2724%27%20viewBox%3D%270%200%2024%2024%27%3E%3Ccircle%20cx%3D%2712%27%20cy%3D%2712%27%20r%3D%279.5%27%20fill%3D%27%23ffffff%27%20fill-opacity%3D%27.16%27%2F%3E%3Ccircle%20cx%3D%2712%27%20cy%3D%2712%27%20r%3D%279%27%20fill%3D%27%23096b65%27%20fill-opacity%3D%27.42%27%20stroke%3D%27%23096b65%27%20stroke-opacity%3D%27.95%27%20stroke-width%3D%271.3%27%2F%3E%3Ccircle%20cx%3D%2712%27%20cy%3D%2712%27%20r%3D%271.3%27%20fill%3D%27%23096b65%27%2F%3E%3C%2Fsvg%3E") 12 12,pointer}
:root[data-ui-g][data-theme="light"] input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]),
:root[data-ui-g][data-theme="light"] textarea,
:root[data-ui-g][data-theme="light"] [contenteditable="true"]{cursor:text}
:root[data-ui-g][data-theme="light"] [disabled],
:root[data-ui-g][data-theme="light"] [aria-disabled="true"]{cursor:not-allowed}


:root[data-ui-g] .g-chart-readout{display:flex;flex-wrap:wrap;gap:var(--sp-2);font-size:var(--fs-body);font-variant-numeric:tabular-nums;margin-top:var(--sp-2)}
:root[data-ui-g] .g-chart-help{font-size:var(--fs-label);color:var(--ink-2);margin:var(--sp-1) 0;line-height:var(--lh-body)}
:root[data-ui-g] [data-chart-readout]{touch-action:pan-y;cursor:crosshair;min-height:140px}
:root[data-ui-g] .g-chart-window{font-size:var(--fs-body);color:var(--ink-2);line-height:var(--lh-body)}
:root[data-ui-g] [data-chart-readout]:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
:root[data-ui-g] .g-chart-brand{display:block;color:var(--accent);font-size:var(--fs-label);font-weight:700;padding:var(--sp-1) var(--sp-2);background:var(--bg-0);border-bottom:1px solid var(--line)}


:root[data-ui-g] .g-measure-info{position:relative;flex-shrink:0}
:root[data-ui-g] .g-measure-info button{font:inherit;color:var(--ink-2);background:var(--bg-1);border:1px solid var(--line-2);border-radius:var(--r-control);cursor:pointer}
:root[data-ui-g] .g-measure-info button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
:root[data-ui-g] .g-measure-pop{position:absolute;inset-inline-start:0;top:100%;z-index:10;width:min(28ch,70vw);padding:var(--sp-4);background:var(--bg-2);border:1px solid var(--ink-3);border-radius:var(--r-card);box-shadow:var(--shadow-popover);font-size:var(--fs-body);line-height:var(--lh-body);overflow-wrap:anywhere}
:root[data-ui-g] .g-measure-pop p{margin:0 0 var(--sp-3)}
:root[data-ui-g] .g-measure-info button{min-width:24px;min-height:24px;}
@media(max-width:600px){:root[data-ui-g] .g-measure-info button{min-width:44px;min-height:44px;}}