/* today.css: TODAY. One sentence, one number, and the window that made them.
 * ===========================================================================
 * THIS SHEET IMPORTS NOTHING AND CONTAINS NO SECOND DESIGN SYSTEM, which is
 * the whole reason it needs no firewall. Everything below is built out of the
 * app's OWN tokens (--ink/--ink2/--ink3, --line, --line2, --panel, --accent,
 * --neg, --bg, --mono, --focus, --hover-wash, --t-xs/--t-sm/--t-md/--t-lg/
 * --t-hero, --tr-label), so there is nothing here to contain and nothing that
 * can leak. NO @keyframes are declared: keyframe names are document-global and
 * a class prefix cannot scope them.
 *
 * ── FIVE TOKENS, FOUR RENDERED STEPS, ONE ROLE EACH ───────────────────────
 * The sheet this replaces spent SEVENTEEN sizes: 60, 48, 44, 40, 36, 30, 26,
 * 24, 22, 20, 19, 17, 15, 14, 13, 12, 11 and 10px, most of them invented here
 * and several of them describing markup today.js had already stopped
 * rendering. Measured on the rendered PNG, the section had one 40px asset, one
 * 48px figure, one 24px card figure and five different caption steps, which is
 * a hierarchy nobody can hold. It now spends only these five tokens:
 *
 *   --t-hero  THE ONE FIGURE the window answers
 *   --t-lg    THE ONE SENTENCE, and nothing else
 *   --t-md    every figure in a breakdown row, every provenance value, the
 *             window readout, and the name in a breakdown row
 *   --t-sm    prose that is not the sentence
 *   --t-xs    every label and every micro caption
 *
 * AND FIVE TOKENS ARE FOUR STEPS ON THE LIVE THEME, WHICH IS MEASURED AND NOT
 * ASSUMED. Read off the rendered page rather than off the declaration I first
 * grepped, this theme resolves --t-xs 11px, --t-sm 15px, --t-md 15px, --t-lg
 * 30px and --t-hero 76px: --t-sm AND --t-md ARE THE SAME PIXEL SIZE HERE. So
 * the row name and the row figure are the same size by construction, and the
 * hierarchy between them is bought with INK and WEIGHT instead — which is the
 * move payoff.css makes on .pf-set for the same reason. A comment claiming a
 * five step ladder would be describing a page that does not exist. (I first
 * wrote 10/12/14/26 here from a :root block in instrument.css that is NOT the
 * palette this app serves; the numbers above come from getComputedStyle on a
 * probe element in the live document.)
 *
 * The display figure is drawn exactly the way payoff.css draws .pf-live-n and
 * detail.css draws .vp-num-n: --t-hero, 0.92 leading so a 76px number does not
 * reserve 100px of line box, and -0.045em so the digits sit as one shape. The
 * three biggest numbers on the site are now drawn the same way.
 *
 * ── WHAT !important IS AND IS NOT FOR ─────────────────────────────────────
 * instrument.css:343 pins font-family, font-size, font-weight, letter-spacing,
 * border-radius and box-shadow on `body *:not(svg):not(svg *)` with
 * !important, and an important declaration beats a normal one at ANY
 * specificity. It does NOT pin colour, border, padding, margin, display, grid
 * or white-space, which is nearly everything below. The rules that do carry it
 * are claiming a type ROLE, and every size they claim is one the scale already
 * defines. NO NEW SIZE IS INVENTED HERE.
 *
 * THREE CONSEQUENCES OF THAT NORMALISER ARE LOAD BEARING BELOW:
 *   box-shadow is pinned to `none !important`, so the selected window step
 *   cannot be marked with an inset shadow. Nothing here uses one; the marks
 *   are ink, weight and a rule.
 *   border-radius is pinned to 0, and the old sheet asked for `border-radius:
 *   8px` on the cards and for 999px pills on three controls WITHOUT
 *   !important, so every one of them rendered square. Confirmed on the
 *   baseline PNG rather than inferred from the selector. Nothing below asks
 *   for a radius it will not get: the pin does NOT reach pseudo-elements
 *   (`body *` matches elements, never ::-webkit-slider-thumb), so the rail's
 *   thumb is round and is the only round thing in the section.
 *   font-weight is pinned to 400, so every bold below must restate it.
 *
 * ── --accent-ink IS NOT THE INK FOR AN ACCENT FILL ────────────────────────
 * --accent-ink resolves to the SAME value as --accent. Measured in the live
 * document, both are #ff7a1a here. Setting --accent-ink as the colour on an
 * accent background prints the accent on the accent and the element renders as
 * a blank blob. Anything sitting ON the accent takes --bg. Nothing below sits
 * on an accent fill: the thumb is the only filled accent object and it carries
 * no text.
 *
 * ── --fill-1 AND --fill-2 ARE `transparent`, AND --s1 IS NOT ─────────────
 * MEASURED IN THE LIVE DOCUMENT, not read off a :root block: this theme
 * resolves --fill-1 and --fill-2 to `transparent`, so a hover painted with
 * either does not exist and nothing below uses them. --s1 (#17130f) and --s2
 * (#201b16) DO carry a value here, which corrects a claim I made in this
 * comment on the first pass after grepping a palette the app does not serve.
 * They are still not used below, for a different reason: division here is done
 * the way the app does it elsewhere and the way payoff.css draws .pf-b3 — a
 * 1px grid gap over a --line ground with the cells on --bg. That needs no fill
 * token, no radius and no shadow, which is three pins it cannot lose to.
 * --gold-* is a retired palette and appears nowhere below.
 *
 * ── THE SECTION SPENDS ONE ACCENT AND ONE WARNING, AND NOTHING ELSE ───────
 *   --accent  THE LIVE THING YOU ARE MOVING, and only that: the rail thumb,
 *             the filled half of its track, the current tick, and the leading
 *             bar in each breakdown. Same rule the Payoffs section follows.
 *             It is NOT spent on the share button: sharing is not the claim
 *             this section makes, and a filled orange pill was the loudest
 *             object on the baseline render while the coverage line that
 *             qualifies the number sat 800px below it in 11px grey.
 *   --neg     A CLAIM WE CANNOT STAND BEHIND, and only that: the Window cell
 *             when the request cap has eaten the window it is named after.
 *   --pos     NOT USED. No direction is rendered on this surface.
 *   ink       everything else, in three steps.
 */

