/* =====================================================================
   Crosslink Dashboard — Zcash design system

   Light is the default: paper page, white panels, gold at 700 for text
   contrast. Dark is the [data-theme="dark"] variant. The verdict band
   stays deep space in BOTH themes — the design system's anchor pattern.

   Type is self-hosted only: Space Grotesk for display, Plex Sans and
   Plex Mono for body and numerals, nothing below 11px.
   Panels are square — one hairline border, no radius, no soft shadow;
   bands of panels use 1px gaps over the line colour so dividers read as
   ruled lines. Radii exist only on chips, pills and buttons.

   Caveats live behind `i` buttons that open click-popovers — reachable
   on touch, out of the way until asked for.

   Conventions: no rule sets a raw font-size (use a --fs-* step) and no
   rule sets a raw gap/padding (use a --sp-* step).
   ===================================================================== */

@font-face {
  font-family: "Plex Sans";
  src: url("/fonts/plex-sans-var-400-600.woff2") format("woff2-variations");
  font-weight: 400 700;    /* 700 renders from the 600 master — closest weight */
  font-display: swap;
}
@font-face {
  font-family: "Space Grotesk";
  src: url("/fonts/SpaceGrotesk-500.ttf") format("truetype");
  font-weight: 400 500; font-display: swap;
}
@font-face {
  font-family: "Space Grotesk";
  src: url("/fonts/SpaceGrotesk-700.ttf") format("truetype");
  font-weight: 600 800; font-display: swap;
}
@font-face {
  font-family: "Plex Mono";
  src: url("/fonts/plex-mono-400.woff2") format("woff2");
  font-weight: 400; font-display: swap;
}
@font-face {
  font-family: "Plex Mono";
  src: url("/fonts/plex-mono-500.woff2") format("woff2");
  font-weight: 500; font-display: swap;
}
@font-face {
  font-family: "Plex Mono";
  src: url("/fonts/plex-mono-600.woff2") format("woff2");
  font-weight: 600; font-display: swap;
}

:root {
  /* ---- brand ramps ------------------------------------------------- */
  --gold-100:#FEF9E9; --gold-300:#F8CE5E; --gold-500:#F4B728;
  --gold-700:#A87705;   /* borders only — 3.9:1, above the 3:1 non-text floor */
  --gold-800:#7A5602; --gold-900:#5E4201;
  --sp-050:#F6FAFC; --sp-100:#D7E3EB; --sp-200:#AFC3D1; --sp-300:#87A2B4;
  --sp-400:#5F8196; --sp-500:#3F6177; --sp-600:#2B4A5E; --sp-700:#1C3447;
  --sp-t2:#33556B;   /* 7.9:1 on white — secondary prose */
  --sp-t3:#42647A;   /* v11: 4.8:1 on the sunken panel, 5.2:1 on the page, 6.3:1 on white — dim text.
                        v10 moved it two values darker from #4E7288, which
                        was audited against WHITE only and measured 4.43:1
                        on the sunken panel. The rule is the surface the
                        text is ON, so audit every ground a role lands on. */
  --sp-b3:#5F8196;   /* v11: 3.2:1 on the sunken track it sits in — the lightest a bar may be */
  --sp-900:#0B1828; --sp-950:#060F1B;
  --cy:#04FDCF; --teal:#00809E;

  /* ---- LIGHT — the default ----------------------------------------- */
  color-scheme: light;
  --bg:#E4EBF1;            /* v11: was #F4F8FB — 1.05:1 against a white panel, so the page had no structure */
  --bg-raised:#FFFFFF;     /* the one true white: panels only */
  --bg-sunken:#D9E3EB;     /* was #E9EFF4 — tracks, meters, wells */
  --bg-inset:#EFF3F7;      /* was #F4F8FB — hover, folds, strips inside a panel */
  --line:rgba(11,24,40,.22);        /* was .15 — a hairline that reads on both grounds */
  --line-strong:rgba(11,24,40,.40); /* was .26 */
  --line-signal:rgba(122,86,2,.60); /* was .42 */
  --focus:var(--gold-700);          /* v11: the ring was --signal at 1.5:1 on the page; gold-700 is 3.3:1 */
  --fg:var(--sp-900);
  --fg-2:var(--sp-t2);
  --fg-3:var(--sp-t3);            /* 4.2:1 -> 5.1:1 */
  --signal:var(--gold-500);
  --signal-text:var(--gold-800);  /* 3.96:1 -> 6.65:1 — eyebrows AND links */
  --on-signal:var(--sp-900);
  --signal-bg:var(--gold-100);
  --live:#0A6B4A;                 /* 5.34:1 -> 6.53:1 */
  --live-bg:rgba(10,107,74,.10);
  --live-line:rgba(10,107,74,.50);
  --warn:#A83B12;                 /* 4.93:1 -> 6.37:1 */
  --warn-bg:rgba(168,59,18,.10);
  --warn-line:rgba(168,59,18,.55);
  --danger:#B3261E;
  --bar-1:var(--sp-t2); --bar-2:var(--sp-t3); --bar-3:var(--sp-b3);
  --tip-shadow:0 18px 40px -18px rgba(11,24,40,.34);
  /* identicon glyph palette — four brand colours, themed */
  --ic-1:var(--gold-800); --ic-2:#00657D; --ic-3:var(--sp-t2); --ic-4:#0A6B4A;

  /* ---- type: self-hosted OFL faces only -----------------------------
     v9 led these stacks with the PLATFORM faces, on a real legibility
     finding: at 15px in a dense expert list, x-height decides more than the
     size does. v10 keeps the finding and reverses the order, for a licensing
     reason — naming "Segoe UI Variable Text" and "Cascadia Mono" asks for
     faces this project has no licence to host, so they render on the machines
     that already own them and nowhere else. Every face named here is now
     open-licensed and self-hosted, and the stacks LEAD with the shipped file:
     the first choice is always present, so prose renders identically on every
     machine — the one thing v9 listed as its accepted cost — Plex Sans carries
     the x-height v9 was asking for, and the tails are GENERIC keywords rather
     than named proprietary faces. Still no third-party request either way.

     The families are "Plex Sans" and "Plex Mono", matching the @font-face
     declarations above. "IBM Plex Sans" declares nothing here and would fall
     straight through to the generic. */
  --display: "Space Grotesk", "Plex Sans", system-ui, sans-serif;
  --sans:    "Plex Sans", system-ui, sans-serif;
  --mono:    "Plex Mono", ui-monospace, monospace;

  /* ONE TYPE SCALE — seven steps, and nothing else. Ratified as a system
     decision by design v8 (field feedback #5, ask A): the census of the v6
     build found sixteen sizes on this page and nine inside the verdict band
     alone. This block is the only place a size is written down; every older
     token name below resolves to one of the seven, so a rule never invents an
     eighth, and no rule anywhere sets a raw font-size.

       11 · 12 · 13 · 15 · 19 · 34 · 88
     Three text steps (13 · 15 · 19) over two floor steps (11 · 12) and two
     display steps. 12 is the EYEBROW step and 11 is the floor under it —
     review #9 (docs/DESIGN-REVIEW-9-text-in-dashboards.md) asked for 12 on
     anything a screen reader treats as a label, and an eyebrow is one, more
     so since it became a heading. Redefining the floor instead would have
     taken every chart axis and every grade chip up with it, which is not what
     the guidance is about, so the ROLE moved and the floor stayed: 11 is now
     only marks — grade chips, chart axes, the ticks drawn on a figure — and
     it is still audited at 4.5:1 with no large-text exemption.
     13 → 15 is the density step (a row's meta against a row's
     number); 15 → 19 is the hierarchy step (body against a title). Above 19
     nothing is text: 34 is a figure or a band headline, 88 is the finalizer
     page's grade letter, and both are objects to look at, not to read. The
     steps are deliberately far apart at the top — a ladder that can express
     "slightly bigger" gets used to express it. Only the two display steps
     move with the viewport (they clamp); the text steps hold, so a phone
     reads the same words at the same size as a desk.

     THREE FAMILIES, roles tightened. Size no longer separates a claimed name
     from a key, so face and weight must:
       Plex Mono      machine strings and labels only — keys, hashes, figures,
                      uppercase eyebrows, axes, units. Never prose.
       Plex Sans      all prose, and a claimed name at 600. A name is language,
                      a key is a string, and that is the difference readers see.
       Space Grotesk  display only — band headlines, band figures, section
                      titles, the grade letter. Never a paragraph, never a row. */
  --fs-1: 0.6875rem;                                   /* 11px  chips, axes, marks in a figure    */
  --fs-1b: 0.75rem;                                    /* 12px  every eyebrow — review #9         */
  --fs-2: 0.8125rem;                                   /* 13px  notes, meta, fine print           */
  --fs-3: 0.9375rem;                                   /* 15px  body text, rows, keys, prose      */
  --fs-4: 1.1875rem;                                   /* 19px  titles, names, lead numerals      */
  --fs-5: clamp(1.5rem, 1.1rem + 1.8vw, 2.125rem);     /* 34px  headlines and band figures        */
  --fs-6: clamp(3.25rem, 2.2rem + 4.6vw, 5.5rem);      /* 88px  the finalizer page's letter       */

  /* Two prose roles, and the line between them is a question about the
     text, not about the space it sits in:
       If a sentence is meant to be READ, it is --t-body (15px).
       If it is a LABEL on something else, it is --t-meta (13px).
     A canvas writes a role token. It never writes --fs-2 for a sentence. */
  --t-body:   var(--fs-3);
  --t-meta:   var(--fs-2);
  --t-eyebrow:var(--fs-1b); --t-title: var(--fs-4);
  --t-fig:    var(--fs-5); --t-letter:var(--fs-6);

  --fs-row:   var(--fs-3);

  --lh-fig: 1.05;    /* numerals — no descender room needed */
  --lh-tight: 1.1; --lh-snug: 1.25; --lh-title: 1.3;
  --lh-meta: 1.5;    /* labels: tight enough to read as one unit */
  --lh-body: 1.62;   /* sentences: loose enough to track across 68ch */
  --lh-letter: .86;  /* the 88px grade letter — optical, below 1 on purpose */
  --tr-label: 0.14em;

  /* ---- spacing & shape --------------------------------------------- */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-8: 32px; --sp-10: 40px; --sp-12: 48px;
  --pad-page: clamp(14px, 0.5rem + 1.8vw, 32px);
  --pad-head: 15px var(--sp-5);
  --pad-body: 18px var(--sp-5);
  --gap-grid: var(--sp-4);
  --measure: 68ch;          /* prose column */
  --measure-narrow: 52ch;   /* definitions, notes beside a figure */

  --r-1: 4px; --r-2: 8px;
  --snap: 90ms linear;      /* the interaction duration: hover, pressed, theme */

  /* THE TAP RULE (design-system/tokens/space.css): 44 is the target, not the
     glyph. A control smaller than this keeps its glyph and gains the hit box
     from centred slop, so the box grows and the layout does not move.
     --tap-move is the one step up for a hand pressing on a phone. */
  --tap: 44px;
  --tap-move: 48px;

  /* ---- MOTION — the live-update vocabulary (design-system/tokens/motion.css)
     Five finite ticks and two loops. A tick acknowledges a fact that changed
     and runs once; only the live dot, the syncing dot and the skeleton
     shimmer loop. Paint only: opacity, transform, colour, background. */
  --tick: 1.2s ease-out;                    /* a numeral or word that moved */
  --tick-row: 1.6s ease-out;                /* a row whose rank, grade or state moved */
  --tick-chip: .5s ease-out;                /* a chip whose state flipped */
  --sweep: .9s ease-out;                    /* a block arriving, a vote landing */
  --breathe: 1.8s ease-in-out infinite;     /* the live dot — the only slow loop */
  --breathe-fast: .9s ease-in-out infinite; /* the syncing dot, the missing dot */

  /* ---- THE LIST — type and density, set once (design v7, v8) --------
     The board is read at arm's length. Sizes come from the ladder above and
     nothing else: a claimed name is the same step as a key (15px), told apart
     by face and weight — Sans 600 for a name, Mono 400 for a key. The floor
     in a row is 13px. Only the density lives here. */
  --fs-row-name: var(--fs-3);   /* a claimed name is the same step as a key — the display face and weight set it apart */
  --fs-row-key:  var(--fs-3);
  --fs-row-meta: var(--fs-2);
  --row-pad:     15px;
  --row-chip:    var(--fs-1);
  --row-strip:   8px;
  --grid-row: 36px minmax(0,2.25fr) minmax(0,.78fr) minmax(0,1fr) 76px minmax(0,1.05fr);
}

