/* ============================================================================
   fable — the sheet
   ----------------------------------------------------------------------------
   One column, printed top to bottom, like a machine's journal coming off a
   roll. Hairline rules between sections, a fixed left gutter for timestamps,
   and no boxes: a panelled dashboard is a different product's shape.

   Restraint is the brief, not a style option. One mark, small lowercase type,
   hairlines, a lot of empty space, and an accent pulled well off neon.
   ==========================================================================*/

:root {
  --bg:        #08080a;
  --ink:       #e6e2d9;
  --dim:       rgba(230, 226, 217, .46);
  --faint:     rgba(230, 226, 217, .17);
  --ghost:     rgba(230, 226, 217, .07);
  /* The accent IS the mascot's colour, sampled from it. The site and the
     character have to read as one system, not as a page with a logo on it. */
  --clay:      #c8765c;
  --clay-dim:  rgba(200, 118, 92, .5);
  /* Down and sell go COOL against the warm accent. A second warm tone next
     to terracotta reads as muddy rather than as the opposite of it, and the
     warm/cool split is legible at a glance without relying on hue alone. */
  --cool:      #6f8496;
  --cool-dim:  rgba(111, 132, 150, .45);
  --red:       #a3564a;      /* reserved for warnings, not for price */
  --gut:       78px;      /* timestamp gutter */
  --mono: "DejaVu Sans Mono", Consolas, "Cascadia Mono", ui-monospace,
          SFMono-Regular, Menlo, monospace;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { background: var(--bg); }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
::selection { background: var(--clay); color: var(--bg); }
a { color: var(--clay); text-decoration: none; }
a:hover { text-decoration: underline; }

#sheet {
  max-width: 940px;
  margin: 0 auto;
  padding: 0 26px 90px;
}

/* Sections are panels with a hairline border and a tab notched into the top
   edge. This is the terminal chrome the rebuild threw out along with the
   dashboard: the boxes are what make it read as an instrument rather than as
   an article. The single-column printout inside them stays. */
.rule-top {
  position: relative;
  border: 1px solid var(--faint);
  padding: 30px 24px 24px;
  margin-bottom: 18px;
}
/* The tab sits ON the border, with a background patch punching a gap in the
   rule behind it. */
.rule-top > .blk-head {
  position: absolute; top: -9px; left: 16px;
  margin: 0; background: var(--bg); padding: 0 9px;
}
#ident, #figures, #foot { padding-top: 24px; }

/* ------------------------------------------------------------- masthead -- */
#masthead {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 30px; padding: 46px 0 30px; flex-wrap: wrap;
}
.mh-id { display: flex; align-items: center; gap: 18px; }
/* line-height just under 1 so the half-block rows overlap by a hair. At
   exactly 1 the glyph is a shade shorter than its line box and thin seams
   show through the body at most zoom levels. */
#mascot {
  font-family: var(--mono); font-size: 8px; line-height: .92;
  /* Negative tracking closes the horizontal seams the same way the sub-1
     line-height closes the vertical ones: the block glyph is a shade
     narrower than its advance, so neighbours don't quite abut. */
  letter-spacing: -.04em;
  color: var(--clay); white-space: pre; margin: 0;
  -webkit-user-select: none; user-select: none;
}
#masthead h1 {
  font-size: 30px; font-weight: 400; letter-spacing: -.03em; line-height: 1;
  white-space: nowrap;
}
@media (max-width: 560px) { #masthead h1 { font-size: 23px; } }
.mh-sub { color: var(--dim); font-size: 12px; line-height: 1.7; margin-top: 14px; }
.mh-right { display: flex; flex-direction: column; align-items: flex-end; gap: 12px; }
.mh-links { display: flex; gap: 8px; }
.mh-links a, .mh-links button {
  font: inherit; font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--dim); background: none; border: 1px solid var(--faint);
  padding: 4px 11px; cursor: pointer; border-radius: 2px;
}
.mh-links a:hover, .mh-links button:hover { color: var(--clay); border-color: var(--clay-dim); text-decoration: none; }
.mh-links button.ok { color: var(--clay); border-color: var(--clay-dim); }

