* {
    box-sizing: border-box;
}

html, body {
    margin: 0;
    padding: 0;
    height: 100%;
    background-color: #000;
    color: #ecf0f1;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* .app is the shell's PLAYING AREA rect (below the HUD, right of the button
   column, above the GAME BUTTONS footer - see ../../arcade/arcade-shell.css).
   Laid out as a flex column so the board+move-list area and the footer stack
   in normal flow, same pattern as Battlefield's own site.css. */
.app {
    display: flex;
    flex-direction: column;
    /* Sized from the PLAYING AREA itself (a size container, below) rather
       than the viewport, so the board always fits whatever height is left
       once the HUD and the GAME BUTTONS footer - taller in setup mode, with
       its two-row palette - have taken theirs. 3.25rem is .center's vertical
       padding plus the board's top margin. */
    --board-size: min(100cqh - 3.25rem, 55vw);
}
/* When the move list does not fit beside the board it is hidden (board.js,
   fitMoveList, sets .no-moves), and the board can have the full width. */
.app.no-moves {
    --board-size: min(100cqh - 3.25rem, 100cqw - 3rem);
}

/* No generic #touch-controls element exists here (board drag/drop is its
   own pointer-event mechanism), so the shared CSS's automatic touch-row
   --arcade-bottom reservation never fires. the GAME BUTTONS footer below
   just takes its own natural height in the flex column instead - same
   override battlefield/css/site.css uses for the same reason. */
body {
    --arcade-bottom: max(0.75rem, env(safe-area-inset-bottom));
    /* This HUD carries far more text than any arcade game's (both players,
       both clocks, the mode and a status slot), so it needs a smaller font
       than the shared default to stay inside the HUD zone: one line from a
       landscape phone upwards, two on a portrait phone. */
    --hud-font-size: clamp(0.65rem, 2vw, 1.4rem);
}

.playing-area {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    overflow: hidden;
    container-type: size;
}

.center {
    flex: 0 0 auto;
    background-color: #000;
    color: #ecf0f1;
    padding: 1.5rem 0 1.5rem 1.5rem;
}

.board {
    position: relative;
    width: var(--board-size);
    height: var(--board-size);
    margin: 0.25rem 0 0;
    touch-action: none;
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
}

.board__bg {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    z-index: 0;
    touch-action: none;
    -webkit-user-drag: none;
    user-select: none;
}

.board__pieces {
    position: absolute;
    inset: 0;
    display: grid;
    grid-template-columns: repeat(8, 1fr);
    grid-template-rows: repeat(8, 1fr);
    place-items: center;
    pointer-events: auto;
    touch-action: none;
    z-index: 2;
}

.board__pieces img {
    width: 90%;
    height: 90%;
    margin: 0;
    display: block;
    min-width: 0;
    min-height: 0;
    object-fit: contain;
    pointer-events: auto;
    cursor: grab;
    user-select: none;
    -webkit-user-drag: none;
    -webkit-touch-callout: none;
    touch-action: none;
    transition: transform 0s;
}

.board__pieces img.dragging {
    cursor: grabbing;
    z-index: 10;
    filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.35));
}

.board__slide-piece {
    position: absolute;
    pointer-events: none;
    user-select: none;
    object-fit: contain;
    z-index: 20;
    will-change: transform;
    transition: transform 280ms ease-in-out;
}

/* Overlay SVG used to draw arrows for best moves. */
.board__hints {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    overflow: visible;
    z-index: 6;
}

.board__hints .selection {
    fill: none;
    stroke: #f1c40f;
    stroke-width: 0.08;
    pointer-events: none;
}