[data-theme="dark"] {
  color-scheme: dark;
  --focus:var(--gold-500);
  --bg:var(--sp-950);
  --bg-raised:var(--sp-900);
  --bg-sunken:#040A12;
  --bg-inset:rgba(255,255,255,.035);
  --line:rgba(255,255,255,.10);
  --line-strong:rgba(255,255,255,.20);
  --line-signal:rgba(244,183,40,.45);
  --fg:#EDF4F8;
  --fg-2:var(--sp-200);
  --fg-3:#8FA9BA;
  --signal-text:var(--gold-500);
  --signal-bg:rgba(244,183,40,.13);
  --live:var(--cy);
  --live-bg:rgba(4,253,207,.12);
  --live-line:rgba(4,253,207,.32);
  --warn:#FF8A5C; --danger:#FF5C5C;
  --warn-bg:rgba(255,138,92,.12);
  --warn-line:rgba(255,138,92,.42);
  --bar-1:var(--sp-500); --bar-2:var(--sp-400); --bar-3:var(--sp-300);
  --tip-shadow:0 20px 44px -22px rgba(0,0,0,.9);
  --ic-1:#F4B728; --ic-2:#00A8C9; --ic-3:#87A2B4; --ic-4:#3CD9A0;
}

/* =====================================================================
   base
   ===================================================================== */
*, *::before, *::after { box-sizing: border-box; }
/* An author `display:` beats the UA rule for [hidden], and this sheet sets
   display on panels, grids and chips that are hidden until their data lands.
   One rule, so the attribute means what it says on every page. */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--sans);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}
.wrap { max-width: 1240px; margin: 0 auto; padding: 0 var(--pad-page) var(--sp-12); }
.wrap.prose { max-width: 820px; }

h1, h2, h3 {
  margin: 0; font-family: var(--display); font-weight: 700;
  letter-spacing: -0.02em; line-height: var(--lh-snug);
}
p { margin: 0 0 var(--sp-3); }
a { color: var(--signal-text); text-decoration: none; }
a:hover,
a:active { color: var(--gold-800); text-decoration: underline; }
[data-theme="dark"] a:hover,
[data-theme="dark"] a:active { color: var(--gold-300); }
code, .mono { font-family: var(--mono); font-size: var(--t-eyebrow); }
.muted { color: var(--fg-2); }
.faint { color: var(--fg-3); }
:where(button, a, [tabindex]):focus-visible {
  outline: 2px solid var(--focus); outline-offset: 2px;
}

/* mission-control eyebrow: 11px mono caps, wide tracking */
.eyebrow {
  font-family: var(--mono); font-size: var(--t-eyebrow); font-weight: 500;
  letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--fg-3);
  line-height: var(--lh-snug);
}

/* the loops — three on the whole page, and no more (motion.css) */
@keyframes pulse-dot { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }

/* a hidden tab breathes nothing: the loops hold, the polls stop (js/ui.js) */
[data-live="paused"] *, [data-live="paused"] *::before, [data-live="paused"] *::after {
  animation-play-state: paused !important;
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* identicon glyph: stable visual identity for a bare hex key */
.idg { flex: none; vertical-align: -2px; }

/* a fraction is built, never typed (design system house rule, pulled
   2026-09-03): the precomposed glyph draws at half x-height, so at the 11 and
   13px steps its digits land near 6px — under the floor by definition. Two full
   digits at .7em around a fraction slash, inheriting face, size and colour:
   <span class="frac"><sup>2</sup>&frasl;<sub>3</sub></span>, from ui.js frac().
   In an SVG label the same fraction is tspans — the shifts are cumulative dy in
   svgchart.js, the digit size is the last rule here. A sentence says it in
   words: "two thirds", "a third". */
.frac { display: inline-block; white-space: nowrap; font-variant-numeric: lining-nums tabular-nums; letter-spacing: 0; line-height: 1; }
.frac sup, .frac sub { font-size: .7em; line-height: 1; position: relative; vertical-align: baseline; font-weight: 600; }
.frac sup { top: -.42em; margin-right: -.06em; }
.frac sub { top: .1em; margin-left: -.06em; }
text.frac .fd { font-size: .7em; font-weight: 600; }

/* the chart scrub answers any pointer, so the word for it is the pointer's:
   hover under a mouse, drag under a finger. Same rule as the tap targets
   below — it follows the pointer, never the width. */
.scrub-hint .coarse { display: none; }

/* glossary term links: dotted underline, colour inherited */
a.term { color: inherit; text-decoration: none; border-bottom: 1px dotted var(--line-strong); }
a.term:hover,
a.term:active { color: var(--signal-text); border-bottom-color: var(--signal); text-decoration: none; }

/* the state chip — one component, both themes, colours from the tokens */
.schip {
  display: inline-flex; align-items: center; padding: 3px 7px; flex: none;
  font-family: var(--mono); font-size: var(--fs-1); letter-spacing: .12em;
  text-transform: uppercase; white-space: nowrap;
  border: 1px solid var(--line-strong); color: var(--fg-3);
}

/* the glossary list */
.readlist { margin: var(--sp-3) 0 0; }
.readlist > div {
  display: grid; grid-template-columns: 112px minmax(0,1fr); gap: 14px;
  padding: var(--sp-2) 0; border-top: 1px solid var(--line);
  scroll-margin-top: var(--sp-5);
}
.readlist > div:target { background: var(--signal-bg); box-shadow: -8px 0 0 var(--signal-bg), 8px 0 0 var(--signal-bg); }
.readlist dt { font-family: var(--display); font-size: var(--t-body); font-weight: 600; }
.readlist dd { margin: 0; max-width: var(--measure-narrow); font-size: var(--t-body); line-height: var(--lh-body); color: var(--fg-2); }
@media (max-width: 560px) { .readlist > div { grid-template-columns: 88px minmax(0,1fr); } }

/* =====================================================================
   header
   ===================================================================== */
.topbar {
  display: flex; align-items: center; gap: var(--sp-4); flex-wrap: wrap;
  padding: var(--sp-5) 0 var(--sp-4); border-bottom: 1px solid var(--line);
}
.topbar h1 { font-size: var(--t-title); }
.topbar h1 a { color: inherit; }
.brand { display: flex; align-items: center; gap: var(--sp-2); }
/* Two square links passing through each other — the PoS ring and the PoW ring,
   held at the crossing. Square corners, butt caps, one grid, one orientation. */
.brand-mark { width: 20px; height: 20px; flex: none; display: block; }
/* the network selector: one link per network, the current one held in the
   inset tone. It is a link, not a button — the network is part of the address
   (network.js), so a switch is a navigation. The nav below is the page nav;
   this one keeps the label voice so the two read as different controls. */
.netsel {
  display: inline-flex; border: 1px solid var(--line-strong);
  border-radius: var(--r-1); overflow: hidden;
}
.netsel a {
  height: 30px; padding: 0 var(--sp-3); display: grid; place-items: center;
  background: var(--bg-raised); color: var(--fg-3);
  font-family: var(--mono); font-size: var(--t-eyebrow);
  text-transform: uppercase; letter-spacing: var(--tr-label); white-space: nowrap;
  text-decoration: none; transition: background var(--snap), color var(--snap);
}
.netsel a + a { border-left: 1px solid var(--line-strong); }
.netsel a:hover,
.netsel a:active { background: var(--bg-inset); color: var(--fg); text-decoration: none; }
.netsel a[aria-current] { background: var(--bg-inset); color: var(--fg); font-weight: 600; }
.topbar .right { margin-left: auto; display: flex; gap: var(--sp-2); align-items: center; flex-wrap: wrap; }

/* nav as a segmented control: active tab solid gold */
nav.pages {
  display: inline-flex; border: 1px solid var(--line-strong);
  border-radius: var(--r-1); overflow: hidden;
}
nav.pages a {
  height: 30px; padding: 0 14px; display: grid; place-items: center;
  background: var(--bg-raised); color: var(--fg);
  font-family: var(--sans); font-size: var(--t-meta); font-weight: 500;
  text-decoration: none; transition: background var(--snap);
}
nav.pages a + a { border-left: 1px solid var(--line-strong); }
nav.pages a:hover,
nav.pages a:active { background: var(--bg-inset); text-decoration: none; color: var(--fg); }
nav.pages a[aria-current] { background: var(--signal); color: var(--on-signal); font-weight: 600; }

.pill {
  display: inline-flex; align-items: center; gap: 7px;
  height: 26px; padding: 0 10px; border-radius: var(--r-1);
  border: 1px solid var(--line-strong);
  font-family: var(--mono); font-size: var(--t-eyebrow);
  letter-spacing: .1em; text-transform: uppercase; white-space: nowrap;
}
.pill::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; flex: none; }
.pill.ok    { border-color: var(--live-line); background: var(--live-bg); color: var(--live); }
.pill.ok::before { animation: pulse-dot var(--breathe); }
.pill.stale { border-color: var(--line-signal); background: var(--signal-bg); color: var(--signal-text); }
.pill.dead  { border-color: var(--warn-line); background: var(--warn-bg); color: var(--warn); }
/* the tab is hidden: nothing moves, and one fetch on return replaces the gap */
.pill.paused { border-style: dashed; color: var(--fg-3); }
.pill.paused::before { background: transparent; box-shadow: inset 0 0 0 1px currentColor; }
.pill.plain::before { display: none; }

