/* The testnet page, one composition with the live chain as its thread: the
 * hero's strip, the checked network panel, the claim ticket, the stations, the
 * testnet's totals, the first call and the closing line.
 *
 * shared-ui carries the tokens, the type and every .ex-* component; this sheet
 * carries only what the two sections of /testnet ask for, and every class in
 * it is prefixed tn-. Every class the markup uses must exist here or in a
 * sheet that loads before it, because tests/design-language.test.mjs walks
 * both.
 *
 * NOT ONE HEX IN THIS FILE, and no text is coloured with the raw mint: text in
 * the accent uses --pickle-accent-text, the mint itself is for lines and
 * light. The estate's radius is 2px and so is every corner here.
 *
 * MOTION IS A LAYER. Every rule with a duration lives inside
 * @media (prefers-reduced-motion: no-preference) at the end of this file.
 */

/* ================================================================ live chain
 * The hero's second column and the strip under it (web/components/ChainPulse.jsx).
 * The headline says what the page is for; the readout beside it and the strip
 * of mini-blocks under it are the chain itself, measured as the page watches.
 * This is the one bold thing on the page, so everything in it is ink and mint
 * on the ground and nothing is a card. */
@media (min-width: 1024px) {
  .tn-hero {
    grid-template-columns: minmax(0, 1.06fr) minmax(0, .94fr);
    column-gap: var(--pickle-space-7);
    align-items: end;
  }
  .tn-hero-copy { grid-column: 1; grid-row: 1; }
  .tn-live { grid-column: 2; grid-row: 1; }
}

.tn-tape,
.tn-params { grid-column: 1 / -1; }

.tn-live {
  display: flex;
  flex-direction: column;
  gap: var(--pickle-space-5);
  min-width: 0;
  padding: 0 0 var(--pickle-space-2) var(--pickle-space-6);
  border-left: 1px solid var(--pickle-line);
}

.tn-live-state { align-self: flex-start; margin: 0; }

.tn-live-height {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--pickle-space-2);
}

/* The height ticks about a hundred times a second, so its digits are fixed
   width: the number rolls in place instead of shivering sideways. */
.tn-live-n {
  color: var(--pickle-text);
  font-family: var(--pickle-font-mono);
  font-size: clamp(2.5rem, 4.7vw, 4.5rem);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.05em;
  line-height: 1;
  white-space: nowrap;
}

/* A target in the height's slot is set back, so it never reads as a count. */
.tn-live:not([data-mode="live"]):not([data-mode="polled"]) .tn-live-n { color: var(--pickle-muted); }

.tn-live-label {
  color: var(--pickle-muted);
  font-size: var(--pickle-text-sm);
}

.tn-live-figs {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--pickle-line);
  border: 1px solid var(--pickle-line);
  border-radius: var(--pickle-radius);
  overflow: clip;
}

.tn-live-fig {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--pickle-space-2);
  padding: var(--pickle-space-3) var(--pickle-space-4);
  background: var(--pickle-bg);
}

.tn-live-fig dt {
  color: var(--pickle-subtle);
  font-family: var(--pickle-font-mono);
  font-size: var(--pickle-text-2xs);
  letter-spacing: .08em;
  text-transform: uppercase;
  line-height: 1.35;
}

.tn-live-fig dd {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: var(--pickle-space-1);
}

.tn-live-fig b {
  color: var(--pickle-text);
  font-family: var(--pickle-font-mono);
  font-size: var(--pickle-text-lg);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.tn-live-unit {
  color: var(--pickle-muted);
  font-family: var(--pickle-font-mono);
  font-size: var(--pickle-text-xs);
}

/* Whether a figure was measured or is the target is part of the figure. */
.tn-live-fig small {
  flex-basis: 100%;
  color: var(--pickle-subtle);
  font-size: var(--pickle-text-2xs);
}

.tn-live[data-mode="live"] .tn-live-fig small,
.tn-live[data-mode="polled"] .tn-live-fig small { color: var(--pickle-accent-text); }

/* The strip: full-bleed, the past running out to the left edge of the screen
   and "now" on the content's right edge. The section clips the overhang. */
.tn-tape { min-width: 0; }

.tn-strip {
  position: relative;
  height: 8.75rem;
  margin-inline: calc(50% - 50vw);
  border-block: 1px solid var(--pickle-line);
  background:
    radial-gradient(55% 140% at 82% 100%, var(--pickle-mint-soft), transparent 70%),
    var(--pickle-bg-deep);
  overflow: hidden;
}

.tn-canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

/* The schedule, drawn without a script: a tick every 10 ms and a line every
   250 ms, at the strip's own scale. It is what a reader with no JavaScript
   sees, and what shows when the block stream is not reachable. The key below
   calls it the schedule, never live blocks. */
.tn-sched {
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(90deg, var(--pickle-mint-line) 0 1px, transparent 1px 90px)
      left 0 top 14px / 100% calc(100% - 36px) no-repeat,
    repeating-linear-gradient(90deg, var(--pickle-line) 0 1px, transparent 1px 3.6px)
      left 0 bottom 22px / 100% 30% no-repeat;
  mask-image: linear-gradient(90deg, transparent, black 45%);
}

.tn-tape[data-mode="live"] .tn-sched { opacity: 0; }

.tn-key {
  max-width: 60rem;
  margin: var(--pickle-space-4) 0 0;
  display: flex;
  align-items: flex-start;
  gap: var(--pickle-space-4);
  color: var(--pickle-muted);
  font-size: var(--pickle-text-sm);
  line-height: 1.55;
}

/* The three marks the strip draws, at the size it draws them. */
.tn-key-marks {
  flex: none;
  display: inline-flex;
  align-items: flex-end;
  gap: 0.4rem;
  height: 1.1rem;
  margin-top: 0.1rem;
}

.tn-mark { display: block; width: 1px; background: var(--pickle-mint); }
.tn-mark.mini { height: 0.45rem; opacity: .6; }
.tn-mark.tx { width: 2px; height: 0.8rem; background: var(--pickle-mint-hi); }
.tn-mark.seal { height: 1.1rem; }

/* ================================================================ test funds
 * The explanation beside the ticket, on a wide screen; one above the other on
 * a narrow one. */
.tn-funds {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: var(--pickle-space-7);
  align-items: center;
}

.tn-funds-copy .ex-sechead { margin-bottom: var(--pickle-space-5); }

/* Three steps, joined by the line a visitor walks down. */
.tn-steps {
  position: relative;
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--pickle-space-4);
}