.side {
    background-color: #14181b;
    color: #ecf0f1;
    /* Top edge level with the board's: .center's 1.5rem padding plus the
       board's own 0.25rem top margin. Same height as the board, so the
       bottom edges line up too. */
    margin: 1.75rem 0 0 1.5rem;
    padding: 1rem;
    /* As wide as its columns (fixed widths, below) and no wider. */
    flex: 0 0 auto;
    height: var(--board-size);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.side h2 {
    margin: 0 0 0.5rem;
    font-size: 1.5rem;
    line-height: 1.2;
    flex: 0 0 auto;
}

.side .moves-scroll {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    min-height: 0;
}

.moves {
    border-collapse: collapse;
    font-size: 0.875rem;
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
}

.moves th,
.moves td {
    padding: 0.25rem 0.5rem;
    text-align: left;
    border-bottom: 1px solid rgba(255, 255, 255, 0.15);
}

.moves th:last-child {
    text-align: right;
}

/* White and Black share one width: room for a typical move with a hint
   swatch in front of it. Eval only needs room for a number like "+0.62",
   so it is narrower. (A rare longer move just widens its column.) */
.moves th:nth-child(n+2),
.moves > tbody > tr > td:nth-child(n+2) {
    width: 5rem;
    min-width: 5rem;
    box-sizing: border-box;
    white-space: nowrap;
}
.moves th:last-child,
.moves > tbody > tr > td.eval {
    width: 3.75rem;
    min-width: 3.75rem;
}

.moves th:first-child,
.moves td:first-child {
    width: 2.5rem;
    color: #9aa5ab;
    text-align: right;
}

/* Where each of the engine's moves came from (an Analysis option,
   body.origin-colours). Plain = the book; light blue = fetched from Lichess
   just now (and added to the book); green = worked out here by the engine
   (and added to the book). */
body.origin-colours .moves td.from-lichess {
    color: #7fd6ff;
}
body.origin-colours .moves td.from-engine {
    color: #5fd38a;
}
/* The player's own moves, by the grade the coach gave them (an Analysis
   option, body.grade-colours): gold, silver, bronze, or red for a poor move
   played anyway. */
body.grade-colours .moves td.grade-r1 { color: #f1c40f; }
body.grade-colours .moves td.grade-r2 { color: #cfd6da; }
body.grade-colours .moves td.grade-r3 { color: #cd7f32; }
body.grade-colours .moves td.grade-bad { color: #ff5c66; }
/* Silver is close to the plain text colour: bold sets it apart. */
body.grade-colours .moves td.grade-r1,
body.grade-colours .moves td.grade-r2,
body.grade-colours .moves td.grade-r3,
body.grade-colours .moves td.grade-bad {
    font-weight: 700;
}

.moves td.current,
body.learning-mode .moves td.current {
    background-color: #f1c40f;
    color: #2c3e50;
    font-weight: bold;
}

.moves td.move-cell {
    white-space: nowrap;
}

.moves tr.branch td.move-cell {
    font-style: italic;
}

.moves tr.branch-sep td {
    padding: 0;
    border-bottom: none;
    height: 0.25rem;
}

.moves tr.branch-block > td {
    padding: 0.25rem 0 0.25rem 1.5rem;
    border-bottom: none;
    background: rgba(255, 255, 255, 0.04);
}

.moves table.branch-table {
    width: calc(100% - 1.5rem);
    border-collapse: collapse;
    border-left: 2px solid #5a6a73;
    font-style: italic;
}

.moves table.branch-table td {
    padding: 0.15rem 0.5rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.moves table.branch-table td:first-child {
    width: 2.5rem;
    color: #9aa5ab;
    text-align: right;
    font-style: normal;
}

.moves table.branch-table td.eval {
    font-variant-numeric: tabular-nums;
    text-align: right;
    color: #cfd6da;
    white-space: nowrap;
    font-style: normal;
}

.moves [data-node-id],
.moves [data-node-id] * {
    cursor: pointer;
}

.moves td.eval {
    font-variant-numeric: tabular-nums;
    text-align: right;
    color: #cfd6da;
    white-space: nowrap;
}

.moves tr.hint td {
    font-style: italic;
    color: #9aa5ab;
    border-bottom: 1px dashed rgba(255, 255, 255, 0.2);
}

.moves tr.hint td .swatch {
    display: inline-block;
    width: 0.7rem;
    height: 0.7rem;
    margin-right: 0.35rem;
    vertical-align: middle;
    border-radius: 2px;
}

.moves tr.hint.rank-1 .swatch { background: #f1c40f; }
.moves tr.hint.rank-2 .swatch { background: #bdc3c7; }
.moves tr.hint.rank-3 .swatch { background: #cd7f32; }

/* Hide the moves box when there is no room for it beside the board. Board
   always wins. Hidden with visibility, not display, so board.js can still
   measure how wide it would be. */
.app.no-moves .side {
    visibility: hidden;
}
/* Setup mode has no use for the move list (it would show the game just left,
   not the board being arranged). Hidden but still taking its space, so the
   board keeps its size and place when switching between train and setup. */
body.setup-mode .side {
    visibility: hidden;
}

/* ---- GAME BUTTONS: move-navigation footer ---- */
.board-footer {
    flex: 0 0 auto;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 1.875rem; /* same spacing as the other games' .touch-controls row */
    padding: 0.5rem 1rem 0;
    box-sizing: border-box;
    position: relative;
}

body.debug-zones .board-footer {
    background: rgba(124, 252, 0, 0.08) !important;
    outline: 1px dashed #7CFC00;
    outline-offset: -1px;
}
body.debug-zones .board-footer::before {
    content: "GAME BUTTONS";
    position: absolute;
    top: 0.2rem;
    left: 50%;
    transform: translateX(-50%);
    color: #7CFC00;
    font: 0.65rem/1 monospace;
    letter-spacing: 0.05em;
    text-shadow: 0 0 4px rgba(0, 0, 0, 0.9);
    pointer-events: none;
    z-index: 999;
}

.board-footer .arcade-btn {
    width: var(--touch-size);
    height: var(--touch-size);
}
/* Slid sideways so the buttons are centred under the board rather than in
   the footer; board.js (alignFooter) works out how far. */
.board-footer > * {
    transform: translateX(var(--footer-shift, 0px));
}
/* Accept move (learn mode) has its own shift: out to the board's right-hand
   edge when there is room, otherwise along with the rest. */
.board-footer > #btn-accept {
    transform: translateX(var(--accept-shift, 0px));
}
/* Restart likewise, out to the board's left-hand edge. */
.board-footer > #nav-reset {
    transform: translateX(var(--reset-shift, 0px));
}
/* The buttons keep their size: on a narrow screen it is the spacing that
   gives, not the buttons. */
.board-footer > .arcade-btn {
    flex: 0 0 auto;
}
@media (max-width: 30rem) {
    .board-footer {
        gap: 0.5rem;
        padding-left: 0.25rem;
        padding-right: 0.25rem;
    }
}

/* ---- LEFT MENU / GAME BUTTONS icon images ----
   The shared .arcade-btn only styles inline <svg> icons by default (45%
   fill) - these buttons use <img> instead (the existing piece/control art),
   so size them to match. The nav-reset/best-moves/move-nav icons are flat
   dark-stroke SVG files (not currentColor), so - like before, on the old
   dark .menu background - they need inverting to read on .arcade-btn's dark
   circular background. The two king icons stay un-inverted: their literal
   white/black colouring IS the control (choose white, choose black). */
.arcade-actions .arcade-btn img,
.board-footer .arcade-btn img {
    width: 58%;
    height: 58%;
    pointer-events: none;
}
/* The last button of each mode (Analysis in train, Book builder in setup)
   stands a little apart from the buttons above it: a gap of half a
   button's height in all (so less the column's ordinary gap, which still
   applies). */
#btn-analysis,
#btn-book {
    margin-top: calc(var(--arcade-btn-size) / 2 - clamp(0.3rem, 1.6vh, 0.6rem));
}
/* The mode button likewise stands half a button below Mute, setting the
   game's own buttons apart from Menu, Help and Mute. */
#btn-mode {
    margin-top: calc(var(--arcade-btn-size) / 2 - clamp(0.3rem, 1.6vh, 0.6rem));
}
/* The move buttons', Restart's and Best moves' own icons (inline SVG, drawn
   in the button's colour), sized like the image icons rather than the
   shared 45%. */
.board-footer > .arcade-btn svg,
#nav-reset svg,
#btn-book svg {
    width: 58%;
    height: 58%;
}

/* ---- Learn mode / setup mode ----
   board.js toggles body.learning-mode (in a game) and body.setup-mode. The
   mode button shows the icon of the mode you are in. */
/* LEFT MENU colour code.
   Light blue - the "switch to ..." buttons, which change a mode: train /
   setup (the same blue as the mode's name in the HUD) and which colour you
   play (its icon is a piece, so only its ring takes the colour).
   Yellow - buttons that open a dialog: openings (ECO), analysis options,
   book builder. */
#btn-mode,
#btn-mode:hover:not(:disabled),
#btn-color,
#btn-color:hover:not(:disabled) {
    color: #7fd6ff;
    border-color: rgba(127, 214, 255, 0.8);
}
#btn-eco,
#btn-eco:hover:not(:disabled),
#btn-analysis,
#btn-analysis:hover:not(:disabled),
#btn-book,
#btn-book:hover:not(:disabled) {
    color: #f1c40f;
    border-color: rgba(241, 196, 15, 0.8);
}
#btn-mode svg {
    width: 62%;
    height: 62%;
}
#btn-mode .icon-mode-setup,
body.setup-mode #btn-mode .icon-mode-learning {
    display: none;
}
body.setup-mode #btn-mode .icon-mode-setup {
    display: block;
}

