/* Chessingo - play page: neon arcade board vs trash-talking bots.
   Inherits the style.css token palette. */

:root {
    --sky: #3fd8ff;
    --grape: #7b2ff7;
    --grape-deep: #22104e;
    --lime: #4dffb0;
    --lime-deep: #0e8c56;
    --magenta: #ff2d78;
    --magenta-deep: #a90e4c;
    --corn: #ffd23f;
    --tangerine: #ff9f1c;
    --berry: #b34fff;
    --text: #ffffff;
    --text-dim: rgba(255, 255, 255, 0.82);
    --card: rgba(255, 255, 255, 0.10);
    --card-line: rgba(255, 255, 255, 0.25);
    --sq-dark: #22104e;
    --sq-light: #3a2a6e;
    /* In-game backdrop art (Midjourney neon arena) on the tyga CDN. Swapped to
       the portrait crop on narrow screens further down. */
    --bg-art: url('https://prodmedia.tyga.host/public/tyga.cloud/landing/chessingo.com/chessingo_bg.jpg');
}

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

/* THE `hidden` ATTRIBUTE ALWAYS WINS. Any rule that sets `display` on an element
   beats the attribute's UA style, and this repo has shipped that bug four times
   (#vs-intro, .cgl, .cgl-panel, then .clash-stage painting an empty board HUD
   under the /clash lobby on prod). Guarding each element one at a time is how it
   kept coming back, so it is guarded once, for everything. */
[hidden] { display: none !important; }

body {
    font-family: 'Outfit', 'Segoe UI', sans-serif;
    color: var(--text);
    min-height: 100vh;
    min-height: 100dvh;
    overflow-x: hidden;
    background-color: #150c24;
    /* Top-to-bottom layers: a dark scrim keeps the board readable, then the CDN
       art. If the art is slow/blocked its layer is empty and the neon-gradient
       layers below show through (progressive enhancement, never a hard dep). */
    background:
        linear-gradient(rgba(13, 8, 23, 0.72), rgba(13, 8, 23, 0.86)),
        var(--bg-art) center / cover no-repeat,
        radial-gradient(circle at 100% 20%, rgba(255, 45, 120, 0.22) 0%, transparent 45%),
        radial-gradient(circle at 0% 60%, rgba(63, 216, 255, 0.16) 0%, transparent 42%),
        linear-gradient(180deg, #1d1030 0%, #150c24 55%, #0d0817 100%);
    background-attachment: fixed;
}

/* Portrait crop for narrow / tall screens (the widescreen art letterboxes
   badly there; the portrait render keeps the dark center band over the board). */
@media (max-width: 780px) {
    :root {
        --bg-art: url('https://prodmedia.tyga.host/public/tyga.cloud/landing/chessingo.com/chessingo_portrait.jpg');
    }
}

header.play-head {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    flex-wrap: wrap;
    padding: 0.9rem clamp(0.8rem, 3vw, 1.4rem);
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0) 100%);
    border-bottom: 1px solid rgba(255, 255, 255, 0.14);
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
}
header.play-head h1 {
    font-family: 'Bangers', 'Outfit', sans-serif;
    font-weight: 400;
    font-size: 1.875rem;
    color: var(--corn);
    text-shadow: 0 0 18px rgba(255, 210, 63, 0.45);
    line-height: 0;
    margin-right: auto; letter-spacing: 0.03em; }
/* Neon wordmark, outlined Cinzel so it needs no font load at all. Sized small
   on height: the box is ~5.75:1 (nine caps plus the glow margin), so the old
   3.2rem height made it 294px wide and pushed the header controls around. */
header.play-head h1 .logo-mark {
    display: block;
    height: clamp(1.5rem, 3.4vw, 2rem);
    width: auto;
    filter: drop-shadow(0 0 14px rgba(255, 210, 63, 0.35));
}
/* Nav links use the real craftpix blue button art (border-image 9-slice), same
   as the panel buttons - no improvised pill shapes, no square icon tiles. */