/* ------------------------------------------------------------- identity -- */
.id-row { display: flex; gap: 14px; align-items: baseline; padding: 3px 0; flex-wrap: wrap; }
.id-k {
  width: var(--gut); flex: 0 0 var(--gut);
  font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--dim);
}
.id-v { word-break: break-all; }
.id-v.unset { color: var(--dim); }
.id-link { font-size: 11px; }

/* -------------------------------------------------------------- figures -- */
#figures { display: flex; flex-wrap: wrap; gap: 34px 46px; }
.fig { display: flex; flex-direction: column; gap: 3px; }
.fig-k { font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); }
.fig-v { font-size: 20px; line-height: 1.15; }
.fig-v.muted { color: var(--dim); font-size: 20px; }

/* ---------------------------------------------------------- block heads -- */
.blk-head {
  display: flex; align-items: baseline; gap: 14px;
  margin-bottom: 16px;
}
.blk-t { font-size: 11px; letter-spacing: .22em; text-transform: uppercase; color: var(--ink); }
.blk-n { font-size: 10px; letter-spacing: .1em; color: var(--dim); }
.blk-foot { font-size: 11px; color: var(--dim); margin-top: 14px; max-width: 68ch; }

/* ---------------------------------------------------------------- chart -- */
.chart-wrap { display: flex; gap: 14px; align-items: stretch; }
/* line-height 1 and a hair of negative tracking so the filled area is solid.
   At the defaults the block glyph is fractionally smaller than its cell and
   pale seams run through the fill in both directions. */
#chart {
  flex: 1; white-space: pre; overflow: hidden;
  font-family: var(--mono); font-size: 13px; line-height: .93;
  letter-spacing: -.02em;
  color: var(--clay);
}
#chart.up { color: var(--clay); }
#chart.down { color: var(--cool); }
#chart-axis {
  width: 92px; flex: 0 0 92px;
  display: flex; flex-direction: column; justify-content: space-between;
  text-align: right; font-size: 10px; color: var(--dim); padding: 1px 0;
}

/* ------------------------------------------------------------------ log --
   The gutter is the point: a fixed timestamp column down the left is what
   makes this read as a printed record rather than a feed of cards. */
.entry { display: flex; gap: 0; padding: 7px 0; align-items: flex-start; }
.entry + .entry { border-top: 1px solid var(--ghost); }
.e-time {
  width: var(--gut); flex: 0 0 var(--gut);
  font-size: 11px; color: var(--dim); padding-top: 1px;
}
.e-mark {
  width: 20px; flex: 0 0 20px; color: var(--dim); text-align: center;
  padding-top: 1px;
}
.e-body { flex: 1; max-width: 74ch; }
/* A named-wallet call is the line people screenshot. Give it the accent and
   nothing else gets it. */
.entry[data-kind="kol"] .e-mark { color: var(--clay); }
.entry[data-kind="kol"] .e-body { color: var(--ink); }
.entry[data-kind="milestone"] .e-mark { color: var(--clay); }
.entry[data-kind="sys"] .e-body,
.entry[data-kind="thought"] .e-body { color: var(--dim); }
.entry[data-kind="trade"] .e-body { color: var(--dim); }

/* ------------------------------------------------------- who is in/tape -- */
.row {
  display: grid; grid-template-columns: 1fr auto auto; gap: 16px;
  align-items: baseline; padding: 6px 0; font-size: 12px;
}
.row + .row { border-top: 1px solid var(--ghost); }
#tape .row { grid-template-columns: 44px 1fr auto auto; }
.r-side { font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--dim); }
.row.buy  .r-side { color: var(--clay); }
.row.sell .r-side { color: var(--cool); }
.r-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.r-sub, .r-when { color: var(--dim); font-size: 11px; }
.row.holding .r-sub { color: var(--clay); }

/* Empty and offline are real states and must read as sentences, not as a
   widget that failed to load. */
.empty { color: var(--dim); font-size: 12px; max-width: 66ch; line-height: 1.7; }

