
    /* ── PROPHET LIVE strip (P1, spec §3) ─────────────────────────────────────────
       The provisional hue is the lane's OWN component-scoped token, chosen against
       three neighbours — no global token is added and theme.css stays untouched:
         · not --link / --info  → a chip must never read as clickable
         · not --up / --down    → must never read directional (and must not flip under
                                  html[data-lang="zh"] 红涨绿跌)
         · not any --pv-*       → must never read as a nightly verdict (green = confirmed,
                                  and only the nightly build confirms)
       Escalation to the strongest moment (confirming_into_close) is carried by FILL and
       WEIGHT, never by hue: one hue for the whole live family. There is deliberately no
       status dot anywhere — a green "live" pulse is unreachable on a 15-min-delayed plane
       and would encode certainty. The settle rail is the sanctioned proof of life. */
    /* --plv-rh is THE height contract's single free parameter — see .plv-body below. */
    #prophet-live{--plv:#62a0e8;--plv-rh:27px;display:none}
    html[data-theme="light"] #prophet-live{--plv:#2f6fd0}
    #prophet-live.visible{display:block}
    /* Every header item takes the token pill's line box, so a SHORTER token ("READ
       PAUSED") cannot yield a shorter wrapped line than a longer one. Measured: it did,
       by 2.5px — which is a height change, i.e. a board shove. */
    .plv-hd{display:flex;align-items:center;gap:8px;row-gap:4px;flex-wrap:wrap}
    .plv-hd > *{min-height:17px;display:inline-flex;align-items:center}
    /* gap, not a literal space: `.plv-hd > *` makes the title an inline-flex box and flex
       layout discards the whitespace-only text node between the ◐ glyph and the label. */
    .plv-title{margin:0;gap:6px;font-size:12px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--plv)}
    .plv-token{font-size:9.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--plv);
      border:1px solid color-mix(in srgb,var(--plv) 34%,transparent);
      background:color-mix(in srgb,var(--plv) 9%,transparent);border-radius:999px;padding:1.5px 8px;white-space:nowrap}
    /* ── WORST-CASE RESERVATION (the general fix for mode-dependent height) ──────
       Three boxes here hold text that changes with the MODE, and every one of them was
       an unreserved height variable: a wrapped line count is a function of string
       length, so the panel measured up to 32.75px taller in one mode than another and
       shoved the whole board. Reserving a hand-measured min-height per breakpoint would
       need a magic number per width PER LANGUAGE and would rot the first time a word
       changed. Instead every variant stays in the DOM, stacked in ONE grid cell, and
       only the active one is visible: the browser then reserves max(all modes) at
       whatever width and language it is actually rendering, with no numbers at all.
       `visibility:hidden` is load-bearing — it keeps the box sized while removing the
       inactive text from the accessibility tree, so nothing invisible is ever announced
       or read as a claim. `display:none` would size nothing; `opacity:0` would be read. */
    .plv-hd > .plv-token{display:inline-grid;justify-items:center;text-align:center}
    /* The as-of reserves its line even when it has nothing to stamp: at <=340px it sits on
       header line 2 beside the token, so an empty box collapsed that line and shoved the
       board 17px on exactly the days there is no read to stamp. `tabular-nums` above is
       what makes the 12:00 reserver exactly as wide as any real two-digit-hour stamp. */
    .plv-hd > .plv-asof{display:inline-grid;justify-items:end}
    .plv-sub,.plv-fn{display:grid}
    .plv-v{grid-area:1/1;visibility:hidden}
    .plv-v.is-on{visibility:visible}
    /* The TOKEN only needs a mode-independent width where the header wraps — above the
       680px query it sits on one line with room to spare, so drop the reservation there
       and let the pill hug its own text. Below it the pill keeps a constant width, which
       is what stops a short token ("READ PAUSED") from fitting beside the title where a
       long one wraps and taking the as-of onto a line of its own. */
    @media (min-width:681px){ .plv-token .plv-v:not(.is-on){display:none} }
    .plv-token.is-dark{color:var(--muted);border-color:color-mix(in srgb,var(--muted) 30%,transparent);background:color-mix(in srgb,var(--muted) 7%,transparent)}
    .plv-token.is-closed{color:var(--pv-hold);border-color:color-mix(in srgb,var(--pv-hold) 34%,transparent);background:transparent}
    .plv-more{font-size:10.5px;color:var(--muted);background:none;border:0;padding:0 2px;font-family:inherit;cursor:pointer;text-decoration:underline;text-underline-offset:2px}
    .plv-asof{margin-left:auto;font-size:10.5px;color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}
    .plv-sub{font-size:11.5px;line-height:1.45;color:var(--text);opacity:.82;margin:5px 0 0;min-height:17px}
    /* SIGNATURE — the settle rail. Fixed height; the only inline style the JS writes
       anywhere on this page is this fill's width (and the now-tick's left). It encodes the
       one variable that actually converts "forming" into "confirmed": remaining tape.
       aria-hidden — the as-of text and the end-cap label carry it in words. */
    .plv-rail{display:flex;align-items:center;gap:8px;margin:11px 0 10px;height:14px}
    .plv-rail-track{position:relative;flex:1;height:3px;border-radius:2px;background:var(--line);overflow:visible}
    .plv-rail-fill{position:absolute;inset:0 auto 0 0;width:0;height:3px;border-radius:2px;background:color-mix(in srgb,var(--plv) 46%,transparent)}
    .plv-rail-now{position:absolute;top:-3px;left:0;width:1.5px;height:9px;border-radius:1px;background:var(--plv)}
    .plv-rail-lbl{flex:none;font-size:9.5px;color:var(--muted);white-space:nowrap}
    #prophet-live.is-dark .plv-rail{opacity:.45}
    #prophet-live.is-dark .plv-rail-fill,#prophet-live.is-dark .plv-rail-now{display:none}
    #prophet-live.is-closed .plv-rail-now{display:none}
    #prophet-live.is-closed .plv-rail-fill{width:100%!important;background:color-mix(in srgb,var(--pv-hold) 30%,transparent)}
    /* rows: dtp-column discipline — ONE header labels the figure columns, so no row ever
       repeats a constant (doctrine Law 4) and every figure is self-labelled (Law 3). */
    .plv-cols,.plv-row{display:grid;grid-template-columns:minmax(96px,auto) 46px 1fr 74px 74px 52px;align-items:baseline;gap:0 10px}
    .plv-cols{font-size:9.5px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--muted);
      border-bottom:1px solid var(--line);padding-bottom:4px}
    .plv-c2,.plv-c3,.plv-c4{text-align:right}
    /* EVERY cell is pinned to its column, header and row alike. The labels always were;
       the row cells were auto-placed, and auto-placement RESHUFFLES when a cell in the
       middle is removed: the ≤560px rule hides .plv-nm (column 3), so `now` slid into
       that column — which the same rule sets to 0 — and printed on top of `cross level`
       ("$224260.85" at 375px). Pinning makes any future column demotion a no-op for the
       cells that stay. */
    .plv-c1{grid-column:1}.plv-c2{grid-column:4}.plv-c3{grid-column:5}.plv-c4{grid-column:6}
    .plv-row > .plv-chip{grid-column:1}
    .plv-tk{grid-column:2}.plv-nm{grid-column:3}
    .plv-now{grid-column:4}.plv-lvl{grid-column:5}.plv-since{grid-column:6}
    /* empty modes keep the hairline rule (height invariance) but HIDE rather than collapse
       the labels — dead column headings over an empty box read as a broken panel. */
    #prophet-live.is-empty .plv-cols > span{visibility:hidden}
    /* THE HEIGHT CONTRACT — 3 reserved slots, and the reservation is DERIVED from the row
       height instead of being a second hand-measured number. The spec (and the mockup)
       pinned both sides independently at min-height 24.5px / 75.5px; on the real page the
       row measures 26.06px, because this page inherits line-height:1.5 while the mockup
       inherited `normal`, and a baseline-aligned grid row is as tall as
       max(above-baseline) + max(below-baseline) across the chip and the text — not as tall
       as the chip box. The strip came out 4.69px taller in live than in quiet/dark/closed:
       a board shove every time the last cross faded. Two independently guessed numbers
       cannot stay equal, so now `height` (not min-height) fixes the row and the body
       reserves exactly 3 of them. --plv-rh is the one parameter; it must stay >= the row's
       natural content height (21.06px content + 5px padding at time of writing). Re-run
       mockups/refs/prophet_live/verify_p1.py after ANY change to the chip box, the row
       font sizes, or the inherited line-height. */
    .plv-body{min-height:calc(var(--plv-rh) * 3 + 2px);display:flex;flex-direction:column;padding-top:2px}
    .plv-row{padding:2.5px 0;height:var(--plv-rh);box-sizing:border-box;font-size:12.5px;text-decoration:none;color:inherit}
    .plv-row:hover .plv-nm,.plv-row:hover .plv-tk{color:var(--ink-link, var(--link))}
    .plv-tk{font-weight:800;letter-spacing:.01em;white-space:nowrap}
    .plv-nm{color:var(--muted);font-size:11px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
    .plv-now,.plv-lvl,.plv-since{text-align:right;font-variant-numeric:tabular-nums;font-family:var(--font-mono,monospace);white-space:nowrap}
    .plv-now{font-weight:700}
    .plv-lvl{color:var(--muted)}
    .plv-since{color:var(--muted);font-size:11px}
    .plv-chip{display:inline-flex;align-items:center;gap:4px;justify-self:start;font-size:10px;font-weight:800;
      letter-spacing:.04em;text-transform:uppercase;line-height:1.35;padding:2px 8px;border-radius:999px;white-space:nowrap;
      background:color-mix(in srgb,var(--plv) 10%,transparent);color:var(--plv);
      border:1px solid color-mix(in srgb,var(--plv) 42%,transparent)}
    /* the strongest moment escalates by FILL + WEIGHT, never by hue */
    .plv-chip--close{background:var(--plv);color:#fff;border-color:transparent}
    /* "fell back" (grey, it came back toward you) vs "ran past" (amber, don't chase) —
       the two fade stories never share a word and never share a hue, and neither uses a
       directional colour, so 红涨绿跌 holds by construction. Do not add --up/--down. */
    .plv-chip--drop{background:color-mix(in srgb,var(--pv-hold) 10%,transparent);color:var(--pv-hold);
      border-color:color-mix(in srgb,var(--pv-hold) 32%,transparent)}
    .plv-chip--over{background:color-mix(in srgb,var(--pv-wait) 11%,transparent);color:var(--pv-wait);
      border-color:color-mix(in srgb,var(--pv-wait) 40%,transparent)}
    .plv-row.is-past .plv-tk,.plv-row.is-past .plv-now{opacity:.72}
    .plv-none{flex:1;display:flex;flex-direction:column;justify-content:center;gap:3px;font-size:12px;color:var(--muted)}
    .plv-last{font-size:10.5px;opacity:.8}
    .plv-fn{border-top:1px solid var(--line);margin-top:7px;padding-top:7px;font-size:10.5px;line-height:1.5;color:var(--muted)}
    .plv-fig{font-variant-numeric:tabular-nums;font-weight:700;color:var(--text)}  /* figures mono, words never */
    .plv-row.is-new{animation:plv-in .2s ease-out}
    @keyframes plv-in{from{opacity:0}to{opacity:1}}
    @media (prefers-reduced-motion:reduce){.plv-row.is-new{animation:none}}
    @media (max-width:680px){
      /* Header pinned to a deterministic TWO lines: [title ? +N] / [token as-of].
         The reorder alone is not enough. Without it the 44px +N button landed on a THIRD
         line the moment a 4th row appeared — a 21px shove of the whole board, every 5
         minutes. With it, WHICH line the token lands on was still a function of its own
         string length: the short "READ PAUSED" fitted beside the title while
         "INTRADAY · 15-MIN DELAYED" did not, so the header measured 40.25px in dark
         against 41.25px in live — a 1px shove on every mode change. The ::before is a
         zero-content flex item with basis 100%: it consumes the rest of line 1, so the
         token ALWAYS starts line 2 no matter how long it is, and it carries the 4px the
         row-gap gave up so the pinned height is unchanged (18 + 4 + 19.25). */
      .plv-hd{row-gap:0}
      .plv-hd::before{content:"";order:2;flex:0 0 100%;height:4px}
      .plv-more{order:1;margin-left:auto}
      .plv-token{order:3}
      .plv-asof{order:4;margin-left:auto}
      .plv-cols,.plv-row{grid-template-columns:minmax(84px,auto) 44px 1fr 68px 68px 0}
      .plv-c4,.plv-since{display:none}          /* SINCE demoted; it survives in the row tip */
    }
    @media (max-width:560px){
      /* Phone layout: [chip] [ticker] · [now]. Two things had to change here.
         (1) Column 1 keeps min-content. With minmax(0,auto) the grid handed column 1 ZERO
             pixels — the 1fr name column outbid it — and the 148px "HOLDING INTO CLOSE"
             pill printed straight over the ticker at 375px and below.
         (2) The chip is then allowed to WRAP rather than to shorten. Collapsing it to the
             bare ◐ glyph (the card-chip idiom) would leave hue as the only carrier of the
             state, and on the strip the state word IS the content. Wrapping costs row
             height instead — paid ONCE through --plv-rh, so every mode grows together and
             the height contract still holds.
         Cross level is demoted here with the company name (both survive in the row tip);
         NOW stays, because it is the figure the reader is actually looking for. .plv-c3 is
         the CROSS LEVEL heading (column 5), so it goes with .plv-lvl — not with .plv-nm,
         which has no heading of its own. */
      #prophet-live{--plv-rh:40px}
      .plv-cols,.plv-row{grid-template-columns:minmax(min-content,auto) 44px minmax(0,1fr) 66px 0 0;
        gap:0 8px;align-items:center}
      .plv-nm,.plv-c3,.plv-lvl{display:none}
      .plv-chip{white-space:normal;text-align:center}
    }
    