button {
  background: var(--bg-raised); border: 1px solid var(--line-strong); color: var(--fg-2);
  border-radius: var(--r-1); padding: var(--sp-1) var(--sp-3);
  cursor: pointer; font: inherit; font-size: var(--t-meta); line-height: var(--lh-body);
  transition: background var(--snap), color var(--snap), border-color var(--snap);
}
button:hover,
button:active { color: var(--fg); background: var(--bg-inset); }
button.on { color: var(--signal-text); border-color: var(--line-signal); background: var(--signal-bg); }
#theme-toggle { width: 30px; height: 30px; padding: 0; display: grid; place-items: center; }
#theme-toggle:hover,
#theme-toggle:active { border-color: var(--signal); }
#theme-toggle svg { display: block; }
/* moon shows in light (click for dark), sun shows in dark */
#theme-toggle .sun { display: none; }
[data-theme="dark"] #theme-toggle .sun { display: block; }
[data-theme="dark"] #theme-toggle .moon { display: none; }

#banner {
  border: 1px solid var(--warn-line); background: var(--warn-bg); color: var(--warn);
  padding: var(--sp-3) var(--sp-4); margin: var(--sp-4) 0; font-size: var(--t-body);
}

/* =====================================================================
   tooltips — click-popovers behind an `i`
   ===================================================================== */
.tip-wrap { position: relative; display: inline-flex; }
.tip-btn {
  width: 20px; height: 20px; padding: 0; display: grid; place-items: center;
  border: 1px solid var(--line-strong); border-radius: var(--r-1);
  background: var(--bg-inset); color: var(--fg-2);
  font-family: var(--mono); font-size: var(--t-eyebrow); cursor: pointer; flex: none;
}
.tip-btn:hover,
.tip-btn:active { border-color: var(--signal); color: var(--signal-text); }
.tip-panel {
  position: absolute; z-index: 9; top: calc(100% + 10px); left: 0;
  width: min(400px, 84vw); padding: var(--sp-4);
  border: 1px solid var(--line-signal); background: var(--bg-raised);
  box-shadow: var(--tip-shadow);
  font-family: var(--sans); font-size: var(--t-body); font-weight: 400;
  line-height: var(--lh-body); color: var(--fg-2);
  text-transform: none; letter-spacing: 0; text-align: left; white-space: normal;
}
.tip-panel.up { top: auto; bottom: calc(100% + 10px); }
.tip-panel.right { left: auto; right: 0; }
.tip-panel p { margin: 0; }
.tip-panel p + p { margin-top: var(--sp-3); }
.tip-panel[hidden] { display: none; }

/* =====================================================================
   panels
   ===================================================================== */
.panel { border: 1px solid var(--line); background: var(--bg-raised); }

.grid { display: grid; gap: var(--gap-grid); }

/* --- vitals --- */

  

.note { font-size: var(--t-body); color: var(--fg-3); line-height: var(--lh-body); margin-top: var(--sp-3); }

.tip-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3); margin-bottom: var(--sp-3); }
.tip-head .eyebrow { letter-spacing: .1em; color: var(--signal-text); }

/* the lede under the header: what this site is, in two sentences */
.lede {
  margin: var(--sp-5) 0 0; max-width: var(--measure);
  font-size: var(--t-body); line-height: var(--lh-body); color: var(--fg-2);
}
.lede a { font-family: var(--mono); font-size: var(--t-meta); white-space: nowrap; }

/* a one-word state: FINALIZING, STALLED, OPEN */
.figchip {
  font-family: var(--mono); font-size: var(--fs-1); letter-spacing: .12em;
  padding: 2px 5px; border: 1px solid var(--line-strong); color: var(--fg-3);
  white-space: nowrap; flex: none;
}
.figchip:empty { display: none; }
.figchip.breached { border-color: var(--warn-line); color: var(--warn); }
.figchip.tight { border-color: var(--line-signal); color: var(--signal-text); }
.figchip.clear { border-color: var(--live-line); color: var(--live); }

/* a block arriving: a 1px signal line runs the width of the band's top edge,
   once (motion.css `.sweep`). The band clips at its border, so the line sits
   on the inside of the edge (top: 0) rather than over it (the system's -1px). */
.sweep::after {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 1px; background: var(--signal);
  transform-origin: left; transform: scaleX(0); opacity: 0; pointer-events: none;
}
.sweep.block-in::after { animation: head-sweep var(--sweep); }
@keyframes head-sweep { 0% { transform: scaleX(0); opacity: 1; } 70% { opacity: 1; } 100% { transform: scaleX(1); opacity: 0; } }

/* =====================================================================
   where to stake — the Staking Day track, the suggestion, its actions
   ===================================================================== */
.wbar {
  position: relative; flex: 1; min-width: 120px; height: 8px;
  background: var(--bg-sunken); border: 1px solid var(--line);
}
.wbar i { position: absolute; inset: -1px auto -1px -1px; background: var(--live-bg); border-right: 1px solid var(--live-line); }
.wbar.closed i { background: var(--bg-inset); border-right-color: var(--line-strong); }
.wbar u { position: absolute; top: -3px; bottom: -3px; width: 2px; background: var(--fg); }

.sug {
  display: grid; grid-template-columns: minmax(0,1fr) auto; gap: 18px;
  align-items: center; padding: 22px var(--sp-5);
}
@media (max-width: 720px) {
  .sug { grid-template-columns: 1fr; }
  }

.sug-icon canvas, .sug-icon svg { display: block; }
.sug-id { min-width: 0; }

/* uptime as a chip beside a name: ok at the suggestion rule, gold under it */
.uptchip {
  display: inline-flex; align-items: center; flex: none; padding: 3px 9px;
  border: 1px solid var(--line-strong); color: var(--fg-2);
  font-family: var(--mono); font-size: var(--row-chip); font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; white-space: nowrap;
}
.uptchip.ok { border-color: var(--live-line); color: var(--live); }
.uptchip.warn { border-color: var(--line-signal); color: var(--signal-text); }
.uptchip.none { border-style: dashed; color: var(--fg-3); }
.uptchip.plain { color: var(--fg-2); }

/* nobody meets the rule: say so in one sentence, and point at the table */

.se-icon {
  flex: 0 0 auto; width: 46px; height: 46px; display: grid; place-items: center;
  border: 1px dashed var(--line-strong); color: var(--fg-3);
  font-family: var(--mono); font-size: var(--fs-4);
}
.se-title {
  max-width: 62ch; font-family: var(--display); font-size: var(--t-title);
  font-weight: 600; line-height: var(--lh-title); letter-spacing: -.015em; color: var(--fg);
}
.se-go {
  display: inline-flex; align-items: center; height: 38px; padding: 0 18px;
  border: 1px solid var(--line-strong); background: transparent; color: var(--fg-2);
  font-family: var(--mono); font-size: var(--t-meta); letter-spacing: .06em;
  border-radius: var(--r-1); text-decoration: none;
  transition: border-color var(--snap), color var(--snap);
}
.se-go:hover,
.se-go:active { border-color: var(--signal); color: var(--signal-text); text-decoration: none; }

.sug-go {
  display: inline-flex; align-items: center; height: 38px; padding: 0 18px;
  border: 1px solid var(--gold-700); background: var(--signal); color: var(--on-signal);
  font-family: var(--mono); font-size: var(--t-meta); font-weight: 600; letter-spacing: .06em;
  border-radius: var(--r-1); transition: background var(--snap); text-decoration: none;
}
.sug-go:hover,
.sug-go:active { background: var(--gold-300); text-decoration: none; }
/* on a phone the figure drops under its label instead of squeezing it */

.segmented {
  display: inline-flex; border: 1px solid var(--line-strong);
  border-radius: var(--r-1); overflow: hidden;
}
.segmented button {
  height: 28px; padding: 0 var(--sp-3); border: 0; border-radius: 0; background: var(--bg-raised);
  color: var(--fg-2); font-family: var(--mono); font-size: var(--t-eyebrow); line-height: 1;
}
.segmented button + button { border-left: 1px solid var(--line-strong); }
.segmented button.on { background: var(--signal); color: var(--on-signal); font-weight: 600; }

/* =====================================================================
   scoreboard — div grid with folds
   ===================================================================== */
.tablepanel { border: 1px solid var(--line); background: var(--bg-raised); }

.search {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  height: 30px; padding: 0 11px;
  border: 1px solid var(--line-strong); background: var(--bg-inset); color: var(--fg-3);
  border-radius: var(--r-1);
}
.search input {
  background: none; border: 0; outline: none; color: var(--fg);
  font-family: var(--mono); font-size: var(--t-meta); width: 14ch;
}
.search input::placeholder { color: var(--fg-3); }
.search:focus-within { border-color: var(--signal); }