header.play-head a {
    position: relative;
    text-decoration: none;
    color: #06202f;
    font-weight: 800;
    font-size: 0.82rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    text-align: center;
    padding: 0.05rem 0.35rem 0.15rem;
    border-style: solid;
    border-width: 13px 18px 17px 16px;
    border-image-source: url('/img/ui/btnbg-blue.png');
    border-image-slice: 40 48 52 44 fill;
    border-image-repeat: stretch;
    text-shadow: 0 1px 0 rgba(255, 255, 255, 0.4);
    filter: drop-shadow(0 3px 5px rgba(0, 0, 0, 0.35));
    transition: transform 0.07s ease, filter 0.12s ease;
}
header.play-head a:hover { filter: brightness(1.07) saturate(1.06) drop-shadow(0 4px 7px rgba(0, 0, 0, 0.4)); }
header.play-head a:active { transform: translateY(2px); filter: brightness(0.97) drop-shadow(0 2px 3px rgba(0, 0, 0, 0.35)); }

/* GDD s11.4 mode switch: Play | Practice | Friend, one control on every game
   page, the current mode lit. Not the blue button art: a segmented control reads
   as ONE choice between modes rather than three unrelated buttons. */
header.play-head .mode-seg {
    display: inline-flex;
    gap: 2px;
    padding: 3px;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.38);
    border: 1px solid rgba(255, 255, 255, 0.18);
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.5);
}
header.play-head .mode-seg a {
    border: 0;
    border-image: none;
    filter: none;
    text-shadow: none;
    color: #cfe3ff;
    padding: 0.42rem 1rem;
    border-radius: 999px;
    font-size: 0.78rem;
    letter-spacing: 0.06em;
}
header.play-head .mode-seg a:hover { color: #fff; background: rgba(255, 255, 255, 0.08); filter: none; }
header.play-head .mode-seg a[aria-current="page"] {
    color: #06202f;
    background: linear-gradient(180deg, #8fe3ff 0%, #34b4f0 55%, #1f8fe0 100%);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7), 0 0 12px rgba(52, 180, 240, 0.45);
}
@media (max-width: 780px) {
    /* Exit and the switch share ONE row under the logo row on a phone. */
    header.play-head { column-gap: 0.5rem; }
    header.play-head .mode-seg { order: 3; }
    header.play-head .mode-seg a { padding: 0.36rem 0.62rem; font-size: 0.7rem; letter-spacing: 0.04em; }
    header.play-head a.exit-lobby { font-size: 0.7rem; border-width: 10px 13px 13px 12px; }
}

.arena {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: center;
    gap: 1.2rem;
    padding: 0.6rem clamp(0.6rem, 3vw, 1.4rem) 2rem;
    max-width: 1180px;
    margin: 0 auto;
}

/* Three-column table layout: bot avatar + Lingo chat on the LEFT, the board
   centred, match controls on the RIGHT. Pattern: blajacko.com .arena-table. */
.arena-table {
    display: grid;
    grid-template-columns: minmax(260px, 320px) minmax(0, 1fr) minmax(240px, 320px);
    gap: clamp(0.8rem, 1.6vw, 1.5rem);
    align-items: stretch;
    max-width: 1560px;
    padding: clamp(0.6rem, 2vw, 1.2rem) clamp(0.8rem, 2.4vw, 2rem) 1.6rem;
}
.arena-table .rail {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    min-width: 0;
}
/* Center column: board stays square, centred, capped to the viewport height. */
.arena-table .board-wrap {
    flex: none;
    margin: 0 auto;
    align-self: start;
    justify-self: center;
    width: 100%;
    max-width: min(100%, calc(100dvh - 150px), 760px);
}

/* Bot HERO - go big on the persona glyph. */
.hero-opponent { display: flex; flex-direction: column; align-items: center; text-align: center; }
.hero-opponent .rail-cap {
    align-self: stretch;
    text-align: left;
    font-family: 'Outfit', sans-serif;
    font-size: 0.78rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--sky);
    margin-bottom: 0.7rem;
 font-weight: 800; }
/* The big avatar/name styling lives with the #opponent rules below (higher
   specificity); here we only centre the tier line under it. */
.hero-opponent .bot-tier { justify-content: center; margin-top: 0.25rem; }

/* Lingo grows to fill the rest of the left rail; its feed scrolls inside. */
.arena-table .lingo-card { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
.arena-table .lingo-card #events { flex: 1 1 auto; max-height: none; }

/* ONE TABLE ON EVERY GAME SCREEN (GDD s1.2). On a phone the table stacks the
   way you sit at it: the opponent across the board at the top, the board, then
   YOU, then everything else. The rails dissolve (display: contents) so their
   cards can be ordered individually, and both seats shrink to a one-line strip
   so the board stays on screen. */
@media (max-width: 900px) {
    .arena-table {
        grid-template-columns: minmax(0, 1fr);
        max-width: 760px;
    }
    .arena-table .rail { display: contents; }
    .arena-table .rail > * { order: 5; }
    .arena-table .hero-opponent { order: 1; }
    .arena-table .board-wrap { order: 2; }
    .arena-table .seat-card { order: 3; }
    .arena-table .lingo-card { order: 4; }
    .arena-table .lingo-card #events { max-height: 230px; }
    .arena-table .hero-opponent, .arena-table .seat-card {
        flex-direction: row; flex-wrap: wrap; align-items: center; text-align: left; gap: 0.3rem 0.8rem;
    }
    .arena-table .hero-opponent .rail-cap, .arena-table .seat-card .rail-cap { display: none; }
}

/* Board - flexes to fill, but never taller than the viewport (landscape/short
   screens) so the whole board is always visible without scrolling. */
.board-wrap {
    position: relative;
    flex: 1 1 440px;
    max-width: min(100%, calc(100dvh - 150px), 760px);
    margin: 0 auto;
}
@media (max-width: 780px) {
    .board-wrap { flex-basis: 100%; max-width: min(100%, calc(100dvh - 220px)); }
}
#board {
    display: grid;
    grid-template-columns: repeat(8, 1fr);
    grid-template-rows: repeat(8, 1fr);
    aspect-ratio: 1;
    width: 100%;
    border: 5px solid rgba(255, 255, 255, 0.4);
    border-radius: 16px;
    overflow: hidden;
    box-shadow:
        0 0 0 3px rgba(123, 47, 247, 0.55),
        0 12px 44px rgba(123, 47, 247, 0.5),
        inset 0 0 22px rgba(0, 0, 0, 0.45);
    user-select: none;
}
.sq {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    min-height: 0;
    font-size: clamp(1.6rem, 5.4vw, 3.1rem);
    line-height: 1;
    cursor: pointer;
}
.sq.light { background: var(--sq-light); }
.sq.dark { background: var(--sq-dark); }
/* Rendered piece sprites (craftpix chess kit) seated in each square. */
.sq .glyph {
    pointer-events: none;
    width: 88%;
    height: 88%;
    object-fit: contain;
    object-position: center center;
    -webkit-user-drag: none;
    user-select: none;
    transition: transform 0.12s ease;
}
.sq.white-piece .glyph {
    filter: drop-shadow(0 0 5px rgba(63, 216, 255, 0.75)) drop-shadow(0 3px 3px rgba(0, 0, 0, 0.5));
}
.sq.black-piece .glyph {
    filter: drop-shadow(0 0 6px rgba(255, 45, 120, 0.7)) drop-shadow(0 2px 3px rgba(0, 0, 0, 0.6));
}
.sq.white-piece:hover .glyph,
.sq.black-piece:hover .glyph { transform: translateY(-4%) scale(1.04); }
.sq.selected .glyph { transform: translateY(-5%) scale(1.06); }
.sq.selected { outline: 3px solid var(--corn); outline-offset: -3px; }
.sq.last-move { background-image: linear-gradient(rgba(255, 210, 63, 0.22), rgba(255, 210, 63, 0.22)); }
.sq.in-check { background-image: radial-gradient(circle, rgba(255, 45, 120, 0.65) 0%, transparent 70%); }
.sq.hint::after {
    content: '';
    position: absolute;
    width: 26%;
    height: 26%;
    border-radius: 50%;
    background: rgba(77, 255, 176, 0.55);
    box-shadow: 0 0 10px rgba(77, 255, 176, 0.8);
}
.sq.hint.capture-hint::after {
    width: 86%;
    height: 86%;
    background: transparent;
    border: 3px solid rgba(255, 45, 120, 0.8);
    box-shadow: 0 0 12px rgba(255, 45, 120, 0.8);
}
.coord {
    position: absolute;
    font-size: 0.55rem;
    opacity: 0.55;
    pointer-events: none;
    font-family: 'Silkscreen', monospace, sans-serif;
}
.coord.file { right: 3px; bottom: 2px; }
.coord.rank { left: 3px; top: 2px; }

/* Chess clocks (FEAT-2026-0923-0023): on-board time chips. The opponent's sits
   top-right, yours bottom-right; pointer-events off so they never block a
   square. The side to move glows; under 10s it flips corn -> magenta so a flag
   never sneaks up. Hidden entirely in the casual (no-clock) control. */
.chess-clock {
    position: absolute;
    right: 10px;
    z-index: 4;
    pointer-events: none;
    min-width: 3.6rem;
    padding: 0.28rem 0.6rem 0.34rem;
    border-radius: 10px;
    text-align: center;
    font-family: 'Silkscreen', monospace;
    font-size: 1.15rem;
    letter-spacing: 0.06em;
    color: var(--text);
    background: rgba(13, 8, 23, 0.78);
    border: 2px solid rgba(255, 255, 255, 0.28);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.2);
    transition: color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}
