/* ==========================================================================
   /css/demo.css — the landing page's instrument.
   Owner: ISS-167. Binding spec: docs/DESIGN.md v5 + v5.1.

   app.css styles the paper this page is printed on. This file styles the
   things bolted to it: the rig in the hero, the as-of scrubber inside the
   rig, the full-bleed diff ribbon, the persistent telemetry bar, and the
   landing's own asymmetric composition. It defines nothing that another page
   could want, and it never redefines a token — every colour here is a var
   from app.css §1.

   Prefixes this file owns and app.css never touches:
     .lp-*      the landing's layout (hero grid, ribbon, sections, plans)
     .rig-*     the terminal in the hero and its tab strip
     .scrub-*   the as-of scrubber
     .tele*     the persistent bottom telemetry bar
     .j-*, .jl, .jg   JSON syntax and diff gutters inside a scrubber pane
     .demo-*    kept from v4 so a stale page keeps rendering

   THE SIX STRUCTURAL TELLS (docs/DESIGN.md v5), and where each is broken:
     1. Centred monologue      → .lp-hero is a 5/7 grid across the full
                                 viewport; the rig runs to the right edge and
                                 .lp-ribbon runs to both.
     2. Eyebrow→H2→P→3 cards   → hero split, then a dark band, then a ledger
                                 with a side rail, then a table, then a dense
                                 key grid, then plans. No skeleton repeats.
     3. Padded uniformity      → .lp-collide sets padding-top: 0 and closes
                                 the join with a 2px --rule-2, so the hero,
                                 the ribbon and the ledger touch.
     4. Single-accent cowardice→ amber is the control and the cursor, green is
                                 an insertion, red is a deletion or a refusal,
                                 cyan is a clock or a coverage key. Four
                                 colours, four meanings, none decorative.
     5. Simulated artifacts    → every pane in the scrubber is a response this
                                 repo's own /v1/sample/news returned, dropped
                                 in verbatim. Nothing here was written to look
                                 like data.
     6. Zero viewport bleed    → the rig bleeds right, the ribbon bleeds both
                                 ways, and .tele is fixed to the bottom of the
                                 window on every page load.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. The landing's frame. The page grows a bottom gutter for the telemetry
      bar, which is fixed, so nothing at the end of the document hides under
      it.
   -------------------------------------------------------------------------- */

body.lp {
  padding-bottom: calc(var(--tele-h) + var(--s3));
}

/* A band that runs the whole viewport, ignoring .wrap. Used by the hero, the
   ribbon and the ledger. Sections that bleed set their own inner padding. */
.lp-bleed {
  width: 100%;
  margin: 0;
  padding: 0;
}

/* Two sections that touch. The joint is a 2px structural rule and there is no
   air on either side of it: the density spike is the point. */
.lp-collide {
  border-top: 2px solid var(--rule-2);
  padding-top: 0;
}

.lp-pad {
  padding-right: var(--gutter);
  padding-left: var(--gutter);
}

/* --------------------------------------------------------------------------
   2. The hero — 5/7, full bleed, the instrument pinned to the right edge.
   -------------------------------------------------------------------------- */

/* The hero is fixed-height at desktop, which is what makes it a screen rather
   than a section. --hero-h is the height both columns agree on: the rig is
   capped at it and scrolls its own pane, and the pitch column only ever sets
   the floor, so a long envelope in the rig can never push the h1 down the
   page. Below 900px the columns stack and the cap comes off. */
.lp-hero {
  --hero-h: clamp(34rem, calc(100vh - var(--header-h) - var(--tele-h) - 2rem), 50rem);

  display: grid;
  width: 100%;
  border-bottom: 1px solid var(--rule);
  grid-template-columns: 5fr 7fr;
}

@media (min-width: 901px) {
  .lp-hero {
    min-height: var(--hero-h);
  }

  .rig {
    max-height: var(--hero-h);
  }
}

.lp-pitch {
  display: flex;
  min-width: 0;
  flex-direction: column;
  justify-content: center;
  border-right: 1px solid var(--rule-2);
  padding: var(--s9) var(--s8) var(--s8) var(--gutter);
  gap: var(--s5);
}

/* The eyebrow is a rail, not a caption: a mono line pinned to a hairline that
   runs the width of the column. */
.lp-rail {
  display: flex;
  flex-wrap: wrap;
  margin: 0;
  border-bottom: 1px solid var(--rule);
  padding-bottom: var(--s2);
  gap: var(--s2) var(--s4);
  color: var(--ink-2);
  font-family: var(--mono);
  font-size: var(--t-tele);
  letter-spacing: 0.07em;
  line-height: 1.6;
  text-transform: uppercase;
}

.lp-rail b {
  color: var(--ink);
  font-weight: 500;
}