.tn-steps::before {
  content: "";
  position: absolute;
  top: 1rem;
  bottom: 1rem;
  left: calc(1rem - 0.5px);
  width: 1px;
  background: linear-gradient(180deg, var(--pickle-mint-line), var(--pickle-line));
}

.tn-step {
  position: relative;
  display: grid;
  grid-template-columns: 2rem minmax(0, 1fr);
  column-gap: var(--pickle-space-4);
  row-gap: var(--pickle-space-1);
}

.tn-step-n {
  grid-row: span 2;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border: 1px solid var(--pickle-mint-line);
  border-radius: var(--pickle-radius);
  background: var(--pickle-bg);
  color: var(--pickle-accent-text);
  font-family: var(--pickle-font-mono);
  font-size: var(--pickle-text-sm);
  font-weight: 600;
}

.tn-step-k {
  color: var(--pickle-text);
  font-family: var(--pickle-font-display);
  font-size: var(--pickle-text-md);
  font-weight: 600;
  line-height: 2rem;
}

.tn-step-v {
  color: var(--pickle-muted);
  font-size: var(--pickle-text-sm);
  line-height: 1.55;
}

/* On a wide screen the three steps are three stops on one line, read left to
   right, the same drawing as the stations further down. */
@media (min-width: 1024px) {
  .tn-steps {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--pickle-space-5);
  }

  .tn-steps::before {
    top: calc(1rem - 1px);
    bottom: auto;
    left: 1rem;
    right: 1rem;
    width: auto;
    height: 2px;
    background: linear-gradient(90deg, var(--pickle-mint), var(--pickle-mint-line));
  }

  .tn-step { grid-template-columns: minmax(0, 1fr); row-gap: var(--pickle-space-2); }
  .tn-step-n { grid-row: auto; margin-bottom: var(--pickle-space-2); }
  .tn-step-k { line-height: 1.3; }
}

/* The ticket: a lit edge on top, the two amounts as the section's figures, a
   perforation, the rule, and the one action. */
.tn-ticket {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--pickle-space-5);
  padding: var(--pickle-space-6);
  border: 1px solid var(--pickle-line);
  border-top: 2px solid var(--pickle-mint);
  border-radius: var(--pickle-radius);
  background:
    radial-gradient(120% 70% at 100% 0%, var(--pickle-mint-soft), transparent 60%),
    var(--pickle-surface-2);
}

.tn-ticket-head {
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: var(--pickle-subtle);
  font-family: var(--pickle-font-mono);
  font-size: var(--pickle-text-2xs);
  letter-spacing: var(--pickle-tracking-caps);
  text-transform: uppercase;
}

.tn-amounts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  background: var(--pickle-line);
  border: 1px solid var(--pickle-line);
  border-radius: var(--pickle-radius);
  overflow: clip;
}

.tn-amount {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--pickle-space-1);
  padding: var(--pickle-space-5) var(--pickle-space-4);
  background: var(--pickle-bg);
}

.tn-amount-n {
  color: var(--pickle-text);
  font-family: var(--pickle-font-mono);
  font-size: clamp(2rem, 3.4vw, 2.9rem);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.04em;
  line-height: 1;
}

.tn-amount-unit {
  color: var(--pickle-accent-text);
  font-family: var(--pickle-font-mono);
  font-size: var(--pickle-text-xs);
  letter-spacing: var(--pickle-tracking-caps);
  text-transform: uppercase;
}

.tn-amount-for {
  margin-top: var(--pickle-space-2);
  color: var(--pickle-muted);
  font-size: var(--pickle-text-sm);
  line-height: 1.45;
}

/* The rule, behind a perforation: it is the fine print of the ticket. */
.tn-ticket-rule {
  margin: 0;
  display: grid;
  grid-template-columns: 1.25rem minmax(0, 1fr);
  gap: var(--pickle-space-3);
  padding-top: var(--pickle-space-5);
  border-top: 1px dashed var(--pickle-line-strong);
  color: var(--pickle-muted);
  font-size: var(--pickle-text-sm);
  line-height: 1.55;
}

/* A clock face drawn in CSS: a ring and two hands. */
.tn-ticket-clock {
  position: relative;
  width: 1.25rem;
  height: 1.25rem;
  margin-top: 0.1rem;
  border: 1.5px solid var(--pickle-mint);
  border-radius: 50%;
}

.tn-ticket-clock::before,
.tn-ticket-clock::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 50%;
  width: 1.5px;
  background: var(--pickle-mint);
  transform-origin: 50% 100%;
}

.tn-ticket-clock::before { height: 0.4rem; transform: translateX(-50%); }
.tn-ticket-clock::after { height: 0.3rem; transform: translateX(-50%) rotate(90deg); }

.tn-ticket-cta {
  justify-content: center;
  min-height: calc(var(--pickle-tap) + 6px);
  font-size: var(--pickle-text-md);
}