/* ---- Setup position mode ----
   The GAME BUTTONS footer swaps its move-navigation buttons for a palette,
   laid out as a single row no taller than the navigation buttons it
   replaces, so the footer keeps its height and the board does not change
   size on entering or leaving setup mode. */
.board-footer {
    container-type: inline-size;
    min-height: calc(var(--touch-size) + 0.5rem);
}
/* The palette's buttons join the footer's own row (display: contents), so
   Restart - a footer button, also wanted in setup - can sit among them. The
   order is: Restart, clear board, square click, side to move; board.js
   (alignFooter) puts the first two at the board's left-hand edge and
   centres the other two under the board. */
.setup-palette {
    display: none;
}
body.setup-mode .setup-palette {
    display: contents;
}
.setup-palette > .arcade-btn {
    transform: translateX(var(--footer-shift, 0px));
}
/* Clear board keeps Restart company at the board's left-hand edge. */
.setup-palette > [data-tool="clear"] {
    transform: translateX(var(--reset-shift, 0px));
}
body.setup-mode .board-footer > #nav-reset { order: 1; }
body.setup-mode .setup-palette [data-tool="clear"] { order: 2; }
body.setup-mode .setup-palette [data-tool="click"] { order: 3; }
body.setup-mode .setup-palette [data-tool="turn"] { order: 4; }
/* Sized like the footer's own icons. */
.setup-palette [data-tool="clear"] svg {
    width: 58%;
    height: 58%;
}
/* Restart stays (in setup it puts the standard position back). */
body.setup-mode .board-footer > .arcade-btn:not(#nav-reset) {
    display: none;
}
.board-footer .setup-palette .arcade-btn {
    flex: 0 0 auto;
}