.chess-clock.top { top: 10px; }
.chess-clock.bottom { bottom: 10px; }
.chess-clock.active {
    border-color: var(--sky);
    box-shadow: 0 0 14px rgba(63, 216, 255, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.25);
}
.chess-clock.low { color: var(--corn); text-shadow: 0 0 10px rgba(255, 210, 63, 0.6); }
.chess-clock.low.active { border-color: var(--magenta); color: var(--magenta); box-shadow: 0 0 16px rgba(255, 45, 120, 0.6); }

/* Game-over overlay */
#overlay {
    position: absolute;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 0.8rem;
    background: rgba(13, 8, 23, 0.82);
    border-radius: 10px;
    z-index: 5;
    text-align: center;
}
#overlay.show { display: flex; }
#overlay h2 { font-family: 'Bangers', 'Outfit', sans-serif; color: var(--corn); font-size: 2.25rem; letter-spacing: 0.03em; }
#overlay p { color: var(--text-dim); }
#overlay p a { color: var(--lime); font-weight: 700; text-decoration: underline; }
#clash-resign:disabled { opacity: 0.45; cursor: not-allowed; filter: grayscale(0.5); }

/* With an offer up, thin the scrim and pack the stack tighter so the FINAL
   POSITION stays readable behind the card. The offer is about the game that was
   just lost, so a player who cannot still see the board has lost the context the
   offer is trading on. */