.srow {
  position: relative;
  /* the six token columns: # · finalizer · stake · voting power · uptime · status */
  display: grid; grid-template-columns: var(--grid-row); gap: var(--sp-4);
  align-items: center; padding: var(--row-pad) var(--sp-5);
  border-bottom: 1px solid var(--line); transition: background var(--snap);
}
.srow.head {
  position: sticky; top: 0; z-index: 6; background: var(--bg-raised);
  padding: 10px var(--sp-5); border-bottom: 1px solid var(--line-strong);
  font-family: var(--mono); font-size: var(--t-eyebrow); letter-spacing: .06em;
  text-transform: uppercase; color: var(--fg-3);
}
.srow.clickable { cursor: pointer; }
.srow.clickable:hover,
.srow.clickable:active { background: var(--bg-inset); }
.srow.clickable:focus-visible { outline: 2px solid var(--focus); outline-offset: -3px; }
.namecell { min-width: 0; }
.namecell .fin-link { display: inline-flex; align-items: center; gap: 9px; min-width: 0; }
.hexname { font-size: var(--fs-row-key); color: var(--fg-2); letter-spacing: -.01em; }
a.fin-link:hover .hexname,
a.fin-link:active .hexname { color: var(--signal-text); }

/* the uptime figure is the button that opens its readout */
.uptcell { position: relative; display: flex; justify-content: center; min-width: 0; }

/* gold edge = one of the largest N — a location, not a verdict */

.srow .rank { font-family: var(--mono); font-size: var(--fs-row-meta); color: var(--fg-3); }
.srow .r { text-align: right; }

