/* blazecrash.css — 🚀 BLAZE Crash.
 *
 * Modeled on blazewheel.css: same dark-panel, gold-glow, Comic-Sans identity as
 * the rest of the site, and self-sufficient on purpose — nav.css is the only
 * other stylesheet this page links, so the .viewer-info-btn / .viewer-modal-*
 * "how it works" block and the footer/trust-strip rules are copied here rather
 * than shared.
 *
 * nav.css CONSUMES --navbar-bg, --glow, --c-gold and --c-orange from the page's
 * own stylesheet. A page that forgets them renders the navbar transparent with
 * no shadow, and an unresolved var() fails silently. They are declared first,
 * below, for exactly that reason.
 *
 * THE ROCKET'S MOTION CONTRACT, in one place. The flight itself is drawn by
 * blazecrash.js on the #bcCanvas 2D context — CSS never animates the rocket.
 * What CSS owns is the SKY: .bc-skybox carries a data-state attribute
 * ("pad" | "ignition" | "flight" | "won" | "busted" | "moon") that drives the
 * backdrop glow, the pad shake during ignition, and the burst flash — feel,
 * never facts. JS owns WHERE the flight ends (the emitted crashX100).
 */

*, *::before, *::after { box-sizing: border-box; }

:root {
    --nav-h: 80px;
    --touch: 44px;

    /* The four tokens nav.css needs. Do not remove. */
    --navbar-bg: rgba(0, 0, 0, 0.95);
    --glow: 0 0 10px rgba(255, 69, 0, 0.7);
    --c-gold: #ffcf48;
    --c-orange: orange;

    --c-red: #ff4500;
    --c-green: #2ecc71;
    --c-moon: #cfd8ff;

    /* TEXT CONTRAST. Two solid warm neutrals, both well clear of 7:1 on the
       dark panel (same pair as blazeplinko.css/blazewheel.css — translucent
       text over a translucent panel has no fixed contrast ratio at all). */
    --c-soft: #f2ece0;
    --c-dim: #ded6c6;
}

body {
    margin: 0;
    padding: 0;
    font-family: var(--font-body, "Comic Sans MS", system-ui, sans-serif);
    /* Owner report 2026-08-13: this page's background must MATCH its casino
       siblings (wheel/plinko/dice) — same art treatment, same #b0e8f7 sky.
       An earlier draft used cover + a dark navy fallback, which made this the
       only page on the site with a different backdrop. Block copied verbatim
       from blazewheel.css; the wheel proves this layout doesn't ghost-read. */
    background: url('images/BlazeitBG.png') no-repeat center center;
    background-size: 100% auto;
    background-repeat: no-repeat;
    background-position: center center;
    background-attachment: fixed;
    background-color: #b0e8f7;
    color: white;
    display: flex;
    flex-direction: column;
    align-items: center;
    min-height: 100vh;
    width: 100%;
    overflow-x: hidden;
    padding-top: calc(var(--nav-h) + 24px);
}

@media screen and (max-width: 768px) {
    body { padding-top: calc(var(--nav-h) + 16px); }
}

.sr-only {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
    position: absolute; left: -9999px; top: 0;
    background: #000; color: var(--c-gold); padding: 10px 16px; z-index: 3000;
}
.skip-link:focus { left: 8px; top: calc(var(--nav-h) + 8px); }

/* Sticky footer: body is the flex column, main takes the slack, footer
   stretches across the bottom. THREE COLUMNS, same arrangement as
   blazedice/blazeplinko/blazewheel — one 0.75 container, readable panels. */
main.container {
    flex: 1 1 auto;
    width: min(1500px, 96vw);
    margin: 0 auto 24px;
    padding: 18px;
    background: rgba(0, 0, 20, 0.75);
    border-radius: 18px;
    display: grid;
    grid-template-columns: minmax(260px, 1fr) minmax(420px, 1.6fr) minmax(260px, 1fr);
    gap: 18px;
    align-items: start;
}

