/* ═══════════════════════════════════════════════════════════
   FAVOR — Online Card Game
   A Game of Royal Succession
   ═══════════════════════════════════════════════════════════ */

@import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@400;600;700;900&family=Cinzel+Decorative:wght@400;700;900&family=EB+Garamond:ital,wght@0,400;0,600;1,400&display=swap');

:root {
    --gold: #c9a84c;
    --gold-light: #e8d48b;
    --gold-dark: #8b6914;
    --royal-purple: #3d2817;
    --royal-deep: #2a1a10;
    --parchment: #f4e8c1;
    --parchment-dark: #d4c49a;
    --crimson: #8b1a1a;
    --text-light: #f0e6d3;
    --text-dark: #2a1a0e;
    --shadow-glow: rgba(201, 168, 76, 0.4);
    --wood-light: #b8956a;
    --wood-mid: #8b6b4a;
    --wood-dark: #5a3d2b;
    --wood-darker: #3d2817;
    --wood-deepest: #2a1a10;
    --felt-blue: #1e3a5f;
    --felt-dark: #142940;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

/* iOS Safari auto-inflates "small" text in landscape webviews — TEXT ONLY,
   not the boxes around it, which is how one device's achievement titles
   painted over their neighbours (Wyatt 7/20). The layout is designed at
   these sizes; keep the browser's hands off them. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* Long-pressing card/board art on iOS summoned the native "Copy / Save
   Image" sheet ("copy PNGs?" — reported 7/17). Kill the callout and drag
   on every image app-wide; text still selects via the .selectable opt-in. */
img {
    -webkit-touch-callout: none;
    -webkit-user-drag: none;
    -khtml-user-drag: none;
    user-select: none;
    -webkit-user-select: none;
}
.selectable, .selectable * { -webkit-user-select: text; user-select: text; }

html, body {
    width: 100%;
    height: 100%;
    overflow: hidden;
    background: #1a0e08;
    font-family: 'EB Garamond', serif;
    color: var(--text-light);
}

/* ─── TITLE SCREEN ──────────────────────────────────────── */

#title-screen {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background:
        radial-gradient(ellipse at 32% 42%, rgba(201, 168, 76, 0.09) 0%, transparent 55%),
        radial-gradient(ellipse at 50% 85%, rgba(42, 26, 62, 0.6) 0%, transparent 55%),
        linear-gradient(180deg, #0a0612 0%, #1a0f28 40%, #0a0612 100%);
    z-index: 1000;
    transition: opacity 1.2s ease;
}

#title-screen.hidden {
    opacity: 0;
    pointer-events: none;
}

/* ── Wingspan-style stage: a full-bleed hero painting (calm on the left,
     the castle owns the right), the title lockup up top, and a loose grid
     of framed vignette cards — every button is a small painting with a
     plaque, PLAY unmistakably biggest. ── */
.ts-bg {
    position: absolute; inset: 0;
    /* The hero painting (Wyatt 7/16): the storybook meadow — cottage on
       the flowered hill, path winding toward the white castle. Anchored
       right-of-center so the castle survives the crop at every aspect
       ratio (the cottage rides the left edge behind the menu column). */
    background: #2a3a28 url('../assets/ui/menu-meadow.jpg') no-repeat;
    background-size: cover;
    background-position: 68% 34%;
}
/* Legibility wash — deepens the menu side and the footer's ground,
   leaves the castle in its own light. */
.ts-haze {
    position: absolute; inset: 0; pointer-events: none;
    /* Lighter wash than the old dusk art needed — the meadow is a sunny
       painting and should read sunny; just enough scrim for the gold
       lockup (top-left) and the footer line (bottom). */
    background:
        linear-gradient(180deg, rgba(12, 7, 16, 0.32) 0%, transparent 24%, transparent 80%, rgba(8, 5, 10, 0.42) 100%),
        linear-gradient(100deg,
            rgba(12, 7, 16, 0.5) 0%, rgba(12, 7, 16, 0.3) 34%,
            rgba(12, 7, 16, 0.05) 62%, rgba(12, 7, 16, 0.07) 100%);
}

.ts-frame {
    position: relative; z-index: 1;
    width: 100%; height: 100%;
    display: flex; flex-direction: column;
    /* notched landscape phones: never tuck under the sensor housing.
       The +14px keeps daylight between the cutout and the Play card /
       title — the bare inset ends flush at the notch edge and read as
       touching on Wyatt's iPhone 12. Notch side flips with rotation,
       so both sides get the cushion. */
    padding: clamp(12px, 3.5dvh, 36px)
             max(clamp(18px, 4vw, 56px), calc(env(safe-area-inset-right) + 14px))
             calc(clamp(12px, 3.5dvh, 36px) + env(safe-area-inset-bottom))
             max(clamp(18px, 4vw, 56px), calc(env(safe-area-inset-left) + 14px));
    box-sizing: border-box;
}

.ts-lockup { margin: 0 0 clamp(8px, 2.4dvh, 24px); }
/* clear the music toggle (top-left chrome) on screens tall enough to show it */
@media (min-height: 541px) { .ts-lockup { padding-left: 56px; } }
.ts-title {
    font-family: 'Cinzel', serif; font-weight: 900;
    font-size: clamp(30px, 9dvh, 64px);
    letter-spacing: 0.2em;
    color: var(--gold-light);
    margin: 0; line-height: 1;
    text-shadow: 0 0 34px rgba(201, 168, 76, 0.45), 0 3px 12px rgba(0, 0, 0, 0.85);
}
.ts-sub {
    font-family: 'Cinzel', serif;
    font-size: clamp(10px, 2dvh, 15px);
    letter-spacing: 0.42em; text-transform: uppercase;
    color: rgba(232, 205, 120, 0.8);
    margin: 6px 0 0 2px;
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.8);
}

/* The card grid: PLAY spans the full left column; HOST ROOM & SKIRMISH
   are the second tier; four quiet minors fill out the right. The grid
   hugs the left/haze side — the hero painting keeps the right. */
.ts-grid {
    display: grid;
    grid-template-areas:
        "play skirm host"
        "play rival lead"
        "play rival store"
        "play rival ach"
        "play how   how";
    grid-template-columns: minmax(200px, 300px) minmax(140px, 205px) minmax(140px, 205px);
    grid-template-rows: 1fr auto auto auto auto;
    gap: clamp(8px, 1.8dvh, 16px) clamp(10px, 1.4vw, 18px);
    max-width: min(780px, 64vw);
    /* tall screens: the grid floats centered between lockup and footer */
    margin-block: auto;
}

.ts-card {
    position: relative; overflow: hidden;
    display: flex; flex-direction: column;
    align-items: center; justify-content: flex-end;
    border-radius: 12px;
    border: 2px solid rgba(201, 168, 76, 0.55);
    background: linear-gradient(160deg, rgba(34, 19, 9, 0.92), rgba(18, 9, 4, 0.94));
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.55), inset 0 0 0 1px rgba(0, 0, 0, 0.5);
    cursor: pointer;
    transition: transform 0.16s ease, border-color 0.16s ease, box-shadow 0.16s ease;
}
.ts-card:hover, .ts-card:focus-visible {
    transform: translateY(-2px);
    border-color: var(--gold-light);
    box-shadow: 0 0 24px rgba(201, 168, 76, 0.35), 0 10px 26px rgba(0, 0, 0, 0.6);
    outline: none;
}
.ts-card:active { transform: translateY(0); }

/* The vignette painting inside a card, with a scrim so plaques read. */
.ts-art { position: absolute; inset: 0; background-size: cover; }
.ts-art::after {
    content: ''; position: absolute; inset: 0;
    background: linear-gradient(180deg, rgba(10, 6, 2, 0.04) 42%, rgba(10, 6, 2, 0.74) 100%);
}

.ts-plaque {
    position: relative; z-index: 1;
    font-family: 'Cinzel', serif; font-weight: 700;
    letter-spacing: 0.18em; text-transform: uppercase;
    font-size: clamp(11px, 1.9dvh, 14px);
    color: #f0e2b6;
    background: linear-gradient(180deg, rgba(44, 26, 10, 0.94), rgba(24, 13, 5, 0.94));
    border: 1px solid rgba(201, 168, 76, 0.65);
    border-radius: 8px;
    padding: 6px 15px; margin: 8px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.6);
    white-space: nowrap;
}

/* ── Update pill — Nation's notice worn under the profile chip. A slow
   SHINE, never a pulse (Wyatt's call on Nation's). Lives inside the
   title screen so it can never cover a live table. ── */
.update-pill {
    position: absolute;
    top: calc(max(14px, env(safe-area-inset-top)) + 52px);
    right: max(16px, env(safe-area-inset-right));
    display: inline-flex; align-items: center; gap: 7px;
    padding: 7px 14px;
    font-family: 'Cinzel', serif; font-weight: 700; font-size: 12px;
    letter-spacing: 1.5px; text-transform: uppercase;
    color: #1c1006;
    background: linear-gradient(115deg, #d9b44a 0%, #f7e29a 45%, #d9b44a 60%);
    background-size: 220% 100%;
    border: 1px solid #ffe9a8;
    border-radius: 999px;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5), 0 0 18px rgba(232, 195, 75, 0.35);
    cursor: pointer;
    z-index: 60;
    animation: updShine 3.4s linear infinite;
}
.update-pill .up-glyph { font-size: 14px; line-height: 1; }
.update-pill:hover, .update-pill:focus-visible {
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.55), 0 0 26px rgba(232, 195, 75, 0.6);
    outline: none;
}
@keyframes updShine { 0% { background-position: 120% 0; } 100% { background-position: -120% 0; } }

.ts-play { grid-area: play; min-height: clamp(150px, 36dvh, 300px); }
/* Play's vignette: the realm's open gates — castle, falls and the road in
   (Wyatt 7/16); tall cards look through the arch, short-wide cards at the
   castle. New filename on purpose: the stamped CSS busts the old cache. */
.ts-art-play { background-image: url('../assets/ui/menu-play-gates.jpg'); background-position: 50% 42%; }
/* Host Room + Skirmish: purpose-painted MJ vignettes, same family as the hero */
.ts-art-host { background-image: url('../assets/ui/menu-host-vignette.jpg'); background-position: 50% 55%; }
.ts-art-skirm { background-image: url('../assets/ui/menu-skirmish-vignette.jpg'); background-position: 50% 42%; }
.ts-play .ts-plaque {
    font-size: clamp(16px, 3.4dvh, 23px);
    padding: 8px 30px; margin-bottom: 6px;
    box-shadow: 0 0 20px rgba(201, 168, 76, 0.3), 0 2px 8px rgba(0, 0, 0, 0.6);
}
.ts-play .queue-seg {
    position: relative; z-index: 1;
    width: calc(100% - 20px); box-sizing: border-box;
    margin: 0 10px 10px;
    padding: 5px 8px;
    background: rgba(12, 7, 3, 0.6);
    border-radius: 10px;
}

.ts-mid { min-height: clamp(58px, 13.5dvh, 128px); }
.ts-mid:nth-of-type(2) { grid-area: skirm; }
.ts-mid:nth-of-type(3) { grid-area: host; }

.ts-sm { min-height: clamp(34px, 7dvh, 52px); justify-content: center; }
.ts-sm .ts-plaque { font-size: clamp(10px, 1.7dvh, 12px); padding: 4px 12px; margin: 4px; }
.ga-rival { grid-area: rival; }
.ga-lead { grid-area: lead; }
.ga-store { grid-area: store; }
.ga-ach { grid-area: ach; }
.ga-how { grid-area: how; }

/* Footer strip — quiet dev/reference hooks, Wingspan's community line. */
.ts-footer {
    margin-top: auto;
    display: flex; align-items: center;
    gap: clamp(12px, 2vw, 22px);
    padding-top: clamp(8px, 2dvh, 16px);
}
.ts-plate {
    font-family: 'EB Garamond', serif; font-style: italic;
    font-size: clamp(10px, 1.7dvh, 13px);
    letter-spacing: 1px;
    color: rgba(201, 168, 76, 0.55);
    margin: 0 0 0 auto;
}

/* Table size — a segmented row, one tap, stays lit. */
.queue-seg {
    display: flex;
    align-items: center;
    gap: 8px;
}
.queue-label {
    font-family: 'Cinzel', serif;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 2.5px;
    text-transform: uppercase;
    color: var(--gold-dark);
    white-space: nowrap;
    padding-right: 2px;
}
.queue-seg button {
    flex: 1;
    height: 42px;
    font-family: 'Cinzel', serif;
    font-size: 16px;
    font-weight: 700;
    color: var(--gold-light);
    background: rgba(20,10,4,0.55);
    border: 1px solid rgba(201,168,76,0.35);
    border-radius: 9px;
    cursor: pointer;
    transition: all 0.15s;
}
.queue-seg button:hover { border-color: var(--gold); }
.queue-seg button.on {
    background: linear-gradient(160deg, rgba(201,168,76,0.95), rgba(146,110,38,0.95));
    color: #241503;
    border-color: var(--gold-light);
    box-shadow: 0 0 14px rgba(201,168,76,0.35);
}