.srow .num { font-family: var(--mono); font-size: var(--fs-row); }
.srow .num.dim { color: var(--fg-2); }
.fin-name {
  font-family: var(--display); font-size: var(--fs-row-name); font-weight: 600; letter-spacing: -.015em;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

a.fin-link { color: inherit; text-decoration: none; }
a.fin-link:hover .fin-name, a.fin-link:hover .key,
a.fin-link:active .fin-name,
a.fin-link:active .key { color: var(--signal-text); }
/* A key in a row is the row's identity, not an annotation on it: same step as
   the name and the stake (15px), told apart by face. The contextual rules
   below — .rd-key .key, .keyrow .key — still win on specificity where a
   64-character key needs its own size. */
.key { font-family: var(--mono); font-size: var(--fs-row-key); color: var(--fg-2); }

.sharecell { display: flex; align-items: center; gap: var(--sp-2); }
.sharebar { flex: 1; height: 6px; background: var(--bg-sunken); border: 1px solid var(--line); }
.sharebar i { display: block; width: 0; height: 100%; background: var(--bar-1); }

.sharenum { font-family: var(--mono); font-size: var(--fs-row-meta); width: 46px; text-align: right; flex: none; }

.schip.terminated { border-color: var(--warn-line); color: var(--warn); flex: none; }
[data-theme="dark"] .schip.terminated { border-color: rgba(255,138,92,.42); }

/* Status — a dot and Online or Offline, with how long since it last signed.
   Offline is the warn tone; online is quiet; a dash is dashed. */
.statuscell { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 2px; min-width: 0; cursor: help; }
.statuschip {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%; min-width: 0;
  padding: 3px 8px 3px 7px; border: 1px solid var(--line-strong); border-radius: var(--r-1);
  font-family: var(--mono); font-size: var(--row-chip); letter-spacing: .04em; text-transform: uppercase;
  color: var(--fg-3); white-space: nowrap; cursor: help;
  transition: border-color var(--snap), color var(--snap), background var(--snap);
}
.statuschip i { width: 6px; height: 6px; border-radius: 50%; background: var(--fg-3); flex: none; }
.statuscell > .nd { max-width: 100%; font-family: var(--mono); font-size: var(--row-chip); line-height: var(--lh-meta); color: var(--fg-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.statuschip.online { border-color: var(--live-line); color: var(--fg-2); }
.statuschip.online i { background: var(--live); }
.statuschip.offline { border-color: var(--warn-line); background: var(--warn-bg); color: var(--warn); }
.statuschip.offline i { background: var(--warn); }
.statuschip.none { border-color: transparent; background: transparent; color: var(--fg-3); cursor: default; }

/* the change itself, shown once: a row whose facts moved, a chip whose state
   moved, a numeral that ticked. One tick per element at a time — restart by
   removing the class, reading offsetWidth, adding it back (ui.js `tick`),
   never by cloning. Reduced-motion turns every one of these off. */
@keyframes row-tick { 0% { background: var(--signal-bg); } 100% { background: transparent; } }
@keyframes chip-tick { 0% { transform: scale(1.18); } 100% { transform: scale(1); } }
@keyframes text-tick { 0% { color: var(--signal-text); } 100% { color: inherit; } }
.srow.changed { animation: row-tick var(--tick-row); }
.statuschip.changed { animation: chip-tick var(--tick-chip); }
.board-tally .bad { color: var(--warn); }

/* The fold — ONE object for every place the board hides rows behind a line:
   the largest N, the paging fold at the tail of the list, and the pool
   fold in the delegate band. The whole bar is the target and never shorter
   than 44px; the eyebrow names the boundary; the description is dropped,
   not truncated, on a phone; a second action appears only when the
   remainder is more than one page. (design v7) */
.fold {
  width: 100%; min-height: var(--tap); display: flex; gap: 14px; align-items: center;
  padding: var(--sp-2) var(--sp-5); cursor: pointer; text-align: left;
  border: 0; border-bottom: 1px solid var(--line); border-radius: 0;
  background: var(--bg-inset); font: inherit; color: inherit;
  transition: background var(--snap);
}
.fold:hover,
.fold:active { background: var(--bg-sunken); }
.fold:focus-visible { outline: 2px solid var(--focus); outline-offset: -3px; }

.fold .tag {
  font-family: var(--mono); font-size: var(--t-eyebrow); font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; color: var(--fg-2); flex-shrink: 0;
}

.fold .desc {
  flex: 1; min-width: 0; font-size: var(--fs-row-meta); color: var(--fg-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.fold .desc.mono { font-family: var(--mono); color: var(--fg-3); }
.fold .toggle {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  height: 34px; min-width: 112px; padding: 0 12px; margin-left: auto;
  border: 1px solid var(--line-strong); color: var(--fg-2);
  font-family: var(--mono); font-size: var(--t-eyebrow); letter-spacing: .08em;
  border-radius: var(--r-1); flex-shrink: 0; white-space: nowrap;
}
.fold .toggle.all { height: 34px; min-width: 0; padding: 0 12px; }

/* "show more" below the largest N: one fold, one or two actions — each its
   own button, so it is reachable from the keyboard */
.fold.more { cursor: default; }
.fold.more .toggle { background: transparent; cursor: pointer; font: inherit; font-family: var(--mono); font-size: var(--t-eyebrow); }
.fold.more .toggle.all { margin-left: 0; }
.fold.more .toggle:hover, .fold.more .toggle:focus-visible,
.fold.more .toggle:active { border-color: var(--signal); color: var(--signal-text); outline: 0; }

/* the board before data, and an empty search */
.board-loading { padding: var(--sp-4) var(--sp-5); font-size: var(--t-meta); color: var(--fg-3); }

/* the one line above the rows while finality is stalled */
.board-note {
  padding: var(--sp-3) var(--sp-5); border-bottom: 1px solid var(--line);
  font-size: var(--t-meta); line-height: var(--lh-meta); color: var(--fg-2);
}

/* Row detail — five full-width bands: the 64-character key with COPY, four
   vitals across one row, signed blocks over the last 60, stake over 7 days,
   and the way out to the full page. At 900 the vitals fall to 2-up. */
.srow-detail {
  border-bottom: 1px solid var(--line); background: var(--bg-inset);
  box-shadow: inset 3px 0 0 var(--line-strong);
}
.rd-eyebrow {
  font-family: var(--mono); font-size: var(--row-chip); font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--fg-3); flex: 0 0 auto;
}
.rd-key {
  display: flex; align-items: center; gap: 12px 14px; flex-wrap: wrap;
  padding: 13px var(--sp-5); border-bottom: 1px solid var(--line);
}
.rd-key .key {
  flex: 1 1 320px; min-width: 0; font-family: var(--mono); font-size: var(--t-body);
  line-height: var(--lh-meta); color: var(--fg); overflow-wrap: anywhere; word-break: break-all;
}
.rd-copy {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  gap: 7px; height: 34px; min-width: 96px; padding: 0 13px;
  border: 1px solid var(--line-strong); background: var(--bg-raised); color: var(--fg-2);
  font-family: var(--mono); font-size: var(--t-eyebrow); letter-spacing: .1em;
  border-radius: var(--r-1); cursor: pointer;
  transition: border-color var(--snap), color var(--snap);
}
.rd-copy:hover,
.rd-copy:active { border-color: var(--signal); color: var(--signal-text); }

/* four vitals, one row — 1px gaps over the line colour draw the hairlines */
.rd-vitals {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px; background: var(--line);
}
.rd-fact { background: var(--bg-inset); padding: 13px var(--sp-5) 14px; }
.rd-fact b {
  display: block; margin-top: 7px; font-family: var(--mono); font-size: var(--fs-4);
  font-weight: 400; line-height: var(--lh-tight); color: var(--fg);
}
.rd-fact b.live { color: var(--live); }
.rd-fact b.warn { color: var(--signal-text); }
.rd-fact b.dim { color: var(--fg-3); }
.rd-fact small { display: block; margin-top: 4px; font-size: var(--t-meta); line-height: var(--lh-meta); color: var(--fg-3); }

.rd-votes {
  display: flex; align-items: center; gap: 10px 16px; flex-wrap: wrap;
  padding: 14px var(--sp-5); border-top: 1px solid var(--line);
}
.rd-strip { flex: 1 1 220px; min-width: 0; line-height: 0; }  /* layout: same */
.rd-strip svg { max-width: none; height: 16px; }
.rd-count { flex: 0 0 auto; font-family: var(--mono); font-size: var(--t-body); color: var(--fg-2); }

.rd-out {
  display: flex; align-items: center; justify-content: flex-end; gap: 10px 16px; flex-wrap: wrap;
  padding: 11px var(--sp-5); border-top: 1px solid var(--line); background: var(--bg-raised);
}
.rd-out a { flex: 0 0 auto; font-family: var(--mono); font-size: var(--t-meta); }

/* the open row keeps its own edge: gold for the largest N, quiet elsewhere */
.srow.open { background: var(--bg-inset); }

@media (max-width: 900px) {
  .rd-vitals { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rd-key, .rd-fact, .rd-votes, .rd-out { padding-left: var(--row-pad); padding-right: var(--row-pad); }
}
@media (max-width: 560px) {
  .rd-key { align-items: flex-start; }
  .rd-key .key { font-size: var(--t-meta); }
  .rd-copy { width: 100%; }
}

/* the key, and the registry entry when there is one */

.ident-desc {
  margin: 10px 0 0; font-size: var(--t-body); line-height: var(--lh-body);
  max-width: 70ch; color: var(--fg-2); text-wrap: pretty;
}
.linkchips { margin-top: 14px; display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.linkchips:empty { display: none; }
.linkchips a {
  display: inline-flex; align-items: center; height: 30px; padding: 0 11px;
  border: 1px solid var(--line-strong); background: var(--bg-inset);
  font-family: var(--mono); font-size: var(--t-meta); color: var(--fg-2);
}
.linkchips a:hover,
.linkchips a:active { border-color: var(--signal); color: var(--signal-text); text-decoration: none; }

.copybtn {
  flex-shrink: 0; height: 28px; padding: 0 10px; background: var(--bg-inset);
  font-family: var(--mono); font-size: var(--t-eyebrow);
  letter-spacing: .06em; text-transform: uppercase;
}
.copybtn:hover,
.copybtn:active { border-color: var(--signal); color: var(--signal-text); }

/* terminated is a page state */
.removed-banner {
  margin-top: var(--sp-6); padding: 18px 22px;
  border: 1px solid var(--warn); background: var(--warn-bg);
}
.removed-banner[hidden] { display: none; }

.rb-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.rb-title { font-family: var(--display); font-size: var(--t-title); font-weight: 700; letter-spacing: -.02em; }
.removed-banner p { margin: 10px 0 0; max-width: 78ch; font-size: var(--t-body); line-height: var(--lh-body); color: var(--fg-2); }

/* stake history head + shared chart furniture */

.chart-legend {
  margin-top: 10px; display: flex; align-items: center; gap: var(--sp-3) var(--sp-5);
  flex-wrap: wrap; font-family: var(--mono); font-size: var(--t-eyebrow); color: var(--fg-3);
}
.chart-legend > span { display: inline-flex; align-items: center; gap: 7px; }
.chart-legend .sw { width: 8px; height: 8px; display: inline-block; flex: none; }
.chart-legend .sw.tall { height: 10px; }
.chart-legend .sw.low { height: 5px; }
/* the voting power ranking: the largest N in the chart's gold */
.chart-legend .sw.top { background: var(--gold-500); }

/* =====================================================================
   tone utilities
   ===================================================================== */
b.ok, span.ok { color: var(--live); }
b.warn, span.warn { color: var(--signal-text); }
b.bad, span.bad { color: var(--warn); }

/* the data readout popover */

  

.board-tally {
  display: flex; justify-content: space-between; gap: var(--sp-4); flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-5);
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  background: var(--bg-inset);
  font-family: var(--mono); font-size: var(--fs-row-meta); letter-spacing: .04em;
  color: var(--fg-2);
}
.board-tally .tal { display: inline-flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; color: var(--fg); }
.board-tally .sep, .board-tally .faint { color: var(--fg-3); }
.board-tally .dim { color: var(--fg-2); }
.board-tally a { font-family: var(--mono); font-size: var(--t-meta); }

/* still climbing to the tip: a caveat over the whole page, not one panel.
   Quiet, not gold — it is this site's own state, not a network warning. */
.syncnote {
  margin-top: var(--sp-4); padding: 13px 18px 14px;
  border: 1px solid var(--line-strong); background: var(--bg-inset);
}
.syncnote[hidden] { display: none; }
.syncnote .sline { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.syncnote .sline { position: relative; }
.syncnote .tip-wrap { position: static; }
.syncnote .stext {
  flex: 1; min-width: 260px; font-size: var(--t-body); line-height: var(--lh-body); color: var(--fg-2);
}
.syncnote .stext strong { font-family: var(--mono); font-weight: 400; color: var(--fg); }
.syncnote .stext .faint { font-family: var(--mono); color: var(--fg-3); }
.syncnote .sbar {
  position: relative; margin-top: 11px; height: 6px;
  background: var(--bg-sunken); border: 1px solid var(--line);
}
.syncnote .sbar i {
  position: absolute; inset: -1px auto -1px -1px;
  background: var(--bar-2); border-right: 1px solid var(--line-strong);
}

/* ── tier 05 · history — the design system's BondFlow, BondedTrace and Facts
   rules (components/components.css), copied here because components are not
   mirrored. Container queries, not media queries:
   the list lives in a panel, and a 390 phone and a narrow column stack the
   same way. The bar's width is data-w, sized through the CSSOM (ui.js
   sizeBars); the production CSP refuses a style attribute. ─────────────── */

/* BondFlow — one row per finalizer whose stake changed, not counting rewards.
   The bar diverges from a centre line: position carries the sign, the glyph
   in the figure repeats it, colour only says which way. The figure sits LEFT
   of the bar, the actions clause right of it, one step smaller and dim. */
.bflow { container-type: inline-size; }

.bflow-list { border-top: 1px solid var(--line); }
.brow { display: grid; grid-template-columns: minmax(180px, 24fr) 124px minmax(160px, 44fr) minmax(140px, 20fr); gap: var(--sp-4); align-items: center; min-height: var(--tap); padding: var(--sp-2) var(--sp-5); border-bottom: 1px solid var(--line); color: inherit; text-decoration: none; transition: background var(--snap); }
.brow:hover,
.brow:active { background: var(--bg-inset); text-decoration: none; }
.brow:hover .key, .brow:hover .fin-name,
.brow:active .key,
.brow:active .fin-name { color: var(--signal-text); }
.brow:focus-visible { outline: 2px solid var(--focus); outline-offset: -3px; }
.bid { display: flex; align-items: center; gap: 10px; min-width: 0; }
.bid .key { font-family: var(--mono); font-size: var(--fs-row-key); color: var(--fg-2); white-space: nowrap; }
.bid .fin-name { font-family: var(--sans); font-size: var(--fs-row-name); font-weight: 600; color: var(--fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.btag { font-family: var(--mono); font-size: var(--t-eyebrow); letter-spacing: .1em; text-transform: uppercase; color: var(--fg-2); padding: 2px 6px; border: 1px solid var(--line-strong); border-radius: var(--r-1); white-space: nowrap; }
.bamt { font-family: var(--mono); font-size: var(--fs-row); text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--fg); }
.bamt .u { color: var(--fg-3); font-size: var(--t-meta); margin-left: 3px; }
.bbar { position: relative; height: 10px; background: var(--bg-sunken); }
.bbar::before { content: ""; position: absolute; left: 50%; top: -3px; bottom: -3px; width: 1px; background: var(--line-strong); }
.bbar i { position: absolute; top: 0; bottom: 0; display: block; max-width: 50%; min-width: 2px; }
.bbar i.in { left: 50%; background: var(--bar-1); }
.bbar i.out { right: 50%; background: var(--bar-3); }
.bacts { font-family: var(--mono); font-size: var(--t-eyebrow); letter-spacing: .04em; color: var(--fg-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.strip-legend { display: flex; align-items: center; gap: var(--sp-2) var(--sp-4); flex-wrap: wrap; padding: var(--sp-2) var(--sp-5); font-family: var(--mono); font-size: var(--t-eyebrow); color: var(--fg-3); }
.strip-legend .sw { width: 8px; height: 8px; display: inline-block; margin-right: 6px; vertical-align: 0; background: var(--bar-1); }
.strip-legend .sw.out { background: var(--bar-3); }
.strip-legend .sw.stall { background: var(--warn); opacity: .3; }
.strip-legend .sw.nodata { background: repeating-linear-gradient(45deg, var(--fg-3) 0 1px, transparent 1px 3px); opacity: .7; }
.strip-legend .sw.line { height: 0; border-top: 2px solid var(--fg-2); background: none; vertical-align: 3px; }
.strip-legend .sw.line.under { border-top-color: var(--warn); }
.strip-legend .sw.need { height: 0; border-top: 1px dashed var(--fg-3); background: none; vertical-align: 3px; }
.strip-legend .push { margin-left: auto; }
/* the chart legend sits inside .vstrip's own padding */
.strip-legend { padding: var(--sp-2) 0 0; }
.bflow-empty { padding: var(--sp-4) var(--sp-5); border-top: 1px solid var(--line); font-size: var(--t-body); line-height: var(--lh-body); color: var(--fg-3); }
.bflow .fold.more, .panel > .fold.more { border-top: 1px solid var(--line); border-bottom: 0; background: var(--bg-inset); justify-content: center; }
@container (max-width: 700px) {
  .bflow-head { padding-left: var(--sp-4); padding-right: var(--sp-4); }
  .bflow-totals { margin-left: 0; flex-basis: 100%; }
  .brow { grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-1) var(--sp-3); padding: var(--sp-3) var(--sp-4); }
  .bid { flex-wrap: wrap; }
  .bbar, .bacts { grid-column: 1 / -1; }
  .bacts { white-space: normal; }
  .bflow-legend { padding-left: var(--sp-4); padding-right: var(--sp-4); }
  .bflow-legend .push, .strip-legend .push { margin-left: 0; flex-basis: 100%; }
}

/* BondedTrace — one finalizer's stake over a range (the finalizer page's
   Stake panel): the dashed path is the stake step, the fill under it the
   stake, the wedge above it the rewards. */
.btrace { padding: var(--sp-2) var(--sp-5) var(--sp-3); border-top: 1px solid var(--line); }
.btrace svg { display: block; width: 100%; height: auto; overflow: visible; }
.btrace text { font-family: var(--mono); font-size: var(--t-eyebrow); fill: var(--fg-3); }
.btrace .tot { fill: none; stroke: var(--fg); stroke-width: 1.5; }
.btrace .rew { fill: none; stroke: var(--fg-3); stroke-width: 1; stroke-dasharray: 3 3; }
.btrace .beyond { fill: var(--signal-bg); }
.btrace .bonds { fill: var(--bg-sunken); }
.btrace .now { fill: var(--fg); }
.btrace.flush { border-top: 0; padding: var(--sp-2) 0 0; }

.btrace .grid { stroke: var(--line); stroke-width: 1; }
.btrace .tick.in { fill: var(--gold-700); }
.btrace .tick.out { fill: var(--warn); }

/* ParticipationTrace — tier 05's participation chart (svgchart.js
   participationTrace): one line on a 0–100 axis with the dashed two-thirds
   rule, a stretch with finality stalled shaded in the warn tone, a stretch
   with no data hatched. Every colour a token, every size a role. */
.ptrace { margin-top: var(--sp-2); }
.ptrace svg { display: block; width: 100%; height: auto; overflow: visible; }
.ptrace text { font-family: var(--mono); font-size: var(--t-eyebrow); fill: var(--fg-3); }
.ptrace .grid { stroke: var(--line); stroke-width: 1; }
.ptrace .grid.base { stroke: var(--line-strong); }
.ptrace .need { stroke: var(--fg-3); stroke-width: 1; stroke-dasharray: 3 3; }
.ptrace .tick { stroke: var(--line-strong); stroke-width: 1; }
.ptrace .line { fill: none; stroke: var(--fg-2); stroke-width: 1.5; }
.ptrace .line.under { stroke: var(--warn); }
.ptrace .area { fill: var(--fg-2); opacity: .10; }
.ptrace .band.stall { fill: var(--warn); opacity: .12; }
.ptrace .hatch line { stroke: var(--fg-3); stroke-width: 1; opacity: .55; }
.ptrace .now { fill: var(--fg-2); }
.ptrace .now.under { fill: var(--warn); }
.ptrace .cursor { stroke: var(--fg-2); fill: none; }
.ptrace .ring { fill: var(--bg-raised); stroke: var(--fg); }
.ptrace .chip { fill: var(--bg-raised); stroke: var(--line-strong); stroke-width: 1; }
.ptrace .chiptext { fill: var(--fg); }
.btrace-legend { display: flex; align-items: center; gap: var(--sp-2) var(--sp-4); flex-wrap: wrap; margin-top: var(--sp-2); font-family: var(--mono); font-size: var(--t-eyebrow); color: var(--fg-3); }
.btrace-legend .sw { width: 8px; height: 8px; display: inline-block; margin-right: 6px; }
.btrace-legend .sw.beyond { background: var(--signal-bg); box-shadow: inset 0 0 0 1px var(--line-signal); }
.btrace-legend .sw.rew { height: 0; border-top: 1px dashed var(--fg-3); }
.btrace-legend .sw.tot { height: 0; border-top: 2px solid var(--fg); }
.btrace-legend .sw.bonds { background: var(--bg-sunken); box-shadow: inset 0 0 0 1px var(--line-strong); }
.btrace-legend .sw.in { background: var(--gold-700); }
.btrace-legend .sw.out { background: var(--warn); }
.btrace-legend .push { margin-left: auto; }

/* a history block: its head, one short line, the chart or list, the legend */

.stall-list { list-style: none; margin: var(--sp-2) 0 0; padding: 0; }
.stall-list li {
  padding: var(--sp-2) 0; border-top: 1px solid var(--line);
  font-family: var(--mono); font-size: var(--t-meta); line-height: var(--lh-meta); color: var(--fg-2);
}
.stall-list li b { color: var(--fg); font-weight: 600; }
.stall-list li.open b { color: var(--warn); }

/* Facts — the labelled lines under the history */

@container (max-width: 700px) { .facts .frow { grid-template-columns: minmax(0, 1fr); gap: 2px; padding-left: var(--sp-4); padding-right: var(--sp-4); } }

/* =====================================================================
   prose pages
   ===================================================================== */
.prose article { padding: var(--sp-6) clamp(var(--sp-5), 3vw, var(--sp-10)) var(--sp-10); }
.prose h2 { font-size: var(--t-title); margin: var(--sp-8) 0 var(--sp-3); }
.prose h2:first-of-type { margin-top: 0; }
.prose article p, .prose article li { font-size: var(--t-body); color: var(--fg-2); line-height: var(--lh-body); }
.prose strong { color: var(--fg); }
.prose li { margin-bottom: var(--sp-1); }
.prose pre {
  font-family: var(--mono); font-size: var(--t-meta); background: var(--bg-sunken);
  border: 1px solid var(--line); padding: var(--sp-3) var(--sp-4); overflow-x: auto; color: var(--fg);
}

/* =====================================================================
   footer — one line
   ===================================================================== */
footer {
  margin-top: 34px; padding-top: var(--sp-5); border-top: 1px solid var(--line);
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 18px var(--sp-10); flex-wrap: wrap;
  font-size: var(--t-body); color: var(--fg-3);
}
footer p { margin: 0; }
footer .sep { color: var(--line-strong); }
.fnotes { display: grid; gap: 7px; line-height: var(--lh-meta); }

/* =====================================================================
   mobile — drop columns, not data (the table's own steps are with it, in
   the design v2 block below)
   ===================================================================== */
@media (max-width: 900px) {
  .fold .desc { display: none; }
  .fold { flex-wrap: wrap; min-height: var(--tap); }
  .fold .tag { flex: 1 1 auto; min-width: 0; }
}

/* method page: numbered sections and a contents rail */
.prose .toc {
  margin-top: var(--sp-4); padding: var(--sp-4) var(--sp-5);
  border: 1px solid var(--line); background: var(--bg-raised);
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 4px 24px;
}
.prose .toc a {
  display: flex; gap: 10px; align-items: baseline; padding: 4px 0;
  font-size: var(--t-meta); color: var(--fg-2); text-decoration: none;
  border-bottom: 1px solid transparent;
}
.prose .toc a:hover,
.prose .toc a:active { color: var(--signal-text); }
.prose .toc .n {
  font-family: var(--mono); font-size: var(--t-eyebrow); color: var(--fg-3); flex: none; width: 18px;
}
.prose h2 { display: flex; gap: 12px; align-items: baseline; scroll-margin-top: 16px; }
.prose h2 .n {
  font-family: var(--mono); font-size: var(--t-meta); font-weight: 600;
  color: var(--signal-text); flex: none;
}
.prose h2 a.anchor { margin-left: auto; font-family: var(--mono); font-size: var(--t-meta);
  color: var(--fg-3); text-decoration: none; opacity: 0; }
.prose h2:hover a.anchor { opacity: 1; }
/* a subsection inside a numbered section: one step under the section title,
   the same anchor, and a link target (the network page links into it) */
.prose h3 {
  display: flex; gap: 12px; align-items: baseline; scroll-margin-top: 16px;
  margin: var(--sp-4) 0 var(--sp-2); font-size: var(--t-title);
}
.prose h3 a.anchor { margin-left: auto; font-family: var(--mono); font-size: var(--t-meta);
  color: var(--fg-3); text-decoration: none; opacity: 0; }
.prose h3:hover a.anchor,
.prose h3:active a.anchor { opacity: 1; }
.prose .checklist { list-style: none; padding-left: 0; }
/* a block range such as 0–70 reads as one figure */
.prose .nobreak { white-space: nowrap; }
.prose .checklist li { padding: 9px 0 9px 26px; position: relative; border-top: 1px solid var(--line); }
.prose .checklist li::before {
  content: "→"; position: absolute; left: 2px; font-family: var(--mono); color: var(--signal-text);
}

/* =====================================================================
   design v8 — the text budget, the split verdict, the bonding cycle and
   the method sheet. Field feedback #5: what a delegator acts on stays on
   the surface; the why goes behind an `i` or into the sheet. Nothing here
   sets a raw font-size, and every colour is a token.
   ===================================================================== */

/* --- shared utilities: what used to be a style attribute --------------
   The production CSP is `style-src 'self'` with no 'unsafe-inline', so a
   style attribute is refused outright. Everything that was one is a class. */
.eyebrow.wide { letter-spacing: .12em; }

.push { margin-left: auto; }
.mono.step { font-size: var(--t-meta); }

.chart-legend .sw.seen { background: var(--live); }
.chart-legend .sw.miss { background: var(--bar-3); }

/* the identicon's four brand tones — a class, because var() needs CSS and
   an inline style attribute never survives the CSP */
.idg.ic1 { fill: var(--ic-1); }
.idg.ic2 { fill: var(--ic-2); }
.idg.ic3 { fill: var(--ic-3); }
.idg.ic4 { fill: var(--ic-4); }
.idg.idg-blank { fill: none; }

/* --- the band collapses before the columns get too narrow to read ------ */

@media (max-width: 720px) {
  footer { align-items: flex-start; }
}

/* uptime over days: the legend's swatches for a slot with no finalized block —
   a stall (a baseline tick), or a stretch with no data (hatched) */
.chart-legend .sw.none { height: 2px; background: var(--line-strong); }
.chart-legend .sw.nodata { height: 10px; background: repeating-linear-gradient(45deg, var(--fg-3) 0 1px, transparent 1px 3px); opacity: .7; }

/* A signed block arriving: the newest tile glows once in the signal colour
   and settles. Reduced-motion turns it off. */
@keyframes tile-in { 0% { opacity: 1; } 100% { opacity: 0; } }
.tile-new { fill: var(--signal); animation: tile-in 1.4s ease-out forwards; pointer-events: none; }

/* Status keeps its distance: a hairline off the uptime cell */
.srow .statuscell { padding-left: var(--sp-4); border-left: 1px solid var(--line); min-height: 26px; }
.srow.head .statushead { padding-left: var(--sp-4); border-left: 1px solid transparent; }
@media (max-width: 900px) {
  .srow .statuscell { padding-left: var(--sp-2); }
  .srow.head .statushead { padding-left: var(--sp-2); }
}
@media (max-width: 560px) {
  .srow .statuscell { padding-left: 0; border-left: 0; }
}

/* Footer, two columns: what this dashboard is and who maintains it, and
   Crosslink with Shielded Labs' page, FAQ and book. A name in the display
   face, a by-line in the meta step, links in mono. */
.fcol { flex: 1 1 280px; min-width: 0; display: grid; gap: var(--sp-2); align-content: start; }
.fline { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-1) var(--sp-2); }
.fname { font-family: var(--display); font-size: var(--t-body); font-weight: 600; color: var(--fg); }
.fby { font-size: var(--t-meta); line-height: var(--lh-meta); color: var(--fg-3); }
.fby a { color: var(--fg-2); }
.fby a:hover,
.fby a:active { color: var(--signal-text); }
.fnotes a { font-family: var(--mono); font-size: var(--t-meta); }

/* =====================================================================
   design v2 — one dense board (the Crosslink v2 canvases, 2026-09-15)

   Every page opens on an overview strip that stays in view, then panels
   of the same construction: an eyebrow heading, the figure, the one line
   under it. The strip's cells, the network page's cards and the history
   and finalizer panels are one component each, used everywhere.
   ===================================================================== */
.wrap.wide { max-width: 1360px; }

/* the overview strip: sticky, cells over the line colour so the dividers
   read as ruled lines, wrapping two by two on a phone */
.ov {
  position: sticky; top: 0; z-index: 30; margin-top: var(--sp-4);
  display: flex; flex-wrap: wrap; gap: 1px;
  background: var(--line-strong); border: 1px solid var(--line-strong);
}
.ov-cell {
  flex: 1 1 178px; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-1);
  padding: var(--sp-2) var(--sp-4); background: var(--bg-raised);
}
.ov-cell .eyebrow a.term { color: inherit; }
.ov-val { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0 var(--sp-2); min-width: 0; }
.ov-val .figchip { align-self: center; }
.ov-fig {
  font-family: var(--mono); font-size: var(--t-title); font-weight: 500;
  line-height: var(--lh-fig); letter-spacing: -.01em; color: var(--fg); white-space: nowrap;
}
.ov-fig.clear { color: var(--live); }
.ov-fig.tight { color: var(--signal-text); }
.ov-fig.breached { color: var(--warn); }
.ov-fig.dim { color: var(--fg-3); }
.ov-sub { font-size: var(--t-meta); line-height: var(--lh-meta); color: var(--fg-3); }
.ov-sub.breached { color: var(--warn); }
.ov-sub.clear { color: var(--live); }
.ov-sub a.term { color: inherit; }
.coef-fig { font-family: var(--display); font-weight: 700; color: var(--signal-text); }
/* the line under the strip while finality is stalled */
.ov + .board-note { margin: 0; border: 1px solid var(--line-strong); border-top: 0; background: var(--bg-raised); }
.board-note a { font-family: var(--mono); white-space: nowrap; }

/* a panel: one hairline, a head with its eyebrow, the body */
.box { margin-top: var(--sp-4); background: var(--bg-raised); border: 1px solid var(--line-strong); min-width: 0; }
.box-head {
  position: relative; display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-4); padding: var(--sp-3) var(--sp-5); border-bottom: 1px solid var(--line-strong);
}
.box-head h2, .box-head h3 { margin: 0; }
.box-head .tip-wrap { position: static; }
.box-sub { font-size: var(--t-meta); line-height: var(--lh-meta); color: var(--fg-3); }
.box-fig { margin-left: auto; font-family: var(--mono); font-size: var(--t-meta); color: var(--fg-2); white-space: nowrap; }
.box-fig b { color: var(--fg); font-weight: 500; }
.box-body { padding: var(--sp-4) var(--sp-5); }
.box-foot {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4);
  padding: var(--sp-2) var(--sp-5); font-family: var(--mono); font-size: var(--t-eyebrow); color: var(--fg-3);
}
.box-grid {
  margin-top: var(--sp-4); display: grid; gap: var(--sp-4); align-items: start;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 540px), 1fr));
}
.box-grid > .box { margin-top: 0; }

/* `level`: a band of CHART panels, every one the same size. The charts are
   drawn at one height (finalizer.js CHART_H) and the row tracks are equal, so
   what a head or a note line adds is taken by the chart, which centres in the
   space, rather than showing as a ragged edge under a legend. A band of lists
   is not level — their lengths are the reading, and stretching one leaves a
   hole above its fold. */
.box-grid.level { align-items: stretch; grid-auto-rows: 1fr; }
.box-grid.level > .box { display: flex; flex-direction: column; }
.box-grid.level > .box > .box-body { flex: 1; display: flex; flex-direction: column; }
.box-grid.level > .box > .box-body > .chart-fill { flex: 1; display: flex; align-items: center; }
.box-grid.level > .box > .box-body > .chart-fill > svg { flex: 1; min-width: 0; }
.card-link { margin-left: auto; font-family: var(--mono); font-size: var(--t-meta); white-space: nowrap; }

/* the network page's three cards */
.cards {
  margin-top: var(--sp-4); display: grid; gap: var(--sp-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
}
.card {
  display: flex; flex-direction: column; gap: var(--sp-3); min-width: 0;
  padding: var(--sp-4) var(--sp-5) var(--sp-5); background: var(--bg-raised); border: 1px solid var(--line-strong);
}
.card-head { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-1) var(--sp-2); }
.card-head h2 { margin: 0; }
.card-head .figchip + .card-link, .card-head h2 + .card-link { margin-left: auto; }
.card-yield { margin-left: auto; font-size: var(--t-meta); line-height: var(--lh-meta); color: var(--fg-2); text-align: right; }
.card-yield b { font-family: var(--mono); font-weight: 500; color: var(--live); }
.card-yield a.term { color: inherit; }
.card-fig { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0 var(--sp-3); font-size: var(--t-meta); line-height: var(--lh-meta); color: var(--fg-2); }
.card-fig .big {
  font-family: var(--mono); font-size: var(--t-fig); font-weight: 500;
  line-height: var(--lh-fig); letter-spacing: -.02em; color: var(--fg);
}
.card-fig .big.coef-fig { font-family: var(--display); font-weight: 700; color: var(--signal-text); }
.card-fig .big.clear { color: var(--live); }
.card-scale {
  position: relative; display: flex; justify-content: space-between; gap: var(--sp-3);
  font-family: var(--mono); font-size: var(--t-eyebrow); letter-spacing: .02em; color: var(--fg-3);
}
.card-foot {
  margin: auto 0 0; padding-top: var(--sp-2); border-top: 1px solid var(--line);
  font-size: var(--t-meta); line-height: var(--lh-meta); color: var(--fg-2);
}
.card-foot:empty { display: none; }
.card-foot strong { color: var(--fg); font-weight: 600; }
.card-acts { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2) var(--sp-3); }
.card-acts button {
  display: inline-flex; align-items: center; height: 38px; padding: 0 var(--sp-3);
  border: 1px solid var(--line-strong); background: transparent; color: var(--fg-2);
  font-family: var(--mono); font-size: var(--t-meta); letter-spacing: .06em; border-radius: var(--r-1);
}
.card-acts button:hover,
.card-acts button:active { border-color: var(--signal); color: var(--signal-text); background: transparent; }

