/*
 * Strike Board stylesheet — strike-box-redesign.md rev 4, mock v44 is the normative visual.
 *
 * Rules baked in here (do not "improve" them away):
 *  - SOLID FLAT ONLY: no shadow declarations of any kind, no decorative gradients (SBX-122).
 *    The liquidity ribbon's heat colors are DATA, painted per-column as solid segments.
 *  - Fluid to the full viewport (SBX-140): no max-width cap; wings are 1fr each and the grid
 *    consumes a 49" monitor's entire width with zero overlap (nowrap fields + flex-wrap rows).
 *  - Fixed uniform box height (SBX-004): --sbx-h; checkbox toggles reserve rows via
 *    visibility, never display (SBX-118).
 *  - Both themes: dark default; body.sbx-light overrides. Clock/spot schedule colors are set
 *    inline by JS from one source (SBX-119/125).
 *  - Type scale per SBX-127: base 17px, nothing below ~11px, tabular numerals everywhere.
 */

/* ---------- page frame ---------- */
#strikeBoardRoot { display: block; }
.sbx-page {
  --sbx-core-w: clamp(392px, 26vw, 520px);
  /* SBX-147: measured worst-case NATURAL height of the squeezed layout (165px) + slack.
     The chip strip has FIXED SLOTS in three rows, so this height no longer depends on the data
     at all — a sparse ES row and the densest SPX row measure the same. That is what let the
     budget come down from 212px: it used to reserve room for a dense row that ES never shows,
     which the owner saw as dead space in every cell (2026-08-17).
     384px -> 174px was -55%: ~8 strikes on a 1440p screen instead of 3.
     SBX-171 then moved every reading OUT of the gamma bar into its own row, and SBX-173 gave the
     bar its full 30px back (owner: "i want bigger like before") — the 15px that costs is carried
     HERE rather than by a thinner bar. SBX-180 then removed the buy/sell ratio bar (owner:
     "remove the sell and buy bar below to net classifier") and with it the row it was alone in —
     MEASURED at 8px in every box. The box gives back what it honestly can: 187px, not the full
     8px. The densest boxes were already close to the old 189px budget, and the binding case is
     ZOOM 0.6, where sub-pixel rounding costs more than the arithmetic suggests — the gate clips
     at 186px and passes at 187px, so 187 is a measured floor, not a guess. Still 25px under the
     212px it came from. */
  /* 2026-08-31: 187 -> 207 for the SPOT BAND lane below the gamma. The lane itself is 18px (15px
     track + 3px margin) and the densest box overflowed by exactly that at zoom 1 — but the binding
     case is still ZOOM 0.6, where sub-pixel rounding costs 2px more than the arithmetic says, the
     same way it did when this budget was last measured. 206 clips at 0.6 and 207 passes, so 207 is
     measured, not derived. The budget exists to keep every box the SAME height whatever its data,
     not to forbid a row: a new row is PAID FOR here rather than squeezed in, which would have
     quietly shortened a row somebody already measured. */
  --sbx-h: 207px;
  --sbx-red: #e62e2e;
  --sbx-green: #299e3b;
  --sbx-orange: #f28f1f;
  /* STAND_DOWN and UNAVAILABLE are not degrees of the three above and must not wear their hues.
     A calendar veto is not a measurement, and "we cannot see" is off the ordered scale entirely
     (design §5.6) — a grey that reads as absence is the point, never a dimmed green. */
  --sbx-violet: #8b6fd4;
  --sbx-grey: #6f7b91;
  background: #07090f;
  color: #e9edf6;
  font: 17px/1.45 -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, sans-serif;
  font-variant-numeric: tabular-nums;
  min-height: 100vh;
  padding: 16px 20px 56px;
}
/* The Wall toggle adds one 18px row (15px track + 3px margin) to every box. Paid for here, not squeezed:
   +20px, the same measured cost the spot band lane's identical row took (18px plus the 2px zoom-0.6
   sub-pixel rounding the squeeze gate found). With the toggle off the budget is untouched. */