.info-panel { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
/* Panel titles sit centred in BOTH side columns, matching 🎲 Roll the Dice,
   🪀 Blaze Drop and 🎡 Spin the Wheel, which all carry this exact rule. Crash
   shipped without it and was the only game whose box titles hugged the left
   edge while its siblings centred theirs. Scoped to .info-panel on purpose: the
   middle column's control headings (Stake / Target / Session budget) are not
   box titles and stay where they are, same as on the other three. */
.info-panel h3, .info-panel h2 { text-align: center; }
.game-panel { display: flex; flex-direction: column; align-items: center; gap: 14px; min-width: 0; }

@media screen and (max-width: 1100px) {
    main.container { grid-template-columns: 1fr; }
    /* Spine first on a phone: the rocket and the button above the fold. */
    .game-panel { order: -1; }
}

/* The shared readable panel. */
.stats {
    background: rgba(0, 0, 0, 0.78);
    border: 1px solid rgba(255, 207, 72, 0.35);
    border-radius: 14px;
    padding: 14px 16px;
    box-shadow: var(--glow);
    width: 100%;
    color: var(--c-soft);
}
.stats h3, .stats h2 { margin: 0 0 10px; color: var(--c-gold); font-size: 1.05rem; }
.stats p { margin: 6px 0; font-size: 0.95rem; line-height: 1.45; }
/* The 3-steps-blockhash / 2-steps-VRF note (owner request, 2026-08-13). Reads
   as a callout under the ritual, not as another step. */
.bc-mode-note {
    margin-top: 10px;
    padding: 8px 10px;
    border-left: 3px solid var(--c-orange);
    border-radius: 6px;
    background: rgba(255, 140, 0, 0.09);
}

.title {
    margin: 0;
    color: var(--c-gold);
    text-shadow: 0 0 12px rgba(255, 69, 0, 0.8);
    font-size: clamp(1.6rem, 3.4vw, 2.4rem);
    text-align: center;
}
.tagline { margin: 0; color: var(--c-dim); text-align: center; }

.bc-banner {
    width: 100%;
    border-radius: 10px;
    padding: 10px 14px;
    font-weight: bold;
    text-align: center;
}
.bc-banner-warn { background: rgba(255, 69, 0, 0.25); border: 1px solid var(--c-red); color: #ffd9c9; }

/* ------------------------------ The hero ------------------------------ */

.bc-hero { width: 100%; display: flex; flex-direction: column; align-items: center; gap: 8px; }

/* The sky. The canvas scales with its box; blazecrash.js reads the box's
   CSS pixel size each frame and resizes the bitmap for devicePixelRatio, so
   the drawing is crisp at every width without any layout dependence here. */
.bc-skybox {
    position: relative;
    width: 100%;
    max-width: 640px;
    aspect-ratio: 32 / 21;
    border-radius: 14px;
    overflow: hidden;
    border: 1px solid rgba(255, 207, 72, 0.4);
    background: linear-gradient(to top, #1a1035 0%, #0b1030 55%, #05081c 100%);
    box-shadow: var(--glow);
}
.bc-skybox canvas { display: block; width: 100%; height: 100%; }

/* WATCH OUT — IGNITION. Blinks INSIDE the flight board while a launch waits
   for the chain/oracle to decide the flight (owner request, 2026-08-13).
   Decoration over the canvas; #bcReadout carries the accessible status. */
.bc-ignition-warning {
    position: absolute;
    /* Clear of the ringed planet at 16%/16% — the two used to overlap. */
    top: 26%;
    left: 50%;
    transform: translateX(-50%);
    padding: 6px 14px;
    border-radius: 10px;
    background: rgba(11, 16, 48, 0.72);
    border: 1px solid rgba(255, 69, 0, 0.75);
    color: var(--c-gold);
    font-weight: bold;
    font-size: 1.02rem;
    letter-spacing: 0.04em;
    text-shadow: 0 0 8px rgba(255, 140, 0, 0.9);
    white-space: nowrap;
    animation: bc-ignition-blink 0.9s steps(2, jump-none) infinite;
    pointer-events: none;
}
@keyframes bc-ignition-blink {
    0% { opacity: 1; }
    100% { opacity: 0.25; }
}

/* 🏆 THE RECORD BOX. Fires only when the player's own flight beats the
   game's altitude record, so it is allowed to be the loudest thing on the
   page: a rotating gold-to-fire conic border, a pop-in, and a slow shimmer.
   Everything here is motion and colour — the numbers inside come from the
   chain like every other figure on this page. */
.bc-record {
    position: relative;
    margin: 10px auto 0;
    max-width: 640px;
    padding: 14px 34px 12px;
    text-align: center;
    border-radius: 16px;
    background:
        linear-gradient(rgba(11, 16, 48, 0.94), rgba(26, 16, 53, 0.94)) padding-box,
        conic-gradient(from var(--bc-rec-spin, 0deg), #ffcf48, #ff8c00, #ff4500, #ffcf48) border-box;
    border: 3px solid transparent;
    box-shadow: 0 0 22px rgba(255, 140, 0, 0.55);
    animation: bc-record-in 0.5s cubic-bezier(0.2, 1.5, 0.4, 1), bc-record-spin 4s linear infinite;
}
@property --bc-rec-spin {
    syntax: "<angle>";
    inherits: false;
    initial-value: 0deg;
}
@keyframes bc-record-spin { to { --bc-rec-spin: 360deg; } }
@keyframes bc-record-in {
    from { transform: scale(0.82) translateY(8px); opacity: 0; }
    to   { transform: scale(1) translateY(0); opacity: 1; }
}
.bc-record-title {
    margin: 0;
    font-size: 1.05rem;
    font-weight: bold;
    color: var(--c-gold);
    letter-spacing: 0.05em;
    text-shadow: 0 0 10px rgba(255, 207, 72, 0.85);
}
.bc-record-x {
    margin: 4px 0 2px;
    font-size: 2rem;
    font-weight: bold;
    color: #fff3c4;
    text-shadow: 0 0 16px rgba(255, 140, 0, 0.95);
}
.bc-record-sub { margin: 0; font-size: 0.92rem; color: var(--c-soft); }
.bc-record-pop {
    margin: 6px 0 0;
    font-size: 1.3rem;
    letter-spacing: 0.25em;
    animation: bc-record-pop 1.4s ease-in-out infinite;
}
@keyframes bc-record-pop {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-4px); }
}
.bc-record-close {
    position: absolute;
    top: 6px;
    right: 10px;
    background: none;
    border: none;
    color: var(--c-soft);
    font-size: 1rem;
    cursor: pointer;
    opacity: 0.7;
}
.bc-record-close:hover { opacity: 1; }

/* 🤠 Best Space Cowboy — the altitude podium in The House box. */
.bc-cowboy-head {
    margin-top: 10px !important;
    color: var(--c-gold);
    font-weight: bold;
}
.bc-podium {
    list-style: none;
    margin: 4px 0 0;
    padding: 0;
    font-size: 0.9rem;
}
.bc-podium li {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    padding: 3px 0;
    border-bottom: 1px dashed rgba(255, 207, 72, 0.18);
}
.bc-podium li:last-child { border-bottom: none; }
.bc-podium-x { color: var(--c-gold); font-weight: bold; }
.bc-podium-who { opacity: 0.75; }
.bc-podium-empty { opacity: 0.7; justify-content: flex-start !important; }

/* 🔁 Replay flight — re-flies the last result. Quiet by design: it is a
   toy, not an action, so it never competes with the launch button. */
.bc-replay-btn {
    display: block;
    /* The result banner directly below has margin-top:0, so a 0 bottom margin
       left the pill sitting flush on its border — it read as overlapping.
       12px matches the readout gap above it, so the button sits evenly between
       the two rather than clinging to one. */
    margin: 6px auto 12px;
    padding: 5px 14px;
    font-family: inherit;
    font-size: 0.85rem;
    color: var(--c-gold);
    background: rgba(255, 207, 72, 0.10);
    border: 1px solid rgba(255, 207, 72, 0.55);
    border-radius: 999px;
    cursor: pointer;
    transition: background 0.15s, transform 0.15s;
}
.bc-replay-btn:hover:not(:disabled) { background: rgba(255, 207, 72, 0.22); transform: translateY(-1px); }
.bc-replay-btn:disabled { opacity: 0.45; cursor: default; }
/* [hidden] is set by JS when there is nothing to replay, but the UA rule it
   relies on (display:none) LOSES to the display above — so the button stayed
   visible on every page load and, on the wheel, clickable. Reported live
   2026-08-15. Class+attribute outranks the bare class, so this settles it. */
.bc-replay-btn[hidden] { display: none; }

/* Sky moods — feel only, never facts. */
.bc-skybox[data-state="ignition"] { animation: bc-pad-shake 0.28s linear infinite; }
.bc-skybox[data-state="won"] { border-color: var(--c-green); box-shadow: 0 0 14px rgba(46, 204, 113, 0.8); }
.bc-skybox[data-state="busted"] { border-color: var(--c-red); box-shadow: 0 0 14px rgba(255, 69, 0, 0.85); }
.bc-skybox[data-state="moon"] { border-color: var(--c-moon); box-shadow: 0 0 18px rgba(207, 216, 255, 0.9); }

@keyframes bc-pad-shake {
    0% { transform: translate(0, 0); }
    25% { transform: translate(1px, -1px); }
    50% { transform: translate(-1px, 1px); }
    75% { transform: translate(1px, 1px); }
    100% { transform: translate(0, 0); }
}

.bc-readout {
    margin: 0;
    font-size: 1.05rem;
    color: var(--c-gold);
    text-align: center;
    min-height: 1.4em;
}

.bc-result {
    width: 100%;
    max-width: 640px;
    border-radius: 12px;
    padding: 12px 16px;
    text-align: center;
    font-size: 1.15rem;
    font-weight: bold;
}
.bc-result[data-kind="win"] { background: rgba(46, 204, 113, 0.18); border: 1px solid var(--c-green); color: #d9ffe9; }
.bc-result[data-kind="bust"] { background: rgba(255, 69, 0, 0.18); border: 1px solid var(--c-red); color: #ffd9c9; }
.bc-result[data-kind="moon"] { background: rgba(207, 216, 255, 0.18); border: 1px solid var(--c-moon); color: #eef1ff; }
.bc-result[data-kind="reclaim"] { background: rgba(255, 207, 72, 0.15); border: 1px solid var(--c-gold); color: #fff3d1; }

.bc-quote { margin: 0; color: var(--c-dim); font-style: italic; text-align: center; min-height: 1.3em; max-width: 640px; }

/* ----------------------------- The console ---------------------------- */

.bc-console { display: flex; flex-direction: column; gap: 6px; }
.bc-budget-line { color: var(--c-gold); font-weight: bold; min-height: 1.2em; }
.bc-bet-summary { color: var(--c-soft); }
.bc-odds-line { color: var(--c-gold); font-weight: bold; min-height: 1.2em; }
.bc-payout-preview { color: var(--c-dim); min-height: 1.2em; }
.bc-vrf-fee { color: var(--c-dim); }

.bc-actions { display: flex; flex-direction: column; align-items: center; gap: 6px; margin-top: 4px; }

.wallet-btn {
    font-family: inherit;
    font-size: 1.05rem;
    font-weight: bold;
    color: #1a1035;
    background: linear-gradient(180deg, var(--c-gold), var(--c-orange));
    border: none;
    border-radius: 12px;
    padding: 10px 22px;
    min-height: var(--touch);
    cursor: pointer;
    box-shadow: var(--glow);
}
.wallet-btn:hover:not(:disabled) { filter: brightness(1.08); }
.wallet-btn:disabled { opacity: 0.55; cursor: not-allowed; }

.bc-action-btn { width: 100%; max-width: 420px; font-size: 1.15rem; }
.bc-reclaim-btn { background: linear-gradient(180deg, #9be7ff, #4db8e8); }

.bc-step { margin: 0; color: var(--c-gold); font-weight: bold; }
.bc-hint { margin: 0; color: var(--c-dim); font-size: 0.9rem; text-align: center; max-width: 460px; }

.bc-tx-status { margin: 4px 0 0; color: var(--c-soft); text-align: center; min-height: 1.2em; }
.bc-tx-link { margin: 0; text-align: center; min-height: 1.2em; }
.bc-tx-link a { color: var(--c-gold); }

/* ------------------------- Inputs, chips, budget ----------------------- */

.bc-amount input, .bc-target input {
    width: 100%;
    font-family: inherit;
    font-size: 1.2rem;
    font-weight: bold;
    text-align: center;
    color: var(--c-gold);
    background: rgba(0, 0, 0, 0.6);
    border: 1px solid rgba(255, 207, 72, 0.5);
    border-radius: 10px;
    padding: 8px 12px;
    min-height: var(--touch);
}

.bc-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }

.bc-chip, .bc-target-chip, .bc-budget-chip {
    font-family: inherit;
    font-size: 0.95rem;
    font-weight: bold;
    color: var(--c-gold);
    background: rgba(0, 0, 0, 0.6);
    border: 1px solid rgba(255, 207, 72, 0.5);
    border-radius: 999px;
    padding: 8px 14px;
    min-height: var(--touch);
    min-width: var(--touch); /* a one-digit chip was narrower than it was tall */
    cursor: pointer;
    flex: 1 1 auto;
}
.bc-chip:hover, .bc-target-chip:hover, .bc-budget-chip:hover { border-color: var(--c-gold); box-shadow: var(--glow); }

.bc-allin-chip { color: #ffb066; border-color: rgba(255, 100, 30, 0.7); }

.bc-target-chip[aria-pressed="true"],
.bc-budget-chip[aria-pressed="true"] {
    color: #1a1035;
    background: linear-gradient(180deg, var(--c-gold), var(--c-orange));
}

.bc-limits { color: var(--c-dim); font-size: 0.9rem; }
.bc-amount-error, .bc-target-error { color: #ff9d7a; font-weight: bold; }
.bc-group-label { color: var(--c-dim); font-size: 0.9rem; }
.bc-budget-note { color: var(--c-dim); font-size: 0.9rem; min-height: 1.2em; }

/* ----------------------------- Info panel ----------------------------- */

.bc-info-label { color: var(--c-gold); margin-top: 10px; }
.bc-info-list { margin: 4px 0; padding-left: 20px; }
.bc-info-list li { margin: 3px 0; font-size: 0.92rem; color: var(--c-soft); }

.bc-verify-head { color: var(--c-gold); font-weight: bold; margin-top: 12px; }
.contract-link { color: var(--c-gold); }
.bc-verify-note { color: var(--c-dim); font-size: 0.85rem; }

/* -------------------------- History + the feed ------------------------- */

.bc-history, .bc-feed { list-style: none; margin: 6px 0 0; padding: 0; }
.bc-history li, .bc-feed li {
    display: flex; justify-content: space-between; gap: 8px;
    padding: 6px 8px; border-radius: 8px; font-size: 0.9rem;
}
.bc-history li:nth-child(odd), .bc-feed li:nth-child(odd) { background: rgba(255, 255, 255, 0.05); }
.bc-history li[data-kind="win"], .bc-feed li[data-kind="win"] { color: #b9f2cf; }
.bc-history li[data-kind="bust"], .bc-feed li[data-kind="bust"] { color: #ffc4ab; }
.bc-history li[data-kind="pending"] { color: var(--c-gold); }

/* The outcome half of a Mission Control row must never break mid-value. A win
   carries both the payout and how far the rocket actually flew, which is longer
   than a bust's "burst 1.12x" — without this it wrapped and split a number
   across two lines. nowrap on the outcome, and min-width:0 on the row so the
   description half is the part that gives if the panel gets narrow. */
.bc-feed li { min-width: 0; }
.bc-feed-out { white-space: nowrap; }
.bc-history-status, .bc-feed-status { color: var(--c-dim); font-size: 0.85rem; }

/* ------------------------------ FX layer ------------------------------- */

.bc-fx-layer {
    position: fixed; inset: 0;
    pointer-events: none;
    overflow: hidden;
    z-index: 2500;
}
.bc-fx-layer span {
    position: absolute;
    top: -8vh;
    font-size: 26px;
    animation: bc-fx-fall linear forwards;
}
@keyframes bc-fx-fall {
    from { transform: translateY(0) rotate(0deg); opacity: 1; }
    to { transform: translateY(115vh) rotate(340deg); opacity: 0.85; }
}

/* ---------------------- "how it works" modal shell --------------------- */
/* Copied from blazewheel.css (which copied blazeplinko.css) — the shared
   viewer-modal.js expects these class hooks; each page ships its own copy
   because the site deliberately has no shared game stylesheet. */

.viewer-info-btn {
    font-family: inherit;
    font-size: 0.9rem;
    font-weight: bold;
    color: var(--c-gold);
    background: rgba(0, 0, 0, 0.6);
    border: 1px solid rgba(255, 207, 72, 0.5);
    border-radius: 999px;
    padding: 6px 14px;
    min-height: var(--touch);
    cursor: pointer;
}
.viewer-info-btn:hover { box-shadow: var(--glow); }

.viewer-modal { position: fixed; inset: 0; z-index: 3000; display: flex; align-items: center; justify-content: center; }
.viewer-modal[hidden] { display: none; }
.viewer-modal-backdrop { position: absolute; inset: 0; background: rgba(0, 0, 10, 0.8); }
.viewer-modal-card {
    position: relative;
    width: min(760px, 94vw);
    max-height: 86vh;
    overflow-y: auto;
    background: #10142e;
    border: 1px solid rgba(255, 207, 72, 0.5);
    border-radius: 16px;
    box-shadow: var(--glow);
    padding: 22px 26px;
    color: var(--c-soft);
}
.viewer-modal-card h2 { color: var(--c-gold); margin-top: 0; }
.viewer-modal-close {
    position: absolute; top: 10px; right: 10px;
    font-size: 1.1rem; color: var(--c-gold);
    background: transparent; border: none; cursor: pointer;
    min-height: var(--touch); min-width: var(--touch);
}
.viewer-rap-intro, .viewer-rap-outro { color: var(--c-dim); }
.viewer-rap-verse { margin: 16px 0; }
.viewer-rap-mode { color: var(--c-gold); font-weight: bold; margin-bottom: 4px; }
.viewer-rap { margin: 6px 0; line-height: 1.55; }
.viewer-modal-done { display: block; margin: 18px auto 0; }

/* ------------------------------- Footer -------------------------------- */

/* Footer — the SITE-STANDARD block, byte-for-byte the one in wrapper.css /
   revoker.css / txdecoder.css and the rest. This page used to carry its own
   darker, dimmer variant (0.9 alpha, dim text, bigger padding); the owner saw
   the seam from page to page (2026-09-02: "the footer has to be the same in
   all of our pages"). tests/footer-parity.spec.js pins the computed result. */
.footer {
    width: 100%;
    text-align: center;
    padding: 10px 0;
    background: rgba(0, 0, 0, 0.8);
    color: #fff;
    font-size: 14px;
    margin-top: 20px;
    box-sizing: border-box;
}
.footer p { margin: 0; }
.trust-strip {
    margin-top: 6px;
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    justify-content: center;
    align-items: baseline;
    padding: 0 12px;
    font-size: 12px;
    color: #ded6c6; /* opaque: translucent text over a translucent panel has no contrast ratio (READABILITY rule) */
}
.trust-strip a { color: var(--c-gold); text-decoration: none; }
.trust-strip a:hover, .trust-strip a:focus-visible { color: var(--c-orange); text-decoration: underline; }
.trust-sep { opacity: 0.5; }

/* --------------------------- Reduced motion ---------------------------- */
/* The replay itself is skipped in JS under prefers-reduced-motion (the
   result renders instantly); CSS drops its own theatre to match. */
@media (prefers-reduced-motion: reduce) {
    .bc-skybox[data-state="ignition"] { animation: none; }
    .bc-fx-layer span { animation: none; display: none; }
    /* The record box still APPEARS — it is information, and suppressing it
       would hide a real event. Only its motion stands down. */
    .bc-record { animation: none; }
    .bc-record-pop { animation: none; }
    .bc-ignition-warning { animation: none; }
}

/* ============================ HUD READOUTS ============================
   Owner request, 2026-08-14: "too much information ... doesn't look like the
   UI of a game."

   The diagnosis was hierarchy, not volume. Every readout was
   `Label: value UNIT` at ONE weight and ONE colour, so "House float" and
   "1,309,996" competed as equals and the panel read as a spec sheet. A game HUD
   does the opposite: the label recedes to a caption, the NUMBER is the thing.

   So: labels shrink, uppercase and dim; the value — which is always the
   element carrying the id — goes big, bold and gold with tabular figures so it
   cannot jitter as it repolls. Row rules give the eye a grid to run down.

   CSS ONLY, and deliberately so. Every value already sits in a span[id] that
   the page scripts write into and the tests assert on by exact text, so
   restyling without touching markup means no id moves, no unit sneaks inside a
   value, and nothing to re-verify but the look.

   `:has(span[id])` is what keeps it honest — it selects only rows that actually
   carry a readout. Prose paragraphs in the same panels (the Jackpot Winners
   taunt, the "not audited" note) are left completely alone; uppercasing those
   would have been the obvious way to wreck this. */
.stats p:has(span[id]) {
    display: block;
    margin: 0;
    padding: 6px 0;
    font-size: 12px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    /* OPAQUE, and 7:1 on the panel. The first version used
       rgba(255,255,255,.42) and the dice page's readability guard caught it
       immediately: translucent text over a translucent panel over a photographic
       background has no fixed contrast ratio at all — it is whatever pixel
       happens to sit behind it. --c-dim is the token that exists for this exact
       job (14.5:1 here). The label still recedes, by SIZE, CASE and TRACKING
       rather than by fading out. */
    color: var(--c-dim, #ded6c6);
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.stats p:has(span[id]):last-child { border-bottom: none; }

.stats p:has(span[id]) span[id] {
    display: inline-block;
    margin-left: 2px;
    font-size: 15px;
    font-weight: bold;
    letter-spacing: 0;
    text-transform: none;
    color: var(--c-gold, #ffcf48);
    font-variant-numeric: tabular-nums;
}