/* ---- Square click ----
   One button says what a click on a board square does in setup mode, and
   opens a chooser to change it. Its icon is a board square with the yellow
   inset highlight a selected square has, holding the piece that will be
   placed, a cross for "remove", or nothing. */
.click-icon {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 62%;
    height: 62%;
    background: #b98a62;
    box-shadow: inset 0 0 0 0.16em #f1c40f;
    border-radius: 0.12em;
    pointer-events: none;
}
.click-icon img {
    width: 84%;
    height: 84%;
}
.click-icon svg {
    width: 62%;
    height: 62%;
    color: #fff;
}
/* The chooser: two rows of seven, floating just above the row of buttons.
   board.js sets its left edge so it sits over the button, inside the footer. */
.click-chooser {
    /* Seven across, within the footer's width on a narrow screen. */
    --choice-size: min(2.6rem, (100cqw - 4.2rem) / 7);
    position: absolute;
    bottom: calc(100% + 0.4rem);
    left: 0;
    z-index: 35;
    display: grid;
    grid-template-columns: repeat(7, var(--choice-size));
    gap: 0.35rem;
    padding: 0.6rem;
    background: rgba(8, 12, 18, 0.97);
    border: 2px solid rgba(216, 245, 255, 0.55);
    box-shadow: 0 0 24px rgba(0, 0, 0, 0.6);
    transform: none;
}
.click-chooser.hidden {
    display: none;
}
.board-footer .click-chooser .arcade-btn {
    width: var(--choice-size);
    height: var(--choice-size);
}
.board-footer .click-chooser .arcade-btn img {
    width: 78%;
    height: 78%;
}
/* Piece buttons sit on the board's dark-square colour, so black pieces show
   up as well as white ones (they vanish on the usual dark button). */