#overlay.has-offer { background: rgba(13, 8, 23, 0.58); gap: 0.45rem; }
#overlay.has-offer h2 { font-size: 1.45rem; }
/* The ranked offer REPLACES the hardcoded premium nudge rather than sitting next
   to it. Two competing paid CTAs on one screen split the decision and, at this
   height, physically collide with the card. */
#overlay.has-offer #ai-review { display: none; }

/* Ranked offer card (wesell GameOfferSurface), post-match only. Sized to sit
   INSIDE the board without covering the final position: the board state and the
   offer have to be legible in the same frame, which is the whole point of
   surfacing it here instead of on a separate upgrade page. */
.offer-card {
    width: min(300px, 82%);
    padding: 0.75rem 0.9rem 0.85rem;
    border: 1px solid var(--corn);
    border-radius: 10px;
    background: linear-gradient(170deg, rgba(42, 20, 68, 0.96), rgba(16, 9, 28, 0.96));
    box-shadow: 0 0 22px rgba(255, 210, 63, 0.22);
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}
.offer-kicker {
    font-size: 0.68rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--magenta);
}
#overlay .offer-title {
    font-family: 'Outfit', sans-serif;
    font-weight: 800;
    font-size: 1.05rem;
    color: var(--text);
    line-height: 1.2;
}
#overlay .offer-price { color: var(--corn); font-size: 1.3rem; font-weight: 700; }
/* The struck list price only renders when it differs from the charged amount, so
   a full-price offer never shows a fake discount. */
#overlay .offer-price .was {
    color: var(--text-dim);
    font-size: 0.85rem;
    font-weight: 400;
    text-decoration: line-through;
    margin-left: 0.35rem;
}
.offer-cta { width: auto; margin-top: 0.25rem; padding: 0.25rem 1.4rem 0.4rem; text-decoration: none; }
/* Declining must be as easy as accepting, and legible rather than hidden in a
   corner: a dismissal is a real outcome row we want the player to be able to file. */
.offer-dismiss {
    border: 0;
    background: none;
    color: var(--text-dim);
    font-size: 0.72rem;
    text-decoration: underline;
    cursor: pointer;
    padding: 0.15rem;
}
.offer-dismiss:hover { color: var(--text); }