/* The ticket's headline is its value, in dollars, the estate's rule for every
   money figure: and a claim is worth $0, which is the point of it. */
.tn-worth {
  margin: 0;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: end;
  gap: var(--pickle-space-5);
}

.tn-worth-n {
  color: var(--pickle-accent-text);
  font-family: var(--pickle-font-mono);
  font-size: clamp(4.5rem, 9vw, 7.5rem);
  font-weight: 500;
  letter-spacing: -.07em;
  line-height: .82;
}

.tn-worth-for {
  max-width: 17rem;
  color: var(--pickle-muted);
  font-size: var(--pickle-text-sm);
  line-height: 1.5;
}

/* The faucet's one live figure: how many more claims it can pay. */
.tn-stock {
  margin: calc(var(--pickle-space-2) * -1) 0 0;
  display: flex;
  align-items: baseline;
  gap: var(--pickle-space-2);
  color: var(--pickle-subtle);
  font-size: var(--pickle-text-sm);
  line-height: 1.5;
}

.tn-stock.on { color: var(--pickle-muted); }

.tn-stock b {
  color: var(--pickle-text);
  font-family: var(--pickle-font-mono);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.tn-stock .dot {
  flex: none;
  width: .45rem;
  height: .45rem;
  border-radius: 50%;
  background: var(--pickle-mint);
}

/* =============================================================== what to try
 * The applications as stations on one line, because they are ten doors onto
 * the same chain. The line runs down the left; the station in focus opens in
 * the panel beside it. The one bold thing in this section is that panel; the
 * line itself stays quiet. */
.tn-line {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.12fr);
  gap: var(--pickle-space-7);
  align-items: start;
}

.tn-stations {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Each stop draws the stretch of track down to the next one. */
.tn-stop { position: relative; }

.tn-stop::before {
  content: "";
  position: absolute;
  top: 50%;
  left: calc(0.55rem - 1px);
  width: 2px;
  height: 100%;
  background: var(--pickle-mint);
  opacity: .55;
}

.tn-stop:last-child::before { display: none; }

/* The track into a station that is not open yet is still being laid. */
.tn-stop:has(+ .tn-stop.soon)::before {
  width: 0;
  background: none;
  border-left: 2px dashed var(--pickle-line-strong);
  opacity: 1;
}

.tn-station {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: 1.1rem 1.35rem auto minmax(0, 1fr);
  align-items: center;
  column-gap: var(--pickle-space-4);
  height: 3.6rem;
  padding: 0 var(--pickle-space-4) 0 0;
  color: inherit;
  text-decoration: none;
  outline: none;
}

/* The station in focus is lit from the track outwards. */
.tn-station::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset: .3rem 0 .3rem 1.6rem;
  border-radius: var(--pickle-radius);
  background: linear-gradient(90deg, var(--pickle-mint-soft), transparent 85%);
  opacity: 0;
  pointer-events: none;
}

.tn-station.on::after { opacity: 1; }
.tn-station.soon.on::after { background: linear-gradient(90deg, var(--pickle-surface-hover), transparent 85%); }

/* The train: a ring on the chosen stop that rides the track to the next. Its
   stop is a class per station (data-at), never a style attribute. */
.tn-track { position: relative; }

/* The chain running down the line: one canvas over the track, drawn by
   AppLine's TrackFlow while the feed is live. */