.click-chooser .arcade-btn[data-piece],
.click-chooser .arcade-btn[data-piece]:hover:not(:disabled) {
    background: #b98a62;
}
.click-chooser .arcade-btn.selected,
.click-chooser .arcade-btn.selected:hover:not(:disabled) {
    border-color: #f1c40f;
    box-shadow: 0 0 0 2px #f1c40f;
}
.setup-btn--turn {
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
    font-weight: 700;
    font-size: 1rem;
    color: #fff;
}

/* Engine licence credit at the foot of the help panel. */
.help-credit {
    font-size: 0.85em;
    opacity: 0.8;
}
.help-credit a {
    color: #f1c40f;
}

/* ---- Book builder (setup mode's Book builder button) ----
   A dialog (the shared help-overlay / help-panel look). Number fields opt
   back in to text selection, which the arcade shell turns off page-wide. */
/* ---- Board dialogs ----
   The opening picker's and the book builder's dialogs open over the board:
   they are children of .board, so they are centred on it and cannot spill
   outside it. Whatever does not fit scrolls inside the panel. */
.board-dialog {
    position: absolute;
    inset: 0;
    z-index: 50;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 3%;
    box-sizing: border-box;
    background: rgba(0, 0, 0, 0.6);
    container-type: size;
    /* The board itself is locked while the book builder runs; its dialog,
       which holds the Stop button, is not. */
    pointer-events: auto;
    cursor: default;
}
.board-dialog.hidden {
    display: none;
}
.board-dialog__panel {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    /* One width for all three dialogs. */
    width: min(100%, 30rem);
    max-width: 100%;
    max-height: 100%;
    box-sizing: border-box;
    padding: 0.9rem;
    overflow-y: auto;
    touch-action: pan-y;
    background: rgba(8, 12, 18, 0.97);
    border: 2px solid rgba(216, 245, 255, 0.55);
    box-shadow: 0 0 24px rgba(0, 0, 0, 0.7);
    color: #ecf0f1;
}
.board-dialog .board-dialog__close {
    flex: 0 0 auto;
    align-self: center;
    min-width: 6rem;
}
/* ---- Analysis options ----
   Three tick boxes. The real checkbox is kept (for the keyboard and screen
   readers) but drawn as a square of our own. */
#btn-analysis svg {
    width: 66%;
    height: 66%;
}
.analysis-dialog {
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
    font-size: 0.9rem;
}
.tick {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    line-height: 1.3;
    cursor: pointer;
}
.tick input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}
.tick__box {
    flex: 0 0 auto;
    width: 1.15em;
    height: 1.15em;
    margin-top: 0.05em;
    box-sizing: border-box;
    border: 2px solid rgba(216, 245, 255, 0.7);
    background: rgba(0, 0, 0, 0.5);
}
.tick input:checked + .tick__box {
    border-color: #f1c40f;
    background: #f1c40f
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12.5 L10 17.5 L19 7' fill='none' stroke='%232c3e50' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
        center / 90% no-repeat;
}
.tick input:focus-visible + .tick__box {
    outline: 2px solid #fff;
    outline-offset: 2px;
}
/* The opening picker's dialog uses the board's full height for its list. */
#opening-dialog-panel {
    height: 100%;
}
/* A LEFT MENU button that carries a short word rather than an icon. */
.arcade-btn--text {
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
    font-weight: 700;
    font-size: calc(var(--arcade-btn-size) * 0.3);
    letter-spacing: 0;
}
.book-panel {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
    font-size: 0.875rem;
}
/* On a board wide enough, the mini board goes beside the controls rather
   than under them, so the dialog is short enough to fit without scrolling. */