/* Promotion picker - overlays the board when a pawn reaches the last rank. */
#promo {
    position: absolute;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 0.7rem;
    background: rgba(13, 8, 23, 0.88);
    border-radius: 10px;
    z-index: 6;
}
#promo.show { display: flex; }
#promo p {
    font-family: 'Outfit', sans-serif;
    color: var(--corn);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-size: 1rem;
 font-weight: 800; }
#promo .promo-row { display: flex; gap: 0.6rem; }
#promo .promo-btn {
    width: clamp(56px, 14vw, 84px);
    height: clamp(56px, 14vw, 84px);
    padding: 6px;
    border-radius: 12px;
    border: 1px solid var(--card-line);
    background: rgba(255, 255, 255, 0.08);
    cursor: pointer;
    transition: transform 0.12s ease, box-shadow 0.12s ease;
}
#promo .promo-btn img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    filter: drop-shadow(0 0 5px rgba(63, 216, 255, 0.75));
    -webkit-user-drag: none;
}
#promo .promo-btn:hover {
    transform: translateY(-3px) scale(1.05);
    box-shadow: 0 0 16px rgba(255, 210, 63, 0.5);
    border-color: var(--corn);
}

/* Side panel */
.panel {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    flex: 1 1 260px;
    min-width: 240px;
    max-width: 380px;
}
@media (max-width: 780px) { .panel { max-width: none; } }
.card {
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.18) 0%, rgba(255, 255, 255, 0.04) 55%),
        rgba(29, 16, 48, 0.55);
    border: 1px solid rgba(255, 255, 255, 0.3);
    border-radius: 18px;
    padding: 0.95rem 1.05rem 1.05rem;
    box-shadow:
        0 8px 22px rgba(0, 0, 0, 0.4),
        inset 0 1px 0 rgba(255, 255, 255, 0.4),
        inset 0 -6px 14px rgba(0, 0, 0, 0.22);
    backdrop-filter: blur(7px);
    -webkit-backdrop-filter: blur(7px);
}
.card h3 {
    font-size: 0.78rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--sky);
    margin-bottom: 0.6rem;
    text-shadow: 0 0 10px rgba(63, 216, 255, 0.5);
}
/* Big centred hero avatar (see .arena-table above); the glyph is set by play.js.
   Scoped under #opponent so it beats the base .card typography. */
.arena-table .hero-opponent .bot-face {
    width: 100%;
    max-width: 200px;
    height: auto;
    aspect-ratio: 1 / 1;
    border-radius: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: clamp(4rem, 9vw, 7rem);
    line-height: 1;
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.22) 0%, rgba(255, 255, 255, 0) 52%),
        radial-gradient(circle at 50% 32%, rgba(123, 47, 247, 0.5), rgba(0, 0, 0, 0.45));
    border: 3px solid rgba(255, 255, 255, 0.32);
    box-shadow: inset 0 2px 3px rgba(255, 255, 255, 0.3), 0 8px 22px rgba(0, 0, 0, 0.4);
    text-shadow: 0 0 18px currentColor;
}
/* A ranked challenger is a real vipsallowed member with real pixel art, so the
   frame drops its glyph styling and becomes a picture frame. Only applied once
   the image has actually loaded, so a dead CDN leaves the glyph in place. */
.arena-table .hero-opponent .bot-face.has-ava {
    padding: 0;
    overflow: hidden;
    text-shadow: none;
    background: rgba(4, 10, 20, 0.82);
}
/* YOUR SEAT (GDD s1.2): the same frame as the opponent's, on your side of the
   board, holding the fighter you picked in the sign-up wizard. */
.seat-card { display: flex; flex-direction: column; align-items: center; text-align: center; }
.seat-card .rail-cap {
    align-self: stretch; text-align: left; font-family: 'Outfit', sans-serif; font-size: 0.78rem;
    letter-spacing: 0.14em; text-transform: uppercase; color: var(--sky); margin-bottom: 0.7rem;
 font-weight: 800; }