/* the stake of every finalizer as one bar, the largest N in gold, a third ruled */
.segbar { position: relative; display: flex; height: 12px; background: var(--bg-sunken); }
.segbar i { display: block; flex: none; height: 100%; background: var(--bar-2); box-shadow: inset -1px 0 0 var(--bg-raised); }
.segbar i.top { background: var(--signal-text); }
.segbar i.tail { background: var(--bar-3); box-shadow: none; }
.segbar u { position: absolute; top: -3px; bottom: -3px; width: 2px; margin-left: -1px; background: var(--fg); }

/* Staking Day: the open blocks filled, now ruled, the close under its tick */
.daybar { display: flex; flex-direction: column; gap: var(--sp-2); }
.daybar .wbar { display: block; flex: none; height: 12px; border: 0; }
.daybar .wbar i { inset: 0 auto 0 0; background: var(--live); border: 0; }
.daybar .wbar i.closed { background: var(--bar-3); }
.daybar .card-scale > span:nth-child(2) { position: absolute; left: var(--at, 50%); transform: translateX(-50%); }
.daybar .wopen { color: var(--live); }

/* the suggestion inside its card */
.card .sug { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; padding: 0; }
.card .sug-icon svg { display: block; }
.card .sug-id { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; }
.sug-key { font-family: var(--mono); font-size: var(--t-body); color: var(--fg); overflow-wrap: anywhere; }
.sug-key.named { font-family: var(--sans); font-weight: 600; }
.sug-chips { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2); }
.sug-power { font-family: var(--mono); font-size: var(--t-meta); color: var(--fg-3); }
.card .se-icon { width: 40px; height: 40px; }
.card .se-title { font-family: var(--sans); font-size: var(--t-body); font-weight: 400; line-height: var(--lh-meta); letter-spacing: 0; }
.card-acts .sug-go, .card-acts .se-go { padding: 0 var(--sp-4); }