/* ------------------------------------------------------------- document -- */
#statement {
  white-space: pre-wrap; font-family: var(--mono); font-size: 12px;
  line-height: 1.8; color: var(--dim); max-width: 68ch;
}

#foot p { color: var(--dim); font-size: 11px; max-width: 72ch; margin-bottom: 9px; }

/* ---- tabs ----
   Terminal chips, not a nav bar. The active one is the only thing that gets
   the accent, so which panel you are on is readable at a glance. */
#tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 18px; }
.tab {
  font: inherit; font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--dim); background: none; border: 1px solid var(--faint);
  padding: 6px 13px; cursor: pointer; border-radius: 2px;
  display: inline-flex; align-items: baseline; gap: 7px;
}
.tab:hover { color: var(--ink); border-color: var(--clay-dim); }
.tab.on { color: var(--clay); border-color: var(--clay-dim); background: rgba(200,118,92,.07); }
.tab-n { font-size: 9px; opacity: .7; letter-spacing: 0; }
/* Panels not on the active tab are removed from layout, not just hidden, so
   the fixed statusbar clearance stays correct. */
[data-panel] { display: none; }
[data-panel].on { display: block; }
/* #figures carries an ID rule setting display:flex, which outranks the
   attribute selector above and left it visible on every tab. Hide it with
   matching specificity rather than by reordering, which would break the
   moment someone moves a rule. */
#figures[data-panel]:not(.on) { display: none; }
#figures[data-panel].on { display: flex; }

/* ---- log filters ---- */
#log-filters { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.chip {
  font: inherit; font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--dim); background: none; border: 1px solid var(--faint);
  padding: 3px 10px; cursor: pointer; border-radius: 2px;
}
.chip:hover { color: var(--ink); }
.chip.on { color: var(--clay); border-color: var(--clay-dim); }

/* ---- market watch ---- */
.mw-row {
  display: grid; grid-template-columns: 1fr auto auto auto; gap: 16px;
  align-items: baseline; padding: 8px 0; font-size: 12px;
}
.mw-row + .mw-row { border-top: 1px solid var(--ghost); }
.mw-sym { color: var(--ink); }
.mw-k { color: var(--dim); font-size: 11px; }
.mw-age { color: var(--dim); font-size: 11px; }
@media (max-width: 720px) {
  .mw-row { grid-template-columns: 1fr auto auto; }
  .mw-row .mw-liq { display: none; }
}

/* ---- the paper book ----
   The "this is paper" fact is carried as a plain line of body copy, not as a
   bordered warning slab. Same information, but a page that leads with a
   caution box about its own feature reads as an apology for it. */
.pb-sum { display: flex; flex-wrap: wrap; gap: 26px 40px; margin-bottom: 20px; }
.pb-sub { font-size: 10px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--dim); margin: 20px 0 8px; }
.pb-row {
  display: grid; grid-template-columns: 1fr auto auto auto; gap: 16px;
  align-items: baseline; padding: 7px 0; font-size: 12px;
}
.pb-row + .pb-row { border-top: 1px solid var(--ghost); }
.pb-sym { color: var(--ink); }
.pb-k { color: var(--dim); font-size: 11px; }
.pb-pnl.up { color: var(--clay); }
.pb-pnl.down { color: var(--cool); }
@media (max-width: 720px) { .pb-row { grid-template-columns: 1fr auto auto; } .pb-why { display: none; } }

/* ---- demo banner ----
   Deliberately the loudest thing on the page. Demo data is real data off the
   chain, but it is somebody else's coin, and the one failure that would
   matter here is a viewer thinking these are fable's numbers. */
#demo-bar {
  border: 1px solid var(--clay-dim);
  background: rgba(200, 118, 92, .07);
  padding: 12px 16px; margin-bottom: 18px;
  font-size: 12px; line-height: 1.65; color: var(--ink);
}
#demo-bar b { color: var(--clay); font-weight: 400; letter-spacing: .14em; text-transform: uppercase; }
#demo-bar span { color: var(--dim); }
#demo-bar code { color: var(--ink); word-break: break-all; }