.seat-card .seat-face {
    position: relative;
    width: 100%; max-width: 160px; aspect-ratio: 1 / 1; border-radius: 18px;
    display: flex; align-items: center; justify-content: center; overflow: hidden;
    font-size: 3rem; line-height: 1; color: var(--sky);
    background: radial-gradient(circle at 50% 32%, rgba(63, 216, 255, 0.28), rgba(0, 0, 0, 0.45));
    border: 3px solid rgba(63, 216, 255, 0.45);
    box-shadow: inset 0 2px 3px rgba(255, 255, 255, 0.25), 0 8px 22px rgba(0, 0, 0, 0.4);
}
.seat-card .seat-name { font-family: 'Bangers', 'Outfit', sans-serif; font-weight: 400; color: var(--text); font-size: 1.562rem; margin-top: 0.6rem; letter-spacing: 0.03em; }
.seat-card .seat-sub { font-size: 0.9rem; color: var(--text-dim); margin-top: 0.15rem; }
.seat-pick { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: .2rem;
  font-size: 0.85rem; font-weight: 700; color: var(--corn); text-align: center; text-decoration: none; padding: 0.4rem 0.4rem 0.55rem;
  background: radial-gradient(circle at 50% 38%, rgba(255,255,255,.10), rgba(255,255,255,0) 62%); }
.seat-pick .seat-pawn { flex: 1 1 auto; min-height: 0; max-height: 70%; width: auto; object-fit: contain;
  filter: grayscale(1) brightness(.75) drop-shadow(0 4px 8px rgba(0,0,0,.5)); opacity: .55; transition: opacity .15s, filter .15s; }
.seat-pick:hover .seat-pawn { opacity: .8; filter: grayscale(.3) brightness(.95) drop-shadow(0 4px 10px rgba(0,0,0,.5)); }
.seat-pick span { text-decoration: underline; text-underline-offset: 3px; }
/* A face painted by js/seat.js. Fighter stills are smooth art (contain);
   members' avatars are pixel art (cover, crisp). */
.has-face { padding: 0 !important; text-shadow: none !important; background: rgba(4, 10, 20, 0.82) !important; overflow: hidden; }
.seat-img { width: 100%; height: 100%; object-fit: contain; display: block; }
.seat-img.is-pixel { object-fit: cover; image-rendering: pixelated; }
.bot-face .bot-ava {
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Low-res art blown up to 200px: keep the pixels. */
    image-rendering: pixelated;
}
.arena-table .hero-opponent .bot-name { font-family: 'Bangers', 'Outfit', sans-serif; font-weight: 400; color: var(--corn); font-size: 1.75rem; margin-top: 0.7rem; letter-spacing: 0.03em; }
@media (max-width: 900px) {
    .arena-table .hero-opponent .bot-face { max-width: 130px; }
}
.hero-opponent .bot-tier {
    font-size: 0.85rem;
    color: var(--text-dim);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
    margin-top: 0.15rem;
}
.hero-opponent .bot-tier::before {
    content: '';
    width: 1.1rem;
    height: 1.1rem;
    background: url('/img/ui/star.png') center / contain no-repeat;
    filter: drop-shadow(0 0 4px rgba(255, 210, 63, 0.6));
}

/* Glossy candy select - beveled dropdown to match the button kit. */
select {
    width: 100%;
    padding: 0.6rem 0.8rem;
    border-radius: 12px;
    border: 2px solid rgba(255, 255, 255, 0.35);
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.28) 0%, rgba(255, 255, 255, 0) 48%),
        linear-gradient(180deg, #2f1a5e 0%, #1a0e3a 100%);
    color: var(--text);
    font-family: inherit;
    font-weight: 600;
    font-size: 0.95rem;
    cursor: pointer;
    box-shadow: inset 0 2px 3px rgba(255, 255, 255, 0.3), inset 0 -3px 6px rgba(0, 0, 0, 0.35), 0 4px 10px rgba(0, 0, 0, 0.35);
}

/* Buttons ARE the craftpix 567216 blank button art (real kit PNGs), drawn as a
   CSS border-image 9-slice so the glossy body, rounded corners and baked drop
   shadow scale to any label width without distorting. The label sits on top in
   the flat middle band. Colour = which kit PNG (grey default; per-id below). */