/* the finalizer table: # · finalizer · stake · voting power · uptime · 30 days ·
   status. Scoped to the board, so the system's --grid-row stays as pulled. The
   finalizer column is a short key and gives way; the status column holds its
   longest sub-line, "last connected 10h 26m", whole (180px). */
#board { --grid-row: 40px minmax(140px,.9fr) 96px minmax(110px,1fr) 72px 90px 180px; }
.tablepanel { margin-top: var(--sp-4); border-color: var(--line-strong); }
.board-head .count { font-family: var(--mono); font-size: var(--t-meta); color: var(--fg-3); }
.board-head .search { margin-left: auto; }
.board-head .card-link { margin-left: 0; }
.phone-sort { display: none; }
.srow { min-height: 46px; padding: var(--sp-2) var(--sp-5); }
.srow.head {
  position: static; min-height: 38px; padding: 0 var(--sp-5); background: var(--bg-inset);
  letter-spacing: .09em;
}
.sorthead {
  position: relative; border: 0; border-radius: 0; background: none; padding: 0; text-align: left;
  font-family: var(--mono); font-size: var(--t-eyebrow); letter-spacing: .09em; text-transform: uppercase;
  line-height: var(--lh-meta); color: var(--fg-3); white-space: nowrap;
}
.sorthead.r { text-align: right; }
.sorthead.on { color: var(--fg); background: none; border: 0; }
.sorthead:hover,
.sorthead:active { background: none; color: var(--signal-text); }
.srow .uptcell {
  display: block; text-align: right; font-family: var(--mono); font-size: var(--t-body); color: var(--fg);
}
.srow .uptcell.ok { color: var(--live); }
.srow .uptcell.warn { color: var(--signal-text); }
.srow .uptcell.none { color: var(--fg-3); }
.srow .sparkcell { display: block; min-width: 0; }
.srow .rowmeta { display: none; }
.srow.top .sharebar i { background: var(--signal-text); }
.srow .sharebar { border: 0; }
.upthead { text-align: right; }
/* where the ranking crosses a third of all stake: said once, between the rows */
.nband {
  position: relative; display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-1) var(--sp-3);
  min-height: var(--tap); padding: var(--sp-2) var(--sp-5);
  background: var(--signal-bg); border-top: 1px solid var(--line-signal); border-bottom: 1px solid var(--line-signal);
}
.nband .eyebrow { color: var(--signal-text); }
.nband-say { flex: 1 1 280px; font-size: var(--t-meta); line-height: var(--lh-meta); color: var(--fg-2); }
.nband .tip-wrap { position: static; }
.rd-votes .rd-out { margin-left: auto; padding: 0; border: 0; background: none; }
.rd-votes .rd-strip { flex: 1 1 300px; }