@container (min-width: 26rem) {
    .book-panel {
        display: grid;
        grid-template-columns: 1fr auto;
        column-gap: 1rem;
        align-items: start;
    }
    .book-panel > * {
        grid-column: 1;
    }
    .book-panel > .book-mini-wrap {
        grid-column: 2;
        grid-row: 1 / span 6;
        align-self: center;
    }
}
.book-panel__title {
    font-weight: 700;
    letter-spacing: 0.12em;
    padding-bottom: 0.35rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.15);
}
.book-panel__field {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}
.book-panel__field input {
    width: 3.6rem;
    box-sizing: border-box;
    padding: 0.25rem 0.35rem;
    background: rgba(0, 0, 0, 0.5);
    color: #fff;
    border: 1px solid rgba(216, 245, 255, 0.55);
    border-radius: 0;
    font: inherit;
    text-align: right;
    -webkit-user-select: text;
    user-select: text;
    touch-action: auto;
}
.book-panel__field input:focus {
    outline: none;
    border-color: #f1c40f;
}
.book-panel__buttons {
    display: flex;
    gap: 0.5rem;
}
.book-btn {
    flex: 1;
    padding: 0.4rem 0;
    background: transparent;
    color: #f1c40f;
    border: 2px solid #f1c40f;
    border-radius: 0;
    font: inherit;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    cursor: pointer;
}
.book-btn:hover:not(:disabled) {
    background: rgba(241, 196, 15, 0.15);
}
.book-btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}
.book-panel__stats {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.2rem 0.75rem;
    margin: 0;
}
.book-panel__stats dt {
    color: #9aa5ab;
}
.book-panel__stats dd {
    margin: 0;
    text-align: right;
}
.book-panel__message {
    min-height: 1.3em;
    color: #9aa5ab;
    line-height: 1.3;
}
.book-panel__dots {
    color: #f1c40f;
}
/* Mini board: the position being worked on. */
.book-mini-wrap {
    display: flex;
    justify-content: center;
}
.book-mini {
    position: relative;
    width: min(11rem, 42cqw, 42cqh);
    height: min(11rem, 42cqw, 42cqh);
    background: url("../images/board%20white.svg") center / 100% 100% no-repeat;
    visibility: hidden;
}
.book-mini.has-position {
    visibility: visible;
}
.book-mini img {
    position: absolute;
    width: 12.5%;
    height: 12.5%;
    pointer-events: none;
}
/* While a run is in progress the setup board is not for editing. */
body.book-running .board {
    pointer-events: none;
}

/* ---- Opening picker (setup mode's ECO button) ----
   Takes the move list's place in the side panel, like the book builder, at
   the same width. The text field opts back in to text selection, which the
   arcade shell turns off page-wide. */
.opening-panel {
    display: flex;
    flex: 1 1 auto;
    min-height: 0;
    flex-direction: column;
    gap: 0.5rem;
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
    font-size: 0.875rem;
}
.opening-input {
    width: 100%;
    box-sizing: border-box;
    padding: 0.35rem 0.5rem;
    background: rgba(0, 0, 0, 0.5);
    color: #fff;
    border: 1px solid rgba(216, 245, 255, 0.55);
    border-radius: 0;
    font: inherit;
    -webkit-user-select: text;
    user-select: text;
    touch-action: auto;
}
.opening-input:focus {
    outline: none;
    border-color: #f1c40f;
}
.opening-status {
    min-height: 1.2em;
    font-size: 0.8rem;
    color: #9aa5ab;
}
.opening-list {
    flex: 1 1 0;
    min-height: 0;
    margin: 0;
    padding: 0;
    list-style: none;
    overflow-y: auto;
    touch-action: pan-y;
    border-top: 1px solid rgba(255, 255, 255, 0.15);
}
.opening-item {
    padding: 0.3rem 0.25rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    cursor: pointer;
    font-size: 0.8rem;
    line-height: 1.25;
}
.opening-item:hover {
    background: rgba(255, 255, 255, 0.08);
}
.opening-item.active {
    background: #f1c40f;
    color: #2c3e50;
}
.opening-item__eco {
    color: #f1c40f;
    font-weight: 700;
    margin-right: 0.4em;
}
/* "None" has no code. */
.opening-item__eco:empty {
    display: none;
}
.opening-item.active .opening-item__eco {
    color: inherit;
}
.opening-item__moves {
    display: block;
    color: #9aa5ab;
    font-size: 0.72rem;
}
.opening-item.active .opening-item__moves {
    color: inherit;
}
/* The book builder works from the setup board: a setup-mode button. */
body:not(.setup-mode) #btn-book {
    display: none;
}
/* (The move list's Eval column is not hidden here: the list is out of sight
   in setup anyway, and must keep its width there - fitMoveList measures it
   to decide whether the list fits, and so how big the board is.) */
