/* Tape Zones price ladder (/zones). Dark shell to match Gamma Migration and the option chain.
   The BANDS are deliberately light: their six fills are the page's whole vocabulary and are set
   inline from tape-zones-model.js, so the legend and the ladder can never disagree about which
   colour means what. Nothing in this file may restate a state colour. */
:root {
    --zn-bg: #0e1116;
    --zn-panel: #161b22;
    --zn-line: #2a323d;
    --zn-tx: #e6edf3;
    --zn-dim: #8b949e;
    --zn-dim2: #6e7681;
    --zn-neg: #f85149;
    --zn-accent: #58a6ff;
}

body {
    margin: 0;
    background: var(--zn-bg);
    color: var(--zn-tx);
    font: 13px/1.55 ui-sans-serif, -apple-system, "Segoe UI", Roboto, sans-serif;
}

.zn-page { max-width: 1080px; margin: 0 auto; padding: 20px 18px 60px; position: relative; }
.zn-head h1 { font-size: 20px; margin: 0 0 4px; font-weight: 650; }
.zn-sub { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 14px; }

.zn-status {
    max-width: 1080px; margin: 0 auto; padding: 8px 18px 0;
    color: var(--zn-dim2); font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
}

.zn-badge {
    font-size: 11px; letter-spacing: .05em; text-transform: uppercase;
    padding: 2px 8px; border-radius: 999px;
    border: 1px solid var(--zn-line); color: var(--zn-dim);
}
.zn-badge-shadow { border-color: #d29922; color: #d29922; }
.zn-badge-overnight { border-color: var(--zn-accent); color: var(--zn-accent); }
.zn-clock, .zn-gamma { font-size: 11.5px; color: var(--zn-dim2); }
/* Records arriving for another chain are ignored, and the page says how many — "unknown while
   nothing is arriving" and "unknown while somebody else's chain is arriving" are different faults. */
.zn-gamma-rejected {
    font-size: 11.5px; color: #d29922; cursor: help;
    border-bottom: 1px dotted currentColor;
}

.zn-waiting { padding: 48px 0; text-align: center; color: var(--zn-dim2); }

/* --- stale ---------------------------------------------------------------------------------- */
/* The overlay sits ON the page, not beside it: a frozen board that still reads as live is the one
   failure a descriptive page can cause by itself. */
.zn-stale-overlay {
    position: sticky; top: calc(var(--oc-topnav-h, 42px) + 6px); z-index: 5;
    background: rgba(248, 81, 73, .14); border: 1px solid var(--zn-neg); border-radius: 8px;
    padding: 9px 14px; margin-bottom: 12px; color: var(--zn-neg);
    display: flex; align-items: baseline; gap: 10px;
}
.zn-stale-overlay small { color: var(--zn-tx); }
/* Overnight MARKS; it never hides and never fades. The zones are real, they are just not RTH. */
.zn-page.zn-overnight .zn-ladder, .zn-page.zn-overnight .zn-table {
    box-shadow: inset 4px 0 0 var(--zn-accent);
}

/* STALE is marked, not faded (2026-08-13, USER: "remove this blur layer"). The ladder used to drop
   to .45 opacity + grayscale(.5), which is exactly the reading the banner above already gives you —
   except it also made the prices unreadable. The banner says stale; the rail keeps saying it while
   you can still read every number.
   Declared AFTER overnight ON PURPOSE: zones.js appends both classes independently, they have equal
   specificity, and source order decides. Stale is the higher-stakes state, so stale wins. */
.zn-page.zn-stale .zn-ladder, .zn-page.zn-stale .zn-table {
    box-shadow: inset 4px 0 0 var(--zn-neg);
    outline: 1px solid rgba(248, 81, 73, .55);
    outline-offset: 2px;
}

/* Both at once: stale keeps the left rail, overnight is composed onto the right edge rather than
   being dropped. box-shadow REPLACES, it never merges — so the combination has to be written out. */
.zn-page.zn-stale.zn-overnight .zn-ladder, .zn-page.zn-stale.zn-overnight .zn-table {
    box-shadow: inset 4px 0 0 var(--zn-neg), inset -4px 0 0 var(--zn-accent);
    outline: 1px solid rgba(248, 81, 73, .55);
    outline-offset: 2px;
}

/* --- legend --------------------------------------------------------------------------------- */
.zn-legend {
    display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
    background: var(--zn-panel); border: 1px solid var(--zn-line); border-radius: 8px;
    padding: 9px 12px; margin-bottom: 14px; font-size: 12px;
}
.zn-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.zn-legend-sep { color: var(--zn-dim2); }
.zn-legend-fallback { font-style: italic; }
.zn-swatch {
    width: 16px; height: 12px; border-radius: 3px; border: 1px solid transparent;
    display: inline-block;
}

/* --- ladder --------------------------------------------------------------------------------- */
.zn-ladder {
    display: flex; gap: 10px;
    background: var(--zn-panel); border: 1px solid var(--zn-line); border-radius: 8px;
    padding: 12px; margin-bottom: 16px;
}
.zn-ladder-empty {
    flex-direction: column; align-items: center; justify-content: center; gap: 6px;
    padding: 46px 12px; color: var(--zn-dim);
}
.zn-ladder-empty strong { font-size: 15px; color: var(--zn-tx); }
.zn-ladder-empty small { color: var(--zn-dim2); }

.zn-axis {
    display: flex; flex-direction: column; justify-content: space-between;
    width: 62px; flex: none; color: var(--zn-dim2); font-size: 11px; text-align: right;
}
.zn-track { position: relative; flex: 1 1 auto; min-height: 420px; }

.zn-band {
    position: absolute; left: 0; right: 0; box-sizing: border-box;
    border-radius: 4px; padding: 3px 8px; overflow: hidden;
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    font-size: 12px;
}
.zn-band-price { display: flex; flex-direction: column; line-height: 1.25; }
.zn-band-price small { font-size: 10.5px; }
.zn-band-label { font-size: 11.5px; text-align: right; }
.zn-band-forming { font-style: italic; }

.zn-spot {
    position: absolute; left: 0; right: 0; height: 0;
    border-top: 2px solid var(--zn-accent);
    display: flex; align-items: center; gap: 8px;
}
.zn-spot-tag {
    background: var(--zn-accent); color: #04121f; font-weight: 700; font-size: 11px;
    padding: 1px 7px; border-radius: 999px; transform: translateY(-50%);
}
.zn-spot-sub { color: var(--zn-accent); font-size: 11px; transform: translateY(-50%); }

/* --- table ---------------------------------------------------------------------------------- */
.zn-table {
    width: 100%; border-collapse: collapse;
    background: var(--zn-panel); border: 1px solid var(--zn-line); border-radius: 8px;
    font-size: 12px; margin-bottom: 14px;
}
.zn-table th, .zn-table td {
    text-align: left; padding: 7px 10px; border-bottom: 1px solid var(--zn-line);
}
.zn-table th { color: var(--zn-dim); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: .05em; }
.zn-table tr:last-child td { border-bottom: none; }
.zn-table td small { color: var(--zn-dim2); }

/* --- footer --------------------------------------------------------------------------------- */
/* Persistent in EVERY state — it is the measured result the page is a description of. */
.zn-foot {
    border-top: 1px solid var(--zn-line); padding-top: 10px;
    color: var(--zn-dim2); font-size: 11.5px; line-height: 1.6;
}

/* ── LIVE ZONE RE-VALIDATION (2026-08-10) ─────────────────────────────────────
   HOLDING blinks; CONTRADICTED warns; THIN and UNMEASURED stay quiet ON PURPOSE.
   A touch with no flow, or a board too old to carry the check, must never read as
   confirmation — the same rule the wall column follows. The measured gap behind the
   colour: after HOLDING the defended edge broke 34.9%, after CONTRADICTED 46.6%
   (259 sessions, 15,853 revisits, split-sample +11.8 pts in both halves). */
.zn-live {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 10px; font-weight: 900; letter-spacing: .05em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 3px; white-space: nowrap;
}
.zn-live-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.zn-live-holding { color: #0d7a52; background: rgba(13, 122, 82, .12); }
.zn-live-holding .zn-live-dot { animation: zn-live-blink .85s steps(1, end) infinite; }
@keyframes zn-live-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: .15; } }
@media (prefers-reduced-motion: reduce) { .zn-live-holding .zn-live-dot { animation: none; } }
.zn-live-contradicted { color: #a3271a; background: rgba(163, 39, 26, .12); }
.zn-live-thin { color: #6b7280; background: rgba(107, 114, 128, .10); }
.zn-live-armed { color: #3b6ea5; background: rgba(59, 110, 165, .10); }
.zn-live-unmeasured { color: #8b8b86; background: rgba(139, 139, 134, .08); }
.zn-live-cell { line-height: 1.35; }
.zn-live-cell small { display: block; color: #6b7280; font-size: 10.5px; margin-top: 2px; }
/* The row tint is the only thing that carries the warning at a glance; it is applied to the
   CONTRADICTED row alone, never to a thin or unmeasured one. */
.zn-row.zn-live-row-contradicted > td { background: rgba(163, 39, 26, .05); }

@media (prefers-color-scheme: dark) {
  .zn-live-holding { color: #44f19a; background: rgba(68, 241, 154, .12); }
  .zn-live-contradicted { color: #ff6a76; background: rgba(255, 106, 118, .13); }
  .zn-live-thin { color: #8b99ab; background: rgba(139, 153, 171, .10); }
  .zn-live-armed { color: #5aa9ff; background: rgba(90, 169, 255, .10); }
  .zn-live-unmeasured { color: #6c7a8c; background: rgba(108, 122, 140, .08); }
  .zn-live-cell small { color: #8b99ab; }
  .zn-row.zn-live-row-contradicted > td { background: rgba(255, 106, 118, .06); }
}

/* ── ZONE-STATE PALETTE (2026-08-10, USER) ────────────────────────────────────
   GREEN = buying, RED = selling, ORANGE = absorption. The six colours used to be
   hard-coded pastels in the model, applied inline: chosen for a light card, and on
   the dark ES board they read as washed-out grey. They are variables now, so each
   theme gets a palette that actually separates the states and the model stays free
   of presentation.
   The two dealer-absorption states are both ORANGE by instruction; they are kept
   apart by DEPTH (amber = selling absorbed below, tangerine = buying absorbed
   above), because merging them into one colour would lose which side was absorbed. */
:root {
  --zn-fill-customer-buying: #D6F5E3;   --zn-text-customer-buying: #0A6B3D;
  --zn-fill-customer-selling: #FBDDDD;  --zn-text-customer-selling: #A11B1B;
  --zn-fill-dealer-absorption-down: #FDE7CC; --zn-text-dealer-absorption-down: #8A4A05;
  --zn-fill-dealer-absorption-up: #FFEEDA;   --zn-text-dealer-absorption-up: #A85E12;
  --zn-fill-customer-absorption: #FCEEDB;    --zn-text-customer-absorption: #8A5A22;
  --zn-fill-absorption-gamma-unknown: #F3EDE4; --zn-text-absorption-gamma-unknown: #6E6256;
  --zn-text-forming: #7C8794;
}
/* Dark: saturated translucent fills and text bright enough to tell the quadrants
   apart AT A GLANCE — the colour exists to be read from across the room. */
@media (prefers-color-scheme: dark) {
  :root {
    --zn-fill-customer-buying: rgba(46, 229, 148, .32);   --zn-text-customer-buying: #5CFFB4;
    --zn-fill-customer-selling: rgba(255, 82, 82, .32);   --zn-text-customer-selling: #FF8A8A;
    --zn-fill-dealer-absorption-down: rgba(255, 149, 0, .34);  --zn-text-dealer-absorption-down: #FFB74D;
    --zn-fill-dealer-absorption-up: rgba(255, 183, 77, .28);   --zn-text-dealer-absorption-up: #FFD08A;
    --zn-fill-customer-absorption: rgba(255, 167, 38, .22);    --zn-text-customer-absorption: #FFC780;
    --zn-fill-absorption-gamma-unknown: rgba(190, 160, 120, .20);
    --zn-text-absorption-gamma-unknown: #C9B79B;
    --zn-text-forming: #9AA7B6;
  }
  /* At small band heights the border carries most of the signal, so give it weight. */
  .zn-band { box-shadow: 0 0 0 1px rgba(255, 255, 255, .06) inset; }
  .zn-band-price { color: #F2F7FF; font-weight: 800; }
  .zn-table td, .zn-table th { color: #E6EDF7; }
}

/* ── READABILITY (2026-08-10, USER: "I cannot read anything") ─────────────────
   Two separate faults made the ladder unreadable, and only one of them was size.

   1. OVERLAP. Bands are absolutely positioned from their price range, and a
      PROVISIONAL "forming" cell can cover exactly the same range as a FINAL zone —
      measured live: two pairs sharing an identical top (44.375% and 56.875%), their
      labels printed straight on top of each other. Forming bands now take the RIGHT
      side of the lane and finalized zones the LEFT, so two bands at the same price
      can never write over one another. They still sit at their true price.
   2. The price was the smallest thing in the row, when it is the one value you look
      up first. It is now the largest. */
.zn-band { padding: 4px 10px; }
.zn-band.zn-band-forming { left: 52%; }
.zn-band:not(.zn-band-forming) { right: 0; }

.zn-band-price {
    font-size: 15px; font-weight: 900; letter-spacing: -.01em;
    color: var(--zn-price-ink); text-shadow: 0 1px 0 rgba(0, 0, 0, .35);
    line-height: 1.15; white-space: nowrap;
}
.zn-band-price small { font-size: 11px; font-weight: 700; }
.zn-band-label { font-size: 11px; }
.zn-band-forming .zn-band-price { font-size: 12.5px; font-weight: 800; }

/* The ladder axis and the spot tag are read at the same glance as the bands. */
.zn-axis, .zn-ladder-axis, .zn-scale { font-size: 12px; font-weight: 700; }
.zn-spot-tag { font-size: 12.5px; font-weight: 900; padding: 2px 9px; }

/* The zone table's price column is the same lookup, so it gets the same weight. */
.zn-table td:first-child strong { font-size: 14px; font-weight: 900; }
.zn-table td:first-child small { font-size: 11px; }

:root { --zn-price-ink: #12181f; }
@media (prefers-color-scheme: dark) {
  :root { --zn-price-ink: #FFFFFF; }
  .zn-band-price { text-shadow: 0 1px 2px rgba(0, 0, 0, .75); }
  .zn-band-label { opacity: 1; }
}

/* ── TABLE CONTRAST (2026-08-10, USER: "faded, hidden on a black sheet") ──────
   The STATE column was inline-coloured text on the black table. Those colours are
   tuned to sit ON a band fill; with nothing behind them they read as dim brown —
   the row's most important word was its least visible one. It is a chip now, so it
   carries its own fill exactly like the ladder band and the live-check chip.
   Everything else here is the same complaint: secondary text was set by opacity,
   which on black turns information into texture. */
.zn-state-chip {
    display: inline-block; padding: 3px 9px; border-radius: 4px;
    font-size: 11.5px; font-weight: 800; letter-spacing: .01em;
    border: 1px solid transparent; white-space: nowrap;
}
.zn-table { border-collapse: separate; border-spacing: 0; }
.zn-table th {
    font-size: 10.5px; font-weight: 900; letter-spacing: .07em;
    padding: 10px 12px; border-bottom: 2px solid rgba(140, 160, 190, .35);
}
.zn-table td { padding: 11px 12px; border-bottom: 1px solid rgba(140, 160, 190, .16); }
.zn-table tbody tr:nth-child(even) td { background: rgba(255, 255, 255, .022); }
.zn-table tbody tr:hover td { background: rgba(120, 170, 255, .10); }

@media (prefers-color-scheme: dark) {
  .zn-table td, .zn-table th { color: #EEF4FD; }
  .zn-table th { color: #AEBED4; }
  /* Secondary text gets a real colour instead of an opacity fade: at 0.5 alpha on
     black, 11px text stops being readable and becomes decoration. */
  .zn-table td small, .zn-table .zn-sub { color: #9FB2C9; opacity: 1; font-size: 11.5px; }
  .zn-live-cell small { color: #A8BACF; opacity: 1; }
  .zn-table td:first-child strong { color: #FFFFFF; }
  .zn-state-chip { filter: saturate(1.15); }
}

/* ── LIVE CHECK COLUMN (2026-08-10, USER: "almost not visible") ───────────────
   The live-check chips kept the low-alpha fills from their first pass (~.12), and
   the numbers under them were grey. Next to the state chips — which now carry a
   real fill — the column that says whether the zone is STILL TRUE was the faintest
   thing on the row. It is the newest and most actionable reading on the page, so it
   is now the strongest.

   The numbers matter as much as the word: "202 / 167 lots · imb +0.09" is the
   evidence for the chip, so it is near-white and tabular, not a grey footnote. */
.zn-live {
    font-size: 11.5px; font-weight: 900; padding: 3px 10px;
    border: 1px solid transparent; letter-spacing: .04em;
}
.zn-live-dot { width: 7px; height: 7px; }
.zn-live-cell small {
    font-size: 11.5px; font-variant-numeric: tabular-nums; letter-spacing: .01em;
    margin-top: 3px;
}

@media (prefers-color-scheme: dark) {
  .zn-live-holding {
      color: #062E1C; background: #47F0A4; border-color: #47F0A4;
      box-shadow: 0 0 10px rgba(71, 240, 164, .35);
  }
  .zn-live-holding .zn-live-dot { background: #062E1C; }
  .zn-live-contradicted {
      color: #2B0508; background: #FF6B75; border-color: #FF6B75;
      box-shadow: 0 0 10px rgba(255, 107, 117, .30);
  }
  .zn-live-contradicted .zn-live-dot { background: #2B0508; }
  .zn-live-armed { color: #BBDBFF; background: rgba(90, 169, 255, .26); border-color: rgba(90, 169, 255, .55); }
  .zn-live-thin { color: #D3DDEA; background: rgba(160, 176, 198, .26); border-color: rgba(160, 176, 198, .5); }
  .zn-live-unmeasured { color: #CBD3DE; background: rgba(150, 158, 170, .22); border-color: rgba(150, 158, 170, .45); }
  .zn-live-cell small { color: #D7E3F2; opacity: 1; }
  /* The warning tint was .05 alpha — invisible. A contradicted row should be
     obvious from the far side of the screen, with a left rail to anchor it. */
  .zn-row.zn-live-row-contradicted > td { background: rgba(255, 107, 117, .12); }
  .zn-row.zn-live-row-contradicted > td:first-child { box-shadow: inset 3px 0 0 #FF6B75; }
  .zn-table tbody tr:nth-child(even) td { background: rgba(255, 255, 255, .045); }
  .zn-table tbody tr:hover td { background: rgba(120, 170, 255, .16); }
}

/* ── UPDATED COLUMN (2026-08-10, USER) ────────────────────────────────────────
   A zone's age is the END of its newest bucket — when it last took in evidence.
   Deliberately NOT the board timestamp: the board republishes every second, so
   using it would print "1s ago" against a zone last touched four hours back. */
.zn-updated strong { display: block; font-size: 13px; font-weight: 900; font-variant-numeric: tabular-nums; }
.zn-updated small { display: block; font-size: 11px; margin-top: 2px; }
@media (prefers-color-scheme: dark) {
  .zn-updated strong { color: #FFFFFF; }
  .zn-updated small { color: #9FB2C9; opacity: 1; }
}

/* ── LEVEL LADDER (2026-08-15) ───────────────────────────────────────────────
   Four questions, four channels. Each rule below serves exactly one of them, and
   nothing else in this file may answer the same question:
     1 which side is it        -> .zn-side-* fill        (pale; identity, never emphasis)
     2 is price inside it      -> .zn-inside/.zn-outside border weight ONLY
     3 is it still standing    -> .zn-strike             (one line across the box)
     4 which edge gave way     -> .zn-edge-*             (that one edge)
   Text is NOT a channel: every band reads at full brightness in both states. Dimming the
   type to also mean "price is elsewhere" is what made the previous build unreadable.     */
:root{
  --zn-floor:#2FD87A; --zn-ceil:#FF5A5A; --zn-absorb:#FF9A2E;
  --zn-break:#FF4D4D; --zn-near:#5AB7FF; --zn-gold:#FFC24D;
}
.zn-ladder .zn-axis{position:relative;width:92px;flex:none}
.zn-tick{position:absolute;right:12px;transform:translateY(-50%);text-align:right;
  font-variant-numeric:tabular-nums;white-space:nowrap}
.zn-tick b{display:block;font:900 16px/1.1 ui-monospace,Menlo,monospace;color:#FFF}
.zn-tick small{display:block;font:700 10px/1.3 ui-monospace,Menlo,monospace;color:#9FB4C8}
.zn-lanes{position:absolute;left:0;top:0;bottom:0;right:0}

.zn-band{position:absolute;border-radius:8px;padding:6px 9px;overflow:visible;
  display:flex;flex-direction:column;justify-content:center;gap:0}
.zn-side-floor{background:rgba(47,216,122,.11)}
.zn-side-ceiling{background:rgba(255,90,90,.10)}
.zn-inside{border:2px solid}
.zn-inside.zn-side-floor{border-color:var(--zn-floor)}
.zn-inside.zn-side-ceiling{border-color:var(--zn-ceil)}
.zn-outside{border:1px solid}
.zn-outside.zn-side-floor{border-color:rgba(47,216,122,.30)}
.zn-outside.zn-side-ceiling{border-color:rgba(255,90,90,.28)}
/* about to be tested — OUTSIDE the box, so the fill keeps meaning direction only */
.zn-near{box-shadow:0 0 0 2px rgba(90,183,255,.55),0 0 20px rgba(90,183,255,.26)}

.zn-band-price{font:900 16px/1.12 ui-monospace,Menlo,monospace;color:#FFF;
  font-variant-numeric:tabular-nums;white-space:nowrap;letter-spacing:-.01em}
.zn-band-size{display:flex;align-items:baseline;gap:7px;white-space:nowrap}
.zn-band-size .zn-plain{font:800 13px/1.2 ui-monospace,Menlo,monospace;color:#DFE9F4;
  font-variant-numeric:tabular-nums}
.zn-gold{font-family:ui-monospace,Menlo,monospace;font-weight:900;color:var(--zn-gold);
  line-height:1.12;font-variant-numeric:tabular-nums;text-shadow:0 0 12px rgba(255,194,77,.38)}
.zn-side-net{font:800 10.5px/1.3 ui-sans-serif;color:#9FB4C8;letter-spacing:.05em;
  text-transform:uppercase;font-style:normal}

/* Net line: zero is the centre, LENGTH is the whole message. No track — an empty full-width
   bar weighs the same whether the net is 4.9k or 0.4k, which is exactly what it must not do. */
.zn-net{position:relative;display:block;height:3px;margin-top:3px}
.zn-net:before{content:"";position:absolute;left:50%;top:-3px;height:9px;width:1px;
  background:rgba(255,255,255,.42)}
.zn-net i{position:absolute;top:0;height:3px;border-radius:2px}
.zn-net .zn-net-up{background:var(--zn-floor);box-shadow:0 0 7px rgba(47,216,122,.45)}
.zn-net .zn-net-dn{background:var(--zn-ceil);box-shadow:0 0 7px rgba(255,90,90,.45)}

.zn-band-state{margin-top:3px}
.zn-band-state .zn-chip{display:inline-flex;align-items:center;border-radius:999px;padding:3px 9px;
  font:900 10px/1 ui-sans-serif;letter-spacing:.09em;text-transform:uppercase;font-style:normal}
.zn-chip-holding{background:var(--zn-floor);color:#06210F}
.zn-chip-contradicted{background:var(--zn-break);color:#2A0606}
.zn-chip-thin,.zn-chip-unmeasured{background:#22303F;color:#C4D3E2;border:1px solid #35485C}
.zn-dist{display:inline-flex;align-items:center;font:800 10.5px/1 ui-monospace,Menlo,monospace;
  color:#DFE9F4;border:1px solid #46596E;background:rgba(255,255,255,.05);border-radius:999px;
  padding:4px 9px;font-variant-numeric:tabular-nums;font-style:normal}
.zn-dist-near{color:#CDE8FF;border-color:var(--zn-near)}

/* Q3 — one line straight across. Present = no longer standing. Two states, no third. */
.zn-strike{position:absolute;left:-1px;right:-1px;top:50%;height:0;z-index:6;pointer-events:none}
.zn-strike:before{content:"";position:absolute;left:0;right:0;top:-1px;height:4px;
  background:#06090D;opacity:.34}
.zn-strike:after{content:"";position:absolute;left:0;right:0;top:0;height:2.5px;
  background:var(--zn-break)}

/* Q4 — the one edge it defends. A price break turns THAT edge dashed; nothing else changes. */
.zn-edge{position:absolute;left:-1px;right:-1px;height:3px;z-index:5;border-radius:2px}
.zn-edge-lo{bottom:-2px}.zn-edge-hi{top:-2px}
.zn-edge-held{background:var(--zn-absorb);box-shadow:0 0 9px rgba(255,154,46,.55)}
.zn-edge-faint{background:rgba(255,154,46,.34)}
.zn-edge-gone{background:repeating-linear-gradient(90deg,var(--zn-break) 0 6px,transparent 6px 12px)}

.zn-brk{position:absolute;right:6px;z-index:8;background:var(--zn-break);color:#2A0606;
  font:900 10px/1 ui-monospace,Menlo,monospace;padding:3px 6px;border-radius:4px;white-space:nowrap;
  box-shadow:0 2px 8px rgba(0,0,0,.55);font-style:normal}
.zn-brk-lo{bottom:6px}.zn-brk-hi{top:6px}
/* No verdict yet => no side to claim: dashed neutral outline, NO fill. A forming bucket must
   never be paintable as a finished floor or ceiling. */
.zn-side-none{background:transparent;border-style:dashed !important;border-color:#5A6E82 !important}
.zn-side-none .zn-band-price{color:#C3D5E6}

/* The outcome sits with the net, never apart from it: "absorbed" and "carried" are what make
   the same net sign mean opposite things. */
.zn-outc{display:block;margin-top:2px;font:800 10px/1.15 var(--oe-font-sans,ui-sans-serif);
  letter-spacing:.07em;text-transform:uppercase;white-space:nowrap}
.zn-outc-abs{color:var(--oe-absorb,#FF9A2E)}
.zn-outc-won{color:#FFD2D2}
