/* swap.css — the BLAZE buy/sell window (window.BlazeSwap, see swap.js).
 *
 * Every class here is created by swap.js's node()/button()/venueChip() helpers.
 * The module builds its DOM with createElement + textContent, so this file is
 * the ONLY place its appearance is decided — there is no inline style anywhere
 * in it.
 *
 * ======================================================================
 *  THIS CARD IS A BLAZE PANEL, NOT A GENERIC DEX WIDGET
 * ======================================================================
 *
 * Rewritten 2026-09-01 against the palette and button language the rest of the
 * site actually uses, rather than a lookalike. Where each cue comes from:
 *
 *   · the card       — style.css `.blaze-board`: radial top glow over a near
 *                      black panel, gold hairline border, the fire glow, and the
 *                      marquee bulb strips that are the site's one unmistakable
 *                      casino cue. The title takes .blaze-board's marquee
 *                      treatment (13px, uppercase, .18em, gold, lit).
 *   · panels/insets  — blazecrash.css `.stats` and `.blaze-board .board-inset`.
 *   · primary button — blazedice.css `.wallet-btn` / style.css `button`: FLAT
 *                      `orange`, BLACK text, bold, 10px radius, `darkorange` on
 *                      hover. The old gradient here was invented; the site has
 *                      no gradient buttons.
 *   · chips + tabs   — blazedice.css `.bd-chip`: pill, gold hairline over near
 *                      black, gold text; pressed goes solid `orange` with black
 *                      text and a white border, exactly like a picked call.
 *   · the input      — blazedice.css `#bdAmountInput`.
 *   · focus ring     — nav.css / blazedice.css: `3px solid var(--c-gold)`,
 *                      offset 2px, on every interactive element. This file had
 *                      none at all before.
 *   · disclaimer     — blazecrash.css `.bc-mode-note`: an orange left rule over
 *                      a faint orange wash, so the honesty line reads as a
 *                      callout instead of as fine print.
 *
 * ======================================================================
 *  FOUR THINGS THIS FILE IS RESPONSIBLE FOR
 * ======================================================================
 *
 *   1. NUMBERS THAT DO NOT JITTER. Every figure in this card refreshes on a
 *      timer while the visitor is reading it. `font-variant-numeric: tabular-nums`
 *      on every numeric cell keeps digit columns still, so a quote updating from
 *      248,683 to 248,691 does not make the whole row twitch.
 *
 *   2. A PRIMARY BUTTON THAT LOOKS LIKE WHAT IT DOES. The confirm button spends
 *      real money on a real chain. It is the loudest thing on the card, and when
 *      it is disabled it does not merely fade — it LOSES THE ORANGE, which is
 *      the only thing on this card that means "this one sends a transaction".
 *
 *   3. ITS OWN BOX MODEL. price.html's stylesheet has no global box-sizing
 *      reset (house.css and arena.css are the same), and `.bsw-btn` is
 *      `width: 100%` plus horizontal padding — under content-box that button is
 *      wider than the card that holds it. The reset at the top of this file is
 *      not tidiness; without it the card visibly spills on that page.
 *
 *   4. HIDING WHAT swap.js HIDES. A class rule that sets `display` beats the UA
 *      `[hidden]` rule, whatever the specificity. `.bsw-tx` used to declare
 *      `display: inline-block`, so the "🔎 View on SonicScan" link rendered on
 *      every card from the moment it mounted, hrefless, whether or not anything
 *      had been sent. Every element the module toggles with `hidden` therefore
 *      gets an explicit `[hidden]` rule below.
 *
 * State — which side, which pool, which slippage — rides on `aria-pressed`, not
 * on a class. swap.js sets the attribute and the selectors below hang off it, so
 * what is drawn and what a screen reader announces are the same fact instead of
 * two things that can drift apart.
 *
 * Brand tokens (--c-gold, --c-orange, --glow, --navbar-bg) come from the host
 * page's own stylesheet; nav.css defines :root fallbacks for all four, so a page
 * that forgets them still renders a sane dark card rather than a transparent
 * one. Every var() below still carries a literal fallback of its own.
 *
 * NOTE ON --glow: it is a full box-shadow VALUE ("0 0 10px rgba(255,69,0,.7)"),
 * not a colour. `box-shadow: 0 0 22px var(--glow)` expands to a malformed
 * shadow and the whole declaration is dropped — which is why the old primary
 * button had no glow at all on either page that hosts it. Use it as the entire
 * value, never as a component of one.
 */