/* ============================ terminal chrome ============================
   Boot, ticker and statusbar, carried over from the original terminal.
   These are what make the page feel like a running machine; the printout
   underneath is what makes it readable. */

/* ---- cold boot ---- */
#boot {
  position: fixed; inset: 0; z-index: 100; background: var(--bg);
  padding: 9vh 8vw; cursor: pointer; overflow: hidden;
}
#boot-lines { white-space: pre-wrap; font-size: 14px; line-height: 1.75; color: var(--ink); }
#boot-lines .dim { color: var(--dim); }
#boot-lines .a { color: var(--clay); }
#boot-skip {
  position: fixed; bottom: 7vh; left: 8vw;
  font-size: 10px; letter-spacing: .18em; text-transform: uppercase; color: var(--dim);
}

/* ---- ticker ---- */
#ticker-wrap {
  border-top: 1px solid var(--faint); border-bottom: 1px solid var(--faint);
  overflow: hidden; margin-bottom: 18px; padding: 5px 0;
}
#ticker { display: flex; width: max-content; animation: tick 64s linear infinite; }
#ticker span { white-space: pre; font-size: 11px; color: var(--dim); padding-right: 3ch; }
#ticker b { color: var(--ink); font-weight: 400; }
#ticker .a { color: var(--clay); }
/* Two identical copies scroll past, so -50% lands exactly where 0 started
   and the loop has no visible seam. */
@keyframes tick { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { #ticker { animation: none; } }

/* ---- statusbar ---- */
#statusbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  display: flex; gap: 22px; flex-wrap: wrap;
  background: var(--bg); border-top: 1px solid var(--faint);
  padding: 7px 26px; font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--dim);
}
#statusbar b { color: var(--ink); font-weight: 400; }
#statusbar b.warn { color: var(--red); }
#statusbar b.ok { color: var(--clay); }
@media (max-width: 720px) {
  #statusbar { gap: 12px; padding: 6px 16px; font-size: 9px; }
  #boot-lines { font-size: 11px; }
}

/* ------------------------------------------------------------ responsive --
   Recomputed by the browser at every width, and the chart re-renders on
   resize rather than being measured once at load. */
@media (max-width: 720px) {
  :root { --gut: 58px; }
  /* The statusbar is fixed and wraps to two rows at this width, so the sheet
     needs clearance or the last line sits under it. */
  #sheet { padding: 0 16px 104px; }
  .rule-top { padding: 28px 14px 20px; }
  #masthead { padding: 32px 0 22px; }
  #masthead h1 { font-size: 25px; }
  .mh-right { align-items: flex-start; }
  #figures { gap: 22px 30px; }
  .fig-v { font-size: 17px; }
  #chart { font-size: 9px; }
  #chart-axis { width: 74px; flex-basis: 74px; }
  .row { grid-template-columns: 1fr auto; }
  #tape .row { grid-template-columns: 40px 1fr auto; }
  .r-when { display: none; }
}


/* ============================ interactivity ============================
   Everything below moves, and all of it is driven by real state: flashes
   fire on measured changes, the pulse is the decoded tape, the caret types
   a line the engine actually said. One media query at the end kills the
   lot for anyone who asked motion to stop. */

/* value flashes: the figure briefly takes the direction's colour, then
   settles back to ink. */
@keyframes fup { from { color: var(--clay); } }
@keyframes fdn { from { color: var(--cool); } }
.flash-up { animation: fup .9s ease-out; }
.flash-down { animation: fdn .9s ease-out; }

/* panel entrance on tab switch: 3px of lift, nothing theatrical */
@keyframes panelIn { from { opacity: 0; transform: translateY(3px); } }
[data-panel].on { animation: panelIn .16s ease-out; }

/* rows that open their own on-chain proof */
.row[data-sig], .row[data-wallet], .mw-row[data-mint], .pb-row[data-mint] { cursor: pointer; }
.row[data-sig]:hover, .row[data-wallet]:hover,
.mw-row[data-mint]:hover, .pb-row[data-mint]:hover,
.entry:hover { background: rgba(230, 226, 217, .025); }

/* the caret on the line currently being typed */
.e-body.typing::after { content: '▌'; color: var(--clay); }