.lp-h1 {
  margin: 0;
  color: var(--ink);
  font-size: clamp(2rem, 1rem + 2.4vw, 2.75rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.05;
  text-wrap: balance;
}

.lp-lede {
  margin: 0;
  max-width: 46ch;
  color: var(--ink-2);
  font-size: var(--t-md);
  line-height: 1.5;
}

.lp-lede b {
  color: var(--ink);
  font-weight: 500;
}

/* The query builder: the call the rig is running right now, in one line, with
   the as-of bound to the scrubber. It is a real URL — the copy button hands
   over exactly what a terminal would need. */
.lp-q {
  display: flex;
  min-width: 0;
  align-items: stretch;
  border: 1px solid var(--i-rule);
  background: var(--i-canvas);
}

.lp-q-line {
  min-width: 0;
  flex: 1;
  padding: var(--s2) var(--s3);
  color: var(--i-ink-2);
  font-family: var(--mono);
  font-size: var(--t-sm);
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.lp-q-line b {
  color: var(--i-ink);
  font-weight: 500;
}

.lp-q-line .lp-q-asof {
  color: var(--i-cyan);
  font-weight: 500;
}

.lp-q-copy {
  flex: none;
  border: 0;
  border-left: 1px solid var(--i-rule);
  background: var(--i-inset);
  padding: 0 var(--s3);
  color: var(--i-ink-2);
  font-family: var(--mono);
  font-size: var(--t-xs);
  cursor: pointer;
  transition: color 100ms linear, background-color 100ms linear;
}

.lp-q-copy:hover {
  background: var(--i-rule);
  color: var(--i-amber);
}

.lp-q-copy:focus-visible {
  outline: 2px solid var(--i-cyan);
  outline-offset: -2px;
}

.lp-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  margin: 0;
  gap: var(--s3);
}

.lp-fine {
  margin: 0;
  color: var(--ink-2);
  font-size: var(--t-sm);
  line-height: 1.5;
}

.lp-works {
  display: flex;
  flex-direction: column;
  margin: 0;
  border-top: 1px solid var(--rule);
  padding-top: var(--s4);
  gap: var(--s3);
}

/* --------------------------------------------------------------------------
   3. The rig — the terminal, edge to edge on the right of the hero.
   -------------------------------------------------------------------------- */

.rig {
  display: flex;
  min-width: 0;
  flex-direction: column;
  background: var(--i-canvas);
  color: var(--i-ink);
}

.rig-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  margin: 0;
  border-bottom: 1px solid var(--i-rule);
  background: var(--i-surface);
  padding: var(--s2) var(--s4);
  gap: var(--s2) var(--s4);
  color: var(--i-ink-2);
  font-family: var(--mono);
  font-size: var(--t-xs);
  line-height: 1.6;
}

.rig-title {
  margin: 0;
  color: var(--i-ink-2);
  font-family: var(--mono);
  font-size: var(--t-xs);
  font-weight: 400;
  letter-spacing: 0;
}

.rig-title b {
  color: var(--i-ink);
  font-weight: 500;
}

/* The one moving light on the page that is not a control: a square that says
   the attract loop is running. It stops on first input and stays stopped. */