.tn-flow {
  position: absolute;
  z-index: 1;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.tn-train {
  position: absolute;
  z-index: 2;
  top: calc(1.8rem - 1rem);
  left: calc(0.55rem - 1rem);
  width: 2rem;
  height: 2rem;
  border: 1px solid var(--pickle-mint);
  border-radius: 50%;
  pointer-events: none;
}

.tn-track[data-at="1"] .tn-train { transform: translateY(3.6rem); }
.tn-track[data-at="2"] .tn-train { transform: translateY(7.2rem); }
.tn-track[data-at="3"] .tn-train { transform: translateY(10.8rem); }
.tn-track[data-at="4"] .tn-train { transform: translateY(14.4rem); }
.tn-track[data-at="5"] .tn-train { transform: translateY(18rem); }
.tn-track[data-at="6"] .tn-train { transform: translateY(21.6rem); }
.tn-track[data-at="7"] .tn-train { transform: translateY(25.2rem); }
.tn-track[data-at="8"] .tn-train { transform: translateY(28.8rem); }
.tn-track[data-at="9"] .tn-train { transform: translateY(32.4rem); }
.tn-track[data-at="9"] .tn-train { border-style: dashed; border-color: var(--pickle-line-strong); }

.tn-dot {
  position: relative;
  z-index: 1;
  width: 1.1rem;
  height: 1.1rem;
  border: 2px solid var(--pickle-mint);
  border-radius: 50%;
  background: var(--pickle-bg);
}

.tn-station.on .tn-dot {
  background: var(--pickle-mint);
  box-shadow: 0 0 0 5px var(--pickle-mint-soft);
}

.tn-station.soon .tn-dot {
  border-style: dashed;
  border-color: var(--pickle-line-strong);
}

.tn-station.soon.on .tn-dot {
  background: var(--pickle-bg);
  box-shadow: 0 0 0 5px var(--pickle-surface-2);
}

.tn-station-glyph,
.tn-panel-glyph,
.tn-panel-mark {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.tn-station-glyph {
  width: 1.35rem;
  height: 1.35rem;
  stroke-width: 1.6;
  color: var(--pickle-subtle);
}

.tn-station-name {
  color: var(--pickle-muted);
  font-family: var(--pickle-font-display);
  font-size: clamp(1.35rem, 1.9vw, 1.8rem);
  font-weight: 600;
  letter-spacing: var(--pickle-tracking-tight);
  line-height: 1.15;
  white-space: nowrap;
}

.tn-station-hint {
  justify-self: end;
  color: var(--pickle-subtle);
  font-size: var(--pickle-text-sm);
  text-align: right;
}

/* The description belongs to the panel on a wide screen and to the station
   on a phone. */
.tn-station-what { display: none; }

.tn-station:hover .tn-station-name,
.tn-station:focus-visible .tn-station-name,
.tn-station.on .tn-station-name { color: var(--pickle-text); }

.tn-station.on .tn-station-glyph { color: var(--pickle-accent-text); }
.tn-station.on .tn-station-hint { color: var(--pickle-muted); }

.tn-station:focus-visible .tn-station-name {
  text-decoration: underline;
  text-decoration-color: var(--pickle-mint);
  text-decoration-thickness: 2px;
  text-underline-offset: 6px;
}

.tn-station.soon { cursor: default; }
.tn-station.soon .tn-station-name { color: var(--pickle-subtle); }
.tn-station.soon.on .tn-station-name { color: var(--pickle-muted); }

/* The panel: the station in focus, large. */
.tn-panel {
  position: sticky;
  top: 6rem;
  /* As tall as the line beside it, so choosing a station never moves the
     edge of the panel. */
  min-height: 44rem;
  display: flex;
  border: 1px solid var(--pickle-line);
  border-top: 2px solid var(--pickle-mint);
  border-radius: var(--pickle-radius);
  background:
    radial-gradient(90% 70% at 100% 100%, var(--pickle-mint-soft), transparent 62%),
    var(--pickle-surface-2);
  overflow: clip;
}

.tn-panel-body {
  position: relative;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: var(--pickle-space-4);
  padding: var(--pickle-space-7);
}

/* The station's drawing, once at the size of a word and once at the size of
   the panel, faint, in the empty corner above the name and clear of the
   action. */
.tn-panel-mark {
  position: absolute;
  top: -2.5rem;
  right: -3rem;
  width: 16rem;
  height: 16rem;
  stroke-width: .6;
  color: var(--pickle-accent-text);
  opacity: .07;
  pointer-events: none;
}

.tn-panel-glyph {
  width: 3rem;
  height: 3rem;
  margin-bottom: var(--pickle-space-2);
  stroke-width: 1.4;
  color: var(--pickle-accent-text);
}

.tn-panel-top {
  margin: 0;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--pickle-space-4);
}

.tn-panel-top .tn-panel-glyph { margin-bottom: 0; }

.tn-panel-stop {
  color: var(--pickle-subtle);
  font-family: var(--pickle-font-mono);
  font-size: var(--pickle-text-2xs);
  letter-spacing: var(--pickle-tracking-caps);
  text-transform: uppercase;
}

.tn-panel-name {
  margin: 0;
  color: var(--pickle-text);
  font-family: var(--pickle-font-display);
  font-size: clamp(2.4rem, 4vw, 3.6rem);
  white-space: nowrap;
  font-weight: 600;
  letter-spacing: var(--pickle-tracking-display);
  line-height: 1;
}

.tn-panel-what {
  max-width: 34rem;
  margin: 0;
  color: var(--pickle-muted);
  font-size: var(--pickle-text-base);
  line-height: 1.6;
}

.tn-panel-does {
  margin: var(--pickle-space-2) 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--pickle-space-3);
}

.tn-panel-does li {
  position: relative;
  padding-left: 1.6rem;
  color: var(--pickle-text);
  font-size: var(--pickle-text-sm);
  line-height: 1.5;
}

/* A tick, drawn. */
.tn-panel-does li::before {
  content: "";
  position: absolute;
  top: 0.3rem;
  left: 0.15rem;
  width: 0.7rem;
  height: 0.38rem;
  border-left: 2px solid var(--pickle-mint);
  border-bottom: 2px solid var(--pickle-mint);
  transform: rotate(-45deg);
}

.tn-panel-foot {
  position: relative;
  margin-top: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--pickle-space-4);
  padding-top: var(--pickle-space-5);
  border-top: 1px dashed var(--pickle-line-strong);
}

.tn-panel-open {
  justify-content: center;
  min-width: 12rem;
}

.tn-panel-host {
  color: var(--pickle-subtle);
  font-family: var(--pickle-font-mono);
  font-size: var(--pickle-text-xs);
}

.tn-panel-soon {
  padding: var(--pickle-space-2) var(--pickle-space-4);
  border: 1px dashed var(--pickle-line-strong);
  border-radius: var(--pickle-radius);
  color: var(--pickle-muted);
  font-size: var(--pickle-text-sm);
}

/* ============================================================ section rhythm */
.tn-top { padding-bottom: var(--pickle-section-sm); }
.tn-funds-sec { padding: var(--pickle-section-sm) 0; border-top: 1px solid var(--pickle-line); }
.tn-apps-sec { padding-bottom: var(--pickle-section-sm); }
.tn-build-sec { padding-bottom: var(--pickle-space-7); }

/* =========================================================== network panel
 * The chain ID set large, and checked against the node; the other values in
 * the list beside it. */
.tn-net {
  display: grid;
  grid-template-columns: minmax(15rem, .8fr) minmax(0, 2fr);
  gap: var(--pickle-space-6);
  margin-top: var(--pickle-space-4);
}

.tn-net-id {
  display: flex;
  flex-direction: column;
  gap: var(--pickle-space-3);
  padding-right: var(--pickle-space-6);
  border-right: 1px solid var(--pickle-line);
}