/* the pulse: last ~40 trades, height by size, colour by side */
#pulse { display: flex; align-items: flex-end; gap: 3px; height: 16px; margin-top: 14px; }
#pulse .pu { width: 4px; border-radius: 1px 1px 0 0; background: var(--clay); opacity: .85; transform-origin: bottom; }
#pulse .pu.s { background: var(--cool); }
@keyframes pop { from { transform: scaleY(.2); } }
#pulse .pu.pop { animation: pop .3s ease-out; }

/* chart crosshair */
.chart-wrap { position: relative; }
#chart-cross { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--clay-dim); pointer-events: none; }
#chart-tip { position: absolute; background: var(--bg); border: 1px solid var(--faint);
  padding: 2px 8px; font-size: 10px; white-space: nowrap; pointer-events: none; color: var(--ink); }

/* paper meter: where an open position sits between stop and target. The
   fixed tick is entry (zero), at (0+35)/95 of the track. */
.pb-meter { display: inline-block; vertical-align: middle; margin-left: 12px;
  width: 72px; height: 3px; background: var(--ghost); position: relative; }
.pb-meter::before { content: ''; position: absolute; left: 36.8%; top: -2px; bottom: -2px;
  width: 1px; background: var(--faint); }
.pb-meter i { position: absolute; top: -1px; width: 5px; height: 5px; border-radius: 50%;
  background: var(--clay); margin-left: -2px; }
.pb-meter i.down { background: var(--cool); }

/* the shell */
#shell { position: fixed; left: 0; right: 0; bottom: 32px; z-index: 50;
  background: rgba(8, 8, 10, .98); border-top: 1px solid var(--clay-dim);
  padding: 12px 26px; max-height: 42vh; display: flex; flex-direction: column; }
#shell[hidden] { display: none; }
#shell-out { overflow-y: auto; font-size: 12px; line-height: 1.7; margin-bottom: 8px; }
.s-line { white-space: pre-wrap; }
.s-dim { color: var(--dim); }
.s-acc { color: var(--clay); }
#shell-row { display: flex; gap: 8px; align-items: baseline; }
#shell-ps { color: var(--clay); font-size: 12px; }
#shell-in { flex: 1; background: none; border: none; outline: none;
  color: var(--ink); font: inherit; font-size: 12px; caret-color: var(--clay); }
.sb-hint { cursor: pointer; }
.sb-hint:hover { color: var(--ink); }
@media (max-width: 720px) { #shell { bottom: 55px; padding: 10px 16px; } }

/* keyboard users get a visible focus ring; mouse users never see it */
.tab:focus-visible, .chip:focus-visible,
.mh-links a:focus-visible, .mh-links button:focus-visible { outline: 1px solid var(--clay-dim); outline-offset: 2px; }

/* one switch kills every animation on the page */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}


/* ========================= boot + screen effects =========================
   The boot is the first thing anyone sees, so it gets the most deliberate
   treatment on the page. Everything here is decoration and all of it is
   switched off by the reduced-motion query at the bottom of this file. */

#boot { display: flex; flex-direction: column; justify-content: center; }
/* An ID rule setting display OUTRANKS the UA stylesheet's [hidden]{display:none},
   so without this the overlay never hides and covers the whole site forever.
   Same trap as #figures on the tab panels. Any element that is toggled with
   [hidden] AND given a display by an ID rule needs this pair. */
#boot[hidden] { display: none; }
#boot-inner { max-width: 640px; margin: 0 auto; width: 100%; }
#boot-art {
  font-family: var(--mono); font-size: 9px; line-height: .92;
  letter-spacing: -.04em; color: var(--clay); white-space: pre;
  margin: 0 0 26px; min-height: 66px;
}
#boot-lines { font-size: 13px; line-height: 1.85; }
#boot-lines .big { font-size: 28px; letter-spacing: -.03em; line-height: 1.3; }
#boot-lines .dim { color: var(--dim); }
#boot-lines .a { color: var(--clay); }
/* A check that has come back reads as ink; one still waiting stays dim, so
   the eye can see at a glance what has actually been answered. */