body:not(.learning-mode) #btn-accept,
body:not(.learning-mode) #btn-analysis {
    display: none;
}

/* ---- HUD over the board ----
   board.js (alignHud) sets the HUD's side padding to the space either side
   of the board, so the HUD spans exactly the board's width. Three columns:
   the mode at the board's left edge, the players and clocks in the middle
   one - centred over the board, since the two outer columns share the rest
   equally - and an empty third column to balance the first. The status
   (thinking dots, verdicts) has its own line underneath, also centred, so
   it never moves the line above. */
.hud {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    grid-template-rows: auto auto;
    align-content: center;
    /* Gaps in em, so they shrink with the text. */
    column-gap: 0.8em;
    row-gap: 0.15em;
    padding-left: var(--hud-board-left, var(--arcade-btn-col));
    padding-right: var(--hud-board-right, var(--arcade-right));
    /* Sized from the board's width (the HUD has no more room than that),
       so the mode, players and clocks fit on one line. */
    font-size: clamp(0.5rem, var(--hud-board-width, 40rem) * 0.03, 1.4rem);
}
#mode-label {
    grid-area: 1 / 1;
    justify-self: start;
    color: #7fd6ff;
    text-shadow: 0 0 6px rgba(127, 214, 255, 0.45);
}
/* The two players either side of VS. The outer columns are equal (each as
   wide as the wider player), so VS sits exactly over the middle of the
   board whatever the names and clocks read: White's side ends against it,
   Black's starts from it. */
.hud__main {
    grid-area: 1 / 2;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    white-space: nowrap;
    align-items: center;
    column-gap: 0.8em;
}
.hud__side {
    display: flex;
    align-items: center;
    gap: 0.5em;
}
.hud__side--white {
    justify-self: end;
}
.hud__side--black {
    justify-self: start;
}
/* A king in place of the words WHITE and BLACK, on a tile of the board's
   dark-square colour so the black one shows against the black HUD. */
.hud__king {
    width: 1.35em;
    height: 1.35em;
    padding: 0.08em;
    box-sizing: border-box;
    background: #b98a62;
    border-radius: 0.2em;
    flex: 0 0 auto;
}
.hud > .hud-status {
    grid-area: 2 / 2;
    justify-self: center;
}

/* ---- HUD status slot ("THINKING...", learning-mode verdicts) ----
   The hidden sizer holds the longest text the slot ever shows and the live
   text sits in the same grid cell, so the slot keeps one width whether it is
   empty or not and the rest of the HUD never shifts. */