.tn-net-id-k {
  margin: 0;
  color: var(--pickle-subtle);
  font-family: var(--pickle-font-mono);
  font-size: var(--pickle-text-2xs);
  letter-spacing: .13em;
  text-transform: uppercase;
}

.tn-net-id-v {
  margin: 0;
  color: var(--pickle-text);
  font-family: var(--pickle-font-mono);
  font-size: clamp(3.2rem, 6vw, 5.4rem);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.06em;
  line-height: .9;
}

.tn-net-id-copy { display: flex; flex-wrap: wrap; gap: var(--pickle-space-2); }

.tn-net-check {
  margin: var(--pickle-space-3) 0 0;
  display: grid;
  grid-template-columns: 1rem minmax(0, 1fr);
  gap: var(--pickle-space-3);
  color: var(--pickle-muted);
  font-size: var(--pickle-text-sm);
  line-height: 1.5;
}

/* A ring while asking; a filled ring with a tick once the node has agreed. */
.tn-net-check-mark {
  position: relative;
  width: 1rem;
  height: 1rem;
  margin-top: .15rem;
  border: 1.5px solid var(--pickle-line-strong);
  border-radius: 50%;
}

.tn-net-check.ok .tn-net-check-mark { border-color: var(--pickle-mint); background: var(--pickle-mint); }

.tn-net-check.ok .tn-net-check-mark::after {
  content: "";
  position: absolute;
  top: .22rem;
  left: .2rem;
  width: .45rem;
  height: .24rem;
  border-left: 2px solid var(--pickle-mint-ink);
  border-bottom: 2px solid var(--pickle-mint-ink);
  transform: rotate(-45deg);
}

.tn-net-kv { align-self: start; }

/* The value first, its Copy at the row's end, wherever the value wraps. */
.tn-net-kv dd {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: var(--pickle-space-3);
  row-gap: var(--pickle-space-2);
}

.tn-net-kv dd .ex-btn { margin-left: auto; }

/* ================================================================== so far
 * The testnet's totals as one sentence, on the strip's deep ground, full
 * width: the one place the page lets the index speak in display type. */
.tn-sofar {
  padding: var(--pickle-section-sm) 0;
  border-block: 1px solid var(--pickle-line);
  background:
    radial-gradient(60% 120% at 12% 0%, var(--pickle-mint-soft), transparent 65%),
    var(--pickle-bg-deep);
}

.tn-sofar-k {
  margin: 0 0 var(--pickle-space-5);
  color: var(--pickle-subtle);
  font-family: var(--pickle-font-mono);
  font-size: var(--pickle-text-2xs);
  letter-spacing: var(--pickle-tracking-caps);
  text-transform: uppercase;
}

.tn-sofar-line {
  max-width: 66rem;
  margin: 0;
  color: var(--pickle-text);
  font-family: var(--pickle-font-display);
  font-size: clamp(1.9rem, 4.8vw, 4.4rem);
  font-weight: 600;
  letter-spacing: var(--pickle-tracking-display);
  line-height: 1.06;
  text-wrap: balance;
}

.tn-sofar-line b {
  color: var(--pickle-accent-text);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.tn-sofar-note {
  max-width: 40rem;
  margin: var(--pickle-space-5) 0 0;
  color: var(--pickle-muted);
  font-size: var(--pickle-text-sm);
  line-height: 1.55;
}

/* =============================================================== first call
 * The request and the node's real answer, side by side, on the strip's
 * ground. */
.tn-call {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  margin-bottom: var(--pickle-space-7);
  background: var(--pickle-line);
  border: 1px solid var(--pickle-line);
  border-top: 2px solid var(--pickle-mint);
  border-radius: var(--pickle-radius);
  overflow: clip;
}

.tn-call-part {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--pickle-space-4);
  padding: var(--pickle-space-5) var(--pickle-space-6);
  background: var(--pickle-bg-deep);
}

.tn-call-k {
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--pickle-space-3);
  min-height: 2.25rem;
  color: var(--pickle-subtle);
  font-family: var(--pickle-font-mono);
  font-size: var(--pickle-text-2xs);
  letter-spacing: .13em;
  text-transform: uppercase;
}

.tn-code {
  margin: 0;
  color: var(--pickle-text);
  font-family: var(--pickle-font-mono);
  font-size: var(--pickle-text-sm);
  line-height: 1.75;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* The request is a command, so it keeps its own line breaks and scrolls
   inside its block on a narrow screen rather than wrapping mid-argument. */
.tn-code.req {
  font-size: var(--pickle-text-xs);
  white-space: pre;
  overflow-wrap: normal;
  overflow-x: auto;
  padding-bottom: var(--pickle-space-2);
}

.tn-code.res {
  min-height: 3.5em;
  white-space: pre;
  overflow-wrap: normal;
  overflow-x: auto;
  color: var(--pickle-accent-text);
  font-size: var(--pickle-text-md);
}

/* No answer is not news: a failure is never written in the emphasis colour. */
.tn-code.res.off { color: var(--pickle-muted); }

.tn-call-note {
  margin: auto 0 0;
  color: var(--pickle-muted);
  font-size: var(--pickle-text-sm);
  line-height: 1.55;
}

/* The reference, as four rows with their names at reading size. */
.tn-docs {
  margin: 0 0 var(--pickle-space-5);
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--pickle-space-7);
  border-top: 1px solid var(--pickle-line);
}

.tn-doc {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "name chev" "what what" "host host";
  row-gap: var(--pickle-space-2);
  column-gap: var(--pickle-space-4);
  padding: var(--pickle-space-5) 0;
  border-bottom: 1px solid var(--pickle-line);
  color: inherit;
  text-decoration: none;
}