button.btn {
    position: relative;
    display: block;
    width: 100%;
    min-height: 20px;
    padding: 0.2rem 0.7rem 0.35rem;
    border-style: solid;
    /* border-width < slice px => corners render crisp and compact */
    border-width: 18px 24px 26px 22px;
    border-image-source: url('/img/ui/btnbg-grey.png');
    border-image-slice: 40 48 52 44 fill;
    border-image-repeat: stretch;
    background: transparent;
    color: #2a1a08;
    font-family: inherit;
    font-weight: 800;
    font-size: 0.98rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    text-align: center;
    cursor: pointer;
    text-shadow: 0 1px 0 rgba(255, 255, 255, 0.45);
    filter: drop-shadow(0 4px 7px rgba(0, 0, 0, 0.4));
    transition: transform 0.07s ease, filter 0.12s ease;
}
button.btn:hover { filter: brightness(1.07) saturate(1.06) drop-shadow(0 5px 9px rgba(0, 0, 0, 0.45)); }
button.btn:active { transform: translateY(3px); filter: brightness(0.97) drop-shadow(0 2px 4px rgba(0, 0, 0, 0.4)); }
button.btn + button.btn, button.btn + select, select + button.btn { margin-top: 0.6rem; }

/* Colour variants = swap in the matching kit button PNG. */
button.btn.primary { border-image-source: url('/img/ui/btnbg-green.png'); color: #0c3a1e; }
button.btn.danger  { border-image-source: url('/img/ui/btnbg-red.png');   color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,0.4); }
button.btn.gold    { border-image-source: url('/img/ui/btnbg-gold.png');  color: #2a1600; }

/* Per-action kit button colour (kit palette: gold / red / blue). */
#new-game, #create, #rematch, #leave { border-image-source: url('/img/ui/btnbg-gold.png'); color: #2a1600; }
#resign                              { border-image-source: url('/img/ui/btnbg-red.png');  color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,0.4); }
#join, #chat-send, #copy-code        { border-image-source: url('/img/ui/btnbg-blue.png'); color: #06202f; }

/* The overlay REVIEW link is an <a>, so the button.btn kit rules don't reach
   it - re-apply the blue kit art explicitly (FEAT-2026-0923-0025). */
a.btn#review,
a.btn#offer-cta {
    display: inline-block;
    border-style: solid;
    border-width: 15px 18px 18px 16px;
    border-image-source: url('/img/ui/btnbg-blue.png');
    border-image-slice: 40 48 52 44 fill;
    border-image-repeat: stretch;
    background: transparent;
    color: #06202f;
    font-family: inherit;
    font-weight: 800;
    font-size: 0.88rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    text-align: center;
    cursor: pointer;
    text-shadow: 0 1px 0 rgba(255, 255, 255, 0.45);
    filter: drop-shadow(0 4px 7px rgba(0, 0, 0, 0.4));
    transition: transform 0.07s ease, filter 0.12s ease;
}
a.btn#review:hover,
a.btn#offer-cta:hover { filter: brightness(1.07) saturate(1.06) drop-shadow(0 5px 9px rgba(0, 0, 0, 0.45)); }
a.btn#review:active,
a.btn#offer-cta:active { transform: translateY(3px); filter: brightness(0.97); }
/* The paid CTA takes the GOLD kit so it reads as the one buying action on the
   screen; REMATCH keeps gold too but sits above the card, not inside it. */
a.btn#offer-cta { border-image-source: url('/img/ui/btnbg-gold.png'); color: #2a1600; }

#status { font-size: 0.95rem; min-height: 1.4em; }
#status .thinking { color: var(--sky); }
#status .danger { color: var(--magenta); }

/* Event feed (chat pane placeholder - FEAT-0022 replaces this with lingo) */
#events {
    max-height: 230px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    font-size: 0.85rem;
}
#events .ev {
    padding: 0.35rem 0.55rem;
    border-radius: 8px;
    background: rgba(0, 0, 0, 0.3);
    color: var(--text-dim);
}
#events .ev.spicy { border-left: 3px solid var(--magenta); color: var(--text); }
#events .ev-who { color: var(--corn); font-weight: 700; }
/* Player talk-back lines (FEAT-2026-0923-0022): your own chat, right-aligned. */
#events .ev.me { border-left: 3px solid var(--sky); color: var(--text); align-self: flex-end; text-align: right; }
#events .ev.me .ev-who { color: var(--sky); }