#boot-lines .ck { color: var(--ink); }
#boot-lines .ck.pend { color: var(--faint); }
#boot-meter {
  font-size: 11px; line-height: 1; letter-spacing: -.05em;
  color: var(--clay-dim); margin-top: 26px; white-space: pre;
}
@keyframes blink { 50% { opacity: .25; } }
#boot-lines .blink { animation: blink 1.1s steps(1) infinite; }

/* The whole overlay fades out rather than vanishing, so the sheet underneath
   arrives instead of appearing. */
#boot.going { animation: bootOut .32s ease-in forwards; }
@keyframes bootOut { to { opacity: 0; } }

/* A single band of light crossing the panel, once every few seconds. This is
   the one purely decorative thing on the page and it earns its place by being
   almost invisible: it reads as a tube warming up, not as an effect. */
#boot::after {
  content: ''; position: absolute; left: 0; right: 0; height: 140px;
  pointer-events: none;
  background: linear-gradient(to bottom, transparent, rgba(200,118,92,.05), transparent);
  animation: sweep 4.2s linear infinite;
}
@keyframes sweep { from { top: -140px; } to { top: 100%; } }

/* ---- crt wash ----
   Two layers in one element: hairline scanlines and a corner vignette. Kept
   under 4% opacity, because the moment this is visible as an effect it stops
   reading as a screen and starts reading as a filter. */
#crt {
  position: fixed; inset: 0; z-index: 200; pointer-events: none;
  background:
    repeating-linear-gradient(
      to bottom,
      rgba(0,0,0,.13) 0px,
      rgba(0,0,0,.13) 1px,
      transparent 1px,
      transparent 4px
    ),
    radial-gradient(ellipse at center, transparent 62%, rgba(0,0,0,.38) 100%);
  opacity: .42;
  mix-blend-mode: multiply;
}

/* ---- log: a hairline in the gutter, coloured by what kind of line it is.
   Cheaper to scan than reading the marker glyph, and it makes a named-wallet
   call findable at a glance in a long log. */
.entry { position: relative; padding-left: 10px; }
.entry::before {
  content: ''; position: absolute; left: 0; top: 6px; bottom: 6px;
  width: 2px; background: transparent;
}
.entry[data-kind="kol"]::before { background: var(--clay); }
.entry[data-kind="milestone"]::before { background: var(--clay-dim); }
.entry[data-kind="market"]::before { background: var(--cool-dim); }
.entry[data-kind="paper"]::before { background: var(--faint); }

/* ---- chart: a dashed marker at the latest price, with its own label ---- */
#chart-last {
  position: absolute; right: 0; height: 1px;
  border-top: 1px dashed var(--clay-dim); pointer-events: none;
}
#chart-last span {
  position: absolute; right: 0; top: -8px; background: var(--bg);
  padding-left: 6px; font-size: 10px; color: var(--clay);
}

/* ---- tab attention: a dot on a tab whose panel gained something while you
   were looking somewhere else. Cleared the moment you open it. */
.tab .tab-dot {
  width: 5px; height: 5px; border-radius: 50%; background: var(--clay);
  display: inline-block; margin-left: 2px;
}


/* ============================== the instruments ============================
   The readouts that make this a machine rather than a page about one. Every
   value here was measured by the engine; nothing has a decorative fallback,
   which is why each of these panels has an empty state written as a sentence.

   Shared idea: a SEGMENTED gauge. The track is a repeating gradient, so a
   bar reads as discrete cells like a hardware meter instead of a rounded
   progress bar, and it still reflows to any width — which an ascii bar of a
   fixed character count does not. */