.tn-doc-name {
  grid-area: name;
  color: var(--pickle-text);
  font-family: var(--pickle-font-display);
  font-size: var(--pickle-text-xl);
  font-weight: 600;
  letter-spacing: var(--pickle-tracking-tight);
}

/* A chevron, drawn: two borders of a turned square. */
.tn-doc::after {
  content: "";
  grid-area: chev;
  align-self: center;
  width: .55rem;
  height: .55rem;
  margin-right: .3rem;
  border-top: 2px solid var(--pickle-mint);
  border-right: 2px solid var(--pickle-mint);
  transform: rotate(45deg);
}

.tn-doc-what { grid-area: what; color: var(--pickle-muted); font-size: var(--pickle-text-sm); line-height: 1.55; }
.tn-doc-host { grid-area: host; color: var(--pickle-subtle); font-family: var(--pickle-font-mono); font-size: var(--pickle-text-2xs); }

.tn-doc:hover .tn-doc-name,
.tn-doc:focus-visible .tn-doc-name { color: var(--pickle-accent-text); }

/* ================================================================= closing
 * The page ends on the chain, still running, and the one thing to do next. */
.tn-close { padding: var(--pickle-section-sm) 0 var(--pickle-section); }

/* The hero's composition, closed: the words on the left, the chain on the
   right behind the same hairline. */
.tn-close-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.06fr) minmax(0, .94fr);
  column-gap: var(--pickle-space-7);
  row-gap: var(--pickle-space-6);
  align-items: end;
}

.tn-close-count {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--pickle-space-2);
  padding: 0 0 var(--pickle-space-2) var(--pickle-space-6);
  border-left: 1px solid var(--pickle-line);
  color: var(--pickle-muted);
  font-size: var(--pickle-text-sm);
}

.tn-close-n {
  color: var(--pickle-accent-text);
  font-family: var(--pickle-font-mono);
  font-size: clamp(2.5rem, 4.7vw, 4.5rem);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.05em;
  line-height: 1;
  white-space: nowrap;
}

.tn-close-n.off { color: var(--pickle-muted); }

.tn-close-h {
  max-width: 15ch;
  margin: 0 0 var(--pickle-space-6);
  font-family: var(--pickle-font-display);
  font-size: var(--pickle-text-display);
  font-weight: 600;
  letter-spacing: var(--pickle-tracking-display);
  line-height: var(--pickle-leading-display);
}

.tn-close-actions { margin-bottom: var(--pickle-space-3); }

/* ================================================================== scenes
 * A small picture of each application inside the stations panel
 * (components/testnet/StationScene.jsx): live where the application has
 * something real to read, otherwise what the application is. */
.tn-scene {
  display: flex;
  flex-direction: column;
  gap: var(--pickle-space-3);
  padding: var(--pickle-space-4);
  border: 1px solid var(--pickle-line);
  border-radius: var(--pickle-radius);
  background: var(--pickle-bg-deep);
}

.tn-sc-row {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  column-gap: var(--pickle-space-4);
  row-gap: var(--pickle-space-2);
}

.tn-sc-big {
  color: var(--pickle-accent-text);
  font-family: var(--pickle-font-mono);
  font-size: clamp(2.2rem, 3.6vw, 3.2rem);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.05em;
  line-height: .9;
}

.tn-sc-sub {
  max-width: 17rem;
  color: var(--pickle-muted);
  font-size: var(--pickle-text-sm);
  line-height: 1.45;
}

.tn-sc-live {
  margin: 0;
  color: var(--pickle-subtle);
  font-size: var(--pickle-text-sm);
  line-height: 1.5;
}

.tn-sc-live.on { color: var(--pickle-muted); }

.tn-sc-live b,
.tn-sc-head b {
  color: var(--pickle-text);
  font-family: var(--pickle-font-mono);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.tn-sc-head {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--pickle-space-2);
  color: var(--pickle-subtle);
  font-family: var(--pickle-font-mono);
  font-size: var(--pickle-text-2xs);
  letter-spacing: .1em;
  text-transform: uppercase;
}

/* The explorer's latest transactions, as its own rows would show them. */
.tn-sc-rows { margin: 0; padding: 0; list-style: none; }

.tn-sc-tx {
  display: grid;
  grid-template-columns: .5rem minmax(0, 1.25fr) minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--pickle-space-3);
  padding: .5rem 0;
  border-top: 1px solid var(--pickle-line);
  font-family: var(--pickle-font-mono);
  font-size: var(--pickle-text-xs);
}