.hud-status {
    display: inline-grid;
}
.hud-status > span {
    grid-area: 1 / 1;
    margin-left: 0;
    text-align: center;
}
.hud-status__sizer {
    visibility: hidden;
}
.hud-status > span.is-r1 { color: #f1c40f; }
.hud-status > span.is-r2 { color: #cfd6da; }
.hud-status > span.is-r3 { color: #cd7f32; }
.hud-status > span.is-bad { color: #ff5c66; }

/* Learning-mode verdict on the square the player moved to: gold / silver /
   bronze for the engine's first, second and third choice (same colours as
   the Analysis arrows), flashing red for a move that is taken back. */
.board__hints .coach-flash--r1 { fill: rgba(241, 196, 15, 0.55); }
.board__hints .coach-flash--r2 { fill: rgba(189, 195, 199, 0.6); }
.board__hints .coach-flash--r3 { fill: rgba(205, 127, 50, 0.55); }
.board__hints .coach-flash--bad {
    fill: rgba(231, 76, 60, 0.8);
    animation: coach-flash-bad 0.3s ease-in-out 3;
}
/* A move forced through with thumbs-up: steady red among the ranked moves. */
.board__hints .coach-flash--override { fill: rgba(231, 76, 60, 0.75); }
/* Rating inset in the corner of each highlighted square. */
.board__hints .coach-label {
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
    font-weight: 700;
    fill: #fff;
    stroke: rgba(0, 0, 0, 0.85);
    stroke-width: 0.045;
    paint-order: stroke;
}
@keyframes coach-flash-bad {
    50% { opacity: 0.25; }
}

/* Game-local "selected/toggled" state (current colour, analysis on) -
   additive modifier on top of the shared .arcade-btn, not a redefinition. */
.arcade-actions .arcade-btn.active {
    background: rgba(255, 255, 255, 0.15);
    border-color: #f1c40f;
}

/* ---- Clocks: plain HUD-item content, unshaded - which one is ticking (not
   any colour-coding) is what shows whose move it is. ---- */
.board-timer {
    display: inline-flex;
    justify-content: center;
    align-items: center;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

/* ---- Start / pause / game-over overlay ----
   Not part of the shared arcade-shell.css (each game supplies its own base
   look); adapted from Battlefield's own site.css but re-themed for
   chess-trainer's pale page instead of Battlefield's black background.
   Needs an explicit z-index here (Battlefield's own .overlay doesn't,
   because Battlefield's board is one flat <canvas> with no z-index of its
   own) - chess-trainer's board pieces/hints/drag layer use explicit
   z-index: 2/6/10/20 for their own internal stacking, which would otherwise
   paint above this overlay (z-index: auto always loses to a positioned
   sibling's explicit z-index, regardless of DOM order) and silently eat
   clicks meant for the Start button. */
.overlay {
    position: absolute;
    inset: 0;
    z-index: 40;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.5rem;
    background: rgba(0, 0, 0, 0.75);
    text-align: center;
    padding: 1rem;
    box-sizing: border-box;
}
.overlay.hidden {
    display: none;
}
.overlay__title {
    color: #fff;
    text-shadow: 0 0 12px rgba(241, 196, 15, 0.5);
}
.overlay__hint {
    max-width: 32rem;
    font-size: 1.1rem;
    line-height: 1.6;
    color: #dfe4e6;
}

/* ---- Centred VICTORY / YOU LOSE / DRAW banner, shown over the board the
   moment the game ends and before the shell's standard GAME OVER overlay
   takes over - a sibling of .overlay, earlier in the markup, so .overlay
   always stacks on top of it once both are visible (same pattern as
   Battlefield's .result-banner). Needs to beat the board's own z-index too
   (see .overlay's comment above), but stay below .overlay's 40. ---- */
.result-banner {
    position: absolute;
    inset: 0;
    z-index: 30;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}
.result-banner.hidden {
    display: none;
}
.result-banner__text {
    font-size: clamp(2.2rem, 10vw, 4.5rem);
    letter-spacing: 0.25em;
    text-align: center;
    padding: 0 1rem;
    color: #2c3e50;
    text-shadow: 0 0 2px rgba(255, 255, 255, 0.9), 0 0 18px rgba(255, 255, 255, 0.8);
}
.result-banner__text.win {
    color: #1e8449;
}
.result-banner__text.lose {
    color: #c0392b;
}
.result-banner__text.draw {
    color: #7f8c8d;
}

.btn {
    background: transparent;
    color: #f1c40f;
    border: 2px solid #f1c40f;
    border-radius: 0;
    padding: 0.5rem 1.5rem;
    font-family: inherit;
    font-size: 1.1rem;
    letter-spacing: 0.15em;
    cursor: pointer;
}
.btn:hover {
    background: rgba(241, 196, 15, 0.15);
}
#btn-start {
    min-width: 10rem;
    text-transform: uppercase;
}