.gauge {
  position: relative; height: 12px; width: 100%;
  background: var(--ghost);
  /* the cells. 1px of background every 5px, punched over the fill too. */
  -webkit-mask-image: repeating-linear-gradient(to right, #000 0 4px, transparent 4px 5px);
  mask-image: repeating-linear-gradient(to right, #000 0 4px, transparent 4px 5px);
}
/* Eased, so the curve filling is something you can watch happen rather than a
   number that was one thing and is now another. Killed by the reduced-motion
   switch at the end of the file along with everything else. */
.gauge > i {
  position: absolute; inset: 0 auto 0 0; background: var(--clay); display: block;
  transition: width .55s cubic-bezier(.22,.61,.36,1);
}
.gauge.split > i { background: var(--clay); }
.gauge.split { background: var(--cool-dim); }
.gauge.venue > i { background: var(--faint); }

/* ---- the curve ---- */
#curve-sec .gauge { height: 18px; margin-bottom: 20px; }
.curve-figs { display: flex; flex-wrap: wrap; gap: 20px 44px; margin-bottom: 18px; }
.cfig { display: flex; flex-direction: column; gap: 2px; }
.cfig-k { font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); }
.cfig-v { font-size: 18px; line-height: 1.2; }
.cfig-s { font-size: 10px; color: var(--dim); }
.curve-line { font-size: 11px; color: var(--dim); max-width: 68ch; line-height: 1.7; margin-bottom: 14px; }
.curve-addr { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px;
  border-top: 1px solid var(--ghost); padding-top: 12px; }
.ca-k { font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); }
.ca-v { font-size: 11px; word-break: break-all; }
.ca-n { font-size: 10px; color: var(--faint); }

/* ---- pressure ---- */
#pressure { margin-top: 16px; }
.pr-row { display: grid; grid-template-columns: 62px 1fr auto; gap: 12px;
  align-items: center; padding: 4px 0; }
.pr-k { font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); }
.pr-bar .gauge { height: 8px; }
.pr-v { font-size: 11px; color: var(--dim); white-space: nowrap; }
.pr-note { font-size: 10px; color: var(--faint); margin-top: 8px; max-width: 66ch; line-height: 1.6; }

/* ---- who holds it ---- */
.hd-row { display: grid; grid-template-columns: minmax(90px, 1fr) minmax(60px, 2fr) auto;
  gap: 14px; align-items: center; padding: 5px 0; font-size: 12px; }
.hd-row + .hd-row { border-top: 1px solid var(--ghost); }
.hd-row[data-wallet] { cursor: pointer; }
.hd-row[data-wallet]:hover { background: rgba(230, 226, 217, .025); }
.hd-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hd-row.venue .hd-name { color: var(--dim); font-style: italic; }
.hd-row.named .hd-name { color: var(--clay); }
.hd-bar .gauge { height: 7px; }
.hd-pct { font-size: 11px; color: var(--dim); white-space: nowrap; }

/* ---- the decode pipeline ----
   A left rail of box glyphs, a label, a proportional track and a count. The
   rail is one character in a fixed column so the whole thing still reflows;
   an ascii diagram of fixed width would not survive 375px. */
.pl-row { display: grid; grid-template-columns: 14px minmax(0, 1fr) 64px 62px;
  gap: 10px; align-items: center; padding: 4px 0; font-size: 12px; }
.pl-g { color: var(--faint); text-align: center; }
.pl-k { color: var(--dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pl-t { height: 6px; background: var(--ghost); position: relative; }
.pl-t > i { position: absolute; inset: 0 auto 0 0; background: var(--dim); display: block; }
.pl-v { text-align: right; font-size: 11px; color: var(--dim); }
.pl-row.head { padding-top: 14px; }
.pl-row.head .pl-k { color: var(--ink); }
.pl-row.head .pl-t > i { background: var(--cool); }
.pl-row.head .pl-v { color: var(--ink); }
.pl-row.out .pl-k, .pl-row.out .pl-v { color: var(--clay); }
.pl-row.out .pl-t > i { background: var(--clay); }
.pl-row.warn .pl-k, .pl-row.warn .pl-v { color: var(--red); }
.pl-row.warn .pl-t > i { background: var(--red); }

/* ---- vitals ---- */
.vt-row { display: grid; grid-template-columns: 150px auto 1fr; gap: 16px;
  align-items: baseline; padding: 6px 0; font-size: 12px; }
.vt-row + .vt-row { border-top: 1px solid var(--ghost); }
.vt-k { font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); }
.vt-v { color: var(--ink); white-space: nowrap; }
.vt-s { font-size: 11px; color: var(--faint); }

/* ---- rpc latency ----
   Block glyphs rather than divs. This is the panel where the page shows its
   own workings, so it is drawn in the same material as the chart. */
.lt-row { display: grid; grid-template-columns: 74px auto 1fr; gap: 12px;
  align-items: baseline; font-size: 11px; line-height: 1.5; }
.lt-k { color: var(--dim); text-align: right; }
.lt-b { color: var(--clay); white-space: pre; letter-spacing: -.06em; overflow: hidden; }
.lt-d { color: var(--ghost); }
.lt-v { color: var(--dim); }
.mth-head { font-size: 10px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--dim); margin: 20px 0 6px; }
.mth { display: grid; grid-template-columns: minmax(0,1fr) auto auto auto; gap: 14px;
  padding: 4px 0; font-size: 11px; color: var(--dim); }