.td { display: flex; flex-direction: column; gap: 26px; }

html body .td-status { color: var(--ink2); padding: 44px 0; text-align: center; line-height: 1.6; }
html body .td-status--bad { color: var(--neg); }

/* THE MICRO LABEL, one definition for the whole sheet. It was written out five
   times with three different letter-spacings. */
html body .td-lbl {
  margin: 0;
  color: var(--ink3);
  text-transform: uppercase;
  font-size: var(--t-xs) !important;
  letter-spacing: var(--tr-label) !important;
}

/* ══ 1. THE KPI: ONE SENTENCE, ONE NUMBER ══════════════════════════════════
 * A stranger arriving from a posted link reads this block and nothing else, so
 * the block has to be a complete claim on its own. The sentence carries the
 * subject, the superlative, the window and the population; the figure carries
 * the quantity; the line under the figure carries the DENOMINATOR, because a
 * share is a ratio and a ratio without its denominator is a claim.
 *
 * The sentence is on the LEFT and reads first, which is the inversion that
 * matters: the baseline render led with a 40px "ETH" and a 48px "$269.1K" and
 * put the only words on the screen in 13px underneath them. A number is not a
 * headline until something has said what it is a number OF.
 * ─────────────────────────────────────────────────────────────────────────── */

.td-kpi {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 20px;
  align-items: end;
}
@media (min-width: 900px) {
  .td-kpi { grid-template-columns: minmax(0, 1fr) auto; gap: 48px; }
  .td-fig { text-align: right; }
}

/* THE ONE SENTENCE ON THE SECTION, and the only thing at --t-lg. 46ch keeps it
   to two lines at this size on a desk, which is the length a sentence can be
   and still be repeated from memory. */