/* ── box model ────────────────────────────────────────────────────────── */

.bsw-wrap,
.bsw-wrap *,
.bsw-card,
.bsw-card * {
    box-sizing: border-box;
}

/* ── tokens ───────────────────────────────────────────────────────────────
   Declared on BOTH the host rail and the card itself. The card is the only
   consumer, and a page that mounts #blazeSwap without wrapping it in
   .bsw-wrap must still resolve every one of them — an unresolved var() fails
   silently and takes its whole declaration with it, which is how a dark panel
   turns into a transparent one with no error anywhere. */

.bsw-wrap,
.bsw-card {
    /* Surfaces, matched to blazecrash.css `.stats` / `.blaze-board`. */
    --bsw-panel: rgba(0, 0, 0, .84);
    --bsw-inset: rgba(0, 0, 0, .45);
    --bsw-field: rgba(0, 0, 0, .55);

    /* The gold hairline every panel and chip on this site is drawn with. */
    --bsw-line: rgba(255, 207, 72, .35);
    --bsw-line-chip: rgba(255, 207, 72, .45);
    --bsw-line-hot: rgba(255, 207, 72, .95);

    /* Two solid warm neutrals, the same pair blazecrash/plinko/wheel use —
       translucent text over a translucent panel has no fixed contrast ratio. */
    --bsw-soft: #f2ece0;
    --bsw-dim: #ded6c6;

    /* Status colours, matched to style.css --c-ok / --c-bad and the ticker. */
    --bsw-good: #4ade80;
    --bsw-warm: #ffb066;
    --bsw-bad: #ff6b5e;

    /* The whole shadow, never a piece of one. See the note in the header. */
    --bsw-glow: var(--glow, 0 0 10px rgba(255, 69, 0, .7));
}

.bsw-wrap {
    width: 100%;
    max-width: 460px;
    margin-inline: auto;
}

/* ── the card ─────────────────────────────────────────────────────────── */

.bsw-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: .85rem;
    /* Extra top/bottom room for the marquee bulb strips. */
    padding: 1.4rem 1.15rem;
    border-radius: 14px;
    border: 1px solid var(--bsw-line);
    background:
        radial-gradient(120% 90% at 50% -10%, rgba(255, 122, 61, .16), transparent 60%),
        var(--bsw-panel);
    box-shadow: var(--bsw-glow), inset 0 0 40px rgba(255, 69, 0, .10);
    color: var(--bsw-soft);
}

/* Marquee bulbs along the top and bottom edge — lifted verbatim from
   style.css `.blaze-board`. Painted as a repeating radial gradient rather than
   dozens of elements, so it costs nothing and never reflows. */
.bsw-card::before,
.bsw-card::after {
    content: "";
    position: absolute;
    left: 0;
    width: 100%;
    height: 8px;
    background-image: radial-gradient(circle, rgba(255, 207, 72, .95) 1.6px, rgba(255, 207, 72, .12) 2.2px, transparent 2.6px);
    background-size: 16px 8px;
    background-position: center;
    opacity: .85;
    pointer-events: none;
}
.bsw-card::before { top: 6px; }
.bsw-card::after  { bottom: 6px; }

.bsw-card.bsw-compact { padding: 1.15rem .95rem; gap: .7rem; }

/* One focus ring for everything in the card, identical to the one every game
   page and the navbar use. */