.mth + .mth { border-top: 1px solid var(--ghost); }
.mth-n { color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- the wire ---- */
.wr { display: grid; grid-template-columns: 62px 34px minmax(0, 1fr) auto auto;
  gap: 12px; align-items: baseline; padding: 4px 0; font-size: 11px; cursor: pointer; }
.wr + .wr { border-top: 1px solid var(--ghost); }
.wr:hover { background: rgba(230, 226, 217, .025); }
.wr-t { color: var(--faint); }
.wr-s { letter-spacing: .08em; }
.wr-s.b { color: var(--clay); }
.wr-s.s { color: var(--cool); }
.wr-h { color: var(--dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wr-w { color: var(--faint); }
.wr-u { color: var(--ink); text-align: right; }

/* ---- what i cannot see ---- */
.cn { display: grid; grid-template-columns: 170px 1fr; gap: 20px; padding: 10px 0; }
.cn + .cn { border-top: 1px solid var(--ghost); }
.cn-k { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--clay); }
.cn-v { font-size: 12px; color: var(--dim); line-height: 1.7; max-width: 64ch; }

/* ---- the carrier ----
   A 4px lamp beside the feed state. Lit only by a real notification delta. */
#sb-carrier {
  display: inline-block; width: 4px; height: 4px; border-radius: 50%;
  background: var(--faint); margin-left: 7px; vertical-align: middle;
}
#sb-carrier.lit { animation: carrier .55s ease-out; }
@keyframes carrier { 0% { background: var(--clay); } 100% { background: var(--faint); } }

/* the newest decoded line on the wire arrives rather than appearing */
@keyframes wireIn { from { opacity: 0; transform: translateX(-3px); } }
.wr.fresh { animation: wireIn .3s ease-out; }

/* ---- the sparkline under the market cap ---- */
/* An svg polyline. currentColor carries the direction, so the whole thing is
   one rule and the line matches the chart's own up/down convention. */
.fig-spark {
  display: block; margin-top: 8px; color: var(--clay); opacity: .75;
  max-width: 100%; overflow: hidden; line-height: 0;
}
.fig-spark.down { color: var(--cool); }
.fig-spark svg { display: block; max-width: 100%; }

@media (max-width: 720px) {
  .vt-row { grid-template-columns: 1fr auto; }
  .vt-s { display: none; }
  .cn { grid-template-columns: 1fr; gap: 4px; }
  .pl-row { grid-template-columns: 12px minmax(0, 1fr) 40px 52px; gap: 8px; }
  .lt-row { grid-template-columns: 62px auto 1fr; gap: 8px; }
  .wr { grid-template-columns: 54px 32px minmax(0, 1fr) auto; gap: 8px; }
  .wr-w { display: none; }
  .mth { grid-template-columns: minmax(0,1fr) auto auto; gap: 10px; }
  .mth-x { display: none; }
  .hd-row { grid-template-columns: minmax(80px, 1fr) minmax(40px, 1.4fr) auto; gap: 10px; }
  .pr-row { grid-template-columns: 52px 1fr; }
  .pr-v { grid-column: 1 / -1; }
  .curve-figs { gap: 16px 28px; }
  .cfig-v { font-size: 16px; }
}