.rig-live {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  color: var(--i-ink-2);
  font-size: var(--t-tele);
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.rig-live::before {
  width: 6px;
  height: 6px;
  background: var(--i-dim);
  content: "";
}

.rig[data-play="on"] .rig-live::before {
  animation: rig-blink 1.6s steps(1, end) infinite;
  background: var(--i-amber);
}

@keyframes rig-blink {
  0%,
  60% {
    opacity: 1;
  }

  61%,
  100% {
    opacity: 0.25;
  }
}

.rig-tabs {
  display: flex;
  margin: 0;
  border-bottom: 1px solid var(--i-rule);
  background: var(--i-surface);
  padding: 0;
  gap: 0;
  list-style: none;
}

.rig-tab {
  border: 0;
  border-right: 1px solid var(--i-rule);
  border-bottom: 2px solid transparent;
  background: none;
  padding: var(--s2) var(--s4);
  color: var(--i-ink-2);
  font-family: var(--mono);
  font-size: var(--t-xs);
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: color 100ms linear, background-color 100ms linear;
}

.rig-tab:hover {
  background: var(--i-inset);
  color: var(--i-ink);
}

.rig-tab[aria-selected="true"] {
  border-bottom-color: var(--i-amber);
  background: var(--i-canvas);
  color: var(--i-ink);
}

.rig-tab:focus-visible {
  outline: 2px solid var(--i-cyan);
  outline-offset: -2px;
}

.rig-body {
  display: flex;
  min-height: 0;
  flex: 1;
  flex-direction: column;
  overflow: hidden;
}

/* The pane scrolls, not the page: a 60-line envelope is a long artifact and
   scrolling it inside the instrument is what an inspector does. */
.rig-pane {
  min-height: 0;
  flex: 1;
  overflow: auto;
  overscroll-behavior: contain;
}

.rig-pane[hidden] {
  display: none;
}

/* The honesty label, pinned to the bottom of the rig. docs/DEMO.md calls it
   the flex rather than the hedge: it names what the panes are and hands over
   the link that lets a reader falsify them, and there is no further hedging
   anywhere on the page. */
.rig-foot {
  margin: 0;
  border-top: 1px solid var(--i-rule);
  background: var(--i-surface);
  padding: var(--s2) var(--s4);
  color: var(--i-ink-2);
  font-family: var(--mono);
  font-size: var(--t-xs);
  line-height: 1.6;
}

.rig-foot a {
  color: var(--i-cyan);
}

/* --------------------------------------------------------------------------
   4. The as-of scrubber. A range input, restyled, over a real timeline: the
      eleven ticks are the eleven instants this page holds a captured envelope
      for, and the two labelled marks are the two clocks the pitch is about.
   -------------------------------------------------------------------------- */

.scrub {
  border-bottom: 1px solid var(--i-rule);
  background: var(--i-surface);
  padding: var(--s3) var(--s4) var(--s2);
}

.scrub-top {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  margin: 0 0 var(--s2);
  gap: var(--s2) var(--s4);
}

.scrub-label {
  margin: 0;
  color: var(--i-ink-2);
  font-family: var(--mono);
  font-size: var(--t-tele);
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.scrub-at {
  margin: 0;
  color: var(--i-cyan);
  font-family: var(--mono);
  font-size: var(--t-ui);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  letter-spacing: -0.01em;
}

/* 46px: 34 for the control, 12 under it for the two labels. The labels are
   drawn inside the track and anchored from whichever side keeps them off the
   rig's edge, so nothing here can be clipped. */
.scrub-track {
  position: relative;
  height: 46px;
}

/* The rail the ticks sit on. */
.scrub-track::before {
  position: absolute;
  top: 15px;
  right: 0;
  left: 0;
  height: 1px;
  background: var(--i-rule-2);
  content: "";
}

.scrub-ticks {
  position: absolute;
  top: 9px;
  right: 0;
  left: 0;
  height: 13px;
  margin: 0;
  padding: 0;
  list-style: none;
  pointer-events: none;
}

.scrub-tick {
  position: absolute;
  top: 0;
  width: 1px;
  height: 13px;
  background: var(--i-rule-2);
  transform: translateX(-0.5px);
}

/* A labelled mark runs the full height of the control so the label under it is
   unambiguous about which second it points at. */
.scrub-tick[data-mark] {
  height: 30px;
  margin-top: -6px;
  background: var(--i-ink-2);
}

.scrub-tick[data-mark]::after {
  position: absolute;
  top: 32px;
  left: 4px;
  color: var(--i-ink-2);
  content: attr(data-mark);
  font-family: var(--mono);
  font-size: var(--t-tele);
  letter-spacing: 0.05em;
  line-height: 1;
  white-space: nowrap;
}

/* The one tick that is a fact about the row rather than a stop on the track:
   the minute EDGAR accepted the filing. Nothing in the envelope changes here,
   which is the whole argument, so it is marked in amber and labelled from the
   right so it cannot be mistaken for a detent. */
/* The one tick that is a fact about the row rather than a stop on the track:
   the minute EDGAR accepted the filing. Nothing in the envelope changes here,
   which is the whole argument, so it is marked in amber. Its label is anchored
   from the right because the mark sits at 94% and a left-anchored label would
   run off the rig. */
.scrub-tick--edgar[data-mark] {
  background: var(--i-amber);
}

.scrub-tick--edgar[data-mark]::after {
  right: 4px;
  left: auto;
  color: var(--i-amber);
}

/* The filled part of the rail: how much of the window is behind the handle. */
.scrub-fill {
  position: absolute;
  top: 15px;
  left: 0;
  height: 1px;
  background: var(--i-amber);
}

/* The input itself. It is a real range input so it arrives with keyboard
   stepping, a pointer capture, and the platform's own touch handling; only
   its skin is ours. */
/* app.css gives every control a 1px --field-line boundary, which on a range
   input paints a box around the whole track. The scrubber's boundary is the
   rail, so the border comes off here and nowhere else. */
.scrub-input {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  width: 100%;
  height: 34px;
  min-height: 0;
  margin: 0;
  border: 0;
  background: none;
  padding: 0;
  appearance: none;
  cursor: ew-resize;
  touch-action: pan-y;
}

.scrub-input::-webkit-slider-runnable-track {
  height: 34px;
  border: 0;
  background: none;
}

.scrub-input::-moz-range-track {
  height: 34px;
  border: 0;
  background: none;
}

.scrub-input::-webkit-slider-thumb {
  width: 12px;
  height: 26px;
  border: 1px solid var(--i-canvas);
  border-radius: 0;
  margin-top: 4px;
  background: var(--i-amber);
  appearance: none;
  cursor: ew-resize;
}

.scrub-input::-moz-range-thumb {
  width: 12px;
  height: 26px;
  border: 1px solid var(--i-canvas);
  border-radius: 0;
  background: var(--i-amber);
  cursor: ew-resize;
}

.scrub-input:focus-visible {
  outline: 2px solid var(--i-cyan);
  outline-offset: 2px;
}

/* The step controls. They are the whole story on a phone, where a 1-second
   detent is not something a thumb can land on, and they are the reason the
   scrubber works with no pointer at all. */
.scrub-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  margin-top: var(--s1);
  gap: var(--s2);
}

.scrub-steps {
  display: flex;
  gap: 0;
}

.scrub-step {
  min-width: 34px;
  border: 1px solid var(--i-rule);
  background: var(--i-inset);
  padding: 2px var(--s2);
  color: var(--i-ink-2);
  font-family: var(--mono);
  font-size: var(--t-sm);
  line-height: 1.5;
  cursor: pointer;
  transition: color 100ms linear, background-color 100ms linear;
}

.scrub-step + .scrub-step {
  border-left: 0;
}

.scrub-step:hover:not(:disabled) {
  background: var(--i-rule);
  color: var(--i-amber);
}

/* A disabled step is the one place --i-dim carries a glyph. WCAG 1.4.3
   exempts inactive controls from the contrast floor, and dimming the arrow is
   how the control says the reader is already at the end of the window. */
.scrub-step:disabled {
  color: var(--i-dim);
  cursor: default;
}

.scrub-step:focus-visible {
  outline: 2px solid var(--i-cyan);
  outline-offset: -2px;
}

.scrub-of {
  margin: 0;
  color: var(--i-ink-2);
  font-family: var(--mono);
  font-size: var(--t-tele);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   5. The reading pane — the envelope, read out loud.
   -------------------------------------------------------------------------- */

.rig-read {
  padding: var(--s4);
}

/* The verdict line: the one number that answers the question the scrubber
   asks. It is set at display size because it is the answer. */
.read-count {
  display: flex;
  align-items: baseline;
  margin: 0 0 var(--s3);
  gap: var(--s3);
}

.read-n {
  color: var(--i-ink);
  font-family: var(--mono);
  font-size: 2.5rem;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1;
}

.rig[data-hit="1"] .read-n {
  color: var(--i-green);
}

.read-k {
  color: var(--i-ink-2);
  font-family: var(--mono);
  font-size: var(--t-tele);
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.read-k b {
  display: block;
  color: var(--i-ink);
  font-size: var(--t-sm);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
}

/* The row, when there is one. A definition grid, not a card: label column in
   mono caps, value column in mono, one hairline per row. */
.read-row {
  display: grid;
  margin: 0 0 var(--s3);
  border-top: 1px solid var(--i-rule);
  grid-template-columns: 10.5rem minmax(0, 1fr);
}

.read-row[hidden] {
  display: none;
}

.read-row dt {
  border-bottom: 1px solid var(--i-rule);
  padding: var(--s2) var(--s3) var(--s2) 0;
  color: var(--i-ink-2);
  font-family: var(--mono);
  font-size: var(--t-tele);
  letter-spacing: 0.07em;
  line-height: 1.5;
  text-transform: uppercase;
}

.read-row dd {
  margin: 0;
  border-bottom: 1px solid var(--i-rule);
  padding: var(--s2) 0;
  color: var(--i-ink);
  font-family: var(--mono);
  font-size: var(--t-sm);
  font-variant-numeric: tabular-nums;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.read-row dd.is-clock {
  color: var(--i-cyan);
}

.read-row dd.is-null {
  color: var(--i-yellow);
}

.read-row dd.is-new {
  color: var(--i-green);
}

.read-note {
  margin: 0 0 var(--s3);
  color: var(--i-ink-2);
  font-family: var(--mono);
  font-size: var(--t-sm);
  line-height: 1.5;
}

.read-note b {
  color: var(--i-ink);
  font-weight: 500;
}

.read-note .is-red {
  color: var(--i-red);
}

.read-note .is-green {
  color: var(--i-green);
}

/* The same instant, put to each of the three clocks. This is the argument in
   three lines: the filer clock answers, the availability clock refuses because
   nobody certified that day, and the commit clock answers zero because the row
   reached this corpus in 2026. */
.read-clocks {
  display: grid;
  margin: 0 0 var(--s3);
  border-top: 1px solid var(--i-rule);
  grid-template-columns: 10.5rem minmax(0, 1fr);
}

.read-clocks dt {
  border-bottom: 1px solid var(--i-rule);
  padding: var(--s2) var(--s3) var(--s2) 0;
  color: var(--i-cyan);
  font-family: var(--mono);
  font-size: var(--t-sm);
  line-height: 1.5;
}

.read-clocks dd {
  margin: 0;
  border-bottom: 1px solid var(--i-rule);
  padding: var(--s2) 0;
  color: var(--i-ink);
  font-family: var(--mono);
  font-size: var(--t-sm);
  font-variant-numeric: tabular-nums;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.read-clocks dd.is-refused {
  color: var(--i-red);
}

.read-clocks dd.is-hit {
  color: var(--i-green);
}

/* The certificate, under the count. It is here because on eleven of the twelve
   stops the count does not move and this does: the day keys roll from 03-09 to
   03-10 at midnight, in front of the reader, which is the certificate doing
   its job. Both lists are written from the same capture the raw pane holds. */
.read-cov {
  margin: 0 0 var(--s3);
  border-top: 1px solid var(--i-rule);
  padding-top: var(--s3);
}

.read-cov-h {
  display: flex;
  align-items: baseline;
  margin: 0 0 var(--s2);
  gap: var(--s2);
  color: var(--i-ink-2);
  font-family: var(--mono);
  font-size: var(--t-tele);
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.read-cov-h b {
  color: var(--i-ink);
  font-weight: 500;
  letter-spacing: 0;
}

.read-cov-l {
  margin: 0 0 var(--s3);
  padding: 0;
  list-style: none;
  color: var(--i-cyan);
  font-family: var(--mono);
  font-size: var(--t-sm);
  line-height: 1.6;
  overflow-wrap: anywhere;
}

.read-cov-l li.is-day {
  color: var(--i-green);
}

.read-cov-l li.is-frontier {
  color: var(--i-ink-2);
}

.read-cov-l:last-child {
  margin-bottom: 0;
}

.read-cov-none {
  margin: 0;
  color: var(--i-ink-2);
  font-family: var(--mono);
  font-size: var(--t-sm);
}

/* --------------------------------------------------------------------------
   6. The raw pane — the captured envelopes, one per stop, as a unified diff
      against the first capture.
   -------------------------------------------------------------------------- */

.rig-raw {
  padding: 0;
}

.scrub-json {
  width: max-content;
  min-width: 100%;
  margin: 0;
  border: 0;
  border-radius: 0;
  background: var(--i-canvas);
  padding: var(--s3) 0 var(--s4);
  color: var(--i-ink);
  font-family: var(--mono);
  font-size: var(--t-sm);
  font-variant-numeric: tabular-nums;
  line-height: 1.5;
}

.jl {
  display: block;
  border-left: 2px solid transparent;
  padding-right: var(--s4);
}

.jg {
  display: inline-block;
  width: 2.5ch;
  padding-left: var(--s2);
  color: var(--i-dim);
  user-select: none;
}

.jl--add {
  border-left-color: var(--i-green);
  background: rgb(16 185 129 / 12%);
}

.jl--add .jg {
  color: var(--i-green);
}

.jl--del {
  border-left-color: var(--i-red);
  background: rgb(239 68 68 / 12%);
}

.jl--del .jg {
  color: var(--i-red);
}

.jl--del > :not(.jg) {
  opacity: 0.75;
}

.j-k {
  color: var(--i-ink-2);
}

.j-s {
  color: var(--i-ink);
}

.j-t {
  color: var(--i-cyan);
}

.j-key {
  color: var(--i-cyan);
}

.j-hash {
  color: var(--i-ink-2);
}

.j-n {
  color: var(--i-amber);
  font-weight: 500;
}

.j-b {
  color: var(--i-amber);
}

.j-null {
  color: var(--i-yellow);
}

.rig-elide {
  margin: 0;
  border-top: 1px solid var(--i-rule);
  background: var(--i-surface);
  padding: var(--s2) var(--s4);
  color: var(--i-ink-2);
  font-family: var(--mono);
  font-size: var(--t-xs);
  line-height: 1.5;
}

.rig-elide a {
  color: var(--i-cyan);
}

/* --------------------------------------------------------------------------
   7. The run-it-yourself pane.
   -------------------------------------------------------------------------- */

.rig-run {
  padding: var(--s4);
}

.rig-run pre {
  margin: 0 0 var(--s3);
  border: 1px solid var(--i-rule);
  background: var(--i-surface);
  padding: var(--s3);
  color: var(--i-ink);
  font-size: var(--t-sm);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.rig-run p {
  margin: 0 0 var(--s3);
  color: var(--i-ink-2);
  font-size: var(--t-sm);
  line-height: 1.55;
}

.rig-run p:last-child {
  margin-bottom: 0;
}

.rig-run b {
  color: var(--i-ink);
  font-weight: 500;
}

.rig-run a {
  color: var(--i-cyan);
}

/* --------------------------------------------------------------------------
   8. The full-bleed ribbon: the ablation chart, then the line that fixes it.
      It touches the hero above it — no top padding, a 2px structural rule —
      and it runs edge to edge.

      Colour here is the same vocabulary as everywhere else. Red and dashed is
      the arm the file marks reachable: false; muted is the honest-but-late
      baseline; amber is the instrument's own clock. The dash is the second
      signal, so "not reachable" survives with colour switched off.
   -------------------------------------------------------------------------- */

.lp-ribbon {
  border-top: 2px solid var(--i-rule-2);
  border-bottom: 2px solid var(--i-rule-2);
  background: var(--i-canvas);
  color: var(--i-ink);
}

.lp-ribbon-in {
  display: grid;
  align-items: stretch;
  grid-template-columns: 7fr 5fr;
}

.lp-ribbon-chart {
  min-width: 0;
  margin: 0;
  border-right: 1px solid var(--i-rule);
  padding: var(--s5) var(--s6) var(--s5) var(--gutter);
}

.lp-ribbon-h {
  margin: 0 0 var(--s3);
  color: var(--i-ink-2);
  font-family: var(--mono);
  font-size: var(--t-tele);
  font-weight: 400;
  letter-spacing: 0.07em;
  line-height: 1.7;
  text-transform: uppercase;
}

.lp-ribbon-h b {
  color: var(--i-amber);
  font-weight: 500;
}

.chart {
  min-height: 210px;
  margin: 0 0 var(--s4);
}

.chart svg {
  display: block;
  max-width: 100%;
}

.chart .g-line {
  stroke: var(--i-rule);
  stroke-width: 1;
}

.chart .g-base {
  stroke: var(--i-rule-2);
  stroke-width: 1;
}

.chart .g-lab {
  fill: var(--i-ink-2);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.04em;
}

/* The two acceptance-gap marks: a clock fact, so cyan, and dashed so it does
   not read as a fourth curve. */
.chart .g-mark {
  stroke: var(--i-cyan);
  stroke-dasharray: 2 4;
  stroke-width: 1;
}

.chart .g-marklab {
  fill: var(--i-cyan);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.04em;
}

.chart .c {
  stroke-width: 1.5;
  stroke-linejoin: round;
}

.chart .c-lab {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: -0.02em;
}

@media (min-width: 560px) {
  .chart .c-lab {
    font-size: 13px;
  }
}

.chart .c-sub {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  opacity: 0.75;
}

.chart path.c-leaky {
  stroke: var(--i-red);
  stroke-dasharray: 4 3;
}

.chart text.c-leaky {
  fill: var(--i-red);
}

.chart path.c-dump {
  stroke: var(--i-ink-2);
}

.chart text.c-dump {
  fill: var(--i-ink-2);
}

.chart path.c-pit {
  stroke: var(--i-amber);
  stroke-width: 2;
}

.chart text.c-pit {
  fill: var(--i-amber);
}

.chart-note {
  margin: 0;
  max-width: 78ch;
  color: var(--i-ink-2);
  font-size: var(--t-sm);
  line-height: 1.6;
}

.chart-note b {
  color: var(--i-ink);
  font-weight: 500;
}

.chart-note .is-red {
  color: var(--i-red);
}

.chart-note .is-amber {
  color: var(--i-amber);
}

.chart-note a {
  color: var(--i-cyan);
}

.lp-ribbon-nums {
  display: grid;
  min-width: 0;
  align-content: center;
  padding: 0;
  grid-template-rows: repeat(3, auto);
}

.lp-num {
  display: flex;
  align-items: baseline;
  margin: 0;
  padding: var(--s4) var(--gutter) var(--s4) var(--s6);
  gap: var(--s4);
}

.lp-num + .lp-num {
  border-top: 1px solid var(--i-rule);
}

.lp-num-n {
  min-width: 5.5ch;
  color: var(--i-red);
  font-family: var(--mono);
  font-size: 1.75rem;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1;
  white-space: nowrap;
}

.lp-num--dump .lp-num-n {
  color: var(--i-ink-2);
}

.lp-num--pit .lp-num-n {
  color: var(--i-amber);
}

.lp-num-l {
  color: var(--i-ink-2);
  font-size: var(--t-sm);
  line-height: 1.5;
}

.lp-num-l b {
  color: var(--i-ink);
  font-weight: 500;
}

/* The fix strip. It touches the chart above it: one hairline, no air. */
.lp-ribbon-fix {
  display: grid;
  align-items: center;
  border-top: 1px solid var(--i-rule);
  padding: var(--s4) var(--gutter);
  gap: var(--s3) var(--s6);
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
}

.lp-ribbon-fix .lp-ribbon-h {
  margin: 0 0 var(--s2);
  grid-column: 1;
}

.lp-ribbon-fix .diff {
  overflow-x: auto;
  margin: 0;
  border: 0;
  background: none;
  grid-column: 1;
  grid-row: 2;
}

.lp-ribbon-fix .diff-add,
.lp-ribbon-fix .diff-del,
.lp-ribbon-fix .diff-ctx {
  padding: 2px var(--s3);
  font-size: var(--t-sm);
  white-space: pre;
}

.lp-ribbon-nums-inline {
  display: flex;
  flex-direction: column;
  margin: 0;
  gap: var(--s2);
  grid-column: 2;
  grid-row: 1 / span 2;
  color: var(--i-ink-2);
  font-size: var(--t-sm);
  line-height: 1.4;
}

.lp-ribbon-nums-inline b {
  color: var(--i-red);
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* --------------------------------------------------------------------------
   9. The ledger section: the master.idx line at full bleed with a side rail.
   -------------------------------------------------------------------------- */

.lp-ledger {
  display: grid;
  align-items: stretch;
  grid-template-columns: 7fr 5fr;
}

.lp-ledger-art {
  min-width: 0;
  border-right: 1px solid var(--rule-2);
  padding: var(--s6) var(--s6) var(--s6) var(--gutter);
}

.lp-ledger-art .ledger {
  margin: 0;
}

.lp-ledger-side {
  min-width: 0;
  padding: var(--s6) var(--gutter) var(--s6) var(--s6);
}

.lp-ledger-side h2 {
  margin: 0 0 var(--s3);
}

.lp-ledger-side p {
  margin: 0 0 var(--s3);
  color: var(--ink-2);
  font-size: var(--t-base);
  line-height: 1.55;
}

.lp-ledger-side p:last-child {
  margin-bottom: 0;
}

/* --------------------------------------------------------------------------
   10. The dense grids: the two control arms, and the three fields.
   -------------------------------------------------------------------------- */

.lp-dense {
  padding: var(--s6) var(--gutter);
}

.lp-dense-head {
  display: grid;
  align-items: end;
  margin: 0 0 var(--s4);
  border-bottom: 1px solid var(--rule-2);
  padding-bottom: var(--s2);
  gap: var(--s4);
  grid-template-columns: minmax(0, 1fr) minmax(0, 30rem);
}

.lp-dense-head h2 {
  margin: 0;
  border: 0;
  padding: 0;
  font-size: var(--t-2xl);
  letter-spacing: -0.02em;
}

.lp-dense-head p {
  margin: 0;
  color: var(--ink-2);
  font-size: var(--t-sm);
  line-height: 1.5;
}

/* Three fields, three rows, one hairline each. Not three cards: a card would
   pad them apart and pretend they are peers of equal weight. */
.lp-keys {
  display: grid;
  border-top: 1px solid var(--rule);
  grid-template-columns: 12rem minmax(0, 22rem) minmax(0, 1fr);
}

.lp-keys > * {
  border-bottom: 1px solid var(--rule);
  padding: var(--s3) var(--s4) var(--s3) 0;
}

.lp-key-n {
  margin: 0;
  color: var(--ink);
  font-size: var(--t-h3);
  font-weight: 600;
  letter-spacing: -0.015em;
}

.lp-key-f {
  margin: 0;
  color: var(--key);
  font-family: var(--mono);
  font-size: var(--t-sm);
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.lp-key-p {
  margin: 0;
  color: var(--ink-2);
  font-size: var(--t-sm);
  line-height: 1.5;
}

/* --------------------------------------------------------------------------
   11. Plans. Three columns, and the middle one is wider because it is the
       one most people buy — the asymmetry is the recommendation.
   -------------------------------------------------------------------------- */

.lp-plans {
  display: grid;
  border-top: 1px solid var(--rule-2);
  grid-template-columns: 1fr 1.25fr 1fr;
}

.lp-plan {
  display: flex;
  min-width: 0;
  flex-direction: column;
  padding: var(--s5) var(--s5) var(--s5) 0;
  gap: var(--s3);
}

.lp-plan + .lp-plan {
  border-left: 1px solid var(--rule);
  padding-left: var(--s5);
}

.lp-plan--pick {
  border-top: 2px solid var(--act);
  margin-top: -2px;
}

.lp-plan h3 {
  margin: 0;
  border: 0;
  padding: 0;
  font-size: var(--t-h3);
  letter-spacing: -0.01em;
}

.lp-plan-price {
  margin: 0;
  color: var(--ink);
  font-size: 1.75rem;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
}

.lp-plan-price span {
  color: var(--ink-2);
  font-size: var(--t-sm);
  font-weight: 400;
  letter-spacing: 0;
}

.lp-plan-p {
  margin: 0;
  color: var(--ink-2);
  font-size: var(--t-sm);
  line-height: 1.5;
}

.lp-plan-specs {
  display: grid;
  margin: 0;
  border-top: 1px solid var(--rule);
  grid-template-columns: auto minmax(0, 1fr);
}

.lp-plan-specs dt {
  border-bottom: 1px solid var(--rule);
  padding: var(--s1) var(--s3) var(--s1) 0;
  color: var(--ink-2);
  font-family: var(--mono);
  font-size: var(--t-tele);
  letter-spacing: 0.07em;
  line-height: 1.8;
  text-transform: uppercase;
}

.lp-plan-specs dd {
  margin: 0;
  border-bottom: 1px solid var(--rule);
  padding: var(--s1) 0;
  color: var(--ink);
  font-family: var(--mono);
  font-size: var(--t-sm);
  font-variant-numeric: tabular-nums;
  line-height: 1.8;
  text-align: right;
}

.lp-plan-specs dd.is-off {
  color: var(--ink-2);
}

.lp-plan-foot {
  margin: auto 0 0;
}

/* --------------------------------------------------------------------------
   12. The persistent telemetry bar. It is fixed to the bottom of the window,
       it is dark in both schemes, and every value in it is written by
       /js/demo.js from a real same-origin read of /health and /v1/meta. The
       text shipped in the markup says when it was written, so a stale reading
       is never presented as a live one.
   -------------------------------------------------------------------------- */

.tele {
  position: fixed;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  overflow-x: auto;
  border-top: 1px solid var(--i-rule);
  background: var(--i-canvas);
  padding: 0 var(--gutter);
  gap: var(--s5);
  color: var(--i-ink-2);
  font-family: var(--mono);
  font-size: var(--t-tele);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.06em;
  line-height: var(--tele-h);
  white-space: nowrap;
  scrollbar-width: none;
}

.tele::-webkit-scrollbar {
  display: none;
}

.tele-item {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: var(--s2);
}

.tele-k {
  color: var(--i-ink-2);
  text-transform: uppercase;
}

.tele-v {
  color: var(--i-ink);
}

.tele-note {
  flex: none;
  color: var(--i-ink-2);
  letter-spacing: 0.04em;
  text-transform: none;
}

/* The state lamp. Grey until the browser has actually read /health, green
   when it answered ok, red when it did not — three states, never two. */
.tele-dot {
  width: 6px;
  height: 6px;
  flex: none;
  background: var(--i-dim);
}

.tele[data-state="ok"] .tele-dot {
  background: var(--i-green);
}

.tele[data-state="down"] .tele-dot {
  background: var(--i-red);
}

.tele[data-state="ok"] [data-sys="state"] {
  color: var(--i-green);
}

.tele[data-state="down"] [data-sys="state"] {
  color: var(--i-red);
}

/* --------------------------------------------------------------------------
   13. Responsive. 375px is the floor and the scrubber has to work there with
       a thumb, so below 900px the hero stacks, the rig keeps its full width,
       and the step buttons grow to a 44px touch target.
   -------------------------------------------------------------------------- */

@media (max-width: 1080px) {
  .lp-keys {
    grid-template-columns: 10rem minmax(0, 1fr);
  }

  .lp-key-p {
    grid-column: 1 / -1;
    padding-top: 0;
  }
}

@media (max-width: 900px) {
  .lp-hero,
  .lp-ribbon-in,
  .lp-ledger,
  .lp-plans {
    grid-template-columns: minmax(0, 1fr);
  }

  .lp-pitch {
    border-right: 0;
    border-bottom: 1px solid var(--rule-2);
    padding: var(--s7) var(--gutter) var(--s6);
  }

  .lp-ribbon-chart,
  .lp-ledger-art {
    border-right: 0;
    border-bottom: 1px solid var(--i-rule);
    padding: var(--s5) var(--gutter);
  }

  .lp-ribbon-fix {
    grid-template-columns: minmax(0, 1fr);
  }

  .lp-ribbon-fix .lp-ribbon-h,
  .lp-ribbon-fix .diff,
  .lp-ribbon-nums-inline {
    grid-column: 1;
    grid-row: auto;
  }

  .lp-ribbon-nums-inline {
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--s2) var(--s5);
  }

  .lp-ledger-art {
    border-bottom-color: var(--rule-2);
  }

  .lp-ledger-side {
    padding: var(--s5) var(--gutter);
  }

  .lp-num {
    padding: var(--s3) var(--gutter);
  }

  .lp-plan,
  .lp-plan + .lp-plan {
    border-left: 0;
    padding: var(--s5) 0;
  }

  .lp-plan + .lp-plan {
    border-top: 1px solid var(--rule);
  }

  .lp-plan--pick {
    border-top: 2px solid var(--act);
    margin-top: 0;
  }

  .lp-dense-head {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s2);
  }
}

@media (max-width: 640px) {
  .lp-h1 {
    font-size: clamp(1.75rem, 1.1rem + 3.4vw, 2.25rem);
  }

  .rig-head,
  .scrub,
  .rig-read,
  .rig-run {
    padding-right: var(--s3);
    padding-left: var(--s3);
  }

  .rig-tab {
    flex: 1;
    padding: var(--s2) var(--s2);
    text-align: center;
  }

  .read-n {
    font-size: 2rem;
  }

  .read-row,
  .read-clocks {
    grid-template-columns: minmax(0, 1fr);
  }

  .read-row dt,
  .read-clocks dt {
    border-bottom: 0;
    padding-bottom: 0;
  }

  .read-row dd,
  .read-clocks dd {
    padding-top: 0;
  }

  .lp-num-n {
    font-size: 1.375rem;
  }

  .lp-keys {
    grid-template-columns: minmax(0, 1fr);
  }

  .lp-keys > * {
    border-bottom: 0;
    padding: var(--s1) 0;
  }

  .lp-key-n {
    border-top: 1px solid var(--rule);
    padding-top: var(--s3);
  }

  .lp-key-p {
    padding-bottom: var(--s3);
  }
}

/* A thumb needs 44px; a mouse does not. The scrubber's own track grows too,
   because a 34px strip is a hard thing to catch while scrolling a page. */
@media (pointer: coarse) {
  .scrub-track {
    height: 56px;
  }

  .scrub-input,
  .scrub-input::-webkit-slider-runnable-track,
  .scrub-input::-moz-range-track {
    height: 44px;
  }

  .scrub-track::before,
  .scrub-fill {
    top: 20px;
  }

  .scrub-ticks {
    top: 14px;
  }

  .scrub-tick[data-mark] {
    height: 40px;
  }

  .scrub-tick[data-mark]::after {
    top: 42px;
  }

  .scrub-input::-webkit-slider-thumb {
    width: 16px;
    height: 34px;
    margin-top: 5px;
  }

  .scrub-input::-moz-range-thumb {
    width: 16px;
    height: 34px;
  }

  .scrub-step,
  .rig-tab,
  .lp-q-copy {
    min-height: 44px;
  }
}

/* A reader who asked for less motion gets the end of the story instead of the
   attract loop: the scrubber is parked on the last instant, where the 8-K is
   visible, and it still drags. The lamp never blinks. */
@media (prefers-reduced-motion: reduce) {
  .rig[data-play="on"] .rig-live::before {
    animation: none;
    background: var(--i-dim);
  }
}

/* --------------------------------------------------------------------------
   14. v4 leftovers. /demo and any page still carrying the v4 recorded-session
       markup must keep rendering while it is replaced; these rules give the
       old class names the instrument's colours and nothing else. They are
       deletable the day no page emits a .demo-stage.
   -------------------------------------------------------------------------- */

.demo-stage,
.demo-sysbar {
  border: 1px solid var(--i-rule);
  background: var(--i-canvas);
  color: var(--i-ink);
  font-family: var(--mono);
  font-size: var(--t-sm);
}

.demo-bar,
.demo-sysbar {
  padding: var(--s2) var(--s3);
}

.demo-k {
  color: var(--i-ink-2);
}

.demo-s {
  color: var(--i-ink);
}

.demo-n {
  color: var(--i-amber);
}

.demo-elide,
.demo-cap,
.demo-fine {
  color: var(--i-ink-2);
}

.demo-label {
  color: var(--ink-2);
  font-size: var(--t-sm);
}