/* the history page: the range control under the strip, the stall table, the
   range in four figures */
.range-head { margin-top: var(--sp-4); display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); }
.range-head h2 { margin: 0; }
.box .ptrace { margin-top: 0; }
.box .strip-legend { padding: var(--sp-2) 0 0; }
.box .bflow-list { border-top: 0; }
.box > .bflow-empty:first-child { border-top: 0; }
.box-foot .sw { width: 8px; height: 8px; display: inline-block; margin-right: 6px; background: var(--bar-1); }
.box-foot .sw.out { background: var(--bar-3); }
.box-foot a { font-size: var(--t-meta); }
.box > .fold.more { border-top: 1px solid var(--line); border-bottom: 0; justify-content: center; }
.stall-table .bflow-empty { border-top: 0; }
.st-row {
  display: grid; grid-template-columns: 90px 76px minmax(0, 1fr); gap: var(--sp-3); align-items: center;
  min-height: var(--tap); padding: 0 var(--sp-5); border-bottom: 1px solid var(--line);
  font-family: var(--mono); font-size: var(--t-meta); color: var(--fg-2);
}
.st-row b { font-size: var(--t-body); font-weight: 400; color: var(--fg); }
.st-row.open b { color: var(--warn); }
.st-row span:last-child { color: var(--fg-3); }
.st-row.st-head {
  min-height: 0; padding-top: var(--sp-2); padding-bottom: var(--sp-2); background: var(--bg-inset);
  font-size: var(--t-eyebrow); letter-spacing: .09em; text-transform: uppercase; color: var(--fg-3);
}
.facts-band {
  margin-top: var(--sp-4); display: grid; gap: 1px; background: var(--line-strong); border: 1px solid var(--line-strong);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
}
.fact { display: flex; flex-direction: column; gap: var(--sp-1); padding: var(--sp-3) var(--sp-5); background: var(--bg-raised); min-width: 0; }
.fact b { font-family: var(--mono); font-size: var(--t-title); font-weight: 400; line-height: var(--lh-title); color: var(--fg); }
.fact small { font-size: var(--t-meta); line-height: var(--lh-meta); color: var(--fg-3); }
.fact small:empty { display: none; }
@media (max-width: 720px) {
  .st-row { padding-left: var(--sp-3); padding-right: var(--sp-3); grid-template-columns: 70px 56px minmax(0, 1fr); }
  .fact { padding: var(--sp-2) var(--sp-3); }
}

/* the finalizer page: the way back, who it is, its status */
.crumb {
  margin-top: var(--sp-4); display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--sp-1) var(--sp-3);
  font-family: var(--mono); font-size: var(--t-meta); color: var(--fg-3);
}
.fid { padding: var(--sp-4) var(--sp-5); margin-top: var(--sp-3); }
.fid-row { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-3) var(--sp-4); }
.fid-icon svg { display: block; }
.fid-who { flex: 1 1 280px; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-1); }
.fid-who h2 {
  font-family: var(--mono); font-size: var(--t-title); font-weight: 500; letter-spacing: 0;
  line-height: var(--lh-title); color: var(--fg); overflow-wrap: anywhere;
}
.fid-who h2.named { font-family: var(--sans); font-weight: 600; }
.fid-who .key { font-size: var(--t-meta); line-height: var(--lh-meta); color: var(--fg-3); word-break: break-all; }
.fid-status { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.fid-status .nd { font-family: var(--mono); font-size: var(--row-chip); line-height: var(--lh-meta); color: var(--fg-3); white-space: nowrap; }
.fid-note { margin: var(--sp-3) 0 0; font-size: var(--t-meta); line-height: var(--lh-meta); color: var(--fg-2); }
.fid-ident { margin-top: var(--sp-3); padding-top: var(--sp-3); border-top: 1px solid var(--line); }
.fid-ident .ident-desc { margin-top: 0; }
.fid-links { margin-top: var(--sp-2); display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); }
.fid-links .linkchips { margin-top: 0; }
.box-body.btrace { padding: var(--sp-4) var(--sp-5); border-top: 0; }
.chart-note { margin: var(--sp-2) 0 0; font-size: var(--t-meta); line-height: var(--lh-meta); color: var(--fg-2); }
.chart-note strong { color: var(--fg); font-weight: 600; }
.box .chart-legend .push { margin-left: auto; }
.fid + .ov, .removed-banner + .fid { margin-top: var(--sp-4); }
@media (max-width: 720px) {
  .fid { padding: var(--sp-3); }
  .fid-status { flex-direction: row; align-items: center; gap: var(--sp-2); }
}

/* the methodology page: contents in a rail beside the article, which stays at
   the prose measure */
.wrap.docs { max-width: 1200px; }
.docs-grid { margin-top: var(--sp-5); display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: var(--sp-8); align-items: start; }
.docs-grid > article { max-width: 820px; min-width: 0; }
.docs-grid > article > .lede { margin-top: 0; }
.docs-grid > article > h2:first-of-type { margin-top: var(--sp-6); }
.prose .docs-grid .toc {
  position: sticky; top: var(--sp-4); margin: 0; padding: 0; border: 0; border-top: 1px solid var(--line-strong);
  background: none; display: flex; flex-direction: column; gap: 0;
}
.docs-grid .toc .eyebrow { padding: var(--sp-3) 0 var(--sp-2); }
.prose .docs-grid .toc a { font-family: var(--mono); padding: 6px 0; }
@media (max-width: 900px) {
  .docs-grid { grid-template-columns: minmax(0, 1fr); gap: var(--sp-4); }
  .prose .docs-grid .toc {
    position: static; display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 0 var(--sp-6);
  }
  .docs-grid .toc .eyebrow { grid-column: 1 / -1; }
}

@media (min-width: 901px) {
  #board.nospark { --grid-row: 40px minmax(140px,.9fr) 96px minmax(110px,1fr) 72px 180px; }
  #board.nospark .sparkcell { display: none; }
}
@media (max-width: 900px) {
  #board { --grid-row: 36px minmax(0,1fr) 96px 72px 176px; }
  .srow .sharecell, .srow .sparkcell { display: none; }
  .srow .stakecell { display: block; }
}
/* the phone: two cells a row in the strip, and every row two lines — key
   over stake and voting power, uptime over status — with two sort buttons
   in place of the column heads a finger cannot hit */
@media (max-width: 720px) {
  .ov-cell { flex-basis: calc(50% - 1px); padding: var(--sp-2) var(--sp-3); }
  .ov .ov-wide { display: none; }
  .ov-fig { font-size: var(--t-body); }
  .box-head, .box-body, .box-foot, .nband { padding-left: var(--sp-3); padding-right: var(--sp-3); }
  .phone-sort { display: inline-flex; }
  .board-head .search { margin-left: 0; flex: 1 1 160px; }
  .board-head .search input { width: 100%; }
  #board .srow.head { display: none; }
  #board .srow {
    grid-template-columns: 24px minmax(0,1fr) auto;
    grid-template-areas: "rank name upt" "rank name stat";
    gap: var(--sp-1) var(--sp-3); min-height: 52px; padding: var(--sp-2) var(--sp-3);
  }
  #board .srow .rank { grid-area: rank; }
  #board .srow .namecell { grid-area: name; display: flex; flex-direction: column; gap: 2px; }
  #board .srow .uptcell { grid-area: upt; }
  #board .srow .statuscell { grid-area: stat; align-items: flex-end; padding-left: 0; border-left: 0; min-height: 0; }
  #board .srow .stakecell, #board .srow .sharecell, #board .srow .sparkcell { display: none; }
  #board .srow .rowmeta { display: block; font-size: var(--t-meta); line-height: var(--lh-meta); color: var(--fg-3); }
}

/* ── Touch: 44 is the target, not the glyph ──────────────────────────────────
   Pulled with design-system/tokens/space.css (--tap, --tap-move) and its
   "Touch & the phone" guideline. A dense board is read on a phone as often as
   on a desk, and two things follow. A control's TARGET is --tap however small
   its glyph: the controls below are declared between 18 and 38px, so
   each carries a centred pseudo-element that holds the hit box while the glyph
   and the layout stay exactly where they were. And a press is ANSWERED —
   every :hover above now has an :active in the same tones, because a phone has
   no hover to fall back on. Nothing here changes what the page looks like. */
.tip-btn, .copybtn, .rd-copy, .card-acts button, .sorthead,
.fold .toggle, .linkchips a, .sug-go, .se-go,
nav.pages a, .netsel a, #theme-toggle, .prose .toc a {
  position: relative;
}
.tip-btn::after, .copybtn::after, .rd-copy::after,
.card-acts button::after, .sorthead::after,
.fold .toggle::after,
.linkchips a::after, .sug-go::after, .se-go::after, nav.pages a::after,
.netsel a::after, #theme-toggle::after, .prose .toc a::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 100%; height: 100%;
  min-width: var(--tap); min-height: var(--tap);
}

/* The segmented control is the exception the guideline names: its container
   clips, so slop would be cut off. It grows instead, and only where a hand is
   doing the pressing. --tap-move is applied on the pointer, never on width:
   a narrow window on a desk is still a mouse. */
@media (pointer: coarse) {
  .scrub-hint .fine { display: none; }
  .scrub-hint .coarse { display: inline; }
  .segmented button { height: var(--tap); }
  .tip-btn::after, .copybtn::after, .rd-copy::after,
  .card-acts button::after, .sorthead::after,
  .fold .toggle::after,
  .linkchips a::after, .sug-go::after, .se-go::after, nav.pages a::after,
  .netsel a::after, #theme-toggle::after, .prose .toc a::after {
    min-width: var(--tap-move); min-height: var(--tap-move);
  }
}