.tn-sc-ok { width: .45rem; height: .45rem; border-radius: 50%; background: var(--pickle-mint); }
.tn-sc-ok.bad { background: var(--pickle-rose); }
.tn-sc-hash { color: var(--pickle-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tn-sc-method { color: var(--pickle-accent-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tn-sc-block { color: var(--pickle-subtle); }

/* The eight cabinets. */
.tn-sc-tiles {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--pickle-line);
  border: 1px solid var(--pickle-line);
  border-radius: var(--pickle-radius);
  overflow: clip;
}

.tn-sc-tiles li {
  padding: .75rem var(--pickle-space-3);
  background: var(--pickle-bg);
  color: var(--pickle-text);
  font-family: var(--pickle-font-display);
  font-size: var(--pickle-text-md);
  font-weight: 600;
}

/* A name, as it would read. */
.tn-sc-name {
  margin: 0;
  font-family: var(--pickle-font-display);
  font-size: clamp(2rem, 3.2vw, 2.7rem);
  font-weight: 600;
  letter-spacing: var(--pickle-tracking-display);
  line-height: 1;
}

.tn-sc-name span { color: var(--pickle-text); }
.tn-sc-name b { color: var(--pickle-accent-text); font-weight: 600; }

/* The toolkit's four forms, and the account's two ways in. */
.tn-sc-forms {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--pickle-space-2);
}

.tn-sc-forms li,
.tn-sc-ways li {
  display: flex;
  flex-direction: column;
  gap: var(--pickle-space-1);
  padding: .7rem var(--pickle-space-3);
  border: 1px dashed var(--pickle-line-strong);
  border-radius: var(--pickle-radius);
}

.tn-sc-forms b,
.tn-sc-ways b { color: var(--pickle-text); font-size: var(--pickle-text-sm); font-weight: 600; }

.tn-sc-forms span,
.tn-sc-ways span { color: var(--pickle-subtle); font-size: var(--pickle-text-xs); }

.tn-sc-ways {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--pickle-space-2);
}

.tn-sc-ways li { border-style: solid; border-color: var(--pickle-line); }

/* Mini-blocks as they arrive, newest on top. */
.tn-sc-feed {
  margin: 0;
  padding: 0;
  list-style: none;
  font-family: var(--pickle-font-mono);
  font-size: var(--pickle-text-xs);
  font-variant-numeric: tabular-nums;
}

.tn-sc-feed li {
  padding: .28rem 0;
  border-top: 1px solid var(--pickle-line);
  color: var(--pickle-subtle);
  white-space: pre;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tn-sc-feed li:first-child { color: var(--pickle-accent-text); }
.tn-sc-feed li:nth-child(2) { color: var(--pickle-text); }
.tn-sc-feed li:nth-child(3) { color: var(--pickle-muted); }

/* The bridge: two shores and the track between them still being laid. */
.tn-sc-bridge {
  margin: 0;
  display: flex;
  align-items: center;
  gap: var(--pickle-space-3);
  color: var(--pickle-text);
  font-family: var(--pickle-font-display);
  font-size: var(--pickle-text-lg);
  font-weight: 600;
}

.tn-sc-bridge i { flex: 1 1 auto; border-top: 2px dashed var(--pickle-line-strong); }

/* ================================================================== narrower */
@media (max-width: 1023px) {
  .tn-funds { grid-template-columns: minmax(0, 1fr); gap: var(--pickle-space-6); }

  /* No hover to choose with, so no panel: each station says what it is. */
  .tn-line { grid-template-columns: minmax(0, 1fr); }
  .tn-panel { display: none; }

  .tn-stop::before { top: 1.9rem; }

  .tn-train { display: none; }
  .tn-station::after { display: none; }

  .tn-station {
    grid-template-columns: 1.1rem 1.35rem minmax(0, 1fr);
    align-items: start;
    row-gap: var(--pickle-space-1);
    height: auto;
    padding: var(--pickle-space-4) 0;
  }

  .tn-dot { margin-top: 0.35rem; }
  .tn-station-glyph { margin-top: 0.25rem; }
  .tn-station-name { grid-column: 3; color: var(--pickle-text); white-space: normal; }
  .tn-station-hint { grid-column: 3; justify-self: start; text-align: left; color: var(--pickle-accent-text); }
  .tn-station-what { display: block; grid-column: 3; color: var(--pickle-muted); font-size: var(--pickle-text-sm); line-height: 1.55; }
  /* Without the panel there is nothing to select, so the chosen station
     looks like every other one. */
  .tn-station.on .tn-dot { background: var(--pickle-bg); box-shadow: none; }
  .tn-station.on .tn-station-hint { color: var(--pickle-accent-text); }
  .tn-station.on .tn-station-glyph { color: var(--pickle-subtle); }
  .tn-station.soon .tn-station-hint { color: var(--pickle-subtle); }
}

@media (max-width: 1023px) {
  .tn-close-grid { grid-template-columns: minmax(0, 1fr); }
  .tn-close-count { order: -1; padding: 0; border-left: 0; }
  .tn-live {
    padding: var(--pickle-space-5) 0 0;
    border-left: 0;
    border-top: 1px solid var(--pickle-line);
  }
}

@media (max-width: 767px) {
  .tn-net { grid-template-columns: minmax(0, 1fr); gap: var(--pickle-space-5); }
  .tn-net-id { padding: 0 0 var(--pickle-space-5); border-right: 0; border-bottom: 1px solid var(--pickle-line); }
  .tn-call { grid-template-columns: minmax(0, 1fr); }
  .tn-docs { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 639px) {
  .tn-ticket { padding: var(--pickle-space-5); }
  .tn-call-part { padding: var(--pickle-space-4); }
  .tn-code { font-size: var(--pickle-text-xs); }
  .tn-worth { grid-template-columns: minmax(0, 1fr); gap: var(--pickle-space-3); }
  .tn-ticket-head { flex-direction: column; align-items: flex-start; gap: var(--pickle-space-1); }
  .tn-net-kv { grid-template-columns: minmax(0, 1fr); }
  .tn-net-kv dt { padding-bottom: 0; border-bottom: 0; }
  .tn-code.res { font-size: var(--pickle-text-xs); }
  .tn-strip { height: 7.25rem; }
  .tn-live-fig { padding: var(--pickle-space-3); }
  .tn-live-fig b { font-size: var(--pickle-text-md); }
  .tn-key { gap: var(--pickle-space-3); }
}

@media (max-width: 379px) {
  .tn-amounts { grid-template-columns: minmax(0, 1fr); }
}

/* ==================================================================== motion
 * The strip moves because the chain does; that is drawn by script, and the
 * script stills it under reduced motion. Here: the strip arrives a beat after
 * the hero copy, the line of stations lights once on first sight, and the
 * panel's contents arrive when the visitor chooses a station. */
@media (prefers-reduced-motion: no-preference) {
  .tn-hero > .tn-tape { animation-delay: 420ms; }
  .tn-sched { transition: opacity 600ms ease-out; }
  .tn-beat { animation: pickle-pulse 1.6s ease-in-out infinite; }

  /* Armed only by AppLine's script, and only when the line starts below the
     fold: with no script the line is simply there. */
  .tn-line.tn-armed .tn-stop { opacity: 0; transform: translateY(10px); }
  .tn-line.tn-armed .tn-stop::before { transform: scaleY(0); transform-origin: 50% 0; }

  .tn-line.tn-armed.tn-lit .tn-stop {
    opacity: 1;
    transform: none;
    transition: opacity 480ms ease-out, transform 620ms var(--pickle-ease);
  }

  .tn-line.tn-armed.tn-lit .tn-stop::before {
    transform: none;
    transition: transform 240ms linear;
  }

  .tn-line.tn-lit .tn-stop:nth-child(2) { transition-delay: 90ms; }
  .tn-line.tn-lit .tn-stop:nth-child(3) { transition-delay: 180ms; }
  .tn-line.tn-lit .tn-stop:nth-child(4) { transition-delay: 270ms; }
  .tn-line.tn-lit .tn-stop:nth-child(5) { transition-delay: 360ms; }
  .tn-line.tn-lit .tn-stop:nth-child(6) { transition-delay: 450ms; }
  .tn-line.tn-lit .tn-stop:nth-child(7) { transition-delay: 540ms; }
  .tn-line.tn-lit .tn-stop:nth-child(8) { transition-delay: 630ms; }
  .tn-line.tn-lit .tn-stop:nth-child(9) { transition-delay: 720ms; }
  .tn-line.tn-lit .tn-stop:nth-child(10) { transition-delay: 810ms; }
  .tn-line.tn-lit .tn-stop:nth-child(1)::before { transition-delay: 80ms; }
  .tn-line.tn-lit .tn-stop:nth-child(2)::before { transition-delay: 170ms; }
  .tn-line.tn-lit .tn-stop:nth-child(3)::before { transition-delay: 260ms; }
  .tn-line.tn-lit .tn-stop:nth-child(4)::before { transition-delay: 350ms; }
  .tn-line.tn-lit .tn-stop:nth-child(5)::before { transition-delay: 440ms; }
  .tn-line.tn-lit .tn-stop:nth-child(6)::before { transition-delay: 530ms; }
  .tn-line.tn-lit .tn-stop:nth-child(7)::before { transition-delay: 620ms; }
  .tn-line.tn-lit .tn-stop:nth-child(8)::before { transition-delay: 710ms; }
  .tn-line.tn-lit .tn-stop:nth-child(9)::before { transition-delay: 800ms; }

  /* While the chain flows down the line, the drawn track steps back so the
     mini-blocks are what the eye follows. */
  .tn-line[data-flow="live"] .tn-stop::before { opacity: .22; }
  .tn-line[data-flow="live"] .tn-stop:has(+ .tn-stop.soon)::before { opacity: 1; }

  /* The train rides the track to the station chosen. */
  .tn-train { transition: transform 460ms var(--pickle-ease), border-color 200ms ease-out; }
  .tn-station::after { transition: opacity 220ms ease-out; }

  /* The three steps light left to right, the track drawing ahead of them. */
  .tn-steps.tn-armed .tn-step { opacity: 0; transform: translateY(10px); }
  .tn-steps.tn-armed::before { transform: scaleX(0); transform-origin: 0 50%; }
  .tn-steps.tn-armed.tn-lit::before { transform: none; transition: transform 900ms var(--pickle-ease) 100ms; }

  .tn-steps.tn-armed.tn-lit .tn-step {
    opacity: 1;
    transform: none;
    transition: opacity 480ms ease-out, transform 620ms var(--pickle-ease);
  }

  .tn-steps.tn-lit .tn-step:nth-child(2) { transition-delay: 220ms; }
  .tn-steps.tn-lit .tn-step:nth-child(3) { transition-delay: 440ms; }

  /* Each answer from the node arrives, once a second, without a flash. */
  .tn-code.res { animation: tn-answer 420ms ease-out both; }

  @keyframes tn-answer {
    from { opacity: .45; }
    to { opacity: 1; }
  }

  .tn-doc::after { transition: transform 200ms var(--pickle-ease); }
  .tn-doc:hover::after { transform: translateX(3px) rotate(45deg); }

  /* Then one pulse of light runs the length of the track, behind the dots. */
  .tn-stations { position: relative; }

  .tn-line.tn-armed .tn-stations::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: calc(0.55rem - 1px);
    width: 2px;
    background: linear-gradient(180deg, transparent 44%, var(--pickle-mint-hi) 50%, transparent 56%);
    background-size: 100% 300%;
    background-position: 0 100%;
    pointer-events: none;
  }

  .tn-line.tn-armed.tn-lit .tn-stations::after {
    animation: tn-run 1500ms cubic-bezier(.45, 0, .2, 1) 700ms both;
  }

  @keyframes tn-run {
    from { background-position: 0 100%; }
    to { background-position: 0 0; }
  }

  .tn-panel-body { animation: tn-arrive 260ms var(--pickle-ease, ease-out) both; }
  .tn-dot { transition: background-color 160ms ease-out, box-shadow 200ms ease-out; }

  @keyframes tn-arrive {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: none; }
  }
}

/* Paper has no scroll position: a line armed to light on sight prints lit. */
@media print {
  .tn-line.tn-armed .tn-stop,
  .tn-steps.tn-armed .tn-step { opacity: 1; transform: none; }
  .tn-line.tn-armed .tn-stop::before,
  .tn-steps.tn-armed::before { transform: none; }
}