html body .td-say {
  margin: 0;
  max-width: 46ch;
  color: var(--ink);
  font-size: var(--t-lg) !important;
  font-weight: 600 !important;
  line-height: 1.18;
  letter-spacing: -0.015em !important;
  text-wrap: balance;
}

.td-fig { min-width: 0; }

/* THE FIGURE. The one thing that has to survive a timeline screenshot. */
html body .td-n {
  margin: 0;
  font-family: var(--mono) !important;
  font-size: var(--t-hero, clamp(48px, 6.6vw, 76px)) !important;
  font-weight: 600 !important;
  line-height: 0.92;
  letter-spacing: -0.045em !important;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
/* AN EMPTY WINDOW PRINTS THE WORD "none", NOT "$0". A zero is a measurement
   and this is an absence, and the two must not be drawn the same. It is set
   lighter and tracked OPEN so it can never be scanned as a quantity that
   happens to be spelled out. Same device .pf-b-none uses. */
html body .td-n--none {
  color: var(--ink3);
  font-weight: 400 !important;
  letter-spacing: 0.04em !important;
}
/* THE DENOMINATOR RIDES WITH THE FIGURE. Not in a footer, not behind a
   disclosure: in the same frame, so a screenshot of the number is a screenshot
   of what it is a share of. */
html body .td-nu {
  margin: 9px 0 0;
  color: var(--ink2);
  font-size: var(--t-sm) !important;
  line-height: 1.5;
  max-width: 38ch;
  text-wrap: pretty;
}
@media (min-width: 900px) {
  .td-nu { margin-left: auto; }
}

/* ══ 2. THE PROVENANCE STRIP ═══════════════════════════════════════════════
 * Four cells, and every one is a population statement: the window, our
 * coverage, the count, the clock. It sits directly under the KPI and above the
 * control, because the failure this section is most exposed to is a big number
 * and its coverage living in different halves of a scroll.
 *
 * Drawn as a 1px grid gap over a --line ground with the cells on --bg. No
 * radius to lose to the pin, no shadow to lose to the pin, no fill token that
 * resolves to transparent.
 * ─────────────────────────────────────────────────────────────────────────── */

.td-prov {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
@media (min-width: 760px) {
  .td-prov { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.td-p {
  background: var(--bg);
  padding: 12px 15px 14px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-width: 0;
}
html body .td-p-v {
  margin: 0;
  color: var(--ink);
  font-family: var(--mono) !important;
  font-size: var(--t-md) !important;
  font-weight: 600 !important;
  line-height: 1.25;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 8px;
}
/* The second count, which appears only when the two populations diverge. */
/* THE WINDOW CELL IS THE ONE VALUE ON THIS STRIP THAT IS WORDS RATHER THAN A
   QUANTITY, and mono tabular figures are a register for quantities. "last 24
   hours" set in the figure face was the weakest thing on the rendered strip
   and it also ran wide enough on a phone to push its own method mark onto a
   second line. It keeps the size, the weight and the ink; it drops the face. */
html body .td-prov .td-p:first-child .td-p-v {
  font-family: inherit !important;
  letter-spacing: normal !important;
}
html body .td-p-v i {
  font-style: normal;
  color: var(--ink3);
  font-weight: 400 !important;
  font-size: var(--t-xs) !important;
  letter-spacing: var(--tr-label) !important;
}
/* A CLAIM WE CANNOT STAND BEHIND. The one place --neg is spent here: the cap
   ate the window this cell is named after, so the label above it is no longer
   true of the figures beside it. It is not a styling flourish, it is the
   section refusing its own headline. */
.td-p--bad { background: var(--bg); }
html body .td-p--bad .td-p-v { color: var(--neg); }
.td-p--bad { outline: 1px solid var(--neg); outline-offset: -1px; }

/* ══ 3. THE WINDOW, AS A CONTROL ═══════════════════════════════════════════
 * The linked views recompute live because every step is a re-filter of fills
 * already in memory, so a drag costs no request and there is nothing to flash.
 *
 * THE READOUT RESTATES THE WINDOW IN WORDS ON EVERY MOVE. The whole risk of a
 * window control is a number read against the wrong window, and a tick strip
 * alone ("1h 3h 6h 12h 24h") leaves the reader to remember which one is lit.
 * The sentence, the figure's own subline and this readout all say it, so the
 * number and its window cannot be separated by a screenshot.
 * ─────────────────────────────────────────────────────────────────────────── */

.td-winbox { display: flex; flex-direction: column; gap: 10px; }
.td-winhd {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
html body .td-win-l {
  margin: 0;
  color: var(--ink2);
  font-family: var(--mono) !important;
  font-size: var(--t-md) !important;
  font-variant-numeric: tabular-nums;
}

/* THE RAIL. touch-action IS ON THE INPUT, which is the element that receives
   the pointer, and not on .td-winbox around it. On a wrapper the browser
   claims the gesture for a page scroll and the drag never receives an event,
   which reads as a broken control and is really a control that was never
   given the pointer. */
html body .td-win {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 100%;
  height: 26px;
  margin: 0;
  padding: 0;
  background: transparent;
  cursor: ew-resize;
  touch-action: none;
}
/* THE TRACK IS SPLIT rather than flat, because the filled share is what tells
   a reader the rail is a control at all: a flat --line2 hairline read as no
   rail at all on the first render. It is TWO GREYS AND NOT THE ACCENT — the
   accent is already spent on the thumb and on the leading bar of each
   breakdown, and a third full-width accent line would be a fourth thing on
   the screen claiming to be the live one.
   Custom properties cascade into pseudo-elements from the element they are
   set on, so the single --td-fill that today.js writes on the input drives
   both halves, and it is rewritten on every paint rather than only on input,
   so the track cannot drift from the thumb after a poll. */
.td-win::-webkit-slider-runnable-track {
  height: 2px;
  border: 0;
  background: linear-gradient(
    to right,
    var(--ink3) 0%,
    var(--ink3) var(--td-fill, 100%),
    var(--line2) var(--td-fill, 100%),
    var(--line2) 100%
  );
}
.td-win::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--bg);
  margin-top: -9px;
  cursor: grab;
}
.td-win::-moz-range-track { height: 2px; background: var(--line2); border: 0; }
.td-win::-moz-range-progress { height: 2px; background: var(--ink3); }
.td-win::-moz-range-thumb {
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--accent); border: 2px solid var(--bg); cursor: grab;
}
.td-win:focus { outline: none; }
.td-win:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* THE TICKS. Labels, not decoration: the step you are on is named, so the
   control can be read without moving it. The current one takes the accent
   because it IS the live thing, which is the only job the accent has here. */
html body .td-ticks {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: space-between;
  color: var(--ink3);
  font-family: var(--mono) !important;
  font-size: var(--t-xs) !important;
  letter-spacing: var(--tr-label) !important;
}
html body .td-ticks li[aria-current="true"] { color: var(--accent); font-weight: 600 !important; }

/* ══ 4. THE BREAKDOWNS ═════════════════════════════════════════════════════
 * Two columns, and they are DIFFERENT QUESTIONS, so they are two headed lists
 * rather than nine identical cards in one wall. On the baseline render the six
 * asset cards and the three venue cards were drawn identically and read as one
 * grid of nine things.
 *
 * NO BOX PER ROW. The rows are separated by a hairline and by space, which is
 * the house rule; a border around each would be a second frame arguing with
 * the strip above.
 * ─────────────────────────────────────────────────────────────────────────── */

.td-brk {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 30px;
}
@media (min-width: 900px) {
  .td-brk { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); gap: 44px; align-items: start; }
}
.td-col { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.td-colhd {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
}
/* THE UNIT, STATED ONCE. Every card used to carry "of the day" itself, nine
   times on one screen. It is a column heading, so it is set like one: lower
   case against the label's caps, so the eye reads one as the label and this as
   the reading instruction rather than as a second label. */
html body .td-colu {
  margin: 0;
  color: var(--ink3);
  font-size: var(--t-xs) !important;
}

html body .td-rows { list-style: none; margin: 0; padding: 0; }

/* ── one row ────────────────────────────────────────────────────────────────
   THE SHARE IS A GRID COLUMN, NOT AN ABSOLUTE OVERLAY. It used to be pinned to
   the card's corner and revealed on :hover, with the rank digit hidden on the
   same trigger. A hover rule never fires on a touch screen, so a
   `@media (hover:none)` block forced the button visible and it landed straight
   on top of the rank: measured on the 390 baseline PNG, every card in the
   grid read "Share2", "Share3", "Share4". A column cannot collide with the
   thing beside it, at any width, on any input. */
.td-r {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr) auto auto;
  grid-template-areas:
    "n a   a  v"
    ". bar s  b";
  align-items: center;
  gap: 5px 10px;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
}
@media (min-width: 620px) {
  .td-r {
    grid-template-columns: 20px minmax(76px, auto) minmax(56px, 1fr) auto 84px 62px;
    grid-template-areas: "n a bar v s b";
    gap: 12px;
    padding: 9px 0;
  }
}

/* The rank orders the list and is never the point of a row. */
html body .td-r-n {
  grid-area: n;
  color: var(--ink3);
  font-family: var(--mono) !important;
  font-size: var(--t-xs) !important;
  font-variant-numeric: tabular-nums;
}
.td-r-a {
  grid-area: a;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
}
/* --t-md, THE SAME STEP AS THE FIGURE TWO COLUMNS OVER, because --t-sm and
   --t-md resolve to the same 15px on this theme and pretending otherwise would
   describe a hierarchy the render does not have. The subject reads first
   because it is on the left and in full ink; the figure reads as the figure
   because it is mono, tabular and tracked tight. */
html body .td-r-a b {
  color: var(--ink);
  font-size: var(--t-md) !important;
  font-weight: 600 !important;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.td-mk { flex: none; }

/* THE BAR IS THE SHAPE, and it is the quietest thing in the row: the exact
   share is written two columns over, so the bar is not carrying a number, it
   is carrying the GAP. Only the leader is inked with the accent — if every bar
   were accent the ranking would carry no information. */
.td-r-bar {
  grid-area: bar;
  display: block;
  height: 4px;
  background: var(--line);
  min-width: 40px;
}
.td-r-bar i { display: block; height: 100%; background: var(--ink3); min-width: 2px; }
/* min-width, NOT a percentage floor in the renderer. A floor applied to the
   VALUE made every asset under 2% of the leader draw the same bar: measured
   2026-08-19, XAUT $5.4K, ZEC $1.8K and META $1.5K were pixel-identical and
   3.6x apart. 2px is the smallest mark that still reads as a mark and it
   applies AFTER the true width, so a bar can be short but never wrong. */
.td-r--lead .td-r-bar i { background: var(--accent); }

html body .td-r-v {
  grid-area: v;
  text-align: right;
  color: var(--ink);
  font-family: var(--mono) !important;
  font-size: var(--t-md) !important;
  font-weight: 600 !important;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em !important;
}
html body .td-r-s {
  grid-area: s;
  color: var(--ink2);
  font-family: var(--mono) !important;
  font-size: var(--t-xs) !important;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
@media (min-width: 620px) { .td-r-s { text-align: right; } }
/* The fill count, set back one step and separated by a middot rather than by a
   word: the column heading above already says "share of window, fills". */
html body .td-r-s em { font-style: normal; color: var(--ink3); }
html body .td-r-s em::before { content: " \00b7 "; color: var(--line2); }

/* THE SHARE BUTTON IS AN OUTLINE, NOT AN ACCENT FILL. On the baseline render
   the only filled accent object on the section was "Share this", which made
   posting the loudest thing on a screen whose claim is measurement. The accent
   is spent on the live control and on the leading bar; a share is an action
   and it is drawn as one.
   IT IS ALWAYS VISIBLE. A control that only exists on hover does not exist on
   a touch screen, and hiding it was what forced the collision above. */
html body .td-r-b {
  grid-area: b;
  justify-self: start;
  border: 1px solid var(--line2);
  background: transparent;
  color: var(--ink3);
  padding: 4px 11px;
  font-size: var(--t-xs) !important;
  letter-spacing: var(--tr-label) !important;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 120ms ease-out, border-color 120ms ease-out;
}
@media (min-width: 620px) { .td-r-b { justify-self: end; } }
/* --fill-1 and --fill-2 are BOTH `transparent` on every theme in this app, so
   a hover painted with them does not exist. The neutral ink wash is the token
   that actually carries one. */
.td-r-b:hover { color: var(--ink); border-color: var(--ink3); background: var(--hover-wash); }
.td-r-b:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
/* The placeholder that holds the column open at every window below 24h, so the
   rows do not reflow as the reader drags. It renders nothing and announces
   nothing.
   `html body` IS LOAD BEARING ON THIS RULE AND IT WAS MISSING. Written as a
   bare `.td-r-b--off`, it is (0,1,0) against the base button's (0,1,2), so the
   base rule's `border: 1px solid var(--line2)` won and every row below 24h
   rendered an EMPTY OUTLINED BOX in the share column. Caught on the 6h PNG,
   not in the source: the rule looked correct and lost a cascade. */
html body .td-r-b--off { border: 0; background: none; padding: 0; }

/* NOTHING REACHED US IS A SENTENCE, NOT AN EMPTY LIST. An empty <ol> says the
   surface is broken; this says the market was quiet where we can see. */
html body .td-r--none {
  display: block;
  color: var(--ink3);
  font-size: var(--t-sm) !important;
  line-height: 1.55;
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
}

/* THE TAIL AND THE SILENCES. Both are the same kind of statement — something
   real that is not in the list above — so they are drawn the same way, under
   their own list. The tail was sliced off in silence; a venue we read that
   printed nothing left no trace at all. */
html body .td-tail {
  margin: 10px 0 0;
  color: var(--ink3);
  font-size: var(--t-xs) !important;
  line-height: 1.6;
  max-width: 54ch;
}

/* ══ 5. THE METHOD ═════════════════════════════════════════════════════════
 * .td-foot IS GONE, AND SO IS ITS RULE. The paragraph restated the fill count,
 * the window, the venue names and the coverage ratio, all four of which are
 * provenance cells or venue rows higher up the same screen. What it carried
 * alone — premium is a lower bound — is now a visible slot on the Venues read
 * cell, so the fact survives a screenshot instead of a hover.
 * The closing hairline went with it and is not missed: the section already
 * ends on two hairline-ruled lists, and a third rule under them was a frame
 * around a frame. (The lesson the deleted rule recorded is kept here because
 * it is general: a max-width belongs to the WORDS, never to the element
 * carrying a border, or the border stops where the measure stops.)
 * ─────────────────────────────────────────────────────────────────────────── */

/* AN EMPTY TAIL TAKES NO ROOM. td-silent now renders nothing when every venue
   we read printed, and a <p> with a 10px top margin and no words is a gap the
   reader has to account for. :empty is exact here — the element is written by
   innerHTML, so it holds no whitespace text node when the string is "". */
html body .td-tail:empty { display: none; margin: 0; }

/* ── narrow ────────────────────────────────────────────────────────────────
   The KPI stacks, the sentence keeps its size (it is the headline and shrinking
   it would make the figure the headline again), and the provenance strip goes
   two by two rather than four across, where each cell would be 87px and the
   coverage ratio would break over two lines. */
@media (max-width: 620px) {
  .td { gap: 22px; }
  .td-brk { gap: 26px; }
  .td-say { max-width: none; }
  .td-nu { max-width: none; }
  /* A finger is 44px and this rail is the only drag target on the section. */
  html body .td-win { height: 34px; }
  .td-win::-webkit-slider-thumb { width: 26px; height: 26px; margin-top: -12px; }
  .td-win::-moz-range-thumb { width: 22px; height: 22px; }
}