/* Talk-back input row: rides on button.btn art, mirrors the multiplayer chat. */
.lingo-chat { display: flex; gap: 0.4rem; margin-top: 0.55rem; }
.lingo-input {
    flex: 1;
    padding: 0.62rem 0.8rem;
    border-radius: 12px;
    border: 2px solid rgba(255, 255, 255, 0.28);
    background:
        linear-gradient(180deg, rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.25)),
        rgba(13, 8, 23, 0.5);
    color: var(--text);
    font-family: inherit;
    font-size: 0.95rem;
    letter-spacing: 0.06em;
    box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.45), inset 0 -1px 0 rgba(255, 255, 255, 0.12);
}
.lingo-input::placeholder { color: rgba(255, 255, 255, 0.4); text-transform: uppercase; letter-spacing: 0.12em; }
.lingo-input:focus { outline: none; border-color: var(--corn); box-shadow: 0 0 12px rgba(255, 210, 63, 0.35); }
button.btn.lingo-send {
    width: auto;
    padding: 0.02rem 0.2rem 0.1rem;
    font-size: 0.74rem;
    border-width: 12px 16px 15px 14px;
}
.lingo-input:disabled, .lingo-send:disabled { opacity: 0.45; cursor: not-allowed; }

/* Opening coach card (FEAT-2026-0926-0064). Names the live opening from the
   tauTree; .coach-avatar is the 3D-grandmaster swap-in slot. */
.coach-head { display: flex; align-items: center; gap: 0.7rem; }
.coach-avatar {
    flex: 0 0 auto;
    width: 52px;
    height: 52px;
    display: grid;
    place-items: center;
    font-size: 2rem;
    line-height: 1;
    color: var(--corn);
    border-radius: 14px;
    border: 1px solid var(--card-line);
    background: radial-gradient(circle at 50% 35%, rgba(255, 210, 63, 0.22), rgba(29, 16, 48, 0.6));
    text-shadow: 0 0 12px rgba(255, 210, 63, 0.6);
}
.coach-id { min-width: 0; }
.coach-name {
    font-family: 'Bangers', 'Outfit', sans-serif;
    font-weight: 400;
    color: #fff;
    line-height: 1.15; letter-spacing: 0.03em; }
.coach-eco {
    display: inline-block;
    margin-top: 0.25rem;
    padding: 0.05rem 0.5rem 0.1rem;
    font-size: 0.7rem;
    letter-spacing: 0.1em;
    color: var(--sky);
    border: 1px solid var(--card-line);
    border-radius: 999px;
}
.coach-line {
    margin-top: 0.7rem;
    font-size: 0.82rem;
    line-height: 1.4;
    color: rgba(255, 255, 255, 0.82);
}

/* Head-to-head rivalry line under the opponent (FEAT-2026-0926-0064). */
.bot-rivalry {
    margin-top: 0.5rem;
    font-size: 0.78rem;
    letter-spacing: 0.02em;
    color: rgba(255, 255, 255, 0.8);
}
.bot-rivalry .h2h { font-variant-numeric: tabular-nums; }
.bot-rivalry .nemesis { color: var(--magenta); font-weight: 700; }

/* Ranked Challenger badge (FEAT-2026-0930-0008): the honesty marker on a
   seeded quick-match opponent. Shared by /webplay and /multiplayer. */
.ranked-badge {
    display: inline-block;
    font-family: 'Silkscreen', monospace;
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    padding: 0.1rem 0.45rem 0.16rem;
    border-radius: 999px;
    border: 1px solid rgba(63, 216, 255, 0.55);
    color: var(--sky);
    background: rgba(63, 216, 255, 0.12);
    vertical-align: middle;
}

/* Phone seat strips (GDD s1.2). Kept LAST so they beat the desktop frame sizes
   defined above, which sit later than the layout block. */
@media (max-width: 900px) {
    .arena-table .hero-opponent .bot-face,
    .arena-table .seat-card .seat-face { width: 64px; max-width: 64px; font-size: 2.2rem; border-radius: 12px; border-width: 2px; }
    .arena-table .hero-opponent .bot-name,
    .arena-table .seat-card .seat-name { margin-top: 0; font-size: 1.1rem; }
    .arena-table .hero-opponent .bot-tier { justify-content: flex-start; flex-basis: 100%; }
    .arena-table .hero-opponent .bot-rivalry { flex-basis: 100%; }
}

/* Season run on the result screen (run-bank.js). */
.run-box { margin: .4rem 0 .6rem; text-align: center; }
.run-box .run-line { margin: 0 0 .4rem; font-weight: 700; color: var(--corn, #ffd23f); font-size: .95rem; }
.run-box[hidden] { display: none; }