.bsw-card a:focus-visible,
.bsw-card button:focus-visible,
.bsw-card input:focus-visible {
    outline: 3px solid var(--c-gold, #ffcf48);
    outline-offset: 2px;
}

/* ── head ─────────────────────────────────────────────────────────────── */

.bsw-head { display: flex; flex-direction: column; gap: .3rem; }

/* The marquee title, same treatment as every board on the home page. */
.bsw-title {
    margin: 0;
    font-size: 13px;
    font-weight: bold;
    letter-spacing: .18em;
    line-height: 1.4;
    text-transform: uppercase;
    color: var(--c-gold, #ffcf48);
    text-shadow: 0 0 10px rgba(255, 207, 72, .45);
}

/* The "this is a practice token" line. It is not fine print and must not look
   like it, so it takes blazecrash.css's callout treatment: an orange left rule
   over a faint orange wash, full body size, never grey-on-grey. */
.bsw-honest {
    margin: 0;
    padding: .55rem .7rem;
    border-left: 3px solid var(--c-orange, orange);
    border-radius: 6px;
    background: rgba(255, 140, 0, .09);
    font-size: .86rem;
    line-height: 1.6;
    color: var(--bsw-soft);
    max-width: 60ch;
}

/* ── buy / sell tabs ──────────────────────────────────────────────────── */

.bsw-tabs { display: flex; gap: .5rem; }

.bsw-tab {
    flex: 1 1 0;
    min-width: 0;
    font: inherit;
    font-weight: bold;
    font-size: .95rem;
    padding: .55rem .5rem;
    min-height: var(--touch, 44px);
    border-radius: 999px;
    cursor: pointer;
    color: var(--c-gold, #ffcf48);
    background: rgba(0, 0, 0, .5);
    border: 1px solid var(--bsw-line-chip);
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.bsw-tab:hover {
    background: rgba(255, 122, 24, .2);
    border-color: var(--bsw-line-hot);
}

/* Same filled treatment as a picked call button on the dice table — a selected
   tab must not read weaker than a selected chip. */
.bsw-tab[aria-pressed="true"] {
    color: #000;
    background: var(--c-orange, orange);
    border-color: #fff;
}

/* ── the two amount boxes ─────────────────────────────────────────────── */

.bsw-box {
    display: flex;
    flex-direction: column;
    gap: .4rem;
    padding: .75rem .85rem;
    border-radius: 12px;
    border: 1px solid var(--bsw-line);
    background: var(--bsw-inset);
}

.bsw-box-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: .6rem;
    font-size: .82rem;
    color: var(--bsw-dim);
}

/* Both boxes label themselves ("You pay" / "You get (estimated)"). The pay side
   uses a <label> bound to the input; the get side is a <span>, because there is
   no control under it to label. Same look either way. */
.bsw-box-label { font-weight: bold; color: #fff; letter-spacing: .01em; }

.bsw-box-bal { font-variant-numeric: tabular-nums; }

.bsw-box-line { display: flex; align-items: center; gap: .5rem; }

.bsw-input {
    flex: 1 1 auto;
    min-width: 0;
    font: inherit;
    font-size: 1.35rem;
    font-weight: bold;
    font-variant-numeric: tabular-nums;
    color: #fff;
    background: transparent;
    border: 0;
    padding: 0;
    min-height: var(--touch, 44px); /* the amount field itself was 25px tall */
    outline-offset: 3px;
}
.bsw-input::placeholder { color: rgba(255, 255, 255, .3); }

/* The receive side is not an input — it must still line up with the one above,
   or the card looks broken every time the quote changes width. */
.bsw-out {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 1.35rem;
    font-weight: bold;
    font-variant-numeric: tabular-nums;
    color: #fff;
    overflow-wrap: anywhere;
}

.bsw-sym {
    flex: 0 0 auto;
    font-weight: bold;
    font-size: .95rem;
    padding: .3rem .6rem;
    border-radius: 999px;
    color: var(--c-gold, #ffcf48);
    background: rgba(255, 207, 72, .10);
    border: 1px solid var(--bsw-line-chip);
}

.bsw-max {
    flex: 0 0 auto;
    font: inherit;
    font-size: .78rem;
    font-weight: bold;
    padding: .3rem .6rem;
    min-height: var(--touch, 44px); /* was 0: a 29px MAX chip on the page's money control */
    border-radius: 999px;
    cursor: pointer;
    color: var(--c-gold, #ffcf48);
    background: rgba(0, 0, 0, .5);
    border: 1px solid var(--bsw-line-chip);
    transition: background-color .15s ease, border-color .15s ease;
}
.bsw-max:hover:not(:disabled) {
    background: rgba(255, 122, 24, .2);
    border-color: var(--bsw-line-hot);
}
.bsw-max:disabled { opacity: .4; cursor: not-allowed; }

/* ── the flip button between the boxes ────────────────────────────────── */

.bsw-flip {
    /* The direction chip (owner, 2026-09-01: "look much better") — a real
       casino chip now, not a ghost ring: gold coin face, lit from inside,
       spins on hover like the wheel it funds. */
    align-self: center;
    /* Flex-center the glyph — button padding + glyph baseline metrics were
       nudging the arrows off the coin's center (owner, 2026-09-01). */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    font: inherit;
    font-size: 1.35rem;
    font-weight: bold;
    line-height: 1;
    width: 48px;
    height: 48px;
    margin: -.55rem 0;
    border-radius: 50%;
    cursor: pointer;
    color: #1a1005;
    background:
        radial-gradient(circle at 30% 28%, #ffe9a8, #ffcf48 45%, #ff9a2e 80%, #ff7a18);
    border: 2px solid rgba(255, 207, 72, .8);
    box-shadow: 0 0 14px rgba(255, 122, 24, .55),
                inset 0 2px 4px rgba(255, 255, 255, .45),
                inset 0 -3px 6px rgba(140, 60, 0, .45);
    transition: transform .18s ease, box-shadow .15s ease, filter .15s ease;
}
.bsw-flip:hover {
    transform: rotate(180deg) scale(1.06);
    filter: brightness(1.12);
    box-shadow: 0 0 22px rgba(255, 122, 24, .85),
                inset 0 2px 4px rgba(255, 255, 255, .45),
                inset 0 -3px 6px rgba(140, 60, 0, .45);
}
.bsw-flip:active { transform: rotate(180deg) scale(.94); }
.bsw-flip:focus-visible { outline: 3px solid var(--c-gold, #ffcf48); outline-offset: 2px; }

/* ── the options panel: which pool, and how much slip ─────────────────────
   Two settings, one grammar: a heading with its CURRENT VALUE on the right, a
   row of chips, then a line that only appears when the setting has a
   consequence worth stating. Recessed like `.blaze-board .board-inset`, so the
   controls read as sunk into the cabinet rather than stuck on top of it. */

.bsw-opts {
    display: flex;
    flex-direction: column;
    gap: .8rem;
    padding: .75rem .8rem;
    border-radius: 12px;
    border: 1px solid var(--bsw-line);
    background: var(--bsw-inset);
}

.bsw-opt { display: flex; flex-direction: column; gap: .45rem; }

.bsw-opt-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: .6rem;
    font-size: .82rem;
}

.bsw-opt-label { font-weight: bold; color: #fff; letter-spacing: .01em; }

/* The live readout of the setting. Gold like every other number on the site,
   and tabular so switching 0.5% -> 3% does not shove the label around. */
.bsw-opt-value {
    color: var(--c-gold, #ffcf48);
    font-weight: bold;
    font-variant-numeric: tabular-nums;
    text-align: right;
    overflow-wrap: anywhere;
}

/* ── the venue picker ─────────────────────────────────────────────────────
   Three equal columns at every width. `minmax(0, 1fr)` rather than `auto` is
   what guarantees a long quote shrinks the cell instead of widening the grid —
   the card sits at 360px on a phone and tests/nav-parity.spec.js fails the
   build for horizontal overflow. */

.bsw-venues {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: .4rem;
}

.bsw-venue {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    min-width: 0;
    min-height: var(--touch, 44px);
    padding: .45rem .3rem;
    border-radius: 12px;
    cursor: pointer;
    font: inherit;
    line-height: 1.2;
    color: var(--c-gold, #ffcf48);
    background: var(--bsw-field);
    border: 1px solid var(--bsw-line-chip);
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.bsw-venue:hover:not(:disabled) {
    background: rgba(255, 122, 24, .2);
    border-color: var(--bsw-line-hot);
}

.bsw-venue[aria-pressed="true"] {
    color: #000;
    background: var(--c-orange, orange);
    border-color: #fff;
    font-weight: bold;
}

/* A venue that did not answer. Declared AFTER the pressed rule on purpose:
   a chosen pool that goes dark must stop looking chosen-and-fine, and start
   looking broken, without the selection silently moving somewhere else. The
   dashed edge carries the meaning even where the colour does not land. */
.bsw-venue[data-state="down"] {
    color: var(--bsw-bad);
    background: rgba(255, 107, 94, .1);
    border-color: rgba(255, 107, 94, .55);
    border-style: dashed;
    font-weight: normal;
    cursor: not-allowed;
    opacity: 1;
}

.bsw-venue:disabled { cursor: not-allowed; }

.bsw-venue-name {
    font-weight: bold;
    font-size: .82rem;
    overflow-wrap: anywhere;
}

/* The whole argument for offering a picker at all: each pool shows its own
   live quote, so the choice is informed rather than a coin flip. */
.bsw-venue-quote {
    font-size: .78rem;
    font-variant-numeric: tabular-nums;
    overflow-wrap: anywhere;
}

.bsw-venue-fee {
    font-size: .68rem;
    opacity: .8;
    overflow-wrap: anywhere;
}

/* The penalty line. Amber, not red — picking the worse pool is a COST the
   visitor is entitled to accept, not an error. Red is reserved for the pool
   that cannot be traded against at all. */
.bsw-venue-warn {
    margin: 0;
    font-size: .82rem;
    line-height: 1.55;
    color: var(--bsw-dim);
}
.bsw-venue-warn[data-kind="warn"] { color: var(--bsw-warm); }
.bsw-venue-warn[data-kind="down"] { color: var(--bsw-bad); }
.bsw-venue-warn[hidden] { display: none; }

/* ── slippage ─────────────────────────────────────────────────────────── */

/* The second setting in the panel. A hairline above it keeps "which pool" and
   "how much slip" from reading as one seven-chip soup. */
.bsw-slip {
    padding-top: .75rem;
    border-top: 1px dashed rgba(255, 255, 255, .12);
}

.bsw-slip-row { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }

.bsw-slip-btn {
    font: inherit;
    font-size: .82rem;
    font-variant-numeric: tabular-nums;
    padding: .35rem .8rem;
    min-height: var(--touch, 44px);
    min-width: var(--touch, 44px);
    border-radius: 999px;
    cursor: pointer;
    color: var(--c-gold, #ffcf48);
    background: var(--bsw-field);
    border: 1px solid var(--bsw-line-chip);
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.bsw-slip-btn:hover {
    background: rgba(255, 122, 24, .2);
    border-color: var(--bsw-line-hot);
}
.bsw-slip-btn[aria-pressed="true"] {
    color: #000;
    font-weight: bold;
    background: var(--c-orange, orange);
    border-color: #fff;
}

/* The custom field wears its own "%" so the unit never disappears the moment
   somebody types — "3" meaning 3% is exactly the ambiguity that sends a swap
   with the wrong gate. The ring goes on the whole group, not the bare input,
   so the suffix does not sit outside the focus indicator. */
.bsw-slip-custom {
    display: inline-flex;
    align-items: center;
    gap: .1rem;
    padding-right: .6rem;
    min-height: 36px;
    border-radius: 999px;
    background: var(--bsw-field);
    border: 1px solid var(--bsw-line-chip);
}
.bsw-slip-custom:focus-within {
    border-color: var(--bsw-line-hot);
    outline: 3px solid var(--c-gold, #ffcf48);
    outline-offset: 2px;
}

.bsw-slip-input {
    width: 4.6rem;
    font: inherit;
    font-size: .82rem;
    font-variant-numeric: tabular-nums;
    padding: .35rem .5rem .35rem .8rem;
    min-height: var(--touch, 44px);
    color: #fff;
    background: transparent;
    border: 0;
    border-radius: 999px;
}
.bsw-slip-input::placeholder { color: rgba(255, 255, 255, .4); }
/* The group already draws the ring on :focus-within — a second one inside it
   just makes the pill look doubled. */
.bsw-card .bsw-slip-input:focus-visible { outline: none; }

.bsw-slip-suffix {
    font-size: .82rem;
    font-weight: bold;
    color: var(--c-gold, #ffcf48);
}

/* A slippage setting loose enough to be dangerous has to LOOK it. */
.bsw-slip-warn {
    margin: 0;
    font-size: .82rem;
    line-height: 1.55;
    color: var(--bsw-bad);
}
.bsw-slip-warn:empty { display: none; }
.bsw-slip-warn[hidden] { display: none; }

/* ── the detail rows (rate, minimum received, impact, venue) ──────────── */

.bsw-rows {
    display: flex;
    flex-direction: column;
    gap: .3rem;
    padding: .7rem .8rem;
    border-radius: 12px;
    border: 1px solid var(--bsw-line);
    background: var(--bsw-inset);
}

.bsw-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    font-size: .85rem;
    /* Dotted separators, the same rule the home-page boards and the dice
       history use to keep dense rows readable. */
    padding-bottom: .3rem;
    border-bottom: 1px dashed rgba(255, 255, 255, .12);
}
.bsw-row:last-child { padding-bottom: 0; border-bottom: 0; }

.bsw-row-label { color: var(--bsw-dim); flex: 0 1 auto; }

.bsw-row-value {
    color: #fff;
    font-variant-numeric: tabular-nums;
    text-align: right;
    overflow-wrap: anywhere;
}

/* Price impact past 5%. swap.js sets data-hot; nothing styled it before, so
   the one row on the card that can quietly cost somebody real value looked
   exactly like the row above it. */
.bsw-row-value[data-hot="true"] {
    color: var(--bsw-bad);
    font-weight: bold;
}

/* ── buttons ──────────────────────────────────────────────────────────── */

.bsw-btn {
    font: inherit;
    font-weight: bold;
    font-size: 1.05rem;
    padding: .85rem 1rem;
    min-height: var(--touch, 44px);
    width: 100%;
    border-radius: 10px;
    cursor: pointer;
    border: 1px solid transparent;
    transition: background-color .2s ease, opacity .2s ease, box-shadow .2s ease;
}

/* The site's action button, exactly: flat orange, black text, darkorange on
   hover. The fire glow is the WHOLE --glow value — see the header note. */
.bsw-btn-primary {
    color: #000;
    background-color: var(--c-orange, orange);
    box-shadow: var(--bsw-glow);
}
.bsw-btn-primary:hover:not(:disabled) {
    background-color: var(--c-orange-dark, darkorange);
}

/* The wrap/unwrap helper: a chip, scaled up. It is a step on the way to the
   swap, never the swap itself, so it must not compete with the orange. */
.bsw-btn-ghost {
    color: var(--c-gold, #ffcf48);
    background: var(--bsw-field);
    border-color: var(--bsw-line-chip);
}
.bsw-btn-ghost:hover:not(:disabled) {
    background: rgba(255, 122, 24, .2);
    border-color: var(--bsw-line-hot);
}

/* A disabled money button must read as OFF at a glance, not merely a bit
   faded. It gives up the orange entirely — on this card orange is the single
   signal that means "this one broadcasts a transaction" — and goes flat, grey
   and unlit. */
.bsw-btn:disabled {
    opacity: .55;
    cursor: not-allowed;
    box-shadow: none;
    background-color: rgba(255, 255, 255, .07);
    color: var(--bsw-dim);
    border-color: var(--bsw-line);
}

/* ── status line + receipt link ───────────────────────────────────────── */

.bsw-status {
    margin: 0;
    font-size: .88rem;
    line-height: 1.6;
    color: var(--bsw-dim);
    min-height: 1.4em;      /* reserve the row so the card does not jump */
    overflow-wrap: anywhere;
}
/* swap.js has always written data-kind here; nothing read it, so a failure and
   a confirmation were the same colour. */
.bsw-status[data-kind="error"]   { color: var(--bsw-bad); }
.bsw-status[data-kind="success"] { color: var(--bsw-good); }

.bsw-tx {
    display: inline-block;
    font-size: .85rem;
    font-weight: bold;
    color: var(--c-gold, #ffcf48);
    overflow-wrap: anywhere;
}
/* Required, not defensive: the display above would otherwise beat the UA's
   [hidden] rule and show an hrefless receipt link on every freshly mounted
   card. */
.bsw-tx[hidden] { display: none; }

/* ── the wrap / unwrap helper ─────────────────────────────────────────── */

/* NOT `.bsw-wrap` — that is the OUTER rail the host pages put around the whole
   card (index.html and price.html both do). Two different boxes must not
   answer to one selector. */
.bsw-wrapbox {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    padding: .7rem .8rem;
    border-radius: 12px;
    border: 1px dashed var(--bsw-line-chip);
    background: rgba(255, 140, 0, .07);
}
.bsw-wrapbox[hidden] { display: none; }

.bsw-wrap-note {
    margin: 0;
    font-size: .82rem;
    line-height: 1.55;
    color: var(--bsw-dim);
}
.bsw-wrap-note:empty { display: none; }

/* ── the footer fine print ────────────────────────────────────────────── */

.bsw-foot {
    margin: 0;
    padding-top: .6rem;
    border-top: 1px dashed rgba(255, 255, 255, .15);
    font-size: .78rem;
    line-height: 1.65;
    color: var(--bsw-dim);
}

/* ── narrow screens ───────────────────────────────────────────────────────
   The card is already a single column; the real risks at 360px are the amount
   row (a long quote plus a symbol pill plus MAX) and the three venue chips.
   The amount row is allowed to wrap; the venue grid is already
   minmax(0, 1fr) and therefore cannot widen, it only gets tighter type.
   tests/nav-parity.spec.js fails the build for horizontal overflow. */
@media (max-width: 420px) {
    .bsw-card { padding: 1.15rem .9rem; }
    .bsw-box-line { flex-wrap: wrap; }
    .bsw-input, .bsw-out { font-size: 1.15rem; flex-basis: 100%; }
    .bsw-row { flex-wrap: wrap; gap: .1rem .8rem; }
    .bsw-row-value { text-align: left; }
    .bsw-venues { gap: .3rem; }
    .bsw-venue { padding: .45rem .2rem; }
    .bsw-venue-name { font-size: .76rem; }
    .bsw-venue-quote { font-size: .72rem; }
    .bsw-venue-fee { font-size: .64rem; }
    .bsw-slip-input { width: 4rem; }
}

@media (prefers-reduced-motion: reduce) {
    .bsw-tab, .bsw-btn, .bsw-flip, .bsw-venue, .bsw-slip-btn, .bsw-max { transition: none; }
    .bsw-flip:hover { transform: none; }
}

/* The wrap helper's typed amount + the pointer to the standalone tool
   (2026-09-01 — the helper used to be button-only: "can't type anything"). */
/* Unlike the pay-side input, this one sits on the bare card, not inside a
   dark pane — so it draws its own box or it reads as loose placeholder text
   (owner, 2026-09-01: "not visible easily"). */
.bsw-wrap-input {
    margin: 8px 0 2px;
    width: 100%;
    box-sizing: border-box;
    font-size: 1.15rem;
    text-align: center;
    padding: 10px 12px;
    border-radius: 10px;
    border: 1px solid rgba(255, 207, 72, .45);
    background: rgba(0, 0, 0, .45);
}
.bsw-wrap-input:focus-visible {
    outline: 3px solid var(--c-gold, #ffcf48);
    outline-offset: 1px;
}
.bsw-wrap-link { color: var(--c-gold, #ffcf48); }
