/* LEARN — the teaching surface.
 *
 * Loaded LAST, after controls.css, deliberately. instrument.css:343 sets
 * `font-size: var(--t-sm) !important` on `body *:not(svg):not(svg *)`, and an
 * important declaration beats a normal one at any specificity, so every size
 * step here carries !important or it silently flattens. That rule already ate
 * one type scale in this app; it is not a style preference, it is the reason
 * these declarations look the way they do.
 *
 * TOKENS ONLY. No authored colour anywhere.
 */

/* ── THE SHOCK PANEL ─────────────────────────────────────────────────────── */
/* Three numbers, no chart. A chart of "one address is 42% of the market" is a
   bar next to a sliver, which is less legible than the sentence. */
.lrn-shock {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 20px;
  margin: 22px 0 10px;
  padding: 22px 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
@media (min-width: 780px) {
  .lrn-shock { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 32px; }
}
.lrn-shock > div { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.lrn-shock b {
  font-size: 34px !important;
  line-height: 1.05;
  font-weight: 600 !important;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.lrn-shock i {
  font-style: normal;
  font-size: 12px !important;
  line-height: 1.45;
  color: var(--ink2);
}

.lrn-note {
  margin: 0 0 6px;
  max-width: 68ch;
  font-size: 13px !important;
  line-height: 1.65;
  color: var(--ink2);
}

/* ── LESSON BODY ─────────────────────────────────────────────────────────── */
.lrn-h {
  margin: 34px 0 10px;
  font-size: 17px !important;
  font-weight: 600 !important;
  color: var(--ink);
  letter-spacing: -0.01em;
}
.lrn-p {
  margin: 0 0 12px;
  max-width: 68ch;
  font-size: 14px !important;
  line-height: 1.7;
  color: var(--ink2);
}
.lrn-p b { color: var(--ink); font-weight: 600 !important; }
.lrn-p em { font-style: italic; color: var(--ink); }

/* The caveat that keeps lesson 2 honest. Muted rather than alarmed: it is a
   correction to a claim people over-extend, not a warning. */
.lrn-warn {
  border-left: 2px solid var(--line2);
  padding-left: 14px;
  color: var(--ink3);
}

.lrn-quiet {
  margin: 0 0 12px;
  max-width: 62ch;
  font-size: 13px !important;
  line-height: 1.65;
  color: var(--ink3);
  font-style: italic;
}

/* ── THE REAL FILL ───────────────────────────────────────────────────────── */
/* The object the whole section exists for. Set apart by a rule and space, not
   by a box: same house convention the venue table follows. */
.lrn-fill {
  margin: 16px 0 22px;
  padding: 18px 0 4px;
  border-top: 1px solid var(--line2);
}
.lrn-fill-k {
  margin: 0 0 4px;
  font-size: 11px !important;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink3);
}
.lrn-fill-i {
  margin: 0 0 16px;
  font-size: 15px !important;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.lrn-decode {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px 24px;
  margin-bottom: 14px;
}
@media (min-width: 720px) {
  /* Five, not four: contracts joined the decode as its own field. */
  .lrn-decode { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}
.lrn-decode > div { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.lrn-decode b {
  font-size: 20px !important;
  font-weight: 600 !important;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.lrn-decode i {
  font-style: normal;
  font-size: 11px !important;
  line-height: 1.4;
  color: var(--ink3);
}

.lrn-teach {
  margin: 0;
  max-width: 66ch;
  font-size: 13px !important;
  line-height: 1.7;
  color: var(--ink2);
}

/* ── THE FOUR AXES ───────────────────────────────────────────────────────── */
.lrn-axes {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 14px;
  margin: 16px 0 18px;
}
@media (min-width: 780px) {
  .lrn-axes { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px 28px; }
}
.lrn-axes > div {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-left: 14px;
  border-left: 1px solid var(--line2);
  min-width: 0;
}
.lrn-axes b { font-size: 14px !important; font-weight: 600 !important; color: var(--ink); }
.lrn-axes i { font-style: normal; font-size: 12px !important; line-height: 1.55; color: var(--ink3); }

/* ── CTA ─────────────────────────────────────────────────────────────────── */
.lrn-cta {
  margin: 38px 0 8px;
  padding: 26px 0 0;
  border-top: 1px solid var(--line);
}
.lrn-cta-h {
  margin: 0 0 6px;
  font-size: 17px !important;
  font-weight: 600 !important;
  color: var(--ink);
}
.lrn-cta-p {
  margin: 0 0 16px;
  max-width: 60ch;
  font-size: 13px !important;
  line-height: 1.65;
  color: var(--ink2);
}
.lrn-cta-a {
  display: inline-block;
  cursor: pointer;
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: var(--bg);
  text-decoration: none;
  font-weight: 600 !important;
  font-size: 14px !important;
  padding: 10px 20px;
}
.lrn-cta-a:hover { filter: brightness(1.08); }
.lrn-cta-a:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Disabled state, used while no real invite exists. It must not look clickable,
   because a button that does nothing is worse than an absent one. */
.lrn-cta-off {
  background: transparent;
  color: var(--ink3);
  border: 1px dashed var(--line2);
  cursor: default;
}
.lrn-cta-off:hover { filter: none; }

.lrn-cta-n {
  margin: 14px 0 0;
  font-size: 11px !important;
  color: var(--ink3);
}

/* ── THE PAYOFF EXPLORER ──────────────────────────────────────────────────── */
/* The lesson IS the control (owner: "not in terms of text explanation, that's
   the most important part"). So it gets the space and the weight that would
   otherwise go to prose. */

.pf {
  margin: 20px 0 26px;
  padding: 20px 0 4px;
  border-top: 1px solid var(--line2);
}

.pf-ctl {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 18px;
}

/* Two buttons, one obviously on. The Hyperliquid read: the choice is the
   interface, not a dropdown hiding it. */
.pf-seg { display: inline-flex; gap: 8px; }
.pf-b {
  cursor: pointer; border: 1px solid var(--line2); background: transparent;
  color: var(--ink2); border-radius: 999px; padding: 8px 16px;
  font-size: 13px !important; font-weight: 600 !important;
}
.pf-b:hover { color: var(--ink); border-color: var(--ink3); }
.pf-b.on { background: var(--accent); border-color: var(--accent); color: var(--bg); }
.pf-b:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.pf-as { display: inline-flex; align-items: center; gap: 8px; font-size: 12px !important; color: var(--ink3); }
.pf-sel {
  background: transparent; color: var(--ink); border: 1px solid var(--line2);
  border-radius: 6px; padding: 6px 10px; font-size: 13px !important;
}

.pf-row { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.pf-lbl { font-size: 13px !important; color: var(--ink3); }
.pf-px {
  font-size: 30px !important; font-weight: 600 !important; color: var(--ink);
  font-variant-numeric: tabular-nums; letter-spacing: -0.02em;
}
.pf-mv { font-size: 15px !important; font-weight: 600 !important; font-variant-numeric: tabular-nums; }
.pf-mv.up { color: var(--pos); }
.pf-mv.dn { color: var(--neg); }

.pf-r { width: 100%; margin: 4px 0 2px; accent-color: var(--accent); }
.pf-scale {
  display: flex; justify-content: space-between;
  font-size: 10px !important; color: var(--ink3); margin-bottom: 18px;
}

.pf-res {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px;
  padding: 16px 0; border-top: 1px solid var(--line2); border-bottom: 1px solid var(--line2);
}
@media (min-width: 780px) { .pf-res { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 26px; } }
.pf-res > div { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.pf-res b {
  font-size: 24px !important; font-weight: 600 !important; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.pf-res i { font-style: normal; font-size: 11px !important; line-height: 1.45; color: var(--ink3); }
/* Direction keeps the same meaning it has everywhere else in the app. */
.pf-res > div.ok b { color: var(--pos); }
.pf-res > div.bad b { color: var(--neg); }

.pf-src { margin: 12px 0 0; font-size: 11px !important; line-height: 1.6; color: var(--ink3); max-width: 66ch; }
.pf-src b { color: var(--ink2); font-weight: 600 !important; }

/* Where to trade it. Logos carry the identification, the line under each one
   carries the thing that actually differs between them. */
.pf-vn { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line2); }
.pf-vn-h {
  margin: 0 0 12px; font-size: 11px !important; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--ink3);
}
.pf-vn-list { display: flex; flex-wrap: wrap; gap: 12px 26px; }
.pf-vn-i { display: inline-flex; flex-direction: column; gap: 3px; min-width: 0; }
.pf-vn-i i {
  font-style: normal; font-size: 10px !important; color: var(--ink3);
  letter-spacing: 0.01em;
}
.pf-vn-n {
  margin: 14px 0 0; font-size: 11px !important; line-height: 1.6;
  color: var(--ink3); max-width: 64ch;
}

/* ── THE TWO NUMBERS ─────────────────────────────────────────────────────── */
/* The wall every beginner hits. The ask is not "highlighted" as decoration:
   the reader is buying, so one of these two numbers is theirs and the other is
   context, and the design says which without a sentence. */
.bk { margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--line2); }
.bk-h {
  margin: 0 0 4px; font-size: 11px !important; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--ink3);
}
.bk-i {
  margin: 0 0 14px; font-size: 13px !important; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.bk-i span { color: var(--ink3); }

.bk-pair { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
@media (min-width: 680px) { .bk-pair { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; } }

.bk-side {
  display: flex; flex-direction: column; gap: 4px; min-width: 0;
  padding: 14px 16px; border: 1px solid var(--line2); border-radius: 8px;
}
.bk-side b {
  font-size: 28px !important; font-weight: 600 !important; color: var(--ink3);
  font-variant-numeric: tabular-nums; line-height: 1.05;
}
.bk-side i {
  font-style: normal; font-size: 10px !important; letter-spacing: 0.1em;
  color: var(--ink3);
}
.bk-side span { font-size: 11px !important; line-height: 1.5; color: var(--ink3); }

/* The one that is actually yours. */
.bk-side.on { border-color: var(--accent); }
.bk-side.on b { color: var(--ink); }
.bk-side.on i { color: var(--accent); }
.bk-side.on span { color: var(--ink2); }
.bk-side.on span b { font-size: 11px !important; color: var(--ink); }

.bk-sp, .bk-ord {
  margin: 14px 0 0; max-width: 66ch;
  font-size: 12px !important; line-height: 1.65; color: var(--ink3);
}
.bk-sp b { color: var(--ink); font-weight: 600 !important; }

.bk-cex { margin: -8px 0 14px; font-size: 11px !important; line-height: 1.55; color: var(--ink3); max-width: 64ch; font-style: italic; }

/* ── PAYOFF SHAPES ───────────────────────────────────────────────────────── */
/* The paragraphs that used to live here described these lines. A drawn payoff
   is a better description of a collar than any sentence about floors and
   ceilings, so the sentences went and the lines stayed. */
.sh-wrap { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line2); }
.sh-h {
  margin: 0 0 14px; font-size: 11px !important; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--ink3);
}
.sh-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px 22px;
}
@media (min-width: 760px) { .sh-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.sh { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.sh-g { width: 100%; height: 70px; display: block; overflow: visible; }
/* The payoff line is ink, not accent: six of these on screen at once in accent
   would read as six alerts. */
.sh-l { fill: none; stroke: var(--ink); stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.sh-z { stroke: var(--line2); stroke-width: 1; stroke-dasharray: 2 3; vector-effect: non-scaling-stroke; }
.sh b { font-size: 13px !important; font-weight: 600 !important; color: var(--ink); }
.sh i { font-style: normal; font-size: 11px !important; line-height: 1.45; color: var(--ink3); }

.sh-n {
  margin: 16px 0 0; max-width: 64ch;
  font-size: 11px !important; line-height: 1.6; color: var(--ink3);
}

/* ── THE ONE CHART ───────────────────────────────────────────────────────── */
/* Replaces six static shape cards. It draws the position actually selected and
   moves with the slider, so the picture and the numbers below it are the same
   fact stated twice rather than an illustration parked beside a calculation. */
.pc-g { width: 100%; height: 150px; display: block; margin: 6px 0 2px; }
.pc-l { fill: none; stroke: var(--ink); stroke-width: 2; vector-effect: non-scaling-stroke; }
/* Profit and loss as REGIONS. Same jade/rose that means direction everywhere
   else in this app, at low opacity so the payoff line stays the subject. */
.pc-up { fill: var(--pos); opacity: 0.16; stroke: none; }
.pc-dn { fill: var(--neg); opacity: 0.16; stroke: none; }
.pc-z { stroke: var(--line2); stroke-width: 1; vector-effect: non-scaling-stroke; }
.pc-k { stroke: var(--line2); stroke-width: 1; stroke-dasharray: 3 3; vector-effect: non-scaling-stroke; }
/* Where the slider currently sits. Accent, because it is the one thing on the
   chart the reader is moving. */
.pc-c { stroke: var(--accent); stroke-width: 1; vector-effect: non-scaling-stroke; }
.pc-d { fill: var(--accent); }

.pc-ax {
  display: flex; justify-content: space-between;
  font-size: 10px !important; color: var(--ink3); margin-bottom: 14px;
}

/* Four actions wrap on narrow screens rather than shrinking to unreadable. */
.pf-seg { flex-wrap: wrap; }

/* Gated rail item: labelled, visible, not clickable. */
.rl-soon {
  margin-left: 6px; font-size: 9px !important; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink3);
  border: 1px solid var(--line2); border-radius: 999px; padding: 1px 6px;
}
.rl-item.rl-locked { cursor: default; opacity: 0.55; }
.rl-item.rl-locked:hover { opacity: 0.55; }

/* ── SPOT / STRIKE / EXPIRY, NAMED ───────────────────────────────────────── */
/* A beginner meets bid, ask, strike and spot in the same glance and nothing
   says which is which. These three are the vocabulary everything below assumes,
   so they are stated in words before any chart or book appears. */
.pf-facts {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px 20px; margin: 0 0 20px; padding-bottom: 18px;
  border-bottom: 1px solid var(--line2);
}
.pf-facts > div { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.pf-fa { flex-direction: row !important; align-items: center; gap: 10px !important; }
.pf-fa .mk { flex: 0 0 auto; }
.pf-facts b {
  font-size: 24px !important; font-weight: 600 !important; color: var(--ink);
  font-variant-numeric: tabular-nums; line-height: 1.1;
}
.pf-facts i {
  font-style: normal; font-size: 11px !important; line-height: 1.4; color: var(--ink3);
}

/* ── CHART MARKERS ───────────────────────────────────────────────────────── */
.pc-wrap { position: relative; padding-bottom: 34px; margin-bottom: 8px; }
/* Spot is a solid hairline, strike is dashed: two different kinds of fact, and
   the reader can tell them apart before reading either label. */
.pc-s { stroke: var(--ink3); stroke-width: 1; vector-effect: non-scaling-stroke; }
.pc-tag {
  position: absolute; bottom: 0; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  white-space: nowrap; pointer-events: none;
}
.pc-tag i { font-style: normal; font-size: 9px !important; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--ink3); }
.pc-tag b { font-size: 12px !important; font-weight: 600 !important;
  color: var(--ink2); font-variant-numeric: tabular-nums; }
.pc-tag-k b { color: var(--ink); }

/* Venue identity in the book header: logo at readable size, name spelled out. */
.bk-v { display: inline-flex; align-items: center; gap: 7px; color: var(--ink); }
.bk-inst { display: block; margin-top: 3px; color: var(--ink3); font-size: 12px !important; }

/* The number and its label were rendering on one line ("1,882ETH price now")
   because .pf-facts>div's column direction does not reach the div nested
   inside the logo row. */
.pf-fa > div { display: flex; flex-direction: column; gap: 3px; min-width: 0; }

/* Stacked variant, used when strike sits within 12% of spot — i.e. almost
   always, since that is where the volume is. Two rows, so each label stays
   under its own mark instead of overprinting the other. */
.pc-wrap--stacked { padding-bottom: 56px; }
.pc-tag--up { bottom: 26px; }
.pc-wrap--stacked .pc-tag::after {
  content: ""; position: absolute; left: 50%; width: 1px;
  background: var(--line2);
}
.pc-wrap--stacked .pc-tag-s::after { top: -8px; height: 8px; }
.pc-wrap--stacked .pc-tag-k::after { top: -8px; height: 8px; }

/* Which way this position wants the price to go. */
.pf-dir { font-size: 12px !important; color: var(--ink3); }

/* ── THE ORDER, SIMULATED ────────────────────────────────────────────────── */
/* Reads as a receipt, because that is what it is: the money that leaves, the
   fee that is usually hidden, and what you hold afterwards. */
.or { margin: 18px 0 22px; padding-top: 16px; border-top: 1px solid var(--line2); }
.or-h {
  margin: 0 0 12px; font-size: 11px !important; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--ink3);
}
.or-rows { display: flex; flex-direction: column; gap: 8px; max-width: 460px; }
.or-rows > div { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.or-rows span { font-size: 13px !important; color: var(--ink2); }
.or-rows span i {
  display: block; font-style: normal; font-size: 10px !important; color: var(--ink3);
}
.or-rows b {
  font-size: 14px !important; font-weight: 600 !important; color: var(--ink);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.or-na span, .or-na b { color: var(--ink3) !important; }
/* The line that matters: what actually moves. */
.or-tot { padding-top: 8px; border-top: 1px solid var(--line2); }
.or-tot span { color: var(--ink) !important; }
.or-tot b { font-size: 20px !important; }

.or-own { margin-top: 16px; display: flex; flex-direction: column; gap: 6px; }
.or-own p {
  margin: 0; max-width: 66ch; font-size: 12px !important; line-height: 1.6; color: var(--ink3);
}
.or-own b { color: var(--ink2); font-weight: 600 !important; }

/* The venue strip is a control now, not a caption. */
.pf-vn-i { cursor: pointer; background: transparent; border: 1px solid transparent; border-radius: 8px; padding: 6px 10px; text-align: left; }
.pf-vn-i:hover { border-color: var(--line2); }
.pf-vn-i.on { border-color: var(--accent); }
.pf-vn-i.on i { color: var(--ink2) !important; }

/* ── THE BOOK AS THE CONTROL ─────────────────────────────────────────────── */
/* These two are now the primary action on the surface, so they stop looking
   like read-outs and start looking like the thing you press. Label ABOVE the
   number: you scan for "ask", then read its price, not the reverse. */
.bk-side {
  cursor: pointer; text-align: left; width: 100%;
  padding: 16px 18px; border-radius: 10px;
  border: 1px solid var(--line2); background: transparent;
  display: flex; flex-direction: column; gap: 2px;
  transition: none;
}
.bk-side:hover { border-color: var(--ink3); }
.bk-side:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.bk-side i {
  font-style: normal; font-size: 10px !important; letter-spacing: 0.12em;
  color: var(--ink3); order: -1;
}
.bk-side b {
  font-size: 34px !important; font-weight: 600 !important; line-height: 1.05;
  color: var(--ink2); font-variant-numeric: tabular-nums;
}
.bk-side span { font-size: 11px !important; color: var(--ink3); }

/* The side you have chosen. Filled, not outlined: it is the current state of
   the whole panel below, not a hover. */
.bk-side.on { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
.bk-side.on b { color: var(--ink); }
.bk-side.on i { color: var(--accent); }
.bk-side.on span { color: var(--ink2); }

/* Direction is conventional: selling is the left/rose side, buying the right.
   Only ever on the CHOSEN one, so the palette stays quiet while you scan. */
.bk-side.bk-sell.on { border-color: var(--neg); background: color-mix(in srgb, var(--neg) 10%, transparent); }
.bk-side.bk-sell.on i { color: var(--neg); }
.bk-side.bk-buy.on { border-color: var(--pos); background: color-mix(in srgb, var(--pos) 10%, transparent); }
.bk-side.bk-buy.on i { color: var(--pos); }

.bk-pair { gap: 14px !important; }

/* ── THE EXPIRY LADDER ───────────────────────────────────────────────────── */
/* Read down the ask column and you are reading the price of protection as a
   function of time. That is the axis a perp does not have. */
.ld { margin: 0 0 22px; }
.ld-head, .ld-row {
  display: grid;
  grid-template-columns: minmax(84px, 1.1fr) minmax(64px, 0.9fr) minmax(56px, 0.8fr) minmax(56px, 0.8fr) minmax(64px, 0.9fr);
  gap: 10px 14px; align-items: center; width: 100%; text-align: left;
}
.ld-head {
  padding: 0 10px 8px; border-bottom: 1px solid var(--line2);
  font-size: 10px !important; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--ink3);
}
.ld-n { text-align: right; }
.ld-row {
  cursor: pointer; background: transparent; border: 1px solid transparent;
  border-radius: 8px; padding: 10px; font-size: 14px !important; color: var(--ink2);
  font-variant-numeric: tabular-nums;
}
.ld-row:hover { background: rgba(255,255,255,0.03); }
.ld-row.on { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, transparent); }
.ld-row.on span { color: var(--ink); }
.ld-d { display: flex; flex-direction: column; gap: 1px; color: var(--ink); }
.ld-d i { font-style: normal; font-size: 10px !important; color: var(--ink3); }
/* Bid and ask keep the same meaning they have on the two big buttons below. */
.ld-bid { color: var(--neg); }
.ld-ask { color: var(--pos); }
.ld-pct { color: var(--ink3); }
.ld-n2 { margin: 12px 10px 0; font-size: 11px !important; line-height: 1.6; color: var(--ink3); max-width: 66ch; }

/* Calls, labelled and inert. */
.pf-b--soon { cursor: default; opacity: 0.5; border-style: dashed; }
.pf-b--soon:hover { color: var(--ink2); border-color: var(--line2); }

.ld-k { display: flex; flex-direction: column; gap: 2px; }
.ld-k i { font-style: normal; font-size: 10px !important; color: var(--ink3); display: inline-flex; align-items: center; gap: 4px; }

.pf-dist { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.pf-dist > span { font-size: 11px !important; color: var(--ink3); }
.pf-d { cursor: pointer; background: transparent; border: 1px solid var(--line2); color: var(--ink3); border-radius: 999px; padding: 5px 12px; font-size: 12px !important; }
.pf-d:hover { color: var(--ink); }
.pf-d.on { border-color: var(--accent); color: var(--ink) !important; }

/* ── NETWORKS ────────────────────────────────────────────────────────────── */
/* The empty ones are the finding, so they get the same shape as the live ones
   rather than being demoted to a footnote or dropped from the list. */
.nw { display: flex; flex-wrap: wrap; gap: 10px 12px; margin: 14px 0 6px; }
.nw-i {
  display: flex; flex-direction: column; gap: 2px; min-width: 0;
  padding: 10px 14px; border: 1px solid var(--line2); border-radius: 8px;
}
.nw-i b { font-size: 13px !important; font-weight: 600 !important; color: var(--ink2); }
.nw-i i { font-style: normal; font-size: 10px !important; color: var(--ink3); }
.nw-on { border-color: var(--line); }
.nw-on b { color: var(--ink); }
/* A chain whose only venue shut down. Muted and dashed: not an error, a fact. */
.nw-dead { border-style: dashed; }
.nw-dead b { color: var(--ink3); }
.nw-h {
  margin: 20px 0 0; font-size: 11px !important; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--ink3);
}

/* ── SETTLED ─────────────────────────────────────────────────────────────── */
/* The transfer, stated as three numbers that add up in front of the reader:
   premium in, intrinsic out, difference. */
.st-top {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 18px;
  margin: 20px 0 14px; padding: 20px 0; border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
@media (min-width: 820px) { .st-top { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 30px; } }
.st-top > div { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.st-top b {
  font-size: 30px !important; font-weight: 600 !important; line-height: 1.05;
  color: var(--ink); font-variant-numeric: tabular-nums; letter-spacing: -0.02em;
}
.st-top i { font-style: normal; font-size: 12px !important; line-height: 1.45; color: var(--ink3); }
/* The one that is the point of the section. */
.st-net b { color: var(--accent); }

.st-line { margin: 0 0 6px; font-size: 14px !important; line-height: 1.6; color: var(--ink2); max-width: 68ch; }
.st-line b { color: var(--ink); font-weight: 600 !important; }

.st-h { margin: 30px 0 4px; font-size: 16px !important; font-weight: 600 !important; color: var(--ink); }
.st-sub { margin: 0 0 14px; font-size: 12px !important; color: var(--ink3); max-width: 66ch; }

/* THE TABLE IS THE TAPE'S TABLE. Everything structural (sticky header, cell
   padding, the mono uppercase column labels, the three-grey ladder where an
   absent value sits BELOW the furniture) comes from .tw-head/.tw-row/.tw-c in
   tools.css and controls.css. Only the track widths are set here, through the
   same --tape-cols variable those rules read, so the header and the rows cannot
   resolve different tracks. Redeclaring any of the rest would fork the design
   and let the two tables drift, which is the thing this reuse prevents. */
/* `html body` because controls.css:1436 sets --tape-cols on `html body
   .tw-grid` with five tracks, and at (0,1,2) it beats a bare `.st-grid` at
   (0,1,0). The element therefore does NOT carry tw-grid at all: this table
   wants the tape's row and cell styling, not the tape's column count, and
   inheriting seven tracks from a five-track variable silently collapsed the
   last two columns to NaN. */
html body .st-grid {
  /* FIVE tracks. The address board this table replaced needed six; the band
     ladder needs five, and every qualifier that would have wanted a column of
     its own (median tenor, share expired worthless, what the sellers kept)
     rides under its value as the .stk secondary line instead. That is how the
     tape carries a qualifier, and it is what keeps the row from clipping at
     1280px where a sixth track would not fit.

     NO PIXEL FLOORS, AND THAT IS THE TAPE'S OWN RULE RATHER THAN a preference.
     This first read minmax(208px, 2fr) and friends, chosen so the longest label
     ("Within 2%, in the money") could never clip. Measured at 900px wide the
     floors summed to 678px inside a 570px container, and because nothing in
     this column scrolls sideways (.tw-grid sets overflow-x: hidden and the
     tl-body ancestors are all visible) the last column simply left the screen
     with no way to reach it. The real tape never does this: controls.css:1436
     and tools.css:1207 use bare fr tracks and CHANGE THE COLUMN COUNT at
     breakpoints, so the row always fits the width it is given. Same here, with
     minmax(0, Nfr) so a track may shrink below its content, and .stk .p given
     the ellipsis that .stk .s already carries so the shrink is visible instead
     of bleeding. A truncated label with the full text in its title is a
     legible compromise; an unreachable column is not.

     AND THIS BLOCK IS ONE COMMENT BECAUSE A STRAY COMMENT-CLOSE BROKE IT TWICE.
     Editing the note above into two comments left an orphan close marker; CSS
     dropped the rest of the rule, --tape-cols went unset, and the whole table
     collapsed into a single column. Rewriting the warning then broke it AGAIN,
     because the warning quoted the marker it was warning about. So: never
     write the two-character close sequence inside a comment here, not even in
     backticks.
     It survived a DOM check while broken, which is the part worth keeping:
     with one track nothing overflows, so scrollWidth === clientWidth and the
     "no clipped cells" assertion PASSED on a table that was unreadable. Only
     the screenshot caught it. */
  --tape-cols: minmax(0, 2fr) minmax(0, 1.05fr) minmax(0, 1.1fr)
               minmax(0, 1.25fr) minmax(0, 1.2fr);
}
/* Direction keeps the meaning it carries everywhere else in the app. Only the
   bands where most of the premium came back are inked — if every row were
   coloured the ladder would carry no information, which is the same reason
   today.css only inks the leading bar. */
.st-up { color: var(--pos) !important; }
.st-dn { color: var(--neg) !important; }

/* THE BAR IS THE PREMIUM, AND THE FILL IS WHAT CAME BACK OF IT. The empty part
   is therefore not empty: it is the money the sellers kept, which is why the
   track is inked at all rather than left hollow. Same reading today.css:396
   settled on for the bought/sold split.

   THE 2px FLOOR IS A CORRECTNESS RULE, NOT A FLOURISH. The last band returns
   0.1%, which at any table width rounds to a sub-pixel fill and disappears,
   and an invisible bar is indistinguishable from a missing one, which is the
   n/a-is-not-zero rule failing in the one row a reader is most curious about.
   `.on` is set only when the ratio is > 0, so a measured zero still renders as
   an unfilled track and an ABSENT ratio renders no bar at all.

   THE TOKENS ARE --line AND --ink3, WHICH IS NOT THE OBVIOUS PAIR. The obvious
   pair is today.css's (--s2 track, --line2 fill). instrument.css §1 sets
   --s2: transparent in the BASE :root layer and only the dark block at §63
   restores it, which is the same trap §32 of that file already records against
   .tc-share ("background-color rgba(0,0,0,0) <- asks for var(--s2)"). The app
   ships dark only (theme.js, 2026-08-05), so --s2 does resolve today; building
   on a token whose base value is transparent is still borrowing against the
   one layer that is not currently painted. Measured in the browser rather than
   assumed: dark resolves --line #302a23 and --ink3 #9b8e82, which is also the
   more legible of the two pairings at 5px tall. */
html body .st-grid .st-bar {
  width: 100%; max-width: 118px; height: 5px; margin-top: 5px;
  border-radius: 999px; background: var(--line); overflow: hidden; flex: none;
}
html body .st-grid .st-bar > i {
  display: block; height: 100%; background: var(--ink3); border-radius: 999px;
}
html body .st-grid .st-bar.on > i { min-width: 2px; }

/* The sentence the table was built to support. Same type as .st-line, given
   air above it so it reads as the conclusion of the table rather than as
   another caption under it. */
.st-punch { margin-top: 16px; }
.st-punch b { color: var(--accent) !important; }

/* The honesty contract. Full sentences, in the reading column, under the thing
   they qualify. Not a tooltip, and not 9px grey. */
.st-note {
  margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--line2);
  display: flex; flex-direction: column; gap: 10px;
}
.st-note p { margin: 0; max-width: 72ch; font-size: 12px !important; line-height: 1.65; color: var(--ink3); }
.st-note b { color: var(--ink2); font-weight: 600 !important; }

/* THE STACK FILLS THE CELL, so the cell's packing stops deciding where the
   text sits. controls.css:1433 pins .tw-c to flex-start and .tw-c.num to
   flex-end with !important, which is vertical alignment on a column flexbox.
   The real tape never shows it because every one of its cells carries a
   two-line stack that already fills the height. Ours are one-line in three
   columns, so measured tops came out [4, 23, 10, 23, 4, 4] and each row read
   as two rows. Giving the stack flex:1 hands the centring back to .stk's own
   justify-content, which is what the tape intends. */
html body .st-grid .tw-c .stk { flex: 1 1 auto; justify-content: center; }
/* AND IT STRETCHES ACROSS THE CELL, which matters for exactly one reason: the
   bar. .tw-c is a column flexbox, so without align-self the stack is only as
   wide as its widest line — measured, that made the bar's TRACK 38px on the
   row reading "74.2%" and 31px on the row reading "0.1%". A proportional bar
   whose track changes width per row is not a comparison, it is decoration that
   looks like one. Stretching pins every track to the same width; the text stays
   right-aligned because .tw-c.num .stk already sets align-items: flex-end. */
html body .st-grid .tw-c .stk { align-self: stretch; }
/* The secondary line is a qualifier, so it must not compete with the value it
   sits under. Same relationship .stk .s has in the tape. */
/* The primary line gets the ellipsis the secondary line already has, because
   with no pixel floors a track may now be narrower than its label. Truncation
   that shows is fine; text sliding out of the table is not. The full string is
   on the cell's title either way. */
html body .st-grid .stk .p {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 100%;
}
html body .st-grid .stk .s {
  font-size: 10px !important; color: var(--ink3) !important;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ── TRADES: ONE SECTION, TWO PANES ───────────────────────────────────────
   2026-08-19. Settled stopped being its own rail entry and became the second
   pane of Trades (owner: "settled inside trades... It should be Trades, and we
   split the section inside into 2"). nav.js owns which pane is showing; this
   block owns the geometry, and every rule in it exists because of something
   already measured in this codebase rather than as a preference.

   THE VIEW BECOMES A GRID, NOT A FLEX COLUMN, and that choice is the whole
   reason nothing above had to be rewritten. tools.css:1610 pins
   `.view[data-view="trades"] .tape-panel { height: 100% }` so the sticky
   column header has a scrollport to stick inside, and instrument.css:754 pins
   `body .tape-panel { flex: none !important }`. In a flex column the pane's
   100% would resolve against the WHOLE view and overflow it by exactly the
   height of the segmented control, and fixing that would mean out-!importanting
   another file's layout. In a grid, a percentage height resolves against the
   GRID AREA — the minmax(0, 1fr) track — so `height: 100%` silently starts
   meaning "the room left under the tabs", which is what it always meant, and
   `flex: none` is inert because the pane is no longer a flex item.
   minmax(0, 1fr) rather than 1fr: an fr track floors at min-content, and the
   tape's min-content is 2,000 rows. */
/* :not([hidden]) IS LOAD-BEARING, NOT TIDINESS. Without it this selector is
   (0,2,2) and nav.css:31 `.view[hidden] { display:none }` is (0,2,0), so the
   grid won the cascade even while the view carried `hidden` — measured live
   on 2026-08-19: on #trade the Trades view rendered 774px tall with
   hidden=true, on top of a Compare view collapsed to 14px. Same defect the
   block below fixes for panes, one level up. Guard the selector rather than
   out-!importanting nav.css: when the view IS hidden this rule simply does
   not apply and the existing hide rule is left to do its job. */
html body .view[data-view="trades"]:not([hidden]) {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  align-content: stretch;
  gap: 10px;
  min-height: 0;
}

/* A HIDDEN PANE MUST ACTUALLY HIDE. `[hidden] { display: none }` is a USER
   AGENT rule, and style.css:897 sets `.tape-panel { display: flex }` as an
   AUTHOR rule — author beats UA at any specificity, so the hidden tape pane
   would have stayed on screen underneath the settled one. This is the same
   defect nav.css:31 already fixes for `.view[hidden]`, one level down. */
html body .view[data-view="trades"] > [data-pane][hidden] { display: none !important; }

/* THE SEGMENTED CONTROL. .pf-b is the house pill (learn.css above: "Two
   buttons, one obviously on. The choice is the interface, not a dropdown
   hiding it"), reused rather than reinvented so the two cannot drift. Only the
   parts that are specific to these being ANCHORS are set here — .pf-b was
   written for <button>, which is not a link and does not inherit link colour,
   underline or baseline. They are anchors because the pane state is addressable
   (#trades, #settled): a real href middle-clicks into a new tab and survives a
   reload, and it is never empty, which is the bug nav.js:252 records. */
html body .trv-seg {
  display: flex; gap: 8px; flex-wrap: wrap;
  align-items: center; min-width: 0;
}
html body a.trv-b {
  display: inline-flex; align-items: center;
  text-decoration: none !important;
  /* --t-sm is forced onto `body *:not(svg):not(svg *)` at instrument.css:343
     with !important, which beats a normal declaration at ANY specificity, so a
     type step that is not !important silently flattens. .pf-b already carries
     its own !important 13px; this only has to not undo it. */
  line-height: 1 !important;
  padding: 9px 18px;
}
html body a.trv-b:hover { text-decoration: none !important; }
/* AND THE ON-STATE INK, for the same reason as the two lines above. .pf-b.on
   (learn.css:237) sets `color: var(--bg)` — dark on the accent, which is what
   .td-share does — but instrument.css carries `body a { color: var(--ink)
   !important }`, and these pills are ANCHORS. Measured 2026-08-19: the active
   pane pill rendered #f8f4f0 on #ff7a1a = 2.38:1, against 7.58:1 for the
   identical button-based pill on Today. Same component, two colours, one app. */
html body a.trv-b.on { color: var(--bg) !important; }

/* THE SETTLED PANE SCROLLS ITSELF, the way the tape's grid does two rules up.
   The alternative is letting main.stage scroll the whole section, which is how
   this content behaved inside the tools view — but then the tab strip leaves
   the screen on the first flick and the way back to the live tape is above the
   fold. One section, one pair of tabs, always reachable. */
/* !important, AND IT IS NOT OPTIONAL. instrument.css:712 carries
   `body .panel { overflow: visible !important }` as part of its density pass,
   and an important declaration beats this selector's (0,4,2) at any
   specificity — so the block below was DEAD and the pane never scrolled.
   Measured 2026-08-19 at 1500px: the pane painted 865px tall with its content
   running to 24,505px, so the ladder, the punch line and both regroupings
   rendered BELOW the panel's bottom rule on bare ground, and the rule itself
   cut across the middle of the section. Scoped to this one pane rather than
   weakened upstream: every other .panel in the app still wants the blanket. */
html body .view[data-view="trades"] > .trv-pane[data-pane="settled"] {
  min-height: 0;
  overflow-y: auto !important;
  overflow-x: hidden !important;
  overscroll-behavior-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--line2) transparent;
}
html body .view[data-view="trades"] > .trv-pane::-webkit-scrollbar { width: 12px; }
html body .view[data-view="trades"] > .trv-pane::-webkit-scrollbar-track { background: transparent; }
html body .view[data-view="trades"] > .trv-pane::-webkit-scrollbar-thumb {
  background-color: var(--line2); border-radius: 12px; border: 3px solid var(--s1);
}
html body .view[data-view="trades"] > .trv-pane::-webkit-scrollbar-thumb:hover {
  background-color: var(--ink3);
}

/* THE BAND LADDER IS NOT THE TAPE, EVEN THOUGH IT WEARS ITS CLASSES.
   The settled table is `<div class="tw st-grid">` on purpose — the block above
   explains that it borrows .tw-head/.tw-row/.tw-c so the two tables cannot
   drift. Inside the Trades view that reuse collects one rule it must not have:
   tools.css:1665 gives `.view[data-view="trades"] .tw { height: 100% }`, which
   is correct for the tape (it fills a scrollport) and wrong here (it would
   stretch a six-row ladder to the height of the pane and then clip it, because
   the pane is the scroller now). The table sizes to its rows; the PANE scrolls.
   Not a blanket reset: display:flex and container-type from tools.css:1111 are
   what .st-grid's own container queries and cell layout depend on. */
html body .view[data-view="trades"] .tw.st-grid { height: auto; }

/* The two extra cuts share the ladder's shape but have one column fewer, so
   they get their own track list rather than inheriting one that would leave a
   gap. `html body` because controls.css:1436 sets --tape-cols on
   `html body .tw-grid` at a specificity a bare class loses to, which once
   collapsed a table to a single column that passed an overflow test. */
html body .st-grid--cut {
  --tape-cols: minmax(132px, 1.6fr) minmax(84px, 0.9fr) minmax(120px, 1.3fr)
               minmax(126px, 1.3fr) minmax(128px, 1.4fr);
}
/* One line where three paragraphs were. Still says all three things. */
.st-foot {
  margin: 22px 0 0; padding-top: 14px; border-top: 1px solid var(--line2);
  max-width: 92ch; font-size: 11px !important; line-height: 1.75; color: var(--ink3);
}

/* ── THE SETTLED TAPE: ONE ROW PER POSITION ───────────────────────────────
   Owner, 2026-08-19: "make the trades settled show like the rest of trades:
   by min / days etc in a table and columns near it showing more details with
   venue etc". The three tables above are one dataset grouped three ways; this
   is the dataset.

   IT BORROWS .tw-head / .tw-row / .tw-c / .stk AND NOTHING ELSE, which is the
   same reuse the band ladder above documents. What it deliberately does NOT
   wear is either of the two classes that carry the live tape's LAYOUT:

     .tw-grid  declares --tape-cols for the live tape at four container widths.
               This table has a different column count at every one of those
               widths, and reading nine tracks out of a five-track variable is
               how the ladder above once collapsed into a single unreadable
               column that passed an overflow assertion.
     .tw       is where tools.css:1665 hangs `height: 100%` inside the Trades
               view — right for a tape that fills its own scrollport, wrong for
               one that sizes to its rows inside the settled pane, which is the
               scroller here. It is also display:flex, and a sticky header
               inside a flex container is trapped in its own flex line
               (tools.css:1640 measures that at -142px of drift). .st-tape is a
               plain block, so .tw-head is in normal flow and sticks against the
               pane, which is the box the reader is actually scrolling.

   THE CONTAINER IS .st-tape AND THE TRACKS ARE ON .st-tw, one element down,
   because an element cannot be queried against itself: a container query
   resolves against the nearest ANCESTOR container. Same two-element shape the
   live tape uses (.tw wraps .tw-grid) and for the same reason. */
html body .st-tape {
  container-type: inline-size;
  display: block;
  min-width: 0;
}
html body .st-tw { display: block; min-width: 0; }

/* THE COLUMN COUNT CHANGES WITH THE WIDTH, AND THE TRACK WIDTHS CARRY NO PIXEL
   FLOORS. Both halves are the live tape's own rule and both are recorded
   failures in this file: floors chosen so a label could never clip summed to
   678px inside a 570px container and pushed the last column off a surface that
   does not scroll sideways. minmax(0, Nfr) lets a track shrink below its
   content, .stk .p already carries the ellipsis, and the full string is on the
   row's title.

   EVERY TRACK LIST BELOW MUST MATCH THE HIDE-SET DIRECTLY UNDER IT. Grid places
   every visible child in order, so a column that is display:none while its
   track is still in the list shifts every column after it by one. The two are
   one decision written twice, and they are adjacent so they cannot be edited
   apart. Assert the TRACK COUNT when testing this, never just "nothing
   overflowed": a one-track grid never overflows either.

   NINE COLUMNS — the live tape's nine (owner: "follow the style of live fills
   to keep both in the same style"), with age+expiry collapsed into one and
   value taking the track that frees up:

     DOM order   settled  asset  what happened  size  premium  value  venue  taker  maker
     tier           0       1          0         2      0       0      2      3      3

   Proportions for the shared columns are the live tape's own (tools.css:1235:
   age 1, asset 1.9, act 3, size 2, premium 2, venue 1.5, taker 2.3, maker 2.3)
   so the two panes line up when a reader flips between them.

     base   settled, what happened, premium, value            4 tracks
     560    + asset                                           5
     900    + size, venue                                     7
     1100   + taker, maker                                    9

   1100, NOT the live tape's 1060, for the last step. It was 1180 for one commit
   and that threshold is UNREACHABLE: the panel caps .st-tape at 1138px even in
   a 1900px viewport, so taker and maker never appeared at any window size. 1100
   clears the 1130 the section actually renders at and stays above the 920 of
   the step below it. The step where a column APPEARS is the step where it has
   to fit. */
html body .st-tw {
  --tape-cols: minmax(0, 1.55fr) minmax(0, 2.95fr) minmax(0, 1.9fr) minmax(0, 1.45fr);
}
html body .st-tape .st-c-ast,
html body .st-tape .st-c-siz,
html body .st-tape .st-c-ven,
html body .st-tape .st-c-tak,
html body .st-tape .st-c-mak { display: none; }

@container (min-width: 560px) {
  html body .st-tw {
    --tape-cols: minmax(0, 1.5fr) minmax(0, 1.9fr) minmax(0, 3fr)
                 minmax(0, 2fr) minmax(0, 2.4fr);
  }
  /* `flex`, NOT `block`. Re-showing a .tw-c as block strips the column flexbox
     the stacked cells are built on and collapses both lines into inline text —
     the second half of the bug tools.css:1215 records. */
  html body .st-tape .st-c-ast { display: flex; }
}
@container (min-width: 900px) {
  html body .st-tw {
    --tape-cols: minmax(0, 1.5fr) minmax(0, 1.9fr) minmax(0, 3fr)
                 minmax(0, 2fr) minmax(0, 2fr) minmax(0, 2.2fr)
                 minmax(0, 1.5fr);
  }
  html body .st-tape .st-c-siz,
  html body .st-tape .st-c-ven { display: flex; }
}
@container (min-width: 1100px) {
  html body .st-tw {
    --tape-cols: minmax(0, 1.4fr) minmax(0, 1.6fr) minmax(0, 2.7fr)
                 minmax(0, 1.75fr) minmax(0, 1.75fr) minmax(0, 1.85fr)
                 minmax(0, 1.6fr) minmax(0, 2.05fr) minmax(0, 2.05fr);
  }
  html body .st-tape .st-c-tak,
  html body .st-tape .st-c-mak { display: flex; }
}

/* THE ACTION INKS BUY/SELL, THE WAY THE LIVE TAPE'S DOES. instrument.css:1497
   colours it as `body .tw-c.c-act .tw-b.buy .p`, and that selector needs a
   .tw-b — a BUTTON, which the live tape's action cell is because clicking it
   filters the tape. This table has no facet filtering, so its action cell is a
   plain .stk and inherited none of it. Same two tokens, same two states, no
   button: a control that looks clickable and is not would be worse than a
   colourless cell. */
html body .st-tape .tw-c.c-act .stk.buy .p  { color: var(--pos) !important; }
html body .st-tape .tw-c.c-act .stk.sell .p { color: var(--neg) !important; opacity: 1 !important; }

/* THE SAME STACK FIX THE LADDER ABOVE NEEDED, for the same reason and it is
   worth repeating rather than widening that selector: controls.css:1433 pins
   .tw-c to flex-start and .tw-c.num to flex-end with !important, and the cells
   are flex-direction:column, so that is VERTICAL alignment. The rows here are
   not uniformly two lines — asset, size and distance are one — so without this
   a one-line cell sat at the top of the row and the numeric one beside it sat
   at the bottom, and each row read as two. Giving the stack flex:1 hands the
   centring back to .stk's own justify-content, which is what the tape intends;
   stretching it keeps the numeric columns' right edge on one line. */
html body .st-tape .tw-c .stk {
  flex: 1 1 auto;
  align-self: stretch;
  justify-content: center;
}
/* The asset mark rides INSIDE the primary line here rather than beside it as
   it does on the live tape, because this cell's second line is the venue. It
   is an illustration of the word next to it, so it takes no space it does not
   need and no baseline of its own. */
/* display:inline-block IS THE WHOLE RULE. style.css:739 sets `.mk{display:block}`
   for the flex contexts every other surface puts a mark in, and inside a nowrap
   text line a block-level svg takes a line of its own: measured, the asset cell
   rendered the glyph, then "BTC", then "Derive" as three lines inside a row
   that is physically 44px tall, so the venue was clipped out of the bottom of
   its own cell. */
html body .st-tape .st-c-ast .mk {
  display: inline-block; vertical-align: -2px; margin-right: 5px;
}
/* THE TIER, WHERE IT CANNOT BE MISSED. A substitute row is a paradex fill
   priced on derive's settlement for the same expiry: defensible, both cut at
   08:00Z, and NOT paradex's own number, so the row has to say so (house rule
   5) in something a skimming reader will actually see.

   --accent, AND THE FIRST CUT'S --warn WAS MEASURED IN THE BROWSER RATHER THAN
   TRUSTED: in the shipped dark theme --warn resolves to #8a877e, byte-identical
   to --mid and to --v3 and one step off --ink3, so the label it was supposed to
   flag rendered as the same grey as every other secondary line beside it. A
   token named for a job it is not doing in this theme is exactly the trap
   instrument.css records for --s2 resolving to transparent. */
html body .st-tape .st-sub-tier { color: var(--accent) !important; }
/* NO height RESET IS NEEDED HERE, and that is the point of not wearing `tw`.
   .tw.st-grid one block up exists only because that element carries the class
   tools.css:1665 hangs `height: 100%` off. .st-tape carries neither `tw` nor
   `tw-grid`, so it sizes to its rows on its own and the PANE keeps the scroll.
   Adding `tw` to it later would silently reintroduce both that stretch and the
   trapped-sticky-header bug, which is why the JS says so too. */

/* ── TRADERS ────────────────────────────────────────────────────────────────
 *
 * Built on the SAME .tw-head/.tw-row/.tw-c machinery as the live tape and the
 * settled tape so all three line up when a reader flips between them, and so a
 * column rule fixed in one place is fixed everywhere.
 *
 * THE CONTAINER IS .tr-tape AND THE TRACKS ARE ON .tr-tw, one element down: a
 * container query resolves against the nearest ANCESTOR container, so an
 * element cannot be queried against itself. Identical two-element shape to
 * .st-tape/.st-tw above.
 *
 * EIGHT COLUMNS SINCE 2026-08-27, DOWN FROM THIRTEEN (owner: "check what are
 * the important columns in traders and keep only the important ones, and for
 * the style follow the trades style please"). EVERY TRACK LIST BELOW MUST MATCH
 * THE HIDE-SET UNDER IT. Grid places every visible child in order, so a column
 * left display:none while its track stays in the list shifts every column after
 * it by one. The two are one decision written twice, kept adjacent so they
 * cannot be edited apart. Assert the TRACK COUNT when testing, never just
 * "nothing overflowed": a one-track grid never overflows either.
 *
 *   DOM  address role legs premium net realised edge flip
 *   tier    0     1    0     2      0     2      3    1
 *
 *     base   address, legs, net                                 3 tracks
 *     560    + role, flip                                       5
 *     900    + premium, realised                                7
 *     1100   + edge                                             8
 *
 * WHAT THE FIVE DELETED TRACKS BOUGHT, in pixels, because that is the half of
 * this change a stylesheet can state. At thirteen tracks the 1138px container
 * left 948px of content after 12px of inset a side, so the board bought two of
 * its columns back by cutting that inset to 7px, and twelve of the thirteen
 * tracks then sat within about 2px of their binding content. At eight tracks
 * the SAME 946px of content is available at the site-standard 12px inset, so
 * the 7px override is DELETED with the columns that needed it, along with the
 * trap it carried: that rule needed a third class and an !important to beat
 * controls.css:998, and the first attempt at it had neither and clipped four
 * headers at once. Every track below now carries tens of pixels of margin
 * rather than ones, which is why the labels are whole words again ("Premium",
 * not "Prem"; "Realised", not a shortened form) for the first time since the
 * header budget got tight.
 *
 * WHERE THE DELETED COLUMNS' FACTS WENT, because none of them was thrown away:
 *   Sold     the second line of the Legs cell.
 *   RFQ      the second line of the Premium cell.
 *   Biggest  the Legs cell's title. Its denominator was the NET, so on 44 of
 *            the 80 ranked rows the ratio exceeded 100% and had to be rendered
 *            as a multiple; a column needing that escape hatch on 55% of its
 *            rows is not a column, and Flip measures the same instability
 *            honestly.
 *   Early    the Net cell's title, which is the figure it qualifies.
 *   Dates    the Legs cell's title.
 * The money version of Early is now on the board in its own right: the second
 * line of the Realised cell splits that total into the half booked at
 * settlement, and on 39 of the 79 scored rows the two halves disagree in sign.
 *
 * WHAT THE PAYLOAD STILL CARRIES AND THIS BOARD STILL DOES NOT SHOW.
 * /api/realised computes more per address than eight tracks should hold, and
 * the ones left out are left out on purpose. Ranked by what they would change:
 *   net_to_venue / rebates_earned. The venue PAYS a handful of these addresses,
 *     so net_to_venue goes negative and no board that ranks fees paid can
 *     express it. Deliberately NOT added: for the large majority of rows it
 *     restates the fee number Derive's own board already publishes. The right
 *     home is a fourth marker chip in the Role cell, and that chip row is
 *     nowrap: it fits three chips at this tier and a fourth needs its own
 *     measurement pass before anyone adds one.
 *   median_moneyness_pct / median_tenor_days, where on the surface the address
 *     trades, and the honest ones: they are computed from each fill's own
 *     index_price at TRADE TIME, not from spot now. Two figures, one track's
 *     worth of meaning, and no track.
 * None of these may be rendered as a zero or a blank if they ever land. They
 * are absent, and absence on this board is always a word with a reason.
 *
 * A HEADER COSTS ITS TEXT PLUS TEN PIXELS, AND FORGETTING THAT SHIPPED FIVE
 * CLIPPED HEADERS AT ONCE. Every sortable label lives inside a .tw-sort flex
 * button that also carries a .tw-caret: the caret measures 6px and the button's
 * gap is 4px, so the label's real budget is the cell's content box MINUS 10.
 * The first costing of the thirteen tracks compared the label to the CELL and
 * declared the fit good; the render came back reading "iOLD", "iLOCKS",
 * "REMIUM", "LOSED" and "XPIRIES". Nothing reported it: not the body's
 * scrollWidth, not the cell's, not the track count, and NOT the button's
 * either, because the button is a flex box that never overflows: its TEXT NODE
 * shrinks instead. It was caught by reading a screenshot. THE TEST THAT WORKS
 * is geometric: put a Range over the element's own text node and compare its
 * rect against the box, on HEADERS AND ON BODY CELLS, walking every descendant.
 *
 * THE ADDRESS TRACK IS THE ONE THAT MAY NOT BE SQUEEZED, and measurement is why.
 * The cliff was measured directly, by stepping the track down and counting
 * ellipsized rows: at 182.0px of content 0 of 80 rows truncate, at 179.5px 71
 * of them do. A clipped header loses a letter; a squeezed address loses the
 * identity of every row on screen. It is the first and largest track at every
 * tier and it took the largest share of what the five deleted columns gave back.
 *
 * FLIP IS IN THE SECOND TIER, NOT THE LAST, and it is last in the DOM. Those
 * are the same decision seen twice: reading left to right it is the last word
 * on everything beside it, and reading by width it has to survive to 560px
 * because it is the column that says whether the ORDER means anything, and the
 * order is on screen at every width.
 *
 * AND BELOW 560px THE COLUMN IS GONE, SO THE FIGURE IS NOT. The base tier is
 * three tracks and none of them can be Flip: measured at 390px the container is
 * 300px, a fourth track wants 43px of it, and there is nowhere to take 43px
 * from. The address cell is 156px and needs every one of them for a rank chip,
 * an address, an explorer link and a share control; Net has 73px for a value
 * that wants 72.4; Legs has 45px for a header that wants 41.7. For as long as
 * a fourth track was the only way to show Flip, a PHONE GOT A RANKED BOARD WITH
 * NO UNCERTAINTY ON IT, which is the one thing this board may never be, at the
 * width where a posted link is most likely to be opened.
 *
 * .tr-nf IS THAT FIGURE AS A SECOND LINE INSIDE THE ADDRESS CELL: "sign flips
 * 23%", under the address, in the only cell that survives to the base tier. Not
 * a tooltip, not a toggle, not an info icon, because every one of those needs an
 * action the reader is by definition not taking. It costs NO track and NO row
 * height (the cell holds 20px of controls in a 35px content box), so the rule
 * this file opens with is untouched: three tracks in, three tracks out.
 *
 * .tr-nf AND .tr-c-flp ARE ONE DECISION WRITTEN TWICE, exactly like a track list
 * and the hide-set under it, and they are kept adjacent below for the same
 * reason. Exactly one of the two is visible at every width. Show both and the
 * same number is on the row twice; hide both and the board is dishonest.
 *
 * NO PIXEL FLOORS on the tracks. Recorded failure in this file: floors chosen
 * so a label could never clip summed to 678px inside a 570px container and
 * pushed the last column off a surface that does not scroll sideways.
 * minmax(0, Nfr) lets a track shrink below its content and the full string is
 * on the cell's title. */
html body .tr-tape {
  container-type: inline-size;
  display: block;
  min-width: 0;
}
html body .tr-tw { display: block; min-width: 0; }

/* THE BASE TIER IS UNCHANGED BY THE CUT FROM THIRTEEN TO EIGHT, and that is
   worth stating rather than leaving to be noticed: nothing deleted was visible
   at this width, so not a pixel here moved. The proportions are measured. At
   390px the container is 300px, so 2.6/1.3/1.9 gave the address 133.6px: the
   rank chip, the share button and their gaps take 62px of that, which left
   59.6px for an identicon, a truncated address that wants 86px, and an explorer
   arrow, and the address ellipsized to "0x…". The 14px came off Net, which
   needs 62px for its longest value ("+$543.0K" at the 13px mono step) and had
   86px. Legs is left alone on purpose: its header already sits close to its own
   LEFT edge at this width, where a right-aligned .tw-c gets no ellipsis and
   scrollWidth reports nothing, so taking pixels from it would make a defect
   quietly worse.
   THE RANK CHIP IS WIDER ON A TWO-DIGIT RANK and that is what the address track
   is really paying for. Measured, with the chip at 4px of side padding: rows 1
   to 9 rendered the address whole and rows 10 down lost the last four
   characters to an ellipsis, which is a defect that shows up nowhere except on
   the rows a reader scrolls to. 8.4px of track plus 2px off the chip covers the
   widest chip on the board. */
html body .tr-tw {
  --tape-cols: minmax(0, 3.19fr) minmax(0, 1.16fr) minmax(0, 1.75fr);
}
html body .tr-tape .tr-c-rol,
html body .tr-tape .tr-c-prm,
html body .tr-tape .tr-c-rls,
html body .tr-tape .tr-c-edg,
html body .tr-tape .tr-c-flp { display: none; }
/* AND THE OTHER HALF OF THE SAME DECISION. .tr-c-flp is hidden directly above;
   .tr-nf carries its figure on the row instead, so the base tier is never a
   ranking without its uncertainty. Read the block at the head of this section.
   `block` and not `flex`: it is one line of text, and it is a sibling of
   .tr-idc inside a .tw-c that is already a column flex, so it needs no box of
   its own. `flex: none` is the guard the tape's own arithmetic asks for: if
   this line ever outgrows its 35px content box it must CLIP against the cell's
   overflow:hidden rather than squash into the line above it. */
html body .tr-tape .tr-nf { display: block; }

@container (min-width: 560px) {
  /* FIVE TRACKS, AND THE SAME FIVE COLUMNS AS BEFORE THE CUT. Role and Flip are
     the two that arrive here and that is unchanged: Role says what kind of
     business the row is and therefore how every figure beside it should be
     read, and Flip says how much of the ORDER to believe. Neither is a question
     a reader can defer to a wider screen.
     THE PROPORTIONS DID CHANGE, AND THEY FIX A DEFECT THIS CUT DID NOT CAUSE.
     The old split was 2.4/1.9/1.1/1.8/1.1 and it was costed at the TOP of this
     tier. At the BOTTOM of it the address was clipping on all 80 rows, and
     silently, because a truncated address is ellipsized by tape.js's own cell
     and reports nothing to a track count, a row scrollWidth or a body
     scrollWidth. Measured, by stepping a viewport across the whole tier: at a
     588.4px container the address text wanted 35.8px more than it had, at 612.4
     it wanted 16.9, at 686 it wanted 7.6, and from 717 up it fitted. Every row.
     The tier only looked healthy because the widths anyone had checked sat at
     its top end.
     THE INSET IS INSIDE THE TRACK, WHICH IS THE ARITHMETIC A FIRST PASS AT
     THIS FILE GETS WRONG. A track is `minmax(0, Nfr)` of the CONTAINER, and
     controls.css:998 then spends 12px a side of that track on the cell, so a
     column needing C pixels of content needs a track of C + 24 and the fr
     shares are costed against the CONTAINER, never against a pool of content.
     Costed the other way, Legs and Flip came out at 43.7px where they were
     meant to have 56, and the flip header wrapped. Measured, then corrected.
     COSTED AT THE NARROWEST CONTAINER THIS TIER ACTUALLY REACHES, which is
     575.6px (measured, not assumed: it is where the container query flips).
     Tracks, with the content each leaves in brackets:
       adr 196 (172)  rol 116 (92)  legs 80 (56)  net 102 (78)  flip 81 (57)
     against binding content of 148 for the address without its identicon (see
     the identicon block below), 88 for "Mostly quoting", 54 for the "100% sold"
     second line, 72.4 for the widest money value and 54.2 for the "sign flips"
     unit line, WHICH MAY NOT WRAP. At the top of the tier every one of those
     roughly doubles, and the marker row's 154px two-chip case comes in around
     an 870px container. */
  html body .tr-tw {
    --tape-cols: minmax(0, 3.41fr) minmax(0, 2.02fr) minmax(0, 1.39fr)
                 minmax(0, 1.77fr) minmax(0, 1.41fr);
  }
  /* `flex`, NOT `block`. Re-showing a .tw-c as block strips the column flexbox
     the stacked cells are built on and collapses both lines into inline text. */
  html body .tr-tape .tr-c-rol,
  html body .tr-tape .tr-c-flp { display: flex; }
  /* THE COLUMN IS BACK, SO THE LINE GOES. Exactly one of the two renders at any
     width: the same figure in two places on one row reads as two figures. */
  html body .tr-tape .tr-nf { display: none; }
}
@container (min-width: 900px) {
  html body .tr-tw {
    /* SEVEN TRACKS, DOM ORDER adr, rol, n, prm, net, rls, flp. Two columns
       arrive here and they arrive together on purpose: Premium is how much
       money moved and Realised is what the address booked of it, and each is
       carrying a second line the other's absence would make harder to read.
       COSTED AT THE BOTTOM OF THE TIER, a 900px container, because that is
       where it is tightest and where the previous costing of this file was not
       looking. Tracks, with the content each leaves after 24px of inset:
         adr 227 (203)  rol 154 (130)  legs 80 (56)  prem 120 (96)
         net 106 (82)   rls 132 (108)  flip 81 (57)              = 900
       Each figure is the largest of its header text PLUS 10px for the caret,
       its unit line where that line may not wrap, its widest VALUE, and its
       SECOND LINE where it has one. The binding one differs per column and that
       is the point.
         SECOND-LINE-BOUND: legs ("100% sold", 54), prem ("100.0% RFQ", 60),
           rls ("settled -564K" at the 10px mono step, 78).
         BODY-BOUND: rol ("Registered maker" at 96.3), net and rls (72.4 for
           "-$542.1K" and its siblings at the 15px money step).
         UNIT-LINE-BOUND: flip, whose "sign flips" wants 54.2 and MAY NOT WRAP.
         HEADER-BOUND: prem ("PREMIUM" at 68 plus the caret's 10).
       Subs that ARE allowed to wrap (Net, Realised) are costed on their longest
       WORD and not their full string.
       THE ADDRESS TRACK CAME OUT 35px AHEAD of the nine-track version this
       replaced, which is the whole dividend of deleting Sold and RFQ as tracks:
       both of their figures are still on this board, on the second line of the
       cell each belongs to, and neither is spending a track on it. */
    --tape-cols: minmax(0, 2.52fr) minmax(0, 1.71fr) minmax(0, 0.89fr)
                 minmax(0, 1.33fr) minmax(0, 1.18fr) minmax(0, 1.47fr)
                 minmax(0, 0.90fr);
  }
  html body .tr-tape .tr-c-prm,
  html body .tr-tape .tr-c-rls { display: flex; }
}
@container (min-width: 1100px) {
  /* EIGHT TRACKS, DOM ORDER adr, rol, n, prm, net, rls, edg, flp. Edge is the
     last column to arrive because it is the only one here that compares a price
     to a reference rather than counting an outcome: it qualifies the money
     columns beside it and a reader who never reaches this width has lost a
     qualifier, not a fact.
     THE 7px INSET OVERRIDE IS GONE WITH THE FIVE COLUMNS THAT NEEDED IT. It
     used to sit here, pinned at (0,3,2) with !important so it could beat
     controls.css:998, and it existed only because thirteen tracks spent 312px
     of a 1138px container on gutter. Eight tracks at the site-standard 12px
     spend 192px and leave 946px of content, which is the same total the
     override used to buy. One fewer scoped rule, one fewer place where a
     specificity mistake clips four headers at once, and the live tape and the
     settled tape were never touched by it either way.
     COSTED AT THE 1138px THIS CONTAINER CAPS AT, tracks first and the content
     each leaves after 24px of inset in brackets:
       adr 304 (280)  rol 193 (169)  legs 80 (56)   prem 124 (100)
       net 109 (85)   rls 138 (114)  edge 109 (85)  flip 81 (57)   = 1138
     Every one of those carries tens of pixels over its binding content
     rather than the ones and twos the thirteen-track version was living on,
     which is what took the labels back to whole words: "PREMIUM" needs 78 with
     its caret and has 100, "REALISED" needs 69 and has 114.
     LEGS AND FLIP ARE COSTED ON THEIR SECOND LINE AND THEIR UNIT LINE, not on
     their headers. LEGS needs 54 for "100% sold" against 52 for its header plus
     caret, and FLIP needs 54.2 for a "sign flips" unit line that MAY NOT WRAP
     against 35 for its header. Both sat at 43.7 for one revision and the flip
     header wrapped to two lines, which is the one header on this board that
     most has to be read at a glance. Caught by reading a screenshot.
     ROLE IS THE WIDEST NON-ADDRESS TRACK AND IT IS PAID FOR BY THE ADDRESS,
     which is the one reallocation in this file that goes the other way. Its
     binding content is not the role word (88px for "Mostly quoting") but the
     MARKER ROW under it: measured, "Custodied" is 66.2px and the maker chip was
     108.3px, so a two-chip row wanted 178.5px with its gap. At the 132px it
     held, that row was sliced THROUGH THE SECOND CHIP'S BORDER, mid-glyph, and
     nothing reported it: the chips are sized to their own text and it is their
     PARENT that clips them, so the Range test that catches every other clip on
     this board is structurally blind to it. It took a screenshot. Again, and
     that is now the fourth time this file has had to write that sentence.
     The address pays for it and still holds 280 against a measured cliff at 182
     that costs 71 of 80 rows their last four characters when crossed.
     WHAT IS STILL NOT FIXED, MEASURED AND STATED RATHER THAN LEFT TO BE FOUND:
     a TWO-CHIP row wants 154px of marker line even with the shortened labels,
     and the 560 tier gives Role between 93 and 156px. Two of the eighty ranked
     rows carry two chips, and below a 1130px container the trailing chip on
     those two rows ellipsizes. That is a visible truncation inside a complete
     chip with the full set on the cell's title, which is this file's own rule
     for what a shrinking track may do ("truncation that shows is fine; text
     sliding out of the table is not"). It is not the same defect as the slice
     it replaced, and closing it entirely would cost the address track more than
     its cliff allows at the bottom of that tier. */
  html body .tr-tw {
    --tape-cols: minmax(0, 2.67fr) minmax(0, 1.70fr) minmax(0, 0.70fr)
                 minmax(0, 1.09fr) minmax(0, 0.96fr) minmax(0, 1.21fr)
                 minmax(0, 0.96fr) minmax(0, 0.71fr);
  }
  html body .tr-tape .tr-c-edg { display: flex; }
}

/* THE OUTCOME COLUMNS INK THEIR SIGN, and that is the only colour on the board.
   Net and Realised carry .tr-net and are tinted; nothing else is. A ranking
   whose rows are already ordered by Net does not need the number shouted, and
   colouring Flip or the share sold would read as a verdict on the address
   rather than a property of the sample.
   (This comment said "the Net column" and named only Net for as long as Net was
   the only one. Realised has carried .tr-net since it landed, so the rule was
   already about a class and not a column; it is written that way now.)

   AND EDGE IS NOT INKED, WHICH IS THE DELIBERATE ASYMMETRY. It is a money
   figure with a direction, so tinting it would be consistent and would still be
   wrong. Net and Realised are OUTCOMES — what the entries were worth, what the
   address booked — and green on an outcome is a description. Edge is a
   COMPARISON against a reference price, so green on it reads as "this address
   trades well", which is a verdict the sample cannot support: the figure is
   absolute, so it scales with size before anything else, and on these rows a
   single negotiated ticket can carry the entire total. The sign is still on
   every value, in the minus glyph, where it is a fact rather than a grade.
   --pos/--neg are the palette's own direction tokens (chain.css:13). */
html body .tr-tape .tr-net { font-variant-numeric: tabular-nums; }
/* Same figures, no tint. It inherits the row's colour, which is one step down
   from the ink Net and Realised take, so it reads as a qualifier of the money
   beside it rather than as a fourth money column competing with them. It keeps
   the 15px Inter every wrapped value in this table gets, because that IS the
   money treatment and Edge sits directly beside the two columns wearing it. */
html body .tr-tape .tr-edge { font-variant-numeric: tabular-nums; }

/* ── THE STACKED CELLS, AND THE TWO FONT BLANKETS THAT EAT THEM ────────────
 * Four cells now carry a primary over a secondary line, which is the live
 * tape's own device and the reason this board is eight columns instead of
 * thirteen: Legs holds the share sold, Premium holds the share negotiated,
 * Realised holds the half booked at settlement, Role holds the marker chips.
 *
 * WRAPPING A VALUE IN AN ELEMENT CHANGES ITS TYPE IN THIS TABLE, and that is
 * not a figure of speech. A bare text node inherits the cell's 13px mono. An
 * ELEMENT is caught by instrument.css:343, `body *:not(svg) { font-size:
 * var(--t-sm) !important }`, and renders at 15px. Measured on the column this
 * rule was first written for: "100.0%" went from 47px to 57.7px and overflowed
 * a RIGHT-ALIGNED cell, where it spills off the LEFT edge with no ellipsis and
 * nothing reporting it. Every line below is now an element, so every line below
 * needs the pin.
 *
 * THERE ARE TWO BLANKETS, NOT ONE, AND THE SECOND ONE IS THE FAMILY.
 * The size blanket is the famous one, but `body *:not(svg):not(svg *)` is
 * declared twice in this app: once with `font-family: var(--mono) !important`
 * and again, later, with `font-family: var(--sans) !important`. The cell wins
 * mono through a more specific important rule of its own; a CHILD element does
 * not, so a span came out 15px Inter inside a 13px mono cell. A plain
 * `font-family: inherit` at (0,3,2) loses to an important declaration no matter
 * how specific it is, and `inherit` is no use here anyway: .stk is itself an
 * element and is itself blanketed, so a child inheriting from it inherits the
 * blanket. Both lines therefore name their own face and step.
 *
 * NOT A `font` SHORTHAND. The shorthand also resets font-style, which has
 * silently killed an italic in this file once. Longhands only.
 *
 * THE PRIMARY MATCHES THE CELL AND THE SECONDARY IS 10px, which is the same
 * relationship .tr-nf already has with the address above it and the same one
 * .stk .s has on the live tape. The money columns keep their 15px treatment: a
 * .tr-net span is deliberately NOT given .p, so Realised's total sits at the
 * same step as Net's beside it. That is the whole reason .p is a class and not
 * a rule on the first child. */
html body .tr-tape .tw-c .stk .p {
  font-family: var(--mono) !important;
  font-size: 13px !important;
  font-weight: 400 !important;
  font-variant-numeric: tabular-nums;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}
/* :not(.tr-mk) BECAUSE THE MARKER ROW IS A .s TOO AND IS NOT TYPE. It is a flex
   row of bordered chips that pin their own 10px, and letting this rule reach it
   would set a step on a container that has no text of its own while overriding
   the chip rule by specificity. Written at (0,5,2) so it beats that row's own
   (0,3,2) declaration only where it is meant to. */
html body .tr-tape .tw-c .stk .s:not(.tr-mk) {
  font-family: var(--mono) !important;
  font-size: 10px !important;
  font-weight: 400 !important;
  font-style: normal;
  line-height: 1.25;
  color: var(--ink3) !important;
  font-variant-numeric: tabular-nums;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}
/* THE STACK FILLS THE CELL, so the cell's packing stops deciding where the text
   sits. controls.css:1433 pins .tw-c to flex-start and .tw-c.num to flex-end
   with !important, and .tw-c is a COLUMN flex, so that is VERTICAL alignment;
   this board overrides it to center a few rules down. The rows here are not
   uniformly two lines (Net, Edge and Flip are one), so without this a one-line
   cell and a two-line cell beside it read as two half-rows. Giving the stack
   flex:1 hands the centring back to .stk's own justify-content, which is what
   the tape intends. Horizontal alignment is untouched: tools.css:1365 already
   pins .tw-c.num .stk to flex-end, which keeps the numeric columns' right edge
   on one line. Same rule, same reason, as .st-tape and .st-grid above. */
html body .tr-tape .tw-c .stk {
  flex: 1 1 auto;
  justify-content: center;
  min-width: 0;
}
html body .tr-tape .tr-up { color: var(--pos); }
html body .tr-tape .tr-dn { color: var(--neg); }

/* SHAKY IS DE-EMPHASIS, NOT ALARM. At or above a third, resampling this
   address's own legs reverses the sign of its total a third of the time, so the
   number is doing its job by being unreliable — it is muted and italic, which
   reads as "discount this row", where red would read as "this address lost". */
html body .tr-tape .tr-shaky {
  color: var(--ink3);
  font-style: italic;
}

/* The role chip. A word, not a colour: quoting and taking are two businesses,
   not two outcomes, and tinting them would imply one is better.
   IT IS A <button> SINCE THE FACET LANDED and it still has to look like the
   text it replaced, which is what .tr-rf below is for: a button carries a UA
   background, border, padding, alignment and font-family of its own, and every
   one of those had to be taken back off before this rule could describe what
   renders. The two are adjacent so they cannot be edited apart. */
html body .tr-tape .tr-role {
  font: 400 11px/1.3 var(--mono);
  color: var(--ink2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* .tr-lede AND .tr-cov WERE DELETED, NOT LEFT STANDING. They styled two of the
   three paragraphs that used to sit above the table; the owner removed all
   three ("i don't need this text") and tools.js renders none of them, so both
   rules had become instructions to a reader about markup that does not exist.
   The comment on .tr-cov was worse than dead: it said the coverage line MUST
   sit above the table, which the code had already stopped doing.

   THE FACT THAT LINE CARRIED IS NOT DELETED and must never be. This board is
   one venue on a product that indexes eleven, and it says so three times in the
   furniture instead of once in prose: the heading names Derive, the strip reads
   "1 of 11 venues scored" with the endpoint's own reason under it (.tr-st-w),
   and "on Derive" is the unit line under the Address header at every width
   (.tr-sub). Remove all three and the paragraph has to come back. */

/* CELLS CENTRE ON THE ROW, VIA justify-content AND NOT align-items.
   .tw-c is a COLUMN flex (it exists to stack a primary over a secondary line),
   so its cross axis is HORIZONTAL: align-items:center was the obvious-looking
   fix and it did nothing vertically while quietly dragging the Role cell to the
   middle of its track, away from the left edge every other text column sits on.
   Measured before: the role span sat at the top of a 35px content box, 8px
   above the figures beside it, and the row read as two half-rows.

   The role label is also pinned at --t-sm !important: instrument.css:343 sets
   `body *:not(svg) { font-size: var(--t-sm) !important }`, so an 11px rule here
   loses and the chip rendered LARGER than the numbers it labels. Matching the
   column deliberately beats losing to a global by accident. */
/* !important IS REQUIRED AND IT IS SCOPED TO THIS PANE ONLY. controls.css:1433
   pins `html body .tw-row .tw-c { justify-content: flex-start !important }` for
   every tape on the site, and no specificity beats an !important without one.
   The live and settled tapes never notice: their cells are two-line .stk blocks
   that fill the row, so top-aligning them is invisible. This board's cells are
   single-line, so the global left them sitting at the top of a 35px box. Same
   scoped-override shape the settled pane uses against instrument.css:712.
   Horizontal alignment is NOT touched here: controls.css:1435 keeps .num on
   flex-end, which is the cross axis and still correct. */
html body .tr-tape .tw-row .tw-c { justify-content: center !important; }
/* instrument.css:343 forces `body *:not(svg) { font-size: var(--t-sm)
   !important }`, which rendered the role chip LARGER than the figures beside
   it. Matched to the cell rather than left to lose to a global by accident. */
html body .tr-tape .tr-role { font-size: 13px !important; }

/* ── THE ONE FACET ─────────────────────────────────────────────────────────
 * The live fills tape's value cells are clickable facets and this board had
 * none; the owner asked for the tape's style, so Role is one now. Every other
 * column here is a magnitude, and the tape's own rule for a magnitude is that
 * "which is biggest" is a question about the COLUMN, so it stays in the header
 * as a sort. One facet, because there is exactly one field whose values are a
 * small closed set every row belongs to exactly one of.
 *
 * IT IS NOT A .tw-b, AND THAT IS MEASURED RATHER THAN STYLISTIC.
 * controls.css:1003 pins `body .tw-row .tw-b:not(.tw-ab) { width: calc(100% +
 * 24px) !important }`, which exists to bleed the live tape's buttons back over
 * a 12px cell inset. Every .tw-b on this board is the address button and it
 * carries .tw-ab, so it is excluded; a Role cell borrowing .tw-b would be the
 * first that is not, and it would hang 24px out of its own track. .tr-rf is
 * this board's own class and takes nothing from that file.
 *
 * A BUTTON ARRIVES WITH A UA BACKGROUND, BORDER, PADDING, CENTRED TEXT AND ITS
 * OWN FONT-FAMILY, and all five have to be taken off before .tr-role above can
 * describe what renders. font-family is `inherit` and not a token because
 * .tr-role deliberately does not name a face either: it takes whatever the
 * cell resolves to, and pinning one here would make this the only place on the
 * board where the role word's face is decided. */
/* align-self, NOT display:inline-block. .stk is a COLUMN flex and its default
   align-items is stretch, so a block child takes the whole track and the
   pressed state below would paint a pill the width of the column rather than
   the width of the word it marks. flex-start shrinks it to its text and keeps
   the ellipsis working, because max-width still caps it at the track. */
html body .tr-tape .tr-rf {
  display: block;
  align-self: flex-start;
  max-width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 3px;
  background: transparent;
  font-family: inherit;
  font-weight: inherit;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}
html body .tr-tape .tr-rf:hover { color: var(--ink); }
html body .tr-tape .tr-rf:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
/* THE PRESSED STATE IS INK, NOT COLOUR. Colour on this board is spent on the
   sign of the two outcome columns and nowhere else; a tinted role would read as
   a verdict on the business rather than as "this is what you clicked". Full ink
   against the row's muted default is enough of a step to find at a glance, and
   the chip above the rows states it in words as well. */
html body .tr-tape .tr-rf-on {
  color: var(--ink);
  background: color-mix(in srgb, var(--ink3) 16%, transparent);
  padding: 0 4px;
  margin-left: -4px;
}

/* DIMMED, NEVER REMOVED. On the live tape the reason is that a row which
   VANISHED when you filtered is indistinguishable from a fill that never
   happened. Here it is stronger: this is a RANKING, and lifting rows out of it
   would leave the rank numbers with holes and seat every survivor next to a
   number that no longer describes what is on screen. 0.26 is low enough to
   read as background and high enough that the shape of the board, which is the
   thing a reader is filtering against, is still there.
   NOT display:none AND NOT visibility:hidden: both would collapse the grid
   rows and both are the behaviour this board is refusing. */
html body .tr-tape .tr-row.tr-off { opacity: .26; }
/* The tier marking is a property of the RANKING and a dimmed row is still in
   it, so nothing here touches .tr-top. Sorting is what removes that marking
   (.tr-resorted, below); filtering does not reorder anything. */

/* THE FILTER STATE, ABOVE THE ROWS AND CARRYING ITS OWN WAY OUT. A filter a
   reader cannot see is on is a filter they will read the whole board through
   without knowing. The chip borrows .tw-chip from the live tape so the two
   surfaces state a filter the same way, and it takes no data-facet attribute:
   tape.js's handler is bound to its own .tw container and selects
   `.tw-chip[data-facet]`, so this can neither be reached by it nor look like
   something it owns. */
html body .tr-fbar {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px 12px;
  margin: 0 0 10px;
}
html body .tr-fbar[hidden] { display: none; }
html body .tr-fbar .tr-fn {
  font-size: 11px !important;
  line-height: 1.45;
  color: var(--ink3);
  max-width: 60ch;
}

/* A SELF-DISCLOSED NAME, shown above the address it belongs to. The address is
   never replaced by the name: the name is a claim its holder made, the address
   is the thing a reader can check on chain, and dropping the checkable half
   would turn evidence into a label. */
html body .tr-tape .tr-named {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
html body .tr-tape .tr-nm {
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: help;
}
.tr-claim-cta {
  margin: 0 0 14px;
  max-width: 74ch;
  color: var(--ink2);
}

/* The venue's own registration, under our measured read of the role. Muted and
   smaller: it qualifies the line above it rather than competing with it, and it
   is emphatically not a firm name. */
html body .tr-tape .tr-mk {
  color: var(--ink3);
  font-size: 11px !important;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: help;
}

/* ── TRADERS, PART TWO: THE LEADERBOARD ─────────────────────────────────────
 *
 * Everything above this comment styles a TABLE that lived in a pane of Trades.
 * Since 2026-08-25 the same table is a top-level section and a LEADERBOARD
 * (owner: "for the traders features i would add it as a section rather and see
 * the traders and add leaderboard and make it socialized"). Nothing above was
 * rewritten, because nothing above was wrong about the leaderboard: the four
 * container-query tiers, the hide-sets under them and the rule that every track
 * list must match the hide-set directly under it all still govern this file.
 * The COUNT above did change, from thirteen tracks to eight, on 2026-08-27; the
 * head of this section is where that is recorded.
 *
 * WHAT A LEADERBOARD ADDED, AND WHERE IT WENT. Two controls and one tier
 * marking, and ALL THREE ARE INSIDE EXISTING TRACKS OR OUTSIDE THE GRID:
 *
 *   .tr-rk      the rank, inside the address cell
 *   .tr-share   the per-row share control, inside the address cell
 *   .tr-top     a class on the row, which is not a cell at all
 *
 * NOT ONE NEW TRACK. A track for the rank and another for the share button
 * would have meant editing four track lists and four hide-sets, at four widths,
 * for a three-character number and a 13px icon. The address cell
 * is also the only cell that survives to the base tier, which is what makes
 * both controls reachable at 390px where five of the eight columns are hidden.
 *
 * IT MUST NOT READ AS A CASINO, and the whole defence is that the emphasis is
 * TYPOGRAPHIC. No medal, no colour ramp, no badge per position. The first three
 * rows take a slightly denser ground and a filled rank chip; rank one takes the
 * accent the rest of the product already uses for "this is the thing". Colour
 * on this board stays where it was: the Net column's sign, and nothing else.
 */

/* THE SECTION HEAD. A rail item is arrived at cold and from a link, so it gets
   a heading line rather than the bare h2 a pane could get away with. The share
   control sits on that line and is RENDERED BY tools.js AND WIRED BY NEITHER
   FILE: the share module binds it. */
.tr-hd {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.tr-hd .tl-h { margin: 0; }

html body .tr-share-board {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--ink2);
  font: 500 12px/1 var(--mono) !important;
  font-size: 12px !important;
  cursor: pointer;
  white-space: nowrap;
  flex: 0 0 auto;
}
html body .tr-share-board:hover {
  color: var(--ink);
  border-color: var(--accent);
}
html body .tr-share-board:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* THE SAMPLE, BEFORE THE ROWS. Five figures, every one a payload field. It is a
   <ul> because it is a list of facts and not a table: giving it grid tracks
   would invite the next reader to align it with the board below, and the two
   have nothing to do with each other. */
html body .tr-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 28px;
  margin: 12px 0 14px;
  padding: 0;
  list-style: none;
}
html body .tr-stats li {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
html body .tr-stats b {
  font: 600 18px/1.1 var(--mono) !important;
  font-size: 18px !important;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
html body .tr-stats span {
  font-size: 11px !important;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink3);
}

/* THE ADDRESS CELL NOW HOLDS THREE THINGS, so it needs a row inside a column.
   .tw-c is a COLUMN flex (tools.css:1350) and this is its single child, so the
   horizontal arrangement has to be declared here rather than on the cell.

   `width: 100%` and not `flex: 1`: the cell's cross axis is horizontal and its
   default align-items is stretch, but controls.css:1505 gives every direct
   child of a .tw-c `min-width: 0` plus `overflow: hidden`, and a stretched item
   with min-width:0 still needs to be told to take the line. */
html body .tr-tape .tr-idc {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  min-width: 0;
}
/* The identity half is the only part allowed to absorb the slack, and the only
   part allowed to shrink. The rank and the share control are fixed. */
html body .tr-tape .tr-who {
  display: flex;
  align-items: center;
  gap: 5px;
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
}

/* THE RANK. tools.css:1712 pins `body .tw-c b { font-size: 14px !important }`
   and instrument.css:343 pins every element to --t-sm !important, so a rank
   chip authored at 12px without an !important of its own renders at 14 or 15
   and out-shouts the address next to it. Declared at (0,2,2) with !important,
   which is the same manoeuvre .tr-role and .tr-mk above already make. */
html body .tr-tape .tr-rk {
  flex: 0 0 auto;
  min-width: 22px;
  padding: 2px 5px;
  border-radius: 5px;
  text-align: center;
  font: 600 12px/1.35 var(--mono) !important;
  font-size: 12px !important;
  font-variant-numeric: tabular-nums;
  color: var(--ink3);
  /* A TRANSLUCENT INK TINT, NOT A SURFACE TOKEN. The chip was var(--s2), which
     is also the ground the first tier's rows take three rules below: on ranks
     two and three the chip and the row it sits on resolved to the same colour
     and the chip vanished, leaving a bare numeral exactly where the board is
     making its loudest claim. An ink-derived tint cannot collide with a
     surface, because it is defined against the text colour and composites over
     whatever is behind it. --line was the other candidate and is worse: the
     default palette declares --line and --s2 as the SAME hex (style.css:54 and
     :56), so a hairline ring would have been invisible for the same reason. */
  background: color-mix(in srgb, var(--ink3) 16%, transparent);
  letter-spacing: 0;
  cursor: help;
}

/* THE PER-ROW SHARE CONTROL. Rendered on every row and wired by the share
   module, never here. It is dimmed rather than hidden-until-hover: hover does
   not exist on the width where this board is most likely to be screenshot, and
   a control that only appears to a mouse is a control half the readers do not
   have. 0.45 is still a hit target and still visibly a button. */
html body .tr-tape .tr-share {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--ink3);
  opacity: .45;
  cursor: pointer;
}
html body .tr-tape .tr-share:hover,
html body .tr-tape .tr-share:focus-visible {
  opacity: 1;
  color: var(--ink);
  background: var(--glass);
}
html body .tr-tape .tr-share:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
/* The icon carries its own size on the element (width/height attributes) so it
   cannot lose to instrument.css:343, which exempts <svg> and nothing else. */
html body .tr-tape .tr-sh-i,
html body .tr-share-board .tr-sh-i { flex: 0 0 auto; }

/* ── THE FIRST TIER ────────────────────────────────────────────────────────
   Three rows, marked on the ROW so every column stays in its track. The four
   things that qualify a row (Flip, and the second line under Legs, Premium and
   Realised) are the ones a reader is most likely to skip on exactly these three
   rows, which is why the marking may never be a card that lifts a row out of
   the grid.

   The tier boundary is a single hairline under row three, not a gap: a gap
   would break the row rhythm the tape shares with the two boards next door. */
/* --s2, NOT --glass. .tw-row:hover is already var(--glass) (tools.css:1345),
   so a tier marked with the same token would be indistinguishable from a row
   the cursor happens to be on, and would vanish entirely under it. --s2 is the
   palette's second surface and the rows sit on --s1, so the band reads as a
   step in the surface rather than as a tint. No colour is spent here. */
html body .tr-tape .tr-row.tr-top { background: var(--s2); }
html body .tr-tape .tr-row.tr-top-3 { box-shadow: inset 0 -1px 0 var(--line); }
html body .tr-tape .tr-row.tr-top .tr-rk {
  color: var(--ink);
  background: color-mix(in srgb, var(--ink3) 26%, transparent);
}
/* Rank one takes the product's own attention colour, which is already what
   --accent means everywhere else here. One instance, on one row. */
html body .tr-tape .tr-row.tr-top-1 .tr-rk {
  color: var(--bg);
  background: var(--accent);
}
html body .tr-tape .tr-row.tr-top .tr-share { opacity: .7; }

/* ── AND IT ALL LEAVES WHEN THE RANKING DOES ───────────────────────────────
   trApplyOrder puts .tr-resorted on the container while any column sort is on.
   Sort by Flip and the three marked rows scatter; a highlight left sitting on
   visible rows 12, 40 and 3 reads as a bug, or worse, as a second verdict
   nobody explained. The tier marking is a property of the ranking, so it is
   visible only while the ranking is what is on screen.

   THE RANK NUMBER ITSELF DOES NOT LEAVE, it only stops being a chip. It is the
   row's answer to "where does this sit in the ranking", which is a question a
   re-sorted reader asks more often and not less. */
html body .tr-tape.tr-resorted .tr-row.tr-top { background: transparent; }
html body .tr-tape.tr-resorted .tr-row.tr-top-3 { box-shadow: none; }
html body .tr-tape.tr-resorted .tr-row.tr-top .tr-rk,
html body .tr-tape.tr-resorted .tr-row.tr-top-1 .tr-rk {
  color: var(--ink3);
  background: color-mix(in srgb, var(--ink3) 16%, transparent);
}

/* ── WHERE THIS BOARD MEETS THE SHARE MODULE ───────────────────────────────
 * traders-share.css styles .tr-share and .tr-share-board too, and that is not
 * a mistake by either side: this file renders those two controls and that file
 * gives them behaviour, so both had an opinion about how they should look. The
 * collision is resolved by SPECIFICITY and not by load order, deliberately, so
 * a re-ordered <link> cannot change what renders: every rule here is written at
 * (0,2,2) or better against that file's (0,1,0) class selectors.
 *
 * WHAT THIS FILE INSISTS ON AND WHY. The row control is a 24px icon, not the
 * labelled chip that file draws. At the base container tier this board is
 * three tracks wide and the address cell carries a rank, an identicon, a
 * truncated address, an explorer arrow and this button inside roughly 120px; a
 * chip reading "Share" at 10.5px plus 18px of padding does not fit, and
 * measured at 390px it rendered as "Shar" with the label clipped. An icon fits
 * at every tier, which is the requirement, because the address cell is the only
 * cell that survives to the narrowest one.
 *
 * WHAT IT KEEPS FROM THAT FILE, because those were good calls and specificity
 * would otherwise silently drop them: the row-hover reveal, and the progress
 * cursor while a card is being made. Both are re-declared here at this file's
 * specificity rather than left to lose. If the owner prefers that file's chip,
 * the whole of this block is what to delete. */
html body .tr-tape .tr-row:hover .tr-share { opacity: 1; }
html body .tr-tape .tr-share[disabled] { cursor: progress; opacity: .6; }

/* THE HIDDEN WORD ON THE ROW BUTTON. Clipped, never display:none and never
   hidden: it is the button's accessible name in the plain case, and it is also
   what stops the share module's empty-button guard from overwriting the icon
   with the same word rendered visibly. See TR_SHARE_ICON in tools.js. */
html body .tr-tape .tr-share .tr-sh-t {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── THE ADDRESS CELL AT THE NARROWEST TIER ────────────────────────────────
 * At the base tier the board is three tracks and the address cell has to seat
 * five things: a rank chip, an identicon, the address, an explorer arrow and
 * the share control. Measured at 390px it cannot, so this block decides what
 * gives, in a container query so nothing here reaches a desktop.
 *
 * THE IDENTICON IS WHAT GOES, and it goes across a wider range than this block:
 * its rule sits directly above, at 719px, because the address was clipping well
 * past this tier. Measured, hiding it returns 19px of mark plus a 4px gap and
 * takes the address from "0x…" back to its full truncation.
 *
 * THE SHARE CONTROL DOES NOT GO. It is the reason this section exists in the
 * shape the owner asked for, and 390px is the width a board is most likely to
 * be read and posted from. It shrinks; it does not leave. */
/* THE IDENTICON GOES WHEREVER THE ADDRESS WOULD OTHERWISE TRUNCATE, which is a
   wider range than the base tier and is the same argument the base tier already
   makes. tape.js draws the mark on every address cell in the product and says
   why: "recognising the wallet does not depend on being able to leave for it".
   That is right where there is room for both. Where there is room for one, the
   six hex characters win: they are the value a reader can check on chain and
   paste into an explorer, and the identicon is a shortcut to a value that would
   no longer be on screen.
   719px AND NOT 559px, MEASURED. The mark and its gap are 23px, and across the
   560 tier the address was short by 35.8px at a 588.4px container and by 7.6px
   at 686px, with the clip gone by 717px. Widening the address track pays for
   most of that (see the tier's own comment) and this pays for the rest, so the
   mark is back the moment the track can seat the address beside it.
   display:none AND NOT visibility:hidden, because the cell is a flex row and a
   hidden item still holds its place. Scoped to .tr-tape: the live tape and the
   settled tape are untouched at every width. */
@container (max-width: 719px) {
  html body .tr-tape .tw-ic { display: none !important; }
}

@container (max-width: 559px) {
  html body .tr-tape .tr-idc { gap: 3px; }
  html body .tr-tape .tr-rk {
    min-width: 18px;
    /* 3px, not 4. Two-digit ranks are 7px wider than one-digit ones and the
       address is what pays for it: see the track comment above. */
    padding: 1px 3px;
    line-height: 1.2 !important;
  }
  html body .tr-tape .tr-share { width: 20px; height: 20px; }
  /* AND THE SEVEN PIXELS THAT WERE COSTING THE ADDRESS ITS LAST FOUR
     CHARACTERS. Measured before this rule: "0xe1dc…69b7" wants 86px at the 13px
     mono step and had 79px of box, so it ellipsized to "0xe1dc…69…" on every
     row. That is the exact regression the base-tier rebalance above was written
     to prevent, and it PREDATES .tr-nf: at the old 146.5px address track the
     text had 71px and lost more. The track gave 7.4px back; this gives the rest.

     THE SEVEN PIXELS COME FROM PADDING AND GAPS, NOT FROM TYPE OR FROM AN
     ELEMENT. Shrinking the address a step would have been the easy 7px and it
     is the wrong one: the hex is the value a reader checks on chain, and it is
     already the smallest thing in the row that anyone has to read character by
     character. Dropping the explorer arrow was the other candidate and is
     worse than it looks: the identicon above could go because it is a shortcut
     to a value that stays on screen, while the arrow is the only way OFF this
     page to the chain. So the address button gives up 3px of horizontal padding
     each side (its vertical padding, which is the hit target this row height
     allows, is untouched) and the two gaps give up 1px each.

     MEASURED AFTER: the address button's content box is 88px for the 86px the
     text wants, and the address renders whole on every row of the board. At the
     original 6px it was 79px and every row ellipsized. Assert this the way it
     was found, on the TEXT span's scrollWidth against its clientWidth: the cell
     around it reports nothing, because a right-aligned neighbour is what
     overflows the row and this one is not right-aligned at all. */
  html body .tr-tape .tr-who .tw-b { padding-left: 3px; padding-right: 3px; }
  html body .tr-tape .tr-who { gap: 4px; }
  /* THE VERTICAL BUDGET AT THIS TIER, SINCE .tr-nf NOW SHARES IT. The cell is a
     35px content box (44px row, less a 1px border and 4px of padding each side)
     and it holds two lines instead of one:

       .tr-idc   20.89px   the FLOOR, and not one this section may lower. It is
                           the address button (.tw-b, 16.89px of text on 2px of
                           padding each side), which is a hit target owned by
                           tape.js, with the 20px share control just under it.
                           The two rules above took the rank chip from 20.19 to
                           16.39 and the inherited line box from 22.5 to 18, and
                           neither moved this number: both were under the floor
                           already. They are kept because the chip reads better
                           small beside a line of type than tall beside one.
       .tr-nf      12.00   10px at 1.2, with no margin of its own.
                 -------
                  32.89px  in 35.00px.

     2.11px of slack, which survives a font fallback. Past that .tr-nf CLIPS
     rather
     than squashing into the address above it, because both children are
     `flex: none`: see the two-line-cell autopsy in tools.css for why a stack on
     this row must be made to fail the legible way. THE 44px ROW HEIGHT IS NOT
     THIS SECTION'S TO CHANGE. It is shared with the live tape and the settled
     tape, and a marker chip row already broke it once. */
  html body .tr-tape .tr-idc { line-height: 1.2; }
}

/* SOCIAL MARKERS. Several can apply at once, so they lay out as a row of small
   chips rather than one sentence. Muted by design: they qualify the role above
   them, and a marker that shouted would read as an endorsement of the account
   rather than a fact about it. */
/* ONE LINE, NEVER WRAPPED. Measured: an address carrying two markers (a
   custody rail AND a registered-maker listing) wrapped to a second chip row,
   which pushed the stack past the 44px row height and CLIPPED the role label
   above it top and bottom. The row height is shared with the live tape and the
   settled tape and is not this section's to change, so the markers yield
   instead: they stay on one line, overflow is hidden, and the full set is on
   the cell's title where nothing can clip it. */
html body .tr-tape .tr-mk {
  display: flex;
  flex-wrap: nowrap;
  gap: 4px;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
}
/* AND WHERE IT STILL DOES NOT FIT, IT ELLIPSIZES INSTEAD OF BEING AMPUTATED.
   The row is nowrap with overflow hidden, so before this the last chip was cut
   THROUGH ITS OWN BORDER, mid-glyph: at a 132px role track a two-chip row wants
   178.5 and rendered "Registerec" with no right-hand border at all, which reads
   as a rendering fault rather than as a truncation. Letting the last chip
   shrink turns the same overflow into an ellipsis inside a complete chip, which
   is a thing a reader recognises and can act on, and the full set is on the
   cell's title where nothing clips it.
   THE LAST CHIP ONLY. The earlier ones are 60 to 66px and are what says WHICH
   facts are here; the trailing one loses characters instead. With one chip it
   is also the last, which is what fixes the 900 tier, where "Registered maker"
   alone wanted 108.3px in a track that held 104.3 on 16 of the 80 rows. */
html body .tr-tape .tr-mk-i { flex: 0 0 auto; }
html body .tr-tape .tr-mk-i:last-child {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
html body .tr-tape .tr-mk-i {
  font-style: normal;
  font-size: 10px !important;
  line-height: 1.5;
  padding: 0 5px;
  border: 1px solid var(--line);
  border-radius: 3px;
  color: var(--ink3);
  white-space: nowrap;
}

/* ── THE FURNITURE CARRIES THE QUALIFIERS ──────────────────────────────────
 *
 * Three paragraphs used to stand above this board and they are gone at the
 * owner's word ("i don't need this text"). They are not coming back, in this
 * file or in any other. What they carried has to survive anyway, because the
 * section is now reached COLD: from a rail item, or from a link somebody
 * posted, by a reader who has read nothing above it.
 *
 * SO THE QUALIFIERS MOVED INTO THE FURNITURE. A unit line under a column
 * header, a sub-line under a figure in the strip, a line under an address.
 * That is not a smaller paragraph in a different place: a reader meets a unit
 * line while reading the column it qualifies, which is the one moment they are
 * certainly looking at it, and it costs no block of the scroll a phone reader
 * has to get past before the first row.
 *
 * TOOLTIPS ARE THE FLOOR, NEVER THE SOLUTION. Every header here also carries
 * its full hint on `title`, and that is worth keeping for the reader who goes
 * looking. It is worth nothing to the reader who does not, which is nearly all
 * of them, and none at all on a touch screen. Nothing load-bearing may live
 * only in a title attribute.
 *
 * NONE OF THESE IS A NEW TRACK, A NEW ROW, OR ANY CHANGE TO THE 44px ROW
 * HEIGHT, which is shared with the live tape and the settled tape and is not
 * this section's to change. */

/* THE UNIT LINE UNDER A COLUMN HEADER. Lower case against the header's upper
   case, so the two read as label and qualifier rather than as two labels.

   9px WITH !important, AND BOTH ARE REQUIRED. instrument.css:343 pins
   `body *:not(svg) { font-size: var(--t-sm) !important }`, so a plain 9px rule
   loses and this line renders at the body step, LARGER than the 8.5px header it
   is meant to sit under. Same manoeuvre .tr-role, .tr-mk and .tr-rk already
   make against that selector.

   IT IS THE ONE THING IN A HEADER ALLOWED TO WRAP. `.tw-head .tw-c` is nowrap
   with overflow:hidden, which is right for a label and wrong for a qualifier: a
   right-aligned .tw-c overflows to the LEFT, where text-overflow has no
   ellipsis to give and scrollWidth does not report it, so an over-long unit
   line would clip SILENTLY. Wrapping fails visibly and legibly instead, and the
   header is the one part of this board with no fixed height. Keep the strings
   short anyway: tools.js says why, next to them. */
html body .tr-tape .tr-sub {
  display: block;
  margin-top: 2px;
  max-width: 100%;
  font: 400 9px/1.25 var(--mono) !important;
  font-size: 9px !important;
  letter-spacing: .03em;
  text-transform: none;
  color: var(--ink3);
  font-style: normal;
  white-space: normal;
  overflow-wrap: anywhere;
}
/* The header cell is a column flex and .num right-aligns its items, so the unit
   line lands under the label on both sides of the board with no rule of its
   own. Only the text alignment inside a WRAPPED line needs saying. */
html body .tr-tape .tw-head .tw-c.num .tr-sub { text-align: right; }

/* AND THE ONE HEADER THAT WAS NOT OVER ITS OWN COLUMN. tools.css:1270 gives
   every header cell `align-items: center`, and .tw-c is a COLUMN flex, so on a
   header that is HORIZONTAL centring. Every other column here is .num and
   controls.css:1434 pins those to flex-end, and the address header escapes it
   because tools.css:1432 makes .c-taker a ROW flex where align-items is the
   vertical axis instead. Role is the only cell that is neither, so its label
   sat centred in the track while its values sat at the left edge: measured at a
   1600px viewport the gap was 85.6px, and it got worse rather than better when
   the track widened to hold the marker chips. Written at (0,4,2), which beats
   tools.css's (0,2,0) outright and needs no !important, and scoped so the live
   tape and the settled tape keep whatever they were doing. */
html body .tr-tape .tw-head .tw-c.tr-c-rol { align-items: flex-start; }

/* ── THE FLIP FIGURE ON THE ROW, AT THE ONE TIER THAT HAS NO FLIP COLUMN ────
 * Shown and hidden beside the .tr-c-flp hide-set far above, which is where the
 * decision is recorded. This is only what it looks like.
 *
 * "sign flips 23%", NOT "23%" and NOT "flip 23%". A bare figure under an
 * address is a number a cold reader cannot name, and this is the width where
 * there is no column header above it to name it. The wording matches the Flip
 * column's own unit line exactly, so a reader who meets the board on a phone
 * and again on a desktop is reading the same two words in both places.
 *
 * MEASURED: at 390px the address track is 155.8px and gives this line 144px of
 * box. The line wants 78.3px as it renders, and 90.3px at its widest possible
 * value ("sign flips 100%"). It fits with room to spare, which is why it lives
 * here and not under Net: the same phrase under the Net value would have had
 * 73px, so a row above 99% would have ellipsized its own uncertainty away, and
 * the rows that do that are precisely the ones the line exists for.
 *
 * IT IS ALSO THE ONLY PLACE THE SHAKY MARKING LANDS AT THIS WIDTH, so the two
 * states have to be told apart without the Flip column beside them: --ink2
 * upright for a figure worth reading, --ink3 italic at or above the threshold,
 * which reads as "discount this row" where red would read as "this address
 * lost". Declared at (0,4,2) so it beats the plain .tr-nf colour outright
 * rather than by source order. */
/* ── THE ADDRESS CELL IS THE ONE .tw-c THAT IS NOT A COLUMN ────────────────
   AND IT COST A RENDER TO FIND OUT. This file says in three places that .tw-c
   is a COLUMN flex whose cross axis is horizontal, and for seven of these eight
   cells that is true. The address cell is not one of them: tools.js gives it
   `c-taker` so it inherits the live tape's identicon-and-address treatment, and
   tools.css pins `.c-taker, .c-maker { flex-direction: row; align-items:
   center }`. A ROW.

   MEASURED, WITH .tr-nf ADDED AND THIS RULE MISSING, AT 390px: the cell laid
   its two children out SIDE BY SIDE, 227px of content inside a 154px box, so it
   overflowed 20px off its own LEFT edge and took the rank chip and the first
   six characters of the address with it. The row read "…69… ↗ sign flips 0%",
   which is worse than the defect it was fixing: it hid the address as well.
   There is no ellipsis on that edge and scrollWidth on the cell is the only
   thing that reports it, which is why the check for this asserts cell
   scrollWidth against clientWidth and not just the body's.

   `align-items: stretch` because the cross axis is now horizontal and both
   children have to take the full track. Vertical centring comes from the
   existing justify-content:center !important two blocks up, which is the axis
   that rule was always aiming at. This rule is written at (0,3,2), so it beats
   `.c-taker` at (0,1,0) outright and not by load order.

   IT IS DELIBERATELY NOT INSIDE A CONTAINER QUERY. At every tier above the base
   the cell has one child and column and row render identically, so scoping it
   to 559px would buy nothing and leave two layouts to reason about instead of
   one. `flex: none` on both children is the guard the tape's own arithmetic
   asks for (tools.css, the two-line-cell autopsy): a stack that outgrows its
   35px content box must CLIP against the cell's overflow:hidden rather than
   squash its two lines into each other's glyphs. */
html body .tr-tape .tr-c-adr {
  flex-direction: column;
  align-items: stretch;
  /* AND THE GAP HAS TO GO WITH THE DIRECTION, which is the second half of the
     same trap. That same tools.css:1432 rule gives .c-taker `gap: 7px` for the
     identicon-to-address spacing it was written for; turned on its side it
     becomes a 7px ROW gap between .tr-idc and .tr-nf. Measured: 20.9 + 7 + 12
     = 39.9px of stack inside a 35px content box, so the cell reported
     scrollHeight 44 against clientHeight 43 and clipped a pixel off the line
     it had just been given. The gap this cell wants is .tr-idc's own, which is
     declared on .tr-idc and is unaffected. Measured after: 20.89 + 12 = 32.89
     in a 35px box.

     !important IS REQUIRED AND row-gap IS ALL IT TOUCHES. tools.css:1432 is not
     the last word on this: controls.css:528 pins `body .c-taker { gap: 5px
     !important }` and controls.css:975 pins `html body .c-taker { gap: 4px
     !important }`, the second at (0,3,2), which is this rule's own specificity.
     Nothing but an !important beats it, and the same manoeuvre is already made
     twice in this file against controls.css:1433 and instrument.css:343. Only
     the ROW gap is overridden: the column gap is what those rules were written
     for and there are no horizontal siblings here for it to act on, so taking
     it as well would be reaching past the defect. */
  gap: 0;
  row-gap: 0 !important;
}
html body .tr-tape .tr-idc,
html body .tr-tape .tr-nf { flex: none; }
html body .tr-tape .tr-nf {
  width: 100%;
  /* NO MARGIN. Every pixel here is spent against a 35px content box that the
     line above it already takes 20.89 of, and the separation is being done by
     type instead: 10px against the address's 13px, --ink2 against --ink,
     upright against a link. A margin would buy 1px of air for 1px of the slack
     that keeps this stack from clipping. See the budget in the base-tier
     container query above. */
  margin-top: 0;
  font: 400 10px/1.2 var(--mono) !important;
  font-size: 10px !important;
  letter-spacing: 0;
  color: var(--ink2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* font-style CARRIES AN !important AND IT IS NOT DECORATION. The `font`
   shorthand above is itself !important, and a shorthand sets every longhand it
   covers: font-style included, to `normal`, at that same weight. Measured
   without this: a 43%-flip row on a phone rendered UPRIGHT and only a shade
   greyer than a 0% row, so the one signal that says "discount this row" was
   carrying half its meaning at the width where it is the only signal there is.
   The Flip column next door needs no !important for the same effect because
   the span it marks has no shorthand of its own. */
html body .tr-tape .tr-nf.tr-shaky {
  color: var(--ink3);
  font-style: italic !important;
}

/* ── THE STRIP'S SUB-LINE ───────────────────────────────────────────────────
 * A figure and an upper-case label can state a fact. They cannot state the one
 * thing about that fact a reader would otherwise get WRONG, and on three of
 * these six items that is the whole point of the item:
 *
 *   legs to qualify   an address under it is ABSENT from this board, not a zero
 *                     row on it. House rule 1, on the scale of a whole address.
 *   rows flip sign    at the threshold the rows themselves are muted at.
 *   venues            why the other ten cannot be scored, in the endpoint's own
 *                     words (d.coverage_note), never retyped here.
 *
 * Sentence case and no letter-spacing, so it cannot be mistaken for a second
 * label. max-width in ch rather than px: it is a measure, and it has to hold
 * whatever the endpoint's note grows into. */
html body .tr-stats .tr-st-w {
  display: block;
  margin-top: 4px;
  max-width: 34ch;
  /* 10px, and the step down is the whole reason this can exist at all. At 390px
     the strip is what a reader scrolls past before the first row, and three
     sub-lines at the 11px label step cost 138px of it. At 10px/1.35 they cost
     92px, which is less than the heading gave back by dropping to four words.
     Below 10px it stops being readable, so the strings were shortened instead
     of the type: see tools.js, where they are written. */
  font: 400 10px/1.35 var(--mono) !important;
  font-size: 10px !important;
  font-style: normal;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink3);
}
/* An item carrying a sub-line is a measure, not a chip, so it is allowed to
   take a line of the strip to itself and to shrink to that measure rather than
   forcing the strip wider than the board. The items without one keep sizing to
   their content. */
html body .tr-stats li:has(.tr-st-w) {
  flex: 1 1 24ch;
  max-width: 34ch;
}