.menu-link {
    background: none;
    border: none;
    padding: 6px 2px;
    font-family: 'Cinzel', serif;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: rgba(232, 205, 120, 0.7);
    text-decoration: underline;
    text-underline-offset: 4px;
    text-decoration-color: rgba(201,168,76,0.35);
    cursor: pointer;
    transition: color 0.15s;
}
.menu-link:hover { color: var(--gold-light); }
.menu-link.mint-link { color: #ffd97a; text-shadow: 0 0 8px rgba(240, 200, 110, 0.35); }
.menu-link.mint-link:hover { color: #ffe9ad; }
/* iOS shell: no external purchase rail anywhere (Apple 3.1.1) */
.ios-shell .mint-link, .ios-shell .st-mint { display: none !important; }

/* Portrait / narrow: single column, scrollable — the rotate-gate handles
   in-game, but the menu itself stays usable any way you hold it. */
@media (orientation: portrait), (max-width: 640px) {
    .ts-frame { overflow-y: auto; padding: 20px 6vw; }
    .ts-grid {
        grid-template-areas: "play play" "skirm host" "rival rival" "lead store" "ach how";
        grid-template-columns: 1fr 1fr;
        grid-template-rows: auto;
        max-width: 100%;
    }
    .ts-play { min-height: 180px; }
    .ts-haze { background: linear-gradient(180deg, rgba(10,6,14,0.72), rgba(10,6,14,0.5)); }
    /* clear the profile chip; keep footer links on one line each */
    .ts-title { font-size: clamp(24px, 8.5vw, 40px); }
    .ts-lockup { padding-left: 48px; margin-top: 34px; }
    .ts-footer { flex-wrap: wrap; }
    .menu-link, .prompt-test-toggle { white-space: nowrap; }
}

/* Profile chip — top-right of the menu */
.profile-chip {
    position: absolute;
    top: max(14px, env(safe-area-inset-top));
    right: max(16px, env(safe-area-inset-right));
    display: inline-flex;
    align-items: center;
    gap: 11px;
    padding: 8px 18px;
    background: linear-gradient(160deg, rgba(42,22,10,0.88), rgba(20,10,4,0.92));
    border: 1px solid var(--gold-dark);
    border-radius: 999px;
    cursor: pointer;
    font-family: 'Cinzel', serif;
    transition: all 0.2s;
    z-index: 5;
}
.profile-chip:hover { border-color: var(--gold); box-shadow: 0 0 18px rgba(201,168,76,0.25); }
.pc-name { color: var(--gold-light); font-size: 13px; font-weight: 700; letter-spacing: 1px; }
.pc-rating { color: #a9d4ff; font-weight: 900; font-size: 14px; }
.pc-crowns { display: inline-flex; align-items: center; gap: 4px; color: #e8c34b; font-weight: 900; font-size: 13px; }
.crown-ico { width: 17px; height: 12px; display: inline-block; }

/* ── Leaderboard + profile panels ── */
.lb-panel, .profile-panel {
    position: fixed;
    inset: 0;
    z-index: 10005;
    display: none;
    align-items: center;
    justify-content: center;
    background: rgba(14,7,2,0.92);
    backdrop-filter: blur(14px);
}
.lb-panel.active, .profile-panel.active { display: flex; }

.lb-inner, .pf-inner {
    display: flex;
    flex-direction: column;
    width: min(600px, 94vw);
    max-height: 88dvh;
    background: linear-gradient(175deg, #2e1c0e 0%, #1a0d05 100%);
    border: 2px solid var(--gold-dark);
    border-radius: 14px;
    box-shadow: 0 0 0 1px rgba(0,0,0,0.6), 0 30px 90px rgba(0,0,0,0.75), inset 0 1px 0 rgba(232,212,139,0.14);
    padding: 20px 24px 16px;
    animation: ovZoom 0.4s cubic-bezier(0.16,1,0.3,1);
}

.lb-title, .pf-title {
    font-family: 'Cinzel', serif;
    font-size: 18px;
    font-weight: 700;
    letter-spacing: 5px;
    text-transform: uppercase;
    color: var(--gold-light);
    text-align: center;
    text-shadow: 0 0 22px rgba(201,168,76,0.35);
}

.lb-tabs { display: flex; gap: 8px; justify-content: center; margin: 14px 0 8px; }

/* Two-column body (Wyatt 7/17): a character rail down the LEFT — bigger
   crests with names, inviting a tap — and the board rows on the right. */
.lb-main {
    display: flex; gap: 14px; flex: 1 1 auto; min-height: 0;
}
.lb-rail {
    flex: 0 0 auto; width: 132px;
    display: flex; flex-direction: column; min-height: 0;
}
.lb-rail-head {
    font-family: 'Cinzel', serif; font-size: 10px; font-weight: 700;
    letter-spacing: 3px; text-transform: uppercase;
    color: var(--gold-dark); text-align: center; margin-bottom: 8px;
}
.lb-right { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; min-height: 0; }

/* The hero rail — a crest + name per row, whole chip clickable. */
.lb-chartabs {
    display: flex; flex-direction: column; gap: 5px;
    flex: 1 1 auto; overflow-y: auto; padding: 2px 4px 2px 0;
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.lb-chartabs::-webkit-scrollbar { display: none; }
.lb-chartab {
    flex: 0 0 auto;
    display: flex; align-items: center; gap: 9px;
    width: 100%; padding: 4px 8px 4px 4px;
    border-radius: 999px; overflow: hidden;
    border: 2px solid rgba(201, 168, 76, 0.28);
    background: rgba(28, 21, 12, 0.6); cursor: pointer;
    opacity: 0.82; text-align: left;
    transition: border-color 0.15s, opacity 0.15s, transform 0.15s, background 0.15s;
}
.lb-chartab img,
.lb-chartab .lb-chartab-crown {
    flex: 0 0 auto;
    width: 36px; height: 36px; border-radius: 50%; overflow: hidden;
    object-fit: cover; object-position: 50% 20%; display: flex;
    align-items: center; justify-content: center;
    background: #120c06;
}
.lb-chartab .lb-chartab-crown { color: var(--gold-light); font-size: 19px; }
.lb-chartab-name {
    font-family: 'Cinzel', serif; font-size: 11px; font-weight: 700;
    letter-spacing: 0.4px; color: var(--gold-light);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.lb-chartab:hover, .lb-chartab:focus-visible {
    opacity: 1; border-color: var(--gold-light, #ffd97a); outline: none;
    background: rgba(201,168,76,0.12); transform: translateX(2px);
}
.lb-chartab.on {
    opacity: 1; border-color: var(--gold, #d4af37);
    background: rgba(201,168,76,0.16);
    box-shadow: 0 0 12px rgba(232, 195, 75, 0.4);
}

/* The door out of a solo table — a quiet corner chip (Wyatt 7/17).
   Sits under every overlay (z 2800 < thrown zone 2950 < overlays) so
   open stages cover it exactly like they cover the rest of the chrome. */
.game-leave {
    position: fixed;
    bottom: 22px;   /* above the version badge */
    right: max(8px, env(safe-area-inset-right));
    width: 30px; height: 30px;
    display: flex; align-items: center; justify-content: center;
    padding: 0;
    font-size: 13px; line-height: 1;
    color: rgba(232, 202, 160, 0.75);
    background: rgba(24, 14, 7, 0.72);
    border: 1px solid rgba(201, 168, 76, 0.4);
    border-radius: 50%;
    cursor: pointer;
    z-index: 2800;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.game-leave:hover, .game-leave:focus-visible {
    color: #f0dfb8; border-color: var(--gold-light, #ffd97a);
    background: rgba(34, 20, 10, 0.9);
    outline: none;
}
#game-screen:not(.active) .game-leave { display: none; }

/* Melee runs its full ceremony — the Skip chip is retired (Wyatt 7/17).
   Hidden HERE, not in melee.js (Skylar's file, never hand-edited): the
   element stays in the DOM so rig el.click() fast-forwards still work. */
.ms-skip { display: none !important; }

/* The Emblem flare — "who reveals first" with no words (Wyatt 7/17).
   Plays once when the throws lock and the reveal opens. */
.em-first { animation: emFirst 1.9s ease-in-out; }
@keyframes emFirst {
    0%, 100% { transform: scale(1); filter: none; }
    18%, 55% {
        transform: scale(1.55);
        filter: drop-shadow(0 0 10px rgba(232, 195, 75, 0.95));
    }
}
.lb-tab {
    font-family: 'Cinzel', serif;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    padding: 6px 20px;
    border: 1px solid rgba(201,168,76,0.3);
    border-radius: 999px;
    background: transparent;
    color: var(--gold-dark);
    cursor: pointer;
    transition: all 0.2s;
}
.lb-tab.on { color: var(--gold-light); border-color: var(--gold); background: rgba(201,168,76,0.12); }

.lb-localnote {
    font-family: 'Cinzel', serif;
    font-size: 10px;
    letter-spacing: 2px;
    color: #e88;
    text-align: center;
    margin-bottom: 8px;
}

.lb-body { overflow-y: auto; min-height: 140px; }
.lb-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 10px;
    border-bottom: 1px solid rgba(201,168,76,0.08);
    font-family: 'Cinzel', serif;
    animation: lbRowIn 0.28s cubic-bezier(0.16,1,0.3,1) both;
    animation-delay: calc(min(var(--li, 0), 14) * 22ms);
}
@keyframes lbRowIn {
    from { opacity: 0; transform: translateX(-10px); }
}
.lb-row.me {
    background: linear-gradient(90deg, rgba(201,168,76,0.16), rgba(201,168,76,0.05));
    border: 1px solid rgba(201,168,76,0.4);
    border-radius: 8px;
}
.lb-row.podium.p1 { background: linear-gradient(90deg, rgba(240,200,110,0.12), transparent 70%); }
.lb-rank { width: 26px; text-align: center; color: var(--gold-dark); font-weight: 900; flex: none; }
.lb-medal {
    width: 26px; height: 26px; flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 50%;
    font-weight: 900; font-size: 13px; color: #2b1a06;
    box-shadow: inset 0 1px 3px rgba(255,255,255,0.5), 0 1px 4px rgba(0,0,0,0.55);
}
.lb-medal.m1 { background: radial-gradient(circle at 32% 28%, #ffe9ad, #d4a944 68%, #9a7526); animation: medalShine 2.6s ease-in-out infinite; }
.lb-medal.m2 { background: radial-gradient(circle at 32% 28%, #f2f2f4, #b9bcc4 68%, #82868f); }
.lb-medal.m3 { background: radial-gradient(circle at 32% 28%, #ecc39c, #c08a52 68%, #8a5c30); }
@keyframes medalShine {
    50% { box-shadow: inset 0 1px 3px rgba(255,255,255,0.5), 0 0 12px rgba(255,220,130,0.55); }
}
.lb-name { flex: 1; color: var(--parchment); font-size: 13px; display: inline-flex; align-items: center; gap: 8px; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lb-crowns { display: inline-flex; align-items: center; gap: 3px; color: #e8c34b; font-size: 12px; font-weight: 900; }
.lb-you {
    font-size: 9px; letter-spacing: 1.5px; padding: 2px 7px 3px;
    color: #2b1a06; background: linear-gradient(#f4d488, #c99f4b);
    border-radius: 999px; font-weight: 900;
}
.lb-sub { color: rgba(240,230,211,0.42); font-size: 10.5px; letter-spacing: 0.5px; flex: none; }
.lb-score { color: var(--gold-light); font-size: 15px; display: inline-flex; align-items: center; gap: 5px; flex: none; }
.lb-ico { width: 17px; height: 17px; object-fit: contain; }
/* Best single-game score with a hero, on that hero's board — a quieter
   parchment chip so the rating still leads. */
.lb-best {
    display: inline-flex; align-items: center; gap: 4px; flex: none;
    margin-right: 10px; padding: 2px 8px; border-radius: 999px;
    background: rgba(201,168,76,0.12); border: 1px solid rgba(201,168,76,0.22);
    color: var(--parchment); font-size: 12.5px; font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.lb-best .lb-ico { width: 14px; height: 14px; }
.lb-gap { text-align: center; color: var(--gold-dark); letter-spacing: 6px; padding: 2px 0; }
.lb-row.appendix { border-top: 1px solid rgba(201,168,76,0.25); border-bottom: none; }

/* ── Avatar discs — the rival-rail round crop, reused everywhere ── */
.av-disc {
    width: 30px; height: 30px; flex: none;
    border-radius: 50%;
    overflow: hidden;
    border: 1.5px solid rgba(201,168,76,0.55);
    box-shadow: 0 0 0 1.5px rgba(0,0,0,0.4), 0 1px 4px rgba(0,0,0,0.5);
    display: inline-flex;
    background: #1d1106;
}
.av-disc img { width: 100%; height: 100%; object-fit: cover; }
.av-disc.av-empty img { object-fit: contain; padding: 4px; opacity: 0.7; }
.av-disc.pc-av { width: 24px; height: 24px; }
.av-disc.lb-av { width: 30px; height: 30px; }
.av-disc.pf-av-current { width: 53px; height: 53px; }   /* +20% (Wyatt 7/21) — this disc IS the crest-gallery door */

/* Profile — the crest picker grid */
.pf-avatars {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 7px;
    padding: 10px 2px 12px;
    border-bottom: 1px solid rgba(201,168,76,0.14);
}
.pf-av {
    padding: 0; border: 2px solid rgba(201,168,76,0.25);
    border-radius: 50%; overflow: hidden; cursor: pointer;
    aspect-ratio: 1; background: #1d1106;
    transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}
.pf-av img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pf-av:hover { transform: scale(1.08); border-color: var(--gold); }
.pf-av.on { border-color: #ffd97a; box-shadow: 0 0 12px rgba(255,217,122,0.5); }

/* ── Crest gallery — tap your portrait, every crest shows up ── */
.pf-crest-btn {
    background: none; border: none; padding: 0; cursor: pointer;
    position: relative; display: inline-flex; flex: none;
}
.pf-crest-btn .av-disc { transition: box-shadow 0.15s ease, transform 0.15s ease; }
.pf-crest-btn:hover .av-disc { box-shadow: 0 0 12px rgba(255,217,122,0.5); transform: scale(1.05); }
.pf-crest-edit {
    position: absolute; right: -4px; bottom: -4px;
    width: 16px; height: 16px; line-height: 15px; text-align: center;
    font-size: 10px; color: var(--gold);
    background: #1d1106; border: 1px solid rgba(201,168,76,0.45); border-radius: 50%;
    pointer-events: none;
}
.pf-crestrow { align-items: center; gap: 12px; }
.cp-head { display: flex; justify-content: space-between; align-items: center; padding: 2px 0 8px; }
.cp-back {
    background: none; border: 1px solid rgba(201,168,76,0.35); color: var(--gold);
    border-radius: 14px; padding: 4px 14px; cursor: pointer;
    font-family: 'EB Garamond', serif; font-size: 14px;
}
.cp-back:hover { border-color: var(--gold); }
.cp-stars { color: #ffd97a; font-weight: 600; }
.cp-note {
    font-family: 'EB Garamond', serif; font-style: italic; font-size: 12.5px;
    color: rgba(240,230,211,0.55); padding: 2px 0 4px;
}
.pf-avatars.cp-paid { border-bottom: none; padding-bottom: 18px; }
.pf-avatars.cp-px { grid-template-columns: repeat(6, 1fr); border-bottom: none; }
.cp-tile { position: relative; overflow: visible; }
.cp-tile img { border-radius: 50%; }
.cp-tile.locked img { filter: saturate(0.55) brightness(0.72); }
.cp-price {
    position: absolute; left: 50%; bottom: -7px; transform: translateX(-50%);
    background: #1d1106; border: 1px solid rgba(201,168,76,0.5); color: #ffd97a;
    border-radius: 10px; font-size: 10.5px; line-height: 1; padding: 3px 7px;
    white-space: nowrap; pointer-events: none;
}
.cp-price.arm { background: var(--gold); color: #1d1106; border-color: var(--gold); }
.cp-price.poor { color: rgba(240,230,211,0.45); }
/* Pixel portraits stay crisp in every disc, at every size */
.av-disc img[src*="avatars/pixel/"], .cp-pxtile img { image-rendering: pixelated; }
/* The Emporium's crest shelf */
.st-crests {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 12px; padding: 10px 4px;
}
.st-crest {
    /* position:relative is load-bearing — .st-buy/.st-owned are absolute
       rope tags that hang off their nearest positioned ancestor; without
       this every card's tag escapes to the pane corner in one stack. */
    position: relative;
    display: flex; flex-direction: column; align-items: center; gap: 7px;
    background: rgba(29,17,6,0.55); border: 1px solid rgba(201,168,76,0.22);
    border-radius: 12px; padding: 14px 8px 12px;
}
.st-crest.owned { border-color: rgba(201,168,76,0.5); }
.st-crest-disc { width: 64px; height: 64px; }
.st-crest .st-name { font-size: 13px; text-align: center; }

/* In-game identity — your crest + royal name ride the board thumb's
   plate (a row on the stats panel broke its no-scroll fit). */
.thumb-name {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.av-disc.thumb-crest { width: 17px; height: 17px; flex: none; }
/* Human rivals across the wire wear their chosen crest by their name */
.av-disc.opp-crest { width: 17px; height: 17px; vertical-align: -3px; margin-right: 4px; }
.lb-foot, .lb-loading, .pf-note {
    font-family: 'EB Garamond', serif;
    font-style: italic;
    font-size: 12.5px;
    color: rgba(240,230,211,0.55);
    text-align: center;
}
.lb-foot { margin-top: 10px; }
.lb-loading { padding: 34px 0; }

/* ── Character store — a market stall under the royal awning ──
   Wyatt's market scene (the Merchant board) is the backdrop; heroes are
   framed paintings standing on planks, priced with hanging rope tags,
   sealed in wax once owned. Art IS the UI. */

.st-inner {
    width: min(940px, 94vw);
    position: relative;
    overflow: hidden;                 /* keeps the awning + backdrop inside the panel frame */
    padding-top: 50px;                /* room for the canopy */
    background:
        linear-gradient(180deg, rgba(26,13,4,0.78) 0%, rgba(18,9,3,0.92) 58%, rgba(14,7,2,0.97) 100%),
        url('../assets/ui/shop-backdrop.jpg') center 22% / cover no-repeat,
        linear-gradient(175deg, #2e1c0e 0%, #1a0d05 100%);
}
/* Scalloped canopy — two alternating crimson stripes with hanging arcs */
.st-awning {
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 30px;
    background: repeating-linear-gradient(90deg, #6d1a1f 0 44px, #99302a 44px 88px);
    border-bottom: 2px solid rgba(201, 168, 76, 0.85);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.55);
}
.st-awning::after {
    content: '';
    position: absolute;
    left: 0; right: 0; top: 100%;
    height: 13px;
    background:
        radial-gradient(circle at 22px -7px, #6d1a1f 20px, transparent 21px),
        radial-gradient(circle at 66px -7px, #99302a 20px, transparent 21px);
    background-size: 88px 13px;
    filter: drop-shadow(0 3px 3px rgba(0, 0, 0, 0.4));
}
/* The shop sign hangs from the awning on two cords */
.st-sign {
    position: relative;
    margin: 4px auto 0;
    width: fit-content;
    max-width: 92%;
    padding: 8px 24px 9px;
    font-size: 17px;
    background: linear-gradient(180deg, #4a2c12, #2c180a 70%, #241203);
    border: 2px solid var(--gold-dark);
    border-radius: 10px;
    box-shadow: inset 0 1px 0 rgba(232, 212, 139, 0.28), 0 8px 18px rgba(0, 0, 0, 0.55);
    animation: signSettle 1.6s cubic-bezier(0.34, 1.56, 0.64, 1);
    transform-origin: 50% -22px;
}
.st-sign::before, .st-sign::after {
    content: '';
    position: absolute;
    top: -22px;
    width: 2px;
    height: 22px;
    background: linear-gradient(180deg, #caa35a, #7a5a24);
}
.st-sign::before { left: 18%; }
.st-sign::after  { right: 18%; }
@keyframes signSettle {
    0% { transform: rotate(-1.6deg); }
    55% { transform: rotate(1.1deg); }
    100% { transform: rotate(0deg); }
}
/* Your star purse, stitched leather */
.st-stars {
    margin-left: 16px;
    padding: 3px 12px 4px;
    color: #ffd97a;
    letter-spacing: 1px;
    font-size: 0.78em;
    white-space: nowrap;
    background: radial-gradient(130% 170% at 30% 18%, #6b4a22, #3c250e 72%);
    border: 1.5px solid #b98d3e;
    border-radius: 999px;
    box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.55);
    vertical-align: 2px;
}
.st-local {
    font-size: 9px;
    letter-spacing: 2px;
    color: #f0a0a0;
    vertical-align: middle;
}

/* ── The Royal Mint — star bundles under the awning, above the shelves.
   Four coin-purse plaques; the price button opens a PayPal tab and the
   box IPN delivers the Stars into the balance on its own. ── */
.st-mint {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
    margin: 14px 10px 2px;
}
.st-pack {
    flex: 1 1 138px;
    max-width: 190px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 10px 8px 12px;
    background:
        radial-gradient(120% 150% at 50% 0%, rgba(122, 84, 34, 0.55), rgba(38, 22, 8, 0.9) 78%),
        linear-gradient(#2c1a0a, #1d1106);
    border: 1.5px solid #a97f38;
    border-radius: 10px;
    box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.6), 0 2px 8px rgba(0, 0, 0, 0.45);
}
.st-pack.confirming {
    border-color: #ffd97a;
    box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.6), 0 0 14px rgba(255, 217, 122, 0.35);
}
.st-pack-stars {
    font-family: 'Cinzel', serif;
    font-weight: 900;
    font-size: 21px;
    color: #ffd97a;
    text-shadow: 0 0 10px rgba(240, 210, 120, 0.5);
}
.st-pack-name {
    font-style: italic;
    font-size: 11px;
    color: #cdb08a;
    letter-spacing: 0.5px;
}
.st-pack-buy {
    margin-top: 4px;
    padding: 5px 16px;
    font-family: 'Cinzel', serif;
    font-weight: 700;
    font-size: 13px;
    letter-spacing: 1px;
    color: #2b1a06;
    background: linear-gradient(#f4d488, #c99f4b);
    border: 1px solid #8a6a2a;
    border-radius: 999px;
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.st-pack-buy:hover { transform: translateY(-1px); box-shadow: 0 3px 10px rgba(240, 200, 110, 0.35); }
.st-pack-buy.confirm { background: linear-gradient(#ffe9ad, #e0b45e); animation: packPulse 1.1s ease-in-out infinite; }
.st-pack-buy.poor { opacity: 0.4; cursor: default; }
@keyframes packPulse {
    50% { box-shadow: 0 0 16px rgba(255, 217, 122, 0.55); }
}
.st-pack-wait {
    flex: 1 1 100%;
    text-align: center;
    font-style: italic;
    font-size: 12.5px;
    color: #ecd9ae;
    padding: 8px 12px;
    background: rgba(60, 38, 14, 0.55);
    border: 1px dashed #a97f38;
    border-radius: 8px;
    animation: waitBreathe 2.2s ease-in-out infinite;
}
@keyframes waitBreathe {
    50% { opacity: 0.65; }
}
@media (orientation: landscape) and (max-height: 540px) {
    .st-pack { flex-basis: 118px; padding: 7px 6px 9px; }
    .st-pack-stars { font-size: 16px; }
    .st-pack-buy { font-size: 11px; padding: 4px 12px; }
}

/* The single scroll region for the whole store (Wyatt 7/17): awning + sign
   stay pinned above; mint, hero shelf, Table Maker and foot scroll together
   so the heroes are no longer trapped in a narrow band. */
.st-scroll {
    flex: 1 1 auto; min-height: 0;
    overflow-y: auto; overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    padding: 0 2px;
}
.st-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(158px, 1fr));
    gap: 30px 16px;                   /* tall row gap: planks + tags live between rows */
    margin-top: 16px;
    overflow: visible;                /* the whole store scrolls now, not the grid */
    padding: 14px 14px 18px;          /* side padding gives the overhang room INSIDE the box */
}
@keyframes shelfIn {
    from { opacity: 0; transform: translateY(12px); }
}
.st-card {
    position: relative;               /* tags, seals and planks anchor here */
    display: flex;
    flex-direction: column;
    transition: transform 0.25s;
    cursor: pointer;                  /* the painting opens the board inspect */
}
.st-card:hover { transform: translateY(-3px); }
/* every hero stands on a wooden plank */
.st-card::after {
    content: '';
    position: absolute;
    left: -6%; right: -6%; bottom: -12px;
    height: 11px;
    background: linear-gradient(180deg, #6b4423, #4a2c12 55%, #2c1706);
    border-radius: 3px;
    box-shadow: 0 5px 9px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(232, 212, 139, 0.2);
}
.st-frame {
    position: relative;
    padding: 3px;                     /* the gilded frame */
    background: linear-gradient(160deg, #e8c34b, #8a6a1f 38%, #f0d278 66%, #6d4f16);
    border-radius: 4px;
    box-shadow: 0 7px 16px rgba(0, 0, 0, 0.6);
}
.st-card img {
    width: 100%;
    display: block;
    aspect-ratio: 3 / 2;
    object-fit: cover;
    border-radius: 2px;
}
.st-card:not(.owned) img { filter: saturate(0.5) brightness(0.78); }
.st-card.owned .st-frame { box-shadow: 0 0 20px rgba(232, 195, 75, 0.22), 0 7px 16px rgba(0, 0, 0, 0.6); }
.st-plate {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 8px 4px 2px;
}
/* rulebook difficulty — a quiet star row under the plate */
.st-diff {
    font-size: 10px;
    letter-spacing: 2px;
    color: #d9b968;
    text-shadow: 0 1px 2px rgba(0,0,0,0.7);
}
/* brass name plate under the painting */
.st-name {
    font-family: 'Cinzel', serif;
    font-size: 12.5px;
    font-weight: 700;
    letter-spacing: 1px;
    color: var(--gold);
    padding: 2px 14px 3px;
    background: linear-gradient(180deg, rgba(58, 36, 14, 0.92), rgba(30, 17, 6, 0.92));
    border: 1px solid rgba(201, 168, 76, 0.45);
    border-radius: 6px;
    box-shadow: inset 0 1px 0 rgba(232, 212, 139, 0.22), 0 2px 5px rgba(0, 0, 0, 0.4);
}
/* wax seal — stamped once a hero is yours */
.st-owned {
    position: absolute;
    top: -9px; right: -7px;
    z-index: 2;
    width: 46px; height: 46px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Cinzel', serif;
    font-size: 7.5px;
    font-weight: 900;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: #ffe9b8;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.75);
    background: radial-gradient(circle at 34% 28%, #b8452f, #7a1f18 62%, #55110d);
    border: 2px solid rgba(255, 220, 150, 0.35);
    box-shadow: 0 3px 8px rgba(0, 0, 0, 0.55), inset 0 -3px 6px rgba(0, 0, 0, 0.45), inset 0 2px 3px rgba(255, 255, 255, 0.16);
    transform: rotate(8deg);
}
/* hanging price tag — rope, punched hole, parchment */
.st-buy {
    position: absolute;
    top: -8px; right: -5px;
    z-index: 2;
    transform: rotate(6deg);
    transform-origin: 12px -12px;
    font-family: 'Cinzel', serif;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 1px;
    color: #2a1810;
    background: linear-gradient(165deg, #f7ecd2, #e2cd9d);
    border: 1px solid #a98d54;
    border-radius: 4px 9px 9px 4px;
    padding: 5px 12px 5px 17px;
    cursor: pointer;
    box-shadow: 0 3px 8px rgba(0, 0, 0, 0.5);
    transition: transform 0.18s, box-shadow 0.18s;
    animation: tagSettle 0.9s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.st-buy::before {   /* punched hole with brass grommet */
    content: '';
    position: absolute;
    left: 6px; top: 50%;
    transform: translateY(-50%);
    width: 5px; height: 5px;
    border-radius: 50%;
    background: #241203;
    box-shadow: 0 0 0 1.5px #c9b075;
}
.st-buy::after {    /* the string up to the frame */
    content: '';
    position: absolute;
    left: 7px; top: -13px;
    width: 1.5px; height: 14px;
    background: #caa35a;
    transform: rotate(22deg);
}
@keyframes tagSettle {
    0% { transform: rotate(-9deg); }
    55% { transform: rotate(11deg); }
    100% { transform: rotate(6deg); }
}
.st-buy:hover { transform: rotate(1deg) translateY(-1px); box-shadow: 0 5px 12px rgba(232, 195, 75, 0.4); }
.st-buy.confirm {
    background: linear-gradient(165deg, #fff3c4, #ffd97a);
    border-color: #8a6a1f;
    box-shadow: 0 0 16px rgba(255, 217, 122, 0.55);
    animation: ntPulse 1.5s ease-in-out infinite;
}
.st-buy.poor { opacity: 0.6; }
/* ── Board inspect — tap a painting, the whole board on the easel ──
   Full color even when unowned (the player is judging the goods), the
   print-res recut from assets/characters/hd/, same buy button along. */
.st-inspect {
    position: absolute;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    background: rgba(10, 5, 1, 0.84);
    z-index: 6;
}
.st-inspect.active { display: flex; }
.st-insp-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    animation: inspIn 0.28s cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes inspIn {
    from { transform: scale(0.84); opacity: 0; }
    to   { transform: scale(1); opacity: 1; }
}
.st-insp-frame {
    padding: 6px;                     /* the gilded frame, sized up */
    background: linear-gradient(160deg, #e8c34b, #8a6a1f 38%, #f0d278 66%, #6d4f16);
    border-radius: 6px;
    box-shadow: 0 18px 50px rgba(0, 0, 0, 0.75), 0 0 34px rgba(232, 195, 75, 0.18);
}
.st-insp-frame img {
    display: block;
    max-width: min(88vw, 1240px);
    max-height: 64vh;   /* leaves honest room for the epithet row + Tip line */
    border-radius: 3px;
}
.st-insp-row {
    display: flex;
    align-items: center;
    gap: 14px;
}
.st-insp-row .st-name { font-size: 16px; }
/* easel identity — name, italic epithet, DIFFICULTY row (rulebook style) */
.st-insp-id {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 3px;
    min-width: 0;
}
.st-epithet {
    font-family: 'EB Garamond', serif;
    font-style: italic;
    font-size: 13.5px;
    color: #e6cf9d;
    letter-spacing: 0.5px;
}
.st-insp-diff {
    font-family: 'Cinzel', serif;
    font-size: 10px;
    letter-spacing: 2.5px;
    color: rgba(240, 230, 211, 0.6);
}
.st-insp-diff b { color: #ffd97a; letter-spacing: 2px; margin-left: 4px; }
.st-insp-tip {
    font-family: 'EB Garamond', serif;
    font-size: 13.5px;
    color: rgba(240, 230, 211, 0.78);
    padding: 8px 12px;
    margin-top: 2px;
    background: rgba(60, 38, 14, 0.5);
    border-left: 2px solid rgba(201, 168, 76, 0.55);
    border-radius: 0 6px 6px 0;
}
.st-insp-tip i { color: #ecd9ae; }
/* inspect's price tag sits beside the plate, not hung off a shelf frame —
   no rope rigging (::before grommet, ::after string), no settle-swing */
.st-insp-row .st-buy {
    position: static;
    transform: none;
    animation: none;
    padding: 6px 14px;
    font-size: 13px;
}
.st-insp-row .st-buy::before, .st-insp-row .st-buy::after { display: none; }
.st-insp-close {
    position: absolute;
    top: 14px; right: 78px;           /* beside the panel's ESC badge, not on it */
    width: 34px; height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Cinzel', serif;
    font-size: 15px;
    color: var(--gold);
    background: linear-gradient(180deg, rgba(58, 36, 14, 0.92), rgba(30, 17, 6, 0.92));
    border: 1px solid rgba(201, 168, 76, 0.45);
    border-radius: 50%;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
}
.st-insp-close:hover { color: var(--gold-light); box-shadow: 0 0 12px rgba(232, 195, 75, 0.35); }

/* the wares counter along the bottom — the realm's goods on display */
.st-counter {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 20px;
    margin-top: 12px;
    padding: 7px 10px 9px;
    background: linear-gradient(180deg, #5d3a1c, #3a2210 60%, #241203);
    border-radius: 6px;
    border-top: 2px solid rgba(232, 212, 139, 0.3);
    box-shadow: inset 0 -8px 14px rgba(0, 0, 0, 0.45), 0 -3px 10px rgba(0, 0, 0, 0.3);
}
.st-counter img {
    width: 30px; height: 30px;
    object-fit: contain;
    filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.65));
}

.pf-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    padding: 10px 4px;
    border-bottom: 1px solid rgba(201,168,76,0.08);
    font-family: 'Cinzel', serif;
    color: var(--parchment);
}
.pf-label { font-size: 11px; letter-spacing: 2px; text-transform: uppercase; color: var(--gold-dark); }
.pf-row b { color: var(--gold-light); display: inline-flex; align-items: center; gap: 5px; }
.pf-namerow { border-bottom: none; padding-top: 14px; }

/* ═══ PROFILE (Wyatt 7/18: "viewing profile is bad") ═══
   The panel leads with STANDING now, not a crest picker. #profileBody does
   its own scrolling so the title stays pinned — .pf-inner had a plain
   max-height and no inner scroller, unlike .lb-body, so a richer panel would
   simply have overflowed the viewport. */
#profileBody {
    flex: 1 1 auto;
    min-height: 0;              /* without this a flex child refuses to shrink */
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-right: 4px;
}
.pf-standing {
    display: flex; align-items: center; gap: 14px;
    padding: 4px 2px 14px;
    border-bottom: 1px solid rgba(201, 168, 76, 0.16);
}
.pf-standing .pf-av-current { width: 62px; height: 62px; flex: 0 0 auto; }
.pf-standing-main { flex: 1; min-width: 0; }
.pf-rating { display: flex; align-items: baseline; gap: 10px; }
.pf-rating-val { font-family: 'Cinzel', serif; font-weight: 900; font-size: 34px; line-height: 1; }
.pf-tier {
    font-family: 'Cinzel', serif; font-size: 10px; letter-spacing: 2px;
    text-transform: uppercase; color: var(--gold-dark);
}
.pf-record {
    margin-top: 5px; font-family: 'Cinzel', serif; font-size: 12.5px;
    color: var(--parchment);
}
.pf-record b { color: var(--gold-light); }
.pf-purse {
    display: flex; flex-direction: column; align-items: flex-end; gap: 5px;
    font-family: 'Cinzel', serif; font-size: 14px; color: var(--gold-light);
}
.pf-purse .pf-champs { display: inline-flex; align-items: center; gap: 4px; }

.pf-sec {
    display: flex; align-items: center; justify-content: space-between;
    margin: 15px 0 8px;
    font-family: 'Cinzel', serif; font-size: 11px; font-weight: 700;
    letter-spacing: 2.5px; text-transform: uppercase; color: var(--gold-dark);
}
.pf-seeall {
    background: none; border: 1px solid rgba(201, 168, 76, 0.4);
    border-radius: 999px; padding: 2px 11px 3px; cursor: pointer;
    font-family: 'Cinzel', serif; font-size: 9.5px; letter-spacing: 1.4px;
    text-transform: uppercase; color: var(--gold-light);
}
.pf-seeall:hover { border-color: var(--gold-light); background: rgba(201, 168, 76, 0.12); }

/* Per-hero ledgers — every field was already in _me, unrendered. */
.pf-heroes { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 9px; }
.pf-hero {
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: 8px 5px 9px;
    background: rgba(0, 0, 0, 0.26);
    border: 1px solid rgba(201, 168, 76, 0.2);
    border-radius: 9px;
}
.pf-hero img { width: 44px; height: 44px; object-fit: cover; border-radius: 50%; border: 1px solid rgba(201,168,76,0.45); }
.pf-hero-name { font-family: 'Cinzel', serif; font-size: 10px; color: var(--parchment); text-align: center; }
.pf-hero-r { font-family: 'Cinzel', serif; font-weight: 700; font-size: 15px; }
.pf-hero-g { font-size: 9px; letter-spacing: 0.5px; color: var(--gold-dark); }
.pf-hero .lb-best { font-size: 10px; }

.pf-ach { font-family: 'Cinzel', serif; font-size: 12.5px; color: var(--parchment); }
.pf-ach b { color: var(--gold-light); }
.pf-ach-recent { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 7px; }
.pf-ach-recent span {
    font-size: 10px; letter-spacing: 0.4px; padding: 2px 9px 3px;
    color: #ffe9ad; background: rgba(58, 36, 14, 0.85);
    border: 1px solid rgba(232, 195, 75, 0.45); border-radius: 999px;
}

.pf-bounty {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 12px;
    background: rgba(0, 0, 0, 0.26);
    border: 1px solid rgba(232, 195, 75, 0.4);
    border-radius: 10px;
}
.pf-bounty img { width: 38px; height: 38px; object-fit: cover; border-radius: 50%; }
.pf-bounty-name { flex: 1; font-family: 'Cinzel', serif; font-size: 13px; color: var(--parchment); }
.pf-bounty-stars { font-family: 'Cinzel', serif; font-weight: 700; color: var(--gold-light); }
.pf-bounty.done { opacity: 0.6; }
.pf-bounty.done .pf-bounty-stars { color: #9fd8a6; }
.pf-namerow input {
    flex: 1;
    min-width: 0;
    font-family: 'Cinzel', serif;
    font-size: 15px;
    color: var(--gold-light);
    background: rgba(0,0,0,0.35);
    border: 1px solid var(--gold-dark);
    border-radius: 8px;
    padding: 9px 13px;
}
.pf-namerow input.bad { border-color: #e85454; }
.pf-namerow .btn-royal { padding: 9px 20px; font-size: 12px; }
.pf-note { margin-top: 12px; }
.pf-local { color: #e88; font-style: normal; }

/* ── Daily Champion — the royal moment, not a toast ── */
.champ-overlay {
    position: fixed;
    inset: 0;
    z-index: 10008;
    display: none;
    align-items: center;
    justify-content: center;
    background: rgba(10,4,1,0.94);
    backdrop-filter: blur(18px);
}
.champ-overlay.active { display: flex; }
.champ-card {
    position: relative;
    overflow: hidden;
    text-align: center;
    padding: 46px 58px 40px;
    max-width: min(560px, 92vw);
    background:
        radial-gradient(ellipse 90% 70% at 50% 0%, rgba(232,195,75,0.13), transparent 60%),
        linear-gradient(175deg, #32200f 0%, #1a0d05 100%);
    border: 2px solid var(--gold);
    border-radius: 18px;
    box-shadow: 0 0 120px rgba(232,195,75,0.22), 0 30px 90px rgba(0,0,0,0.8);
    animation: ovZoom 0.5s cubic-bezier(0.16,1,0.3,1);
}
.champ-rays {
    position: absolute;
    inset: -60%;
    background: repeating-conic-gradient(from 0deg,
        transparent 0deg 14deg, rgba(232,195,75,0.06) 14deg 22deg);
    animation: champSpin 26s linear infinite;
    pointer-events: none;
}
@keyframes champSpin { to { transform: rotate(360deg); } }
.champ-title {
    position: relative;
    font-family: 'Cinzel', serif;
    font-size: clamp(19px, 3.4vw, 26px);
    font-weight: 700;
    letter-spacing: 2px;
    color: var(--gold-light);
    text-shadow: 0 0 30px rgba(232,195,75,0.5);
}
.champ-sub {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    font-family: 'Cinzel', serif;
    font-size: 14px;
    font-weight: 700;
    color: #e8c34b;
    margin: 14px 0 26px;
}
.champ-card .btn-royal { position: relative; }

.btn-royal {
    font-family: 'Cinzel', serif;
    font-weight: 700;
    font-size: clamp(14px, 2vw, 18px);
    letter-spacing: 3px;
    text-transform: uppercase;
    padding: 14px 48px;
    border: 2px solid var(--gold);
    background: linear-gradient(135deg, rgba(201, 168, 76, 0.15) 0%, rgba(201, 168, 76, 0.05) 100%);
    color: var(--gold);
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.3s ease;
    position: relative;
    overflow: hidden;
    min-width: 280px;
    text-align: center;
}

.btn-royal::before {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg, rgba(201, 168, 76, 0.3) 0%, rgba(201, 168, 76, 0.1) 100%);
    opacity: 0;
    transition: opacity 0.3s ease;
}

.btn-royal:hover {
    border-color: var(--gold-light);
    color: var(--gold-light);
    box-shadow: 0 0 30px rgba(201, 168, 76, 0.3);
    transform: translateY(-2px);
}

.btn-royal:hover::before { opacity: 1; }

.btn-royal span { position: relative; z-index: 1; }

.btn-royal.primary {
    background: linear-gradient(135deg, var(--gold-dark) 0%, var(--gold) 50%, var(--gold-dark) 100%);
    color: var(--royal-deep);
    font-weight: 900;
    border-color: var(--gold-light);
    box-shadow: 0 0 20px rgba(201, 168, 76, 0.2);
}

.btn-royal.primary:hover {
    box-shadow: 0 0 40px rgba(201, 168, 76, 0.5);
    color: var(--royal-deep);
}

/* Prompt Test — dev toggle to replay the in-game tutorial prompts.
   Lives in the menu's quiet row now — no pill chrome, just a checkbox. */
.prompt-test-toggle {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: 'Cinzel', serif;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: rgba(201, 168, 76, 0.55);
    cursor: pointer;
    user-select: none;
    transition: color 0.15s;
}
.prompt-test-toggle:hover { color: var(--gold); }
.prompt-test-toggle input {
    width: 16px; height: 16px;
    margin: 0;
    accent-color: var(--gold);
    cursor: pointer;
}

/* Music toggle */
.music-toggle {
    position: fixed;
    top: 20px;
    right: 20px;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: 1px solid rgba(201, 168, 76, 0.3);
    background: rgba(10, 6, 18, 0.8);
    color: var(--gold);
    font-size: 20px;
    cursor: pointer;
    z-index: 1001;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s ease;
}

.music-toggle:hover {
    border-color: var(--gold);
    box-shadow: 0 0 15px rgba(201, 168, 76, 0.3);
}

/* Pre-game the top-right corner belongs to the PROFILE CHIP: music parks
   top-left and the game-log button waits until there is a game to log.
   In-game the corner belongs to the OPPONENTS rail — floating toggles
   there ate real clicks aimed at the first rival (the log panel opened
   instead of the rival overlay) — so both slide left of the sidebar. */
.music-toggle { right: auto; left: 20px; }
body:has(#game-screen.active) .music-toggle { left: auto; right: 240px; }
/* (log-toggle placement lives with its base block below — cascade order) */

.music-toggle.muted { opacity: 0.4; }

/* ─── CHARACTER SELECT SCREEN ──────────────────────────── */

#character-select {
    position: fixed;
    inset: 0;
    display: none;
    flex-direction: column;
    align-items: center;
    background: linear-gradient(180deg, var(--royal-deep) 0%, #0a0612 100%);
    z-index: 900;
    overflow-y: auto;
    padding: max(40px, env(safe-area-inset-top)) max(20px, env(safe-area-inset-right))
             40px max(20px, env(safe-area-inset-left));
}

#character-select.active { display: flex; }

.select-title {
    font-family: 'Cinzel', serif;
    font-weight: 900;
    font-size: clamp(24px, 4vw, 40px);
    color: var(--gold);
    margin-bottom: 10px;
}

.select-subtitle {
    font-family: 'EB Garamond', serif;
    font-size: 18px;
    color: var(--text-light);
    opacity: 0.7;
    margin-bottom: 30px;
}

.character-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 20px;
    max-width: 1200px;
    width: 100%;
    padding: 0 20px;
}

/* The pledge ribbon — you committed at PLAY NOW; this is the honest
   status line (queue narration + Withdraw) or the solo way home. */
.queue-pledge {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin: -6px auto 14px;
    padding: 6px 18px;
    font-family: 'Cinzel', serif;
    font-size: 12px;
    letter-spacing: 0.5px;
    color: #e6cf9d;
    background: rgba(42, 24, 8, 0.6);
    border: 1px solid rgba(201, 168, 76, 0.3);
    border-radius: 999px;
    width: fit-content;
    max-width: 92vw;
}
.queue-pledge .menu-link { padding: 2px 6px; }
.qp-dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    background: #ffd97a;
    box-shadow: 0 0 8px rgba(255, 217, 122, 0.8);
    animation: qpPulse 1.4s ease-in-out infinite;
}
@keyframes qpPulse {
    50% { opacity: 0.35; }
}

.character-card {
    border: 2px solid rgba(201, 168, 76, 0.3);
    border-radius: 8px;
    overflow: hidden;
    cursor: pointer;
    transition: all 0.3s ease;
    background: rgba(26, 15, 40, 0.8);
}

.character-card:hover {
    border-color: var(--gold);
    box-shadow: 0 0 30px rgba(201, 168, 76, 0.3);
    transform: translateY(-4px);
}

.character-card.selected {
    border-color: var(--gold-light);
    box-shadow: 0 0 40px rgba(201, 168, 76, 0.5);
}

.character-card img {
    width: 100%;
    display: block;
}

.character-info {
    padding: 12px 16px;
    text-align: center;
}

.character-info h3 {
    font-family: 'Cinzel', serif;
    font-size: 18px;
    color: var(--gold);
    margin-bottom: 2px;
}

/* the printed epithet — "Deadly Duelist", "The Wildcard" */
.character-info .epithet {
    font-family: 'EB Garamond', serif;
    font-style: italic;
    font-size: 13.5px;
    color: #e6cf9d;
    margin-bottom: 3px;
}

.character-info .difficulty {
    font-size: 14px;
    color: var(--gold-dark);
}

.character-info .tip {
    font-style: italic;
    font-size: 13px;
    color: var(--text-light);
    opacity: 0.6;
    margin-top: 6px;
}

/* ─── GAME SCREEN — Tavern Board Layout ────────────────── */

#game-screen {
    position: fixed;
    inset: 0;
    display: none;
    background:
        /* Knot suggestion, upper left */
        radial-gradient(ellipse 120px 80px at 12% 18%, rgba(20,10,4,0.35) 0%, transparent 70%),
        /* Knot suggestion, lower right */
        radial-gradient(ellipse 90px 60px at 85% 78%, rgba(20,10,4,0.3) 0%, transparent 70%),
        /* Subtle knot, mid left */
        radial-gradient(ellipse 60px 40px at 7% 55%, rgba(15,8,3,0.25) 0%, transparent 70%),
        /* Main wood warmth gradient — lighter center, darker edges */
        radial-gradient(ellipse at 50% 40%, #6b4a30 0%, #4a3020 35%, #3a2214 65%, #2a1a10 100%),
        /* Base mahogany */
        linear-gradient(175deg, #3d2817 0%, #2a1a10 50%, #1e1208 100%);
    z-index: 800;
}

/* Wood grain texture overlay */
#game-screen::before {
    content: '';
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 0;
    opacity: 0.07;
    background:
        /* Fine grain streaks */
        repeating-linear-gradient(
            91deg,
            transparent 0px,
            rgba(255,220,160,0.6) 1px,
            transparent 2px,
            transparent 18px,
            rgba(200,160,100,0.4) 19px,
            transparent 20px,
            transparent 34px,
            rgba(255,200,120,0.3) 35px,
            transparent 37px,
            transparent 58px,
            rgba(240,180,100,0.5) 59px,
            transparent 60px,
            transparent 80px
        ),
        repeating-linear-gradient(
            89deg,
            transparent 0px,
            rgba(180,130,80,0.3) 1px,
            transparent 3px,
            transparent 45px,
            rgba(220,170,100,0.4) 46px,
            transparent 48px,
            transparent 90px
        );
}

#game-screen.active { display: block; }

/* Warm vignette — brown-tinted edges, not purple */
#game-screen::after {
    content: '';
    position: fixed;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(ellipse at center, transparent 55%, rgba(14,7,2,0.5) 100%);
    z-index: 0;
}

/* ── Main Grid: play-area | sidebar ── */

.game-layout {
    display: grid;
    grid-template-columns: 1fr 220px;
    grid-template-rows: 1fr;
    height: 100vh;
    width: 100vw;
    position: relative;
    z-index: 1;
}

/* ── Phase Bar (top-center of play area) ── */

.phase-bar {
    position: fixed;   /* screen-level: visible in both desktop grid and table view */
    top: 10px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 30;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 6px 20px;
    border-radius: 24px;
    background:
        linear-gradient(180deg, var(--wood-dark) 0%, var(--wood-deeper, #4a2e1a) 50%, var(--wood-dark) 100%);
    border: 2px solid var(--gold-dark);
    box-shadow:
        inset 0 2px 6px rgba(0,0,0,0.6),
        inset 0 -1px 3px rgba(255,200,100,0.06),
        0 3px 12px rgba(0,0,0,0.5),
        0 1px 0 rgba(255,200,120,0.08);
    backdrop-filter: blur(8px);
}

.phase-bar .act-tag {
    font-family: 'Cinzel', serif;
    font-size: 12px;
    color: var(--gold);
    letter-spacing: 2px;
    font-weight: 700;
}

.phase-bar .phase-text {
    font-family: 'Cinzel', serif;
    font-size: 10px;
    color: var(--gold-dark);
    letter-spacing: 2px;
    text-transform: uppercase;
}

/* ── Play Area ── */

.play-area {
    grid-column: 1;
    position: relative;
    display: flex;
    align-items: flex-start;
    padding: 50px 24px calc(var(--handCardH) + 40px);
    padding-left: 282px;   /* clears the 250px stats panel + 16px inset */
    overflow-y: auto;
    overflow-x: hidden;
}

/* ── Board Thumbnail — top-left ── */

.board-thumb {
    position: absolute;
    top: 50px;
    left: 16px;
    z-index: 10;
    cursor: pointer;
    border-radius: 8px;
    overflow: hidden;
    border: 3px solid var(--gold-dark);
    box-shadow:
        inset 0 0 8px rgba(0,0,0,0.5),
        0 4px 24px rgba(0,0,0,0.7),
        0 0 20px rgba(201,168,76,0.06);
    transition: all 0.3s ease;
    background: var(--wood-deepest);
    width: 195px;
}

.board-thumb:hover {
    border-color: var(--gold);
    box-shadow:
        inset 0 0 8px rgba(0,0,0,0.4),
        0 4px 30px rgba(201,168,76,0.25),
        0 0 40px rgba(201,168,76,0.1);
    transform: scale(1.03);
}

.board-thumb img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 6px;
}

/* Ring token on the thumbnail — same %-track as the big overlay, so it
   scales with the thumb and always marks the current slot. */
.board-thumb .thumb-boardwrap {
    position: relative;
}

.board-thumb .thumb-ring {
    position: absolute;
    width: 9%;
    height: auto;
    aspect-ratio: 1;
    transform: translate(-50%, -50%);
    pointer-events: none;
    filter: drop-shadow(0 1px 2px rgba(0,0,0,0.65));
}

.board-thumb .thumb-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 5px 8px;
    background: rgba(20,10,4,0.88);
}

.board-thumb .thumb-name {
    font-family: 'Cinzel', serif;
    font-size: 10px;
    color: var(--gold-light);
    letter-spacing: 1px;
    flex: 1 1 auto;      /* a long royal name truncates instead of… */
}

.board-thumb .thumb-hint {
    font-family: 'Cinzel', serif;
    font-size: 7px;
    color: var(--gold-dark);
    letter-spacing: 1px;
    text-transform: uppercase;
    flex: none;          /* …squeezing the hint into a wrap */
    white-space: nowrap;
}

/* ── Stats Panel — under board thumbnail ── */

/* Juicy stats scale — tokens on a table, readable at arm's length.
   Full size on tall windows; ~0.78 on short desktops (≤849px) so the
   panel + mission strip still clear 1280×800 without colliding. */
:root { --sx: 1; }
@media (max-height: 849px) { :root { --sx: 0.78; } }

.stats-panel {
    position: absolute;
    top: 185px;
    left: 16px;
    z-index: 10;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 10px;
    border-radius: 10px;
    background:
        linear-gradient(160deg, var(--wood-darker) 0%, var(--wood-deepest) 100%);
    border: 2px solid var(--gold-dark);
    box-shadow:
        inset 0 2px 8px rgba(0,0,0,0.6),
        inset 0 -1px 3px rgba(255,190,90,0.04),
        0 4px 16px rgba(0,0,0,0.5);
    width: 250px;
    /* Safety net for rare tall states (flex + both specials): scroll
       inside the panel rather than run under the hand zone. */
    max-height: calc(100dvh - 285px);
    overflow-y: auto;
}

.stats-panel .act-badge {
    text-align: center;
    font-family: 'Cinzel', serif;
    font-size: 11px;
    color: var(--gold-dark);
    letter-spacing: 2px;
    text-transform: uppercase;
    padding-bottom: 4px;
    border-bottom: 1px solid rgba(201, 168, 76, 0.12);
    margin-bottom: 2px;
}

.stats-panel .stats-row {
    display: flex;
    gap: 4px;
    justify-content: center;
    flex-wrap: wrap;
}

/* ── Resource Tokens (Gold / Prestige / Scorn) ── */

.resource-tokens {
    display: flex;
    flex-direction: column;
    gap: calc(3px * var(--sx));
    padding: 3px 0 5px;
    border-bottom: 1px solid rgba(201, 168, 76, 0.08);
    margin-bottom: 6px;
}

.resource-token {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: calc(1px * var(--sx)) 14px calc(1px * var(--sx)) 6px;
    border-radius: 999px;
    background: rgba(0,0,0,0.2);
    border: 1px solid rgba(201, 168, 76, 0.1);
}

.token-img {
    /* 38→32: makes room for the 4th (Favor) token row without scroll */
    width: calc(32px * var(--sx));
    height: calc(32px * var(--sx));
    border-radius: 50%;
    object-fit: cover;
    box-shadow: 0 1px 4px rgba(0,0,0,0.4);
}

.token-val {
    font-family: 'Cinzel', serif;
    font-size: calc(34px * var(--sx));
    font-weight: 900;
    line-height: 1;
}

.token-val.gold-val { color: #ffd700; text-shadow: 0 0 6px rgba(255,215,0,0.4); }
.token-val.prestige-val { color: #6cb4ee; text-shadow: 0 0 6px rgba(108,180,238,0.4); }
.token-val.scorn-val { color: #e85454; text-shadow: 0 0 6px rgba(232,84,84,0.4); }
.token-val.favor-val { color: #4fc3f7; text-shadow: 0 0 6px rgba(79,195,247,0.4); }

/* ── Skills Grid ── */

.skills-grid {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 4px 0;
}

.skill-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 1px 6px;
    border-radius: 6px;
    transition: background 0.2s ease;
}

.skill-row:hover {
    background: rgba(201, 168, 76, 0.05);
}

.skill-row.special-ability {
    border-top: 1px solid rgba(201, 168, 76, 0.08);
    margin-top: 2px;
    padding-top: 5px;
}

/* Flex skill (Mining Guild etc.): one unit, either option per use. */
.skill-row.flex-skill {
    border: 1px dashed rgba(201, 168, 76, 0.35);
    background: rgba(201, 168, 76, 0.04);
    margin-top: 2px;
}
.skill-row.flex-skill .skill-label { font-style: normal; }
.skill-row.flex-skill .skill-label i { color: var(--gold); font-size: 0.85em; }
/* Both faces of the either/or pair share the icon cell — a lone icon
   read as a duplicate of the fixed skill row above it. */
.skill-icon.flex-pair { width: auto; }
.skill-icon.flex-pair .skill-svg {
    width: calc(22px * var(--sx));
    height: calc(22px * var(--sx));
}
.skill-icon.flex-pair .skill-svg + .skill-svg { margin-left: -5px; }

.skill-icon {
    width: calc(30px * var(--sx));
    height: calc(30px * var(--sx));
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.skill-svg {
    width: calc(30px * var(--sx));
    height: calc(30px * var(--sx));
    border-radius: 6px;
    object-fit: contain;
}

.skill-label {
    font-family: 'Cinzel', serif;
    font-size: 12px;
    color: var(--gold-dark);
    letter-spacing: 1px;
    text-transform: uppercase;
    flex: 1;
}
/* The full "Philosopher's Stone" fits its row at a smaller size (Wyatt:
   no more "PHIL. STONE"). */
.skill-label.phil-label { font-size: 9.5px; letter-spacing: 0.6px; }

.skill-value {
    font-family: 'Cinzel', serif;
    font-size: calc(30px * var(--sx));
    font-weight: 900;
    color: rgba(201, 168, 76, 0.25);
    min-width: calc(44px * var(--sx));
    text-align: right;
}

.skill-value.has-skill {
    color: var(--gold-light);
    text-shadow: 0 0 8px rgba(201, 168, 76, 0.3);
}

.ring-indicator {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    margin-top: 4px;
    font-family: 'Cinzel', serif;
    font-size: 12px;
    color: rgba(255,255,255,0.5);
}

.stat-pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 10px;
    border-radius: 12px;
    font-family: 'Cinzel', serif;
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
}

/* Real token art inside stat pills (never emoji). */
.stat-pill .pill-icon {
    width: 18px;
    height: 18px;
    object-fit: contain;
    filter: drop-shadow(0 1px 1px rgba(0,0,0,0.6));
}
.stat-pill.prestige .pill-icon { border-radius: 50%; object-fit: cover; }

/* The Emblem marker, anywhere "emblem holder" shows — a round mini-token. */
.emblem-badge {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    object-fit: cover;
    border: 1px solid var(--gold-dark);
    box-shadow: 0 1px 3px rgba(0,0,0,0.6);
    vertical-align: -3px;
}

.stat-pill.gold {
    background: rgba(201, 168, 76, 0.14);
    color: var(--gold-light);
    border: 1px solid rgba(201, 168, 76, 0.28);
}

.stat-pill.favor {
    background: rgba(70, 130, 220, 0.12);
    color: #8cb8f0;
    border: 1px solid rgba(70, 130, 220, 0.22);
}

.stat-pill.scorn {
    background: rgba(200, 40, 40, 0.12);
    color: #f08080;
    border: 1px solid rgba(200, 40, 40, 0.22);
}

.stat-pill.prestige {
    background: rgba(79, 195, 247, 0.12);
    color: #8cd8f8;
    border: 1px solid rgba(79, 195, 247, 0.22);
}

.stats-panel .emblem-tag,
.opp-ov-panel .emblem-tag {
    text-align: center;
    font-family: 'Cinzel', serif;
    font-size: 11px;
    color: var(--gold);
    letter-spacing: 1px;
    margin-top: 2px;
}

/* ── Mission Strip — under stats ── */

.mission-strip {
    position: absolute;
    top: 290px;
    left: 16px;
    z-index: 10;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 8px 10px;
    border-radius: 10px;
    background:
        linear-gradient(160deg, var(--wood-darker) 0%, var(--wood-deepest) 100%);
    border: 2px solid rgba(201, 168, 76, 0.12);
    box-shadow:
        inset 0 2px 6px rgba(0,0,0,0.55),
        0 3px 12px rgba(0,0,0,0.45);
    width: 250px;   /* matches the stats panel above it */
}

.mission-section {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.mission-section + .mission-section {
    border-top: 1px solid rgba(201, 168, 76, 0.08);
    padding-top: 6px;
}

.mission-pips {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
}

.mission-strip .strip-label {
    font-family: 'Cinzel', serif;
    font-size: 8px;
    color: var(--gold-dark);
    letter-spacing: 2px;
    text-transform: uppercase;
}

.mission-strip .mission-pip {
    width: clamp(28px, 4.6vh, 50px);
    height: clamp(39px, 6.44vh, 70px);
    border-radius: 3px;
    object-fit: cover;
    cursor: pointer;
    border: 1px solid rgba(201, 168, 76, 0.12);
    opacity: 0.55;
    transition: all 0.2s;
    box-shadow: 0 2px 6px rgba(0,0,0,0.4);
}

.mission-strip .mission-pip:hover {
    opacity: 1;
    border-color: var(--gold);
    transform: scale(1.15);
    box-shadow: 0 4px 16px rgba(201, 168, 76, 0.15);
}

.mission-strip .mission-pip.active {
    opacity: 0.8;
    border-color: var(--gold);
}

.mission-strip .mission-pip.available {
    opacity: 0.45;
    border-style: solid;
}

.mission-strip .mission-pip.completed {
    opacity: 0.85;
    border-color: #4caf50;
    box-shadow: 0 0 8px rgba(76, 175, 80, 0.3);
}

/* ── Card Stacks — played cards grouped by skill ── */

.card-stacks {
    display: flex;
    gap: 22px;
    align-items: flex-start;
    flex-wrap: wrap;
    align-content: flex-start;
    position: relative;
    z-index: 5;
    min-height: 200px;
}

.card-stack {
    display: flex;
    flex-direction: column;
    position: relative;
    min-width: calc(var(--stackCardH) * 0.714);
    transition: gap 0.3s ease;
}

.card-stack .stack-label {
    font-family: 'Cinzel', serif;
    font-size: 7px;
    color: var(--typeC, var(--gold-dark));
    letter-spacing: 2px;
    text-transform: uppercase;
    text-align: center;
    margin-bottom: 5px;
    opacity: 0.95;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}

.card-stack .stack-card {
    width: calc(var(--stackCardH) * 0.714);
    height: var(--stackCardH);
    border-radius: 5px;
    box-shadow: 0 3px 12px rgba(0,0,0,0.65);
    object-fit: cover;
    transition: transform 0.2s ease, box-shadow 0.2s ease;
    cursor: pointer;
    position: relative;
}

.card-stack .stack-card + .stack-card {
    margin-top: calc(38px - var(--stackCardH)); /* tucked: 38px peek */
}

.card-stack .stack-card:hover {
    transform: translateY(-8px) scale(1.05);
    box-shadow: 0 10px 30px rgba(0,0,0,0.6), 0 0 20px rgba(201,168,76,0.08);
    z-index: 20;
    position: relative;
}

.card-stack:hover .stack-card + .stack-card {
    margin-top: calc(54px - var(--stackCardH)); /* peek + 16px spread */
}

/* Empty stacks placeholder */
.card-stacks .no-cards-msg {
    font-family: 'Cinzel', serif;
    font-size: 11px;
    color: var(--gold-dark);
    opacity: 0.4;
    letter-spacing: 2px;
    padding: 40px 0;
}

/* ── Sidebar — Opponents Only ── */

.game-sidebar {
    grid-column: 2;
    grid-row: 1;
    display: flex;
    flex-direction: column;
    border-left: 2px solid var(--wood-dark);
    background:
        linear-gradient(180deg, rgba(42,22,10,0.92) 0%, rgba(26,14,5,0.96) 100%);
    overflow-y: auto;
    padding: 0;
    z-index: 2;
    box-shadow: inset 2px 0 8px rgba(0,0,0,0.4);
}

.game-sidebar .sidebar-header {
    font-family: 'Cinzel', serif;
    font-size: 8px;
    color: var(--gold-dark);
    letter-spacing: 3px;
    text-transform: uppercase;
    padding: 14px 12px 8px;
}

.opp-entry {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 10px 12px;
    cursor: pointer;
    transition: all 0.25s ease;
    border-bottom: 1px solid rgba(90,61,43,0.35);
    background: linear-gradient(135deg, rgba(42,22,10,0.5) 0%, rgba(26,14,5,0.4) 100%);
    box-shadow: inset 0 1px 4px rgba(0,0,0,0.35);
}

.opp-entry:hover {
    background: linear-gradient(135deg, rgba(66,38,18,0.7) 0%, rgba(42,22,10,0.6) 100%);
}

.opp-entry .opp-avatar {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    object-fit: cover;
    border: 2px solid rgba(201, 168, 76, 0.45);
    box-shadow: 0 0 0 2px rgba(0,0,0,0.4), 0 2px 8px rgba(0,0,0,0.5);
    flex-shrink: 0;
}

.opp-entry .opp-details {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
    min-width: 0;
}

.opp-entry .opp-name {
    font-family: 'Cinzel', serif;
    font-size: 13px;
    letter-spacing: 0.5px;
    color: var(--gold-light);
    display: flex;
    align-items: center;
    gap: 5px;
}

/* Gold rides the rail (Wyatt keeps it glanceable) — the game's own coin
   art, big Cinzel count. Everything else waits behind the click. */
.opp-entry .opp-gold-row {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 3px;
}
.opp-entry .opp-gold-row img {
    width: 24px;
    height: 24px;
    object-fit: contain;
    filter: drop-shadow(0 1px 2px rgba(0,0,0,0.6));
}
.opp-entry .opp-gold-row b {
    font-family: 'Cinzel', serif;
    font-size: 18px;
    font-weight: 900;
    color: var(--gold-light);
    line-height: 1;
    text-shadow: 0 0 8px rgba(255,215,0,0.25);
}

.opp-entry .mini-stack {
    display: flex;
    margin-top: 6px;
}

.opp-entry .mini-card {
    width: 32px;
    height: 48px;
    border-radius: 3px;
    object-fit: cover;
    border: 1px solid rgba(201, 168, 76, 0.25);
    box-shadow: 0 2px 5px rgba(0,0,0,0.5);
    opacity: 0.6;
    transition: opacity 0.2s, transform 0.2s;
}
.opp-entry .mini-card + .mini-card { margin-left: -9px; }

.opp-entry:hover .mini-card {
    opacity: 0.9;
}

.opp-entry.active-turn {
    border-left: 2px solid var(--gold);
    padding-left: 10px;
}

/* ── Neighbor-target highlight — who does the selected card read? ──
   .nt-read marks the entries/chips a selected card reads (see
   TARGET_READ_SPECIALS in ui.js); .nt-tag is the floating label. */

/* Scoped: sidebar rows are static and need a positioning context for the
   tag; #statsPanel is ALREADY position:absolute — forcing relative on it
   would yank the whole panel out of its place in the layout. */
.opp-entry.nt-read { position: relative; z-index: 5; }

.opp-entry.nt-read .opp-avatar,
.tv-seats .pmat.nt-read,
#statsPanel.nt-read {
    animation: ntPulse 1.5s ease-in-out infinite;
}
.opp-entry.nt-read {
    background: linear-gradient(135deg, rgba(72,52,16,0.55) 0%, rgba(42,26,8,0.5) 100%);
}

@keyframes ntPulse {
    0%, 100% { box-shadow: 0 0 0 2px rgba(232, 195, 75, 0.9), 0 0 12px 2px rgba(232, 195, 75, 0.35); }
    50%      { box-shadow: 0 0 0 3px rgba(240, 210, 120, 1), 0 0 22px 7px rgba(232, 195, 75, 0.6); }
}

.nt-tag {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    background: linear-gradient(180deg, #f0d278, #c9a84c);
    color: #2a1810;
    font: 700 9px 'Cinzel', serif;
    letter-spacing: 0.5px;
    padding: 2px 8px;
    border-radius: 8px;
    border: 1px solid #8a6a1f;
    white-space: nowrap;
    /* Tappable: the tag is the most button-looking thing on the seat and
       hangs OUTSIDE its chip — pointer-events:none let taps fall through
       to dead space, and the outside-click handler ate the action panel.
       Now a tag tap bubbles to its chip and opens the rival peek instead. */
    pointer-events: auto;
    cursor: pointer;
    z-index: 7;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
}

/* Desktop sidebar rows: the tag sits INSIDE the row's bottom edge —
   the sidebar scrolls (overflow-y:auto), anything hung outside clips. */
.opp-entry .nt-tag { bottom: 3px; }

/* Desktop stats panel: tag pinned inside the top edge. */
#statsPanel .nt-tag { top: 4px; }

/* Phone seat chips hug the top screen edge — tags hang BELOW their chip,
   arrow end anchored under it: the left tag extends rightward (its ◀
   points at the chip), the right tag extends leftward (its ▶ points at
   the chip). Opposite directions = no collision on 3–4 player tables
   where the two marked chips sit close. */
.tv-seats .pmat.nt-left .nt-tag  { top: calc(100% + 6px); transform: translateX(-9%); }
.tv-seats .pmat.nt-right .nt-tag { top: calc(100% + 6px); transform: translateX(-91%); }

/* While marks are up, the seat row must outrank the phase pill (z:6,
   reparented into #table-view AFTER the seats — DOM order would win). */
.tv-seats:has(.nt-read) { z-index: 12; }

/* ── Hand Zone — bottom tray ── */

.hand-zone {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 220px;
    height: calc(var(--handCardH) + 40px);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    padding: 0 30px 12px;
    background: linear-gradient(0deg,
        rgba(22,10,3,0.97) 0%,
        rgba(35,18,7,0.82) 45%,
        rgba(42,22,10,0.55) 70%,
        transparent 100%
    );
    box-shadow: inset 0 6px 18px rgba(0,0,0,0.35);
    z-index: 5;
}

.hand-zone .hand-hint {
    position: absolute;
    top: 8px;
    left: 50%;
    transform: translateX(-50%);
    font-family: 'Cinzel', serif;
    font-size: 7px;
    color: var(--gold-dark);
    letter-spacing: 2px;
    text-transform: uppercase;
    opacity: 0;
    transition: opacity 0.2s;
    cursor: pointer;
}

.hand-zone:hover .hand-hint { opacity: 1; }

.hand-arc {
    display: flex;
    justify-content: center;
    align-items: flex-end;
}

/* Resting card sizes scale with the window (Battlegrounds proportions) —
   fixed laptop-era pixels left fullscreen tables feeling empty. The 0.714
   factor is the 333x500 card-scan aspect. Phone table view overrides these
   with its own tuned sizes inside the landscape media query. */
:root {
    --handCardH: clamp(133px, 21vh, 230px);
    --stackCardH: clamp(175px, 24vh, 250px);
}

.hand-card {
    width: calc(var(--handCardH) * 0.714);
    height: var(--handCardH);
    border-radius: 6px;
    overflow: hidden;
    cursor: pointer;
    /* ease-out (fast start) so the card answers the cursor instantly. */
    transition: all 0.22s ease-out;
    border: 2px solid rgba(201, 168, 76, 0.3);
    position: relative;
    margin: 0 -6px;
    transform-origin: bottom center;
    box-shadow: 0 3px 12px rgba(0,0,0,0.65);
}

.hand-card img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Battlegrounds bloom: the hovered card grows to near screen height in
   place. --bloomScaleDesk fits it to the actual window and --bloomShift
   keeps edge cards fully on-screen (set by _bloomLayout in ui.js).
   Margins never change, so the fan never reflows under the cursor.
   MICE ONLY: touch browsers keep :hover stuck on the last-touched card,
   which double-bloomed alongside the JS glide (.bloom) — so touch relies
   on .bloom exclusively. */
@media (hover: hover) {
    .hand-card:hover {
        transform: translateX(var(--bloomShift, 0px)) translateY(-14px) scale(var(--bloomScaleDesk, 4)) rotate(0deg) !important;
        transform-origin: bottom center;
        /* Above .selected (31): the card you're READING always wins the
           stack — a selected neighbor used to paint over the bloom. */
        z-index: 33;
        border-color: var(--gold);
        box-shadow: 0 12px 40px rgba(0,0,0,0.7), 0 0 20px rgba(201,168,76,0.1);
    }

    /* While a card blooms, the hand must outrank the fixed phase bar (z 30)
       — .game-layout is a z-1 stacking context, so bump the layout itself. */
    .game-layout:has(.hand-card:hover) { z-index: 31; }
    .hand-zone:has(.hand-card:hover) { z-index: 40; }
}

.hand-card.selected {
    transform: translateY(-36px) scale(1.18) rotate(0deg) !important;
    z-index: 31;
    margin: 0 5px;
    border-color: var(--gold-light);
    box-shadow: 0 12px 40px rgba(201,168,76,0.3), 0 0 30px rgba(201,168,76,0.15);
}

/* A selected card must beat the phase bar (z 30) even with no hover —
   same layout bump as :hover above, but hover-independent: without it
   the card only outranks the pill while the mouse happens to rest on it. */
.game-layout:has(.hand-card.selected) { z-index: 31; }
.hand-zone:has(.hand-card.selected) { z-index: 40; }

/* Desktop drag-to-play (the phone's Hearthstone pull, mouse-driven):
   the pulled card rides the cursor via inline transform — transition off
   so it tracks 1:1 — while the rest of the fan dims and goes hover-dead
   (a neighbor blooming to screen height mid-drag would bury the drag). */
#handZone .hand-card.dragging {
    transition: none !important;
    z-index: 70;
    cursor: grabbing;
    filter: drop-shadow(0 14px 26px rgba(0,0,0,0.65)) drop-shadow(0 0 16px rgba(240,210,120,0.4));
}
#handZone.drag-from .hand-card:not(.dragging) { opacity: 0.45; pointer-events: none; }
.game-layout:has(.hand-card.dragging) { z-index: 31; }
.hand-zone:has(.hand-card.dragging) { z-index: 40; }
#handZone .hand-card img { -webkit-user-drag: none; }

/* Hand waiting text */
.hand-zone .hand-waiting {
    color: var(--gold);
    opacity: 0.4;
    font-family: 'Cinzel', serif;
    font-size: 12px;
    padding: 40px;
    letter-spacing: 2px;
}

/* ── Bottom Stats Bar (for animation system) ── */

.bottom-stats {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex;
    align-items: center;
    gap: 20px;
    padding: 4px 20px;
    background: transparent;
    z-index: 0;
    pointer-events: none;
    opacity: 0;
    height: 0;
    overflow: hidden;
}

.stat {
    display: flex;
    align-items: center;
    gap: 6px;
    font-family: 'Cinzel', serif;
    font-size: 15px;
}

.stat.gold { color: #ffd700; }
.stat.prestige { color: #4fc3f7; }
.stat.scorn { color: #ef5350; }
.stat.favor { color: #ab47bc; }

/* ═══ OVERLAYS ═══════════════════════════════════════════ */

/* Shared close button */
.ov-close {
    position: absolute;
    top: 20px;
    right: 20px;
    font-family: 'Cinzel', serif;
    font-size: 11px;
    color: var(--gold-dark);
    cursor: pointer;
    padding: 6px 16px;
    border: 1px solid rgba(201, 168, 76, 0.2);
    border-radius: 8px;
    letter-spacing: 2px;
    transition: all 0.2s;
    z-index: 10;
}
.ov-close:hover { color: var(--gold-light); border-color: var(--gold); }

/* ── Board Overlay ── */

.board-overlay {
    position: fixed;
    inset: 0;
    z-index: 10001;
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: rgba(20,12,5,0.96);
    backdrop-filter: blur(20px);
}
.board-overlay.active { display: flex; }

.board-ov-boardwrap {
    position: relative;
    display: inline-block;
    line-height: 0;
    animation: ovZoom 0.45s cubic-bezier(0.16,1,0.3,1);
}

.board-ov-full {
    max-width: 90vw;
    max-height: 74vh; /* the board IS the sheet now — give it the screen */
    border-radius: 12px;
    box-shadow: 0 0 120px rgba(201,168,76,0.08), 0 24px 80px rgba(0,0,0,0.7);
}

/* The ring token, sitting ON the track's slot circle (same geometry the
   table mats use: slot centers at 16/33/50/67/84%, track at 88% height). */
.board-ov-ring {
    position: absolute;
    top: 88%;
    width: 9%;
    aspect-ratio: 1;
    transform: translate(-50%, -50%);
    pointer-events: none;
    filter: drop-shadow(0 2px 5px rgba(0,0,0,0.65));
    transition: left 0.4s cubic-bezier(0.16, 1, 0.3, 1);
    z-index: 3;
}

/* Invisible hotspots on the art's slot circles — hover shows the landing
   halo + cost tooltip, click pays & slides the ring there. */
.board-ov-slot {
    position: absolute;
    top: 88%;
    width: 9.5%;
    aspect-ratio: 1;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    cursor: pointer;
    z-index: 4;
}
.board-ov-slot:hover {
    box-shadow: 0 0 0 2px rgba(240,210,120,0.9), 0 0 22px 6px rgba(201,168,76,0.45);
}
.board-ov-slot.current { cursor: default; }
.board-ov-slot.current:hover { box-shadow: none; }

/* Pick-a-slot mode (⇄ Discard: Slide Ring) — the circles one step from
   the ring glow and take the click; everything farther is dead. */
.board-ov-slot.pickable {
    animation: slotPulse 1.1s ease-in-out infinite;
}
.board-ov-slot.dimmed { pointer-events: none; cursor: default; }
@keyframes slotPulse {
    0%, 100% { box-shadow: 0 0 0 3px rgba(240,210,120,0.95), 0 0 26px 8px rgba(201,168,76,0.55); }
    50%      { box-shadow: 0 0 0 3px rgba(240,210,120,0.65), 0 0 36px 14px rgba(201,168,76,0.3); }
}

/* Paid mode: circles a slide can reach right now (gold + direction) wear
   a quiet standing halo — the pulse stays the discard-picker's language.
   Blocked circles still take the tap (a notification says why). */
.board-ov-slot.reach {
    box-shadow: 0 0 0 2px rgba(240,210,120,0.5), 0 0 14px 3px rgba(201,168,76,0.28);
}
.board-ov-slot.reach:hover, .board-ov-slot.snap {
    box-shadow: 0 0 0 2px rgba(240,210,120,0.95), 0 0 24px 7px rgba(201,168,76,0.5);
}
.board-ov-slot.blocked { cursor: default; }
.board-ov-slot.blocked:hover { box-shadow: none; }

/* While the ring is in hand, EVERY circle shows itself: gold = payable
   right now, grey = it exists but the drop would be refused (gold short /
   direction lock). The circle under the finger answers louder: gold snap
   halo if the drop will take, red if the ring will bounce home. */
#boardOvSlots.dragging .board-ov-slot:not(.current) {
    box-shadow: 0 0 0 2px rgba(205,195,175,0.35), 0 0 10px 2px rgba(0,0,0,0.3);
}
#boardOvSlots.dragging .board-ov-slot.reach {
    box-shadow: 0 0 0 2px rgba(240,210,120,0.75), 0 0 16px 4px rgba(201,168,76,0.42);
}
#boardOvSlots.dragging .board-ov-slot.snap {
    box-shadow: 0 0 0 3px rgba(240,210,120,0.98), 0 0 26px 8px rgba(201,168,76,0.55);
}
#boardOvSlots.dragging .board-ov-slot.snap-bad {
    box-shadow: 0 0 0 3px rgba(224,92,70,0.9), 0 0 20px 6px rgba(200,60,40,0.45);
}

/* The ring is grabbable in paid mode — raised above the hotspots so the
   grab wins; while a slide waits on its confirm it pulses on the target. */
.board-ov-ring.grab { pointer-events: auto; cursor: grab; z-index: 5; touch-action: none; }
.board-ov-ring.dragging { transition: none; cursor: grabbing; transform: translate(-50%, -50%) scale(1.1); }
.board-ov-ring.pending { animation: ringPending 1.1s ease-in-out infinite; }
@keyframes ringPending {
    0%, 100% { filter: drop-shadow(0 2px 5px rgba(0,0,0,0.65)) drop-shadow(0 0 5px rgba(240,210,120,0.95)); }
    50%      { filter: drop-shadow(0 2px 5px rgba(0,0,0,0.65)) drop-shadow(0 0 15px rgba(240,210,120,0.55)); }
}

/* Home marker while the ring is out on a preview/drag. */
.board-ov-ghost {
    position: absolute;
    top: 88%;
    width: 9%;
    aspect-ratio: 1;
    transform: translate(-50%, -50%);
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.25s;
    z-index: 2;
}
.board-ov-ghost.show { opacity: 0.35; }

/* Pay-&-slide confirm chip — anchored INSIDE the board art, just above
   the target circle (the old fixed-position bubble hung above the board
   RECT and rendered off-screen on phones). Reuses the .sc-bubble skin. */
#boardOvConfirm {
    position: absolute;
    display: none;
    transform: translate(-50%, -100%);
    line-height: 1.3;
    z-index: 6;
}
#boardOvConfirm.active { display: block; }

.board-ov-hint {
    margin-top: 6px;
    font-family: 'EB Garamond', serif;
    font-size: 15px;
    color: var(--gold-light);
    letter-spacing: 0.5px;
    min-height: 18px;
    text-shadow: 0 0 18px rgba(201,168,76,0.35);
}

.board-ov-name {
    margin-top: 16px;
    font-family: 'Cinzel', serif;
    font-size: 24px;
    color: var(--gold-light);
    letter-spacing: 5px;
    text-shadow: 0 0 30px rgba(201,168,76,0.2);
}

.board-ov-sub {
    font-family: 'EB Garamond', serif;
    font-size: 14px;
    color: rgba(240,230,211,0.35);
    font-style: italic;
    margin-top: 4px;
}

/* ── Hand Inspect Overlay ── */

.hand-inspect-overlay {
    position: fixed;
    inset: 0;
    z-index: 10000;
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: rgba(14,7,2,0.95);
    backdrop-filter: blur(16px);
}
.hand-inspect-overlay.active { display: flex; }

.hand-ov-spread {
    display: flex;
    gap: 16px;
    align-items: flex-end;
    animation: ovFan 0.4s cubic-bezier(0.16,1,0.3,1);
}

.hand-ov-spread .ov-hand-card {
    width: 150px;
    height: 210px;
    border-radius: 6px;
    box-shadow: 0 6px 24px rgba(0,0,0,0.6);
    object-fit: cover;
    transition: transform 0.25s ease;
    cursor: default;
}

.hand-ov-spread .ov-hand-card:hover {
    transform: translateY(-12px) scale(1.06);
    box-shadow: 0 12px 40px rgba(0,0,0,0.7), 0 0 24px rgba(201,168,76,0.1);
}

.hand-ov-label {
    margin-top: 20px;
    font-family: 'Cinzel', serif;
    font-size: 12px;
    color: var(--gold-dark);
    letter-spacing: 3px;
    text-transform: uppercase;
}

/* ── Opponent Overlay ── */

.opp-overlay {
    position: fixed;
    inset: 0;
    z-index: 10002;
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: rgba(14,7,2,0.96);
    backdrop-filter: blur(20px);
}
.opp-overlay.active { display: flex; }

.opp-ov-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.opp-ov-header {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-bottom: 24px;
    animation: ovZoom 0.4s cubic-bezier(0.16,1,0.3,1);
}

.opp-ov-avatar {
    width: 60px;
    height: 60px;
    border-radius: 50%;
    object-fit: cover;
    border: 2px solid var(--gold);
    box-shadow: 0 0 30px rgba(201, 168, 76, 0.15);
}

.opp-ov-name {
    font-family: 'Cinzel', serif;
    font-size: 26px;
    color: var(--gold-light);
    letter-spacing: 4px;
}

.opp-ov-stats {
    display: flex;
    gap: 8px;
    margin-top: 6px;
}

/* Phone chip rail — hidden on desktop (the panel below carries it) */
.opp-ov-chips { display: none; }

/* Middle row: their variables (left) + their board (right). The panel
   reads exactly like your own left-rail panel — same classes, same
   token art — just without the fixed positioning. */
.opp-ov-mid {
    display: flex;
    align-items: center;
    gap: 22px;
    margin-bottom: 20px;
}
.opp-ov-panel {
    width: 250px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 10px;
    border-radius: 10px;
    background:
        linear-gradient(160deg, var(--wood-darker) 0%, var(--wood-deepest) 100%);
    border: 2px solid var(--gold-dark);
    box-shadow:
        inset 0 2px 8px rgba(0,0,0,0.6),
        inset 0 -1px 3px rgba(255,190,90,0.04),
        0 4px 16px rgba(0,0,0,0.5);
    max-height: 76vh;
    overflow-y: auto;
    animation: ovZoom 0.4s cubic-bezier(0.16,1,0.3,1);
}

/* Board + ring on BOTH layouts: with the ring-dots gone from the rail,
   the overlay board is where a rival's position lives. The wrapper is
   position:relative so the %-based ring rides the art (phone media block
   re-tunes sizes for its side-by-side layout). Stacks stay phone-only —
   desktop keeps the big inline cards panel. */
.opp-ov-boardwrap {
    display: block;
    position: relative;
    line-height: 0;
    animation: ovZoom 0.45s cubic-bezier(0.16,1,0.3,1);
}
.opp-ov-ring {
    display: block;
    position: absolute;
    width: 11%;
    aspect-ratio: 1;
    transform: translate(-50%, -50%);
    pointer-events: none;
    filter: drop-shadow(0 1px 2px rgba(0,0,0,0.6));
}
.opp-ov-stacks { display: none; }

.opp-ov-board {
    display: block;
    max-width: 70vw;
    max-height: 42vh;   /* the board IS their sheet — let it breathe */
    border-radius: 10px;
    box-shadow: 0 8px 40px rgba(0,0,0,0.5);
    animation: none;    /* the wrapper animates so the ring rides along */
}

.opp-ov-section-label {
    font-family: 'Cinzel', serif;
    font-size: 10px;
    color: var(--gold-dark);
    letter-spacing: 3px;
    text-transform: uppercase;
    margin-bottom: 12px;
}

.opp-ov-cards {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
    justify-content: center;
    animation: ovFan 0.45s cubic-bezier(0.16,1,0.3,1);
}

/* Toggle + panel: desktop keeps cards inline (toggle/close hidden);
   landscape swaps to a button-revealed centered panel (see media query). */
.opp-ov-toggle,
.opp-ov-cards-close { display: none; }
.opp-ov-cards-panel {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.opp-ov-card-wrap {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    transition: transform 0.25s;
}

.opp-ov-card-wrap:hover { transform: translateY(-8px); }

.opp-ov-card-wrap img {
    width: 150px;
    height: 225px;      /* true 2:3 card ratio — no cropped art */
    border-radius: 6px;
    box-shadow: 0 6px 24px rgba(0,0,0,0.6);
    object-fit: cover;
    transition: box-shadow 0.2s;
}

.opp-ov-card-wrap:hover img {
    box-shadow: 0 10px 40px rgba(201,168,76,0.15), 0 6px 24px rgba(0,0,0,0.6);
}

.lend-btn {
    font-family: 'Cinzel', serif;
    font-size: 9px;
    color: var(--gold-dark);
    letter-spacing: 1px;
    padding: 4px 12px;
    border-radius: 12px;
    border: 1px solid rgba(201, 168, 76, 0.2);
    background: rgba(201, 168, 76, 0.06);
    cursor: pointer;
    transition: all 0.2s;
    opacity: 0;
    white-space: nowrap;
}

.opp-ov-card-wrap:hover .lend-btn { opacity: 1; }

.lend-btn:hover {
    color: var(--gold-light);
    border-color: var(--gold);
    background: rgba(201, 168, 76, 0.12);
}

/* ── Mission Browser — the whole row of missions, one in focus ── */

.mission-lb {
    position: fixed;
    inset: 0;
    z-index: 10000;
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: rgba(14,7,2,0.94);
    backdrop-filter: blur(16px);
}
.mission-lb.active { display: flex; }

.mb-title {
    font-family: 'Cinzel', serif;
    font-size: 13px;
    color: var(--gold-dark);
    letter-spacing: 4px;
    text-transform: uppercase;
    margin-bottom: 4px;
    animation: ovZoom 0.3s ease;
}

/* The film strip: half-viewport inline padding lets the first and last
   cards reach dead center; JS settles the nearest card there on idle. */
.mb-track {
    display: flex;
    align-items: center;
    gap: clamp(16px, 3vw, 36px);
    width: 100vw;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    padding: 26px 50vw;
    scrollbar-width: none;
}
.mb-track::-webkit-scrollbar { display: none; }

.mb-card {
    position: relative;
    flex: 0 0 auto;
    cursor: pointer;
    opacity: 0.5;
    transform: scale(0.84);
    transition: transform 0.32s cubic-bezier(0.16,1,0.3,1), opacity 0.32s;
}
.mb-card img {
    display: block;
    height: min(62vh, 560px);
    border-radius: 12px;
    box-shadow: 0 14px 50px rgba(0,0,0,0.75);
    -webkit-user-drag: none;
}
.mb-card.focus {
    opacity: 1;
    transform: scale(1);
}
.mb-card.focus img {
    box-shadow: 0 0 80px rgba(201,168,76,0.14), 0 20px 60px rgba(0,0,0,0.8);
}
.mb-card.done img { outline: 2px solid rgba(76,175,80,0.55); }
.mb-done-ribbon {
    position: absolute;
    top: 10px;
    left: 50%;
    transform: translateX(-50%);
    font-family: 'Cinzel', serif;
    font-size: 10px;
    letter-spacing: 2px;
    color: #cfe8cf;
    background: rgba(30,70,34,0.9);
    border: 1px solid rgba(76,175,80,0.6);
    border-radius: 10px;
    padding: 3px 10px;
    pointer-events: none;
}

.mb-nav {
    position: fixed;
    top: 50%;
    transform: translateY(-50%);
    width: 52px;
    height: 52px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Cinzel', serif;
    font-size: 34px;
    line-height: 1;
    color: var(--gold);
    background: rgba(20,10,4,0.75);
    border: 1px solid rgba(201,168,76,0.35);
    border-radius: 50%;
    cursor: pointer;
    user-select: none;
    transition: all 0.2s;
    z-index: 3;
}
.mb-nav:hover { color: var(--gold-light); border-color: var(--gold); }
.mb-nav.prev { left: 26px; }
.mb-nav.next { right: 26px; }
.mission-lb.mb-solo .mb-nav { display: none; }

/* ── Mission Journal — a royal ledger, rolled at both ends ── */

.mission-journal {
    position: fixed;
    inset: 0;
    z-index: 9998;   /* below the browser (10000) — tapping a card layers it on top */
    display: none;
    align-items: center;
    justify-content: center;
    background: rgba(14,7,2,0.9);
    backdrop-filter: blur(14px);
}
.mission-journal.active { display: flex; }

.mj-scroll {
    position: relative;
    display: flex;
    flex-direction: column;
    width: min(880px, 92vw);
    max-height: 88dvh;
    background: linear-gradient(175deg, #2e1c0e 0%, #241407 45%, #1a0d05 100%);
    border: 2px solid var(--gold-dark);
    border-radius: 14px;
    box-shadow:
        0 0 0 1px rgba(0,0,0,0.6),
        0 30px 90px rgba(0,0,0,0.75),
        inset 0 1px 0 rgba(232,212,139,0.14);
    overflow: hidden;
    animation: ovZoom 0.4s cubic-bezier(0.16,1,0.3,1);
}

/* Rolled parchment ends — a slim wooden cylinder top and bottom. */
.mj-roller {
    flex: 0 0 auto;
    height: 13px;
    background: linear-gradient(180deg, #4a2f16 0%, #6b4a24 30%, #2a1708 100%);
    border-bottom: 1px solid rgba(201,168,76,0.35);
    box-shadow: inset 0 -3px 6px rgba(0,0,0,0.55), inset 0 2px 3px rgba(255,215,130,0.18);
}
.mj-roller.bottom {
    border-bottom: none;
    border-top: 1px solid rgba(201,168,76,0.35);
    background: linear-gradient(0deg, #4a2f16 0%, #6b4a24 30%, #2a1708 100%);
}

.mj-head {
    flex: 0 0 auto;
    text-align: center;
    padding: 12px 20px 8px;
    border-bottom: 1px double rgba(201,168,76,0.3);
}
.mj-title {
    font-family: 'Cinzel', serif;
    font-size: 20px;
    font-weight: 700;
    letter-spacing: 6px;
    text-transform: uppercase;
    color: var(--gold-light);
    text-shadow: 0 0 22px rgba(201,168,76,0.35);
}

.mj-body {
    overflow-y: auto;
    padding: 12px 24px 16px;
}

.mj-section + .mj-section { margin-top: 14px; }
.mj-section-title {
    font-family: 'Cinzel', serif;
    font-size: 12px;
    letter-spacing: 3px;
    text-transform: uppercase;
    color: var(--gold-dark);
    padding-bottom: 5px;
    margin-bottom: 12px;
    border-bottom: 1px solid rgba(201,168,76,0.15);
}

.mj-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 18px;
}

.mj-card {
    position: relative;
    cursor: pointer;
    text-align: center;
    transition: transform 0.22s;
}
.mj-card:hover { transform: translateY(-6px); }
.mj-card img {
    display: block;
    height: clamp(190px, 30vh, 300px);
    border-radius: 9px;
    border: 1px solid rgba(201,168,76,0.35);
    box-shadow: 0 8px 26px rgba(0,0,0,0.6);
    -webkit-user-drag: none;
}
.mj-card:hover img { box-shadow: 0 12px 34px rgba(201,168,76,0.18), 0 8px 26px rgba(0,0,0,0.6); }
.mj-card.done img { outline: 2px solid rgba(76,175,80,0.5); opacity: 0.92; }

.mj-due {
    margin-top: 6px;
    font-family: 'EB Garamond', serif;
    font-style: italic;
    font-size: 13px;
    color: rgba(240,230,211,0.7);
}
.mj-ribbon {
    position: absolute;
    top: 8px;
    left: 50%;
    transform: translateX(-50%);
    font-family: 'Cinzel', serif;
    font-size: 9px;
    letter-spacing: 2px;
    color: #cfe8cf;
    background: rgba(30,70,34,0.92);
    border: 1px solid rgba(76,175,80,0.6);
    border-radius: 10px;
    padding: 3px 10px;
    pointer-events: none;
}
.mj-empty {
    font-family: 'EB Garamond', serif;
    font-style: italic;
    font-size: 14px;
    color: rgba(240,230,211,0.5);
    padding: 4px 0 8px;
}

/* Desktop strip head: the at-a-glance pips stay; Journal opens the ledger. */
.mission-strip-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}
.mj-open {
    font-family: 'Cinzel', serif;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: var(--gold);
    background: rgba(201,168,76,0.07);
    border: 1px solid rgba(201,168,76,0.3);
    border-radius: 9px;
    padding: 3px 10px;
    cursor: pointer;
    transition: all 0.2s;
}
.mj-open:hover { color: var(--gold-light); border-color: var(--gold); background: rgba(201,168,76,0.14); }

.mission-lb-label {
    position: absolute;
    bottom: 36px;
    left: 50%;
    transform: translateX(-50%);
    text-align: center;
    font-family: 'Cinzel', serif;
    font-size: 16px;
    color: var(--gold-light);
    letter-spacing: 3px;
}

/* Turn-in row: shown only for YOUR active missions during gameplay. */
.mission-lb-action {
    position: absolute;
    bottom: 70px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 7px;
    z-index: 2;
}
.mission-lb-action:empty { display: none; }
.mission-lb-due {
    font-family: 'EB Garamond', serif;
    font-style: italic;
    font-size: 13px;
    color: rgba(240,230,211,0.65);
    text-shadow: 0 2px 6px rgba(0,0,0,0.8);
}

/* ── Lend Toast ── */

.lend-toast {
    position: fixed;
    bottom: 40px;
    left: 50%;
    transform: translateX(-50%);
    font-family: 'Cinzel', serif;
    font-size: 13px;
    color: var(--gold-light);
    letter-spacing: 2px;
    padding: 12px 28px;
    border-radius: 12px;
    background: rgba(42,22,10,0.97);
    border: 1px solid var(--gold);
    box-shadow: 0 8px 40px rgba(201, 168, 76, 0.2);
    z-index: 10003;
    display: none;
    animation: toastIn 0.3s ease;
}
.lend-toast.active { display: block; }

/* ── Overlay Animations ── */

@keyframes ovZoom {
    from { transform: scale(0.5) translateY(120px); opacity: 0; }
    to { transform: scale(1) translateY(0); opacity: 1; }
}

@keyframes ovFan {
    from { transform: translateY(80px) scale(0.85); opacity: 0; }
    to { transform: translateY(0) scale(1); opacity: 1; }
}

@keyframes toastIn {
    from { transform: translateX(-50%) translateY(20px); opacity: 0; }
    to { transform: translateX(-50%) translateY(0); opacity: 1; }
}

/* ─── CARD ZOOM OVERLAY ────────────────────────────────── */

.card-zoom {
    position: fixed;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.85);
    z-index: 2000;
    cursor: pointer;
}

.card-zoom.active { display: flex; }

.card-zoom img {
    max-height: 85vh;
    max-width: 90vw;
    border-radius: 12px;
    box-shadow: 0 0 80px rgba(201, 168, 76, 0.4);
}

/* ─── ACTION PANEL ─────────────────────────────────────── */

.action-panel {
    position: fixed;
    bottom: calc(var(--handCardH) + 47px); /* clears the hand zone at any size */
    left: 50%;
    transform: translateX(-50%);
    display: none;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 20px 30px;
    background: linear-gradient(180deg, rgba(55, 35, 20, 0.98) 0%, rgba(40, 22, 35, 0.98) 100%);
    border: 2px solid var(--gold-light);
    border-radius: 12px;
    box-shadow: 0 0 0 1px rgba(201, 168, 76, 0.3), 0 0 50px rgba(201, 168, 76, 0.45), 0 8px 32px rgba(0, 0, 0, 0.7);
    z-index: 9999;
    min-width: 280px;
}

.action-panel.active { display: flex; }

/* ─── LOG PANEL ────────────────────────────────────────── */

.game-log {
    position: fixed;
    right: 0;
    top: 0;
    bottom: 0;
    width: 280px;
    background: rgba(22,10,3,0.93);
    border-left: 1px solid rgba(90,61,43,0.4);
    padding: 16px;
    overflow-y: auto;
    font-size: 13px;
    line-height: 1.6;
    z-index: 400;
    transform: translateX(100%);
    transition: transform 0.3s ease;
}

.game-log.open { transform: translateX(0); }

.game-log .entry {
    padding: 4px 0;
    border-bottom: 1px solid rgba(201, 168, 76, 0.05);
    color: var(--text-light);
    opacity: 0.7;
}

/* ─── SCORING SCREEN ───────────────────────────────────── */

#scoring-screen {
    position: fixed;
    inset: 0;
    display: none;
    flex-direction: column;
    align-items: center;
    background: linear-gradient(180deg, var(--royal-deep) 0%, #0a0612 100%);
    z-index: 950;
    overflow-y: auto; /* short screens scroll instead of clipping */
}

#scoring-screen.active { display: flex; }

/* margin:auto centers when the content fits and scrolls when it doesn't —
   justify-content:center would clip the top on short screens. */
#scoringContent {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin: auto;
    padding: 16px;
    max-width: 100vw;
}

.scoring-title {
    font-family: 'Cinzel', serif;
    color: var(--gold);
    font-size: 28px;
    margin: 20px 0;
    text-align: center;
}

.scoring-sub {
    color: var(--text-light);
    opacity: 0.7;
    margin-bottom: 20px;
}

/* ── Victory ceremony — headline, deltas, placement ladder ── */

.vs-head {
    position: relative;
    overflow: hidden;
    text-align: center;
    padding: 26px 46px 18px;
    border-radius: 16px;
    max-width: min(720px, 94vw);
}
.vs-head.win {
    background: radial-gradient(ellipse 90% 85% at 50% 0%, rgba(232, 195, 75, 0.13), transparent 65%);
}
.vs-head .champ-rays { inset: -120% -60%; }
.vs-headline {
    position: relative;
    font-family: 'Cinzel Decorative', 'Cinzel', serif;
    font-size: clamp(24px, 5vw, 42px);
    font-weight: 700;
    letter-spacing: 2px;
    color: var(--gold);
    text-shadow: 0 0 34px rgba(232, 195, 75, 0.45);
}
.vs-head.win .vs-headline {
    color: #f4dd8f;
    text-shadow: 0 0 40px rgba(232, 195, 75, 0.65);
}
.vs-personal {
    position: relative;
    font-family: 'EB Garamond', serif;
    font-style: italic;
    font-size: clamp(14px, 2.2vw, 19px);
    color: var(--parchment-dark);
    margin-top: 7px;
}

/* The tie explainer — only ever drawn when a tie decided your placement.
   Gold-lit so it reads as the reason for the standing, not as flavor. */
.vs-tiebreak {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 9px;
    margin-top: 10px;
    padding: 7px 15px;
    max-width: 100%;
    border: 1px solid rgba(201, 168, 76, 0.5);
    border-radius: 11px;
    background: linear-gradient(180deg, rgba(60, 40, 14, 0.5), rgba(30, 18, 7, 0.6));
    font-family: 'EB Garamond', serif;
    font-size: clamp(13px, 1.9vw, 16px);
    color: var(--parchment-dark);
    text-align: left;
}
.vs-tiebreak img { width: 22px; height: 22px; flex: 0 0 22px; object-fit: contain; }
.vs-tiebreak b { color: var(--gold-light); font-weight: 700; }

.vs-deltas {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    justify-content: center;
    margin: 12px 0 4px;
}
.vs-delta {
    display: flex;
    align-items: baseline;
    gap: 9px;
    font-family: 'Cinzel', serif;
    font-size: clamp(15px, 2.4vw, 20px);
    padding: 9px 20px;
    border: 1px solid rgba(201, 168, 76, 0.45);
    border-radius: 12px;
    background: linear-gradient(180deg, rgba(60, 40, 14, 0.55), rgba(30, 18, 7, 0.65));
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
}
.vs-delta b { color: var(--gold-light); font-size: 1.3em; }
.vs-delta.stars b { color: #ffd97a; }
.vs-d-what { color: var(--gold); letter-spacing: 1px; }
.vs-d-arrow { color: var(--parchment-dark); opacity: 0.8; }
/* The fellowship note rides INSIDE the Stars chip, on its own line. */
.vs-delta.stars { flex-wrap: wrap; }
.vs-d-fellow {
    flex-basis: 100%;
    text-align: center;
    font-size: 0.58em;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: #ffd97a;
    opacity: 0.85;
}

/* ── The Score Sheet — the box's tally grid recreated: heirs across,
   color-coded categories down, chunky numbers, one glance tells all. ── */
.vs-trophy { width: 22px; height: 22px; flex: 0 0 22px; }

.vs-grid {
    display: grid;
    grid-template-columns: minmax(96px, auto) repeat(var(--vsgCols, 5), minmax(64px, 1fr));
    gap: 4px;
    margin: 18px auto 4px;
    width: min(720px, 94vw);
    font-family: 'Cinzel', serif;
}
.vsg-head {
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: 4px 4px 6px; min-width: 0;
}
.vsg-face {
    width: 40px; height: 40px; border-radius: 50%; object-fit: cover;
    object-position: top; border: 2px solid rgba(201, 168, 76, 0.45);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
}
.vsg-head.win .vsg-face { border-color: #e8c34b; box-shadow: 0 0 14px rgba(232, 195, 75, 0.5); }
.vsg-ord {
    display: inline-flex; align-items: center; gap: 3px;
    font-size: 10px; font-weight: 700; letter-spacing: 1px; color: #8d8578;
}
.vsg-ord .vs-trophy { width: 13px; height: 13px; flex: 0 0 13px; }
.vsg-hname {
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-size: 11px; letter-spacing: 0.5px; color: #e8dcc0;
}
.vsg-head.me .vsg-hname { color: #ffe9a8; font-weight: 700; }
.vsg-label {
    display: flex; align-items: center; gap: 7px;
    background: var(--rowC);
    background: linear-gradient(180deg, color-mix(in srgb, var(--rowC) 86%, #fff), var(--rowC));
    color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
    padding: 5px 10px; border-radius: 7px;
    border: 1px solid rgba(0, 0, 0, 0.35);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 2px 5px rgba(0, 0, 0, 0.35);
    font-size: 11px; font-weight: 700; letter-spacing: 1.5px; text-transform: uppercase;
}
.vsg-label img { width: 20px; height: 20px; object-fit: contain; filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.45)); }
.vsg-label.total { color: #3a3325; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.4); }
.vsg-cell {
    display: flex; align-items: center; justify-content: center;
    background: rgba(26, 17, 9, 0.72);
    background: color-mix(in srgb, var(--rowC, #c9a84c) 16%, rgba(26, 17, 9, 0.72));
    border: 1px solid rgba(201, 168, 76, 0.18);
    border-color: color-mix(in srgb, var(--rowC, #c9a84c) 32%, transparent);
    border-radius: 7px; padding: 4px;
    color: #f3e9d2; font-size: 16px; font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.vsg-cell.bad { color: #ff9d8a; }
.vsg-cell.win { box-shadow: inset 0 0 0 1px rgba(232, 195, 75, 0.4), 0 0 10px rgba(232, 195, 75, 0.12); }
.vsg-cell.total {
    background: rgba(239, 230, 207, 0.14);
    border-color: rgba(239, 230, 207, 0.45);
    font-size: 20px; color: #fff;
}
.vsg-cell.total.win { color: #f4dd8f; }
/* Gold · tiebreak — under the total, dimmed, because it is the reason for
   the order and never part of the score. The seats a tie actually caught
   light up; everyone else's coins stay quiet reference. */
.vsg-label.tiebreak { font-size: 9.5px; letter-spacing: 1.2px; }
.vsg-cell.tiebreak { font-size: 14px; color: #cdbf9f; opacity: 0.62; }
.vsg-cell.tiebreak.live {
    opacity: 1; color: #ffd97a;
    box-shadow: inset 0 0 0 1px rgba(232, 195, 75, 0.45);
}
@keyframes vsgIn {
    from { opacity: 0; transform: translateY(9px); }
    to { opacity: 1; transform: none; }
}
.vs-grid > * { animation: vsgIn 0.45s both; animation-delay: calc(var(--ri, 0) * 90ms + 250ms); }

/* Drillable score cells invite the tap; a breakdown opens over the sheet. */
.vsg-cell.drill { cursor: pointer; }
.vsg-cell.drill:hover { box-shadow: inset 0 0 0 2px rgba(232, 212, 139, 0.55); }
#scoreBreakdown {
    position: fixed; inset: 0; z-index: 970; display: none;
    align-items: center; justify-content: center;
    background: rgba(8, 5, 2, 0.82); backdrop-filter: blur(6px);
}
#scoreBreakdown.active { display: flex; animation: vsgFade 0.2s both; }
@keyframes vsgFade { from { opacity: 0; } to { opacity: 1; } }
.sb-inner {
    width: min(460px, 92vw); max-height: 82dvh; position: relative;
    display: flex; flex-direction: column;
    background: linear-gradient(#241b0f, #14100a);
    border: 2px solid var(--gold-dark); border-radius: 12px;
    padding: 16px 18px 14px; box-shadow: 0 24px 70px rgba(0, 0, 0, 0.7);
    animation: ovZoom 0.32s cubic-bezier(0.16, 1, 0.3, 1);
}
.sb-x { position: absolute; top: 9px; right: 12px; background: none; border: none; color: #a8926a; font-size: 18px; cursor: pointer; }
.sb-x:hover { color: #f0dfb8; }
.sb-head {
    font-family: 'Cinzel', serif; font-size: 15px; color: #f0dfb8; letter-spacing: 0.5px;
    padding: 0 22px 10px 0; border-bottom: 1px solid #3a2d17;
    display: flex; align-items: center; gap: 7px;
}
.sb-who { color: var(--gold-light); font-weight: 700; }
.sb-total { margin-left: auto; color: var(--gold-light); font-size: 15px; font-variant-numeric: tabular-nums; }
.sb-list { overflow-y: auto; padding-top: 10px; display: flex; flex-direction: column; gap: 6px; }
.sb-row { display: flex; align-items: center; gap: 14px; padding: 7px 2px; border-bottom: 1px solid rgba(201, 168, 76, 0.08); }
.sb-thumb { width: 58px; height: 80px; object-fit: cover; object-position: top; border-radius: 6px; flex: 0 0 auto; background: #120c06; box-shadow: 0 3px 9px rgba(0, 0, 0, 0.55); cursor: zoom-in; transition: transform .12s; }
.sb-thumb:hover { transform: scale(1.04); }
.sb-name { flex: 1; font-family: 'EB Garamond', serif; font-size: 15px; color: #e8d9bf; min-width: 0; }
.sb-val { font-family: 'Cinzel', serif; font-weight: 700; font-size: 15px; color: var(--gold-light); font-variant-numeric: tabular-nums; }
.sb-note { font-size: 12px; color: #9c8a68; font-style: italic; padding: 5px 2px; }

.scoring-scroll { max-width: 96vw; overflow-x: auto; }

.scoring-actions {
    margin: 22px 0 10px;
    display: flex;
    gap: 12px;
    justify-content: center;
    flex-wrap: wrap;
    /* Pinned so the way out is always on screen — no scrolling to leave. */
    position: sticky;
    bottom: 0;
    z-index: 3;
    padding: 14px 0 10px;
    width: 100%;
    background: linear-gradient(180deg, rgba(10,6,18,0) 0%, rgba(10,6,18,0.82) 42%, #0a0612 100%);
}

/* Always-visible corner exit — the obvious "leave the game" the score
   sheet never had (Wyatt 7/17). Fixed to the viewport, above the scroll. */
.vs-leave {
    position: fixed;
    top: max(12px, env(safe-area-inset-top));
    right: max(12px, env(safe-area-inset-right));
    z-index: 20;
    width: 42px; height: 42px;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 20px; line-height: 1;
    color: var(--gold-light);
    background: rgba(20, 12, 8, 0.7);
    border: 1.5px solid rgba(201, 168, 76, 0.5);
    cursor: pointer;
    backdrop-filter: blur(4px);
    transition: background 0.15s, border-color 0.15s, transform 0.15s;
}
.vs-leave:hover { background: rgba(139, 26, 26, 0.7); border-color: var(--gold); transform: scale(1.06); }

/* Narrow portrait: tighter sheet, scroll inside .scoring-scroll if needed. */
@media (max-width: 480px) {
    .vs-grid { grid-template-columns: minmax(78px, auto) repeat(var(--vsgCols, 5), minmax(52px, 1fr)); gap: 3px; }
    .vsg-cell { font-size: 13px; }
    .vsg-label { font-size: 9px; padding: 4px 7px; letter-spacing: 1px; gap: 5px; }
    .vsg-label img { width: 15px; height: 15px; }
}

/* Phone landscape: the whole sheet fits 844×390 under the headline. */
@media (max-height: 500px) {
    .vs-grid { gap: 3px; width: min(640px, 96vw); margin-top: 10px; }
    .vsg-face { width: 26px; height: 26px; }
    .vsg-hname { font-size: 9px; }
    .vsg-label { font-size: 9px; padding: 3px 7px; letter-spacing: 1px; gap: 5px; }
    .vsg-label img { width: 14px; height: 14px; }
    .vsg-cell { font-size: 12.5px; padding: 2px 3px; border-radius: 5px; }
    .vsg-cell.total { font-size: 15px; }
    .scoring-actions { margin: 12px 0 10px; }
}

/* ─── ANIMATIONS ───────────────────────────────────────── */

@keyframes fadeIn {
    from { opacity: 0; transform: translateY(20px); }
    to { opacity: 1; transform: translateY(0); }
}

@keyframes shimmer {
    0% { background-position: -200% center; }
    100% { background-position: 200% center; }
}

.fade-in { animation: fadeIn 0.6s ease forwards; }

/* ─── NOTIFICATIONS ───────────────────────────────────── */

#notifications {
    position: fixed;
    top: 70px;
    left: 50%;
    transform: translateX(-50%);
    /* Above the leaderboard/store panels (10005) so queue verdicts land
       over an open menu surface; below the pp overlay (10550) and the
       MATCH FOUND ring (10560). */
    z-index: 10520;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    pointer-events: none;
}

.game-toast {
    padding: 10px 24px;
    border-radius: 6px;
    font-family: 'Cinzel', serif;
    font-size: 14px;
    letter-spacing: 1px;
    opacity: 0;
    transform: translateY(-10px);
    transition: all 0.3s ease;
    pointer-events: auto;
    max-width: 500px;
    text-align: center;
    /* Long announcements (Emblem passes, the Queen's boon) wrap inside
       the box — nowrap let them ghost past the gold edge. Short toasts
       under the max-width still read as one line. */
    white-space: normal;
    line-height: 1.4;
}

.game-toast.show { opacity: 1; transform: translateY(0); }
.game-toast.fade-out { opacity: 0; transform: translateY(-20px); }

.game-toast.play {
    background: rgba(76, 175, 80, 0.92);
    color: white;
    border: 1px solid rgba(129, 199, 132, 0.6);
}

.game-toast.discard {
    background: rgba(201, 168, 76, 0.92);
    color: var(--royal-deep);
    border: 1px solid var(--gold-light);
}

.game-toast.error {
    background: rgba(239, 83, 80, 0.92);
    color: white;
    border: 1px solid rgba(239, 83, 80, 0.6);
}

.game-toast.mission {
    background: rgba(171, 71, 188, 0.92);
    color: white;
    border: 1px solid rgba(206, 147, 216, 0.6);
}

.game-toast.melee {
    background: rgba(244, 67, 54, 0.92);
    color: white;
    border: 1px solid rgba(244, 67, 54, 0.6);
}

.game-toast.act {
    background: rgba(201, 168, 76, 0.95);
    color: var(--royal-deep);
    border: 1px solid var(--gold-light);
    font-size: 18px;
    font-weight: 700;
    padding: 14px 32px;
}

.game-toast.info {
    background: rgba(42,22,10,0.95);
    color: var(--gold);
    border: 1px solid rgba(201, 168, 76, 0.3);
}

/* ─── LOG TOGGLE ──────────────────────────────────────── */

.log-toggle {
    position: fixed;
    top: 20px;
    right: 74px;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: 1px solid rgba(201, 168, 76, 0.3);
    background: rgba(10, 6, 18, 0.8);
    color: var(--gold);
    font-size: 18px;
    cursor: pointer;
    z-index: 1001;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s ease;
}

/* No game yet, nothing to log: hidden pre-game (the profile chip owns the
   corner); in-game it rides left of the sidebar beside the music note. */
.log-toggle { display: none; }
body:has(#game-screen.active) .log-toggle { display: flex; right: 294px; }

.log-toggle:hover {
    border-color: var(--gold);
    box-shadow: 0 0 15px rgba(201, 168, 76, 0.3);
}

/* ─── GAME LOG ENTRIES ────────────────────────────────── */

.game-log .log-entry {
    padding: 4px 0;
    border-bottom: 1px solid rgba(201, 168, 76, 0.05);
    color: var(--text-light);
    opacity: 0.7;
    font-size: 12px;
    line-height: 1.5;
}

/* ─── ACTION PANEL DETAILS ────────────────────────────── */

.action-header {
    text-align: center;
    margin-bottom: 6px;
}

.action-card-name {
    font-family: 'Cinzel', serif;
    font-size: 16px;
    color: var(--gold);
    font-weight: 700;
}

.action-card-type {
    font-size: 11px;
    color: var(--text-light);
    opacity: 0.5;
    text-transform: uppercase;
    letter-spacing: 2px;
    margin-top: 2px;
}

.action-skills {
    font-size: 13px;
    color: #4fc3f7;
    margin-top: 4px;
}

.action-rewards {
    font-size: 13px;
    color: #81c784;
    margin-top: 2px;
}

/* Small-caps prefix labels on the panel's summary lines (Grants/Gains/Price) */
.ap-lbl {
    font-size: 9.5px;
    color: var(--text-light);
    opacity: 0.55;
    text-transform: uppercase;
    letter-spacing: 1.5px;
    margin-right: 7px;
}

/* Special-ability sentence — the card's power in plain words */
.action-special {
    font-size: 12.5px;
    color: #d8b4fe;
    font-style: italic;
    margin-top: 3px;
    max-width: 300px;
}

/* The price line stays visible on EVERY layout — a hidden price is a trap */
.action-price {
    font-size: 13px;
    color: #e85454;
    margin-top: 2px;
}

.action-buttons {
    display: flex;
    flex-direction: column;
    gap: 8px;
    width: 100%;
    margin-top: 6px;
}

.action-btn {
    padding: 10px 20px !important;
    min-width: unset !important;
    font-size: 13px !important;
    letter-spacing: 1px !important;
}

/* ─── PLAYED CARDS (player board) ─────────────────────── */

.played-card {
    width: 45px;
    height: 63px;
    border-radius: 4px;
    border: 1px solid rgba(201, 168, 76, 0.3);
    overflow: hidden;
    cursor: pointer;
    transition: all 0.2s ease;
    flex-shrink: 0;
}

.played-card:hover {
    border-color: var(--gold);
    transform: scale(1.15);
    z-index: 5;
    box-shadow: 0 0 10px rgba(201, 168, 76, 0.3);
}

.played-card img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ─── MISSION SELECT OVERLAY ─────────────────────────── */

.mission-select-overlay {
    position: fixed;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.88);
    z-index: 1800;
}

.mission-select-overlay.active { display: flex; }

.mission-select-content { text-align: center; }

.mission-options {
    display: flex;
    gap: 24px;
    justify-content: center;
    margin-top: 20px;
}

.mission-option {
    cursor: pointer;
    transition: all 0.3s ease;
    padding: 12px;
    border: 2px solid rgba(201, 168, 76, 0.2);
    border-radius: 10px;
    background:
        linear-gradient(160deg, rgba(61,40,23,0.75) 0%, rgba(42,26,16,0.65) 100%);
}

.mission-option:hover {
    border-color: var(--gold);
    box-shadow: 0 0 30px rgba(201, 168, 76, 0.4);
    transform: translateY(-8px) scale(1.03);
}

.mission-option img {
    width: 150px;
    border-radius: 8px;
}

/* ─── CINEMATIC CARD SPOTLIGHT ─────────────────────────── */

.card-spotlight {
    position: fixed;
    inset: 0;
    z-index: 10000;
    display: none;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    cursor: pointer;
    opacity: 0;
    transition: opacity calc(0.3s * var(--cinematic-speed, 1)) ease;
}

.card-spotlight.active {
    display: flex;
}

.card-spotlight.visible {
    opacity: 1;
}

/* Dark vignette backdrop */
.spotlight-backdrop {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(ellipse at center, rgba(0,0,0,0.88) 0%, rgba(0,0,0,0.95) 70%, rgba(0,0,0,0.98) 100%);
    backdrop-filter: blur(5px);
    -webkit-backdrop-filter: blur(5px);
    animation: spotlightFadeIn calc(0.3s * var(--cinematic-speed, 1)) ease-out forwards;
}

@keyframes spotlightFadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes spotlightPlayerIn {
    from { opacity: 0; transform: translateY(-20px); }
    to { opacity: 0.8; transform: translateY(0); }
}

/* Card image container — the star of the moment, height-driven BIG.
   333×500 scans go soft past ~680px tall, so cap there (same soft cap
   as the hand bloom). */
.spotlight-card {
    position: relative;
    z-index: 1;
    height: min(560px, 56vh);
    aspect-ratio: 2 / 3;
    max-width: 86vw;
    border-radius: 12px;
    overflow: hidden;
    box-shadow:
        0 0 0 2px var(--gold),
        0 0 60px rgba(201, 168, 76, 0.5),
        0 0 120px rgba(201, 168, 76, 0.2),
        0 30px 80px rgba(0, 0, 0, 0.8);
    transform: scale(0.3) rotateY(90deg);
    opacity: 0;
    animation: cardReveal calc(0.5s * var(--cinematic-speed, 1)) cubic-bezier(0.34, 1.56, 0.64, 1) calc(0.1s * var(--cinematic-speed, 1)) forwards;
}

.spotlight-card img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

@keyframes cardReveal {
    0% {
        transform: scale(0.3) rotateY(90deg);
        opacity: 0;
    }
    50% {
        transform: scale(1.08) rotateY(0deg);
        opacity: 1;
    }
    100% {
        transform: scale(1.0) rotateY(0deg);
        opacity: 1;
    }
}

/* Gold shimmer sweep across the card */
.spotlight-card::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(
        105deg,
        transparent 40%,
        rgba(201, 168, 76, 0.25) 45%,
        rgba(201, 168, 76, 0.4) 50%,
        rgba(201, 168, 76, 0.25) 55%,
        transparent 60%
    );
    transform: translateX(-150%);
    animation: spotlightShimmer calc(0.8s * var(--cinematic-speed, 1)) ease-out calc(0.5s * var(--cinematic-speed, 1)) forwards;
    pointer-events: none;
}

@keyframes spotlightShimmer {
    from { transform: translateX(-150%); }
    to { transform: translateX(150%); }
}

/* Card name with gold glow */
.spotlight-name {
    position: relative;
    z-index: 2;
    font-family: 'Cinzel', serif;
    font-weight: 900;
    font-size: clamp(22px, 4vw, 36px);
    color: var(--gold-light);
    text-shadow:
        0 0 10px rgba(201, 168, 76, 0.8),
        0 0 30px rgba(201, 168, 76, 0.4),
        0 0 60px rgba(201, 168, 76, 0.2);
    letter-spacing: 3px;
    text-transform: uppercase;
    margin-top: 20px;
    opacity: 0;
    animation: spotlightNameIn calc(0.4s * var(--cinematic-speed, 1)) ease-out calc(0.4s * var(--cinematic-speed, 1)) forwards;
}

@keyframes spotlightNameIn {
    from { opacity: 0; transform: translateY(15px) scale(0.9); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes spotlightEffectIn {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 0.85; transform: translateY(0); }
}

/* Spotlight dismiss hint */
.spotlight-dismiss {
    position: absolute;
    bottom: 30px;
    left: 50%;
    transform: translateX(-50%);
    font-family: 'EB Garamond', serif;
    font-size: 13px;
    color: rgba(201, 168, 76, 0.3);
    letter-spacing: 2px;
    opacity: 0;
    animation: spotlightDismissIn calc(0.3s * var(--cinematic-speed, 1)) ease-out calc(1.2s * var(--cinematic-speed, 1)) forwards;
}

@keyframes spotlightDismissIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* Spotlight exit animation */
.card-spotlight.exiting .spotlight-card {
    animation: cardExit calc(0.3s * var(--cinematic-speed, 1)) ease-in forwards;
}

.card-spotlight.exiting .spotlight-backdrop {
    animation: spotlightFadeOut calc(0.3s * var(--cinematic-speed, 1)) ease-in forwards;
}

.card-spotlight.exiting .spl-head,
.card-spotlight.exiting .spl-glow,
.card-spotlight.exiting .spl-payoff,
.card-spotlight.exiting .spotlight-dismiss {
    animation: spotlightFadeOut calc(0.2s * var(--cinematic-speed, 1)) ease-in forwards;
}

@keyframes cardExit {
    to {
        transform: scale(0.8) translateY(-40px);
        opacity: 0;
    }
}

@keyframes spotlightFadeOut {
    to { opacity: 0; }
}

/* Discard spotlight variant — muted red/gold */
.card-spotlight.discard-variant .spotlight-card {
    box-shadow:
        0 0 0 2px rgba(201, 168, 76, 0.4),
        0 0 30px rgba(139, 26, 26, 0.4),
        0 0 60px rgba(139, 26, 26, 0.15),
        0 20px 60px rgba(0, 0, 0, 0.7);
}

.card-spotlight.discard-variant .spotlight-name {
    color: var(--parchment-dark);
    text-shadow:
        0 0 10px rgba(139, 26, 26, 0.5),
        0 0 30px rgba(139, 26, 26, 0.2);
}

.card-spotlight.discard-variant .spl-verb { color: #e08a7a; }
.card-spotlight.discard-variant .spl-glow {
    background: radial-gradient(ellipse at center,
        rgba(160, 44, 32, 0.30) 0%,
        rgba(160, 44, 32, 0.10) 42%,
        transparent 70%);
}

/* ── Opponent Turn Spotlight — one story, four beats: who plays →
   the card lands BIG (flip + shimmer + glow bloom) → its name →
   what it does, as ceremony payout chips + the special's line.
   Desktop reads top-to-bottom; compact landscape goes left-to-right
   (head | card | payoff) so the card takes most of the screen. ── */

.spl-inner {
    position: relative;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    max-width: 94vw;
}

.spl-head {
    display: flex;
    align-items: center;
    gap: 13px;
    opacity: 0;
    animation: spotlightPlayerIn calc(0.4s * var(--cinematic-speed, 1)) ease-out calc(0.1s * var(--cinematic-speed, 1)) forwards;
}

.spl-avatar {
    width: 58px;
    height: 58px;
    border-radius: 50%;
    object-fit: cover;
    border: 2px solid var(--gold);
    box-shadow: 0 0 22px rgba(201, 168, 76, 0.35);
}

.spl-head-text { text-align: left; }

.spl-title {
    font-family: 'Cinzel', serif;
    font-size: clamp(17px, 2.6vw, 24px);
    color: var(--gold-light);
    letter-spacing: 2px;
}

.spl-verb {
    font-family: 'EB Garamond', serif;
    font-style: italic;
    font-size: 0.82em;
    color: rgba(240, 230, 211, 0.75);
    letter-spacing: 1px;
}

.spl-char {
    font-family: 'EB Garamond', serif;
    font-size: 13px;
    font-style: italic;
    color: rgba(240, 230, 211, 0.4);
}

/* The stage: a warm glow blooms behind the flipping card */
.spl-stage {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
}

.spl-glow {
    position: absolute;
    inset: -22% -34%;
    background: radial-gradient(ellipse at center,
        rgba(201, 168, 76, 0.26) 0%,
        rgba(201, 168, 76, 0.09) 42%,
        transparent 70%);
    opacity: 0;
    pointer-events: none;
    animation:
        splGlowIn calc(0.6s * var(--cinematic-speed, 1)) ease-out calc(0.18s * var(--cinematic-speed, 1)) forwards,
        splGlowBreathe 3.4s ease-in-out calc(0.9s * var(--cinematic-speed, 1)) infinite;
}

@keyframes splGlowIn {
    from { opacity: 0; transform: scale(0.55); }
    to { opacity: 1; transform: scale(1); }
}

@keyframes splGlowBreathe {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.7; }
}

/* The payoff: card name, honest chips, special line */
.spl-payoff {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
}

.spl-payoff .spotlight-name {
    margin-top: 0;
    font-size: clamp(20px, 3vw, 30px);
}

.spl-chips {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 7px;
    max-width: min(560px, 92vw);
}

/* Chips pop ceremony-style, one beat after the card lands */
.spl-chips .mc-chip { animation-delay: calc(0.62s * var(--cinematic-speed, 1)); }
.spl-chips .mc-chip:nth-child(2) { animation-delay: calc(0.72s * var(--cinematic-speed, 1)); }
.spl-chips .mc-chip:nth-child(3) { animation-delay: calc(0.82s * var(--cinematic-speed, 1)); }
.spl-chips .mc-chip:nth-child(4) { animation-delay: calc(0.92s * var(--cinematic-speed, 1)); }
.spl-chips .mc-chip:nth-child(5) { animation-delay: calc(1.02s * var(--cinematic-speed, 1)); }
.spl-chips .mc-chip:nth-child(n+6) { animation-delay: calc(1.1s * var(--cinematic-speed, 1)); }

.spl-special {
    font-family: 'EB Garamond', serif;
    font-size: clamp(14px, 1.9vw, 17px);
    font-style: italic;
    color: var(--gold-light);
    text-align: center;
    max-width: min(480px, 90vw);
    line-height: 1.4;
    opacity: 0;
    animation: spotlightEffectIn calc(0.4s * var(--cinematic-speed, 1)) ease-out calc(0.95s * var(--cinematic-speed, 1)) forwards;
}

/* Exit animation */
.card-spotlight.exiting .spl-inner {
    animation: spotlightFadeOut calc(0.25s * var(--cinematic-speed, 1)) ease-in forwards;
}

/* ─── STAT CHANGE ANIMATIONS ──────────────────────────── */

@keyframes statPulse {
    0% { transform: scale(1); }
    40% { transform: scale(1.35); }
    100% { transform: scale(1); }
}

.stat-pulse {
    animation: statPulse calc(0.4s * var(--cinematic-speed, 1)) ease-out;
}

.stat-gain {
    animation: statPulse calc(0.4s * var(--cinematic-speed, 1)) ease-out;
    color: #81c784 !important;
    text-shadow: 0 0 8px rgba(129, 199, 132, 0.6);
}

.stat-loss {
    animation: statPulse calc(0.4s * var(--cinematic-speed, 1)) ease-out;
    color: #ef5350 !important;
    text-shadow: 0 0 8px rgba(239, 83, 80, 0.6);
}

/* ─── EFFECT FLOAT TEXT ───────────────────────────────── */

/* ─── MINI SPOTLIGHT (human player's quick confirmation) ─── */

.mini-spotlight {
    position: fixed;
    bottom: 80px;
    left: 50%;
    transform: translateX(-50%) translateY(60px);
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 10px 20px 10px 10px;
    background: linear-gradient(135deg, rgba(42,22,10,0.97), rgba(58,32,14,0.97));
    border: 1px solid rgba(201, 168, 76, 0.5);
    border-radius: 12px;
    box-shadow: 0 4px 30px rgba(0, 0, 0, 0.6), 0 0 20px rgba(201, 168, 76, 0.15);
    z-index: 9999;
    opacity: 0;
    transition: transform 0.3s ease, opacity 0.3s ease;
    pointer-events: none;
}

.mini-spotlight.show {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

.mini-spotlight.exit {
    opacity: 0;
    transform: translateX(-50%) translateY(-20px);
}

.mini-spotlight img {
    width: 55px;
    height: 78px;
    border-radius: 6px;
    border: 1px solid rgba(201, 168, 76, 0.4);
    object-fit: cover;
}

.mini-spotlight-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.mini-spotlight-name {
    font-family: 'Cinzel', serif;
    font-size: 15px;
    font-weight: 700;
    color: var(--gold);
    text-shadow: 0 0 8px rgba(201, 168, 76, 0.4);
}

.mini-spotlight-effect {
    font-family: 'EB Garamond', serif;
    font-size: 13px;
    color: var(--text-light);
    opacity: 0.8;
    font-style: italic;
}

.mini-spotlight.mini-discard {
    border-color: rgba(180, 80, 80, 0.5);
}

.mini-spotlight.mini-discard .mini-spotlight-name {
    color: #c9a84c;
    opacity: 0.7;
}

.effect-floats-container {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 10001;
}

.effect-float {
    position: absolute;
    font-family: 'Cinzel', serif;
    font-weight: 700;
    font-size: 22px;
    letter-spacing: 2px;
    text-shadow: 0 2px 8px rgba(0,0,0,0.7);
    white-space: nowrap;
    pointer-events: none;
    animation: effectFloat calc(1.4s * var(--cinematic-speed, 1)) ease-out forwards;
}

.effect-float.gain {
    color: #81c784;
}

.effect-float.loss {
    color: #ef5350;
}

.effect-float.gold-change {
    color: #ffd700;
}

.effect-float.prestige-change {
    color: #4fc3f7;
}

.effect-float.scorn-change {
    color: #ef5350;
}

.effect-float.favor-change {
    color: #ab47bc;
}

.effect-float.power-change {
    color: #ff7043;
}

.effect-float.special {
    color: var(--gold-light);
    font-size: 18px;
    font-style: italic;
}

@keyframes effectFloat {
    0% {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
    20% {
        opacity: 1;
        transform: translateY(-15px) scale(1.1);
    }
    100% {
        opacity: 0;
        transform: translateY(-80px) scale(0.9);
    }
}

/* ═══════════════════════════════════════════════════════════
   RESPONSIVE  —  Rotate gate + Landscape-phone table layout
   ═══════════════════════════════════════════════════════════ */

/* Left rail is transparent on desktop: children act as direct .play-area
   children, so the existing absolute positioning + JS-set tops are unchanged. */
.left-rail { display: contents; }

/* ─── ROTATE GATE ──────────────────────────────────────────
   Only phones/tablets (coarse pointer, no hover) held in portrait. */
#rotate-gate { display: none; }

@media (hover: none) and (pointer: coarse) and (orientation: portrait) {
    #rotate-gate {
        display: flex;
        position: fixed;
        inset: 0;
        z-index: 100000;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        text-align: center;
        padding: 40px;
        background:
            radial-gradient(ellipse at 50% 40%, #6b4a30 0%, #3a2214 55%, #1e1208 100%);
        color: var(--gold-light);
    }
    .rotate-icon {
        font-size: 64px;
        animation: rotateHint 2.4s ease-in-out infinite;
    }
    .rotate-title {
        font-family: 'Cinzel', serif;
        font-weight: 900;
        font-size: 26px;
        letter-spacing: 4px;
        color: var(--gold);
        margin-top: 20px;
    }
    .rotate-text {
        font-family: 'EB Garamond', serif;
        font-style: italic;
        font-size: 16px;
        color: var(--text-light);
        opacity: 0.75;
        max-width: 340px;
        margin-top: 12px;
        line-height: 1.5;
    }
}

@keyframes rotateHint {
    0%, 55%, 100% { transform: rotate(0deg); }
    75%, 90%      { transform: rotate(-90deg); }
}

/* ─── TABLE VIEW (phone landscape) ─────────────────────────
   Desktop keeps .game-layout untouched. On short landscape screens we
   hide it and show #table-view: a shared table of player "mats" (board +
   tokens on the board + played cards tucked underneath) around a center
   missions area, with the hand along the bottom. */

#table-view { display: none; }

@media (orientation: landscape) and (max-height: 540px) {

    /* Dynamic viewport height so mobile browser chrome doesn't clip;
       no rubber-banding so hand glides never fight a page scroll. */
    html, body { height: 100dvh; overscroll-behavior: none; }

    /* ── Title screen: landscape phones keep the side-by-side stage —
       this IS the landscape design — just denser, all on one screen. ── */
    #title-screen {
        justify-content: center;
        padding: 8px 14px;
        overflow-y: auto; /* safety: Play always reachable */
    }
    .ts-frame { padding: 10px 16px 8px; }
    .ts-lockup { margin-bottom: 8px; }
    .ts-grid {
        max-width: min(640px, 70vw);
        gap: 7px 10px;
        grid-template-columns: minmax(180px, 250px) minmax(120px, 175px) minmax(120px, 175px);
    }
    .queue-seg { gap: 6px; }
    .queue-seg button { height: 26px; font-size: 12px; border-radius: 7px; }
    .ts-play .queue-seg { margin: 0 8px 8px; padding: 4px 6px; }
    .ts-art-play { background-position: 50% 46%; }
    .queue-label { font-size: 8px; letter-spacing: 1.5px; }
    .menu-link { font-size: 10px; }
    .prompt-test-toggle { font-size: 9px; gap: 6px; }
    .prompt-test-toggle input { width: 13px; height: 13px; }
    .profile-chip { padding: 5px 12px; gap: 8px; }
    .pc-name { font-size: 11px; }
    .pc-rating, .pc-crowns { font-size: 12px; }
    .update-pill {
        top: calc(max(10px, env(safe-area-inset-top)) + 42px);
        padding: 5px 11px; font-size: 10px; gap: 5px;
    }
    .update-pill .up-glyph { font-size: 12px; }
    /* Compact tables keep their corners busy on the right — the door
       moves to the quiet bottom-left, clear of purse, fan and badge. */
    .game-leave {
        right: auto;
        left: max(8px, env(safe-area-inset-left));
        bottom: max(8px, env(safe-area-inset-bottom));
        width: 26px; height: 26px; font-size: 11px;
    }
    .lb-inner, .pf-inner { max-height: calc(100dvh - 12px); padding: 12px 14px 10px; }
    /* Landscape phone: the richer profile must still fit 375x667 rotated. */
    .pf-standing { gap: 10px; padding-bottom: 10px; }
    .pf-standing .pf-av-current { width: 46px; height: 46px; }
    .pf-rating-val { font-size: 25px; }
    .pf-record { font-size: 11px; }
    .pf-sec { margin: 10px 0 6px; font-size: 9.5px; letter-spacing: 1.8px; }
    .pf-heroes { grid-template-columns: repeat(auto-fill, minmax(78px, 1fr)); gap: 6px; }
    .pf-hero { padding: 6px 4px 7px; }
    .pf-hero img { width: 34px; height: 34px; }
    .pf-hero-name { font-size: 8.5px; }
    .pf-hero-r { font-size: 12px; }
    .pf-ach { font-size: 11px; }
    .pf-bounty img { width: 30px; height: 30px; }
    .pf-bounty-name { font-size: 11px; }
    .lb-title, .pf-title { font-size: 14px; letter-spacing: 3px; }
    .lb-main { gap: 9px; }
    .lb-rail { width: 108px; }
    .lb-rail-head { font-size: 9px; letter-spacing: 2px; margin-bottom: 5px; }
    .lb-chartab { padding: 3px 6px 3px 3px; gap: 6px; }
    .lb-chartab img, .lb-chartab .lb-chartab-crown { width: 30px; height: 30px; }
    .lb-chartab .lb-chartab-crown { font-size: 16px; }
    .lb-chartab-name { font-size: 9.5px; }
    .lb-tabs { margin: 8px 0 6px; }
    .champ-card { padding: 26px 30px 24px; }

    /* ── Character select: compact + scrollable ── */
    #character-select { padding: max(14px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) 22px max(16px, env(safe-area-inset-left)); }
    #character-select .select-title { font-size: 20px; margin-bottom: 6px; }
    .character-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
    .character-info h3 { font-size: 14px; }
    .character-info .difficulty { font-size: 11px; }
    .character-info .tip { font-size: 10px; margin-top: 3px; }

    /* Swap desktop layout for the table view. */
    .game-layout { display: none !important; }
    #table-view {
        display: block;
        position: absolute;
        inset: 0;
        z-index: 1;
        height: 100dvh;
        overflow: hidden;
    }

    /* The table is a positioning canvas; mats seat around the center. */
    .tv-table { position: relative; height: 100dvh; }

    /* Scene depth (Wingspan-style): a warm pool of light on the play area
       and a soft vignette at the edges, breathing very slowly. */
    .tv-table::before {
        content: '';
        position: absolute;
        inset: 0;
        background:
            radial-gradient(ellipse 62% 55% at 50% 44%, rgba(255,196,110,0.10), transparent 70%),
            radial-gradient(ellipse 130% 120% at 50% 50%, transparent 55%, rgba(0,0,0,0.42) 100%);
        pointer-events: none;
        z-index: 1;
        animation: tvGlowBreathe 16s ease-in-out infinite;
    }

    /* ── Z8 · Phase pill — slim, top-center just under the seat chips ── */
    .phase-bar {
        top: 52px;
        padding: 2px 12px;
        gap: 6px;
        border-width: 1px;
        z-index: 6;
    }
    .phase-bar .act-tag { font-size: 9px; }
    .phase-bar .phase-text { font-size: 9px; letter-spacing: 1.5px; }

    /* The TEST REALM badge would sit on the mission rail — park it
       bottom-left, out of every zone's way (build stamp stays legible). */
    #testRealmBadge {
        top: auto !important;
        right: auto !important;
        bottom: 0;
        left: 0;
        border-radius: 0 8px 0 0 !important;
        padding: 2px 8px !important;
        opacity: 0.7 !important;
    }

    /* ── Z1 · Purse — your four currencies, top-left, 2×2 grid of big
       table-token chips (juicy pass: icons 34px, numbers 26px). ── */
    .tv-purse {
        position: absolute;
        top: 6px;
        left: max(8px, env(safe-area-inset-left));
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 5px;
        z-index: 6;
    }
    .tv-purse-chip {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        padding: 4px 10px 4px 5px;
        border-radius: 17px;
        background: rgba(10,6,3,0.68);
        border: 1px solid rgba(201,168,76,0.25);
        box-shadow: 0 1px 3px rgba(0,0,0,0.5);
        cursor: pointer;
    }
    .tv-purse-chip img {
        width: 34px; height: 34px;
        object-fit: contain;
        filter: drop-shadow(0 1px 1px rgba(0,0,0,0.6));
    }
    .tv-purse-chip.prestige img { border-radius: 50%; object-fit: cover; }
    .tv-purse-chip b {
        font-family: 'Cinzel', serif;
        font-weight: 900;
        font-size: 26px;
        color: var(--gold-light);
        line-height: 1;
    }
    .tv-purse-chip.scorn b { color: #f0a0a0; }
    .tv-purse-chip.favor b { color: #a9d4ff; }
    /* Tap-a-chip name label (phones have no hover) */
    #tvChipTip {
        position: fixed;
        z-index: 10500;
        font-family: 'Cinzel', serif;
        font-size: 10px;
        letter-spacing: 1px;
        color: var(--gold-light);
        background: rgba(14,7,2,0.92);
        border: 1px solid var(--gold-dark);
        border-radius: 8px;
        padding: 4px 10px;
        pointer-events: none;
        white-space: nowrap;
        transition: opacity 0.25s;
        box-shadow: 0 3px 10px rgba(0,0,0,0.5);
    }
    #tvChipTip.out { opacity: 0; }

    /* ── Z3 · Seat chips — every player in one top-center row, YOU first.
       Chips keep .pmat + data-pi so the delta FX and coach-marks that
       target #table-view .pmat[data-pi] keep landing. ── */
    .tv-seats {
        position: absolute;
        top: 3px;
        left: 50%;
        transform: translateX(-50%);
        display: flex;
        gap: 7px;
        z-index: 6;
    }
    .tv-seats .pmat.seat-chip {
        position: relative;
        width: 37px; height: 37px;
        border-radius: 9px;
        border: 2px solid var(--gold-dark);
        background: var(--wood-deepest);
        box-shadow: 0 2px 8px rgba(0,0,0,0.55);
        cursor: pointer;
        transition: border-color 0.2s, box-shadow 0.2s, transform 0.2s;
    }
    .tv-seats .pmat.seat-chip:hover { border-color: var(--gold); }
    .tv-seats .pmat.seat-chip.active {
        border-color: var(--gold-light);
        box-shadow: 0 0 12px rgba(201,168,76,0.65), 0 2px 8px rgba(0,0,0,0.55);
        transform: translateY(1px) scale(1.07);
    }
    .chip-art {
        position: absolute;
        inset: 0;
        width: 100%; height: 100%;
        object-fit: cover;
        border-radius: 7px;
        display: block;
    }
    .chip-crown {
        position: absolute;
        top: -8px; right: -6px;
        pointer-events: none;
    }
    .chip-crown .emblem-badge {
        width: 15px;
        height: 15px;
        vertical-align: 0;
        border-color: var(--gold);
    }
    .chip-you {
        position: absolute;
        bottom: -7px; left: 50%;
        transform: translateX(-50%);
        font-family: 'Cinzel', serif;
        font-size: 6px;
        font-weight: 700;
        letter-spacing: 1px;
        color: var(--gold-light);
        background: rgba(14,7,2,0.85);
        border: 1px solid rgba(201,168,76,0.4);
        border-radius: 4px;
        padding: 0 4px;
        pointer-events: none;
    }
    .chip-count {
        position: absolute;
        bottom: -5px; right: -5px;
        min-width: 13px; height: 13px;
        border-radius: 7px;
        background: rgba(14,7,2,0.88);
        border: 1px solid rgba(201,168,76,0.35);
        color: var(--gold-dark);
        font-family: 'Cinzel', serif;
        font-size: 7px;
        font-weight: 700;
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 0 2px;
        pointer-events: none;
    }

    /* ── Z2 · Skill rail — always-visible icon+number chips, left edge,
       TWO columns under the purse (juicy pass). --railRows counts GRID
       rows (set by renderTvSkills = ceil(chips/2)); --tvChipH derives
       the chip height from the space between purse (104) and hand strip
       (106), and icon/number sizes scale off it, so everything fits a
       390px screen and degrades gracefully as flex/special chips appear. */
    .tv-skills {
        position: absolute;
        top: 104px;
        bottom: 106px;
        left: max(8px, env(safe-area-inset-left));
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        align-content: start;
        gap: 4px;
        z-index: 5;
        --railRows: 3;
        --tvChipH: min(56px, calc((100dvh - 210px - (var(--railRows) - 1) * 4px) / var(--railRows)));
    }
    .tv-skill-chip {
        display: flex;
        align-items: center;
        gap: 5px;
        padding: 0 8px 0 5px;
        border-radius: 14px;
        background: rgba(10,6,3,0.68);
        border: 1px solid rgba(201,168,76,0.25);
        box-shadow: 0 1px 3px rgba(0,0,0,0.5);
        height: var(--tvChipH);
        cursor: pointer;
    }
    .tv-skill-chip .skill-svg {
        width: calc(var(--tvChipH) * 0.7);
        height: calc(var(--tvChipH) * 0.7);
        min-width: calc(var(--tvChipH) * 0.7);
        object-fit: contain;
    }
    .tv-skill-chip b {
        font-family: 'Cinzel', serif;
        font-weight: 900;
        font-size: calc(var(--tvChipH) * 0.52);
        color: var(--gold-light);
        min-width: calc(var(--tvChipH) * 0.4);
        text-align: center;
        line-height: 1;
    }
    .tv-skill-chip.zero { opacity: 0.38; }
    .tv-skill-chip.flex {
        border-style: dashed;
        border-color: rgba(201,168,76,0.5);
    }
    /* The flex chip wears BOTH faces of its either/or pair, slightly
       overlapped — one icon read as a duplicate of the fixed chip. */
    .tv-skill-chip.flex .flex-pair { display: inline-flex; align-items: center; }
    .tv-skill-chip.flex .flex-pair .skill-svg {
        width: calc(var(--tvChipH) * 0.58);
        height: calc(var(--tvChipH) * 0.58);
        min-width: calc(var(--tvChipH) * 0.58);
    }
    .tv-skill-chip.flex .flex-pair .skill-svg + .skill-svg { margin-left: -4px; }
    .tv-skill-chip.special { border-color: rgba(176,138,255,0.45); }

    /* ── Z4 · Mission rail — Missions of the Realm + My Missions, top-right ── */
    .tv-mission-rail {
        position: absolute;
        top: 6px;
        right: max(8px, env(safe-area-inset-right));
        display: flex;
        align-items: stretch;
        gap: 4px;
        z-index: 6;
    }
    .tv-mission-rail .tv-mission {
        width: 37px;
        aspect-ratio: 46 / 64;
        height: auto;
        border-radius: 4px;
        object-fit: cover;
        border: 1px solid rgba(201,168,76,0.35);
        box-shadow: 0 3px 8px rgba(0,0,0,0.5);
        cursor: pointer;
        transition: transform 0.2s, border-color 0.2s, box-shadow 0.2s;
    }
    .tv-mission-rail .tv-mission:hover {
        transform: translateY(-2px) scale(1.05);
        border-color: var(--gold);
        box-shadow: 0 6px 12px rgba(0,0,0,0.55), 0 0 10px rgba(201,168,76,0.3);
    }
    /* Ghost seat (Wingspan): an empty mission slot still reads as a place. */
    .tv-mission-rail .tv-mission.ghost {
        display: inline-block;
        background: rgba(201,168,76,0.045);
        border: 1.5px dashed rgba(201,168,76,0.3);
        box-shadow: inset 0 0 16px rgba(0,0,0,0.35);
        cursor: default;
    }
    .tv-mission-rail .tv-mission.ghost:hover { transform: none; border-color: rgba(201,168,76,0.3); }
    .tv-mym {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 1px;
        padding: 2px 6px;
        border-radius: 8px;
        background: rgba(10,6,3,0.68);
        border: 1px solid rgba(201,168,76,0.25);
        box-shadow: 0 1px 3px rgba(0,0,0,0.5);
        cursor: pointer;
        font-family: 'Cinzel', serif;
        line-height: 1.1;
    }
    .tv-mym:hover { border-color: var(--gold); }
    .tv-mym .mym-icon { width: 16px; height: 16px; object-fit: contain; }
    .tv-mym .mym-label {
        font-size: 6px; font-weight: 700; letter-spacing: 0.5px;
        text-transform: uppercase; color: var(--gold-dark);
    }
    .tv-mym .mym-count { font-size: 12px; font-weight: 900; color: var(--gold-light); }

    /* ── Z5 · Your board, small — right column under the missions.
       The ring rides the same %-track as the big overlay. ── */
    .tv-board-thumb {
        position: absolute;
        top: 64px;
        right: max(8px, env(safe-area-inset-right));
        /* 2× the original 118px on standard phones (Wyatt 7/8); eases
           down on narrow viewports so the stage keeps its floor. The
           stage's right edge tracks this same clamp — change together. */
        width: clamp(150px, 28vw, 236px);
        border: 2px solid var(--gold-dark);
        border-radius: 6px;
        overflow: hidden;
        background: var(--wood-deepest);
        box-shadow: 0 3px 10px rgba(0,0,0,0.55);
        cursor: pointer;
        z-index: 5;
        transition: border-color 0.2s;
    }
    .tv-board-thumb:hover { border-color: var(--gold); }
    .tv-board-thumb .tv-thumb-board {
        display: block;
        width: 100%;
        height: auto;
    }
    .tv-board-thumb .thumb-ring {
        position: absolute;
        width: 11%;
        aspect-ratio: 1;
        transform: translate(-50%, -50%);
        pointer-events: none;
        filter: drop-shadow(0 1px 2px rgba(0,0,0,0.6));
    }

    /* ── Z6 · Center stage — YOUR played cards as tucked skill stacks.
       Every focus moment (overlays, action panel, FX) lands over this. ── */
    .tv-stage {
        position: absolute;
        left: 206px;   /* clears the two-column juicy skill rail */
        right: calc(clamp(150px, 28vw, 236px) + 20px);   /* clears the 2× board thumb */
        top: 62px;
        bottom: 100px;
        display: flex;
        justify-content: center;
        align-items: flex-start;
        gap: 10px;
        z-index: 2;
        --tvStackCardH: clamp(64px, 24dvh, 96px);
        /* Many piles must never slide under the board thumb — the strip
           scrolls instead (Wyatt 7/23: every pile observable, tappable). */
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }
    .tv-stage::-webkit-scrollbar { display: none; }
    /* 5+ families: thinner cards, left-anchored so the scroll start is
       always reachable (a centered overflow clips its own head). */
    .tv-stage.dense {
        --tvStackCardH: clamp(56px, 19dvh, 80px);
        justify-content: flex-start;
        gap: 8px;
    }
    .tv-stack {
        display: flex;
        flex-direction: column;
        align-items: center;
        position: relative;
        flex: none;
    }
    .tv-stack-card {
        width: calc(var(--tvStackCardH) * 0.666);
        height: var(--tvStackCardH);
        border-radius: 4px;
        object-fit: cover;
        border: 1px solid rgba(201,168,76,0.3);
        box-shadow: 0 3px 10px rgba(0,0,0,0.55);
    }
    .tv-stack-card + .tv-stack-card {
        margin-top: calc(var(--tvPeek, 20px) - var(--tvStackCardH));
    }
    .tv-stack-card.doubled {
        box-shadow: 0 0 0 2px rgba(255,200,80,0.9), 0 0 12px rgba(255,190,60,0.5), 0 3px 10px rgba(0,0,0,0.55);
    }
    .tv-stack-label {
        font-family: 'Cinzel', serif;
        font-size: 6.5px;
        letter-spacing: 1.5px;
        text-transform: uppercase;
        color: var(--typeC, var(--gold-dark));
        opacity: 0.95;
        margin-top: 3px;
        text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
    }
    .tv-stage-empty {
        font-family: 'EB Garamond', serif;
        font-style: italic;
        font-size: 12px;
        color: var(--gold-dark);
        opacity: 0.55;
        align-self: center;
        letter-spacing: 1px;
    }

    /* ── Popovers (gear menu / My Missions) ── */
    .tv-popover-host { display: none; }
    .tv-popover-host.active {
        display: block;
        position: absolute;
        inset: 0;
        z-index: 70;
        background: rgba(8,4,2,0.45);
    }
    .tv-pop {
        position: absolute;
        background: linear-gradient(160deg, var(--wood-darker) 0%, var(--wood-deepest) 100%);
        border: 2px solid var(--gold-dark);
        border-radius: 10px;
        box-shadow: 0 10px 30px rgba(0,0,0,0.6);
        padding: 8px;
        max-height: calc(100dvh - 60px);
        overflow-y: auto;
    }
    .tv-pop.mym {
        top: 58px;
        right: max(8px, env(safe-area-inset-right));
        width: 216px;
    }
    .tv-pop-title {
        font-family: 'Cinzel', serif;
        font-size: 9px;
        letter-spacing: 2px;
        text-transform: uppercase;
        color: var(--gold);
        text-align: center;
        margin-bottom: 6px;
    }

    /* The floating music/log buttons relocate into the ⚙ popover here.
       The in-game selector must repeat: `body:has(#game-screen.active)
       .log-toggle { display:flex }` (the desktop slide-aside rule) beats a
       bare class by specificity, so without it the log button REAPPEARS
       on phones mid-game — floating over the seat row and eating taps. */
    .music-toggle, .log-toggle,
    body:has(#game-screen.active) .music-toggle,
    body:has(#game-screen.active) .log-toggle { display: none; }

    /* ── Z7 · Hand strip — ALWAYS visible, card bottoms cropped ~18%.
       The strip hangs 28px past the screen edge and #table-view's
       overflow:hidden does the cropping — never overflow on the strip
       itself, or it would clip the bloom. ── */
    .tv-hand-strip {
        position: absolute;
        left: 0; right: 0;
        bottom: -28px;
        height: 148px;
        z-index: 45;
        /* Only the cards are interactive — the full-width band must not
           eat taps aimed at the skill rail's bottom chip or the table. */
        pointer-events: none;
    }
    .tv-hand-strip .hand-card { pointer-events: auto; }
    .tv-hand-strip::before {
        content: '';
        position: absolute; inset: 0;
        background: linear-gradient(0deg,
            rgba(22,10,3,0.95) 0%, rgba(35,18,7,0.8) 50%, rgba(42,22,10,0) 100%);
        box-shadow: inset 0 6px 18px rgba(0,0,0,0.3);
        z-index: 0;
    }
    /* "Your turn" pulse along the strip's top edge (replaces the
       auto-opening drawer as the signal that you're up). */
    .tv-hand-strip.your-turn::after {
        content: '';
        position: absolute;
        left: 8%; right: 8%; top: 24px;
        height: 2px;
        border-radius: 2px;
        background: linear-gradient(90deg, transparent, rgba(240,210,120,0.85), transparent);
        animation: tvTurnPulse 2.2s ease-in-out infinite;
        pointer-events: none;
    }
    .tv-hand {
        position: relative;
        z-index: 1;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: flex-end;
        padding-bottom: 6px;
    }
    .tv-hand .hand-arc { display: flex; align-items: flex-end; }
    .tv-hand .hand-card {
        width: 86px; height: 120px;
        margin: 0 -11px;
        border-radius: 6px;
        /* Transform is the only animated property, in AND out, and margins
           never change — so gliding across the fan is pure GPU and the tray
           itself never reflows under the finger. */
        transition: transform 0.15s cubic-bezier(0.33, 1, 0.68, 1), opacity 0.2s;
        touch-action: none;          /* the gesture owns the touch — no browser pan / pointercancel */
        -webkit-touch-callout: none; /* long-press must not summon the image save sheet */
        -webkit-user-select: none;
        user-select: none;
    }
    .tv-hand .hand-card img { -webkit-user-drag: none; }
    /* Drag-up (Hearthstone pull): the card rides the finger via inline
       transform — transition off so it tracks 1:1 — while the rest of
       the fan dims to make room for the decision. */
    .tv-hand .hand-card.dragging {
        transition: none !important;
        z-index: 70;
        filter: drop-shadow(0 14px 26px rgba(0,0,0,0.65)) drop-shadow(0 0 16px rgba(240,210,120,0.4));
    }
    .tv-hand-strip.drag-from .hand-card:not(.dragging) { opacity: 0.45; }
    /* Touch or hover BLOOMS the card in place — the Battlegrounds tray feel.
       Slide along the fan and each card blooms in turn (JS .bloom).
       --bloomScale fits the card to the actual screen height and
       --bloomShift walks edge cards inward so nothing is ever cut off;
       both are set by _tvBloomLayout() in ui.js. Touch gets ONLY the
       JS-managed .bloom — sticky mobile :hover next to it showed two
       bloomed cards at once. */
    /* The strip crops the resting card's bottom ~18% below the screen
       edge, so the bloom lifts 28px: 22px to clear the crop + the old
       6px of breathing room. _tvBloomLayout()'s breathe stays honest. */
    .tv-hand .hand-card.bloom {
        transform: translateX(var(--bloomShift, 0px)) translateY(-28px) scale(var(--bloomScale, 2.8)) !important;
        transform-origin: bottom center;
        z-index: 60;
    }
    @media (hover: hover) {
        .tv-hand-strip .tv-hand .hand-card:hover {
            transform: translateX(var(--bloomShift, 0px)) translateY(-28px) scale(var(--bloomScale, 2.8)) !important;
            transform-origin: bottom center;
            z-index: 60;
        }
    }
    /* Selected keeps a modest lift — the action sheet already shows it big. */
    .tv-hand .hand-card.selected {
        transform: translateY(-38px) scale(1.16) !important;
        z-index: 30;
        filter: drop-shadow(0 0 10px rgba(240,210,120,0.65));
    }
    /* Battlegrounds-style playable glow: these you can act on right now. */
    .tv-hand .hand-card.playable {
        box-shadow: 0 0 0 2px rgba(140,225,125,0.95), 0 0 18px 4px rgba(120,220,120,0.55);
        animation: playableBreathe 2.2s ease-in-out infinite;
    }
    .tv-hand-waiting {
        color: var(--gold); opacity: 0.4;
        font-family: 'Cinzel', serif;
        font-size: 11px; letter-spacing: 2px;
        align-self: center;
    }

    /* ── Action sheet: the selected card sits big and readable beside its
       actions (Battlegrounds "the card is the dialog") instead of a menu
       floating over a hidden card. ── */
    .action-panel {
        bottom: 10px;
        padding: 10px 16px;
        min-width: 0;
        max-width: 96vw;
        max-height: calc(100dvh - 16px);
        flex-direction: row;
        align-items: center;
        gap: 16px;
    }
    .action-panel .action-card-img {
        /* !important: outranks the desktop-default display:none that sits
           later in the sheet (same specificity, later source order). */
        display: block !important;
        height: clamp(150px, 54dvh, 214px);
        width: auto;
        border-radius: 8px;
        box-shadow: 0 8px 22px rgba(0,0,0,0.65);
    }
    .action-panel .action-body {
        align-items: stretch;
        min-width: 216px;
        max-width: 52vw;
        overflow-y: auto;
        max-height: calc(100dvh - 40px);
    }
    .action-panel .action-header { margin-bottom: 2px; }
    /* No text summaries — the card image IS the description. The PRICE
       line is the deliberate exception: costs must show before commit. */
    .action-panel .action-card-name,
    .action-panel .action-card-type,
    .action-panel .action-skills,
    .action-panel .action-special,
    .action-panel .action-rewards { display: none; }
    .action-panel .action-price { font-size: 11px; margin-top: 0; }
    .action-panel .action-buttons { gap: 6px; margin-top: 4px; }
    .action-panel .action-btn { padding: 8px 14px !important; font-size: 11px !important; }



    /* ── FX layer (token drops / card tucks / mission reveals) ── */
    #tvFx {
        position: absolute; inset: 0;
        pointer-events: none;
        z-index: 60;
        overflow: hidden;
    }

    /* ── Card-play reveal on a short screen: read it left-to-right —
       who (head) | the card BIG | name + chips. No scroll; the card
       takes nearly the full height. (.mc-chip compact sizing lives in
       the ceremony's landscape block — same media condition.) ── */
    .spl-inner {
        flex-direction: row;
        align-items: center;
        justify-content: center;
        gap: 22px;
        max-width: 96vw;
    }
    .spl-head {
        flex-direction: column;
        text-align: center;
        gap: 7px;
        width: clamp(150px, 24vw, 220px);
        flex-shrink: 0;
    }
    .spl-head-text { text-align: center; }
    .spl-avatar { width: 52px; height: 52px; }
    .spl-title { font-size: 16px; letter-spacing: 1px; }
    .spl-char { font-size: 11px; }
    .spotlight-card { height: min(78dvh, 340px); }
    .spl-payoff {
        width: clamp(170px, 30vw, 300px);
        flex-shrink: 0;
        gap: 8px;
    }
    .spl-payoff .spotlight-name { font-size: 17px; letter-spacing: 1px; }
    .spl-chips { gap: 5px; }
    .spl-special { font-size: 12px; }
    .spotlight-dismiss { font-size: 9px; bottom: 8px; }
    /* Human's own quick banner clears the hand strip. */
    .mini-spotlight { bottom: 128px; }

    /* ── Opponent inspect: header, then their full purse + summed skills
       as one HUD-language chip rail (the same chips you read your own
       stats in on phones), then board (ring on its track) + played-card
       stacks side by side. No stat pills, no reveal toggle. ── */
    .opp-ov-inner {
        gap: 6px;
        max-height: 100dvh;
        max-width: 96vw;
        padding: 6px 0;
    }
    .opp-ov-header { justify-content: center; gap: 10px; margin-bottom: 0; }
    .opp-ov-avatar { width: 40px; height: 40px; }
    .opp-ov-name { font-size: 18px; letter-spacing: 2px; }
    .opp-ov-stats { display: none; }
    .opp-ov-panel { display: none; }
    .opp-ov-chips {
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        gap: 4px 6px;
        max-width: 94vw;
        --tvChipH: 30px;
        animation: ovZoom 0.4s cubic-bezier(0.16,1,0.3,1);
    }
    /* Overlay-sized chips: the rail's purse chips are HUD-large — trim
       them so purse and skills read as one row here. */
    .opp-ov-chips .tv-purse-chip { padding: 2px 8px 2px 4px; gap: 4px; }
    .opp-ov-chips .tv-purse-chip img { width: 22px; height: 22px; }
    .opp-ov-chips .tv-purse-chip b { font-size: 17px; }
    .opp-ov-chips .tv-purse-chip.emblem img { border-radius: 50%; object-fit: cover; }
    .opp-ov-chips .tv-purse-chip.emblem b {
        font-size: 11px;
        letter-spacing: 1px;
    }
    .opp-ov-mid {
        display: flex;
        align-items: center;
        gap: 18px;
        margin-bottom: 0;
    }
    .opp-ov-boardwrap {
        display: block;
        position: relative;
        flex-shrink: 0;
        animation: ovZoom 0.45s cubic-bezier(0.16,1,0.3,1);
    }
    .opp-ov-board {
        display: block;
        max-width: 50vw;
        max-height: 56dvh;
        width: auto;
        margin-bottom: 0;
        animation: none;   /* the wrapper animates so the ring rides along */
    }
    .opp-ov-ring {
        display: block;
        position: absolute;
        width: 11%;
        aspect-ratio: 1;
        transform: translate(-50%, -50%);
        pointer-events: none;
        filter: drop-shadow(0 1px 2px rgba(0,0,0,0.6));
    }
    .opp-ov-stacks {
        display: flex;
        align-items: flex-start;
        gap: 10px;
        max-width: 40vw;
        max-height: 74dvh;
        overflow-x: auto;
        padding: 4px 2px;
        --tvStackCardH: clamp(76px, 24dvh, 112px);
        animation: ovFan 0.45s cubic-bezier(0.16,1,0.3,1);
    }
    .opp-ov-toggle,
    .opp-ov-cards-panel { display: none; }

    /* ── Mission browser on phones: slimmer edge nav, cards fill height ── */
    .mb-title { margin-bottom: 0; }
    .mb-card img { height: 64dvh; }
    .mb-track { padding: 12px 50vw; }
    .mb-nav { width: 40px; height: 40px; font-size: 26px; }
    .mb-nav.prev { left: max(8px, env(safe-area-inset-left)); }
    .mb-nav.next { right: max(8px, env(safe-area-inset-right)); }
    .mission-lb-label { bottom: 8px; font-size: 12px; letter-spacing: 2px; }
    .mission-lb-action { bottom: 30px; }
    .mission-lb-action .btn-royal { padding: 7px 18px; font-size: 11px; }

    /* ── Mission Journal on phones: near-fullscreen ledger ── */
    .mj-scroll { width: 96vw; max-height: 96dvh; }
    .mj-head { padding: 6px 14px 5px; }
    .mj-title { font-size: 13px; letter-spacing: 4px; }
    .mj-body { padding: 8px 14px 10px; }
    .mj-section + .mj-section { margin-top: 8px; }
    .mj-section-title { font-size: 9px; margin-bottom: 8px; }
    .mj-grid { gap: 10px; }
    .mj-card img { height: 42dvh; }
    .mj-due { font-size: 11px; margin-top: 3px; }
    .mj-roller { height: 9px; }
}

/* ─── PHASE C ANIMATIONS (global keyframes + FX element styles) ─── */
@keyframes tvTurnPulse {
    0%, 100% { opacity: 0.25; }
    50%      { opacity: 1; }
}

.tv-token-drop {
    position: fixed;
    transform: translate(-50%, -140%);
    display: flex; flex-direction: column; align-items: center;
    z-index: 60; pointer-events: none;
    animation: tvTokenDrop 1.1s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
.tv-token-drop img {
    width: 22px; height: 22px; border-radius: 50%;
    box-shadow: 0 2px 8px rgba(0,0,0,0.6);
}
.tv-token-drop .tv-token-favor {
    width: 22px; height: 22px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: radial-gradient(circle at 40% 35%, #8cc8ff, #2f6bb0);
    color: #fff; font-size: 13px; box-shadow: 0 2px 8px rgba(0,0,0,0.6);
}
.tv-token-drop .tv-token-amt {
    font-family: 'Cinzel', serif; font-weight: 900; font-size: 11px;
    color: var(--gold-light); text-shadow: 0 1px 3px rgba(0,0,0,0.8);
    margin-top: 1px;
}
@keyframes tvTokenDrop {
    0%   { transform: translate(-50%, -220%) scale(0.6); opacity: 0; }
    35%  { transform: translate(-50%, -140%) scale(1.1); opacity: 1; }
    70%  { transform: translate(-50%, -140%) scale(1); opacity: 1; }
    100% { transform: translate(-50%, -180%) scale(0.9); opacity: 0; }
}

/* Mirrored drop for top-edge targets (seat chips): pops out of the chip
   downward instead of climbing off-screen. */
.tv-token-drop.below {
    transform: translate(-50%, 30%);
    animation-name: tvTokenDropBelow;
}
@keyframes tvTokenDropBelow {
    0%   { transform: translate(-50%, -40%) scale(0.6); opacity: 0; }
    35%  { transform: translate(-50%, 30%) scale(1.1); opacity: 1; }
    70%  { transform: translate(-50%, 30%) scale(1); opacity: 1; }
    100% { transform: translate(-50%, 70%) scale(0.9); opacity: 0; }
}

/* Stat float — a "+N" pops out just RIGHT of the stat that grew, level
   with its row, then rises through open air and fades. (Starting the
   rise ON the anchor drifted it across the row above — a "+3" passing
   over a "2" read as "+32"; the audit shot caught it.) Body-level fixed
   element: survives every panel re-render, works on the desktop rail AND
   the phone chips. `both` fill keeps a staggered float invisible until
   its turn. */
.stat-float {
    position: fixed;
    transform: translate(0, -50%);
    z-index: 10500;
    pointer-events: none;
    font-family: 'Cinzel', serif;
    font-weight: 900;
    font-size: 30px;
    color: var(--gold-light);
    text-shadow: 0 0 14px rgba(240,210,120,0.9), 0 2px 5px rgba(0,0,0,0.95);
    animation: statFloat 1.55s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.stat-float.bad {
    color: #e2574c;
    text-shadow: 0 0 14px rgba(226,87,76,0.75), 0 2px 5px rgba(0,0,0,0.95);
}
/* Wyatt: "you can barely see it" — the +N now rides fully opaque through
   70% of its life (~1.1s of clear reading time) and only then fades. */
@keyframes statFloat {
    0%   { transform: translate(0, -30%) scale(0.55); opacity: 0; }
    12%  { transform: translate(0, -85%) scale(1.25); opacity: 1; }
    70%  { transform: translate(0, -118%) scale(1); opacity: 1; }
    100% { transform: translate(0, -205%) scale(0.95); opacity: 0; }
}
@media (orientation: landscape) and (max-height: 540px) {
    .stat-float { font-size: 19px; }
}

.tv-card-drop {
    position: fixed;
    width: 22px; height: 31px;
    border-radius: 2px;
    transform: translate(-50%, -50%);
    box-shadow: 0 6px 18px rgba(0,0,0,0.6);
    z-index: 60; pointer-events: none;
    animation: tvCardDrop 0.85s cubic-bezier(0.34, 1.4, 0.64, 1) forwards;
}
@keyframes tvCardDrop {
    0%   { transform: translate(-50%, -260%) scale(2.4) rotate(-6deg); opacity: 0; }
    30%  { opacity: 1; }
    100% { transform: translate(-50%, -50%) scale(1) rotate(0deg); opacity: 0; }
}

/* Chip-rail tuck: the card appears big under the chip and shrinks up
   into it — same beat, aimed on-screen. */
.tv-card-drop.below { animation-name: tvCardDropBelow; }
@keyframes tvCardDropBelow {
    0%   { transform: translate(-50%, 30%) scale(2.6) rotate(-6deg); opacity: 0; }
    30%  { opacity: 1; }
    100% { transform: translate(-50%, -60%) scale(0.7) rotate(0deg); opacity: 0; }
}

.tv-mission-reveal {
    position: fixed;
    left: 50%; top: 42%;
    transform: translate(-50%, -50%);
    display: flex; flex-direction: column; align-items: center;
    z-index: 61; pointer-events: none;
    animation: tvMrIn 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
.tv-mission-reveal.out { animation: tvMrOut 0.5s ease forwards; }
.tv-mr-who {
    font-family: 'Cinzel', serif; font-size: 13px; letter-spacing: 2px;
    color: var(--gold-light); text-shadow: 0 2px 8px rgba(0,0,0,0.9); margin-bottom: 8px;
}
.tv-mr-card {
    width: 96px; border-radius: 8px;
    box-shadow: 0 0 40px rgba(201,168,76,0.4), 0 12px 40px rgba(0,0,0,0.7);
}
.tv-mr-name {
    font-family: 'Cinzel', serif; font-size: 12px; color: var(--gold);
    margin-top: 8px; text-shadow: 0 2px 6px rgba(0,0,0,0.9);
}
@keyframes tvMrIn {
    from { transform: translate(-50%, -30%) scale(0.7); opacity: 0; }
    to   { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}
@keyframes tvMrOut {
    to { transform: translate(-50%, -70%) scale(0.9); opacity: 0; }
}

/* ═══════════════════════════════════════════════════════════
   HOW TO PLAY — card-deck tutorial (Prong 1)
   ═══════════════════════════════════════════════════════════ */
#howto-overlay {
    position: fixed; inset: 0; z-index: 2000;
    display: none; align-items: center; justify-content: center;
    padding: 20px;
    background: rgba(10,6,3,0.9);
    backdrop-filter: blur(8px);
}
#howto-overlay.active { display: flex; }

.howto-card {
    position: relative;
    width: min(460px, 92vw);
    background: linear-gradient(160deg, #2e1d11 0%, #1e1208 100%);
    border: 2px solid var(--gold);
    border-radius: 16px;
    box-shadow: 0 0 60px rgba(201,168,76,0.15), 0 20px 60px rgba(0,0,0,0.7);
    padding: 24px 24px 18px;
    display: flex; flex-direction: column; align-items: center;
    text-align: center;
    animation: fadeIn 0.35s ease;
}
.howto-counter {
    position: absolute; top: 12px; right: 16px;
    font-family: 'Cinzel', serif; font-size: 12px;
    color: var(--gold-dark); letter-spacing: 1px;
}

.howto-art {
    height: 165px;
    display: flex; align-items: center; justify-content: center;
    margin: 8px 0 16px;
}
.ht-hero { max-height: 165px; max-width: 100%; border-radius: 8px; box-shadow: 0 6px 20px rgba(0,0,0,0.55); }
.ht-cardimg { max-height: 165px; border-radius: 6px; box-shadow: 0 6px 20px rgba(0,0,0,0.6); border: 1px solid rgba(201,168,76,0.3); }
.ht-icon { width: 56px; height: 56px; object-fit: contain; filter: drop-shadow(0 3px 6px rgba(0,0,0,0.5)); }
.ht-icons { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; align-items: center; }
.ht-icons .ht-icon { width: 48px; height: 48px; }
.ht-token { width: 96px; height: 96px; border-radius: 50%; box-shadow: 0 6px 18px rgba(0,0,0,0.55); }
.ht-fan { display: flex; align-items: center; }
.ht-fan img { width: 74px; height: 104px; border-radius: 5px; object-fit: cover; border: 1px solid rgba(201,168,76,0.35); box-shadow: 0 4px 14px rgba(0,0,0,0.6); }
.ht-fan img:nth-child(1) { transform: rotate(-9deg); margin-right: -16px; }
.ht-fan img:nth-child(2) { z-index: 1; position: relative; }
.ht-fan img:nth-child(3) { transform: rotate(9deg); margin-left: -16px; }
.ht-board-wrap { position: relative; display: inline-block; }
.ht-board-ring { position: absolute; bottom: 7%; left: 50%; transform: translateX(-50%); width: 15%; filter: drop-shadow(0 1px 2px rgba(0,0,0,0.6)); }
.ht-acts { font-family: 'Cinzel Decorative', 'Cinzel', serif; font-size: 50px; font-weight: 900; color: var(--gold-light); letter-spacing: 4px; text-shadow: 0 3px 12px rgba(201,168,76,0.3); }
.ht-win { position: relative; display: inline-block; }
.ht-win .ht-icon { width: 74px; height: 74px; }
.ht-crown { position: absolute; top: -18px; right: -12px; font-size: 30px; }

.howto-text {
    font-family: 'EB Garamond', serif;
    font-size: 17px; line-height: 1.45;
    color: var(--text-light);
    min-height: 74px;
}
.howto-text b { color: var(--gold-light); font-weight: 600; }

.howto-dots { display: flex; gap: 6px; margin: 16px 0 14px; flex-wrap: wrap; justify-content: center; }
.ht-dot { width: 7px; height: 7px; border-radius: 50%; background: rgba(201,168,76,0.22); transition: background 0.2s; }
.ht-dot.on { background: var(--gold); }

.howto-nav { display: flex; gap: 10px; }
.howto-btn {
    font-family: 'Cinzel', serif; font-size: 13px; letter-spacing: 1px;
    padding: 9px 22px; border-radius: 8px; cursor: pointer;
    border: 1px solid var(--gold);
    background: rgba(201,168,76,0.1); color: var(--gold-light);
    transition: all 0.2s;
}
.howto-btn.next { background: linear-gradient(135deg, var(--gold-dark) 0%, var(--gold) 50%, var(--gold-dark) 100%); color: var(--royal-deep); font-weight: 700; border-color: var(--gold-light); }
.howto-btn.dismiss { border-color: rgba(201,168,76,0.3); color: var(--gold-dark); }
.howto-btn:hover { box-shadow: 0 0 14px rgba(201,168,76,0.3); transform: translateY(-1px); }

/* Landscape phone: fit the whole card within a short screen. */
@media (orientation: landscape) and (max-height: 540px) {
    .howto-card { width: min(560px, 94vw); padding: 12px 22px 10px; }
    .howto-counter { top: 8px; right: 12px; font-size: 10px; }
    .howto-art { height: 108px; margin: 4px 0 8px; }
    .ht-hero, .ht-cardimg { max-height: 108px; }
    .ht-icon { width: 44px; height: 44px; }
    .ht-icons .ht-icon { width: 40px; height: 40px; }
    .ht-token { width: 66px; height: 66px; }
    .ht-fan img { width: 56px; height: 78px; }
    .ht-fan img:nth-child(1) { margin-right: -12px; }
    .ht-fan img:nth-child(3) { margin-left: -12px; }
    .ht-acts { font-size: 34px; }
    .ht-win .ht-icon { width: 56px; height: 56px; }
    .howto-text { font-size: 14px; line-height: 1.35; min-height: 44px; }
    .howto-dots { margin: 8px 0 8px; }
    .howto-btn { padding: 7px 16px; font-size: 12px; }

    /* ── Final scoring: the whole ceremony fits a short screen ── */
    #scoringContent { padding: 8px 10px; }
    .scoring-title { font-size: 17px; margin: 6px 0 2px; }
    .scoring-sub { font-size: 11px; margin-bottom: 6px; }
    .scoring-table { margin-top: 8px; }
    .scoring-table th, .scoring-table td { padding: 4px 9px; font-size: 11px; }
    .scoring-table th { font-size: 8px; letter-spacing: 0.5px; }
    .scoring-actions { margin: 12px 0 6px; }
    .scoring-actions .btn-royal { padding: 8px 22px; font-size: 12px; }

    /* Store stall on a short screen: smaller cells, the grid scrolls,
       the wares counter yields its space to the shelves. */
    .st-inner { padding-top: 40px; }
    .st-awning { height: 22px; }
    .st-awning::after { height: 10px; background-size: 88px 10px; }
    .st-sign { font-size: 13px; padding: 5px 14px 6px; margin-top: 2px; }
    .st-sign::before, .st-sign::after { top: -14px; height: 14px; }
    .st-grid { grid-template-columns: repeat(auto-fill, minmax(126px, 1fr)); gap: 24px 12px; margin-top: 10px; padding: 12px 12px 14px; }
    .st-name { font-size: 10px; padding: 2px 10px; }
    .st-buy { font-size: 10px; padding: 3px 9px 3px 14px; }
    .st-owned { width: 38px; height: 38px; font-size: 6.5px; }
    .st-counter { display: none; }

    /* Mission ceremony on a short screen: tighter stage, smaller chips. */
    .mc-inner { gap: 2vh; padding: 2vh 3vw; }
    .mc-stage { gap: clamp(14px, 3.5vw, 34px); }
    .mc-portrait { width: 62px; height: 62px; }
    .mc-pname { font-size: 13px; }
    .mc-pcount { font-size: 10.5px; }
    .mc-player { min-width: 96px; gap: 5px; }
    .mc-card { height: clamp(170px, 58vh, 300px); }
    .mc-stamp { font-size: clamp(15px, 5.4vh, 22px); letter-spacing: 3px; padding: 4px 14px 5px; border-width: 3px; }
    .mc-rewards { min-width: 138px; gap: 6px; max-height: 68vh; }
    .mc-chip { font-size: 11px; padding: 3px 10px 3px 6px; gap: 6px; }
    .mc-chip img { width: 20px; height: 20px; }
    .mc-req { font-size: 10px; padding: 2px 9px 3px; }
    .mc-took, .mc-others { max-width: 190px; gap: 5px; }
    .mc-took-card { width: 38px; }
    .mc-took-card img { width: 38px; height: 54px; }
    .mc-took-card em { font-size: 7px; }
    .mc-other { font-size: 10px; }
    .mc-took-lab, .mc-others-lab { font-size: 9px; letter-spacing: 1.4px; }
    .mc-banner-icon { width: 22px; height: 22px; vertical-align: -5px; margin-right: 7px; }

    /* Victory ceremony tightens to the same short-screen budget. */
    .vs-head { padding: 10px 20px 6px; }
    .vs-headline { font-size: clamp(19px, 4.6vh, 24px); }
    .vs-personal { font-size: 12px; margin-top: 3px; }
    /* The note costs head height on the 844×390 budget, so it pays rent:
       small, tight, one line — it still reads before any scroll. */
    .vs-tiebreak { font-size: 11px; padding: 3px 9px; gap: 5px; margin-top: 4px; border-radius: 8px; }
    .vs-tiebreak img { width: 15px; height: 15px; flex-basis: 15px; }
    .vs-deltas { gap: 8px; margin: 6px 0 2px; }
    .vs-delta { font-size: 13px; padding: 5px 12px; gap: 6px; }
    .vs-places { gap: 3px; margin-top: 8px; }
    .vs-place { padding: 4px 12px 5px; gap: 2px; }
    .vs-place-row { gap: 8px; }
    .vs-place .vs-ord { font-size: 10px; width: 26px; }
    .vs-place .vs-total { font-size: 15px; }
    .vs-trophy { width: 16px; height: 16px; flex-basis: 16px; }
    .vs-holdings { padding-left: 34px; gap: 3px 4px; }
    .vsh-chip { padding: 1px 6px 1px 3px; gap: 3px; }
    .vsh-chip img, .vsh-chip .skill-svg { width: 13px; height: 13px; }
    .vsh-chip b { font-size: 10px; }
}

/* ═══════════════════════════════════════════════════════════════
   COACH-MARKS — Prong 2: in-game contextual tips (SAP-style)
   A single small bubble points at a real UI element, fires once
   per idea on first encounter, ✕ to dismiss. Non-blocking.
   ═══════════════════════════════════════════════════════════════ */
#coach {
    position: fixed;
    z-index: 9990;                 /* above table (<=950), below action panel/overlays */
    max-width: 248px;
    display: none;
    pointer-events: auto;
}
#coach.show { display: block; animation: coachIn 0.28s cubic-bezier(0.2, 0.9, 0.3, 1.2); }
@keyframes coachIn {
    from { opacity: 0; transform: translateY(5px) scale(0.95); }
    to   { opacity: 1; transform: none; }
}

.coach-bubble {
    position: relative;
    background: linear-gradient(180deg, #2c1c11 0%, #1a0f08 100%);
    border: 1.5px solid var(--gold);
    border-radius: 13px;
    padding: 12px 32px 11px 14px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.6), 0 0 0 1px rgba(0,0,0,0.45), inset 0 1px 0 rgba(232,212,139,0.12);
    color: var(--parchment);
    font-family: 'EB Garamond', serif;
    font-size: 13.5px;
    line-height: 1.42;
}
.coach-bubble b { color: var(--gold-light); font-weight: 600; }

.coach-text { position: relative; z-index: 2; }

.coach-x {
    position: absolute;
    top: 7px; right: 8px;
    width: 20px; height: 20px;
    padding: 0; margin: 0;
    border: 1px solid var(--gold-dark);
    border-radius: 50%;
    background: rgba(0,0,0,0.35);
    color: var(--gold);
    font-size: 11px; line-height: 17px;
    text-align: center;
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
    z-index: 3;
}
.coach-x:hover { color: var(--gold-light); border-color: var(--gold); background: rgba(0,0,0,0.55); }

.coach-skip {
    display: inline-block;
    margin-top: 9px;
    font-family: 'Cinzel', serif;
    font-size: 9.5px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--gold-dark);
    cursor: pointer;
    transition: color 0.15s;
    position: relative; z-index: 3;
}
.coach-skip:hover { color: var(--gold); text-decoration: underline; }

/* Caret — a rotated square with two borders trimmed so it merges with the bubble */
.coach-arrow {
    position: absolute;
    width: 12px; height: 12px;
    background: #221509;
    border: 1.5px solid var(--gold);
    transform: rotate(45deg);
    z-index: 1;
}
.coach-arrow.pd-down  { border-top: none;    border-left: none;  background: #1a0f08; }
.coach-arrow.pd-up    { border-bottom: none; border-right: none; background: #2c1c11; }
.coach-arrow.pd-right { border-top: none;    border-right: none; }
.coach-arrow.pd-left  { border-bottom: none; border-left: none;  }

/* Soft glow that frames whatever element the tip points at */
#coach-glow {
    position: fixed;
    z-index: 9989;
    pointer-events: none;
    border: 2px solid var(--gold-light);
    border-radius: 12px;
    box-shadow: 0 0 0 3px rgba(201,168,76,0.22), 0 0 20px rgba(232,212,139,0.5);
    display: none;
}
#coach-glow.show { display: block; animation: coachPulse 1.7s ease-in-out infinite; }
@keyframes coachPulse { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }

/* ═══ CARD PEEK — press & hold "boom" (Battlegrounds-style) ═══════════
   Any card held for a beat blows up to full readable size, with keyword
   plaques alongside explaining exactly what it does. Global: works on the
   phone table view AND the desktop layout. */

[data-peek] {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
}

.card-peek {
    position: fixed;
    inset: 0;
    z-index: 10500; /* above the action panel (9999) — the peek outranks everything */
    display: none;
    align-items: center;
    justify-content: center;
    gap: 20px;
    padding: 10px;
    background: rgba(6,3,1,0.82);
    backdrop-filter: blur(4px);
    cursor: pointer;
}
.card-peek.active { display: flex; }

.peek-card {
    max-height: 92dvh;
    max-width: 58vw;
    border-radius: 12px;
    box-shadow: 0 0 60px rgba(201,168,76,0.45), 0 18px 50px rgba(0,0,0,0.8);
    animation: peekIn 0.18s cubic-bezier(0.2, 1.3, 0.3, 1);
}

.peek-plaques {
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-width: min(300px, 36vw);
    max-height: 92dvh;
    overflow-y: auto;
    animation: peekPlaques 0.26s ease;
}
.peek-plaques:empty { display: none; }

.peek-plaque {
    border: 1px solid rgba(201,168,76,0.4);
    border-radius: 10px;
    background: linear-gradient(160deg, rgba(50,28,13,0.96), rgba(26,13,5,0.97));
    box-shadow: 0 4px 14px rgba(0,0,0,0.55);
    padding: 7px 12px;
}
.peek-plaque .pk-title {
    font-family: 'Cinzel', serif;
    font-size: 11px;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: var(--gold-light);
    margin-bottom: 2px;
}
.peek-plaque .pk-body {
    font-family: 'EB Garamond', serif;
    font-size: 13px;
    color: #e8d9bf;
    line-height: 1.35;
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    align-items: center;
}
.pk-skill { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.pk-skill img { width: 16px; height: 16px; border-radius: 3px; }
.peek-plaque.scorn { border-color: rgba(200,80,80,0.5); }
.peek-plaque.scorn .pk-title { color: #f09a9a; }
.peek-plaque.special { border-color: rgba(140,180,255,0.4); }
.peek-plaque.special .pk-title { color: #a9c8f5; }
.peek-plaque.type { border-color: rgba(201,168,76,0.6); }

@keyframes peekIn { from { transform: scale(0.6); opacity: 0; } }
@keyframes peekPlaques { from { transform: translateX(14px); opacity: 0; } }

/* ═══ HOVER PEEK — point at any small card, see it huge ═══════════════
   Desktop mice only (touch uses hold-to-peek). A fixed, non-interactive
   full-size card floats beside whatever small card the cursor is on —
   played stacks, mission pips, sidebar minis — Battlegrounds-big, never
   clipped by the scroll panes those small cards live inside. */

.hover-peek {
    position: fixed;
    z-index: 10400; /* over everything except the hold-peek overlay (10500) */
    pointer-events: none;
    display: none;
}
.hover-peek.active { display: block; }
.hover-peek img {
    display: block;
    height: min(88vh, 680px); /* card scans are 333x500 — past ~680px they go soft */
    width: auto;
    border-radius: 14px;
    box-shadow: 0 0 70px rgba(201,168,76,0.4), 0 24px 60px rgba(0,0,0,0.75);
    animation: peekIn 0.14s cubic-bezier(0.2, 1.3, 0.3, 1);
}


/* ═══ MISSION CEREMONY — the missions phase, player by player ═══════ */

#missionCeremony {
    position: fixed;
    inset: 0;
    z-index: 9500;
    display: none;
    align-items: center;
    justify-content: center;
    background: radial-gradient(90% 90% at 50% 42%, rgba(26, 13, 4, 0.88), rgba(10, 5, 2, 0.97));
    backdrop-filter: blur(6px);
    cursor: pointer;
}
#missionCeremony.active { display: flex; animation: msFade 0.3s ease; }
.mc-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3.4vh;
    width: 100%;
    max-height: 100dvh;
    padding: 3vh 4vw;
}
/* The ceremony borrows the old splash's banner/act/hint classes — their
   rules live HERE now (the melee splash moved to css/melee.css, whose
   bare .ms-* rules must not restyle the ceremony). */
.mc-inner .ms-banner {
    font-family: 'Cinzel', serif;
    font-weight: 900;
    letter-spacing: 8px;
    font-size: clamp(20px, 7dvh, 36px);
    color: var(--gold-light);
    text-transform: uppercase;
    text-shadow: 0 0 24px rgba(201,168,76,0.55), 0 3px 6px rgba(0,0,0,0.8);
    display: flex;
    align-items: baseline;
    gap: 14px;
    animation: msBanner 0.45s cubic-bezier(0.16, 1, 0.3, 1);
}
.mc-inner .ms-act {
    font-size: 0.45em;
    letter-spacing: 4px;
    color: var(--gold-dark);
}
.mc-inner .ms-hint {
    position: static;
    font-family: 'Cinzel', serif;
    font-size: 10px;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--gold-dark);
    opacity: 0.7;
    animation: none;
}
@keyframes msBanner { from { opacity: 0; transform: scale(1.35); } }
.mc-banner-icon {
    width: 30px; height: 30px;
    object-fit: contain;
    margin-right: 10px;
    vertical-align: -7px;
    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.6));
}
.mc-stage {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: clamp(20px, 4.5vw, 64px);
    width: 100%;
}
.mc-player {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    min-width: 140px;
    animation: mcSlideL 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
.mc-portrait {
    width: 96px; height: 96px;
    border-radius: 12px;
    object-fit: cover;
    border: 2px solid rgba(201, 168, 76, 0.55);
    box-shadow: 0 8px 22px rgba(0, 0, 0, 0.6);
}
.mc-pname {
    font-family: 'Cinzel', serif;
    font-size: 17px;
    font-weight: 700;
    letter-spacing: 1px;
    color: var(--gold-light);
    text-shadow: 0 0 16px rgba(201, 168, 76, 0.3);
}
.mc-pcount {
    font-family: 'EB Garamond', serif;
    font-style: italic;
    font-size: 12px;
    color: rgba(240, 230, 211, 0.6);
}
.mc-cardwrap {
    position: relative;
    animation: mcCardIn 0.45s cubic-bezier(0.16, 1, 0.3, 1);
}
.mc-card {
    display: block;
    height: clamp(220px, 56vh, 460px);
    border-radius: 10px;
    box-shadow: 0 16px 44px rgba(0, 0, 0, 0.7);
    transition: filter 0.35s;
}
.mc-stage.stamped.fail .mc-card { filter: saturate(0.45) brightness(0.78); }
/* the wax verdict — slams down when the beat reveals */
.mc-stamp {
    position: absolute;
    inset: 0;
    margin: auto;
    width: fit-content;
    height: fit-content;
    padding: 7px 24px 8px;
    transform: rotate(-14deg) scale(3);
    opacity: 0;
    font-family: 'Cinzel', serif;
    font-weight: 900;
    font-size: clamp(22px, 4.6vh, 36px);
    letter-spacing: 5px;
    text-transform: uppercase;
    color: #ffe9ad;
    background: rgba(58, 36, 8, 0.4);
    border: 4px solid #e8c34b;
    border-radius: 10px;
    text-shadow: 0 2px 10px rgba(0, 0, 0, 0.85);
    box-shadow: 0 0 34px rgba(232, 195, 75, 0.4), inset 0 0 24px rgba(232, 195, 75, 0.25);
    backdrop-filter: blur(1.5px);
    pointer-events: none;
}
.mc-stage.stamped .mc-stamp { animation: mcStamp 0.4s cubic-bezier(0.22, 1.5, 0.36, 1) forwards; }
.mc-stage.stamped.fail .mc-stamp {
    color: #ffc9bd;
    border-color: #c0392b;
    background: rgba(58, 12, 7, 0.45);
    box-shadow: 0 0 34px rgba(192, 57, 43, 0.45), inset 0 0 24px rgba(192, 57, 43, 0.3);
}
.mc-rewards {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 9px;
    min-width: 180px;
    max-height: 60vh;
}
.mc-chip {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-family: 'Cinzel', serif;
    font-weight: 700;
    font-size: 14.5px;
    letter-spacing: 0.5px;
    color: #f4e6c4;
    padding: 5px 14px 5px 9px;
    background: linear-gradient(180deg, rgba(58, 36, 14, 0.92), rgba(30, 17, 6, 0.94));
    border: 1px solid rgba(201, 168, 76, 0.45);
    border-radius: 999px;
    box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
    opacity: 0;
    animation: mcChip 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
.mc-chip img { width: 27px; height: 27px; object-fit: contain; }
.mc-chip.good { color: #ffe9ad; border-color: rgba(232, 195, 75, 0.7); }
.mc-chip.bad { color: #ffb9a8; border-color: rgba(192, 57, 43, 0.6); }
/* A beat that would otherwise render nothing at all — see beatBody(). */
.mc-chip.flat { color: #ddd0b0; border-color: rgba(201, 168, 76, 0.3); font-size: 13px; }

/* Did they have the prerequisites? details.missing, finally on screen. */
.mc-req {
    font-family: 'Cinzel', serif;
    font-weight: 700;
    font-size: 12.5px;
    letter-spacing: 0.6px;
    padding: 3px 13px 4px;
    border-radius: 999px;
    border: 1px dashed rgba(201, 168, 76, 0.5);
    background: rgba(30, 17, 6, 0.72);
    opacity: 0;
    animation: mcChip 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
.mc-req.ok { color: #cfe6c0; border-color: rgba(120, 180, 110, 0.55); }
.mc-req.bad { color: #ffc0ae; border-color: rgba(192, 57, 43, 0.55); }

/* WHICH cards a bulk discard took — the art, not just a count. */
.mc-took {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 7px;
    max-width: 320px;
    opacity: 0;
    animation: mcChip 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
.mc-took-lab, .mc-others-lab {
    width: 100%;
    font-family: 'Cinzel', serif;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: rgba(201, 168, 76, 0.85);
}
.mc-took-card { display: inline-flex; flex-direction: column; align-items: center; width: 54px; gap: 3px; }
.mc-took-card img {
    width: 54px; height: 76px; object-fit: cover;
    border-radius: 4px;
    border: 1px solid rgba(192, 57, 43, 0.7);
    filter: saturate(0.45) brightness(0.72);
    box-shadow: 0 3px 8px rgba(0, 0, 0, 0.55);
}
.mc-took-card em {
    font-style: normal; font-size: 8.5px; line-height: 1.15;
    text-align: center; color: #e6d3ad;
}

/* Who ELSE this resolution moved. */
.mc-others {
    display: flex; flex-direction: column; gap: 4px; max-width: 320px;
    opacity: 0;
    animation: mcChip 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
.mc-other {
    font-family: 'Cinzel', serif; font-size: 12px; letter-spacing: 0.4px;
    color: #e6d3ad;
}
.mc-other b { color: #ffe9ad; font-weight: 700; margin-right: 7px; }
.mc-other.bad b { color: #ffb9a8; }
/* THE consequence of the mission — what you won, or what it just cost you.
   Wyatt: a 30-Scorn failure has to LAND, not read as one chip among six. It
   leads the list, arrives with a slam, and holds the beat open longer. */
.mc-chip.big {
    font-size: 21px;
    padding: 9px 20px 9px 11px;
    letter-spacing: 0.8px;
    animation: mcChipBig 0.52s cubic-bezier(0.22, 1.5, 0.36, 1) forwards;
}
.mc-chip.big img { width: 38px; height: 38px; }
.mc-chip.good.big {
    color: #fff2c8;
    border-color: rgba(232, 195, 75, 0.95);
    background: linear-gradient(180deg, rgba(92, 66, 16, 0.95), rgba(46, 31, 6, 0.96));
    box-shadow: 0 0 26px rgba(232, 195, 75, 0.42), 0 4px 12px rgba(0, 0, 0, 0.6);
}
.mc-chip.bad.big {
    color: #ffd0c2;
    border-color: rgba(192, 57, 43, 0.95);
    background: linear-gradient(180deg, rgba(96, 24, 14, 0.95), rgba(48, 10, 5, 0.96));
    box-shadow: 0 0 26px rgba(192, 57, 43, 0.5), 0 4px 12px rgba(0, 0, 0, 0.6);
}
@keyframes mcChipBig {
    from { opacity: 0; transform: translateX(22px) scale(0.7); }
    60%  { opacity: 1; transform: translateX(0) scale(1.08); }
    to   { opacity: 1; transform: translateX(0) scale(1); }
}
@keyframes mcStamp {
    from { transform: rotate(-14deg) scale(3); opacity: 0; }
    62%  { transform: rotate(-14deg) scale(0.92); opacity: 1; }
    to   { transform: rotate(-14deg) scale(1); opacity: 1; }
}
@keyframes mcChip { from { opacity: 0; transform: translateX(16px) scale(0.85); } to { opacity: 1; } }
@keyframes mcSlideL { from { opacity: 0; transform: translateX(-20px); } }
@keyframes mcCardIn { from { opacity: 0; transform: translateY(16px) scale(0.94); } }

/* ═══ ACTION PANEL — shared body wrapper + table-scene breathing ═════ */

/* Desktop keeps the classic centered column; the card image is a
   table-view feature (shown inside the landscape media query). */
.action-panel .action-card-img { display: none; }
.action-panel .action-body {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    width: 100%;
}

/* Final-card chooser: the card lives in pending, not the hand, so nothing
   blooms beside the panel — the panel itself shows the art (row layout).
   Phones already show it via the landscape block. */
.action-panel.final-choice {
    flex-direction: row;
    align-items: center;
    gap: 18px;
    max-width: min(640px, 94vw);
}
.action-panel.final-choice .action-card-img {
    display: block;
    height: min(310px, 38vh);
    width: auto;
    border-radius: 10px;
    box-shadow: 0 8px 26px rgba(0, 0, 0, 0.6);
}

/* ═══ THE THROW — face-down cards, take-back, gesture hint ══════════ */

/* Your thrown card: face down above your hand until the reveal. */
.thrown-zone {
    position: fixed;
    left: 50%;
    bottom: calc(clamp(133px, 21vh, 230px) + 44px);
    transform: translateX(-50%);
    display: none;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    background: linear-gradient(160deg, rgba(38,24,12,0.94), rgba(24,14,7,0.94));
    border: 1px solid rgba(212,175,55,0.5);
    border-radius: 12px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.55);
    z-index: 2950;
}
.thrown-zone.active { display: flex; }
/* An open stage (rival peek, board, journal, browser, pickers) outranks
   the reminder — the zone returns when the overlay closes. */
body:has(#oppOverlay.active) .thrown-zone,
body:has(#boardOverlay.active) .thrown-zone,
body:has(#missionJournal.active) .thrown-zone,
body:has(#missionLB.active) .thrown-zone,
body:has(#promisePicker.active) .thrown-zone,
body:has(#missionSelect.active) .thrown-zone,
body:has(#handInspectOv.active) .thrown-zone { display: none; }
.tz-cards { position: relative; display: flex; }
.tz-card {
    width: 52px;
    border-radius: 6px;
    border: 1px solid rgba(212,175,55,0.6);
    box-shadow: 0 4px 12px rgba(0,0,0,0.55);
    animation: tzLand 0.38s ease-out;
}
.tz-cards.pair .tz-card.two {
    position: absolute;
    left: 12px;
    top: 6px;
    transform: rotate(7deg);
    z-index: -1;
    animation: none;
}
.tz-cards.pair { margin-right: 10px; }
.tz-side { display: flex; flex-direction: column; gap: 7px; align-items: flex-start; }
.tz-note {
    font-family: 'EB Garamond', serif;
    font-size: 13px;
    color: var(--parchment, #e8d9b5);
    opacity: 0.9;
    white-space: nowrap;
}
.tz-undo { padding: 5px 12px; }
.tz-undo span { font-size: 12px; }
@keyframes tzLand {
    from { transform: translateY(-26px) scale(1.15); opacity: 0; }
    to   { transform: none; opacity: 1; }
}

/* Rivals' face-down throws — sidebar entries and phone seat chips. */
.opp-entry { position: relative; }
.opp-thrown {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 26px;
    border-radius: 4px;
    border: 1px solid rgba(212,175,55,0.65);
    box-shadow: 0 3px 8px rgba(0,0,0,0.5);
    transform: rotate(5deg);
}
.chip-thrown {
    position: absolute;
    top: -7px;
    right: -7px;
    width: 20px;
    border-radius: 3px;
    border: 1px solid rgba(212,175,55,0.7);
    box-shadow: 0 3px 8px rgba(0,0,0,0.55);
    transform: rotate(8deg);
    z-index: 3;
}
.opp-thrown.land, .chip-thrown.land { animation: thrownToss 0.42s ease-out; }
@keyframes thrownToss {
    0%   { transform: translateY(-30px) rotate(-30deg) scale(1.35); opacity: 0; }
    70%  { opacity: 1; }
    100% { transform: rotate(8deg); }
}

/* Next round's hand waits face down during the reveal. */
.hand-card.facedown { pointer-events: none; }
.hand-card.facedown img { filter: brightness(0.82); }
.hand-arc.awaiting { opacity: 0.85; }

/* The throw-gesture hint: a finger pushes a card ghost upward, on loop.
   Replaces the old "pick one card" text prompt — the gesture teaches. */
.throw-hint {
    position: fixed;
    left: 50%;
    bottom: calc(clamp(133px, 21vh, 230px) + 34px);
    transform: translateX(-50%);
    display: none;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    pointer-events: none;
    z-index: 2940;
}
.throw-hint.active { display: flex; }
.th-stage { position: relative; width: 70px; height: 108px; }
.th-card {
    position: absolute;
    left: 50%;
    bottom: 34px;
    width: 44px;
    height: 62px;
    margin-left: -22px;
    border-radius: 5px;
    background: url('../assets/cards/backs/Back Card 1_Brown1.jpg') center/cover;
    border: 1px solid rgba(212,175,55,0.75);
    box-shadow: 0 4px 14px rgba(0,0,0,0.6);
    animation: thCardRise 1.7s ease-in-out infinite;
}
.th-finger {
    position: absolute;
    left: 50%;
    bottom: 0;
    margin-left: -8px;
    filter: drop-shadow(0 3px 6px rgba(0,0,0,0.6));
    animation: thFingerRise 1.7s ease-in-out infinite;
}
@keyframes thCardRise {
    0%, 18%  { transform: translateY(0); opacity: 0.95; }
    62%      { transform: translateY(-44px); opacity: 1; }
    82%, 100%{ transform: translateY(-52px); opacity: 0; }
}
@keyframes thFingerRise {
    0%, 18%  { transform: translateY(0); opacity: 1; }
    62%      { transform: translateY(-44px); opacity: 1; }
    82%, 100%{ transform: translateY(-50px); opacity: 0; }
}
.th-label {
    font-family: 'Cinzel', serif;
    font-size: 12.5px;
    letter-spacing: 0.4px;
    color: #ffd97a;
    text-shadow: 0 2px 6px rgba(0,0,0,0.8);
    background: rgba(20,12,6,0.82);
    border: 1px solid rgba(212,175,55,0.45);
    border-radius: 8px;
    padding: 4px 10px;
    white-space: nowrap;
}

/* Compact landscape: hand strip hugs the bottom — tuck both lower. */
@media (orientation: landscape) and (max-height: 540px) {
    .thrown-zone { bottom: 128px; padding: 7px 10px; gap: 9px; }
    .tz-card { width: 40px; }
    .tz-note { font-size: 11.5px; }
    .throw-hint { bottom: 118px; }
    .th-stage { width: 60px; height: 92px; }
    .th-card { width: 36px; height: 51px; margin-left: -18px; }
    .th-label { font-size: 11px; }
}

@keyframes tvGlowBreathe { 0%, 100% { opacity: 0.85; } 50% { opacity: 1; } }

@keyframes playableBreathe {
    0%, 100% { box-shadow: 0 0 0 2px rgba(140,225,125,0.95), 0 0 18px 4px rgba(120,220,120,0.55); }
    50%      { box-shadow: 0 0 0 2px rgba(140,225,125,0.7),  0 0 10px 2px rgba(120,220,120,0.35); }
}

/* Purse line inside the action sheet — gold where you're spending it. */
.action-purse {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    font-family: 'EB Garamond', serif;
    font-size: 12px;
    color: var(--gold-dark);
    margin-top: 4px;
}
.action-purse img { width: 14px; height: 14px; border-radius: 50%; }
.action-purse b { color: #ffd97a; font-family: 'Cinzel', serif; font-size: 12px; }

/* ═══ A PROMISE — sacrifice picker ═══════════════════════════════════ */
#promisePicker {
    position: fixed; inset: 0; z-index: 10550;
    display: none; align-items: center; justify-content: center;
    background: rgba(8,4,2,0.93);
    backdrop-filter: blur(4px);
}
#promisePicker.active { display: flex; }
.pp-inner { display: flex; flex-direction: column; align-items: center; gap: 10px; max-width: 94vw; max-height: 96dvh; }
.pp-title {
    font-family: 'Cinzel', serif; font-weight: 900; font-size: clamp(18px, 5dvh, 26px);
    letter-spacing: 4px; color: var(--gold-light); text-transform: uppercase;
    text-shadow: 0 0 18px rgba(201,168,76,0.5);
}
.pp-sub { font-family: 'EB Garamond', serif; font-size: 13px; color: #e8d9bf; }
.pp-sub b { color: #8fd4ff; }
.pp-cards {
    display: flex; gap: 10px; flex-wrap: nowrap; overflow-x: auto;
    max-width: 94vw; padding: 10px 6px;
}
/* The Magician's "Pick One": skill tiles instead of card scans — the icon IS
   the label, with your current total and what it becomes. Sized to fit four
   across a 390px-tall phone in landscape without scrolling. */
.pp-cards.skills { flex-wrap: wrap; justify-content: center; gap: 12px; }
.pp-skill {
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    cursor: pointer; flex-shrink: 0;
    width: clamp(84px, 13vw, 108px);
    padding: 10px 6px 8px;
    border-radius: 10px;
    border: 1px solid rgba(201, 168, 76, 0.32);
    background: linear-gradient(180deg, rgba(58, 36, 14, 0.55), rgba(30, 17, 6, 0.66));
    transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s, background 0.15s;
}
.pp-skill img { width: clamp(42px, 6.4vw, 58px); height: auto; display: block; }
.pp-skill-name {
    font-family: 'Cinzel', serif; font-weight: 700; font-size: 13px;
    letter-spacing: 0.4px; color: #f4e6c4;
}
.pp-skill-have { font-size: 12px; color: #c9a84c; }
.pp-skill-have b { color: #ffe9ad; }
.pp-skill:hover { transform: translateY(-3px); border-color: rgba(232, 195, 75, 0.6); }
.pp-skill.chosen {
    border-color: rgba(232, 195, 75, 0.95);
    background: linear-gradient(180deg, rgba(92, 66, 16, 0.85), rgba(46, 31, 6, 0.9));
    box-shadow: 0 0 22px rgba(232, 195, 75, 0.4), inset 0 0 14px rgba(232, 195, 75, 0.14);
    transform: translateY(-3px);
}
.pp-card {
    position: relative; cursor: pointer; flex-shrink: 0;
    border-radius: 6px; transition: transform 0.15s, box-shadow 0.15s;
}
.pp-card img { width: 92px; border-radius: 6px; display: block; box-shadow: 0 6px 16px rgba(0,0,0,0.55); }
.pp-card:hover { transform: translateY(-4px); }
.pp-card .pp-x {
    position: absolute; inset: 0;
    display: none; align-items: center; justify-content: center;
    font-size: 40px; color: #ff6b5e; font-weight: 900;
    background: rgba(60,10,6,0.45); border-radius: 6px;
    text-shadow: 0 2px 8px rgba(0,0,0,0.8);
}
.pp-card.chosen { box-shadow: 0 0 0 2px #ff6b5e, 0 0 18px rgba(255,107,94,0.5); }
.pp-card.chosen .pp-x { display: flex; }
.pp-actions { display: flex; gap: 12px; }

/* Chemical Y flavor of the picker: choosing is a BOON — gold, not
   sacrifice-red — and each card wears its favor math. */
.pp-inner.chemy .pp-card.chosen { box-shadow: 0 0 0 2px var(--gold-light), 0 0 20px rgba(201,168,76,0.6); }
.pp-card .pp-favor {
    position: absolute;
    bottom: 5px; left: 50%;
    transform: translateX(-50%);
    font-family: 'Cinzel', serif;
    font-size: 10px; font-weight: 700;
    color: #ffe9a8;
    background: rgba(20,10,4,0.88);
    border: 1px solid rgba(201,168,76,0.5);
    border-radius: 8px;
    padding: 1px 7px;
    white-space: nowrap;
    text-shadow: 0 1px 3px rgba(0,0,0,0.8);
}

/* ═══ RANK-1 BOON — the realm's #1 chooses a skill ════════════════════
   Rides the #promisePicker overlay: six skill-icon tiles, gold like the
   royal favor it is. No dismiss path — the Queen does not offer twice. */
.pp-inner.boon .boon-tiles {
    display: flex; flex-wrap: wrap; gap: 12px; justify-content: center;
    max-width: min(94vw, 520px); margin: 12px 0 4px;
}
.boon-tile {
    width: 96px; padding: 12px 6px 9px;
    display: flex; flex-direction: column; align-items: center; gap: 7px;
    background: rgba(24,15,7,0.6);
    border: 1px solid rgba(201,168,76,0.28); border-radius: 10px;
    cursor: pointer;
    transition: transform 0.15s, border-color 0.15s, box-shadow 0.15s, background 0.15s;
}
.boon-tile img {
    width: 46px; height: 46px; object-fit: contain;
    filter: drop-shadow(0 3px 7px rgba(0,0,0,0.55));
}
.boon-tile span {
    font-family: 'Cinzel', serif; font-size: 12px; font-weight: 700;
    letter-spacing: 0.05em; color: var(--gold-light);
}
.boon-tile:hover { transform: translateY(-3px); border-color: rgba(232,205,120,0.6); }
.boon-tile.chosen {
    transform: translateY(-3px);
    background: rgba(58,40,14,0.8);
    border-color: var(--gold-light);
    box-shadow: 0 0 0 2px rgba(232,205,120,0.55), 0 0 22px rgba(201,168,76,0.45);
}
/* Short landscape phones: six tiles must fit beside the title + button. */
@media (orientation: landscape) and (max-height: 540px) {
    .boon-tile { width: 76px; padding: 8px 4px 6px; gap: 5px; }
    .boon-tile img { width: 34px; height: 34px; }
    .boon-tile span { font-size: 10px; }
}

/* A doubled adventure card wears its ×2 in the played stacks. */
.stack-card.doubled {
    box-shadow: 0 0 0 2px rgba(255,225,140,0.9), 0 0 16px rgba(201,168,76,0.5), 0 3px 12px rgba(0,0,0,0.65);
}

/* ═══ MULTIPLAYER — searching spinner + waiting pill ═════════════════ */
/* ═══ THE QUEUE CHIP — the background pledge, visible everywhere ═════
   A root-level fixture ABOVE the leaderboard/store panels (10005) so the
   player browses freely while the realm searches; below the pp overlay
   and the MATCH FOUND ring. Elapsed clock + honest Withdraw. */
#queueChip {
    position: fixed;
    top: 10px; left: 50%;
    transform: translateX(-50%) translateY(-64px);
    z-index: 10010;
    display: flex; align-items: center; gap: 10px;
    padding: 8px 12px 8px 16px;
    border-radius: 999px;
    background: linear-gradient(180deg, rgba(42,24,8,0.95), rgba(24,13,5,0.95));
    border: 1px solid rgba(201,168,76,0.55);
    box-shadow: 0 8px 26px rgba(0,0,0,0.55), 0 0 18px rgba(201,168,76,0.12) inset;
    font-family: 'Cinzel', serif; font-size: 12px; letter-spacing: 0.5px;
    color: #e6cf9d;
    opacity: 0; pointer-events: none;
    transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.3s;
    max-width: 94vw;
}
#queueChip.on { opacity: 1; pointer-events: auto; transform: translateX(-50%) translateY(0); }
#queueChip .qc-dot {
    width: 8px; height: 8px; flex-shrink: 0;
    border-radius: 50%;
    background: #ffd97a;
    box-shadow: 0 0 8px rgba(255, 217, 122, 0.8);
    animation: qpPulse 1.4s ease-in-out infinite;
}
#queueChip .qc-main { white-space: nowrap; }
#queueChip .qc-time {
    color: var(--gold-light);
    font-variant-numeric: tabular-nums;
    margin-left: 2px;
}
#queueChip .qc-sub {
    font-family: 'EB Garamond', serif; font-style: italic;
    font-size: 12px; color: rgba(232, 217, 191, 0.75);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    max-width: 34vw;
}
#queueChip .qc-sub b { color: var(--gold-light); font-style: normal; }
#queueChip .qc-x {
    font-family: 'Cinzel', serif; font-size: 10.5px; font-weight: 700;
    letter-spacing: 1px; text-transform: uppercase;
    color: #d8b8a0;
    background: rgba(90, 34, 24, 0.55);
    border: 1px solid rgba(190, 110, 80, 0.45);
    border-radius: 999px;
    padding: 5px 12px;
    cursor: pointer;
    transition: all 0.15s;
}
#queueChip .qc-x:hover { color: #ffd9c4; border-color: rgba(230, 140, 100, 0.8); }
#queueChip.pulse { animation: qcNudge 0.45s ease; }
@keyframes qcNudge {
    30% { transform: translateX(-50%) translateY(0) scale(1.07);
          box-shadow: 0 8px 26px rgba(0,0,0,0.55), 0 0 26px rgba(201,168,76,0.55); }
}
@media (orientation: landscape) and (max-height: 540px) {
    #queueChip { top: 6px; padding: 6px 10px 6px 13px; font-size: 11px; gap: 8px; }
    #queueChip .qc-sub { display: none; }
}

/* ═══ MATCH FOUND — the accept ring (LoL's beat, FAVOR's clothes) ════
   Root body child over EVERY menu surface. The game's own gold ring art
   is the fixture; a conic countdown drains around it; your crest and the
   court's summons ride the center; gold ACCEPT above a quieter crimson
   DECLINE. */
#matchFound {
    position: fixed; inset: 0;
    z-index: 10560;
    display: none;
    align-items: center; justify-content: center;
    background: rgba(8, 4, 2, 0.9);
    backdrop-filter: blur(5px);
}
#matchFound.on { display: flex; }
.mf-stage {
    display: flex; flex-direction: column; align-items: center;
    gap: clamp(10px, 2.6dvh, 22px);
    animation: mfLand 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
@keyframes mfLand {
    from { transform: scale(0.82); opacity: 0; }
}
.mf-ringwrap {
    position: relative;
    width: min(320px, 54dvh);
    height: min(320px, 54dvh);
    filter: drop-shadow(0 14px 34px rgba(0, 0, 0, 0.6));
}
.mf-countring {
    position: absolute; inset: -4.5%;
    border-radius: 50%;
    background: conic-gradient(var(--gold-light) 360deg, rgba(201,168,76,0.13) 360deg);
    -webkit-mask: radial-gradient(closest-side, transparent 88.5%, #000 89.5%);
    mask: radial-gradient(closest-side, transparent 88.5%, #000 89.5%);
    filter: drop-shadow(0 0 12px rgba(255, 217, 122, 0.55));
}
.mf-ringart {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
}
.mf-core {
    position: absolute; inset: 13%;
    border-radius: 50%;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    gap: clamp(3px, 0.9dvh, 8px);
    text-align: center;
    background: radial-gradient(circle at 50% 32%, rgba(64, 38, 12, 0.92), rgba(16, 9, 4, 0.96) 72%);
    box-shadow: 0 0 44px rgba(201, 168, 76, 0.22) inset;
    padding: 4%;
}
.mf-core .av-disc {
    width: clamp(42px, 11dvh, 62px);
    height: clamp(42px, 11dvh, 62px);
    box-shadow: 0 0 0 2px rgba(201, 168, 76, 0.65), 0 4px 14px rgba(0, 0, 0, 0.5);
}
.mf-headline {
    font-family: 'Cinzel', serif; font-weight: 900;
    font-size: clamp(15px, 4.6dvh, 25px);
    letter-spacing: 3px; text-transform: uppercase;
    color: var(--gold-light);
    text-shadow: 0 0 18px rgba(201, 168, 76, 0.55);
}
.mf-sub {
    font-family: 'EB Garamond', serif;
    font-size: clamp(11px, 2.6dvh, 14px);
    letter-spacing: 1px;
    color: #e8d9bf;
}
.mf-clock {
    font-family: 'Cinzel', serif; font-weight: 700;
    font-size: clamp(12px, 3dvh, 16px);
    color: #8fd4ff;
    font-variant-numeric: tabular-nums;
}
.mf-actions {
    display: flex; flex-direction: column; align-items: center;
    gap: clamp(6px, 1.6dvh, 12px);
    min-height: clamp(74px, 16dvh, 96px);
    justify-content: flex-start;
}
.mf-accept { padding: clamp(10px, 2.6dvh, 15px) 52px; font-size: clamp(15px, 3.4dvh, 19px); letter-spacing: 3px; }
.mf-decline {
    font-family: 'Cinzel', serif; font-size: 11.5px; font-weight: 700;
    letter-spacing: 2px; text-transform: uppercase;
    color: #e0a0a0;
    background: rgba(70, 16, 14, 0.6);
    border: 1px solid rgba(190, 80, 70, 0.5);
    border-radius: 9px;
    padding: 8px 26px;
    cursor: pointer;
    transition: all 0.15s;
}
.mf-decline:hover { color: #ffc4c4; border-color: rgba(235, 120, 100, 0.85); background: rgba(96, 22, 18, 0.7); }
.mf-wait {
    font-family: 'EB Garamond', serif; font-size: 15px;
    color: #e8d9bf; text-align: center;
    padding-top: 8px;
    animation: qpPulse 1.6s ease-in-out infinite;
}
.mf-wait b { color: var(--gold-light); font-family: 'Cinzel', serif; }

/* ═══ THE PICK CLOCK — 20 seconds to choose your hero ═══════════════ */
.qp-clock {
    font-family: 'Cinzel', serif; font-weight: 900;
    font-size: 15px;
    color: var(--gold-light);
    font-variant-numeric: tabular-nums;
    margin-left: 6px;
    text-shadow: 0 0 10px rgba(201, 168, 76, 0.5);
}
.qp-clock.hot {
    color: #ff9f8f;
    text-shadow: 0 0 12px rgba(255, 110, 90, 0.7);
    animation: qpPulse 0.6s ease-in-out infinite;
}

/* Non-modal "waiting on {noble}" pill — top-center, under the phase bar,
   never eats a click. The clock counts down Wyatt's 2-minute AFK boot. */
#mpWait {
    position: fixed; top: 58px; left: 50%;
    transform: translateX(-50%) translateY(-12px);
    z-index: 9500; pointer-events: none;
    padding: 7px 18px; border-radius: 20px;
    background: rgba(24,14,6,0.92);
    border: 1px solid rgba(201,168,76,0.5);
    box-shadow: 0 6px 18px rgba(0,0,0,0.5);
    font-family: 'EB Garamond', serif; font-size: 14px; color: #e8d9bf;
    opacity: 0; transition: opacity 0.25s, transform 0.25s;
}
#mpWait.on { opacity: 1; transform: translateX(-50%) translateY(0); }
#mpWait b { color: var(--gold-light); font-family: 'Cinzel', serif; font-size: 13px; }
#mpWait .mpw-clock {
    margin-left: 8px; color: #8fd4ff; font-variant-numeric: tabular-nums;
}
@media (orientation: landscape) and (max-height: 540px) {
    #mpWait { top: 44px; font-size: 12px; padding: 5px 14px; }
}

/* ═══ BORROW & PLAY — pick your lender ═══════════════════════════════
   Rides the #promisePicker overlay: one card per possible lender, the
   neighbor with nothing to lend sits grayed with the reason. */
/* Multi-skill borrows can outgrow the screen: the section list scrolls
   on its own while the title and Confirm/Cancel stay pinned in reach. */
/* Mission turn-in order picker (solo) — tap cards to number them. */
.mo-due { max-width: min(760px, 94vw); }
.mo-grid { display: flex; flex-wrap: wrap; gap: 14px; justify-content: center; padding: 8px 4px; max-height: 60dvh; overflow-y: auto; }
.mo-card {
    position: relative; width: 130px; cursor: pointer;
    display: flex; flex-direction: column; align-items: center; gap: 6px;
    border-radius: 10px; padding: 6px; border: 2px solid rgba(201,168,76,0.35);
    background: rgba(18,10,5,0.6); transition: transform .15s, border-color .15s, box-shadow .15s;
}
.mo-card img { width: 100%; border-radius: 7px; box-shadow: 0 4px 12px rgba(0,0,0,0.5); }
.mo-card:hover { transform: translateY(-3px); border-color: var(--gold-light); }
.mo-card.picked { border-color: var(--gold); box-shadow: 0 0 16px rgba(232,195,75,0.45); opacity: .92; }
.mo-badge {
    position: absolute; top: -8px; right: -8px; z-index: 2;
    width: 30px; height: 30px; border-radius: 50%;
    display: grid; place-items: center;
    font: 700 15px 'Cinzel', serif; color: #2a1810;
    background: linear-gradient(180deg, #f0d278, #c9a84c); border: 2px solid #8a6a1f;
    box-shadow: 0 2px 8px rgba(0,0,0,0.5);
}
.mo-name { font-family: 'Cinzel', serif; font-size: 11px; font-weight: 700; color: var(--gold-light); text-align: center; line-height: 1.15; }

.pp-inner.bw { flex-wrap: nowrap; }

/* Mission-due chooser: mission card on the SIDE, boards + fail door beside it
   so nothing hides below the fold (Wyatt 7/17). The boards SCROLL and the
   Confirm/Fail row stays pinned — a multi-skill borrow used to push the
   buttons off-screen and strand the player (Wyatt 7/17 pm). Stacks on narrow. */
.pp-inner.bw.mb-due { max-width: min(1040px, 96vw); max-height: 94dvh; overflow: hidden; }
.mb-due .mb-layout {
    display: flex; align-items: center; justify-content: center;
    gap: 26px; min-height: 0; width: 100%;
    max-height: calc(94dvh - 56px);
}
.mb-due .mb-mission { flex: 0 0 auto; align-self: center; }
.mb-due .mb-mission img {
    display: block; width: auto; height: min(46dvh, 340px);
    border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,0.6);
}
.mb-due .mb-choose {
    display: flex; flex-direction: column; align-items: center;
    gap: 10px; min-height: 0; min-width: 0;
}
.mb-due .mb-choose .pp-sub { flex: 0 0 auto; text-align: center; max-width: 460px; }
/* The boards scroll within a viewport-bounded band; the Confirm/Fail row
   sits OUTSIDE it and always stays on screen (fixes the multi-skill stuck). */
.mb-due .mb-choose .bw-scroll {
    flex: 0 1 auto; min-height: 0; max-height: calc(94dvh - 210px);
    overflow-y: auto; padding: 4px 10px;
    display: flex; flex-direction: column; gap: 14px;
}
.mb-due .mb-choose .pp-actions { flex: 0 0 auto; }
@media (max-width: 720px), (max-aspect-ratio: 1/1) {
    .mb-due .mb-layout { flex-direction: column; gap: 10px; }
    .mb-due .mb-mission img { height: min(24dvh, 190px); }
    .mb-due .mb-choose .bw-scroll { max-height: calc(94dvh - 300px); }
}
.pp-inner.bw .bw-scroll {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    overflow-y: auto;
    min-height: 0;
    max-width: 94vw;
    padding: 8px 16px;   /* room for the selection glow */
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
}
.bw-section { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.bw-skill-head {
    font-family: 'Cinzel', serif; font-size: 12px; font-weight: 700;
    letter-spacing: 2px; color: var(--gold-light); text-transform: uppercase;
    margin-top: 4px;
}
.bw-rows { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }
.bw-row {
    display: flex; flex-direction: column; align-items: center; gap: 5px;
    width: 168px; padding: 10px 10px 12px; cursor: pointer;
    border: 1.5px solid rgba(201,168,76,0.45); border-radius: 12px;
    background: linear-gradient(160deg, rgba(50,28,13,0.9), rgba(26,13,5,0.9));
    transition: transform 0.15s, box-shadow 0.15s;
}
.bw-row:hover { transform: translateY(-3px); box-shadow: 0 0 0 2px rgba(240,210,120,0.8), 0 8px 20px rgba(0,0,0,0.5); }
.bw-row.on { box-shadow: 0 0 0 2px var(--gold-light), 0 0 20px rgba(201,168,76,0.6); }
.bw-row.off { opacity: 0.45; filter: grayscale(0.85); cursor: default; pointer-events: none; }
.bw-art {
    width: 146px; height: 92px; object-fit: cover; object-position: top;
    border-radius: 7px; box-shadow: 0 4px 12px rgba(0,0,0,0.5);
}
.bw-tag {
    font: 700 9px 'Cinzel', serif; letter-spacing: 0.5px; color: #2a1810;
    background: linear-gradient(180deg, #f0d278, #c9a84c);
    border: 1px solid #8a6a1f; border-radius: 8px; padding: 2px 8px;
    margin-top: -14px; position: relative; z-index: 2;
    box-shadow: 0 2px 6px rgba(0,0,0,0.5);
}
.bw-name { font-family: 'Cinzel', serif; font-size: 13px; font-weight: 700; color: var(--gold-light); }
.bw-note { font-family: 'EB Garamond', serif; font-size: 12px; color: #e8d9bf; }
.bw-row.off .bw-note { color: #c9a06a; font-style: italic; }

/* ═══ SLIDE CONFIRM SKIN — worn by #boardOvConfirm inside the board ══ */
.sc-bubble {
    background: linear-gradient(160deg, rgba(50,28,13,0.98), rgba(26,13,5,0.98));
    border: 1.5px solid var(--gold);
    border-radius: 12px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.7), 0 0 18px rgba(201,168,76,0.25);
    padding: 10px 14px;
    display: flex; flex-direction: column; gap: 6px; align-items: center;
    min-width: 210px;
}
.sc-text { font-family: 'EB Garamond', serif; font-size: 14px; color: #efe2c8; }
.sc-text b, .sc-cost b { color: var(--gold-light); }
.sc-cost { font-family: 'Cinzel', serif; font-size: 11px; color: #ffd97a; letter-spacing: 0.5px; }
.sc-actions { display: flex; gap: 8px; margin-top: 2px; }
.sc-actions .btn-royal { padding: 6px 14px; font-size: 11px; min-width: 0; }


/* ═══ ACHIEVEMENTS ═══════════════════════════════════════════════════
   Tier colour is the only thing that varies — it derives from the Stars
   reward, exactly as in Nation (Bronze 10 / Silver 20 / Gold 30 /
   Platinum 50 / Legendary 200). Seal + rule pick it up via --tc.        */
.ach-bronze    { --tc: #ff9d4d; --tc2: #a85a1e; }
.ach-silver    { --tc: #e2e8f2; --tc2: #838d9c; }
.ach-gold      { --tc: #ffd23f; --tc2: #c48a0c; }
.ach-platinum  { --tc: #4bf0e6; --tc2: #1f9c9c; }
.ach-legendary { --tc: #d977ff; --tc2: #8a1fd0; }

/* ── Unlock celebration ── */
.ach-pop {
    position: fixed; inset: 0; z-index: 10000;
    display: flex; align-items: center; justify-content: center;
    background: rgba(8, 5, 2, 0.78);
    opacity: 0; transition: opacity .26s ease;
}
.ach-pop.in { opacity: 1; }
.ach-card {
    position: relative; width: min(420px, 88vw);
    padding: 30px 26px 24px; text-align: center;
    background: linear-gradient(#2a2012, #17110a);
    border: 2px solid var(--tc); border-radius: 10px;
    box-shadow: 0 0 0 1px rgba(0,0,0,.6), 0 18px 60px rgba(0,0,0,.65),
                0 0 46px -8px var(--tc);
    transform: translateY(14px) scale(.96);
    transition: transform .3s cubic-bezier(.2,.9,.3,1.2);
}
.ach-pop.in .ach-card { transform: none; }
.ach-tier {
    position: absolute; top: 10px; left: 50%; transform: translateX(-50%);
    font-size: 10px; letter-spacing: .22em; text-transform: uppercase;
    color: var(--tc);
}
.ach-seal {
    width: 66px; height: 66px; margin: 10px auto 14px;
    display: grid; place-items: center; border-radius: 50%;
    background: radial-gradient(circle at 35% 30%, var(--tc), var(--tc2));
    box-shadow: 0 0 22px -4px var(--tc), inset 0 -3px 8px rgba(0,0,0,.35);
    font-size: 30px; color: #2a1c06;
}
.ach-kicker {
    font-size: 11px; letter-spacing: .18em; text-transform: uppercase;
    color: #b39a6a; margin-bottom: 6px;
}
.ach-name { margin: 0 0 8px; font-size: 24px; color: #f4e6c8; }
.ach-desc { margin: 0 0 16px; font-size: 14px; color: #c3ae86; line-height: 1.5; }
.ach-stars {
    font-size: 20px; font-weight: 700; color: var(--tc);
    margin-bottom: 18px; font-variant-numeric: tabular-nums;
}

/* ── Gallery ── */
.ach-gallery {
    position: fixed; inset: 0; z-index: 9500; display: none;
    align-items: center; justify-content: center;
    background: rgba(8, 5, 2, 0.82);
}
.ach-gallery.open { display: flex; }
.ach-inner {
    position: relative;
    width: min(880px, 94vw); max-height: min(88vh, calc(100dvh - 14px)); display: flex; flex-direction: column;
    background: linear-gradient(#241b0f, #14100a);
    border: 2px solid #8a6a1f; border-radius: 10px;
    box-shadow: 0 24px 70px rgba(0,0,0,.7);
}
.ach-head {
    position: relative; padding: 18px 22px 14px;
    border-bottom: 1px solid #3a2d17;
}
.ach-title { font-size: 22px; color: #f0dfb8; }
.ach-sub { font-size: 12.5px; color: #a8926a; margin-top: 3px; font-variant-numeric: tabular-nums; }
.ach-x {
    position: absolute; top: 14px; right: 14px;
    background: none; border: none; color: #a8926a; font-size: 18px; cursor: pointer;
}
.ach-x:hover, .ach-x:focus-visible { color: #f0dfb8; outline: none; }
/* The grid scrolls; the fade says so — a half row at the panel's lip
   read as "cut off" on Wyatt's phone (7/17), not as "more below". */
.ach-inner::after {
    content: ''; position: absolute; left: 3px; right: 3px; bottom: 3px;
    height: 24px; border-radius: 0 0 8px 8px; pointer-events: none;
    background: linear-gradient(transparent, rgba(18, 14, 9, 0.92));
}
.ach-grid {
    padding: 16px 16px 24px; overflow-y: auto;
    /* FLEX-WRAP, deliberately NOT css grid (Wyatt 7/20, Overlap.jpg):
       grid sized its row tracks off pre-fontload metrics and pinned them
       at the 62px minimum; when Cinzel/Garamond swapped in, cells grew to
       82-100px inside 62px rows and every row painted over the next on
       some devices. Flex rows always size to their content. */
    display: flex; flex-wrap: wrap; align-items: stretch; gap: 10px;
}
.ach-cell {
    position: relative; min-height: 62px;
    flex: 1 1 270px; min-width: 270px; max-width: 100%;
    display: grid; grid-template-columns: 44px 1fr auto; align-items: center; gap: 12px;
    padding: 12px 14px; border-radius: 9px;
    background: #1c150c; border: 1px solid #3a2d17;
    border-left: 4px solid var(--tc);
    transition: transform .12s;
}
/* Unlocked achievements light up in their tier colour — a tinted wash,
   a coloured border and a soft outer glow so earned trophies POP (Wyatt
   7/17: "colours can be a lot more exciting"). */
.ach-cell.got {
    background:
        linear-gradient(105deg, color-mix(in srgb, var(--tc) 22%, transparent) 0%,
                                 color-mix(in srgb, var(--tc) 6%, transparent) 42%, #1c150c 78%);
    border-color: color-mix(in srgb, var(--tc) 55%, #3a2d17);
    box-shadow: 0 0 18px -6px var(--tc), inset 0 1px 0 rgba(255,255,255,.05);
}
.ach-cell.got:hover { transform: translateY(-1px); }
.ach-cell.locked { opacity: .5; border-left-color: #4a3c22; }
.ach-cell-seal {
    width: 40px; height: 40px; display: grid; place-items: center; border-radius: 50%;
    background: #2c2213; color: var(--tc); font-size: 18px;
    border: 1px solid color-mix(in srgb, var(--tc) 40%, transparent);
}
.ach-cell.got .ach-cell-seal {
    background: radial-gradient(circle at 35% 30%, var(--tc), var(--tc2)); color: #2a1c06;
    box-shadow: 0 0 14px -3px var(--tc); border-color: transparent;
}
.ach-cell-body { min-width: 0; }
.ach-cell-body b { display: block; font-size: 14.5px; color: #f2e4c2; line-height: 1.25; }
.ach-cell.got .ach-cell-body b { color: #fff3d6; }
.ach-cell-body span { display: block; font-size: 12.5px; color: #cbb488; line-height: 1.4; margin-top: 3px; }
.ach-cell.secret .ach-cell-body b { letter-spacing: .12em; }
.ach-cell-stars {
    display: flex; flex-direction: column; align-items: flex-end; gap: 2px;
    font-size: 14px; font-weight: 700; color: var(--tc);
    font-variant-numeric: tabular-nums;
    text-shadow: 0 0 10px color-mix(in srgb, var(--tc) 50%, transparent);
}
.ach-cell-tier {
    font-size: 8px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
    color: var(--tc); opacity: .85;
}

@media (prefers-reduced-motion: reduce) {
    .ach-pop, .ach-card { transition: none; }
}

/* The mission card rides ABOVE the lender rows in the borrow chooser — you are
   deciding about a card, so the card is on screen (never a text recap of it).
   It shares the .bw-scroll so a multi-skill borrow can still scroll past it. */
.pp-inner.bw .pp-cards.mb-card { margin: 0 0 14px; }
.pp-inner.bw .pp-cards.mb-card .pp-card img {
    width: auto; height: min(26vh, 230px);
    border-radius: 6px; box-shadow: 0 6px 22px rgba(0,0,0,0.6);
}

/* ═══ MODE OVERLAYS — Wanted · Skirmish · Private Game ═══ */

/* ── Wanted (daily rival) intro plaque ── */
.rival-intro {
    position: fixed; inset: 0; z-index: 10540;
    display: none; align-items: center; justify-content: center;
    background: rgba(8, 4, 2, 0.9);
}
.rival-intro.active { display: flex; }
.ri-inner {
    position: relative;
    box-sizing: border-box;
    display: flex; flex-direction: column; align-items: center; gap: 8px;
    max-width: min(420px, 92vw); max-height: min(92vh, calc(100dvh - 16px)); overflow-y: auto;
    padding: 22px 26px;
    background: linear-gradient(160deg, rgba(46, 28, 12, 0.98), rgba(24, 13, 6, 0.98));
    border: 1px solid rgba(212, 175, 55, 0.55);
    border-radius: 14px;
    box-shadow: 0 18px 50px rgba(0, 0, 0, 0.7);
}
.ri-title {
    font-family: 'Cinzel', serif; font-size: 20px; color: var(--gold, #d4af37);
    letter-spacing: 1.5px; text-transform: uppercase;
}
.ri-art {
    width: min(220px, 60vw); border-radius: 10px;
    border: 1px solid rgba(212, 175, 55, 0.5);
    box-shadow: 0 8px 26px rgba(0, 0, 0, 0.6);
}
.ri-art.beaten { filter: grayscale(0.8) brightness(0.7); }
.ri-stamp {
    position: absolute; top: 42%; left: 50%;
    transform: translate(-50%, -50%) rotate(-14deg);
    font-family: 'Cinzel', serif; font-size: 30px; font-weight: 700;
    color: #e8c34b; border: 3px solid #e8c34b; border-radius: 8px;
    padding: 2px 16px; letter-spacing: 4px;
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.8);
    background: rgba(20, 12, 6, 0.55);
    pointer-events: none;
}
.ri-name { font-family: 'Cinzel', serif; font-size: 24px; color: #ffd97a; }
.ri-sub { font-family: 'EB Garamond', serif; font-size: 14px; color: var(--parchment, #e8d9b5); opacity: 0.85; }
.ri-stakes {
    font-family: 'EB Garamond', serif; font-size: 15px; text-align: center;
    color: var(--parchment, #e8d9b5); padding: 4px 6px;
}
/* Same fit rules the room lobby earned (7/16): two .btn-royal at their
   280px min-width overflow a 420px panel — let them split the row instead.
   The stock 48px side padding then eats the label (.btn-royal clips its
   overflow), so action-row buttons wear slim sides. */
.ri-actions { display: flex; gap: 10px; margin-top: 6px; width: 100%; }
.ri-actions .btn-royal { flex: 1; min-width: 0; padding: 14px 10px; }
.ri-actions .btn-royal span { white-space: nowrap; }

/* ── Private room door + lobby ── */
.room-overlay {
    position: fixed; inset: 0; z-index: 10540;
    display: none; align-items: center; justify-content: center;
    background: rgba(8, 4, 2, 0.9);
}
.room-overlay.active { display: flex; }
.rm-inner {
    box-sizing: border-box;
    display: flex; flex-direction: column; align-items: center; gap: 12px;
    width: min(560px, 94vw); max-height: 94vh; overflow: hidden auto;
    padding: 30px 38px;
    background: linear-gradient(160deg, rgba(46, 28, 12, 0.98), rgba(24, 13, 6, 0.98));
    border: 1px solid rgba(212, 175, 55, 0.55);
    border-radius: 14px;
    box-shadow: 0 18px 50px rgba(0, 0, 0, 0.7);
}
.rm-lobby { width: min(600px, 94vw); gap: 13px; }
.rm-or {
    font-family: 'EB Garamond', serif; font-size: 13px; font-style: italic;
    color: var(--parchment, #e8d9b5); opacity: 0.55;
}
.rm-note {
    font-family: 'EB Garamond', serif; font-size: 13px;
    color: var(--parchment, #e8d9b5); opacity: 0.6;
}
/* Two stacked notes read as one quiet block, not two lobby rows. */
.rm-note + .rm-note { margin-top: -9px; }
.rm-status {
    font-family: 'EB Garamond', serif; font-size: 14px; min-height: 18px;
    color: #ffd97a; opacity: 0.9;
}
.rm-actions { width: 100%; display: flex; gap: 12px; margin-top: 2px; }
.rm-actions .btn-royal { flex: 1; min-width: 0; }
.rm-actions .btn-royal span { white-space: nowrap; }
.rm-title {
    font-family: 'Cinzel', serif; font-size: 20px; color: var(--gold, #d4af37);
    letter-spacing: 1.5px; text-transform: uppercase;
}
.rm-sub {
    font-family: 'EB Garamond', serif; font-size: 14px; text-align: center;
    color: var(--parchment, #e8d9b5); opacity: 0.85;
}
.rm-code {
    font-family: 'Cinzel', serif; font-size: 34px; font-weight: 700;
    color: #ffd97a; letter-spacing: 10px; padding: 6px 18px 6px 28px;
    border: 1px dashed rgba(212, 175, 55, 0.6); border-radius: 10px;
    background: rgba(0, 0, 0, 0.3);
    user-select: all;
}
.rm-join { display: flex; gap: 8px; align-items: center; }
.rm-join input {
    width: 120px; padding: 9px 10px;
    font-family: 'Cinzel', serif; font-size: 18px; letter-spacing: 4px;
    text-align: center; text-transform: uppercase;
    color: #ffd97a; background: rgba(0, 0, 0, 0.35);
    border: 1px solid rgba(212, 175, 55, 0.5); border-radius: 8px;
    outline: none;
}
.rm-join input::placeholder { color: rgba(232, 217, 181, 0.35); letter-spacing: 2px; }
.rm-size { align-self: center; }
.rm-list {
    box-sizing: border-box;
    width: 100%; display: flex; flex-direction: column; gap: 8px;
    padding: 12px; border-radius: 10px;
    background: rgba(0, 0, 0, 0.25);
    border: 1px solid rgba(212, 175, 55, 0.25);
}
.rm-row {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 14px; border-radius: 8px;
    background: rgba(212, 175, 55, 0.08);
    font-family: 'EB Garamond', serif; font-size: 16px;
    color: var(--parchment, #e8d9b5);
}
.rm-row.host { border: 1px solid rgba(212, 175, 55, 0.35); }
.rm-row.open { opacity: 0.5; font-style: italic; }
.rm-crown { width: 18px; text-align: center; color: #ffd97a; }
.rm-back { margin-top: 2px; }

/* ── Emotes — the tray, the button, the bubble ── */
.emote-btn {
    position: fixed; right: 14px; bottom: 46px; z-index: 2960;
    width: 44px; height: 44px; border-radius: 50%;
    background: linear-gradient(160deg, #3a2412, #201108);
    border: 1px solid rgba(212, 175, 55, 0.55);
    display: none; align-items: center; justify-content: center;
    cursor: pointer;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);
}
body:has(#game-screen.active) .emote-btn.on { display: flex; }
.emote-btn img { width: 26px; height: 26px; }
.emote-btn:hover { border-color: rgba(212, 175, 55, 0.9); }
.emote-tray {
    position: fixed; right: 12px; bottom: 96px; z-index: 2961;
    display: none; flex-direction: column; gap: 6px;
    padding: 8px;
    background: rgba(24, 14, 7, 0.95);
    border: 1px solid rgba(212, 175, 55, 0.5); border-radius: 12px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.6);
}
.emote-tray.active { display: flex; }
.emote-tray img { width: 40px; height: 40px; cursor: pointer; transition: transform 0.12s ease-out; }
.emote-tray img:hover { transform: scale(1.18); }
.emote-bubble {
    position: fixed; z-index: 10530;
    width: 54px; height: 54px;
    background: rgba(20, 12, 6, 0.92);
    border: 1px solid rgba(212, 175, 55, 0.65);
    border-radius: 50% 50% 50% 12%;
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.55);
    animation: emoteIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
    pointer-events: none;
}
.emote-bubble img { width: 38px; height: 38px; }
.emote-bubble.out { opacity: 0; transform: translateY(-10px); transition: all 0.4s ease-out; }
@keyframes emoteIn { from { opacity: 0; transform: translateY(14px) scale(0.6); } }

/* Compact landscape: the trio tightens; the emote button ducks the hand. */
@media (orientation: landscape) and (max-height: 540px) {
    .emote-btn { right: 10px; bottom: 148px; width: 38px; height: 38px; }
    .emote-btn img { width: 22px; height: 22px; }
    .emote-tray { right: 8px; bottom: 192px; }
    .emote-tray img { width: 34px; height: 34px; }
    .rm-code { font-size: 26px; letter-spacing: 7px; }
}

/* ═══ DAILY RIVAL PLAQUE — Nation's Challenger, worn on the menu ═══ */
.drp {
    grid-area: rival;
    justify-content: flex-start;
    gap: 4px;
    padding: 9px 10px 10px;
    min-height: 158px;
    border-color: rgba(232, 195, 75, 0.85);
    box-shadow: 0 0 22px rgba(201, 168, 76, 0.22), 0 6px 18px rgba(0, 0, 0, 0.55);
    /* The ! badge overhangs the corner OVER the card edge (Wyatt 7/16) —
       the ts-card overflow clip was cutting it off. Nothing else in this
       card reaches the edges, so visible is safe; z-index keeps the badge
       above the neighboring tiles it leans toward. */
    overflow: visible;
    z-index: 1;
}
.drp-head {
    font-family: 'Cinzel', serif; font-size: 12px; font-weight: 700;
    letter-spacing: 2.5px; text-transform: uppercase;
    color: var(--gold, #d4af37);
}
.drp-badge {
    position: absolute; top: -7px; right: -7px; z-index: 2;
    width: 22px; height: 22px; border-radius: 50%;
    background: radial-gradient(circle at 35% 30%, #ff5a4e, #a31408);
    border: 1px solid #ffd97a;
    color: #fff; font-family: 'Cinzel', serif; font-weight: 900; font-size: 14px;
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.6);
    animation: drpPulse 2.2s ease-in-out infinite;
}
@keyframes drpPulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.12); } }
.drp-frame {
    position: relative;
    width: 86%;
    border: 1px solid rgba(212, 175, 55, 0.7);
    border-radius: 6px;
    overflow: hidden;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.55);
}
.drp-art { display: block; width: 100%; height: 58px; object-fit: cover; object-position: center 32%; }
.drp.beaten .drp-art { filter: grayscale(0.85) brightness(0.65); }
.drp-stamp {
    position: absolute; top: 50%; left: 50%;
    transform: translate(-50%, -50%) rotate(-12deg);
    font-family: 'Cinzel', serif; font-size: 15px; font-weight: 900;
    letter-spacing: 3px; color: #e8c34b;
    border: 2px solid #e8c34b; border-radius: 5px; padding: 1px 8px;
    background: rgba(20, 12, 6, 0.55);
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.8);
}
.drp-name {
    max-width: 94%;
    font-family: 'Cinzel', serif; font-size: 12px; font-weight: 700;
    letter-spacing: 0.6px; text-transform: uppercase; text-align: center;
    color: #ffd97a; line-height: 1.25;
}
.drp-stars {
    font-family: 'Cinzel', serif; font-size: 12px; font-weight: 700;
    color: var(--parchment, #e8d9b5);
}
.drp-stars b { color: #e8c34b; }
.drp-clock {
    font-family: 'Cinzel', serif; font-size: 14px; font-weight: 700;
    font-variant-numeric: tabular-nums; letter-spacing: 2px;
    color: #ffd97a; opacity: 0.9;
}

/* ═══ SKIRMISH — the 3/4/5 door ═══ */
.sk-sizes { display: flex; gap: 14px; margin: 10px 0 6px; }
.sk-size {
    display: flex; flex-direction: column; align-items: center; gap: 1px;
    width: 92px; padding: 14px 0 11px;
    background: linear-gradient(160deg, rgba(58, 36, 18, 0.95), rgba(32, 17, 8, 0.95));
    border: 1px solid rgba(212, 175, 55, 0.5); border-radius: 12px;
    cursor: pointer;
    transition: transform 0.14s ease, border-color 0.14s ease, box-shadow 0.14s ease;
}
.sk-size:hover, .sk-size:focus-visible {
    transform: translateY(-2px);
    border-color: var(--gold-light, #ffd97a);
    box-shadow: 0 0 18px rgba(201, 168, 76, 0.3);
    outline: none;
}
.sk-size b { font-family: 'Cinzel', serif; font-size: 32px; font-weight: 900; color: #ffd97a; line-height: 1; }
.sk-size span {
    font-family: 'Cinzel', serif; font-size: 10.5px; letter-spacing: 1.5px;
    text-transform: uppercase; color: var(--parchment, #e8d9b5); opacity: 0.8;
}

/* Compact landscape: the plaque and lobby tighten with the grid. */
@media (orientation: landscape) and (max-height: 540px) {
    .drp { min-height: 118px; gap: 2px; padding: 6px 8px 7px; }
    .drp-head { font-size: 9.5px; letter-spacing: 2px; }
    .drp-art { height: 38px; }
    .drp-name { font-size: 9.5px; }
    .drp-stars { font-size: 10px; }
    .drp-clock { font-size: 11px; }
    .drp-badge { width: 18px; height: 18px; font-size: 11px; top: -6px; right: -6px; }
    .rm-inner, .rm-lobby { padding: 18px 22px; gap: 8px; }
    .rm-row { padding: 7px 10px; font-size: 13.5px; }
    .sk-sizes { gap: 10px; }
    .sk-size { width: 74px; padding: 10px 0 8px; }
    .sk-size b { font-size: 24px; }

    /* Short-landscape fit (Wyatt's 7/17 phone shots): the WANTED intro
       must fit WHOLE — buttons below the fold read as a broken screen,
       and nobody scrolls a plaque. Art gives the ground; text tightens. */
    .ri-inner { max-height: calc(100dvh - 14px); padding: 10px 18px 12px; gap: 4px; }
    .ri-title { font-size: 14px; letter-spacing: 1px; }
    .ri-art { width: auto; max-width: 58vw; max-height: 28dvh; }
    .ri-name { font-size: 15px; }
    .ri-sub { font-size: 11px; }
    .ri-stakes { font-size: 11.5px; }
    .ri-actions { margin-top: 2px; gap: 8px; }
    .ri-actions .btn-royal { padding: 8px 8px; font-size: 11.5px; letter-spacing: 2px; }
    .ri-stamp { font-size: 20px; padding: 1px 10px; }
    .ach-inner { max-height: calc(100dvh - 12px); }
    .ach-head { padding: 9px 16px 7px; }
    .ach-title { font-size: 16px; }
    .ach-sub { font-size: 11px; margin-top: 1px; }
    .ach-grid { padding: 10px 12px 16px; gap: 7px; }
}
/* ── Table skins (cosmetic play surfaces) ──────────────────────────────
   A skin is a MATERIAL, never a scene: dark-to-mid value, low contrast,
   and every skin keeps the same warm center-light vignette so cards and
   text read identically on all of them. */
#game-screen.skin-leather, .tsw-leather {
    background:
        radial-gradient(ellipse at 50% 40%, rgba(60,24,20,0.0) 0%, rgba(26,10,8,0.42) 62%, rgba(14,6,4,0.72) 100%),
        url('../assets/ui/table-leather.jpg');
    background-size: 100% 100%, 640px;
}
#game-screen.skin-velvet, .tsw-velvet {
    background:
        radial-gradient(ellipse at 50% 40%, rgba(40,10,10,0.05) 0%, rgba(22,6,6,0.5) 60%, rgba(10,3,3,0.76) 100%),
        linear-gradient(rgba(20,5,5,0.34), rgba(20,5,5,0.34)),
        url('../assets/ui/table-velvet.jpg');
    background-size: 100% 100%, 100% 100%, 560px;
}
#game-screen.skin-queens, .tsw-queens {
    /* every layer's size lives IN the shorthand — a trailing background-size
       would resize the inlay LINES into full gold SHEETS (learned the hard way) */
    background:
        linear-gradient(rgba(214,178,102,0.42), rgba(214,178,102,0.42)) 10px 10px / calc(100% - 20px) 2px no-repeat,
        linear-gradient(rgba(214,178,102,0.42), rgba(214,178,102,0.42)) 10px calc(100% - 12px) / calc(100% - 20px) 2px no-repeat,
        linear-gradient(rgba(214,178,102,0.42), rgba(214,178,102,0.42)) 10px 10px / 2px calc(100% - 20px) no-repeat,
        linear-gradient(rgba(214,178,102,0.42), rgba(214,178,102,0.42)) calc(100% - 12px) 10px / 2px calc(100% - 20px) no-repeat,
        linear-gradient(rgba(214,178,102,0.22), rgba(214,178,102,0.22)) 17px 17px / calc(100% - 34px) 1px no-repeat,
        linear-gradient(rgba(214,178,102,0.22), rgba(214,178,102,0.22)) 17px calc(100% - 18px) / calc(100% - 34px) 1px no-repeat,
        linear-gradient(rgba(214,178,102,0.22), rgba(214,178,102,0.22)) 17px 17px / 1px calc(100% - 34px) no-repeat,
        linear-gradient(rgba(214,178,102,0.22), rgba(214,178,102,0.22)) calc(100% - 18px) 17px / 1px calc(100% - 34px) no-repeat,
        radial-gradient(ellipse at 50% 40%, rgba(44,26,66,0.08) 0%, rgba(22,12,36,0.52) 60%, rgba(9,5,18,0.8) 100%) 0 0 / 100% 100% no-repeat,
        linear-gradient(rgba(16,9,28,0.5), rgba(16,9,28,0.5)) 0 0 / 100% 100% no-repeat,
        url('../assets/ui/table-queens.jpg') 0 0 / 560px repeat;
}
/* Round-2 skins (2026-07-21): pattern-forward per the round-1 lesson —
   damask/line-work patterns read as a table, material photos don't. */
#game-screen.skin-emerald, .tsw-emerald {
    background:
        radial-gradient(ellipse at 50% 40%, rgba(10,30,20,0.05) 0%, rgba(6,20,13,0.5) 60%, rgba(3,10,6,0.78) 100%) 0 0 / 100% 100% no-repeat,
        linear-gradient(rgba(6,18,12,0.32), rgba(6,18,12,0.32)) 0 0 / 100% 100% no-repeat,
        url('../assets/ui/table-emerald.jpg') 0 0 / 480px repeat;
}
#game-screen.skin-celestial, .tsw-celestial {
    background:
        radial-gradient(ellipse at 50% 40%, rgba(10,16,34,0.0) 0%, rgba(6,10,24,0.46) 62%, rgba(3,5,14,0.76) 100%) 0 0 / 100% 100% no-repeat,
        url('../assets/ui/table-celestial.jpg') 0 0 / 640px repeat;
}
#game-screen.skin-map, .tsw-map {
    /* light parchment needs a firmer edge vignette or the gold UI washes out */
    background:
        radial-gradient(ellipse at 50% 40%, rgba(52,36,18,0.08) 0%, rgba(40,26,12,0.42) 62%, rgba(24,14,6,0.72) 100%) 0 0 / 100% 100% no-repeat,
        linear-gradient(rgba(46,30,14,0.18), rgba(46,30,14,0.18)) 0 0 / 100% 100% no-repeat,
        url('../assets/ui/table-map.jpg') 0 0 / 640px repeat;
}
#game-screen.skin-alchemist, .tsw-alchemist {
    background:
        radial-gradient(ellipse at 50% 40%, rgba(20,20,18,0.0) 0%, rgba(10,10,9,0.42) 62%, rgba(4,4,3,0.74) 100%) 0 0 / 100% 100% no-repeat,
        url('../assets/ui/table-alchemist.jpg') 0 0 / 640px repeat;
}

/* Hero Tables (2026-07-21): one table per character board. One shared
   design language — tone-on-tone damask, the hero's signature color, their
   motif woven faintly into the ornament — so the set stays quiet and cohesive.
   All tile at 600px; every vignette is the skin's own hue, darkened. */
#game-screen.skin-hero-explorer, .tsw-hero-explorer {
    background:
        radial-gradient(ellipse at 50% 40%, rgba(8,26,30,0.04) 0%, rgba(5,17,20,0.48) 60%, rgba(2,8,10,0.76) 100%) 0 0 / 100% 100% no-repeat,
        url('../assets/ui/table-char-explorer.jpg') 0 0 / 600px repeat;
}
#game-screen.skin-hero-merchant, .tsw-hero-merchant {
    background:
        radial-gradient(ellipse at 50% 40%, rgba(34,14,6,0.06) 0%, rgba(24,9,4,0.5) 60%, rgba(12,4,2,0.78) 100%) 0 0 / 100% 100% no-repeat,
        linear-gradient(rgba(20,8,3,0.22), rgba(20,8,3,0.22)) 0 0 / 100% 100% no-repeat,
        url('../assets/ui/table-char-merchant.jpg') 0 0 / 600px repeat;
}
#game-screen.skin-hero-bandit, .tsw-hero-bandit {
    background:
        radial-gradient(ellipse at 50% 40%, rgba(9,13,26,0.0) 0%, rgba(6,9,18,0.46) 60%, rgba(3,4,9,0.76) 100%) 0 0 / 100% 100% no-repeat,
        url('../assets/ui/table-char-bandit.jpg') 0 0 / 600px repeat;
}
#game-screen.skin-hero-fisherman, .tsw-hero-fisherman {
    background:
        radial-gradient(ellipse at 50% 40%, rgba(12,18,8,0.04) 0%, rgba(8,12,5,0.48) 60%, rgba(4,6,2,0.76) 100%) 0 0 / 100% 100% no-repeat,
        url('../assets/ui/table-char-fisherman.jpg') 0 0 / 440px repeat;
}
#game-screen.skin-hero-scientist, .tsw-hero-scientist {
    background:
        radial-gradient(ellipse at 50% 40%, rgba(14,14,14,0.02) 0%, rgba(9,9,9,0.46) 60%, rgba(4,4,4,0.76) 100%) 0 0 / 100% 100% no-repeat,
        url('../assets/ui/table-char-scientist.jpg') 0 0 / 600px repeat;
}
#game-screen.skin-hero-knight, .tsw-hero-knight {
    /* light silver needs the firmer edge + slight darkening (the map lesson) */
    background:
        radial-gradient(ellipse at 50% 40%, rgba(16,18,22,0.06) 0%, rgba(11,13,16,0.48) 60%, rgba(5,6,8,0.76) 100%) 0 0 / 100% 100% no-repeat,
        linear-gradient(rgba(12,14,18,0.24), rgba(12,14,18,0.24)) 0 0 / 100% 100% no-repeat,
        url('../assets/ui/table-char-knight.jpg') 0 0 / 600px repeat;
}
#game-screen.skin-hero-doctor, .tsw-hero-doctor {
    background:
        radial-gradient(ellipse at 50% 40%, rgba(44,36,22,0.08) 0%, rgba(34,26,14,0.44) 60%, rgba(18,13,6,0.72) 100%) 0 0 / 100% 100% no-repeat,
        linear-gradient(rgba(40,32,18,0.18), rgba(40,32,18,0.18)) 0 0 / 100% 100% no-repeat,
        url('../assets/ui/table-char-doctor.jpg') 0 0 / 600px repeat;
}
#game-screen.skin-hero-fiddler, .tsw-hero-fiddler {
    background:
        radial-gradient(ellipse at 50% 40%, rgba(30,11,4,0.06) 0%, rgba(21,7,3,0.5) 60%, rgba(10,3,1,0.78) 100%) 0 0 / 100% 100% no-repeat,
        linear-gradient(rgba(24,8,2,0.2), rgba(24,8,2,0.2)) 0 0 / 100% 100% no-repeat,
        url('../assets/ui/table-char-fiddler.jpg') 0 0 / 600px repeat;
}
#game-screen.skin-hero-duchess, .tsw-hero-duchess {
    background:
        radial-gradient(ellipse at 50% 40%, rgba(26,8,12,0.04) 0%, rgba(18,5,8,0.48) 60%, rgba(9,2,4,0.76) 100%) 0 0 / 100% 100% no-repeat,
        url('../assets/ui/table-char-duchess.jpg') 0 0 / 600px repeat;
}
#game-screen.skin-hero-magician, .tsw-hero-magician {
    background:
        radial-gradient(ellipse at 50% 40%, rgba(18,9,30,0.04) 0%, rgba(12,6,20,0.48) 60%, rgba(6,3,10,0.78) 100%) 0 0 / 100% 100% no-repeat,
        linear-gradient(rgba(14,7,24,0.2), rgba(14,7,24,0.2)) 0 0 / 100% 100% no-repeat,
        url('../assets/ui/table-char-magician.jpg') 0 0 / 600px repeat;
}

/* RARE TABLES (2026-07-21): precious materials + animated life (tablefx.js) */
#game-screen.skin-rare-ember, .tsw-rare-ember {
    background:
        radial-gradient(ellipse at 50% 40%, rgba(24,12,4,0.0) 0%, rgba(14,7,2,0.44) 62%, rgba(6,3,1,0.75) 100%) 0 0 / 100% 100% no-repeat,
        url('../assets/ui/table-rare-ember.jpg') 0 0 / 520px repeat;
}
#game-screen.skin-rare-astronomer, .tsw-rare-astronomer {
    background:
        radial-gradient(ellipse at 50% 40%, rgba(8,12,28,0.0) 0%, rgba(5,8,19,0.44) 62%, rgba(2,4,10,0.75) 100%) 0 0 / 100% 100% no-repeat,
        url('../assets/ui/table-rare-astronomer.jpg') 0 0 / 560px repeat;
}
#game-screen.skin-rare-vault, .tsw-rare-vault {
    background:
        radial-gradient(ellipse at 50% 40%, rgba(6,22,22,0.05) 0%, rgba(4,15,15,0.5) 60%, rgba(2,7,7,0.78) 100%) 0 0 / 100% 100% no-repeat,
        linear-gradient(rgba(4,16,16,0.24), rgba(4,16,16,0.24)) 0 0 / 100% 100% no-repeat,
        url('../assets/ui/table-rare-vault.jpg') 0 0 / 560px repeat;
}

/* ═══ TABLE FX — rare-skin animation layers (js/tablefx.js) ═══
   #tableFx is the FIRST CHILD of #game-screen: above its background,
   under every positioned sibling. All motion is transform/opacity only. */
#tableFx { position: absolute; inset: 0; pointer-events: none; overflow: hidden; display: none; }
#tableFx.tfx-on { display: block; }
#tableFxCanvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.tfx-img { position: absolute; inset: 0; background-repeat: repeat; }
.tfx-glow { mix-blend-mode: screen; opacity: 0.25; }
.tfx-sheen {
    background: linear-gradient(115deg,
        transparent 42%, rgba(255,238,190,0.055) 48%,
        rgba(255,244,214,0.10) 50%, rgba(255,238,190,0.055) 52%, transparent 58%);
    background-size: 260% 100%;
    animation: tfxSheen 26s linear infinite;
}
.tfx-caustic { mix-blend-mode: screen; opacity: 0.16; background-size: 640px; }
.tfx-caustic-0 { animation: tfxDriftA 67s linear infinite; }
.tfx-caustic-1 { animation: tfxDriftB 89s linear infinite; opacity: 0.11; background-size: 470px; }
@keyframes tfxSheen  { 0% { background-position: 130% 0; } 46% { background-position: -130% 0; } 100% { background-position: -130% 0; } }
@keyframes tfxBreathe { 0%, 100% { opacity: 0.14; } 50% { opacity: 0.34; } }
@keyframes tfxDriftA { from { background-position: 0 0; } to { background-position: 640px 214px; } }
@keyframes tfxDriftB { from { background-position: 0 0; } to { background-position: -470px 157px; } }
@media (prefers-reduced-motion: reduce) {
    .tfx-img { animation: none !important; }
}

/* ═══ STORE ECONOMY (Wyatt 7/21) ═══ */
.st-stars-btn {
    position: absolute; top: 44px; right: 16px; z-index: 3;
    font-family: 'Cinzel', serif; font-weight: 700; font-size: 12px;
    letter-spacing: 1.4px; text-transform: uppercase;
    color: #2a1810; cursor: pointer;
    background: linear-gradient(165deg, #f7ecd2, #e2cd9d);
    border: 1px solid #a98d54; border-radius: 999px;
    padding: 6px 14px;
    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.45);
}
.st-stars-btn:hover { transform: translateY(-1px); box-shadow: 0 5px 12px rgba(232, 195, 75, 0.4); }
/* iOS/Steam shell: meta.js already empties the Mint (App Store 3.1.1) —
   the door to it must vanish too, or the shell shows an empty easel */
body.ios-shell .st-stars-btn, body.ios-shell #mintPanel { display: none !important; }
.mint-inner { width: min(620px, 90%); padding-bottom: 10px; }
.mint-head { border-top: none; text-align: center; padding: 14px 0 0; margin: 0 0 4px; }
.tt-insp-lock {
    font-family: 'Cinzel', serif; font-weight: 700; font-size: 12px;
    letter-spacing: 1.2px; color: #cbb377; opacity: 0.85; text-align: right;
}
/* locked shelf cards: still browsable, clearly not yours yet */
.st-table-card.locked .st-table-swatch { filter: saturate(0.65) brightness(0.72); }
.st-table-card.locked .st-table-state { color: #b39a63; }
@media (orientation: landscape) and (max-height: 540px) {
    .st-stars-btn { top: 34px; right: 10px; font-size: 10px; padding: 4px 10px; }
}

/* ═══ TABLE INSPECT — the surface at size before you equip ═══ */
.tt-insp-inner {
    display: flex; flex-direction: column;
    width: min(680px, 88%); max-height: 86%;
    border: 2px solid var(--gold, #c9a84c); border-radius: 12px;
    overflow: hidden; background: #170e06;
    box-shadow: 0 18px 60px rgba(0, 0, 0, 0.7);
}
.tt-insp-surface {
    position: relative; overflow: hidden;
    height: min(46vh, 380px);
    /* the swatch classes carry the REAL skin css; layers fill the box */
}
.tt-insp-row {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 10px 16px 12px;
    border-top: 1px solid rgba(201, 168, 76, 0.35);
    background: linear-gradient(180deg, rgba(46, 30, 12, 0.9), rgba(26, 15, 6, 0.95));
}
.tt-insp-id { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
/* same taming the hero easel does — the shelf's hanging price tag becomes a button */
.tt-insp-row .st-buy {
    position: static;
    transform: none;
    animation: none;
    padding: 6px 14px;
    font-size: 13px;
}
.tt-insp-row .st-buy::before, .tt-insp-row .st-buy::after { display: none; }
.tt-insp-row .st-owned {
    position: static;
    width: auto; height: auto;
    border-radius: 999px;
    transform: none;
    padding: 5px 14px;
    font-size: 12px;
}
.tt-insp-id .st-name { font-size: 16px; }
.tt-insp-rare {
    font-family: 'Cinzel', serif; font-weight: 700; font-size: 11px;
    letter-spacing: 2px; color: #ffd98a;
    text-shadow: 0 0 10px rgba(255, 200, 100, 0.45);
}
@media (orientation: landscape) and (max-height: 540px) {
    .tt-insp-inner { width: min(560px, 90%); }
    .tt-insp-surface { height: 52vh; }
    .tt-insp-row { padding: 6px 12px 8px; }
}

/* ═══ STORE TABS (Wyatt+Skylar 7/21) — one category per pane ═══ */
.st-tabs {
    display: flex; gap: 8px; justify-content: center; align-items: center;
    padding: 8px 6px 2px; flex: 0 0 auto;
}
.st-tab {
    font-family: 'Cinzel', serif; font-weight: 700; font-size: 13px;
    letter-spacing: 1.6px; text-transform: uppercase;
    color: #cbb377; background: rgba(28, 21, 12, 0.6);
    border: 2px solid rgba(201, 168, 76, 0.28); border-radius: 999px;
    padding: 5px 16px 6px; cursor: pointer; opacity: 0.82;
    transition: border-color 0.15s, opacity 0.15s, background 0.15s, transform 0.15s;
}
.st-tab:hover { opacity: 1; border-color: rgba(201, 168, 76, 0.55); }
.st-tab.on {
    color: #ffe9ad; opacity: 1;
    background: rgba(70, 50, 22, 0.72);
    border-color: var(--gold, #c9a84c);
    box-shadow: 0 0 12px rgba(201, 168, 76, 0.25);
}
.st-tab-secret { letter-spacing: 3px; padding-left: 13px; padding-right: 13px; }
.st-tab-secret.locked { opacity: 0.5; border-style: dashed; }
.st-tab-secret.locked.on { opacity: 0.9; }
.st-pane { display: none; }
.st-pane.on { display: block; }
/* the mystery pane speaks in whispers */
.st-secret-tease {
    text-align: center; padding: 46px 20px 40px; color: #cbb377;
    font-family: 'Cinzel', serif;
}
.st-secret-mark {
    font-size: 64px; font-weight: 900; color: rgba(201, 168, 76, 0.5);
    text-shadow: 0 0 24px rgba(201, 168, 76, 0.25); margin-bottom: 10px;
}
.st-secret-tease p { margin: 4px 0; font-size: 16px; letter-spacing: 1.5px; }
.st-secret-sub { font-size: 12px; opacity: 0.65; font-style: italic; letter-spacing: 1px; }
@media (orientation: landscape) and (max-height: 540px) {
    .st-tabs { padding-top: 5px; gap: 6px; }
    .st-tab { font-size: 11px; padding: 3px 11px 4px; letter-spacing: 1.1px; }
    .st-secret-tease { padding: 22px 16px 18px; }
    .st-secret-mark { font-size: 42px; }
}

/* The Table Maker — a quiet shelf below the heroes */
.st-tables-head {
    font-family: 'Cinzel', serif; font-weight: 700;
    font-size: 12px; letter-spacing: 2.5px; text-transform: uppercase;
    color: var(--gold); opacity: 0.8;
    margin: 12px 4px 4px; text-align: left;
    border-top: 1px solid rgba(201,168,76,0.14); padding-top: 12px;
}
/* Compact strip (Wyatt 7/17): the Table Maker used to wrap four big cards
   and swallow the shop — now one tidy horizontal scroll row so the hero
   shelf stays the focus and the whole store is easy to navigate. */
.st-tables {
    display: flex; gap: 10px; justify-content: flex-start; flex-wrap: nowrap;
    overflow-x: auto; padding: 2px 4px 6px; scrollbar-width: none;
    scroll-snap-type: x proximity;
}
.st-tables::-webkit-scrollbar { display: none; }
.st-table-card {
    flex: 0 0 auto; scroll-snap-align: start;
    width: 108px; border-radius: 9px; overflow: hidden;
    border: 1px solid rgba(201,168,76,0.4);
    background: rgba(18,10,5,0.6);
    cursor: pointer; transition: border-color 0.15s, transform 0.15s;
}
.st-table-card:hover { border-color: var(--gold); transform: translateY(-2px); }
.st-table-card.equipped { border-color: var(--gold-light); box-shadow: 0 0 14px rgba(201,168,76,0.3); }
.st-table-swatch { height: 52px; }
.st-table-plate {
    display: flex; flex-direction: column; align-items: center; gap: 2px;
    padding: 5px 5px 7px;
}
.st-table-name { font-family: 'Cinzel', serif; font-weight: 700; font-size: 11px; letter-spacing: 1px; color: var(--gold-light); }
.st-table-state {
    font-family: 'Cinzel', serif; font-size: 9px; font-weight: 700;
    letter-spacing: 1.5px; text-transform: uppercase;
    color: rgba(232,205,120,0.75);
}
.st-table-card.equipped .st-table-state { color: #ffe9ad; }

/* ── Ambient life canvas (menu-ambient) — see js/ambient.js ── */
#tsAmbient {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    pointer-events: none;
}

/* ═══════════ HERO XP — the Gilt Ribbon + Side B (spec 7/19) ═══════════
   One ribbon renderer (FLB.xpRibbonHtml) sized per surface via --h/--nsz.
   Fill is lit VERTICALLY with a 2px lit leading edge — deliberately NOT
   .btn-royal.primary's gradient, which darkens at both ends and makes a
   fill's leading edge match the empty track. At Level 100 (.max) the
   track re-gilds with the store's picture-frame gradient and the numeral
   glows — a mastery mark, no longer a meter. */
.rb { display: flex; align-items: center; gap: 7px; }
.rb-num {
    font-family: 'Cinzel', serif; font-weight: 700; font-size: var(--nsz, 12px);
    color: var(--gold-light); min-width: 2em; text-align: right; flex: none;
    text-shadow: 0 1px 0 #000; font-variant-numeric: tabular-nums;
}
.rb-track {
    position: relative; flex: 1; height: var(--h, 11px); border-radius: 99px;
    overflow: hidden; background: linear-gradient(180deg, #150c05, #2a1908);
    box-shadow: inset 0 2px 5px rgba(0,0,0,0.9), 0 0 0 1px rgba(201,168,76,0.28);
}
.rb-fill {
    position: absolute; left: 0; top: 0; bottom: 0; width: var(--pct, 0%);
    background: linear-gradient(180deg, #f2dc9c 0%, var(--gold-light) 18%, var(--gold) 52%, #96701a 100%);
    box-shadow: 0 0 10px rgba(233,212,139,0.45);
    transition: width 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
.rb-fill::after {
    content: ''; position: absolute; right: 0; top: 0; bottom: 0; width: 2px;
    background: #fff6d8; box-shadow: 0 0 6px 1px rgba(255,246,216,0.9);
}
.rb.max .rb-fill { background: linear-gradient(160deg, #e8c34b, #8a6a1f 38%, #f0d278 66%, #6d4f16); }
.rb.max .rb-fill::after { display: none; }
.rb.max .rb-num { color: #fff3cf; text-shadow: 0 0 10px rgba(233,212,139,0.85); }
.rb.max .rb-track { box-shadow: inset 0 2px 5px rgba(0,0,0,0.9), 0 0 0 1px var(--gold-light), 0 0 12px rgba(201,168,76,0.4); }

/* hero select: ribbon under the board art, badge on the art */
.character-card { position: relative; }
.character-card .hs-xp { padding: 7px 12px 2px; }
.side-badge {
    position: absolute; top: 7px; right: 7px; z-index: 4;
    font-family: 'Cinzel', serif; font-size: 9.5px; letter-spacing: 0.12em;
    padding: 3px 8px 4px; border-radius: 99px; font-weight: 700;
    background: rgba(20,10,4,0.82); border: 1px solid rgba(201,168,76,0.35);
    color: #7d6a4f; pointer-events: none;
}
.side-badge.lit {
    background: linear-gradient(180deg, var(--gold-light), var(--gold));
    color: var(--text-dark); border-color: #6b5210;
}

/* the two-step's second step — the side chooser */
.side-chooser {
    max-width: 640px; margin: 0 auto; opacity: 0; max-height: 0; overflow: hidden;
    transition: opacity 0.35s ease, max-height 0.45s ease, margin 0.35s, padding 0.35s;
    border: 1px solid rgba(201,168,76,0.3); border-radius: 10px;
    background: rgba(0,0,0,0.3); padding: 0 16px;
}
.side-chooser.on { opacity: 1; max-height: 460px; margin-top: 18px; padding: 16px; }
.sc-title {
    font-family: 'Cinzel', serif; font-size: 11px; letter-spacing: 0.24em;
    text-transform: uppercase; color: var(--gold-dark); text-align: center; margin-bottom: 13px;
}
.sc-sides { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; max-width: 520px; margin: 0 auto; }
.sc-side {
    border-radius: 8px; overflow: hidden; cursor: pointer;
    border: 2px solid rgba(201,168,76,0.25); background: rgba(0,0,0,0.35); transition: all 0.2s;
}
.sc-side:hover { border-color: var(--gold-dark); }
.sc-side.on { border-color: var(--gold-light); box-shadow: 0 0 24px rgba(201,168,76,0.4); }
.sc-side img { width: 100%; display: block; aspect-ratio: 1600/1009; object-fit: cover; }
.sc-lab { padding: 8px 6px 10px; text-align: center; }
.sc-lab b {
    display: block; font-family: 'Cinzel', serif; font-size: 10px;
    letter-spacing: 0.18em; color: var(--gold-dark); font-weight: 700;
}
.sc-side.on .sc-lab b { color: var(--gold-light); }
.sc-lab i { font-family: 'EB Garamond', serif; font-size: 14.5px; color: var(--parchment); }

/* profile tile ribbon */
.pf-hero .pf-xp { width: 100%; margin-top: 4px; }

/* victory delta chip */
.vs-delta.xp .vs-d-fv {
    font-family: 'EB Garamond', serif; font-style: italic;
    font-size: 15px; color: #8f7a5c; margin-left: 6px;
}
.vs-delta.xp .vs-d-rb { margin-top: 8px; min-width: 170px; }

/* the Level-5 ceremony — the board turns over inside the champ card */
.champ-art { margin: 4px auto 14px; max-width: 250px; perspective: 1000px; }
.champ-art:empty { display: none; }
.champ-flip { width: 100%; aspect-ratio: 1600/1009; }
.cf-inner {
    position: relative; width: 100%; height: 100%;
    transform-style: preserve-3d; transition: transform 1s cubic-bezier(0.5, 0, 0.25, 1);
}
.cf-inner.turned { transform: rotateY(180deg); }
.cf-face {
    position: absolute; inset: 0; backface-visibility: hidden; border-radius: 5px;
    overflow: hidden; box-shadow: 0 6px 22px rgba(0,0,0,0.7), 0 0 0 1px var(--gold-dark);
}
.cf-face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cf-face.cf-back { transform: rotateY(180deg); }

/* store shelf — the earned hero's lock is the advertisement */
.st-earn {
    display: block; text-align: center; font-family: 'Cinzel', serif;
    font-size: 10.5px; letter-spacing: 0.06em; color: #7d6a4f;
    padding: 8px 6px; border-top: 1px solid rgba(201,168,76,0.18);
}

/* ═══ §2 Character detail — the compact board read (7/20; re-laid the
   same evening as TWO COLUMNS: the stacked card clipped its title at the
   top, its Confirm at the right, and scrolled on landscape phones. Board
   art carries the left column, everything written rides the right — the
   card is wider and shorter and always fits whole. Scroll lives on the
   BACKDROP with margin:auto centering, so if some pathological viewport
   ever does overflow, the card scrolls from its top instead of clipping
   it. Safe-area padding keeps the frame off notches; portrait falls back
   to the stack via the media query below. */
.char-detail {
    position: fixed; inset: 0; z-index: 8000; display: none;
    align-items: center; justify-content: center;
    overflow-y: auto; -webkit-overflow-scrolling: touch;
    padding: max(10px, env(safe-area-inset-top)) max(14px, env(safe-area-inset-right))
             max(10px, env(safe-area-inset-bottom)) max(14px, env(safe-area-inset-left));
    background: rgba(10, 5, 2, 0.82); backdrop-filter: blur(4px);
}
.char-detail.active { display: flex; }
.cd-frame {
    margin: auto;   /* centered when it fits; scrolls from the TOP when it can't */
    display: flex; align-items: center; gap: 16px;
    width: min(880px, 100%);
    padding: 14px; border-radius: 12px;
    border: 2px solid var(--gold-dark);
    background: linear-gradient(175deg, #2e1c0e, #1a0d05);
    box-shadow: 0 24px 80px rgba(0, 0, 0, 0.75);
}
/* The board is the read — as large as the viewport HEIGHT allows, capped
   so the written column keeps its room. svh so iOS toolbars don't lie. */
.cd-art-col {
    flex: 0 0 auto;
    width: clamp(220px, calc((100svh - 110px) * 1.586), 470px);
    max-width: 56%; min-width: 0;
}
.cd-info-col {
    flex: 1 1 0; min-width: 218px;
    display: flex; flex-direction: column; justify-content: center;
    gap: 10px;
}
.cd-title { display: flex; align-items: baseline; gap: 8px 12px; flex-wrap: wrap; }
.cd-title h2 { font-family: 'Cinzel', serif; font-size: clamp(19px, 2.6vw, 26px); color: var(--gold-light); text-shadow: 0 2px 0 #000; }
.cd-epithet { font-family: 'EB Garamond', serif; font-style: italic; font-size: 15px; color: #e6cf9d; }
.cd-diff { font-family: 'Cinzel', serif; font-size: 11px; letter-spacing: 0.14em; color: var(--gold-dark); }
.cd-rb { max-width: 240px; }
.cd-sidetabs { display: flex; gap: 10px; }
.cd-tab {
    flex: 1 1 0; min-width: 0; font-family: 'Cinzel', serif; font-size: 10.5px; letter-spacing: 0.1em;
    padding: 7px 10px; border-radius: 6px; cursor: pointer; font-weight: 700;
    color: #b09a6d; background: linear-gradient(180deg, #3a2617, #241609);
    border: 1px solid rgba(201, 168, 76, 0.3);
}
.cd-tab.on {
    color: var(--text-dark);
    background: linear-gradient(180deg, var(--gold-light), var(--gold) 48%, var(--gold-dark));
    border-color: #6b5210; box-shadow: 0 0 18px rgba(201, 168, 76, 0.35);
}
.cd-art {
    position: relative; border-radius: 8px; overflow: hidden;
    border: 1px solid var(--gold-dark); box-shadow: 0 8px 28px rgba(0,0,0,0.6);
}
.cd-art img { width: 100%; display: block; aspect-ratio: 1600/1009; object-fit: cover; }
/* The ring on the CENTER slot — same slider-ring art and BOARD_OV_TRACK
   geometry as the in-game thumbs, so the start position reads at a glance. */
.cd-art .cd-ring {
    position: absolute; width: 9%; height: auto; aspect-ratio: 1;
    transform: translate(-50%, -50%); pointer-events: none;
    filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.7));
}
.cd-tip { font-family: 'EB Garamond', serif; font-size: 13.5px; color: #8f7a5c; }
.cd-actions { display: flex; gap: 12px; }
/* btn-royal's stage dress (280px min, 48px pads, 3px tracking) cannot sit
   two-abreast in this column — the letter-spaced text clips its own
   overflow:hidden box. Sized to the column here, and never wrapped. */
.cd-actions .btn-royal {
    flex: 1 1 0; min-width: 0; padding: 12px 10px;
    font-size: clamp(12px, 1.5vw, 15px); letter-spacing: 1.5px;
}
.cd-actions .btn-royal span { white-space: nowrap; }
/* Portrait keeps the stack — width-bound, art on top, words below. */
@media (orientation: portrait) {
    .cd-frame { flex-direction: column; align-items: stretch; width: min(480px, 100%); gap: 12px; }
    .cd-art-col { width: 100%; max-width: none; }
    .cd-info-col { min-width: 0; }
    .cd-title { justify-content: center; text-align: center; }
    .cd-rb { max-width: none; }
    .cd-tip { text-align: center; }
}

/* §5 (7/20) — the slide's skill delta in the confirm bubble */
.sc-delta { display: flex; gap: 7px; justify-content: center; flex-wrap: wrap; margin: 2px 0 4px; }
.sc-d {
    display: inline-flex; align-items: center; gap: 4px;
    font-family: 'Cinzel', serif; font-size: 12.5px; font-weight: 700;
    padding: 2px 8px 3px; border-radius: 99px;
    background: rgba(0, 0, 0, 0.35); border: 1px solid rgba(201, 168, 76, 0.25);
}
.sc-d img { width: 14px; height: 14px; object-fit: contain; }
.sc-d.good { color: #9fd79f; }
.sc-d.bad { color: #e0a0a0; border-color: rgba(139, 26, 26, 0.45); }

/* ── The throw hint yields the stage (Wyatt 7/20): while ANY game overlay
   is up — mission browser/journal, a board, a rival, the hero detail, a
   ceremony — the "drag a card up" fixture must not float over it. :has()
   needs iOS 16.4+; older devices keep the cosmetic bug. ── */
body:has(.mission-lb.active) .throw-hint,
body:has(.mission-journal.active) .throw-hint,
body:has(.board-overlay.active) .throw-hint,
body:has(.opp-overlay.active) .throw-hint,
body:has(.char-detail.active) .throw-hint,
body:has(#missionCeremony.active) .throw-hint,
body:has(#meleeSplash.active) .throw-hint,
body:has(#promisePicker.active) .throw-hint,
body:has(.champ-overlay.active) .throw-hint,
body:has(#howto-overlay.open) .throw-hint {
    display: none !important;
}

/* Court Sign-In (7/20) — the platform door that replaced the Court Seal */
#pfSignin .pf-note b { color: var(--gold-light); }
.pf-sealed { color: #46d17f; font-style: normal; font-weight: 700; }
.pf-sign-err { color: #e0a0a0; }
.pf-gsi-host { display: flex; justify-content: center; padding: 6px 0 2px; min-height: 44px; }
.pf-signrow { display: flex; gap: 10px; }
.pf-signrow .btn-royal { flex: 1 1 0; min-width: 0; padding: 10px 12px; font-size: 12px; letter-spacing: 1px; }
.pf-signrow .btn-royal span { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pf-apple {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    width: min(280px, 100%); margin: 6px auto 2px; padding: 11px 18px;
    border-radius: 99px; cursor: pointer;
    background: #000; color: #fff; border: 1px solid #333;
    font-family: -apple-system, 'Helvetica Neue', sans-serif;
    font-size: 15px; font-weight: 600; letter-spacing: 0.01em;
}
.pf-apple:active { background: #1a1a1a; }
.pf-apple-logo { font-size: 17px; line-height: 1; }

/* ═══ GILT LADDER — hero-leveling rewards (branch hero-leveling) ═══ */
/* The number's ring (Wyatt 7/22): circular border on the level number —
   bronze at 10, silver at 30, gold at 50, platinum at 75, radiant at 100.
   Below 10 the number stays bare. Diameter rides --nsz so it scales with
   every ribbon size (profile 7px → select 13px). */
.rb-num.rn-bronze, .rb-num.rn-silver, .rb-num.rn-gold, .rb-num.rn-plat, .rb-num.rn-radiant {
    min-width: 0; text-align: center;
    display: inline-flex; align-items: center; justify-content: center;
    width: calc(var(--nsz, 12px) * 2.1); height: calc(var(--nsz, 12px) * 2.1);
    border-radius: 50%; border: 1.5px solid; flex: none;
    box-shadow: inset 0 1px 3px rgba(0,0,0,0.55);
}
.rb-num.rn-bronze { border-color: #b0713a; color: #d99a5e; background: radial-gradient(circle at 38% 30%, #5a3417, #331a0a 74%); }
.rb-num.rn-silver { border-color: #aeb4bf; color: #dfe3ea; background: radial-gradient(circle at 38% 30%, #4c5158, #26292e 74%); }
.rb-num.rn-gold   { border-color: var(--gold-light); color: #ffe9a8; background: radial-gradient(circle at 38% 30%, #6d5316, #38290a 74%); box-shadow: inset 0 1px 3px rgba(0,0,0,0.55), 0 0 7px rgba(233,212,139,0.5); }
.rb-num.rn-plat   { border-color: #e6ecf5; color: #f4f8ff; background: radial-gradient(circle at 38% 30%, #5d6672, #2d3239 74%); box-shadow: inset 0 1px 3px rgba(0,0,0,0.55), 0 0 8px rgba(214,228,255,0.55); }
.rb-num.rn-radiant { border-color: #fff3cf; color: #fff8e2; background: radial-gradient(circle at 38% 30%, #8a6a1f, #3d2c08 74%); box-shadow: inset 0 1px 3px rgba(0,0,0,0.55), 0 0 10px rgba(255,240,200,0.85), 0 0 20px rgba(233,212,139,0.45); }

/* Level 50+ ribbon re-gilds gold everywhere — the public mastery mark. */
.rb.gild .rb-fill { background: linear-gradient(160deg, #f6e3a4, #e8c34b 30%, #b8902e 60%, #f0d278); box-shadow: 0 0 12px rgba(240,210,120,0.65); }
.rb.gild .rb-num { color: #ffe9a8; text-shadow: 0 0 9px rgba(233,212,139,0.9); }
.rb.gild .rb-track { box-shadow: inset 0 2px 5px rgba(0,0,0,0.9), 0 0 0 1px var(--gold-light), 0 0 10px rgba(201,168,76,0.5); }

/* Hero select: the next visible reward on this hero's climb. */
.hs-next {
    margin: 2px 12px 0; padding: 2px 8px;
    font-family: 'Cinzel', serif; font-size: 10px; font-weight: 700;
    letter-spacing: 0.06em; color: #e9d48b;
    background: rgba(38,24,10,0.72); border: 1px solid rgba(201,168,76,0.4);
    border-radius: 9px; width: fit-content;
}
.hs-next.hs-mastered { color: #fff3cf; border-color: var(--gold-light); }
.hs-next .crown-ico { width: 13px; height: 9px; vertical-align: -1px; }

/* Victory chip: star drop + next-reward loop line. */
.vs-d-stars { color: #ffe9a8; font-weight: 800; text-shadow: 0 0 8px rgba(233,212,139,0.7); }
.vs-d-next {
    flex-basis: 100%; margin-top: 3px;
    font-size: 10px; letter-spacing: 0.05em; color: rgba(240,230,211,0.75);
}

/* Champ-overlay dress: a table swatch or crest as the celebration art.
   .champ-art caps at 250px (tuned for the Side B flip) — the swatch must
   fill it, never exceed it: an over-constrained auto-margin child hangs
   out the RIGHT side (margin-right goes negative) and reads off-center. */
.champ-table {
    width: 100%; aspect-ratio: 5 / 3;
    margin: 10px auto; border-radius: 10px;
    border: 2px solid var(--gold); box-shadow: 0 6px 24px rgba(0,0,0,0.6), inset 0 0 40px rgba(0,0,0,0.35);
    background-size: 280px;
}
.champ-table.champ-rare { box-shadow: 0 6px 28px rgba(233,212,139,0.35), inset 0 0 40px rgba(0,0,0,0.35); }
.champ-crest { width: 92px; height: 92px; margin: 10px auto; display: block; }
.champ-crest img { width: 100%; height: 100%; }

/* Crest gallery: hero-crest tiles reuse cp-tile; locked shows Lv n/15. */
.cp-heroes .cp-tile.locked img { filter: grayscale(0.75) brightness(0.6); }

/* ═══ FREE-PLAY HIGHLIGHT (Wyatt 7/22) — the engine plays this card free
   (map OR Doctor-B potion waiver). Identical structure to the playable
   green: same ring, same soft bloom, same breathe — just orange. ═══ */
.tv-hand .hand-card.freeplay, .hand-zone .hand-card.freeplay {
    box-shadow: 0 0 0 2px rgba(255,157,60,0.95), 0 0 18px 4px rgba(255,140,40,0.55);
    animation: freeplayBreathe 2.2s ease-in-out infinite;
    border-radius: 8px;
}
@keyframes freeplayBreathe {
    0%, 100% { box-shadow: 0 0 0 2px rgba(255,157,60,0.95), 0 0 18px 4px rgba(255,140,40,0.55); }
    50%      { box-shadow: 0 0 0 2px rgba(255,157,60,0.7),  0 0 10px 2px rgba(255,140,40,0.35); }
}
@media (prefers-reduced-motion: reduce) { .hand-card.freeplay { animation: none; } }

/* Desktop hand: the same playable green as the phone — the original rule was
   scoped .tv-hand only, so full-screen web never glowed (operator 7/22). */
.hand-zone .hand-card.playable {
    box-shadow: 0 0 0 2px rgba(140,225,125,0.95), 0 0 18px 4px rgba(120,220,120,0.55);
    animation: playableBreathe 2.2s ease-in-out infinite;
    border-radius: 8px;
}

/* ═══ ALMANAC — lifetime collection book (js/almanac.js) ═══
   Sits UNDER .card-zoom (2000) so tapping a discovered card zooms it with
   the existing lightbox; opens from the title screen only, where nothing
   else stacks this high. */
.alm-gallery {
    position: fixed; inset: 0; z-index: 1980; display: none;
    align-items: center; justify-content: center;
    background: rgba(8, 5, 2, 0.82);
}
.alm-gallery.open { display: flex; }
.alm-inner {
    position: relative;
    width: min(1080px, 96vw); max-height: min(90vh, calc(100dvh - 14px));
    display: flex; flex-direction: column;
    background: linear-gradient(#241b0f, #14100a);
    border: 2px solid #8a6a1f; border-radius: 10px;
    box-shadow: 0 24px 70px rgba(0,0,0,.7);
}
.alm-head {
    position: relative; padding: 16px 22px 10px;
    border-bottom: 1px solid #3a2d17;
}
.alm-title { font-family: 'Cinzel', serif; font-size: 22px; color: #f0dfb8; }
.alm-sub { font-size: 12.5px; color: #a8926a; margin-top: 3px; font-variant-numeric: tabular-nums; }
.alm-x {
    position: absolute; top: 14px; right: 14px;
    background: none; border: none; color: #a8926a; font-size: 18px; cursor: pointer;
}
.alm-x:hover, .alm-x:focus-visible { color: #f0dfb8; outline: none; }
.alm-tabs {
    display: flex; flex-wrap: nowrap; gap: 6px;
    padding: 10px 16px; border-bottom: 1px solid #3a2d17;
}
/* One equal-width tab per category, filling the whole row (Wyatt 7/23).
   Medallion + text: acts wear their numeral, missions the scroll icon,
   each type a wax seal in its FRAME color — the same blue-means-endeavor
   language the cards themselves teach. `--seal` carries the type color;
   an MJ art pass can swap any seal for an image via the tab's `icon`. */
.alm-tab {
    flex: 1 1 0; min-width: 0;
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    background: #1c150c; border: 1px solid #4a3a1c; border-radius: 8px;
    padding: 7px 4px 5px; cursor: pointer;
}
.alm-tab-art {
    width: 34px; height: 34px; border-radius: 50%; overflow: hidden;
    display: flex; align-items: center; justify-content: center;
    border: 2px solid #6a5220; background: radial-gradient(#332712, #1a1309);
    box-shadow: inset 0 0 8px rgba(0,0,0,.7), 0 2px 6px rgba(0,0,0,.5);
    flex: 0 0 auto;
}
.alm-tab-art img.icon { width: 62%; height: 62%; object-fit: contain; }
.alm-tab-art.numeral {
    font-family: 'Cinzel', serif; font-size: 17px; font-weight: 700;
    color: #b39a6a; text-shadow: 0 1px 3px rgba(0,0,0,.8);
}
.alm-tab-art.seal {
    background: var(--seal);   /* stands alone if color-mix is unsupported */
    background:
        radial-gradient(circle at 32% 28%, rgba(255,255,255,.38), rgba(255,255,255,0) 42%),
        radial-gradient(circle at 50% 60%, var(--seal), color-mix(in srgb, var(--seal) 55%, #000));
    filter: saturate(.8) brightness(.9);
}
.alm-tab-lbl {
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-size: 11px; color: #c3ae86; letter-spacing: .02em;
}
.alm-tab .alm-tab-n { font-size: 9.5px; color: #8a7550; font-variant-numeric: tabular-nums; }
.alm-tab:hover { border-color: #8a6a1f; }
.alm-tab:hover .alm-tab-art { border-color: #c9a542; }
.alm-tab:hover .alm-tab-lbl { color: #f0dfb8; }
.alm-tab.cur {
    background: linear-gradient(#3a2c14, #2a1f0e); border-color: #c9a542;
}
.alm-tab.cur .alm-tab-art {
    border-color: #f0d78a;
    box-shadow: inset 0 0 8px rgba(0,0,0,.5), 0 0 10px rgba(201,165,66,.55);
}
.alm-tab.cur .alm-tab-art.seal { filter: none; }
.alm-tab.cur .alm-tab-art.numeral { color: #f0dfb8; }
.alm-tab.cur .alm-tab-lbl { color: #f4e6c8; }
.alm-tab.cur .alm-tab-n { color: #c9a542; }
/* Flex-wrap, NOT css grid — same pre-fontload row-track trap the
   achievements grid hit (Overlap.jpg, 7/20). */
.alm-grid {
    display: flex; flex-wrap: wrap; gap: 10px; justify-content: center;
    padding: 14px 14px 26px; overflow-y: auto;
}
.alm-inner::after {
    content: ''; position: absolute; left: 3px; right: 3px; bottom: 3px;
    height: 24px; border-radius: 0 0 8px 8px; pointer-events: none;
    background: linear-gradient(transparent, rgba(18, 14, 9, 0.92));
}
.alm-tile {
    position: relative; width: 108px; flex: 0 0 auto;
    border-radius: 7px;
}
.alm-tile img {
    display: block; width: 100%; border-radius: 7px;
    aspect-ratio: 5 / 7; object-fit: cover;
    box-shadow: 0 3px 10px rgba(0,0,0,.55);
}
.alm-tile.got { cursor: zoom-in; transition: transform .12s ease; }
.alm-tile.got:hover { transform: translateY(-3px) scale(1.03); }
.alm-tile.locked img { filter: grayscale(.85) brightness(.5); }
.alm-seal {
    position: absolute; inset: 0; display: flex;
    align-items: center; justify-content: center;
    font-family: 'Cinzel', serif; font-size: 30px; color: #8a7550;
    text-shadow: 0 2px 6px rgba(0,0,0,.8); pointer-events: none;
}
.alm-count {
    position: absolute; top: 5px; right: 5px;
    background: rgba(20, 14, 6, 0.9); border: 1px solid #c9a542;
    border-radius: 10px; padding: 1px 7px;
    font-size: 11px; font-weight: 700; color: #f0dfb8;
    font-variant-numeric: tabular-nums;
}

/* Phone landscape: shorter panel, smaller tiles, tighter chrome. */
@media (orientation: landscape) and (max-height: 540px) {
    .alm-inner { max-height: calc(100dvh - 10px); width: 96vw; }
    .alm-head { padding: 9px 16px 6px; }
    .alm-title { font-size: 16px; }
    .alm-sub { font-size: 10.5px; }
    .alm-tabs { padding: 5px 10px; gap: 4px; }
    .alm-tab { padding: 3px 2px 2px; gap: 2px; }
    .alm-tab-art { width: 22px; height: 22px; border-width: 1.5px; }
    .alm-tab-art.numeral { font-size: 12px; }
    .alm-tab-lbl { font-size: 8.5px; }
    .alm-tab .alm-tab-n { font-size: 8px; }
    .alm-grid { gap: 7px; padding: 10px 10px 20px; }
    .alm-tile { width: 76px; }
    .alm-seal { font-size: 20px; }
}

/* ═══ SETTINGS — cog + panel (js/settings.js) ═══
   z 1970: UNDER the Almanac (1980) so its door stacks the book above the
   panel, and both stay under .card-zoom (2000). */
.ts-cog {
    /* Top-left, tucked right below the music note (fixed 20/20, 44px). */
    position: absolute; left: 20px; top: 74px; z-index: 6;
    width: 44px; height: 44px; border-radius: 50%; padding: 0;
    display: flex; align-items: center; justify-content: center;
    background: radial-gradient(#2e2311, #1a1309);
    border: 2px solid #8a6a1f; color: #d8bf8a;
    font-size: 27px; line-height: 1; cursor: pointer;
    box-shadow: 0 3px 10px rgba(0,0,0,.55);
    transition: transform .25s ease, color .15s ease, border-color .15s ease;
}
/* The ⚙ glyph carries baseline lean in most fonts — nudge to optical center. */
.ts-cog span { display: block; transform: translateY(-1px); }
.ts-cog:hover, .ts-cog:focus-visible {
    color: #f4e6c8; border-color: #c9a542; outline: none;
    transform: rotate(45deg);
}
.set-overlay {
    position: fixed; inset: 0; z-index: 1970; display: none;
    align-items: center; justify-content: center;
    background: rgba(8, 5, 2, 0.82);
}
.set-overlay.open { display: flex; }
.set-inner {
    width: min(540px, 94vw); max-height: min(88vh, calc(100dvh - 14px));
    display: flex; flex-direction: column;
    background: linear-gradient(#241b0f, #14100a);
    border: 2px solid #8a6a1f; border-radius: 10px;
    box-shadow: 0 24px 70px rgba(0,0,0,.7);
}
.set-head {
    position: relative; padding: 16px 22px 12px;
    border-bottom: 1px solid #3a2d17;
}
.set-title { font-family: 'Cinzel', serif; font-size: 22px; color: #f0dfb8; }
.set-x {
    position: absolute; top: 14px; right: 14px;
    background: none; border: none; color: #a8926a; font-size: 18px; cursor: pointer;
}
.set-x:hover, .set-x:focus-visible { color: #f0dfb8; outline: none; }
.set-body { padding: 6px 22px 20px; overflow-y: auto; }
.set-sec { margin-top: 14px; }
.set-sec-title {
    font-size: 11px; letter-spacing: .18em; text-transform: uppercase;
    color: #b39a6a; margin-bottom: 8px;
    border-bottom: 1px solid #2c2212; padding-bottom: 4px;
}
.vol-row {
    display: grid; grid-template-columns: 20px 72px 1fr 44px;
    align-items: center; gap: 10px; padding: 5px 0;
}
.vol-row input[type="range"] { width: 100%; accent-color: #c9a542; }
.vol-row input[type="checkbox"], .set-check input[type="checkbox"] { accent-color: #c9a542; }
.vol-lbl { font-size: 13px; color: #c3ae86; }
.vol-pct {
    font-size: 11.5px; color: #8a7550; text-align: right;
    font-variant-numeric: tabular-nums;
}
.vol-row.off .vol-lbl, .vol-row.off .vol-pct { opacity: .45; }
.vol-row.off input[type="range"] { opacity: .35; }
.set-row { padding: 5px 0; }
.set-check {
    display: flex; align-items: center; gap: 9px;
    font-size: 13px; color: #c3ae86; cursor: pointer;
}
.set-check:hover { color: #f0dfb8; }
.set-warn {
    margin: 3px 0 0 29px; font-size: 11px; line-height: 1.35;
    color: #d9534f;
}
.set-build {
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px; padding: 4px 0;
    font-size: 12px; color: #8a7550; font-variant-numeric: tabular-nums;
}
.set-upd-btn {
    background: #1c150c; border: 1px solid #4a3a1c; border-radius: 6px;
    color: #c3ae86; font-size: 12px; padding: 6px 12px; cursor: pointer;
}
.set-upd-btn:hover { border-color: #c9a542; color: #f0dfb8; }

/* Almanac door on the profile's Standing row: the book beside the purse.
   While the profile (z 10005) is up, the book + its card zoom must stack
   ABOVE it — scoped with :has so global overlay order stays untouched. */
.pf-alm-btn { background: none; border: none; padding: 0; cursor: pointer; flex: 0 0 auto; }
.pf-alm-btn img {
    width: 48px; display: block;
    filter: drop-shadow(0 4px 10px rgba(0,0,0,.55));
    transition: transform .15s ease;
}
.pf-alm-btn:hover img, .pf-alm-btn:focus-visible img { transform: scale(1.12) rotate(-3deg); }
body:has(.profile-panel.active) .alm-gallery { z-index: 10600; }
body:has(.profile-panel.active) .card-zoom { z-index: 10610; }

/* Settings kill-switch for the playable glow — GREEN only (Wyatt 7/23).
   The orange freeplay glow survives the toggle: free is a certainty the
   turn can't take away, so its signal never misleads. (.freeplay REPLACES
   .playable in the hand renderers, so this selector can't touch it.) */
body.no-play-glow .hand-card.playable {
    box-shadow: none !important;
    animation: none !important;
}

@media (orientation: landscape) and (max-height: 540px) {
    /* Phones: top-left covers the FAVOR title (Wyatt 7/23) — the cog
       goes bottom-right instead, above the edition plate. */
    .ts-cog { left: auto; top: auto; right: 10px; bottom: 28px; width: 36px; height: 36px; font-size: 22px; }
    .set-inner { max-height: calc(100dvh - 10px); }
    .set-head { padding: 9px 16px 7px; }
    .set-title { font-size: 16px; }
    .set-body { padding: 2px 16px 14px; }
    .set-sec { margin-top: 9px; }
    .vol-row { padding: 3px 0; }
    .set-check, .vol-lbl { font-size: 11.5px; }
    .set-warn { font-size: 10px; }
}