.sbx-page.sbx-wall-on { --sbx-h: 227px; }
.sbx-page * { box-sizing: border-box; margin: 0; padding: 0; }
.sbx-page h1 { font-size: 20px; color: #f4f7fc; font-weight: 650; letter-spacing: .01em; margin-bottom: 12px; }

/* utility text tones */
.sbx-pos { color: #7fd08b; }
.sbx-neg { color: #e07a9a; }
.sbx-dim { color: #8a96ac; }

/* ---------- pinned context header ---------- */
/* The nav rail (.oc-topnav) is ALSO sticky at top: 0, with z-index 999. Pinning these bars at
   the same offset put them UNDERNEATH it the moment the page scrolled, and the nav WRAPS by
   design — so on a board with more nav items (ES) it grows to three lines and swallowed the
   first two bars entirely: DIRECTION/INDICATORS and DELTA FLOW simply were not there (owner,
   2026-08-17, on Edge/ES). Stick below the nav instead. The offset is measured at runtime,
   because the nav's height depends on how many items wrap at the current width — a hard-coded
   value is wrong the moment the window changes or a nav item is added. */
.sbx-topbars { position: sticky; top: var(--sbx-nav-h, 0px); z-index: 40; background: #07090f; padding-top: 2px; }
.sbx-bar {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  background: #0b0e16; border: 1px solid rgba(119, 138, 168, .28); border-bottom: 0;
  padding: 8px 18px; min-height: 44px;
}
.sbx-bar:first-child { border-radius: 8px 8px 0 0; }
.sbx-bar .t { font-size: 12px; font-weight: 800; letter-spacing: .14em; color: #b8c5da; white-space: nowrap; }

.sbx-dirchip { display: inline-flex; align-items: center; gap: 9px; font-size: 15px; font-weight: 800; letter-spacing: .08em;
               border-radius: 5px; padding: 4px 12px; background: #1c2b12; color: #a8e07f; border: 1px solid rgba(168, 224, 127, .4); white-space: nowrap; }
.sbx-dirchip .hz { font-size: 12px; font-weight: 600; opacity: .8; }
/* Vol-premium danger chip. SAME SHAPE as .sbx-dirchip beside it — inline-flex, 9px gap, 15px/800,
   .08em tracking, 5px radius, 4px 12px, a tinted fill with its border at 40% alpha — because it is
   a peer verdict on the same bar, not a louder one. The STATE is carried by hue and border only:
   no opacity, no filter, no shadow (SBX-122, and the page-wide no-faded-states rule). */
.sbx-dangerchip { display: inline-flex; align-items: center; gap: 9px; font-size: 15px; font-weight: 800;
                  letter-spacing: .08em; border-radius: 5px; padding: 4px 12px; white-space: nowrap;
                  border: 1px solid; text-decoration: none; }
.sbx-dangerchip .hz { font-size: 12px; font-weight: 600; opacity: .8; letter-spacing: .04em; }
.sbx-dangerchip:hover { filter: brightness(1.12); }
.sbx-dangerchip:focus-visible { outline: 2px solid #b8c5da; outline-offset: 2px; }
.sbx-dangerchip.dang { background: #2a1010; color: #ff8d83; border-color: rgba(230, 46, 46, .4); }
.sbx-dangerchip.elev { background: #2b1f0c; color: #ffc266; border-color: rgba(242, 143, 31, .4); }
/* CLEAR is green because nothing is firing — NOT because selling is safe. The chip's own words
   (NO DANGER FIRING) carry that distinction; see danger-clock-model.js chip(). */
.sbx-dangerchip.clear { background: #0f2416; color: #7fd894; border-color: rgba(41, 158, 59, .4); }
.sbx-dangerchip.sd { background: #1e1830; color: #b9a4ec; border-color: rgba(139, 111, 212, .4); }
.sbx-dangerchip.na { background: #161b25; color: #8e9aae; border-color: rgba(111, 123, 145, .4); }
/* The §9 lock. Its own badge beside the chip rather than a restyling of it: the verdict is shown
   as the service published it, and the fact that it is UNVALIDATED is a separate statement. */
.sbx-dangerlock { font-size: 11px; font-weight: 800; letter-spacing: .12em; color: #b9a4ec;
                  background: #1e1830; border: 1px solid rgba(139, 111, 212, .4);
                  border-radius: 4px; padding: 3px 8px; white-space: nowrap; }
.sbx-dirchip.unusual { background: #2e2410; color: #ffd965; border-color: rgba(255, 217, 101, .45); }
.sbx-dirchip.off { background: #161c29; color: #8fa0b8; border-color: rgba(143, 160, 184, .3); }
.sbx-trig { font-size: 12.5px; color: #a9b5ca; min-width: 0; }

.sbx-tfs { display: flex; gap: 12px; margin-left: auto; align-items: center; flex-wrap: wrap; }
.sbx-tf { display: flex; flex-direction: column; align-items: center; min-width: 34px; }
.sbx-tf .l { font-size: 11px; color: #94a3bd; }
.sbx-tf .v { font-size: 15px; font-weight: 700; }
.sbx-tf .v.bull { color: #7fd08b; } .sbx-tf .v.bear { color: #e07a9a; } .sbx-tf .v.na { color: #8a96ac; }
/* NEUTRAL, UNRELIABLE and absence are three different facts and get three different marks; a
   single shared dash claimed a silent timeframe and an explicit NEUTRAL were the same thing. */
.sbx-tf .v.neu { color: #8a96ac; } .sbx-tf .v.unr { color: #c8a24a; }
/* MALFORMED is a fault in the RECORD, not a verdict — its own mark and its own colour. */
.sbx-tf .v.mal { color: #e07a9a; }
.sbx-qual.unknown { color: #c8a24a; }
.sbx-consensus.tie { color: #b9c2d4; }
/* Dealer-ledger signal: ARMED is live, DEFENDED has already held once, ARMING is still forming.
   Solid fills only (SBX-122), and the chip occupies a fixed slot like every other. */
.sbx-chip.dl { font-weight: 800; letter-spacing: .03em; }
.sbx-chip.dl.armed { background: #2e2410; color: #ffd965; border-color: rgba(255, 217, 101, .45); }
.sbx-chip.dl.defended { background: #10331c; color: #7fd08b; border-color: rgba(127, 208, 139, .45); }
.sbx-chip.dl.arming { background: #161c29; color: #9fb0c9; border-color: rgba(159, 176, 201, .38); }
/* A CONFLICT chip must not wear the confident green of a real verdict (Codex r5 MINOR-2). */
.sbx-consensus.conflict { color: #c8a24a; }
/* Producer quality badges: market-data staleness and CLOSED/HOLIDAY are different facts from
   transport staleness, and each says so in words rather than being folded into the arrows. */
/* Badges live in a RESERVED slot of fixed width. Rendered conditionally into the wrapping
   .sbx-tfs flex row they changed the row's occupied width, which can push a wrap line and change
   the header's height at some viewport/font-scale thresholds — the header has the same
   constant-metrics rule as the strike box (Codex r9 MINOR). The slot is always present and always
   the same size, so the badges inside it cost nothing. */
.sbx-qualslot { flex: 0 0 auto; width: 168px; overflow: hidden; display: flex; align-items: center; }
.sbx-qual { font-size: 11px; font-weight: 700; letter-spacing: .04em; white-space: nowrap;
            overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.sbx-qual.stale { color: #c8a24a; }
.sbx-qual.closed { color: #8a96ac; }
/* The producer's own "advisory" flag, marked without changing the glyph or the colour: a text
   decoration paints inside the line box, so the strip's height is identical with and without it. */
.sbx-tf .v.adv { text-decoration: underline dotted; text-underline-offset: 2px; }
.sbx-consensus { font-size: 13.5px; font-weight: 800; color: #a8e07f; white-space: nowrap; }

/* gamma leadership bar (top strip): K_A at the left end, K_B at the right, needle on a
   log-scaled track. The needle TRANSITIONS so a move reads as a slide, not a jump. */
.sbx-leadbar { gap: 14px; }
.sbx-leadchip { font-size: 12.5px; font-weight: 800; letter-spacing: .08em; border-radius: 4px; padding: 2px 8px; white-space: nowrap; }
.sbx-leadchip.a { background: #2b1f4d; color: #c6b3ff; }
.sbx-leadchip.b { background: #0f3340; color: #7fd8e8; }
.sbx-leadchip.even { background: #161c29; color: #b8c5da; }
.sbx-leadchip.wait { background: #33131c; color: #ff8fb0; }
.sbx-leadregime { font-size: 10px; font-weight: 800; letter-spacing: .1em; border-radius: 3px; padding: 2px 6px; white-space: nowrap;
  border: 1px solid rgba(119, 138, 168, .45); color: #b8c5da; }
.sbx-leadregime.approaching { color: #7fd08b; border-color: rgba(127, 208, 139, .55); }
.sbx-leadregime.receding { color: #e8b57f; border-color: rgba(232, 181, 127, .55); }
.sbx-leadregime.straddle { color: #9fb0ff; border-color: rgba(159, 176, 255, .55); }
body.sbx-light .sbx-leadregime { color: #4a5670; border-color: #c9d2e0; }
body.sbx-light .sbx-leadregime.approaching { color: #177a41; }
body.sbx-light .sbx-leadregime.receding { color: #9a5b12; }
body.sbx-light .sbx-leadregime.straddle { color: #3a45a8; }
.sbx-leadend { font-size: 13px; font-weight: 700; white-space: nowrap; }
.sbx-leadend.a { color: #c6b3ff; }
.sbx-leadend.b { color: #7fd8e8; }
.sbx-leadtrack { position: relative; flex: 1 1 320px; min-width: 240px; height: 22px; border-radius: 11px;
  background: linear-gradient(90deg, #2b1f4d 0%, #161c29 50%, #0f3340 100%); border: 1px solid rgba(119, 138, 168, .28); }
.sbx-leadtrack.off { opacity: .45; }
.sbx-leadtrack .mid { position: absolute; left: 50%; top: -3px; bottom: -3px; width: 2px; margin-left: -1px; background: rgba(255, 255, 255, .45); }
.sbx-leadtrack .tick { position: absolute; top: 3px; font-size: 10px; color: #8fa0b8; letter-spacing: .04em; }
.sbx-leadtrack .tick.lo { left: 8px; } .sbx-leadtrack .tick.hi { right: 8px; }
.sbx-leadneedle { position: absolute; top: -5px; width: 6px; height: 30px; margin-left: -3px; border-radius: 3px;
  background: #ffd866; border: 1px solid #07090f; transition: left .4s ease; }
.sbx-leadneedle.pinned { background: #ff8fb0; }
body.sbx-light .sbx-leadchip.a { background: #ece6ff; color: #4a2fa8; }
body.sbx-light .sbx-leadchip.b { background: #e0f4f8; color: #0f6b80; }
body.sbx-light .sbx-leadchip.even { background: #eef1f7; color: #4a5670; }
body.sbx-light .sbx-leadchip.wait { background: #fbe6ec; color: #b02a55; }
body.sbx-light .sbx-leadend.a { color: #4a2fa8; } body.sbx-light .sbx-leadend.b { color: #0f6b80; }
body.sbx-light .sbx-leadtrack { background: linear-gradient(90deg, #ece6ff 0%, #eef1f7 50%, #e0f4f8 100%); border-color: #c9d2e0; }
body.sbx-light .sbx-leadtrack .mid { background: rgba(28, 35, 51, .45); }
body.sbx-light .sbx-leadtrack .tick { color: #5d6b84; }
body.sbx-light .sbx-leadneedle { background: #d99a00; border-color: #ffffff; }

/* Candle Direction panel (under the leadership bar). NOTE: it must never restyle `.sbx-dirchip` —
   that class belongs to the older 0DTE DirectionBar, and a bare `.sbx-dirchip` rule here shrank it
   on every board (found 2026-09-07 while simplifying this panel). Solid flat style — no shadows (SBX-122). */
.sbx-dirvoice { font: inherit; font-size: 10.5px; font-weight: 700; letter-spacing: .08em; cursor: pointer;
  border: 1px solid rgba(119, 138, 168, .45); border-radius: 4px; padding: 1px 7px; background: transparent; color: #8fa0b8; }
.sbx-dirvoice.on { border-color: #8fe3a8; color: #8fe3a8; }
body.sbx-light .sbx-dirvoice { border-color: #c9d2e0; color: #5d6b84; }
body.sbx-light .sbx-dirvoice.on { border-color: #176b38; color: #176b38; }
/* A4 direction line: ONE badge, ONE sentence, the record, then the switches. Details are a second row. */
.sbx-dirpanel { gap: 14px; flex-wrap: wrap; }
.sbx-dirverdict { font-size: 13px; font-weight: 800; letter-spacing: .08em; border-radius: 4px; padding: 3px 10px; white-space: nowrap; }
.sbx-dirverdict.long { background: #123a24; color: #8fe3a8; }
.sbx-dirverdict.short { background: #3f1420; color: #ff9db7; }
.sbx-dirverdict.aside { background: #161c29; color: #b8c5da; }
.sbx-dirverdict.wait { background: #2e2a12; color: #f1d97a; }
.sbx-dirsay { font-size: 14px; font-weight: 600; color: #dbe4f2; }
.sbx-dirsay.warn { color: #ffd28a; }
.sbx-dirrec { font-size: 11.5px; font-weight: 700; color: #8fa0b8; white-space: nowrap; }
.sbx-dirspacer { flex: 1 1 auto; }
.sbx-dirshadow { font-size: 10px; letter-spacing: .08em; }
.sbx-dirmore { font: inherit; font-size: 10.5px; font-weight: 700; letter-spacing: .06em; cursor: pointer;
  border: 1px solid rgba(119, 138, 168, .45); border-radius: 4px; padding: 1px 7px; background: transparent; color: #8fa0b8; }
.sbx-dirmore.on { border-color: #8fa0b8; color: #dbe4f2; }
.sbx-dirdetails { flex-basis: 100%; display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-top: 7px; padding-top: 7px; border-top: 1px solid rgba(119, 138, 168, .18); }
.sbx-pushalert { font-size: 10.5px; font-weight: 800; letter-spacing: .06em; color: #ffd866; white-space: nowrap; }
body.sbx-light .sbx-dirverdict.long { background: #e2f6e8; color: #176b38; }
body.sbx-light .sbx-dirverdict.short { background: #fbe4ea; color: #b02a55; }
body.sbx-light .sbx-dirverdict.aside { background: #eef1f7; color: #4a5670; }
body.sbx-light .sbx-dirverdict.wait { background: #fbf3d6; color: #7a5b00; }
body.sbx-light .sbx-dirsay { color: #1c2333; }
body.sbx-light .sbx-dirsay.warn { color: #8a4b00; }
body.sbx-light .sbx-dirrec { color: #5d6b84; }
body.sbx-light .sbx-dirmore { border-color: #c9d2e0; color: #5d6b84; }
body.sbx-light .sbx-pushalert { color: #a06a00; }

.sbx-win { display: inline-flex; align-items: baseline; gap: 6px; white-space: nowrap; }
.sbx-win .l { font-size: 11.5px; color: #94a3bd; }
.sbx-win .v { font-size: 15.5px; font-weight: 700; }
.sbx-win.big .v { font-size: 18px; }
.sbx-bias { font-size: 12.5px; font-weight: 800; letter-spacing: .08em; border-radius: 4px; padding: 2px 8px; white-space: nowrap; }
.sbx-bias.bear { background: #33131c; color: #ff8fb0; } .sbx-bias.bull { background: #10331c; color: #7fd08b; }
.sbx-bias.wait { background: #161c29; color: #8fa0b8; }
.sbx-conv { display: inline-flex; align-items: baseline; gap: 12px; font-size: 13px; color: #b8c5da; margin-left: auto; white-space: nowrap; flex-wrap: wrap; }

/* exposure checkbox row */
.sbx-ctrl { gap: 20px; }
.sbx-ctrl label { display: inline-flex; align-items: center; gap: 7px; font-size: 14.5px; color: #dbe3f0; cursor: pointer; white-space: nowrap; }
.sbx-ctrl input { accent-color: #7fb3ff; width: 15px; height: 15px; }
.sbx-ctrl select { background: #101828; color: #dbe3f0; border: 1px solid rgba(119, 138, 168, .4); border-radius: 4px; font-size: 13.5px; padding: 2px 6px; }

/* ---------- ladder stage ---------- */
.sbx-stage { position: relative; background: #080a10; border: 1px solid rgba(119, 138, 168, .34); border-radius: 0 0 8px 8px; overflow: hidden; }

/* ---------- strike box ---------- */
.sbx-box {
  position: relative;
  display: grid;
  grid-template-columns: 1fr var(--sbx-core-w) 1fr;
  grid-template-rows: 1fr auto;
  height: var(--sbx-h);
  background: #090b11;
  border-bottom: 1px solid rgba(119, 138, 168, .13);
  overflow: hidden;
}
.sbx-box:nth-child(even) { background: #0d0f17; }
.sbx-box.sbx-atm { background: #12101c; }
.sbx-box:last-child { border-bottom: 0; }

.sbx-zone { padding: 8px 16px; min-width: 0; position: relative; }
.sbx-zone.call { grid-column: 1; grid-row: 1; display: flex; flex-direction: column; justify-content: center; gap: 4px; }
.sbx-zone.put  { grid-column: 3; grid-row: 1; display: flex; flex-direction: column; justify-content: center; gap: 4px; align-items: flex-end; text-align: right; }
.sbx-ztitle { font-size: 12px; letter-spacing: .14em; font-weight: 800; }
.sbx-zone.call .sbx-ztitle { color: #7fd08b; }
.sbx-zone.put .sbx-ztitle { color: #e07a9a; }

/* cluster wall membership (SBX-106): solid edge + breathing chip */
.sbx-zone.call.clu-sold  { border-left: 4px solid rgba(255, 107, 138, .85); }
.sbx-zone.put.clu-bought { border-right: 4px solid rgba(127, 208, 139, .85); }

.sbx-row { display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: baseline; min-width: 0; }

.sbx-f { display: inline-flex; align-items: baseline; gap: 5px; white-space: nowrap; }
.sbx-l { font-size: 11px; letter-spacing: .08em; color: #94a3bd; font-weight: 600; }
.sbx-v { font-size: 15px; color: #e9edf6; }
.sbx-v.na { color: #8a96ac; }

/* top-3 volume gold ranks (SBX-102) */
/* SBX-174 (owner, 2026-08-19: "top volume should be gold colour not yellow"): #ffd700 is a
   pure YELLOW at full saturation — it reads as a highlighter, not as metal. The ranks now carry
   a METALLIC gold that darkens with the rank, so 1/2/3 are also told apart by tone rather than
   only by size. Measured against the box background: 9.17 / 7.39 / 6.02:1 — all far above AA,
   and the rank stays legible with the gold cap of a wall zone beside it. */
.sbx-v.vol-r1 { font-size: 22px; font-weight: 800; color: #d4af37; }
.sbx-v.vol-r2 { font-size: 19px; font-weight: 750; color: #c39b2e; }
.sbx-v.vol-r3 { font-size: 16.5px; font-weight: 700; color: #b28a26; }
.sbx-vrk { font-size: 11px; color: #d4af37; vertical-align: super; font-weight: 800; }

/* classifier split (SBX-101) */
.sbx-fflow .sbx-v { display: inline-flex; align-items: baseline; gap: 4px; }
.sbx-fflow .sbx-v b.b { color: #7fd08b; } .sbx-fflow .sbx-v b.s { color: #e07a9a; }
.sbx-fflow .sbx-v b.na { color: #8a96ac; }
.sbx-fsep { color: #6b7891; font-weight: 600; }

.sbx-sweep { font-size: 12.5px; color: #b8c5da; white-space: nowrap; }
.sbx-sweep b.b { color: #7fd08b; } .sbx-sweep b.s { color: #e07a9a; }
.sbx-pace { font-size: 12.5px; color: #b8c5da; white-space: nowrap; }

.sbx-clu { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 800; letter-spacing: .06em;
           border-radius: 4px; padding: 2px 8px; animation: sbx-breathe 2.6s ease-in-out infinite; white-space: nowrap; }
.sbx-clu.sold   { background: #33131c; color: #ff8fb0; }
.sbx-clu.bought { background: #10331c; color: #7fd08b; }
@keyframes sbx-breathe { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }

/* liquidity ribbon (SBX-107a): 1s columns painted as solid per-column segments (data colors) */
.sbx-lh { display: inline-flex; align-items: center; gap: 7px; }
.sbx-lh .cap { font-size: 11px; color: #94a3bd; letter-spacing: .06em; white-space: nowrap; }
.sbx-ribbon { position: relative; display: inline-flex; width: clamp(150px, 12vw, 320px); height: 12px; border-radius: 3px;
              overflow: hidden; background: #0c1020; border: 1px solid rgba(127, 179, 255, .18); align-self: center; }
.sbx-ribbon i { flex: 1 0 auto; height: 100%; }
.sbx-ribbon .dot { position: absolute; top: 50%; transform: translate(-50%, -50%); width: 5px; height: 5px; border-radius: 50%; }
.sbx-ribbon .dot.buy { background: #7fd08b; } .sbx-ribbon .dot.sell { background: #e07a9a; }

/* ---------- strike core ---------- */
.sbx-core { grid-column: 2; grid-row: 1; border-left: 1px solid rgba(119, 138, 168, .16); border-right: 1px solid rgba(119, 138, 168, .16);
            display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 8px 14px; min-width: 0; }

.sbx-priceline { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: center; }
.sbx-price { font-size: 30px; font-weight: 800; color: #f4f7fc; line-height: 1; white-space: nowrap; }
.sbx-atm .sbx-price { color: #ffe08a; }
.sbx-price.magnet { text-decoration: underline dotted rgba(255, 217, 101, .6) 2px; text-underline-offset: 4px; }
.sbx-price.hot { color: #ffd700; }

.sbx-role { font-size: 12px; font-weight: 800; letter-spacing: .1em; border-radius: 4px; padding: 2.5px 9px; white-space: nowrap; }
.sbx-role.wall    { background: #33131c; color: #ff8fb0; }
.sbx-role.magnet  { background: #3a2f10; color: #ffd965; }
.sbx-role.support { background: #10331c; color: #7fd08b; }
.sbx-role.neutral { background: #161c29; color: #b8c5da; }
.sbx-role.es      { background: #0f2a28; color: #7fd0c9; }

.sbx-dist { font-size: 12.5px; color: #a9b5ca; white-space: nowrap; }

/* per-strike clock — color set inline by the shared schedule (SBX-119) */
.sbx-clock { font-size: 15px; font-weight: 800; letter-spacing: .05em; border-radius: 5px; padding: 2px 10px;
             background: rgba(16, 22, 38, .9); border: 1px solid rgba(148, 163, 189, .3); white-space: nowrap; }

/* intelligence badges (SBX-114) */
.sbx-intel { display: inline-flex; align-items: center; gap: 6px; font-size: 13.5px; font-weight: 800; letter-spacing: .05em;
             border-radius: 5px; padding: 3px 10px; white-space: nowrap; }
.sbx-intel.sell { background: #4a1420; color: #ff9fbd; }
.sbx-intel.buy  { background: #143a20; color: #8fe0a5; }
.sbx-intel .burst { font-size: 12px; color: #ffd965; }
.sbx-intel-es { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; font-weight: 700;
                border: 1.5px dashed #3aa89e; color: #7fd0c9; border-radius: 5px; padding: 2px 9px; background: transparent; white-space: nowrap; }
@keyframes sbx-blink { 0%, 100% { opacity: 1; } 50% { opacity: .4; } }

/* gamma gauge (SBX-108) — solid flat fills; width = sqrt(|net| / chain max) of the half-track (SBX-162) */
.sbx-gexbar { position: relative; width: 100%; height: 22px; border-radius: 5px; background: #10162a;
              /* A DEFINED frame, not a hairline (owner, 2026-08-18: "make the border of the gamma
                 box more darker so it clearly see how is the gamma around there"). Same 1px —
                 border-box, so only the colour changed, never the geometry. */
              border: 1px solid rgba(148, 163, 189, .6); overflow: hidden; flex: none; }
/* SBX-163 gave the fill the box's full HEIGHT (owner) and SBX-171 then moved every reading OUT
   of the bar, so no text overlays a fill at all any more — the contrast problem that shaped this
   palette is gone at the root. The restrained fills and their 1px inset EDGES are KEPT because
   they are what makes the bar legible against its own track (dark 5.8/6.4:1, light 3.9/4.3:1 vs
   track), not because text sits on them. Layers: track < lanes/fills < axis/divider. */
.sbx-gexlane { position: absolute; left: 0; right: 0; z-index: 1; }
.sbx-gexlane.gamma { top: 0; height: 100%; }
/* the vanna EXPOSURE toggle — never per-row data — splits the lanes, so every box on the board
   carries the same geometry whatever its data (the constant-geometry rule) */
.sbx-gexbar.van-split .sbx-gexlane.gamma { height: 50%; }
.sbx-gexlane.vanna { top: 50%; height: 50%; }
/* SBX-181: the ES overlay is a THIRD lane, on the same terms — the split follows the TOGGLE, never
   a row's data, so a strike with no ES reading still holds its lane and every box stays identical.
   Enumerated rather than computed (no calc on a lane count): each combination is a geometry the
   squeeze gate measures, and a formula would let an unmeasured fourth combination appear silently.
     ES alone      -> gamma 50 / es 50
     ES + vanna    -> gamma 34 / es 33 / vanna 33, gamma taking the rounding remainder because it
                      is the lane the board is named for. */
.sbx-gexbar.es-split .sbx-gexlane.gamma { height: 50%; }
.sbx-gexbar.es-split .sbx-gexlane.es { top: 50%; height: 50%; }
.sbx-gexbar.es-split.van-split .sbx-gexlane.gamma { height: 34%; }
.sbx-gexbar.es-split.van-split .sbx-gexlane.es { top: 34%; height: 33%; }
.sbx-gexbar.es-split.van-split .sbx-gexlane.vanna { top: 67%; height: 33%; }
/* ES wears its own colour family — teal, claimed by neither gamma nor vanna, because ES and SPX
   gamma are different books whose lengths are never comparable and must not read as one scale. */
.sbx-gexlane.es .sbx-gexfill.pos { background: #10403f; border-color: #35b3a6; }
.sbx-gexlane.es .sbx-gexfill.neg { background: #4a2a10; border-color: #d9954a; }
.sbx-gexfill { position: absolute; top: 0; bottom: 0; height: auto; }
.sbx-gexfill.pos { background: #163d73; border: 1px solid #4d91ff; }
.sbx-gexfill.neg { background: #63203c; border: 1px solid #ef719d; }
/* vanna wears its own colour family — purple, claimed by neither gamma side */
.sbx-vanfill { position: absolute; top: 0; bottom: 0; background: #4b286f; border: 1px solid #aa7bdb; }
/* centre-anchored, like the option-chain page: zero in the middle, magnitude never past half;
   the axis spans BOTH lanes so the two halves share one zero */
.sbx-gexaxis { position: absolute; top: 0; bottom: 0; left: 50%; width: 1px; z-index: 4;
               background: rgba(255, 255, 255, .75); pointer-events: none; }
.sbx-gexdivider { position: absolute; left: 0; right: 0; top: 50%; height: 1px; z-index: 4;
                  background: rgba(148, 163, 189, .45); pointer-events: none; }
/* SBX-181: the divider marks a LANE BOUNDARY, so it has to move when the boundaries do. Left at a
   flat 50% it cut straight through the ES lane in the three-lane layout, and drew nothing at all
   when ES was the only split (Codex 181-r1 MEDIUM) — a line that lands mid-lane is worse than no
   line, because it reads as a zero axis. One rule per enumerated geometry, matching the lanes. */
.sbx-gexbar.es-split .sbx-gexdivider { top: 50%; }
.sbx-gexbar.es-split.van-split .sbx-gexdivider { top: 34%; }
.sbx-gexbar.es-split.van-split .sbx-gexdivider2 { top: 67%; }
.sbx-gexdivider2 { position: absolute; left: 0; right: 0; height: 1px; z-index: 4; display: none;
                   background: rgba(148, 163, 189, .45); pointer-events: none; }
.sbx-gexbar.es-split.van-split .sbx-gexdivider2 { display: block; }
.sbx-gexarrow { position: absolute; bottom: 0; width: 0; height: 0; z-index: 5; margin-left: -4px;
                border-left: 4px solid transparent; border-right: 4px solid transparent;
                border-bottom: 5px solid #cfe4ff; pointer-events: none; }
.sbx-gexbar.van-split .sbx-gexarrow { bottom: 50%; }
/* the arrow belongs to the GAMMA lane, so it sits on that lane's floor in every combination */
.sbx-gexbar.es-split .sbx-gexarrow { bottom: 50%; }
.sbx-gexbar.es-split.van-split .sbx-gexarrow { bottom: 66%; }
.sbx-gexarrow.neg { border-bottom-color: #ffd0e0; }
/* a stale reading claims no level at all — the flat band owns its whole lane */
.sbx-gexfill.stale { background: rgba(88, 96, 108, .34); border: 0; }
.sbx-gexstale { font-size: 10.5px; font-weight: 900; letter-spacing: .06em; color: #ffcc66;
                white-space: nowrap;
 }
.sbx-gexval.stale { color: #9aa6ba; }
/* The VAN letters name the lower lane. With the bar down to 15px (SBX-171) a 10px line box no
   longer fits a ~6.5px lane — it protruded over the divider and the fills, which would have made
   "nothing overlays a fill" false (Codex out-r1 MEDIUM). The label rides the LEFT EDGE of the
   lane as a 3px tick; the vanna figure lives in the lane's tooltip. The tick is layout-free
   and cannot overflow, and the exact vanna figure was always in the tooltip anyway. */
.sbx-vanlabel { position: absolute; left: 0; top: 0; bottom: 0; width: 3px; z-index: 5;
                background: #aa7bdb; font-size: 0; pointer-events: none; }
/* SBX-171: the READINGS ROW — above the bar, never over a fill. Fixed slots left to right:
   lifecycle badge, change trail, the Γ value, γ-TIME. Every cell is rendered whether or not it
   carries a reading (sbx-hold hides, never removes), so data can never move a column. */
/* SBX-175 (owner: "write the gamma value in the center"): the value sits in a middle track of a
   SYMMETRIC grid — 74px | 1fr | 100px | 1fr | 74px — so it is centred on the row, and therefore
   on the bar below it, by construction rather than by arithmetic. The outer tracks are equal
   (γ-TIME needs 74px; the 44px badge simply gets the same slot) and the two 1fr are equal, which
   is what puts the middle track's centre on the row's centre — measured: 0px offset from the
   bar's centre on every row. The middle track is 88px rather than 100: at the 392px core every
   px it takes comes out of the two 1fr the trail lives in, and 100 left the trail at 43px —
   under a single 68px window. 88 gives it 50px, and a figure wider than 88 ellipsizes with its
   exact value in its tooltip.
   An earlier attempt floated the value at left:50% instead. It centred correctly but overlapped
   the trail, and the max-width meant to hold the trail off resolved its percentage against the
   GRID AREA, not the row — 6px of usable trail instead of 73px at the 392px core (Codex
   centre-r1). A track cannot make that mistake. */
.sbx-gexread { display: grid;
               grid-template-columns: 74px minmax(0, 1fr) 88px minmax(0, 1fr) 74px;
               align-items: center; gap: 0 8px; width: 100%; height: 19px; flex: none;
               overflow: hidden; }
/* Γ and γ-TIME are FIXED tracks, never `auto` (Codex out-r1 HIGH): each strike owns its own
   grid, so an auto track sized to its own content — a wide value or a live γ-TIME would move
   that column on one row and not its neighbours, which is exactly the geometry-follows-data
   defect this board forbids. Measured worst cases at the 17px squeezed scale: value
   "Γ −999.9B ▼" = 128px, γ-TIME "12h 00m" = 70px; the tracks carry 132/74 and anything longer
   ellipsizes with its exact figure in the tooltip. */
/* justify-self: STRETCH is load-bearing (the squeeze-r7 lesson, re-learned here): with `end` the
   element is content-sized inside its fixed track, so its LEFT edge moves with the figure —
   the gate measured 63px of drift between rows. Stretched to the track and right-aligned
   INSIDE it, both edges sit at the same x in every box whatever the value reads. */
.sbx-gexval { grid-column: 3; justify-self: stretch; justify-content: center;
              font-size: 14px; font-weight: 800; line-height: 1;
              color: #f2f6fc; white-space: nowrap;
              display: inline-flex; align-items: center; overflow: hidden; }
/* text-overflow needs a text container, not the flex box: the inner span carries the ellipsis,
   so a value past the cap truncates VISIBLY and the exact figure is in its tooltip */
.sbx-gexval > .t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* SBX-180 (owner, 2026-08-20: "change the font colour of the gamma value negative same colour as
   gamma bar and positive same colour as gamma bar"). These are the FILL'S OWN accents — the same
   #4d91ff / #ef719d the bar below draws its border with — so the figure and its bar read as one
   statement. The fill's background is too dark to carry text at 14px; its accent is the colour the
   bar actually reads as. Stated BEFORE the stale/dim rules so those still win: a coloured figure
   asserts a live signed level, and neither state has one. */
.sbx-gexval.pos { color: #4d91ff; }
.sbx-gexval.neg { color: #ef719d; }
/* the absent reading is DIM — stated after .sbx-gexval so it wins the cascade (lanes-r1 M1) */
.sbx-gexval.sbx-dim { color: #8a96ac; }
.sbx-gextime { grid-column: 5; justify-self: stretch; display: inline-flex; align-items: center;
               justify-content: flex-end; overflow: hidden;
               font-size: 12px; font-weight: 700; color: #9fb0c9; white-space: nowrap; }
.sbx-gextime.now { color: #ffd965; }
.sbx-gextime.dirty { color: #c8a24a; }
/* Gamma-lifecycle badge (SBX-156, returned with its ingest): the option-chain page's compact
   vocabulary — ▲ NEW / ● PIN / ▼ FADE. A FIXED slot whether or not a badge is live (sbx-hold
   hides, never removes), because the trail beside it drifted 52px when this cell followed the
   data (squeeze-r6). 40px covers the widest form ("▼ FADE" at 10.5/900 measures ~38px) and is
   half the 74px the old full-word chip took from the trail's band. */
.sbx-gexlc { grid-column: 1; justify-self: start; width: 44px; font-size: 10.5px; font-weight: 900;
             letter-spacing: .04em; white-space: nowrap; }
/* the same luminance discipline as the trail (SBX-157): three states a glance apart, none of
   them dimmer than the others' shadow */
.sbx-gexlc.lc-new { color: #44f19a; }
.sbx-gexlc.lc-pin { color: #8ab8ff; }
.sbx-gexlc.lc-fade { color: #ffa8b0; }
/* SBX-154: gamma change as a SHAPE OVER TIME. Fixed slots, so a window the producer omits leaves
   a dash in place rather than letting its neighbours slide along the bar. */
/* The trail is bounded by its own TRACK now (column 2 of the symmetric grid), so it needs no
   percentage cap — the one it had resolved against the grid area rather than the row and left
   6px of usable width (Codex centre-r1). Past the track it ellipsizes, full text in its tooltip. */
.sbx-gextrail { display: grid; grid-auto-flow: column; grid-auto-columns: 68px;
                align-items: center; gap: 0 6px; overflow: hidden; min-width: 0; height: 100%; }
.sbx-gtw { display: flex; align-items: baseline; gap: 4px;
           min-width: 0; max-width: 100%; overflow: hidden; white-space: nowrap; }
.sbx-gtw .l { font-size: 10.5px; color: #b6c4da; letter-spacing: .02em; }
.sbx-gtgap { color: #8a96ac; font-size: 11px; margin-left: 2px; }
/* the track is 46px and the value carries no natural cap: an extreme reading would paint straight
   over its neighbour, so it clips to its own slot and the tooltip carries the full figure. */
.sbx-gtw .v { font-size: 12.5px; font-weight: 900; color: #c3cfe2; font-variant-numeric: tabular-nums;
              max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
/* Luminance-MATCHED (SBX-157), re-verified over the full-height fills: on the darkest fill the
   dimmest of these still reads 4.89:1, and on the empty track 8.1:1+. */
.sbx-gtw.up .v { color: #44f19a; }
.sbx-gtw.dn .v { color: #ffa8b0; }
.sbx-gtw.na .v { color: #9fb0c9; }

/* auxiliary gauge rows (±Γ sides / vanna / charm / ES) — reserved via visibility (SBX-118) */
.sbx-aux { display: grid; grid-template-columns: 44px 1fr 130px; align-items: center; gap: 8px; width: 100%; flex: none; }
.sbx-aux.reserved-off { visibility: hidden; }
.sbx-aux .ml { font-size: 11.5px; color: #94a3bd; letter-spacing: .06em; font-weight: 700; }
.sbx-aux .bar { position: relative; height: 8px; background: #141927; border-radius: 4px; overflow: hidden; }
.sbx-aux .bar .zero { position: absolute; left: 50%; top: -1px; bottom: -1px; width: 1px; background: #2c3650; }
.sbx-aux .bar i { position: absolute; top: 0; bottom: 0; }
.sbx-aux .bar i.p { background: #2ea564; } .sbx-aux .bar i.n { background: #d8608a; }
.sbx-aux .bar i.v { background: #b07fd0; } .sbx-aux .bar i.c { background: #d0a97f; } .sbx-aux .bar i.e { background: #3aa89e; }
.sbx-aux .mv { font-size: 12.5px; text-align: right; white-space: nowrap; }

/* chips row */
.sbx-chips { display: flex; gap: 5px; row-gap: 4px; flex-wrap: wrap; justify-content: center; align-items: center; min-height: 0; overflow: hidden; }
.sbx-chip { font-size: 12px; border-radius: 4px; padding: 2px 8px; letter-spacing: .04em; white-space: nowrap; border: 1px solid transparent; }
.sbx-chip.zone-d { background: #2a1a2e; color: #d79ae0; }
.sbx-chip.zone-a { background: #0f2a28; color: #7fd0c9; }
.sbx-chip.liq    { background: #101c30; color: #7fb3ff; }
/* the ladder-path targets: NEXT is a waypoint, ULTIMATE is the end of the side — so the second
   one carries the stronger mark. Both are geometry, never a forecast (see the chip titles). */
.sbx-chip.tgt    { font-weight: 800; letter-spacing: .06em; }
.sbx-chip.tgt.nxt { background: #12233a; color: #8ab6f0; border-color: rgba(138, 182, 240, .42); }
.sbx-chip.tgt.ult { background: #1b2540; color: #b3c4ff; border-color: rgba(179, 196, 255, .62); }
.sbx-chip.sr     { background: #2e2410; color: #e8c15a; }
.sbx-chip.dl     { background: #161c29; color: #b8c5da; }
.sbx-chip.rev-t  { background: #33131c; color: #ff8fb0; border: 1px dashed rgba(255, 143, 176, .4); }
.sbx-chip.rev-b  { background: #2e2410; color: #e8b33e; border: 1px solid rgba(232, 179, 62, .45); }
.sbx-chip.lhwall { background: #241c06; color: #ffd700; border: 1px solid rgba(255, 215, 0, .5); font-weight: 700; }
.sbx-chip.migc   { background: #1c1230; color: #c9b9ff; border: 1px solid rgba(184, 164, 255, .35); }
.sbx-chip.gflip  { background: #3a0f18; color: #ff8fb0; border: 1.5px solid #ff5f8a; font-weight: 800; }

/* last-visit memento (SBX-113) */
.sbx-visit { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; white-space: nowrap;
             background: #14110a; border: 1px dashed rgba(232, 179, 62, .45); color: #e6d59a; border-radius: 4px; padding: 2px 9px; }
.sbx-visit b { font-weight: 800; }
.sbx-visit .up { color: #7fd08b; } .sbx-visit .dn { color: #e07a9a; }

/* Δ-flow lattice (SBX-013) */
.sbx-dlat { display: flex; gap: 10px; align-items: center; flex: none; }
.sbx-dlat .dlab { font-size: 12px; font-weight: 800; letter-spacing: .1em; color: #8fb8ff; white-space: nowrap; }
.sbx-dw { display: flex; flex-direction: row; align-items: baseline; gap: 4px; min-width: 0; white-space: nowrap; }
.sbx-dw .l { font-size: 11px; color: #94a3bd; }
.sbx-dw .v { font-size: 13.5px; font-weight: 650; }

/* verdict strip (SBX-115) */
.sbx-cvdread { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; white-space: nowrap;
               background: #101c30; border: 1px solid rgba(127, 179, 255, .25); color: #9fc3ff; border-radius: 4px; padding: 2px 9px; }
.sbx-cvdread.warn { background: #2e2410; border-color: rgba(232, 193, 90, .3); color: #e8c15a; }
.sbx-cvdread.conf { background: #10331c; border-color: rgba(127, 208, 139, .3); color: #7fd08b; }
/* STAGED (doc §0.1): the option-truth thermometer has no truth batch type on this stream
   yet. Kept deliberately as its groundwork — NOT dead weight from SBX-147. */
.sbx-truth { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
.sbx-taxis { position: relative; width: 96px; height: 8px; background: #141927; border-radius: 4px; }
.sbx-taxis i { position: absolute; top: 0; bottom: 0; border-radius: 4px; }

/* ES-only boxes (SBX-129) */

/* ---------- ladder overlay lines ---------- */
.sbx-line { position: absolute; left: 0; right: 0; height: 0; z-index: 3; pointer-events: none; }
.sbx-line.spot { border-top: 2.5px solid #e9edf6; }
.sbx-line.wall-call { border-top: 2px solid rgba(255, 107, 138, .9); }
.sbx-line.wall-put  { border-top: 2px solid rgba(127, 208, 139, .9); }
.sbx-line.rev { border-top: 1.5px dashed rgba(232, 179, 62, .8); }
.sbx-tag { position: absolute; transform: translateY(calc(-50% + var(--sbx-lane, 0px))); font-size: 13px; font-weight: 800; letter-spacing: .04em;
           padding: 2.5px 12px; border-radius: 12px; white-space: nowrap; pointer-events: auto; }
.sbx-line.spot .sbx-tag { left: 50%; transform: translate(-50%, calc(-50% + var(--sbx-lane, 0px))); background: #101c30; color: inherit; border: 1px solid currentColor; font-size: 14px; }
.sbx-line.wall-call .sbx-tag { left: 28px; background: #2a0e17; color: #ff8fb0; border: 1px solid rgba(255, 107, 138, .55); }
.sbx-line.wall-put .sbx-tag { left: 28px; background: #0e2a16; color: #7fd08b; border: 1px solid rgba(127, 208, 139, .55); }
.sbx-line.rev .sbx-tag { right: 28px; background: #1c1608; color: #e8b33e; border: 1px solid rgba(232, 179, 62, .5); font-size: 12px; }

/* ---------- floating controls ---------- */
.sbx-float { position: fixed; z-index: 60; display: inline-flex; align-items: center; gap: 8px;
             border-radius: 22px; padding: 10px 17px; font-size: 14px; font-weight: 800; letter-spacing: .05em;
             cursor: pointer; background: #101c30; color: #cfe4ff; border: 1px solid rgba(127, 179, 255, .55); }
.sbx-float:hover { background: #16273f; }
.sbx-float:disabled { opacity: .45; cursor: default; }
.sbx-float.center { right: 28px; bottom: 28px; }
.sbx-float.center .dot { width: 9px; height: 9px; border-radius: 50%; background: #7fb3ff; }
/* SBX-146: the theme + font controls are IN the control bar, never floating over the header.
   As position:fixed they covered the DELTA FLOW and ES CVD bars' right-hand values at any
   (observed live on ES at 1107px; a DOM probe reproduces the old-CSS overlap at 1107 and
   1370). `margin-left:auto` right-aligns them
   inside the bar, and because the bar is flex-wrap they drop to their own line on narrow
   screens instead of occluding anything. */
.sbx-headctl { display: inline-flex; align-items: center; gap: 10px; margin-left: auto; }
.sbx-themebtn { display: inline-flex; align-items: center; gap: 8px; background: #101d31;
                border: 1px solid rgba(119, 138, 168, .45); border-radius: 7px; color: #cfe4ff;
                font-size: 13.5px; font-weight: 700; padding: 6px 12px; cursor: pointer; white-space: nowrap; }
.sbx-themebtn:hover { background: #16273f; }
body.sbx-light .sbx-themebtn { background: #ffffff; border-color: #9db9e0; color: #2456a8; }
body.sbx-light .sbx-themebtn:hover { background: #eef3fb; }
.sbx-fontctl { display: inline-flex; align-items: center;
               background: #101c30; border: 1px solid rgba(127, 179, 255, .55); border-radius: 22px; overflow: hidden; }
.sbx-fontctl button { background: transparent; border: 0; color: #cfe4ff; font-size: 16px; font-weight: 800; padding: 9px 14px; cursor: pointer; line-height: 1; }
.sbx-fontctl button:hover { background: #16273f; }
.sbx-fontctl .pct { font-size: 13px; font-weight: 700; color: #94a3bd; min-width: 48px; text-align: center; }

/* waiting / empty states */
.sbx-wait { padding: 60px 20px; text-align: center; color: #8a96ac; font-size: 15px; }

/* ---------- ultrawide (SBX-140): consume the full width, spread wing fields ---------- */
@media (min-width: 2200px) {
  .sbx-page { padding: 20px 32px 64px; }
  .sbx-zone { padding: 8px 28px; }
  .sbx-row { gap: 8px 26px; }
  .sbx-ribbon { width: clamp(260px, 16vw, 560px); }
}
@media (min-width: 4000px) {
  .sbx-page { --sbx-core-w: clamp(480px, 14vw, 640px); }
  .sbx-zone { padding: 10px 44px; }
  .sbx-row { gap: 10px 40px; }
  .sbx-f { gap: 7px; }
}

/* ---------- light theme ---------- */
body.sbx-light .sbx-page { background: #f2f4f9; color: #1c2333; }
body.sbx-light .sbx-page h1 { color: #101828; }
body.sbx-light .sbx-topbars { background: #f2f4f9; }
body.sbx-light .sbx-bar { background: #ffffff; border-color: #c9d2e0; }
body.sbx-light .sbx-bar .t { color: #4a5670; }
body.sbx-light .sbx-stage { background: #ffffff; border-color: #c9d2e0; }
body.sbx-light .sbx-box { background: #ffffff; border-color: #dde3ee; }
body.sbx-light .sbx-box:nth-child(even) { background: #f5f7fb; }
body.sbx-light .sbx-box.sbx-atm { background: #fdf9ec; }
body.sbx-light .sbx-core { border-color: #dde3ee; }
body.sbx-light .sbx-pos { color: #177a41; }
body.sbx-light .sbx-neg { color: #c22e5c; }
body.sbx-light .sbx-dim, body.sbx-light .sbx-v.na { color: #8a96ac; }
body.sbx-light .sbx-l, body.sbx-light .sbx-lh .cap, body.sbx-light .sbx-dw .l, body.sbx-light .sbx-tf .l,
body.sbx-light .sbx-win .l, body.sbx-light .sbx-dist, body.sbx-light .sbx-aux .ml { color: #5d6b84; }
body.sbx-light .sbx-v, body.sbx-light .sbx-dw .v, body.sbx-light .sbx-win .v, body.sbx-light .sbx-tf .v { color: #1c2333; }
/* SBX-169 (owner, 2026-08-19: "in the light theme delta flow and cvd on top of the page stay
   black, does not change colour based on + and negative red and green"): the generic value rule
   above is MORE SPECIFIC than .sbx-pos/.sbx-neg (0,2,2 vs 0,2,1), so in light theme it painted
   every signed header reading black — DELTA FLOW, ES/SPX CVD, the Δ-flow lattice and the
   indicator cells all lost their sign. The sign colours are restated here at matching
   specificity, AFTER that rule, so a signed value keeps its meaning in both themes. */
body.sbx-light .sbx-v.sbx-pos, body.sbx-light .sbx-dw .v.sbx-pos,
body.sbx-light .sbx-win .v.sbx-pos, body.sbx-light .sbx-tf .v.sbx-pos { color: #177a41; }
body.sbx-light .sbx-v.sbx-neg, body.sbx-light .sbx-dw .v.sbx-neg,
body.sbx-light .sbx-win .v.sbx-neg, body.sbx-light .sbx-tf .v.sbx-neg { color: #c22e5c; }
/* absence keeps reading as absence rather than borrowing the "real value" ink */
body.sbx-light .sbx-v.sbx-dim, body.sbx-light .sbx-dw .v.sbx-dim,
body.sbx-light .sbx-win .v.sbx-dim, body.sbx-light .sbx-tf .v.sbx-dim { color: #5d6b84; }
/* light theme, same rank grading. The single #a07800 this replaces measured 4.05:1 on white —
   BELOW the 4.5 AA floor every other reading on this board holds; these are 5.06 / 5.79 / 6.9. */
body.sbx-light .sbx-v.vol-r1, body.sbx-light .sbx-vrk { color: #8a6a12; }
body.sbx-light .sbx-v.vol-r2 { color: #7d6210; }
body.sbx-light .sbx-v.vol-r3 { color: #6f570e; }
body.sbx-light .sbx-price { color: #101828; }
body.sbx-light .sbx-atm .sbx-price { color: #8a6400; }
body.sbx-light .sbx-sweep, body.sbx-light .sbx-pace, body.sbx-light .sbx-conv,
body.sbx-light .sbx-trig { color: #55627a; }
body.sbx-light .sbx-sweep b.b { color: #177a41; } body.sbx-light .sbx-sweep b.s { color: #c22e5c; }
body.sbx-light .sbx-fflow .sbx-v b.b { color: #177a41; }
body.sbx-light .sbx-fflow .sbx-v b.s { color: #c22e5c; }
body.sbx-light .sbx-chip { border-color: #d5dce8; }
body.sbx-light .sbx-chip.zone-d { background: #f7e9f9; color: #8a2f9e; }
body.sbx-light .sbx-chip.zone-a { background: #e4f5f2; color: #0f7a6d; }
body.sbx-light .sbx-chip.tgt.nxt { background: #e7effb; color: #1f5695; border-color: #b9cfea; }
body.sbx-light .sbx-chip.tgt.ult { background: #e2e8fb; color: #2b3f8f; border-color: #aab9e8; }
body.sbx-light .sbx-chip.liq { background: #e8f0fd; color: #2456a8; }
body.sbx-light .sbx-chip.sr { background: #faf0d8; color: #8a6410; }
body.sbx-light .sbx-chip.dl { background: #eef1f7; color: #4a5670; }
body.sbx-light .sbx-chip.rev-t { background: #fbe6ec; color: #b02a55; }
body.sbx-light .sbx-chip.rev-b { background: #f8f0da; color: #9a7410; }
body.sbx-light .sbx-chip.lhwall { background: #fdf6d8; color: #8a6d00; border-color: #d9c66a; }
body.sbx-light .sbx-chip.migc { background: #efe9fc; color: #6a4fc2; border-color: #cabcf0; }
body.sbx-light .sbx-chip.gflip { background: #fbe6ec; color: #b02a55; border-color: #d8608a; }
body.sbx-light .sbx-visit { background: #fbf6e8; color: #8a6d2f; border-color: #c9a94f; }
body.sbx-light .sbx-visit .up { color: #177a41; } body.sbx-light .sbx-visit .dn { color: #c22e5c; }
body.sbx-light .sbx-role.wall { background: #fbe6ec; color: #b02a55; }
body.sbx-light .sbx-role.magnet { background: #faf0d8; color: #8a6410; }
body.sbx-light .sbx-role.support { background: #e2f4e8; color: #177a41; }
body.sbx-light .sbx-role.neutral { background: #eef1f7; color: #5d6b84; }
body.sbx-light .sbx-role.es { background: #e4f5f2; color: #0f7a6d; }
body.sbx-light .sbx-clock { background: #f4f6fa; border-color: #c9d2e0; }
/* light theme: same rule — #c9d2e0 on #e6ebf4 was a near-invisible edge; #7e8ca4 reads as a
   clear frame against both the track and the white core behind it */
body.sbx-light .sbx-gexbar { background: #e6ebf4; border-color: #7e8ca4; }
/* SBX-163 light lanes: restrained pastels so the dark reading text stays >= 4.5:1 over every
   fill (measured: dimmest pairing 4.57:1); the 1px edges carry the shape definition (3.9-4.9:1
   vs the track). NA text is #4a5567 here, not #5a6478 — the old NA fell under 4.5:1 on these. */
body.sbx-light .sbx-gexfill.pos { background: #bacef0; border-color: #5073a3; }
body.sbx-light .sbx-gexfill.neg { background: #efc4d0; border-color: #a55470; }
body.sbx-light .sbx-vanfill { background: #d9c7ee; border-color: #79559e; }
body.sbx-light .sbx-vanlabel { background: #79559e; }
body.sbx-light .sbx-gexdivider { background: rgba(74, 85, 103, .5); }
body.sbx-light .sbx-gexaxis { background: rgba(20, 28, 44, .8); }
body.sbx-light .sbx-gexarrow { border-bottom-color: #1d3a68; }
body.sbx-light .sbx-gexarrow.neg { border-bottom-color: #8c1f42; }
body.sbx-light .sbx-gexval { color: #101828; }
/* light theme: its own fills' accents, verbatim — the same rule as above, not a darker cousin of
   it. The owner asked for the FIGURE to be the BAR's colour; a near-miss shade reads as a third
   colour on the board, and the gate compares the two computed values rather than any literal.
   The positive accent moved #5277a8 -> #5073a3 — measured, the old one was 4.29:1 against the
   even-row white and 4.37:1 on the ATM row, under the 4.5:1 that 17px bold text needs. The BAR's
   border moved with it, so the two are still one colour: the fix is a darker shared accent, not a
   figure that quietly disagrees with its bar. */
body.sbx-light .sbx-gexval.pos { color: #5073a3; }
body.sbx-light .sbx-gexval.neg { color: #a55470; }
body.sbx-light .sbx-gexval.sbx-dim { color: #4a5567; }
body.sbx-light .sbx-gexstale { color: #754c00; }
body.sbx-light .sbx-gtw .l { color: #45526b; } body.sbx-light .sbx-gtw .v { color: #1c2333; }
body.sbx-light .sbx-gtw.up .v { color: #0a5c2e; } body.sbx-light .sbx-gtw.dn .v { color: #a81c36; }
body.sbx-light .sbx-gtw.na .v { color: #4a5567; }
body.sbx-light .sbx-gexlc.lc-new { color: #0a5c2e; }
body.sbx-light .sbx-gexlc.lc-pin { color: #1d4fa8; }
body.sbx-light .sbx-gexlc.lc-fade { color: #a81c36; }
body.sbx-light .sbx-gextime { color: #4a5567; }
body.sbx-light .sbx-gextime.now { color: #8a6a12; } body.sbx-light .sbx-gextime.dirty { color: #8a6a12; }
body.sbx-light body.sbx-light .sbx-aux .bar { background: #e2e7f1; }
body.sbx-light .sbx-dlat .dlab { color: #2456a8; }
body.sbx-light .sbx-taxis { background: #e2e7f1; }
body.sbx-light .sbx-cvdread { background: #e8f0fd; color: #2456a8; border-color: #b9cdec; }
body.sbx-light .sbx-cvdread.warn { background: #faf0d8; color: #8a6410; border-color: #d9c66a; }
body.sbx-light .sbx-cvdread.conf { background: #e2f4e8; color: #177a41; border-color: #a8d8b8; }
body.sbx-light .sbx-intel.sell { background: #fbe6ec; color: #b02a55; }
body.sbx-light .sbx-intel.buy { background: #e2f4e8; color: #177a41; }
body.sbx-light .sbx-intel .burst { color: #a07800; }
body.sbx-light .sbx-intel-es { border-color: #0f7a6d; color: #0f7a6d; }
body.sbx-light .sbx-dirchip { background: #e2f4e8; color: #177a41; border-color: #a8d8b8; }
body.sbx-light .sbx-dirchip.unusual { background: #faf0d8; color: #8a6410; border-color: #d9c66a; }
body.sbx-light .sbx-dirchip.off { background: #eef1f7; color: #5d6b84; border-color: #d5dce8; }
/* Light theme, like every other chip: the dark fills are unreadable on white, so each state gets
   its own pair rather than inheriting a wash. Same five states, same meanings. */
body.sbx-light .sbx-dangerchip.dang { background: #fbe9e7; color: #a82525; border-color: #e3a9a3; }
body.sbx-light .sbx-dangerchip.elev { background: #fdf3e2; color: #8f5a08; border-color: #ddbd82; }
body.sbx-light .sbx-dangerchip.clear { background: #e7f4ec; color: #126134; border-color: #a8d8b8; }
body.sbx-light .sbx-dangerchip.sd { background: #efeafa; color: #4d3690; border-color: #bfb0e4; }
body.sbx-light .sbx-dangerchip.na { background: #eef1f6; color: #6c788e; border-color: #ccd4e0; }
body.sbx-light .sbx-dangerchip:focus-visible { outline-color: #4a5670; }
body.sbx-light .sbx-dangerlock { color: #4d3690; background: #efeafa; border-color: #bfb0e4; }
body.sbx-light .sbx-bias.bear { background: #fbe6ec; color: #b02a55; }
body.sbx-light .sbx-bias.bull { background: #e2f4e8; color: #177a41; }
body.sbx-light .sbx-bias.wait { background: #eef1f7; color: #5d6b84; }
body.sbx-light .sbx-consensus { color: #177a41; }
body.sbx-light .sbx-tf .v.bull { color: #177a41; } body.sbx-light .sbx-tf .v.bear { color: #c22e5c; }
body.sbx-light .sbx-tf .v.neu { color: #5a6478; } body.sbx-light .sbx-tf .v.unr { color: #8a6a12; }
body.sbx-light .sbx-tf .v.mal { color: #c22e5c; }
body.sbx-light .sbx-qual.unknown { color: #8a6a12; }
body.sbx-light .sbx-consensus.tie { color: #3a4356; }
body.sbx-light .sbx-consensus.conflict { color: #8a6a12; }
body.sbx-light .sbx-qual.stale { color: #8a6a12; } body.sbx-light .sbx-qual.closed { color: #5a6478; }
body.sbx-light .sbx-ctrl label { color: #2a3345; }
body.sbx-light .sbx-ctrl select { background: #ffffff; color: #1c2333; border-color: #c9d2e0; }
body.sbx-light .sbx-line.spot { border-top-color: #1c2333; }
body.sbx-light .sbx-line.spot .sbx-tag { background: #ffffff; }
body.sbx-light .sbx-line.wall-call .sbx-tag { background: #fbe6ec; color: #b02a55; border-color: #e0a0b5; }
body.sbx-light .sbx-line.wall-put .sbx-tag { background: #e2f4e8; color: #177a41; border-color: #a8d8b8; }
body.sbx-light .sbx-line.rev .sbx-tag { background: #f8f0da; color: #8a6410; border-color: #d9c66a; }
body.sbx-light .sbx-float, body.sbx-light .sbx-fontctl { background: #ffffff; border-color: #9db9e0; }
body.sbx-light .sbx-float, body.sbx-light .sbx-fontctl button { color: #2456a8; }
body.sbx-light .sbx-float:hover, body.sbx-light .sbx-fontctl button:hover { background: #eef3fb; }
body.sbx-light .sbx-fontctl .pct { color: #5d6b84; }
body.sbx-light .sbx-wait { color: #5d6b84; }
body.sbx-light .sbx-ribbon { background: #e6ebf4; border-color: #c9d2e0; }
body.sbx-light .sbx-zone.call.clu-sold { border-left-color: #d8608a; }
body.sbx-light .sbx-zone.put.clu-bought { border-right-color: #2ea564; }
body.sbx-light .sbx-clu.sold { background: #fbe6ec; color: #b02a55; }
body.sbx-light .sbx-clu.bought { background: #e2f4e8; color: #177a41; }

/* flow filter (ControlBar): non-matching boxes dim, never disappear */
.sbx-box.sbx-filtered { opacity: .3; }

/* Turn-alert blink (chain parity): pulses the strike GLYPH only — never the box — while a
   StrikeTurnAlert is live for that strike. Direction sets the colour; cadence matches the
   chain (1.1s). Opacity-only pulse (SBX-122 solid-flat: no glow). */
.sbx-price.sbx-turn-blink { animation: sbxTurnBlink 1.1s ease-in-out infinite; }
.sbx-price.sbx-turn-blink.turn-bearish { color: #ff5d6b; }
.sbx-price.sbx-turn-blink.turn-bullish { color: #2fd39a; }
body.sbx-light .sbx-price.sbx-turn-blink.turn-bearish { color: #c22e5c; }
body.sbx-light .sbx-price.sbx-turn-blink.turn-bullish { color: #177a41; }

/* SBX-179 (owner, 2026-08-19: "who told you to put everything off — i just want border line off
   not everything"). I over-corrected: chasing a blinking BORDER I switched off the flow markers,
   the cluster chip and the strike glyph too. They are all back, exactly as they were. Only the
   wall-zone BORDER is gone (below). */
/* ---------- chain-parity blink systems (opacity/color only, SBX-122) ---------- */
/* top-3 |net| per side: continuous soft-blink of the NET pill (chain .flow-blink, 2.6s) */
.sbx-net.sbx-netblink { animation: sbxSoftBlink 2.6s ease-in-out infinite; }
/* top-2 net-SELL per side: the NET pill pulses red→gold (chain .net-sell-box, 1.4s; color-only) */
.sbx-net.sbx-netsell { animation: sbxNetSellPulse 1.4s ease-in-out infinite; }
/* magnet strike: price glyph soft-blinks (chain .magnet-pin, 2.6s) */
.sbx-price.sbx-magnet-blink { animation: sbxSoftBlink 2.6s ease-in-out infinite; }
/* hot-gamma strike: the gamma gauge FILL pulses (chain .gamma-hot, 1.8s) */
.sbx-gexfill.sbx-gexhot { animation: sbxSoftBlink 1.8s ease-in-out infinite; }
/* SBX-168 (owner: "highest gamma value should be blinking"): the single largest ABSOLUTE gamma
   reading on the board — the strike the whole scale is drawn against — soft-blinks its VALUE.
   Opacity only (SBX-122 solid-flat: no glow), and the same 1.8s cadence as the hot-gamma fill so
   a strike that is both does not beat twice. Exactly ONE box can carry it: the chain maximum is
   one reading, and ties resolve to the first row in ladder order rather than blinking a crowd. */
.sbx-gexval.sbx-gexpeak { animation: sbxSoftBlink 1.8s ease-in-out infinite; }
/* intelligence action: BUY pulses (1.6s; STRONG 1s), SELL carries a moving-edge border pulse
   (chain uses a conic spin; flat-rule equivalent = border-color pulse at the same 2.4s cadence) */
.sbx-intel.sbx-action-pulse { animation: sbxSoftBlink 1.6s ease-in-out infinite; }
.sbx-intel.sbx-action-pulse-fast { animation: sbxSoftBlink 1s ease-in-out infinite; }
.sbx-intel.sbx-action-edge { border: 1.5px solid #ff9fbd; animation: sbxEdgePulse 2.4s ease-in-out infinite; }
@keyframes sbxNetSellPulse { 0%, 100% { color: #ff8fb0; } 50% { color: #ffd965; } }
body.sbx-light .sbx-net.sbx-netsell { animation-name: sbxNetSellPulseLight; }
@keyframes sbxNetSellPulseLight { 0%, 100% { color: #b02a55; } 50% { color: #a07800; } }
@keyframes sbxTurnBlink { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
@keyframes sbxSoftBlink { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }
@keyframes sbxEdgePulse { 0%, 100% { border-color: #ff9fbd; } 50% { border-color: #4a1420; } }
@media (prefers-reduced-motion: reduce) {
  /* the light theme re-points animation-name with an extra `body.sbx-light` selector, which
     outranks these; a media query adds no specificity of its own, so every light override has to
     be named here too or it keeps moving for exactly the users who asked it to stop
     (Codex 179-r4 P1 — measured, the light net-SELL pill was still pulsing). */
  body.sbx-light .sbx-net.sbx-netsell,
  .sbx-net.sbx-netblink, .sbx-net.sbx-netsell, .sbx-price.sbx-magnet-blink,
  .sbx-price.sbx-turn-blink, .sbx-net.sbx-netblink.sbx-netsell, .sbx-price.sbx-turn-blink.sbx-magnet-blink,
  .sbx-clu,
  .sbx-gexfill.sbx-gexhot, .sbx-gexval.sbx-gexpeak, .sbx-intel.sbx-action-pulse, .sbx-intel.sbx-action-pulse-fast,
  .sbx-intel.sbx-action-edge { animation: none; }
}

/* ---------- SBX-144 floor-test sticker (DS-8, verdict verbatim from the record) ---------- */
/* SUPERSEDED by SBX-147: the icon is no longer INSIDE the price span — there it widened the span
   and slid the strike number 28px left the moment a verdict arrived. It now owns a reserved 24px
   cell in the price-line grid. The rest still holds: a solid outline ring on the glyph, outline
   only, no shadow declarations (SBX-122). The icon soft-blinks
   while the verdict is live (γ-TIME leader precedent); the ring is static, so it composes with
   the turn/magnet glyph animations without a precedence rule. */
.sbx-floor-ico { display: inline-block; font-size: 17px; vertical-align: 2px;
                 animation: sbxSoftBlink 1.4s ease-in-out infinite; }
.sbx-price.floor-def { outline: 2px solid rgba(127, 208, 139, .85); outline-offset: 2px; border-radius: 6px; }
.sbx-price.floor-notdef { outline: 2px solid rgba(230, 46, 46, .9); outline-offset: 2px; border-radius: 6px; }
.sbx-floormean { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 800;
                 letter-spacing: .01em; white-space: nowrap; border-radius: 5px; padding: 2px 8px; }
.sbx-floormean.def { background: #10331c; color: #7fd08b; border: 1px solid rgba(127, 208, 139, .4); }
.sbx-floormean.notdef { background: #33131c; color: #ff8fb0; border: 1px solid rgba(255, 107, 138, .45); }
body.sbx-light .sbx-floormean.def { background: #e2f4e8; color: #177a41; border-color: #a5d8b5; }
body.sbx-light .sbx-floormean.notdef { background: #fbe6ec; color: #b02a55; border-color: #e0a0b5; }
body.sbx-light .sbx-price.floor-def { outline-color: #177a41; }
body.sbx-light .sbx-price.floor-notdef { outline-color: #c22e35; }
@media (prefers-reduced-motion: reduce) { .sbx-floor-ico { animation: none; } }

/* ---------- SBX-145 liquidity wall clusters (owner, 2026-08-16) ---------- */
/* The top TWO disjoint zones of three adjacent strikes by current resting size. TWO signals now
   that SBX-179 removed the rails: a static gold outline on the RIBBON of each box in the zone,
   and a named line on the verdict strip. The rails down the box edges — the band that made the
   three boxes read as one — are gone; that is the line the owner asked to remove, and the note
   below records why it appeared to blink. The gold cap and the superscript rank were always
   static, so the zone still reads at a glance. The ribbon outline stays layout-free, so nothing
   shifts. Rank 1 = gold, rank 2 = amber, matching the existing rank idiom. */
.sbx-lh.sbx-liqwall .sbx-ribbon { outline: 2px solid #ffd700; outline-offset: 2px; }
.sbx-lh.sbx-liqwall.r2 .sbx-ribbon { outline-color: #d9a441; }
.sbx-lh.sbx-liqwall.r1 .cap { color: #ffd700; font-weight: 800; }
.sbx-lh.sbx-liqwall.r2 .cap { color: #d9a441; font-weight: 800; }
/* Direction is the real signal now (server WallCluster), so it OVERRIDES the rank gold/amber:
   RESISTANCE reads red, SUPPORT reads green — the SAME palette as the Home page band
   (liquidity-heatmap.css lh-wall-res #d85a30 / lh-wall-sup #1d9e75). */
.sbx-lh.sbx-liqwall.sbx-liqwall-res .sbx-ribbon { outline-color: #d85a30; }
.sbx-lh.sbx-liqwall.sbx-liqwall-sup .sbx-ribbon { outline-color: #1d9e75; }
.sbx-lh.sbx-liqwall.sbx-liqwall-res .cap { color: #ff8a5a; }
.sbx-lh.sbx-liqwall.sbx-liqwall-sup .cap { color: #35c48c; }
.sbx-wrk { font-size: 10px; font-weight: 800; vertical-align: super; margin-left: 1px; }
/* SBX-179 (owner, 2026-08-19: "i just want border line off"): the 4px band that outlined the
   three wall-zone boxes is GONE. That line is what the owner has been pointing at since
   yesterday — and SBX-178 explains why it read as blinking: the zone is recomputed from
   liquidity frames that go stale at 15s, so on a quiet book the outline switched off and back on.
   Nothing else about the zone changes: the ribbon still carries its gold cap and rank, and the
   verdict strip still names it ("▦ #1 · 6000–6050") with the resting total in its tooltip. Only
   the box outline is removed. */
.sbx-wallmean { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 800;
                letter-spacing: .01em; white-space: nowrap; border-radius: 5px; padding: 2px 8px; }
.sbx-wallmean.r1 { background: #2e2410; color: #ffd965; border: 1px solid rgba(255, 217, 101, .45); }
.sbx-wallmean.r2 { background: #241d10; color: #d9a441; border: 1px solid rgba(217, 164, 65, .4); }
/* Direction overrides rank (server WallCluster signal): RESISTANCE red, SUPPORT green — matching
   the Home band palette so the same wall reads the same on both pages. */
.sbx-wallmean.sbx-liqwall-res { background: #2c1109; color: #ff8a5a; border-color: rgba(216, 90, 48, .5); }
.sbx-wallmean.sbx-liqwall-sup { background: #08251c; color: #35c48c; border-color: rgba(29, 158, 117, .5); }
body.sbx-light .sbx-wallmean.r1 { background: #faf0d8; color: #8a6410; border-color: #d8bd72; }
body.sbx-light .sbx-wallmean.r2 { background: #f6efe0; color: #8a6f2f; border-color: #d9c9a0; }
body.sbx-light .sbx-lh.sbx-liqwall.r1 .cap { color: #8a6410; }
body.sbx-light .sbx-lh.sbx-liqwall.r2 .cap { color: #8a6f2f; }
/* Light mode: direction still wins over rank (must come AFTER the rank rules above), matching the
   Home band's red/green in both themes. */
body.sbx-light .sbx-wallmean.sbx-liqwall-res { background: #fbe6dd; color: #b23c17; border-color: #e0a992; }
body.sbx-light .sbx-wallmean.sbx-liqwall-sup { background: #dcefe7; color: #12795a; border-color: #9bd0bd; }
body.sbx-light .sbx-lh.sbx-liqwall.sbx-liqwall-res .cap { color: #b23c17; }
body.sbx-light .sbx-lh.sbx-liqwall.sbx-liqwall-sup .cap { color: #12795a; }

/* ---------- blink composition precedence (Codex blink-r1) ---------- */
/* A pill in BOTH topNet and netSell runs both effects together: opacity and color animate
   independently, so neither replaces the other (the chain composes these on two elements). */
.sbx-net.sbx-netblink.sbx-netsell {
  animation: sbxSoftBlink 2.6s ease-in-out infinite, sbxNetSellPulse 1.4s ease-in-out infinite;
}
body.sbx-light .sbx-net.sbx-netblink.sbx-netsell {
  animation: sbxSoftBlink 2.6s ease-in-out infinite, sbxNetSellPulseLight 1.4s ease-in-out infinite;
}
/* EXPLICIT precedence: a live turn alert (safety-relevant, 1.1s) OVERRIDES the magnet
   soft-blink on the same glyph; the magnet blink resumes when the alert ends. */
.sbx-price.sbx-turn-blink.sbx-magnet-blink { animation: sbxTurnBlink 1.1s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) {
  /* the LIGHT composite has to be named explicitly: `body.sbx-light .sbx-net...` outranks the bare
     three-class selector, and a media query adds no specificity of its own, so without this line
     the light theme kept animating with reduced motion on (Codex 179-r3 P1). */
  .sbx-net.sbx-netblink.sbx-netsell,
  body.sbx-light .sbx-net.sbx-netblink.sbx-netsell,
  .sbx-price.sbx-turn-blink.sbx-magnet-blink { animation: none; }
}

/* ---------- SBX-143 v2: tight columnar layout (visually verified) ---------- */
/* Principles (owner 2026-08-16): both wings render the SAME left-to-right field order
   (MID VOL OI / B-S pill / sweep pace cluster / ribbon LIQ) with IDENTICAL fixed tracks,
   and each wing packs AGAINST the core column: call justify-end, put justify-start — data
   hugs the strike and reads uniformly on both sides. Track minimums cover the WORST
   realistic content, so every track is effectively fixed-width and both edges of every
   column sit at the same X in every box; a pathologically long backend string never shifts a
   track — SUPERSEDED by SBX-147 for the strip, where such a string is capped at 300px and
   ellipsized with its full text in the chip's tooltip rather than wrapping. Absent data renders
   sbx-hold placeholders that keep their track; the box height budgets the worst case, including
   the strip's three lines, so nothing clips. */
.sbx-zone.call .sbx-row, .sbx-zone.put .sbx-row { display: grid; align-items: center; gap: 2px 12px; justify-content: end; }
.sbx-zone.put .sbx-row { justify-content: start; }
.sbx-zone.call { text-align: right; }
.sbx-zone.put { align-items: stretch; text-align: left; }
/* four fixed lines per wing */
.sbx-zone.put .sbx-row.r1 { grid-template-columns: 132px 128px 72px; }
/* SBX-149 MIRROR: the call wing renders its fields in REVERSED order (see strike-board.js),
   so its tracks are the put wing's tracks reversed. Same widths, same total, read the other
   way, which puts every field the same distance from the strike on both sides. */
.sbx-zone.call .sbx-row.r1 { grid-template-columns: 72px 128px 132px; }
.sbx-zone.put .sbx-row.r2 { grid-template-columns: 92px 92px minmax(220px, max-content); }
.sbx-zone.call .sbx-row.r2 { grid-template-columns: minmax(220px, max-content) 92px 92px; }
.sbx-zone.call .sbx-row.r2b, .sbx-zone.put .sbx-row.r2b { grid-template-columns: 200px minmax(188px, max-content); }
/* label tight to value; values start at the same X per column (fixed tracks) */
.sbx-f { gap: 6px; }
.sbx-zone.call .sbx-f { justify-content: flex-end; }
/* A field may never paint outside its own track. The tracks are sized for the worst realistic
   content (a 4-digit premium fits the 132px MID track exactly), but "sized for" is not a
   guarantee: a wider value used to spill into the NEXT field and print over its label — measured
   as a 5x11 CSS-px glyph overlap between a MID value and the VOL label (Codex squeeze-r6 F4).
   Clipping makes that structurally impossible; the field's tooltip already carries the full
   value, so the degradation is visible truncation rather than two readings on top of each other. */
.sbx-zone .sbx-row > .sbx-f { min-width: 0; overflow: hidden; }
.sbx-zone .sbx-row > .sbx-f > .sbx-v { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.sbx-hold { visibility: hidden; }

/* SBX-160: strike-equivalent superscript (SPX on the ES board, ES on the SPX board). Colour and
   weight match `.spx-equiv` on /option-chain so the same reading looks the same on both pages.
   8px, not /option-chain's 9px: MEASURED in the real priceline, 5 digits are 32px at 9px but 29px
   at 8px, and only 30px could be taken from `dist` without pushing it under its own 43px worst
   case. It owns that FIXED 30px track and is `align-self: start`, so the raised position comes
   from the grid, not from a transform that could overflow into the role badge. Never
   `display: none` when absent — `.sbx-hold` hides it while keeping the track, because on this
   board data must not change geometry. */
.sbx-equiv { grid-column: equiv; font-size: 8px; font-weight: 800; line-height: 1; color: #7ce7d0;
             align-self: start; justify-self: start; margin-top: 3px;
             white-space: nowrap; overflow: hidden; }
/* the price column: fixed two-line core header — prices stack down the ladder */
.sbx-priceline {
  display: grid; align-items: center; gap: 2px 10px; width: 100%; justify-content: center;
  /* SUPERSEDED by the SBX-147 block below: [floor] [price] [role] [dist], no clock. */
  grid-template-columns: [price] 96px [role] 118px [clock] 130px;
}
.sbx-priceline .sbx-price { justify-self: end; }
.sbx-chipstrip .sbx-subline { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
/* keep the core compact so the verdict strip ALWAYS fits inside --sbx-h */
.sbx-core { gap: 4px; padding: 6px 12px; }
/* no-suppression: chips keep their intrinsic height (never flex-shrunk away), and any
   over-budget backend string wraps inside its chip rather than clipping silently */
.sbx-chips { max-height: none; flex-shrink: 0; }
.sbx-chips > * { white-space: normal; overflow-wrap: anywhere; }
.sbx-zone .sbx-chip.liq { white-space: normal; overflow-wrap: anywhere; }
@media (min-width: 4000px) {
  .sbx-zone.call .sbx-row, .sbx-zone.put .sbx-row { gap: 2px 22px; }
}

/* ================= SBX-147 SQUEEZE (owner, 2026-08-17) =================
   Goal: fit far more strikes on screen. Measured cause of the old 384px box — the core stacked
   seven blocks (351px) while EACH WING wasted 237px of empty vertical space, and the chips alone
   took 123px purely because they wrapped inside a 366px-wide core.
   Moves, none of which drop data:
     1. chips + Δ-flow + badges + verdict + floor + CVD share ONE full-width strip row
     2. ±Γ / VANNA / CHARM collapse from three stacked rows into one row of three inline meters
     3. the price line is strictly ONE line (badges moved to the strip)
     4. the liquidity ribbons move under the gamma gauge (owner), leaving LIQ state in the wings
   CONSTANT GEOMETRY is a hard rule (owner): the height is fixed and EVERY track is a fixed px
   width — no max-content anywhere — so changing data can never move a column or resize a box. */
.sbx-box { grid-template-rows: 1fr auto; }
/* FIXED SLOTS, not a flow row (owner, 2026-08-17: "MIGR is floating, it's pushing delta flow —
   nothing should be moving in the cell, it creates a lot of disturbance in the eye").
   The strip was the one part of the box still laid out as flex: when a chip changed width or
   appeared, everything after it slid sideways. The box, the wings and the price line were all
   made constant; this was not, and the movement is exactly as distracting as the owner says.
   ONE grid, five fixed columns, three rows. Every chip family owns a column, so a chip that is
   absent leaves its column empty rather than closing the gap, and data changes the NUMBERS but
   never the geometry — the same discipline the wings already use.
   `.sbx-chips` is `display: contents` so its chips are direct grid items: nested inside its own
   grid it could never be wider than the parent track, and its chips overflowed the box. */
.sbx-chipstrip {
  grid-column: 1 / 4; grid-row: 2; display: grid; align-items: center;
  grid-template-columns: [migr] 200px [sr] 176px [dealer] 134px [visit] 176px [rev] 152px [target] 76px;
  grid-auto-rows: 19px; gap: 1px 8px; padding: 1px 14px 2px; min-height: 0;
}
.sbx-chips { display: contents; }
/* row 1 — verdict, floor test, wall zone, intel/ES badges */
.sbx-chipstrip > .sbx-vchip     { grid-row: 1; grid-column: 1; }
.sbx-chipstrip > .sbx-floormean { grid-row: 1; grid-column: 2; }
/* The wall slot holds a CONTAINER, never the chips themselves: a strike can carry a RESISTANCE (call
   book) and a SUPPORT (put book) wall at once, and two chips placed as grid items in one cell were
   painted over each other. Inside it they sit side by side and each shrinks to an ellipsis, with the
   full wall in its own tooltip. */
.sbx-chipstrip > .sbx-walls     { grid-row: 1; grid-column: 3; display: flex; align-items: center; gap: 4px; }
.sbx-walls > .sbx-wallmean      { flex: 0 1 auto; min-width: 0; }
.sbx-chipstrip > .sbx-subline   { grid-row: 1; grid-column: 4 / -1; }
/* row 2 — the chip family, one column each */
.sbx-chips > .sbx-chip.migc, .sbx-chips > .sbx-chip.gflip { grid-row: 2; grid-column: 1; }
.sbx-chips > .sbx-chip.sr    { grid-row: 2; grid-column: 2; }
.sbx-chips > .sbx-chip.dl { grid-row: 2; grid-column: 3; }
.sbx-chips > .sbx-visit      { grid-row: 2; grid-column: 4; }
.sbx-chips > .sbx-chip.rev-b, .sbx-chips > .sbx-chip.rev-t { grid-row: 2; grid-column: 5; }
/* the ladder-path targets own column 6, so the chip lands in the SAME place whatever else is on
   the strip — an auto-placed chip moved with its neighbours and could open a 4th, clipped row
   (Codex targets-r1). Its 76px are TAKEN from the dealer track, measured in headless Chrome at
   this font: dealer's longest state ("DL DEFENDED") paints 106px inside 210px, while migr's
   longest paints 196px inside 200px and has nothing to give. The strip's total is UNCHANGED at
   914px, so the board overflows at the width it did before this feature existed — an added track
   was wrong either way: fixed pushed the requirement to 1132px, and minmax let this last column
   collapse to an unreadable sliver (Codex targets-r2, r3). The labels fit 76px; the sentence is
   in the tooltip. The row-1 subline and the row-3 lattice keep their `/ -1` spans so they run
   THROUGH this column with their widths unchanged — they are on rows 1 and 3, the chip on row 2.
   Pinning them short of it took 76px off the lattice and its values overlapped their labels,
   caught by SBX-147's constant-geometry check. */
.sbx-chips > .sbx-chip.tgt   { grid-row: 2; grid-column: 6; overflow: hidden; text-overflow: ellipsis; }
/* row 3 — the CVD read, the ES footprint chip (ES-FOOTPRINT-STRIKE-INTERACTION.md R15: in the
   chipstrip beside the CVD read, never on the price line) and the per-strike delta-flow lattice.
   The CVD read gave up its second track to the footprint chip; the lattice keeps its THREE tracks.
   It briefly had two (336px): six windows do not fit there, and the squeeze gate measured the
   labels and values of the dense strikes painted over each other. The footprint chip cuts from
   the RIGHT with an ellipsis when narrow (R16) — every field is in its tooltip and its drill-down,
   and a value is never renamed to fit. */
.sbx-chipstrip > .sbx-cvdread { grid-row: 3; grid-column: 1; }
.sbx-chipstrip > .sbx-fpchip  { grid-row: 3; grid-column: 2; }
.sbx-chipstrip > .sbx-dlat    { grid-row: 3; grid-column: 3 / -1; }
/* Every slot holds its width whatever the text does. `justify-self: stretch` (the default) is
   load-bearing: with `start` a chip is sized to its CONTENT and the 300px cap let it spill into
   the next column — measured, γ-TIME ran 424→724 across a track ending at 634. */
.sbx-chipstrip > *, .sbx-chips > * {
  min-width: 0; max-width: 100%; justify-self: stretch;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* The strip is budgeted at THREE lines; a fourth would be clipped in silence. Capping each
   chip means no single backend string can reach one — the overflow ellipsizes with the full text
   in the chip's tooltip, which is visible truncation rather than a vanished line. */
.sbx-chipstrip .sbx-chip, .sbx-chipstrip .sbx-cvdread, .sbx-chipstrip .sbx-fpchip, .sbx-chipstrip .sbx-visit,
.sbx-chipstrip .sbx-floormean, .sbx-chipstrip .sbx-wallmean {
  max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* verdict as a chip; the full read lives in its tooltip */
.sbx-vchip { font-size: 12px; font-weight: 800; letter-spacing: .05em; border-radius: 4px;
             padding: 1px 8px; white-space: nowrap; }
.sbx-vchip.pin { background: #3a2f10; color: #ffd965; }
.sbx-vchip.rej { background: #33131c; color: #ff8fb0; }
.sbx-vchip.def { background: #10331c; color: #7fd08b; }
.sbx-vchip.dim { background: #161c29; color: #93a2ba; }
body.sbx-light .sbx-vchip.dim { background: #eef1f7; color: #5d6b84; }
body.sbx-light .sbx-vchip.pin { background: #faf0d8; color: #8a6410; }
body.sbx-light .sbx-vchip.rej { background: #fbe6ec; color: #b02a55; }
body.sbx-light .sbx-vchip.def { background: #e2f4e8; color: #177a41; }

/* GAMMA LEADS (owner): the gauge GAINS height while everything around it gives it up */
/* SBX-173 (owner, 2026-08-19: "why you made such a thin gamma — i want bigger like before").
   SBX-171 paid for the readings row by halving the bar; the owner would rather pay in box
   height. The bar is back to its full 30px and --sbx-h carries the 15px difference (174 -> 189),
   which is still well under the 212px this box came from. Gamma is the lead reading and now
   looks like it: 30px of bar, with every reading in its own row above rather than on top of it. */
.sbx-gexbar { height: 30px; border-radius: 6px; }
.sbx-gexread { height: 20px; }
.sbx-gexval { font-size: 17px; font-weight: 800; letter-spacing: .01em; }

/* three exposure meters on ONE line */
.sbx-auxrow { display: flex; align-items: center; gap: 14px; width: 100%; flex-wrap: nowrap; }
.sbx-auxrow .sbx-aux { width: auto; flex: 1 1 0; grid-template-columns: 42px 1fr 62px; gap: 5px; }
.sbx-auxrow .sbx-aux .ml { font-size: 10.5px; }
.sbx-auxrow .sbx-aux .mv { font-size: 11.5px; }

/* liquidity ribbons under the gauge (owner), call left / put right */
.sbx-liqpair { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; width: 100%; }
.sbx-liqpair .sbx-lh { gap: 5px; }
/* SBX-171: 11 -> 9px pays the 1px the readings row still owed after the bar gave up 15
   (measured: core 115 in a 174 budget, so the box overflowed by exactly 1). The ribbon is a
   density strip, not a magnitude — 9px reads the same at a glance. */
.sbx-liqpair .sbx-ribbon { width: 100%; min-width: 0; height: 9px; }
.sbx-liqpair .cap { font-size: 10px; white-space: nowrap; }

/* One-line price row. Every track is FIXED and sized from a MEASURED worst case (headless
   Chrome, Range-based text extents at the 392px minimum core, where the line has 366px):
     floor 24  >= icon 21          price 94  >= "19999" at 27px (91)
     role 142  >= "SUPPORT · FLOOR" (139, the widest label roleFor can ever return)
     equiv 30  >= "19999" at 8px (29, the 4-digit real case is 23)
     dist  1fr >= "−199.8" (43)    -> 44px actual, 1px slack
   SBX-160 SPENT the line's remaining headroom: `dist` used to get 82px (39px slack) and the new
   equiv track + its gap take 38 of that. Every case above is MEASURED and fits, but the next
   feature on this line has nowhere left to go — it must take space from a named track, not from
   slack that no longer exists.
   The clock is NOT here: it is a global value the tick wrote identically into every box, and at
   106px it did not fit alongside the rest. It now renders once in the header. */
.sbx-core { gap: 1px; padding: 4px 12px 2px; justify-content: flex-start; }
.sbx-priceline { grid-template-columns: [floor] 24px [price] 94px [equiv] 30px [role] 142px [dist] minmax(0, 1fr);
                 gap: 2px 8px; max-width: 100%;
                 /* Clip HORIZONTALLY only. `overflow: hidden` clipped vertically too, and the
                    floor-test ring is an outline drawn 4px OUTSIDE the 27px price glyph — so its
                    top and bottom arcs were cut away and it read as a pair of angle brackets
                    rather than a ring around the strike (owner, ES 7820). A safety marker that
                    looks like a rendering artifact is worse than no marker. clip-path keeps the
                    width guard the fixed tracks depend on while letting the ring show. */
                 clip-path: inset(-40px 0 -40px 0); }
.sbx-priceline .sbx-dist { grid-column: dist; justify-self: start; white-space: nowrap; font-size: 12.5px; }
.sbx-price { font-size: 27px; }
.sbx-role { font-size: 11px; overflow: hidden; text-overflow: ellipsis; }
.sbx-clock { font-size: 12px; }
/* the sticker owns its own cell now — no inline margin that would shift the strike number */
.sbx-priceline .sbx-floor-ico { grid-column: floor; justify-self: center; margin-right: 0; }

/* wings: the same PROVEN rows (their track math already fits 1370) — height comes out of
   leading and padding, which costs no width. Fixed tracks, no max-content. */
.sbx-zone { padding: 3px 14px; gap: 1px; justify-content: center; }
.sbx-ztitle { display: none; }
.sbx-zone.call .sbx-row, .sbx-zone.put .sbx-row { gap: 0 12px; line-height: 1.15; }
.sbx-zone.put .sbx-row.r2 { grid-template-columns: 92px 92px 220px; }
.sbx-zone.call .sbx-row.r2 { grid-template-columns: 220px 92px 92px; }
.sbx-zone.call .sbx-row.r2b, .sbx-zone.put .sbx-row.r2b { grid-template-columns: 188px; }
.sbx-f { line-height: 1.1; }
.sbx-v { font-size: 14px; }
.sbx-v.vol-r1 { font-size: 19px; } .sbx-v.vol-r2 { font-size: 17px; } .sbx-v.vol-r3 { font-size: 15px; }
.sbx-clu, .sbx-chip { padding: 1px 7px; }
.sbx-ribbon { height: 10px; }
.sbx-dlat { gap: 7px; }
.sbx-dw { min-width: 30px; }
.sbx-dw .l { font-size: 10px; }
.sbx-dw .v { font-size: 12px; }

/* classifier net: the NUMBER, coloured — no pill, no BOUGHT/SOLD/MIXED wording and no
   frontend threshold deciding what "counts" (owner) */
/* SBX-153 (owner, 2026-08-18): the net flow value matches the option-chain page's own net cell —
   same size, same weight, same colours, same tabular figures — so one number does not read as two
   different readings across two pages. The old page also draws a 1px black shadow behind that
   number; that part is deliberately NOT carried over, because this stylesheet is solid-flat only
   (SBX-122) and a test forbids any shadow declaration here. */
.sbx-net { font-size: 14px; font-weight: 950; letter-spacing: .01em; white-space: nowrap;
           font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }
.sbx-net.bought { color: #44f19a; }
.sbx-net.sold { color: #ff6a76; }
/* buy == sell exactly: neither bought nor sold, so neither colour claims it */
.sbx-net.flat { color: #8a99ab; }
body.sbx-light .sbx-net.flat { color: #5d6b84; }
body.sbx-light .sbx-net.bought { color: #177a41; }
body.sbx-light .sbx-net.sold { color: #c22e5c; }

/* SBX-181: the ES book's status, beside the switch that asked for it. Amber, because it reports a
   surface that CANNOT draw — not an error, and not a normal reading either. Inline-block with its
   own padding so turning it on never reflows the toggle row's height. */
/* SBX-181: a PROJECTED basis is HATCHED, so an estimated ES->SPX alignment can never be mistaken
   for a measured one at a glance. The option chain marks the same fact with a dashed axis; this is
   the same statement in this page's idiom. Painted with a gradient over the fill rather than a
   border, so it costs no layout — the lane's geometry must not change with the book's basis. */
.sbx-gexlane.es .sbx-gexfill.sbx-esproj {
  background-image: repeating-linear-gradient(135deg, rgba(255, 255, 255, .30) 0 2px, transparent 2px 5px);
}

.sbx-esoff { display: inline-block; margin-left: 5px; padding: 0 5px; border-radius: 3px;
            font-size: 10.5px; font-weight: 800; white-space: nowrap;
            background: #10403f; color: #7fd8cf; }
body.sbx-light .sbx-esoff { background: #dff1ef; color: #10635c; }
.sbx-esstatus { display: inline-block; margin-left: 6px; padding: 0 5px; border-radius: 3px;
                font-size: 10.5px; font-weight: 800; letter-spacing: .04em; white-space: nowrap;
                background: #3a2c10; color: #ffcc66; }
body.sbx-light .sbx-esstatus { background: #fbf0d8; color: #7d5a08; }

/* STRUCTURAL SENTINEL — keep LAST. The squeeze gate reads this back from the computed style, and
   it gates exactly one thing: the browser abandoning the stylesheet before its end, which leaves
   this property undeclared. It does NOT detect an orphaned comment mid-file — measured, Chrome
   recovers at the next closing brace and still reaches this rule — so that case is caught by the
   lexical test in strike-board-squeeze-geometry.test.js instead. */
:root { --sbx-parsed-to-end: yes; }

/* ---------- SPOT BAND lane: what this strike traded while spot sat in the selected range ----------
   Directly below the gamma bar, and always present so changing the band cannot alter a box's height.
   Colour = side (call / put), fill = direction (solid bought, hollow sold): four quantities, because
   side alone cannot carry direction — a bought call and a SOLD put are both bullish. */
.sbx-bandbar { display: flex; align-items: center; gap: 6px; height: 15px; margin-top: 3px; }
.sbx-bandbar .ml { font-size: 9.5px; letter-spacing: .1em; color: #7d8ba4; min-width: 30px; }
.sbx-bandtrack { position: relative; flex: 1 1 auto; min-width: 0; height: 9px; display: flex; gap: 1px;
                 background: rgba(148,163,189,.10); border-radius: 2px; overflow: hidden; }
.sbx-bandtrack .bd { display: block; height: 100%; border-radius: 1px; }
.sbx-bandtrack .bd.c { background: #3987e5; color: #3987e5; }
.sbx-bandtrack .bd.p { background: #d95926; color: #d95926; }
/* SBX-122 forbids shadows board-wide, so a SOLD segment is outlined with a border. border-box keeps
   the width the same quantity either way. (The banned property is not named here on purpose: the
   stylesheet is SERVED, and the gate that enforces the rule is a plain substring check over it.) */
.sbx-bandtrack .bd.sold { background: transparent; border: 1.5px solid currentColor; box-sizing: border-box; }
.sbx-bandbar .mv { font-size: 10.5px; font-variant-numeric: tabular-nums; color: #b8c5da; min-width: 44px;
                   text-align: right; }
/* the busiest strike of the selected band — the same gold the board already reserves for a leader */
.sbx-bandbar.leads .mv { color: #f5c451; font-weight: 700; }
body.sbx-light .sbx-bandbar .ml { color: #5d6b84; }
body.sbx-light .sbx-bandbar .mv { color: #1c2333; }
body.sbx-light .sbx-bandbar.leads .mv { color: #a8790d; }

/* ---------- WALL box: its own track directly under the gamma bar (the Wall toggle) ----------
   Owner 2026-09-13: "the same on strike board … just below the gamma bar … separate box, not the box
   inside the gamma bar". The gamma bar keeps its full height; this is a row of its own, added to EVERY
   box by the toggle, never by a row's data. Put bid size grows LEFT from the centre in cyan, call ask
   size RIGHT in orange — the Liquidity Wall page's colours. A strike inside a live wall gets a solid
   bracket on that side and an S / R tag; a stale, non-LIVE or DEGRADED frame draws the flat grey track
   and no sizes. Same row metrics as the spot band lane below it (15px + 3px margin). No shadows
   (SBX-122): the bracket is a border. */
/* width: 100% like the gamma bar above it — .sbx-core centres its children, so a row without it shrinks
   to its two numbers and the track collapses (measured: 2px wide at zoom 0.6) */
.sbx-wallbox { display: flex; align-items: center; gap: 6px; width: 100%; height: 15px; margin-top: 3px; }
.sbx-wallbox .wv { font-size: 10.5px; font-variant-numeric: tabular-nums; min-width: 30px; }
.sbx-wallbox .wv.b { color: #3fa7d6; text-align: right; }
.sbx-wallbox .wv.a { color: #e0713a; text-align: left; }
.sbx-wallbox .wv.sbx-dim { color: #7d8ba4; }
.sbx-walltrack { position: relative; flex: 1 1 auto; min-width: 0; height: 11px; box-sizing: border-box;
                 background: rgba(148,163,189,.10); border-radius: 2px; overflow: hidden;
                 border-left: 3px solid transparent; border-right: 3px solid transparent; }
.sbx-walltrack .wb, .sbx-walltrack .wa { position: absolute; top: 0; bottom: 0; display: block; }
.sbx-walltrack .wb { right: 50%; background: #3fa7d6; }
.sbx-walltrack .wa { left: 50%; background: #e0713a; }
.sbx-walltrack .wx { position: absolute; top: 0; bottom: 0; left: 50%; width: 1px; background: rgba(255,255,255,.55); }
.sbx-wallbox.in-s .sbx-walltrack { border-left-color: #3fa7d6; }
.sbx-wallbox.in-r .sbx-walltrack { border-right-color: #e0713a; }
.sbx-walltrack .wt { position: absolute; top: 0; bottom: 0; font-size: 8.5px; font-weight: 800; line-height: 11px;
                     padding: 0 2px; color: #07090f; font-style: normal; }
.sbx-walltrack .wt.s { left: 0; background: #3fa7d6; }
.sbx-walltrack .wt.r { right: 0; background: #e0713a; }
.sbx-wallbox.stale .sbx-walltrack { background: rgba(88,96,108,.45); }
body.sbx-light .sbx-walltrack { background: rgba(28,35,51,.08); }
body.sbx-light .sbx-walltrack .wx { background: rgba(28,35,51,.45); }
body.sbx-light .sbx-wallbox .wv.b { color: #1f7fae; }
body.sbx-light .sbx-wallbox .wv.a { color: #b4541f; }
body.sbx-light .sbx-wallbox.stale .sbx-walltrack { background: rgba(88,96,108,.30); }

/* ---------- SPOT BAND selector: two handles over the prices this board has SEEN trade ---------- */
.sbx-bandslider { position: relative; flex: 1 1 220px; min-width: 180px; height: 26px; }
.sbx-bandslider .rail { position: absolute; top: 11px; left: 0; right: 0; height: 4px; border-radius: 2px;
                        background: rgba(148,163,189,.22); }
.sbx-bandslider .sel { position: absolute; top: 11px; height: 4px; border-radius: 2px; background: #f5c451; }
.sbx-bandslider input[type=range] { position: absolute; top: 2px; left: 0; width: 100%; margin: 0;
  height: 22px; background: none; -webkit-appearance: none; appearance: none; pointer-events: none; }
.sbx-bandslider input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; pointer-events: auto;
  width: 14px; height: 22px; border-radius: 4px; background: #131926; border: 2px solid #f5c451; cursor: ew-resize; }
.sbx-bandslider input[type=range]::-moz-range-thumb { pointer-events: auto;
  width: 14px; height: 22px; border-radius: 4px; background: #131926; border: 2px solid #f5c451; cursor: ew-resize; }
.sbx-bandslider input[type=range]:focus-visible::-webkit-slider-thumb { outline: 2px solid #3987e5; outline-offset: 2px; }
.sbx-bandreset { appearance: none; border: 1px solid rgba(148,163,189,.35); background: transparent;
  color: #b8c5da; font: 600 10px/1 inherit; letter-spacing: .08em; text-transform: uppercase;
  padding: 5px 8px; border-radius: 5px; cursor: pointer; }
.sbx-bandreset:hover { border-color: #f5c451; color: #f5c451; }
body.sbx-light .sbx-bandslider input[type=range]::-webkit-slider-thumb { background: #fff; border-color: #a8790d; }
body.sbx-light .sbx-bandslider .sel { background: #a8790d; }
body.sbx-light .sbx-bandreset { color: #5d6b84; }

/* GMS-R14 leader-fragility chip (FragilityBar). States are the record's own words. */
.sbx-fragchip { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; white-space: nowrap;
  padding: 2px 8px; border-radius: 4px; border: 1px solid transparent; }
.sbx-fragchip.sbx-frag-ok  { background: #10331c; border-color: rgba(127, 208, 139, .3); color: #7fd08b; }
.sbx-fragchip.sbx-frag-mid { background: #2e2410; border-color: rgba(232, 193, 90, .3); color: #e8c15a; }
.sbx-fragchip.sbx-frag-bad { background: #331313; border-color: rgba(226, 116, 116, .35); color: #e27474; }
/* STALE is a STATE, so it gets a hue, never a fade (no-faded-states rule): the grey of a
   reading that stands but cannot claim to be live. */
.sbx-fragchip.sbx-frag-stale { background: #1a1d24; border-color: rgba(150, 155, 165, .3); color: #969ba5; }


/* ES footprint on the ladder (ES-FOOTPRINT-STRIKE-INTERACTION.md R15–R18). The chip is the producer's
   own words under six labels; the three empty states are LOADING, NO DATA and the em dash. */
.sbx-fpchip { display: inline-flex; align-items: center; gap: 7px; font-size: 11px; white-space: nowrap; cursor: default;
              background: #101c30; border: 1px solid rgba(127, 179, 255, .25); color: #9fc3ff; border-radius: 4px; padding: 2px 8px; }
.sbx-fpchip.data { cursor: pointer; }
.sbx-fpchip.data:hover { border-color: rgba(127, 179, 255, .6); }
.sbx-fpchip.loading, .sbx-fpchip.nodata { color: #7d8aa3; border-style: dashed; }
.sbx-fpchip .fp-k { font-weight: 800; letter-spacing: .08em; }
.sbx-fpchip .fp-st { font-weight: 800; letter-spacing: .05em; color: #7fd08b; }
.sbx-fpchip.susp .fp-st { color: #e8c15a; }
.sbx-fpchip .fp-deg { color: #e8c15a; font-weight: 700; }
.sbx-fpchip .fp-k, .sbx-fpchip .fp-st, .sbx-fpchip .fp-deg { flex: none; }
/* R16: the six fields live in ONE shrinking text container, so the ellipsis lands on the rightmost field */
.sbx-fpchip .fp-values { flex: 1 1 auto; min-width: 0; display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sbx-fpchip .fp-f { opacity: .95; }
body.sbx-light .sbx-fpchip { background: #e8f0fd; color: #2456a8; border-color: #b9cdec; }
body.sbx-light .sbx-fpchip.loading, body.sbx-light .sbx-fpchip.nodata { color: #6b7790; }
body.sbx-light .sbx-fpchip .fp-st { color: #177a41; }
body.sbx-light .sbx-fpchip.susp .fp-st, body.sbx-light .sbx-fpchip .fp-deg { color: #8a6410; }
.sbx-fpbar label { display: inline-flex; gap: 6px; align-items: center; }
/* the drill-down: history rows, newest first, expandable to the per-bar series */
.sbx-fpdrill { position: fixed; right: 16px; bottom: 16px; z-index: 70; max-width: min(96vw, 1180px); max-height: 70vh; overflow: auto;
               background: #0c1220; color: #d7e2f5; border: 1px solid rgba(127, 179, 255, .35); border-radius: 6px; padding: 10px 12px; font-size: 12px; }
.sbx-fpdrill .fp-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 6px; }
.sbx-fpdrill .fp-head button, .sbx-fpdrill .fp-more { background: #182338; color: #d7e2f5; border: 1px solid rgba(127, 179, 255, .35); border-radius: 4px; padding: 2px 8px; cursor: pointer; }
.sbx-fpdrill table { border-collapse: collapse; width: 100%; }
.sbx-fpdrill th, .sbx-fpdrill td { padding: 2px 8px; text-align: left; white-space: nowrap; border-bottom: 1px solid rgba(127, 179, 255, .12); }
.sbx-fpdrill th { color: #8fb8ff; font-weight: 700; letter-spacing: .05em; font-size: 11px; }
.sbx-fpdrill tr.fp-ep { cursor: pointer; }
.sbx-fpdrill tr.fp-ep:hover td { background: rgba(127, 179, 255, .08); }
.sbx-fpdrill tr.fp-ep.degraded td:first-child::after { content: ' ◐'; color: #e8c15a; }
.sbx-fpdrill tr.fp-series > td { padding: 4px 8px 8px 24px; background: rgba(127, 179, 255, .04); }
.sbx-fpdrill .fp-boundary { margin-top: 6px; }
/* the row's expansion control is a native button (keyboard + screen reader), styled as the row's own chevron */
.sbx-fpdrill .fp-xbtn { background: transparent; color: inherit; border: 1px solid transparent; border-radius: 3px; padding: 0 5px; font: inherit; line-height: 1.2; cursor: pointer; }
.sbx-fpdrill .fp-xbtn:hover { border-color: rgba(127, 179, 255, .45); }
.sbx-fpdrill .fp-xbtn:focus-visible, .sbx-fpdrill .fp-more:focus-visible, .sbx-fpdrill .fp-head button:focus-visible { outline: 2px solid #7fb3ff; outline-offset: 1px; }
.sbx-fpdrill .fp-series-more { margin-top: 4px; }
.sbx-fpdrill .fp-stalled .fp-more { margin-left: 6px; }
body.sbx-light .sbx-fpdrill .fp-xbtn:focus-visible, body.sbx-light .sbx-fpdrill .fp-more:focus-visible, body.sbx-light .sbx-fpdrill .fp-head button:focus-visible { outline-color: #2456a8; }
body.sbx-light .sbx-fpdrill { background: #f7f9fd; color: #1c2740; border-color: #b9cdec; }
body.sbx-light .sbx-fpdrill th { color: #2456a8; }
body.sbx-light .sbx-fpdrill .fp-head button, body.sbx-light .sbx-fpdrill .fp-more { background: #e8f0fd; color: #2456a8; border-color: #b9cdec; }
body.sbx-light .sbx-fpdrill tr.fp-ep.degraded td:first-child::after { color: #8a6410; }
