/* The board frame (spades/board/BoardFrame.tsx, docs/board-layout-plan.md): a felt table as large as the window allows,
   square or wider on a wide window, with the panel beside it (below it on phones, with a sticky bar). Everything on
   the table scales from the table's own shorter side: card sizes are container units of .ac-stage (--u), and the custom properties lesson.css, card-design.css
   and animations.css work out from --card-width are declared again here, on the elements that set a size, so nothing
   depends on the window's size the way the old board's media queries did. Every board page is in the frame (phases
   1–4); the later sections add what the other boards put on the felt and in their panels. */

/* ---------------------------------------------------------------------------------------------------------------
   Frame
   --------------------------------------------------------------------------------------------------------------- */

main:has(> .ac-board) {
    background-color: var(--ac-bg) !important;
}

/* --nav-h is the navbar's height with its rule, nothing but the rule once it's folded away (small screens).
   --bar-h is the phone's sticky bar, the step controls; --room the screen's height left for the table above it. */
.ac-board {
    /* The felt: our green with a brighter glow in the middle, as on Trickster's tables (owner, 2026-10-07) */
    --ac-felt-wash: radial-gradient(ellipse 72% 66% at 50% 44%, #378c62 0%, #2b7553 24%, var(--ac-felt) 56%, var(--ac-felt-deep) 100%);
    --nav-h: 65px;
    --bar-h: calc(4.25rem + env(safe-area-inset-bottom));
    --room: calc(100dvh - var(--nav-h) - var(--bar-h) - 0.75rem);
    position: relative;
    display: grid;
    gap: 1rem;
    width: 100%;
    max-width: 100% !important;
    padding: 0.75rem 0.75rem 0 !important;
    min-height: calc(100dvh - var(--nav-h)) !important;
}

body:has(#site-nav.vertically-collapsed) .ac-board {
    --nav-h: 1px;
}

@media (min-width: 900px) and (min-height: 500.02px), (min-width: 900px) and (orientation: portrait) {
    /* --side is the table's height: the window's below the navbar, or less when the width is short (a square then).
       The panel is 20-25rem wide, or 40% of --side on high resolutions, its contents then growing with it: it is
       zoomed by its width over 25rem (tan(atan2(a, b)) is a / b as a plain number). The table takes all the width left
       beside the panel, up to 2.25 times its height: on a wide window the board, not the panel, uses the room (owner,
       2026-10-07). Worked out from the window (100vw) rather than the frame, as zoom and the table's height can't take
       the frame's percentages; the two agree, as the page doesn't scroll. */
    .ac-board {
        --side: min(calc(100dvh - var(--nav-h) - 2rem), calc((100vw - 3.75rem) / 1.4), calc(100vw - 23.75rem));
        --panel: max(clamp(20rem, 27vw, 25rem), calc(var(--side) * 0.4));
        grid-template-columns: min(calc(100% - var(--panel) - 1.25rem), calc(var(--side) * 2.25)) var(--panel);
        justify-content: center;
        gap: 1.25rem;
        height: calc(100dvh - var(--nav-h));
        min-height: 34rem !important;
        padding: 1rem 1.25rem !important;
    }
}

/* Out of the grid: as a block it made a second row, and its gap left the panel shorter than the table */
.ac-board > #card-preloader-container {
    position: absolute;
}

.ac-board-table {
    display: grid;
    place-items: center;
    min-width: 0;
    min-height: 0;
}


.ac-stage {
    position: relative;
    overflow: hidden;
    border-radius: 28px;
    background: var(--ac-felt-wash);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.06), inset 0 -1.5rem 3rem rgba(0, 0, 0, 0.3);
    container-type: size;
    color: #fff;
    font-family: var(--ac-font);
    font-variant-numeric: tabular-nums;
}

@media (min-width: 900px) and (min-height: 500.02px), (min-width: 900px) and (orientation: portrait) {
    /* A width-limited table lines up with the panel's top */
    .ac-board-table {
        align-content: start;
        align-items: start;
    }

    /* As wide as its column, --side tall: square when the width is short, wider on a wide window */
    .ac-stage {
        width: 100%;
        height: var(--side);
    }

    /* The navbar spans the window on a board page, its logo over the table's left edge */
    body:has(.ac-board) #site-nav > nav {
        max-width: none;
        padding-inline: 1.25rem;
    }
}

/* Small screens: the felt runs edge to edge (as Trickster's does), as wide as the screen and a little taller than it's
   wide (4:5) on a phone held upright; held sideways, as tall as the room above the bar and still the screen's width
   (owner, 2026-10-07) */
@media (max-width: 899.98px), (orientation: landscape) and (max-height: 500px) {
    .ac-board-table {
        margin: -0.75rem -0.75rem 0;
    }

    .ac-stage {
        width: 100%;
        height: auto;
        max-height: var(--room);
        aspect-ratio: 4 / 5;
        border-radius: 0;
    }
}

/* Small screens: the tab that unfolds the navbar (BoardFrame), hanging in the frame's top-left corner like the older
   boards' nav tab. The speaker tab (SoundToggle, on every board with cards: sound on or off) is the same tab, in the
   felt's top-left corner; the Replay Maker, which is silent, has its Rotate tab there instead (phase 11), the same
   tab again. Replay Analysis' Back during a playout is one more, after the speaker tab (below). */
.ac-nav-tab,
.ac-sound-tab,
.ac-rotate-tab,
.ac-playout-chip {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 35;
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.5rem;
    padding: 0;
    border: 1px solid var(--ac-line);
    border-top: 0;
    border-left: 0;
    border-radius: 0 0 12px 0;
    background-color: var(--ac-bar);
    color: var(--ac-text);
    box-shadow: 0 0.5rem 1.25rem rgba(0, 0, 0, 0.3);
    cursor: pointer;
    transition: background-color 0.15s;
}

    .ac-nav-tab:hover,
    .ac-sound-tab:hover,
    .ac-rotate-tab:not(:disabled):hover,
    .ac-playout-chip:hover {
        border-color: var(--ac-line-strong);
        background-color: var(--ac-raised);
    }

    .ac-nav-tab:focus-visible,
    .ac-sound-tab:focus-visible,
    .ac-rotate-tab:focus-visible,
    .ac-playout-chip:focus-visible {
        outline: 3px solid var(--ac-go);
        outline-offset: -3px;
    }

    .ac-nav-tab svg,
    .ac-sound-tab svg,
    .ac-rotate-tab svg {
        width: 1.25rem;
        height: 1.25rem;
    }

/* The speaker tab's corner rounded as the felt's (so its focus ring isn't cut off there), over the deal shown after
   trick 13 (40) and under the boxes on the felt (60); a step quieter while sound is off. The maker's Rotate tab the
   same, under the deal editor's sheet (100), and quieter while the hand is created (under the spinner then) */
.ac-sound-tab,
.ac-rotate-tab {
    z-index: 45;
    border-radius: 28px 0 12px 0;
}

    .ac-sound-tab[aria-pressed="false"]:not(:hover),
    .ac-rotate-tab:disabled {
        color: var(--ac-text-2);
    }

    .ac-rotate-tab:disabled {
        cursor: default;
    }

/* While the navbar's tab shows (BoardFrame's SMALL_SCREEN), the speaker tab hangs from the felt's top edge beside it.
   The felt starts at the frame's corner there, except on a window 900px or wider and 500-600px tall, where the frame
   keeps its 1rem by 1.25rem padding round the felt and the navbar's tab reaches 1.5rem into it. Neither tab covers
   North's index or the score: the table keeps the corners for them (the lessons below, the phone layouts at the end). */
@media (max-width: 899.98px), (max-height: 599.98px) {
    .ac-sound-tab,
    .ac-rotate-tab {
        left: calc(2.75rem + 0.375rem);
        border-left: 1px solid var(--ac-line);
        border-radius: 0 0 12px 12px;
    }
}

@media (min-width: 900px) and (min-height: 500.02px) and (max-height: 599.98px) {
    .ac-sound-tab,
    .ac-rotate-tab {
        left: calc(2.75rem - 1.25rem + 0.375rem);
    }
}

/* Replay Analysis' Back to the position while a line plays out, and once it's over (continuation-playout plan A38, owner,
   2026-10-28): "↩ Back" as one more tab of the corner's, after the speaker tab (the same height, 0.375rem after it),
   wide enough for its word; over the deal (40) and the trick, under the boxes (60). It reaches over the edge of North's
   fan as the tabs do, never the trick in the middle. */
.ac-playout-chip {
    left: calc(2.75rem + 0.375rem);
    z-index: 45;
    display: flex;
    align-items: center;
    gap: 0.375rem;
    width: auto;
    padding: 0 0.875rem 0 0.6875rem;
    border-left: 1px solid var(--ac-line);
    border-radius: 0 0 12px 12px;
    font-family: var(--ac-font);
    font-size: 0.9375rem;
    font-weight: 700;
    line-height: 1;
    white-space: nowrap;
}

    .ac-playout-chip svg {
        flex: none;
        width: 1.125rem;
        height: 1.125rem;
    }

@media (max-width: 899.98px), (max-height: 599.98px) {
    .ac-playout-chip {
        left: calc(2 * (2.75rem + 0.375rem));
    }
}

@media (min-width: 900px) and (min-height: 500.02px) and (max-height: 599.98px) {
    .ac-playout-chip {
        left: calc(2.75rem - 1.25rem + 0.375rem + 2.75rem + 0.375rem);
    }
}

/* A folded navbar's links aren't reached with Tab */
#site-nav.vertically-collapsed {
    visibility: hidden;
    transition: all 0.5s ease-in-out, visibility 0s 0.5s;
}

/* ---------------------------------------------------------------------------------------------------------------
   The table, laid out like Trickster's (owner's screenshots, 2026-10-07): every hand fanned in an arc and cropped by
   its edge of the table, so the felt goes to the cards: your hand along the bottom, North's, West's and East's backs at
   the other edges, the trick clustered and a little untidy in the middle, the names quiet labels ("Name • 3/4") and
   yours a pill. A phone-sized table lays the hands flat instead (at the end of this file). Everything sizes from the
   table itself (container units): --u is 1% of its height, or 1.25% of its width when that's less (a tall table).
   --------------------------------------------------------------------------------------------------------------- */

/* The sizes are declared again on the stage's children, so a --u set there is the one they work from */
.ac-stage {
    --u: min(1cqh, 1.25cqw);
}

/* Every hand is close to the same size (owner, 2026-10-07: the felt was left empty round small backs and a small
   trick): four card widths, and the rest worked out from them. Top to bottom the table holds North's cards (as much
   as shows, --north-show), North's name, the trick, your name pill, the room your raised card and its badge need
   (--south-lift) and your cards (--south-show); the trick takes the room between the two names, centred in it, up to a
   little larger than your cards. West and East sit at the sides (--side-show of each card on the felt). The shapes of
   table below change these: a squarish one brings North down below the score; a phone-sized one lays the hands flat. */
.ac-stage,
.ac-stage > * {
    --card-width: calc(10 * var(--u));
    --name-font-size: clamp(13px, calc(2.9 * var(--u)), 30px);
    /* The corner index: the rank's and the suit's size, as fractions of the card's width */
    --rank: 0.28;
    --suit: 0.19;
    /* A fan: how much more each card is turned than the one before it, and how much of itself each shows */
    --fan-turn: 3.2deg;
    --fan-step: 0.32;
    /* The score in the top right corner: its type, about how wide it is, and how far down the table it reaches */
    --score-font: clamp(12px, calc(2.4 * var(--u)), 22px);
    --score-w: calc(9.5 * var(--score-font));
    --corner-h: calc(3 * var(--score-font) + 4.5 * var(--u) + 2px);
    /* Card widths: yours as wide as the table's width allows (a fan of 13 is about 5.4 cards wide), the others' a
       little smaller, never larger than yours, and North's fan (about 4.6 cards wide) clear of West's and East's */
    --south-w: min(calc(18 * var(--u)), calc((100cqw - 6 * var(--u)) / 5.4));
    --side-w: min(calc(16 * var(--u)), var(--south-w));
    --north-w: min(calc(16 * var(--u)), var(--south-w), calc((100cqw - 1.6 * var(--side-w) - 2 * var(--u)) / 4.6));
    /* How much of each hand shows: a little over half of North's cards (their corner index), a little over half of
       West's and East's, about two thirds of yours. When North's fan would reach under the score (a squarish or tall
       table), North's cards come down until their corner index is below it (owner): the clamp's middle term is a step,
       the fan's overlap with the score times 1000. */
    --north-show: clamp(calc(0.78 * var(--north-w)), calc(0.78 * var(--north-w) + (2.25 * var(--north-w) + var(--score-w) + 2 * var(--u) - 50cqw) * 1000), calc(var(--corner-h) + 0.62 * var(--north-w)));
    --side-show: 0.58;
    --south-show: calc(0.98 * var(--south-w));
    /* Between a hand and its name (the Hand Solver's counts stand out from the cards: more there, below) */
    --north-gap: calc(0.08 * var(--north-w));
    --side-gap: calc(0.08 * var(--side-w));
    /* Your raised card (a fifth of its height) and its badge, then your pill */
    --south-lift: calc(0.28 * var(--south-w) + min(19px, 0.15 * var(--south-w)));
    --pill-h: calc(1.5 * var(--name-font-size) + 2px);
    /* The room for the trick: from North's name down to your pill */
    --north-bottom: calc(var(--north-show) + var(--north-gap) + 1.3 * var(--name-font-size));
    --south-top: calc(100cqh - var(--south-show) - var(--south-lift) - var(--pill-h));
    --trick-y: calc((var(--north-bottom) + var(--south-top)) / 2);
    /* The trick: how far North's and South's cards sit from its middle (--trick-v) and West's and East's (--trick-h),
       in card widths; its cards up to --trick-cap times yours, else as large as the room allows (the cluster is about
       1.6 + 2 * --trick-v cards tall with the tilts and your badge) */
    --trick-v: 0.5;
    --trick-h: 0.7;
    --trick-cap: 1.12;
    --trick-pad: calc(2 * var(--u));
    --trick-w: min(calc(var(--trick-cap) * var(--south-w)), calc((var(--south-top) - var(--north-bottom) - var(--trick-pad)) / (1.6 + 2 * var(--trick-v))));
    /* West and East: level with the trick, and low enough that East's fan clears the score */
    --side-y: max(var(--trick-y), calc(var(--corner-h) + 2.15 * var(--side-w)));
    /* The Hand Solver's count badges: their smallest size on North's and your cards, and on West's and East's
       (larger on a phone-sized table, below); and how many nil chips stack beyond them (set below when shown) */
    --ns-bubble-min: 18px;
    --we-bubble-min: 18px;
    --nil-rows: 0;
    /* The nil chips on the hand to play (only its cards carry counts): that seat's name moves out past them, into its
       own place in the trick, which is empty until it plays, so the trick keeps its size */
    --north-chips: 0;
    --west-chips: 0;
    --east-chips: 0;
    --south-chips: 0;
    --north-chip-room: calc(var(--north-chips) * (clamp(17px, 0.26 * var(--north-w), 30px) + 2px));
    --west-chip-room: calc(var(--west-chips) * (clamp(17px, 0.26 * var(--side-w), 30px) + 2px));
    --east-chip-room: calc(var(--east-chips) * (clamp(17px, 0.26 * var(--side-w), 30px) + 2px));
    --south-chip-room: calc(var(--south-chips) * (clamp(17px, 0.26 * var(--south-w), 30px) + 2px));
    /* The Hand Solver's raised replay card in North's, West's or East's hand (set below where it's raised): that seat's
       name moves out past it as well, the same way */
    --north-rise-room: 0px;
    --west-rise-room: 0px;
    --east-rise-room: 0px;
}

    .ac-stage #south-hand { --card-width: var(--south-w); }

    .ac-stage #north-hand {
        --card-width: var(--north-w);
        --fan-turn: 3deg;
        --fan-step: 0.26;
    }

    .ac-stage #west-hand,
    .ac-stage #east-hand {
        --card-width: var(--side-w);
        --fan-turn: 3deg;
        --fan-step: 0.26;
    }

    .ac-stage #tricks { --card-width: var(--trick-w); }

/* The Hand Solver's counts stand just beyond the cards' edge, towards the middle (and its playable cards rise under the
   pointer): the names, and your pill above your risen card, stand clear of them. The badge sizes are those below
   (.number-bubble), worked out for each hand. Nil chips stack beyond the counts (the chip rooms above). The replay's
   next card stands raised by --replay-rise of a card's width (with the solver's other card rules, below): your pill
   keeps room for it, so it stays put; the others' names move out past it (the rise rooms above). */
.ac-board-solver .ac-stage > * {
    --north-gap: calc(0.98 * clamp(var(--ns-bubble-min), 0.3 * var(--north-w), 38px) + 0.04 * var(--north-w));
    --side-gap: calc(0.98 * clamp(var(--we-bubble-min), 0.3 * var(--side-w), 38px) + 0.04 * var(--side-w));
    --south-lift: calc(var(--replay-rise) * var(--south-w) + 0.98 * clamp(var(--ns-bubble-min), 0.3 * var(--south-w), 44px) + 4px);
    --replay-rise: 0.25;
}

/* Your cards rise 15% of their height (0.21 of their width) under the pointer (lesson.css): room for the higher rise */
@media (hover: hover) and (pointer: fine) {
    .ac-board-solver .ac-stage > * {
        --south-lift: calc(max(0.21, var(--replay-rise)) * var(--south-w) + 0.98 * clamp(var(--ns-bubble-min), 0.3 * var(--south-w), 44px) + 4px);
    }
}

/* One nil chip under each count, or two when two players bid nil (the nil solver handles two at most): on the table
   at all (--nil-rows, for the room an upright phone leaves under North's cards), and on each seat's hand */
.ac-stage:has(.nil-chip) > * { --nil-rows: 1; }
.ac-stage:has(.nil-chip + .nil-chip) > * { --nil-rows: 2; }
.ac-stage:has(#north-hand .nil-chip) > * { --north-chips: 1; }
.ac-stage:has(#north-hand .nil-chip + .nil-chip) > * { --north-chips: 2; }
.ac-stage:has(#west-hand .nil-chip) > * { --west-chips: 1; }
.ac-stage:has(#west-hand .nil-chip + .nil-chip) > * { --west-chips: 2; }
.ac-stage:has(#east-hand .nil-chip) > * { --east-chips: 1; }
.ac-stage:has(#east-hand .nil-chip + .nil-chip) > * { --east-chips: 2; }
.ac-stage:has(#south-hand .nil-chip) > * { --south-chips: 1; }
.ac-stage:has(#south-hand .nil-chip + .nil-chip) > * { --south-chips: 2; }

/* Duplicate's score carries the hand's number above it */
.ac-stage:has(.ac-scoreboard-caption) > * {
    --corner-h: calc(3.975 * var(--score-font) + 5 * var(--u) + 2px);
}

/* The lessons have no score: their top corners are free, but for the speaker tab, and the navbar's tab beside it on
   small screens (both 2.75rem by 2.5rem, 0.375rem apart). The calculators have neither score nor speaker. North's fan
   is centred, so keeping it clear of the score keeps it clear of the tabs too. */
.ac-stage:not(:has(.ac-scoreboard)) > * {
    --corner-h: 0px;
    --score-w: 0px;
}

.ac-stage:not(:has(.ac-scoreboard)):has(.ac-sound-tab) > * {
    --corner-h: 44px;
    --score-w: 48px;
}

@media (max-width: 899.98px), (max-height: 599.98px) {
    .ac-stage:not(:has(.ac-scoreboard)) > * {
        --corner-h: 44px;
        --score-w: 48px;
    }

    .ac-stage:not(:has(.ac-scoreboard)):has(.ac-sound-tab) > * {
        --score-w: 98px;
    }
}

    /* Worked out again from each element's own --card-width (see card-design.css for why) */
    .ac-stage,
    .ac-stage > *,
    .ac-stage :is(#north-hand, #south-hand, #west-hand, #east-hand, #tricks) {
        --pip-size: calc(var(--card-width) / 5);
        --card-font-size: calc(var(--card-width) * var(--rank));
        --suit-pip-font-size: calc(var(--card-width) * var(--suit));
        --ace-pip-size: calc(var(--pip-size) * 1.6);
        --card-height: calc(var(--card-width) * 1.4);
        --card-border-radius: calc(var(--card-width) / 14);
        --back-border-width: calc(var(--card-width) / 18);
        --card-spacing-horizontal: calc(var(--card-width) * (var(--fan-step) - 1));
        --card-spacing-vertical: calc(var(--card-width) * (var(--fan-step) - 1.4));
        /* How far a card sinks for its distance from the middle of the fan (squared), so the hand follows an arc */
        --fan-drop: calc(var(--card-width) * var(--fan-step) * sin(var(--fan-turn)) / 2);
        --card-trick-bottom-spacing: calc(var(--card-width) * var(--trick-v));
        --card-trick-top-spacing: calc(var(--card-trick-bottom-spacing) * -1);
        --card-trick-right-spacing: calc(var(--card-width) * var(--trick-h));
        --card-trick-left-spacing: calc(var(--card-trick-right-spacing) * -1);
        --left-to-right: calc(var(--card-width) * 3.7);
        --right-to-left: calc(var(--left-to-right) * -1);
        --center-to-right: calc(var(--card-width) * 2.9);
        --center-to-left: calc(var(--center-to-right) * -1);
        --right-to-right: calc(var(--card-width) * 2.1);
        --left-to-left: calc(var(--right-to-right) * -1);
        --top-to-bottom: calc(var(--card-width) * 4.2);
        --bottom-to-top: calc(var(--top-to-bottom) * -0.68);
        --center-to-bottom: calc(var(--card-width) * 2.5);
        --center-to-top: calc(var(--center-to-bottom) * -0.8);
        --top-to-center: calc(var(--card-width) * 1.8);
        --bottom-to-center: calc(var(--top-to-center) * -0.9);
        --bottom-to-bottom: calc(var(--card-width) * 0.7);
        --top-to-top: calc(var(--bottom-to-bottom) * -1);
        --left-to-center: calc(var(--card-width) * 0.8);
        --right-to-center: calc(var(--left-to-center) * -1);
        --card-play-distance: calc(var(--card-width) * 1);
        --card-play-right: calc(var(--card-play-distance) * -1);
        --card-play-down: calc(var(--card-play-distance) * -1);
        --card-play-left: var(--card-play-distance);
        --card-play-up: var(--card-play-distance);
    }

    /* The fans. Each card knows its place in the hand (--i, from 0) and how many cards are left (--n), from
       SpadesBoard: it's turned for its distance from the middle and sinks by that distance squared. North's hand and
       East's are turned round whole (lesson.css), so the same rules fan them towards the middle of the table too. */
    .ac-stage :is(#north-hand, #south-hand, #west-hand, #east-hand) > .card-container {
        --k: calc(var(--i, 0) - (var(--n, 1) - 1) / 2);
        rotate: calc(var(--k) * var(--fan-turn));
    }

    .ac-stage :is(#north-hand, #south-hand) > .card-container {
        translate: 0 calc(var(--k) * var(--k) * var(--fan-drop));
    }

    /* West's and East's cards lie on their sides (lesson.css turns each a quarter), so theirs sink sideways */
    .ac-stage :is(#west-hand, #east-hand) > .card-container {
        translate: calc(var(--k) * var(--k) * var(--fan-drop) * -1) 0;
    }

    /* A hand closes up as its cards are played */
    @media (prefers-reduced-motion: no-preference) {
        .ac-stage :is(#north-hand, #south-hand, #west-hand, #east-hand) > .card-container {
            transition: rotate 0.35s var(--ac-ease-out), translate 0.35s var(--ac-ease-out), transform 0.35s var(--ac-ease-out);
        }
    }

    /* Seats at the table's edges, each hand cropped by its edge as much as the sizes above say. West's and East's cards
       lie on their sides (lesson.css turns each a quarter), so each shows from 1.2 card widths into its hand's box. */
    .ac-stage #south-container {
        bottom: calc(var(--south-show) - 1.4 * var(--south-w));
        left: 50%;
        transform: translateX(-50%);
    }

    .ac-stage #north-container {
        top: calc(var(--north-show) - 1.4 * var(--north-w));
        left: 50%;
        transform: translateX(-50%);
    }

    .ac-stage #west-container {
        top: var(--side-y);
        left: calc((1.4 * var(--side-show) - 1.2) * var(--side-w));
        right: auto;
        transform: translateY(-50%);
    }

    .ac-stage #east-container {
        top: var(--side-y);
        right: calc((1.4 * var(--side-show) - 1.2) * var(--side-w));
        left: auto;
        transform: translateY(-50%);
    }

    .ac-stage #tricks {
        top: var(--trick-y);
    }

    /* lesson.css draws a small window's trick closer together; the frame's trick is sized from the table */
    .ac-stage #west-trick-container { left: var(--card-trick-left-spacing); }
    .ac-stage #east-trick-container { left: var(--card-trick-right-spacing); }
    .ac-stage #north-trick-container { top: var(--card-trick-top-spacing); }
    .ac-stage #south-trick-container { top: var(--card-trick-bottom-spacing); }

    /* Names: quiet white labels by each hand, "Name • 3/4" */
    .ac-stage :is(#north-name, #east-name, #south-name, #west-name) {
        font-size: var(--name-font-size);
        line-height: 1.3;
    }

    .ac-stage #north-name {
        top: 100%;
        bottom: auto;
        margin-top: calc(var(--north-gap) + var(--north-chip-room) + var(--north-rise-room));
        transform: translateX(-50%);
    }

    /* Turned with their hands, just inside the part of each hand that shows (the name's middle, from the hand's box) */
    .ac-stage #west-name {
        left: calc(1.2 * var(--side-w) + var(--side-gap) + var(--west-chip-room) + var(--west-rise-room) + 0.65 * var(--name-font-size));
    }

    .ac-stage #east-name {
        right: calc(1.2 * var(--side-w) + var(--side-gap) + var(--east-chip-room) + var(--east-rise-room) + 0.65 * var(--name-font-size));
    }

    /* Your name a dark pill over the middle of your hand, clear of a raised card and its badge (a fifth of the card's
       height, then about half the badge) */
    .ac-stage #south-name {
        top: auto;
        bottom: calc(100% + var(--south-lift) + var(--south-chip-room));
        left: 50%;
        transform: translateX(-50%);
        padding: 0.1em 0.7em;
        border: 1px solid var(--ac-line-strong);
        border-radius: 999px;
        background-color: rgba(17, 19, 22, 0.78);
        text-shadow: none;
    }

        .ac-stage #south-name.player-with-turn:not(.disconnected-indicator) {
            border-color: transparent;
            background-color: var(--ac-go);
        }

        .ac-stage #south-name.disconnected-indicator {
            border-color: transparent;
            background-color: var(--ac-bad-fill) !important;
        }

    /* The tricks taken / bid after a dot, closed up ("3/4") */
    .ac-stage [id$="-tricks-taken-container"] {
        word-spacing: -0.22em;
    }

        .ac-stage [id$="-tricks-taken-container"]::before {
            content: "•";
            margin: 0 0.45em 0 0.2em;
            opacity: 0.6;
        }

    /* The others' names a step quieter than yours (the turn and disconnected pills keep their own colours) */
    .ac-stage :is(#north-name, #east-name, #west-name):not(.player-with-turn, .disconnected-indicator) {
        color: rgba(255, 255, 255, 0.72);
        font-weight: 500;
    }

        .ac-stage :is(#north-tricks-taken-container, #east-tricks-taken-container, #west-tricks-taken-container) {
            font-weight: 600;
        }

    /* A bot: a drawn computer in place of "(Bot)", before the name as Trickster marks its computer players (the words
       stay for screen readers, and as the icon's title) */
    .ac-stage [id$="-name-text"]:has(> .seat-bot) {
        display: inline-flex;
        flex-direction: row-reverse;
        align-items: baseline;
    }

    .ac-stage .seat-bot {
        display: inline-block;
        width: 0.95em;
        height: 0.95em;
        margin-right: 0.3em;
        overflow: hidden;
        background-color: currentColor;
        text-indent: 2em;
        white-space: nowrap;
        margin-bottom: -0.1em;
        -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4' y='4.5' width='16' height='11.5' rx='1.75'/%3E%3Cpath d='M1.75 19.5h20.5'/%3E%3C/svg%3E") center / contain no-repeat;
        mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4' y='4.5' width='16' height='11.5' rx='1.75'/%3E%3Cpath d='M1.75 19.5h20.5'/%3E%3C/svg%3E") center / contain no-repeat;
    }

    /* During the auction a label is compact (owner, 2026-10-08: the labels crowded the bids): the dealer, the clock
       and the bid alone, the bid a larger figure ("–" until the seat bids); the name stays for screen readers. West's
       and East's stay turned with their hands, so a bid is underlined, as a 6 and a 9 are on cards (owner: West's 6
       read as East's 9); a disconnected seat is its red pill alone (owner). */
    .ac-stage .seat-compact [id$="-name-text"] {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }

    /* The taken count and the slash have no size; the bid has its own */
    .ac-stage .seat-compact [id$="-tricks-taken-container"] {
        font-size: 0;
        word-spacing: normal;
    }

        .ac-stage .seat-compact [id$="-tricks-taken-container"]::before {
            content: none;
        }

    .ac-stage .seat-compact [id$="-tricks-bid"] {
        display: inline-block;
        min-width: 0.6em;
        font-size: calc(1.3 * var(--name-font-size));
        font-weight: 800;
        line-height: 1;
        font-variant-numeric: tabular-nums;
        text-align: center;
        text-decoration: underline;
        text-decoration-thickness: 0.09em;
        text-underline-offset: 0.12em;
        vertical-align: -0.04em;
    }

        .ac-stage .seat-compact:not(.player-with-turn, .disconnected-indicator) [id$="-tricks-bid"] {
            color: #fff;
        }

        /* No bid yet: a quieter dash, not underlined */
        .ac-stage .seat-compact .seat-no-bid {
            text-decoration: none;
        }

        .ac-stage .seat-compact:not(.player-with-turn, .disconnected-indicator) .seat-no-bid {
            opacity: 0.6;
        }

    /* Cards: the corner index larger than the old board's (the rank over a quarter of the card's width tall), rank over
       suit in a column at the edge; the pips and pictures drawn in from the edges to leave it room */
    .ac-stage .playing-card {
        --index-width: calc(max(0.55 * var(--rank), 0.9 * var(--suit)) + 0.02);
        border-color: rgba(0, 0, 0, 0.18);
        box-shadow: 0 calc(0.2 * var(--u)) calc(0.8 * var(--u)) rgba(0, 0, 0, 0.3);
    }

        .ac-stage .playing-card :is(.value, .suit)::before,
        .ac-stage .playing-card :is(.value, .suit)::after {
            width: calc(var(--card-width) * var(--index-width));
            line-height: 1;
            text-align: center;
        }

        .ac-stage .playing-card :is(.value, .suit)::before {
            left: calc(var(--card-width) * 0.03);
            transform: none;
        }

        .ac-stage .playing-card :is(.value, .suit)::after {
            right: calc(var(--card-width) * 0.03);
            transform: rotate(180deg);
        }

        /* card-characters' ranks stand 0.84 of their size tall, 0.1 below the top of a line as tall as the size */
        .ac-stage .playing-card .value::before {
            top: calc(var(--card-width) * 0.035);
        }

        .ac-stage .playing-card .value::after {
            bottom: calc(var(--card-width) * 0.035);
        }

        .ac-stage .playing-card .suit::before {
            top: calc(var(--card-width) * (0.065 + 0.945 * var(--rank) - 0.1 * var(--suit)));
        }

        .ac-stage .playing-card .suit::after {
            bottom: calc(var(--card-width) * (0.065 + 0.945 * var(--rank) - 0.1 * var(--suit)));
        }

        /* --face-w: how much of the pips' width a court card's picture takes */
        .ac-stage .playing-card .pip-container {
            --face-w: 76%;
            width: 74%;
            height: 82%;
        }

        /* Court cards: the picture and its two suit symbols share one box in the picture's own proportions (the
           SVGs' 164 × 264), stacked in the middle of the pips' box, so the symbols sit inside the picture's frame,
           top left and bottom right, and keep to it at every size and shape of card */
        .ac-stage .playing-card:is([data-value="J"], [data-value="Q"], [data-value="K"]) .pip-container {
            display: grid;
            place-items: center;
        }

            .ac-stage .playing-card:is([data-value="J"], [data-value="Q"], [data-value="K"]) .pip-container > * {
                grid-area: 1 / 1;
            }

            .ac-stage .playing-card:is([data-value="J"], [data-value="Q"], [data-value="K"]) .pip-container > :is(.face, .pip:nth-child(-n+2)) {
                position: relative;
                width: var(--face-w);
                height: auto;
                min-height: 0;
                margin: 0;
                aspect-ratio: 164 / 264;
            }

            /* Each symbol 0.32 of the picture's width, as the pictures were drawn for */
            .ac-stage .playing-card:is([data-value="J"], [data-value="Q"], [data-value="K"]) .pip-container > .pip:nth-child(-n+2) {
                container-type: inline-size;
            }

            .ac-stage .playing-card:is([data-value="J"], [data-value="Q"], [data-value="K"]) .pip:nth-child(-n+2)::before {
                font-size: 32cqw;
            }

            .ac-stage .playing-card:is([data-value="J"], [data-value="Q"], [data-value="K"]) .pip:nth-child(1)::before {
                top: 5%;
                left: 15.5%;
            }

            .ac-stage .playing-card:is([data-value="J"], [data-value="Q"], [data-value="K"]) .pip:nth-child(2)::before {
                bottom: 5%;
                right: 15.5%;
            }

    /* The others' fanned backs show only their edges: no logo (a cropped one read as a stray mark at the end of each
       hand), and a thinner white rim, so the slate leads. The deal's deck is the same (its cards are dealt to them). */
    .ac-stage :is(#north-hand, #west-hand, #east-hand, .ac-deal-deck) .playing-card .back {
        --back-border-width: calc(var(--card-width) / 30);
        background-image:
            repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.05) 0 1px, transparent 1px 0.55em),
            repeating-linear-gradient(-45deg, rgba(255, 255, 255, 0.05) 0 1px, transparent 1px 0.55em),
            radial-gradient(circle at 50% 50%, #343943, #22252b);
        background-position: 0 0;
        background-repeat: repeat, repeat, no-repeat;
        background-size: auto, auto, 100% 100%;
    }

    /* The trick lies a little untidily, as cards do on a real table, each seat's card turned its own way. The faces
       turn rather than the card, so the cards still slide straight in and out (animations.css moves them by their
       margins). */
    .ac-stage #tricks .playing-card {
        border: 0;
        box-shadow: none;
    }

        .ac-stage #tricks .playing-card > :is(.front, .back) {
            rotate: var(--tilt, 0deg);
            box-shadow: 0 calc(0.3 * var(--u)) calc(1.2 * var(--u)) rgba(0, 0, 0, 0.32);
        }

        .ac-stage #tricks .playing-card > .front {
            border: 1px solid rgba(0, 0, 0, 0.18);
        }

    .ac-stage #west-trick-container { --tilt: -8deg; }
    .ac-stage #north-trick-container { --tilt: 5deg; }
    .ac-stage #east-trick-container { --tilt: 11deg; }
    .ac-stage #south-trick-container { --tilt: -3deg; }

    /* The deck a new hand is shuffled and dealt from on the game pages (deal-intro.ts), in the middle of the trick:
       each card centred there and upright, its shadow lighter than a trick card's, as ten lie on one another */
    .ac-stage #tricks .ac-deal-deck {
        position: absolute;
        top: 0;
        left: 0;
        pointer-events: none;
    }

        .ac-stage #tricks .ac-deal-deck > .card-container {
            position: absolute;
            top: calc(var(--card-height) / -2);
            left: calc(var(--card-width) / -2);
        }

        .ac-stage #tricks .ac-deal-deck .playing-card > .back {
            box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08), 0 calc(0.1 * var(--u)) calc(0.45 * var(--u)) rgba(0, 0, 0, 0.2);
        }

    /* The grade markers, sized from the card they sit on. A marked card in your hand (the computer's choice) is raised
       whatever its grade, so its badge clears the card on its right and every card's index still shows. */
    .ac-stage #south-hand > :is(.brilliant-move-marker, .good-move-marker, .excellent-move-marker, .neutral-move-marker, .weak-move-marker, .mistake-move-marker, .deceptive-move-marker) {
        transform: translateY(-20%) !important;
    }

    .ac-stage :is(.brilliant-move-marker, .good-move-marker, .excellent-move-marker, .neutral-move-marker, .weak-move-marker, .mistake-move-marker, .deceptive-move-marker)::before {
        --marker: clamp(22px, calc(var(--card-width) * 0.34), 44px);
        top: calc(var(--marker) * -0.42);
        right: calc(var(--marker) * -0.28);
        width: var(--marker);
        height: var(--marker);
        font-family: Verdana, "Segoe UI", system-ui, sans-serif;
        font-size: max(10px, calc(var(--marker) * 0.4));
        font-weight: 700;
        letter-spacing: 0.04em;
        line-height: calc(var(--marker) - 4px);
        cursor: pointer;
    }

    /* Your card in the trick wears its badge on its lower corner, where nothing lies over it and it's clear of East's
       index */
    .ac-stage #tricks :is(.brilliant-move-marker, .good-move-marker, .excellent-move-marker, .neutral-move-marker, .weak-move-marker, .mistake-move-marker, .deceptive-move-marker)::before {
        top: auto;
        bottom: calc(var(--marker) * -0.45);
        right: calc(var(--marker) * -0.45);
    }

    .ac-stage .content-load-spinner-container {
        border-radius: inherit;
        background: rgba(17, 19, 22, 0.55);
    }

/* ---------------------------------------------------------------------------------------------------------------
   The panel
   --------------------------------------------------------------------------------------------------------------- */

/* Positioned, so the screen readers' hidden text inside (position: absolute) stays in the panel's scroll rather than
   making the page taller */
.ac-board-panel {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    min-width: 0;
    padding-bottom: 1rem;
}

@media (min-width: 900px) and (min-height: 500.02px), (min-width: 900px) and (orientation: portrait) {
    .ac-board-panel {
        zoom: max(1, tan(atan2(calc(var(--side) * 0.4), 25rem)));
        min-height: 0;
        overflow-y: auto;
        padding: 0 0.25rem 0.25rem 0;
        scrollbar-width: thin;
        scrollbar-color: #3b4049 transparent;
    }
}

/* Small screens, on the pages where you play a hand yourself (BoardFrame's collapsiblePanel): the panel is a drawer
   over the felt instead of a section below the table, so the table takes the whole room but a slim strip along the
   drawer's edge, its tab (owner, 2026-10-09). Held upright it's a sheet along the bottom; held sideways (a short
   laptop window too) a drawer down the right edge. Open, it covers 80% of the table, its contents scrolling inside
   it, and the table stays playable beside it. BoardFrame adds .ac-board-drawer on small screens only, so these rules
   ask nothing but the screen's shape; they win over the wide screens' grid too, which a window 900px wide and under
   600px tall also gets. Elsewhere the drawer's wrapper lays nothing out. */
.ac-drawer {
    display: contents;
}

.ac-board.ac-board-drawer {
    /* The strip the collapsed drawer leaves, its tab and the room beside it under the home indicator */
    --drawer-tab: 1.75rem;
    --drawer-strip: calc(var(--drawer-tab) + env(safe-area-inset-bottom));
    display: block;
    /* The seated banner ("You're seated at table N") sits above <main> on a practice page, so leave room for it too,
       or the drawer's tab strip falls below the fold; SeatedBanner publishes its height while it shows */
    height: calc(100dvh - var(--nav-h) - var(--seated-banner-h, 0px));
    min-height: 0 !important;
    padding: 0 !important;
    overflow: hidden;
}

    /* Isolated, so the boxes over the felt (z-index 60) stay under the drawer */
    .ac-board-drawer > .ac-board-table {
        display: block;
        width: 100%;
        height: calc(100% - var(--drawer-strip));
        margin: 0;
        isolation: isolate;
    }

        .ac-board-drawer > .ac-board-table > .ac-stage {
            width: 100%;
            height: 100%;
            max-height: none;
            aspect-ratio: auto;
            border-radius: 0;
        }

    /* The sheet: its tab strip over the panel. Collapsed it slides down until only the strip shows, under the table;
       open, it reaches 80% of the way up the table. */
    .ac-board-drawer > .ac-drawer {
        position: absolute;
        inset: auto 0 0;
        z-index: 40;
        display: flex;
        flex-direction: column;
        height: calc(100% - 0.2 * (100% - var(--drawer-strip)));
        /* The strip is the sheet's edge, kept clear of the panel; the folder tab sits on it */
        padding-top: var(--drawer-tab);
        border-top: 1px solid var(--ac-line-strong);
        border-radius: var(--ac-radius) var(--ac-radius) 0 0;
        background-color: var(--ac-bar);
        box-shadow: 0 -0.75rem 1.5rem rgba(0, 0, 0, 0.35);
        transform: translateY(calc(100% - var(--drawer-strip)));
    }

    .ac-board-drawer.ac-board-drawer-open > .ac-drawer {
        transform: none;
    }

    /* The toggle is a file-folder tab, not the whole strip: a whole-width strip in the sheet's dark grey blended into
       the board, so players new to the page missed it (owner, 2026-10-09). A fixed 80px tab, centred on the sheet's
       edge, a bright green arrow and border round its three outer sides, rising --drawer-tab-rise past the edge into
       the board (it may touch the bottom middle of South's cards, under their corner indices). Its inner side has no
       border and the sheet's colour, so it opens into the sheet like a folder's tab; it covers the sheet's top line
       where it sits, so that line meets its green sides. */
    .ac-board-drawer .ac-drawer-tab {
        --drawer-tab-rise: 14px;
        --drawer-tab-lift: 0 -0.25rem 0.625rem -0.125rem rgba(0, 0, 0, 0.5);
        position: absolute;
        top: calc(-1 * (var(--drawer-tab-rise) + 1px));
        left: calc(50% - 40px);
        display: grid;
        place-items: center;
        box-sizing: border-box;
        width: 80px;
        height: calc(var(--drawer-tab-rise) + 1px + var(--drawer-tab));
        padding: 0;
        border: 2px solid var(--ac-go);
        border-bottom: 0;
        border-radius: 12px 12px 0 0;
        background-color: var(--ac-bar);
        /* Lifts the part over the felt off it */
        box-shadow: var(--drawer-tab-lift);
        color: var(--ac-go);
        cursor: pointer;
    }

        .ac-board-drawer .ac-drawer-tab:hover {
            background-color: var(--ac-raised);
            box-shadow: var(--drawer-tab-lift), 0 0 0.75rem color-mix(in srgb, var(--ac-go) 35%, transparent);
        }

        /* Outside the tab, as its border is green already */
        .ac-board-drawer .ac-drawer-tab:focus-visible {
            outline: 3px solid var(--ac-go);
            outline-offset: 2px;
        }

        /* Up, towards the board, while collapsed; down when open */
        .ac-board-drawer .ac-drawer-tab svg {
            width: 1.375rem;
            height: 1.375rem;
            stroke-width: 2.75;
        }

        .ac-board-drawer-open .ac-drawer-tab svg {
            transform: rotate(180deg);
        }

    .ac-board-drawer .ac-drawer > .ac-board-panel {
        flex: 1;
        min-width: 0;
        min-height: 0;
        overflow-y: auto;
        overscroll-behavior: contain;
        zoom: 1;
        padding: 0.25rem 1rem calc(1rem + env(safe-area-inset-bottom));
        scrollbar-width: thin;
        scrollbar-color: #3b4049 transparent;
    }

/* Held sideways: the drawer down the right edge, its tab strip along its left side */
@media (orientation: landscape) {
    .ac-board.ac-board-drawer {
        --drawer-strip: calc(var(--drawer-tab) + env(safe-area-inset-right));
    }

        .ac-board-drawer > .ac-board-table {
            width: calc(100% - var(--drawer-strip));
            height: 100%;
        }

        .ac-board-drawer > .ac-drawer {
            inset: 0 0 0 auto;
            flex-direction: row;
            width: calc(100% - 0.2 * (100% - var(--drawer-strip)));
            height: auto;
            padding: 0 0 0 var(--drawer-tab);
            border-top: 0;
            border-left: 1px solid var(--ac-line-strong);
            border-radius: var(--ac-radius) 0 0 var(--ac-radius);
            box-shadow: -0.75rem 0 1.5rem rgba(0, 0, 0, 0.35);
            transform: translateX(calc(100% - var(--drawer-strip)));
        }

        /* The folder tab turned on its side: 80px tall, centred down the drawer's left edge, rising into the board on
           the left and opening into the drawer on its right */
        .ac-board-drawer .ac-drawer-tab {
            --drawer-tab-lift: -0.25rem 0 0.625rem -0.125rem rgba(0, 0, 0, 0.5);
            top: calc(50% - 40px);
            left: calc(-1 * (var(--drawer-tab-rise) + 1px));
            width: calc(var(--drawer-tab-rise) + 1px + var(--drawer-tab));
            height: 80px;
            border: 2px solid var(--ac-go);
            border-right: 0;
            border-radius: 12px 0 0 12px;
        }

            /* Left, towards the board, while collapsed; right when open */
            .ac-board-drawer .ac-drawer-tab svg {
                transform: rotate(-90deg);
            }

            .ac-board-drawer-open .ac-drawer-tab svg {
                transform: rotate(90deg);
            }

        .ac-board-drawer .ac-drawer > .ac-board-panel {
            padding: 1rem calc(1rem + env(safe-area-inset-right)) calc(1rem + env(safe-area-inset-bottom)) 0.25rem;
        }
}

/* The drawer slides only once the player has moved it (BoardFrame's .ac-board-drawer-moved): becoming a drawer (the page
   loading, the screen shrinking) it's simply collapsed, never seen sliding shut over the felt, nor left part way where
   the page isn't drawn */
@media (prefers-reduced-motion: no-preference) {
    .ac-board-drawer-moved > .ac-drawer,
    .ac-board-drawer .ac-drawer-tab svg {
        transition: transform 0.3s var(--ac-ease-out);
    }

    .ac-board-drawer .ac-drawer-tab {
        transition: background-color 0.15s, box-shadow 0.15s;
    }
}

.ac-panel-head {
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
}

    /* A page's action under its lede (practice's Resign), as wide as its label */
    .ac-panel-head > .ac-btn {
        align-self: flex-start;
    }

.ac-panel-title {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem 0.75rem;
}

    .ac-panel-title h1 {
        font-size: 1.375rem;
        font-weight: 800;
        letter-spacing: -0.02em;
    }

.ac-panel-links {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

    .ac-panel-links .ac-btn {
        min-height: 2.125rem;
        padding: 0.3125rem 0.75rem;
        font-size: 0.875rem;
        box-shadow: 0 3px 0 var(--ac-edge);
    }

/* The grade card: the move just analysed */
.ac-grade-card {
    --grade: var(--ac-line-strong);
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
    padding: 1.125rem 1.25rem;
    border: 1px solid var(--ac-line);
    border-radius: var(--ac-radius);
    background-color: var(--ac-surface);
    box-shadow: inset 0 3px 0 var(--grade);
    scroll-margin: 1rem;
}

.ac-grade-card-brilliant { --grade: var(--ac-g-brilliant); }
.ac-grade-card-excellent { --grade: var(--ac-g-excellent); }
.ac-grade-card-good { --grade: var(--ac-g-good); }
.ac-grade-card-deceptive { --grade: var(--ac-g-deceptive); }
.ac-grade-card-neutral { --grade: var(--ac-g-neutral); }
.ac-grade-card-weak { --grade: var(--ac-g-weak); }
.ac-grade-card-mistake { --grade: var(--ac-g-mistake); }

.ac-grade-head {
    display: flex;
    align-items: center;
    gap: 0.875rem;
}

    .ac-grade-head h2 {
        font-size: 1.375rem;
        font-weight: 800;
        letter-spacing: -0.02em;
        line-height: 1.15;
    }

    .ac-grade-head p {
        margin-top: 0.125rem !important;
        color: var(--ac-text-2);
        font-size: 0.9375rem;
    }

.ac-grade-badge-lg {
    min-width: 3rem;
    height: 3rem;
    font-size: 1.0625rem;
}

.ac-grade-placeholder {
    flex: none;
    width: 2.25rem;
    height: 1.625rem;
    border: 1px dashed var(--ac-line-strong);
    border-radius: 999px;
}

.ac-grade-head .ac-grade-placeholder {
    width: 3rem;
    height: 3rem;
}

.ac-grade-spinner {
    flex: none;
    width: 3rem;
    height: 3rem;
    border: 4px solid rgba(255, 255, 255, 0.14);
    border-top-color: var(--ac-go);
    border-radius: 50%;
    animation: spin 0.9s linear infinite;
}

.ac-grade-cards {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.5rem;
    margin: 0;
}

    .ac-grade-cards > div {
        display: flex;
        flex-direction: column;
        gap: 0.3125rem;
    }

    .ac-grade-cards dt {
        color: var(--ac-text-3);
        font-size: 0.8125rem;
        font-weight: 700;
    }

    .ac-grade-cards dd {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        margin: 0;
    }

.ac-grade-feedback {
    color: var(--ac-text);
    font-size: 1rem;
    line-height: 1.55;
}

    .ac-grade-feedback a {
        color: var(--ac-go);
    }

/* How play might continue (continuation-playout plan A10, A13): the caption, a line of its own, over a card button per
   line, then while one plays out what the board shows, over Stop; the buttons wrap when the panel is narrow (a phone) */
.ac-continuation {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;
    padding-top: 0.875rem;
    border-top: 1px solid var(--ac-line);
}

.ac-continuation-caption {
    flex: 1 1 100%;
    min-width: 0;
    color: var(--ac-text-2);
    font-size: 0.9375rem;
    line-height: 1.45;
    overflow-wrap: break-word;
}

.ac-continuation-cards {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* A green ring inside the raised button's edge, so a new player sees the cards as buttons (owner, 2026-10-28) */
.ac-continuation-card {
    padding-inline: 0.5rem;
    box-shadow: inset 0 0 0 2px var(--ac-go), 0 4px 0 var(--btn-edge);
}

    .ac-continuation-card:active {
        box-shadow: inset 0 0 0 2px var(--ac-go), 0 0 0 var(--btn-edge);
    }

/* While a line plays out: Previous and Next (auto-play off, A33), Stop, then the Auto-play switch at the row's end (the
   profile's switch, its name and On/Off before it), on a line of its own where the panel is narrow */
.ac-continuation-controls {
    flex: 1 1 100%;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.ac-continuation-auto {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0 0 0 auto;
    color: var(--ac-text-2);
    font-size: 0.875rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
}

/* A marker clicked on the table points here */
@media (prefers-reduced-motion: no-preference) {
    .ac-flash {
        animation: ac-flash 0.9s var(--ac-ease-out);
    }
}

@keyframes ac-flash {
    0% { box-shadow: inset 0 3px 0 var(--grade), 0 0 0 3px var(--grade); }
    100% { box-shadow: inset 0 3px 0 var(--grade), 0 0 0 0 transparent; }
}

/* The hand's review */
.ac-review-counts {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
    gap: 0.375rem 0.75rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

    .ac-review-counts li {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        padding: 0.25rem 0;
        font-weight: 600;
    }

        .ac-review-counts li strong {
            margin-left: auto;
            font-size: 1.125rem;
            font-weight: 800;
        }

    .ac-review-counts .ac-review-none {
        color: var(--ac-text-2);
        font-weight: 500;
    }

        .ac-review-counts .ac-review-none strong {
            color: var(--ac-text-3);
        }

/* Step controls: the trick reached, then the steps (first, back, forward, last on Replay Analysis) */
.ac-step-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}

.ac-step-count {
    color: var(--ac-text-2);
    font-weight: 600;
    white-space: nowrap;
}

    .ac-step-count strong {
        color: var(--ac-text);
        font-size: 1.125rem;
        font-weight: 800;
    }

.ac-step-buttons {
    display: flex;
    gap: 0.5rem;
}

.ac-btn-icon-only {
    width: 2.875rem;
    padding: 0;
}

.ac-step-icon {
    width: 1.25rem;
    height: 1.25rem;
}

.ac-btn-icon-only:disabled {
    cursor: default;
    opacity: 0.4;
}

/* Replay Analysis while a line plays out: "↩ Back" in place of the grade and the trick's count (continuation-playout plan
   A38), no taller than the steps, so the bar keeps its height and its one line */
.ac-step-bar > .ac-playout-back {
    flex: none;
    gap: 0.375rem;
    padding-inline: 0.6875rem 0.875rem;
}

    .ac-step-bar > .ac-playout-back svg {
        flex: none;
        width: 1.125rem;
        height: 1.125rem;
    }

/* The phone's sticky bar; the panel's own controls show on wide screens */
.ac-board-bar {
    display: none;
}

@media (max-width: 899.98px), (orientation: landscape) and (max-height: 500px) {
    .ac-board-panel > .ac-step-bar {
        display: none;
    }

    .ac-board-bar {
        position: sticky;
        bottom: 0;
        z-index: 30;
        display: block;
        margin: 0 -0.75rem;
        padding: 0.625rem 0.75rem calc(0.625rem + env(safe-area-inset-bottom));
        border-top: 1px solid var(--ac-line-strong);
        background-color: var(--ac-bar);
        box-shadow: 0 -0.75rem 1.5rem rgba(0, 0, 0, 0.35);
    }

    .ac-step-bar-compact .ac-step-count {
        margin-right: auto;
    }

    /* Four buttons fit a 320px phone */
    .ac-step-bar-compact {
        gap: 0.5rem;
    }

        .ac-step-bar-compact .ac-step-buttons {
            gap: 0.375rem;
        }

        .ac-step-bar-compact .ac-btn-icon-only {
            width: 2.625rem;
            min-height: 2.625rem;
        }

        .ac-step-bar-compact > .ac-playout-back {
            min-height: 2.625rem;
        }
}

/* The hand's tricks */
.ac-panel-h {
    margin-bottom: 0.5rem !important;
    color: var(--ac-text-2) !important;
    font-size: 0.875rem;
    font-weight: 700;
}

/* Replay Analysis' head over its list: "Tricks", and quietly how many are analysed so far */
.ac-trick-list-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.5rem;
}

    .ac-trick-list-head .ac-panel-h {
        margin-bottom: 0 !important;
    }

.ac-trick-progress {
    color: var(--ac-text-3);
    font-size: 0.8125rem;
    font-weight: 600;
    line-height: 1.2;
}

.ac-trick-list ol {
    margin: 0;
    padding: 0;
    border: 1px solid var(--ac-line);
    border-radius: var(--ac-radius);
    background-color: var(--ac-surface);
    list-style: none;
    overflow: hidden;
}

    .ac-trick-list li + li {
        border-top: 1px solid var(--ac-line);
    }

.ac-trick-row {
    display: grid;
    grid-template-columns: 1.75rem minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.625rem;
    width: 100%;
    min-height: 2.75rem;
    padding: 0.4375rem 0.875rem 0.4375rem 0.625rem;
    border: 0;
    background: none;
    color: var(--ac-text);
    font-family: var(--ac-font);
    text-align: left;
    cursor: pointer;
    transition: background-color 0.15s;
}

    .ac-trick-row:hover:not(:disabled) {
        background-color: var(--ac-raised);
    }

    .ac-trick-row:disabled {
        cursor: default;
    }

    .ac-trick-row[aria-current] {
        background-color: rgba(107, 214, 43, 0.1);
    }

    .ac-trick-row:focus-visible {
        outline: 2px solid var(--ac-go);
        outline-offset: -2px;
    }

.ac-trick-row-future {
    color: var(--ac-text-3);
}

.ac-trick-num {
    display: grid;
    place-items: center;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 50%;
    background-color: var(--ac-raised);
    font-size: 0.8125rem;
    font-weight: 700;
}

.ac-trick-row[aria-current] .ac-trick-num {
    background-color: var(--ac-go);
    color: var(--ac-go-ink);
}

.ac-trick-cards {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    min-width: 0;
    font-size: 0.875rem;
}

/* A card written small */
.ac-mini-card {
    display: inline-flex;
    align-items: center;
    gap: 0.0625rem;
    min-width: 2.125rem;
    height: 1.625rem;
    padding: 0 0.3125rem;
    border-radius: 6px;
    background-color: #fff;
    color: var(--ac-bg);
    font-size: 0.875rem;
    font-weight: 800;
    letter-spacing: -0.02em;
    line-height: 1;
}

    .ac-mini-card svg {
        width: 0.875rem;
        height: 0.875rem;
        fill: currentColor;
    }

.ac-mini-card-red {
    color: #d62828;
}

.ac-mini-card-yours {
    box-shadow: 0 0 0 2px var(--ac-go);
}

.ac-mini-card-empty {
    background-color: transparent;
    box-shadow: inset 0 0 0 1px var(--ac-line-strong);
}

/* On demand: remaining cards, legend */
.ac-panel-tabs .ac-tabbar {
    margin-bottom: 1rem;
}

.ac-panel-tabs [role="tabpanel"] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.ac-seg-4 {
    grid-template-columns: repeat(4, 1fr);
    margin: 0;
}

.ac-seg-item[aria-pressed="true"] {
    background-color: var(--ac-raised);
    color: var(--ac-text) !important;
    box-shadow: inset 0 0 0 1px var(--ac-go), 0 2px 0 var(--ac-edge);
}

button.ac-seg-item {
    border: 0;
    background: none;
    font-family: var(--ac-font);
    cursor: pointer;
}

.ac-remaining {
    margin: 0;
    padding: 0.25rem 0;
    list-style: none;
}

    .ac-remaining li {
        display: flex;
        align-items: center;
        gap: 0.75rem;
        padding: 0.375rem 0;
        font-size: 1.0625rem;
        font-weight: 700;
        letter-spacing: 0.06em;
    }

.ac-remaining-suit {
    display: grid;
    place-items: center;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 6px;
    background-color: #fff;
}

    .ac-remaining-suit svg {
        width: 1.125rem;
        height: 1.125rem;
        fill: var(--ac-bg);
    }

.ac-remaining-hearts .ac-remaining-suit svg,
.ac-remaining-diamonds .ac-remaining-suit svg {
    fill: #d62828;
}

.ac-panel-note {
    font-size: 0.875rem;
    line-height: 1.5;
}

.ac-legend {
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

    .ac-legend li {
        display: grid;
        grid-template-columns: 2.5rem minmax(0, 1fr);
        gap: 0.75rem;
        align-items: start;
    }

    .ac-legend strong {
        font-weight: 700;
    }

    .ac-legend p {
        margin-top: 0.125rem !important;
        color: var(--ac-text-2);
        font-size: 0.9375rem;
        line-height: 1.5;
    }

.ac-grade-status {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--ac-line);
    color: var(--ac-text-2);
    font-size: 0.875rem;
    font-weight: 600;
}

.ac-grade-spinner-sm {
    width: 1rem;
    height: 1rem;
    border-width: 2px;
}

/* Wide screens: the controls stay in reach while the tricks scroll */
@media (min-width: 900px) and (min-height: 500.02px), (min-width: 900px) and (orientation: portrait) {
    .ac-board-panel > .ac-step-bar {
        position: sticky;
        top: 0;
        z-index: 2;
        margin: -0.5rem 0;
        padding: 0.5rem 0;
        background-color: var(--ac-bg);
    }
}

/* The review's strip: the hand's 13 cards, each with its grade */
.ac-review-strip {
    display: grid;
    grid-template-columns: repeat(13, minmax(0, 1fr));
    gap: 0.25rem;
    margin: 0;
    padding: 0.75rem 0;
    border-top: 1px solid var(--ac-line);
    border-bottom: 1px solid var(--ac-line);
    list-style: none;
}

    .ac-review-strip li {
        min-width: 0;
    }

    /* Each trick opens from the strip */
    .ac-review-strip button {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 0.25rem;
        width: 100%;
        padding: 0.25rem 0;
        border: 0;
        border-radius: 8px;
        background: none;
        color: inherit;
        font-family: var(--ac-font);
        cursor: pointer;
        transition: background-color 0.15s;
    }

        .ac-review-strip button:hover {
            background-color: var(--ac-raised);
        }

        .ac-review-strip button:focus-visible {
            outline: 2px solid var(--ac-go);
            outline-offset: 0;
        }

    .ac-review-strip .ac-grade-badge {
        min-width: 0;
        width: 100%;
        max-width: 2rem;
        height: 1.375rem;
        padding: 0;
        font-size: 0.6875rem;
    }

.ac-review-dot {
    width: 100%;
    max-width: 2rem;
    height: 1.375rem;
    border: 1px dashed var(--ac-line-strong);
    border-radius: 999px;
}

.ac-review-trick {
    color: var(--ac-text-3);
    font-size: 0.75rem;
    font-weight: 700;
}

/* The panel's tabs share one row */
.ac-panel-tabs .ac-tabbar {
    flex-wrap: nowrap;
    gap: 0;
}

    .ac-panel-tabs .ac-tabbar-item {
        flex: 1;
        padding-inline: 0.375rem;
        white-space: nowrap;
    }

/* ---------------------------------------------------------------------------------------------------------------
   The review's key moments; the deal after trick 13; a wide table
   --------------------------------------------------------------------------------------------------------------- */

/* The page moves focus to its heading for screen readers; the heading isn't a control, so no ring */
.ac-panel-title h1:focus {
    outline: none;
}

/* Four step buttons leave no room for "Trick" on the phone's bar and in a narrow panel: it's left to screen readers
   ("13 of 13") */
.ac-step-bar-compact .ac-step-word {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

@media (min-width: 900px) and (max-width: 1251.98px) {
    .ac-board-panel .ac-step-word {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }
}

/* A step that can't be taken goes slate, not a dimmed green (the end of the hand) */
.ac-step-buttons .ac-btn-go:disabled {
    --btn-bg: var(--ac-raised);
    --btn-hover: var(--ac-raised);
    --btn-edge: var(--ac-edge);
    --btn-ink: var(--ac-text-3);
}

/* The review's key moments: a row per brilliant move, weak move and mistake, each opening its trick */
.ac-moments h3 {
    margin-bottom: 0.375rem !important;
    color: var(--ac-text-2);
    font-size: 0.875rem;
    font-weight: 700;
}

.ac-moments ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

    .ac-moments li + li {
        border-top: 1px solid var(--ac-line);
    }

.ac-moment {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.625rem;
    width: 100%;
    min-height: 2.75rem;
    padding: 0.375rem 0.5rem;
    border: 0;
    border-radius: 8px;
    background: none;
    color: var(--ac-text);
    font-family: var(--ac-font);
    text-align: left;
    cursor: pointer;
    transition: background-color 0.15s;
}

    .ac-moment:hover {
        background-color: var(--ac-raised);
    }

    .ac-moment:focus-visible {
        outline: 2px solid var(--ac-go);
        outline-offset: -2px;
    }

.ac-moment-text {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0 0.5rem;
    min-width: 0;
}

    .ac-moment-text strong {
        font-weight: 700;
    }

    .ac-moment-text span {
        color: var(--ac-text-2);
        font-size: 0.9375rem;
    }

.ac-moment-cards {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    font-size: 0.8125rem;
}

/* After trick 13 the table shows the whole deal: each seat's cards by suit where it sits, on the same felt */
/* It sizes from the table's shorter side: it needs the table's whole height */
.ac-stage > .ac-hand-diagram {
    --u: 1cqmin;
}

.ac-hand-diagram {
    position: absolute;
    inset: 0;
    z-index: 40;
    display: grid;
    grid-template-areas:
        ". north ."
        "west centre east"
        ". south .";
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    grid-template-rows: 1fr auto 1fr;
    gap: calc(3 * var(--u)) calc(2 * var(--u));
    padding: calc(4 * var(--u));
    border-radius: inherit;
    background: var(--ac-felt-wash);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.06), inset 0 -1.5rem 3rem rgba(0, 0, 0, 0.3);
}

@media (prefers-reduced-motion: no-preference) {
    .ac-hand-diagram {
        animation: ac-diagram-in 0.35s var(--ac-ease-out);
    }
}

@keyframes ac-diagram-in {
    from { opacity: 0; }
}

.ac-diagram-seat {
    display: flex;
    flex-direction: column;
    gap: calc(1.2 * var(--u));
    min-width: 0;
}

.ac-diagram-north { grid-area: north; align-self: start; justify-self: center; }
.ac-diagram-south { grid-area: south; align-self: end; justify-self: center; }
.ac-diagram-west { grid-area: west; align-self: center; justify-self: start; }
.ac-diagram-east { grid-area: east; align-self: center; justify-self: end; }

.ac-diagram-name {
    display: flex;
    flex-direction: column;
    font-size: max(11px, calc(2.7 * var(--u)));
    font-weight: 700;
    line-height: 1.2;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
}

    .ac-diagram-name span {
        max-width: calc(26 * var(--u));
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .ac-diagram-name small {
        color: rgba(255, 255, 255, 0.72);
        font-size: max(10px, calc(2.1 * var(--u)));
        font-weight: 600;
    }

.ac-diagram-seat ul {
    display: flex;
    flex-direction: column;
    gap: calc(0.9 * var(--u));
    margin: 0;
    padding: 0;
    list-style: none;
}

.ac-diagram-seat li {
    display: flex;
    align-items: center;
    gap: calc(1.3 * var(--u));
    font-size: max(11px, calc(3 * var(--u)));
    font-weight: 700;
    white-space: nowrap;
}

.ac-diagram-ranks {
    display: flex;
    gap: 0.4em;
}

.ac-diagram-seat .ac-remaining-suit {
    flex: none;
    width: max(16px, calc(3.8 * var(--u)));
    height: max(16px, calc(3.8 * var(--u)));
    border-radius: max(4px, calc(0.8 * var(--u)));
    box-shadow: 0 calc(0.2 * var(--u)) calc(0.8 * var(--u)) rgba(0, 0, 0, 0.3);
}

    .ac-diagram-seat .ac-remaining-suit svg {
        width: 64%;
        height: 64%;
    }

.ac-diagram-centre {
    grid-area: centre;
    align-self: center;
    justify-self: center;
    color: rgba(255, 255, 255, 0.5);
    font-size: max(11px, calc(2.4 * var(--u)));
    font-weight: 700;
}

/* A phone-sized table (under 521px wide or 441px tall), as Trickster's small tables: the hands lie flat and run off
   the table's edges; your cards as large as the width allows, nearly whole, each showing its rank and suit in a jumbo
   corner index; the others' cards about as large as yours (owner, 2026-10-07), North's with a large index too; the
   trick in the room between the names. Sizes come from the table's width or height, whichever is tighter; the score
   (fixed sizes on a phone, below) and the tabs (the navbar's and the speaker's) take the top corners. */
@container (max-width: 520px) or (max-height: 440px) {
    .ac-stage > * {
        --name-font-size: clamp(12px, min(4.4cqw, 4.8cqh), 18px);
        --corner-h: 57px;
        --south-w: min(17cqw, 19.5cqh);
        /* A fifth of each of your cards below the edge */
        --south-show: calc(1.18 * var(--south-w));
        --south-lift: calc(0.28 * var(--south-w) + 13px);
        --trick-pad: 10px;
        --trick-cap: 1.25;
        /* The solver's counts large enough to read at a glance */
        --ns-bubble-min: 22px;
        --we-bubble-min: 20px;
    }

    .ac-stage:has(.ac-scoreboard-caption) > * {
        --corner-h: 71px;
    }

    .ac-stage #north-hand,
    .ac-stage #west-hand,
    .ac-stage #east-hand {
        --fan-turn: 0deg;
    }

    /* West's and East's index a little larger than on a fan, still inside the part of each card that shows */
    .ac-stage #west-hand,
    .ac-stage #east-hand {
        --rank: 0.34;
        --suit: 0.24;
        --fan-step: 0.27;
    }

    /* Your hand spreads across the table's width (each card showing at most three fifths of itself); the jumbo index
       is narrower than the part of each card that shows, down to a 320px phone */
    .ac-stage #south-hand {
        --rank: 0.46;
        --suit: 0.32;
        --fan-turn: 0deg;
        --card-spacing-horizontal: min(calc(var(--card-width) * -0.4), calc((100cqw - 3cqw - var(--card-width)) / max(var(--n, 13) - 1, 1) - var(--card-width)));
    }

        /* Only the top of each card shows (North's are turned round, so the same): no index at the foot, and the pips
           and pictures beside the jumbo index */
        .ac-stage :is(#south-hand, #north-hand) .playing-card :is(.value, .suit)::after {
            display: none;
        }

        .ac-stage :is(#south-hand, #north-hand) .playing-card .pip-container {
            --face-w: 100%;
            top: 57%;
            left: 66%;
            width: 56%;
            height: 70%;
        }

    @container (max-height: 440px) {
        /* On a short table (a phone held sideways) your marked card rises half as far */
        .ac-stage #south-hand > :is(.brilliant-move-marker, .good-move-marker, .excellent-move-marker, .neutral-move-marker, .weak-move-marker, .mistake-move-marker, .deceptive-move-marker) {
            transform: translateY(-10%) !important;
        }

        .ac-stage > * {
            --south-lift: calc(0.29 * var(--south-w) + 4px);
        }
    }
}

/* A score narrower than a 381px phone's table keeps clear of North's hand */
@container (max-width: 380px) {
    .ac-stage > * {
        --corner-h: 50px;
    }

    .ac-stage:has(.ac-scoreboard-caption) > * {
        --corner-h: 63px;
    }
}

/* A phone held upright: North's cards as large as yours, spread across the table like yours, come down until their
   index clears the tabs (the navbar's and the speaker's) and the score (owner, 2026-10-07); West's and East's fill the
   sides between North's cards and yours */
@container ((max-width: 520px) or (max-height: 440px)) and (orientation: portrait) {
    .ac-stage > * {
        --north-w: var(--south-w);
        --north-show: calc(var(--corner-h) + 0.77 * var(--north-w));
        --north-gap: calc(0.06 * var(--north-w));
        --north-reach: max(0.1 * var(--north-w), var(--north-gap) + var(--nil-rows) * (clamp(17px, 0.26 * var(--north-w), 30px) + 2px));
        --side-w: min(var(--south-w), calc((100cqh - var(--south-show) - var(--north-show) - var(--north-reach) - 10px) / 4.24));
        --side-y: calc((var(--north-show) + var(--north-reach) + 100cqh - var(--south-show)) / 2);
        --side-show: 0.5;
        --trick-v: 0.4;
        --trick-h: 0.68;
    }

    .ac-stage #north-hand {
        --rank: 0.42;
        --suit: 0.29;
        --card-spacing-horizontal: min(calc(var(--card-width) * -0.4), calc((100cqw - 3cqw - var(--card-width)) / max(var(--n, 13) - 1, 1) - var(--card-width)));
    }
}

/* A phone held sideways: the table is short and wide, so the room either side of the trick goes to the cards (owner,
   2026-10-07). West's and East's cards are columns down the sides, from below the corners to the bottom edge, and
   your hand lies between them; North's cards stay at the top edge, between the tabs (the navbar's and the speaker's)
   and the score; the trick lies flatter and wider. Every hand comes out about the same size. */
@container ((max-width: 520px) or (max-height: 440px)) and (orientation: landscape) {
    .ac-stage > * {
        --name-font-size: clamp(12px, min(4.4cqw, 4.6cqh), 18px);
        --side-w: min(19.5cqh, calc((100cqh - var(--corner-h) - 6px) / 3.94));
        --side-y: calc((var(--corner-h) + 100cqh - 6px) / 2);
        --side-show: 0.6;
        /* Your hand between West's and East's columns; its cards show a little less (their index and the pips
           beside it) */
        --south-room: calc(100cqw - 2 * (0.84 * var(--side-w) + 4px));
        --south-w: min(17cqw, 19.5cqh, calc(var(--south-room) / 5.32));
        --south-show: calc(1.08 * var(--south-w));
        /* The room between the two tabs (94px) and the score (about 100px), each with a little air */
        --north-room: calc(100cqw - 102px - 106px);
        --north-w: min(var(--south-w), calc(var(--north-room) / 4.48));
        --north-show: calc(0.63 * var(--north-w));
        --trick-v: 0.36;
        --trick-h: 1;
        --trick-pad: 6px;
    }

    .ac-stage #south-hand {
        --card-spacing-horizontal: min(calc(var(--card-width) * -0.4), calc((var(--south-room) - var(--card-width)) / max(var(--n, 13) - 1, 1) - var(--card-width)));
    }

    /* Without a score (the lessons) North's cards centre between the tabs and their mirror */
    .ac-stage:not(:has(.ac-scoreboard)) > * {
        --north-room: calc(100cqw - 204px);
    }

    .ac-stage #north-container {
        left: calc(102px + var(--north-room) / 2);
    }

    /* West and East a little smaller index, so their fans can be closer and their cards larger */
    .ac-stage #west-hand,
    .ac-stage #east-hand {
        --rank: 0.3;
        --suit: 0.21;
        --fan-step: 0.245;
    }

    .ac-stage #north-hand {
        --rank: 0.34;
        --suit: 0.24;
        --card-spacing-horizontal: min(calc(var(--card-width) * -0.55), calc((var(--north-room) - var(--card-width)) / max(var(--n, 13) - 1, 1) - var(--card-width)));
    }
}

/* A phone held sideways (any small screen wider than it's tall, and any screen held sideways under 501px tall, so a
   large phone too): the step bar becomes a rail down the right edge, so the table gets the screen's whole height
   (owner, 2026-10-07); the panel's sections still follow below the table */
@media (max-width: 899.98px) and (orientation: landscape), (orientation: landscape) and (max-height: 500px) {
    .ac-board {
        --room: calc(100dvh - var(--nav-h));
        grid-template-columns: minmax(0, 1fr) auto;
        column-gap: 0;
    }

    .ac-board-table {
        grid-column: 1;
        grid-row: 1;
        margin: -0.75rem 0 0 -0.75rem;
    }

    .ac-board-panel {
        grid-column: 1;
        grid-row: 2;
    }

    .ac-board-bar {
        grid-column: 2;
        grid-row: 1 / span 2;
        align-self: start;
        top: 0;
        bottom: auto;
        height: var(--room);
        margin: -0.75rem -0.75rem 0 0;
        padding: 0.625rem calc(0.4375rem + env(safe-area-inset-right)) 0.625rem 0.4375rem;
        border-top: 0;
        border-left: 1px solid var(--ac-line-strong);
        box-shadow: -0.75rem 0 1.5rem rgba(0, 0, 0, 0.35);
    }

    .ac-step-bar-compact {
        flex-direction: column;
        justify-content: flex-start;
        gap: 0.625rem;
        height: 100%;
    }

        .ac-step-bar-compact .ac-step-count {
            margin: 0;
            color: var(--ac-text-2);
            font-size: 0.8125rem;
            line-height: 1.15;
            text-align: center;
            white-space: normal;
        }

            /* The trick's number over "of 13" */
            .ac-step-bar-compact .ac-step-count strong {
                display: block;
                font-size: 1.25rem;
            }

        .ac-step-bar-compact .ac-step-buttons {
            flex-direction: column;
            margin-top: auto;
        }

        /* Replay Analysis' Back (A38): its arrow over its word, as wide as the steps, so the rail (and the felt) keep
           their width */
        .ac-step-bar-compact > .ac-playout-back {
            flex-direction: column;
            gap: 0.125rem;
            width: 2.625rem;
            padding: 0.375rem 0;
            font-size: 0.75rem;
        }
}

/* ---------------------------------------------------------------------------------------------------------------
   Every board in the frame (phases 2–4): the score on the felt, the boxes over the table, bidding, Play, clocks,
   the solver's counts, the calculators' picker; the panels' shared parts; the phone bars of the lessons, puzzles and
   calculators
   --------------------------------------------------------------------------------------------------------------- */

/* A page without a phone bar gives its room back to the table */
.ac-board:not(.ac-board-has-bar) {
    --bar-h: env(safe-area-inset-bottom);
}

/* The lessons' review quizzes: the same table in blue */
.ac-stage-blue {
    --ac-felt-wash: radial-gradient(ellipse 72% 66% at 50% 44%, #2a72b8 0%, #1f5b96 24%, #174677 56%, #0e2a49 100%);
}

/* The score, always in view in the table's top right corner (owner, 2026-10-07): Us and Them, each with its tricks
   taken / bid. Sized from the table like everything on it. */
.ac-scoreboard {
    position: absolute;
    top: calc(2 * var(--u));
    right: calc(2 * var(--u));
    z-index: 30;
    display: flex;
    flex-direction: column;
    gap: calc(0.5 * var(--u));
    padding: calc(1.1 * var(--u)) calc(1.6 * var(--u));
    border: 1px solid var(--ac-line-strong);
    border-radius: clamp(10px, calc(1.6 * var(--u)), 16px);
    background-color: rgba(17, 19, 22, 0.78);
    box-shadow: 0 calc(0.4 * var(--u)) calc(1.6 * var(--u)) rgba(0, 0, 0, 0.3);
    font-size: var(--score-font);
    line-height: 1.2;
    pointer-events: none;
}

    .ac-scoreboard dl {
        display: grid;
        grid-template-columns: auto auto auto;
        align-items: baseline;
        gap: calc(0.3 * var(--u)) calc(1.4 * var(--u));
        margin: 0;
    }

    .ac-scoreboard-row,
    .ac-scoreboard dd {
        display: contents;
    }

    .ac-scoreboard dt {
        color: rgba(255, 255, 255, 0.72);
        font-weight: 600;
    }

    .ac-scoreboard-score {
        justify-self: end;
        font-size: 1.25em;
        font-weight: 800;
        letter-spacing: -0.02em;
    }

    .ac-scoreboard-contract {
        justify-self: end;
        color: rgba(255, 255, 255, 0.72);
        font-size: 0.875em;
        font-weight: 700;
    }

    /* A row without a contract keeps the grid's third column */
    .ac-scoreboard dd:not(:has(.ac-scoreboard-contract))::after {
        content: "";
    }

.ac-scoreboard-caption {
    color: rgba(255, 255, 255, 0.72);
    font-size: 0.8125em;
    font-weight: 700;
}

/* On a phone-sized table: the scores alone, smaller (each seat shows its own tricks / bid by its name) */
@container (max-width: 520px) or (max-height: 440px) {
    .ac-scoreboard {
        top: 8px;
        right: 8px;
        padding: 5px 9px;
        font-size: 12px;
    }

        .ac-scoreboard dl {
            grid-template-columns: auto auto;
            column-gap: 8px;
        }

        .ac-scoreboard-contract,
        .ac-scoreboard dd::after {
            display: none;
        }
}

/* The boxes over the table (game over, hand complete, the lobby's Start and Leave, puzzle and exercise results): kept
   on the felt (owner, 2026-10-07), centred over the trick */
.ac-table-box {
    position: absolute;
    top: 46%;
    left: 50%;
    z-index: 60;
    display: flex;
    flex-direction: column;
    width: min(22rem, calc(100% - 1.5rem));
    max-height: calc(100% - 1.5rem);
    overflow: auto;
    border: 1px solid var(--ac-line-strong);
    border-radius: var(--ac-radius);
    background-color: var(--ac-surface);
    color: var(--ac-text);
    font-family: var(--ac-font);
    text-align: left;
    box-shadow: 0 1.25rem 3rem rgba(0, 0, 0, 0.5);
    transform: translate(-50%, -50%);
}

@media (prefers-reduced-motion: no-preference) {
    .ac-table-box:not(.hidden) {
        animation: ac-box-in 0.45s var(--ac-ease-out);
    }
}

@keyframes ac-box-in {
    from {
        opacity: 0;
        transform: translate(-50%, calc(-50% + 1rem)) scale(0.97);
    }
}

.ac-table-box-title {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    margin: 0 !important;
    padding: 0.875rem 1.25rem;
    border-bottom: 1px solid var(--ac-line);
    background-color: var(--ac-raised);
    font-size: 1.25rem;
    font-weight: 800;
    letter-spacing: -0.01em;
}

    .ac-table-box-title.correctly-answered {
        background-color: #1d3512;
        color: var(--ac-go);
    }

    .ac-table-box-title.incorrectly-answered {
        background-color: #3d1c1e;
        color: var(--ac-bad);
    }

    .ac-table-box-title.submitting-answer {
        background-color: var(--ac-raised) !important;
    }

.ac-table-box-body {
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
    padding: 1rem 1.25rem 1.25rem;
}

    .ac-table-box-body > .ac-btn {
        align-self: stretch;
    }

.ac-table-box-caption {
    color: var(--ac-text-2);
    font-size: 0.9375rem;
    font-weight: 700;
}

.ac-table-box-note {
    color: var(--ac-text-2);
    font-size: 0.9375rem;
    line-height: 1.5;
}

    .ac-table-box-note a {
        color: var(--ac-go);
        font-weight: 700;
        text-underline-offset: 0.2em;
    }

.ac-table-box-label {
    font-weight: 700;
}

.ac-table-box-winners {
    color: var(--ac-go);
    font-weight: 700;
}

.ac-table-box-status {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    font-weight: 700;
}

.ac-waiting-dot {
    width: 0.625rem;
    height: 0.625rem;
    border-radius: 50%;
    background-color: var(--ac-go);
}

@media (prefers-reduced-motion: no-preference) {
    .ac-waiting-dot {
        animation: ac-breathe 1.6s ease-in-out infinite;
    }
}

@keyframes ac-breathe {
    50% { opacity: 0.35; }
}

.ac-table-box-actions {
    display: flex;
    gap: 0.75rem;
}

    .ac-table-box-actions .ac-btn {
        flex: 1;
    }

/* More buttons than fit in a row (Play Again's result box): two to a row */
.ac-table-box-actions-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* A team duplicate table's link, the partner's invitation (TableOptionsBox): read-only in its field, Copy beside it */
.ac-table-box-invite {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
}

    .ac-table-box-invite .ac-input {
        flex: 1;
        min-width: 0;
        font-size: 0.875rem;
    }

.ac-btn:disabled {
    cursor: default;
    opacity: 0.55;
}

    .ac-btn:disabled:active {
        transform: none;
        box-shadow: 0 4px 0 var(--btn-edge);
    }

/* Ratings and scores: label over value, on the shell's colour */
.ac-result-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(6rem, 1fr));
    gap: 0.5rem;
    margin: 0;
}

    .ac-result-stats > div {
        display: flex;
        flex-direction: column;
        gap: 0.125rem;
        padding: 0.625rem 0.75rem;
        border-radius: var(--ac-radius-sm);
        background-color: var(--ac-bg);
    }

    .ac-result-stats dt {
        color: var(--ac-text-3);
        font-size: 0.8125rem;
        font-weight: 700;
    }

    .ac-result-stats dd {
        margin: 0;
        font-size: 1.125rem;
        font-weight: 800;
        letter-spacing: -0.01em;
    }

/* The hand's summary between two hands (practice, the casual table): each team's lines side by side, figures
   right-aligned, the hand's change in Play Green or Bad. Fixed columns, so a long nil bidder's name is cut short rather
   than widening the box past the felt. It stays up until it's closed, over the next hand's deal, bid tray, Play button,
   trick and thinking bars: all of them sit below a table box's 60. */
.ac-hand-summary {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    font-size: 0.9375rem;
    font-variant-numeric: tabular-nums;
}

    .ac-hand-summary .ac-hand-summary-label {
        width: 36%;
    }

    .ac-hand-summary :is(th, td) {
        padding: 0.3125rem 0 0.3125rem 0.75rem;
        text-align: right;
        vertical-align: top;
    }

    .ac-hand-summary :is(th, td):first-child {
        padding-left: 0;
        text-align: left;
    }

    .ac-hand-summary thead th {
        padding-top: 0;
        color: var(--ac-text-3);
        font-size: 0.8125rem;
        font-weight: 700;
    }

    .ac-hand-summary tbody th {
        color: var(--ac-text-2);
        font-weight: 600;
    }

    .ac-hand-summary td {
        font-weight: 700;
    }

    .ac-hand-summary tbody tr {
        border-top: 1px solid var(--ac-line);
    }

    .ac-hand-summary .ac-hand-summary-hand {
        border-top-color: var(--ac-line-strong);
    }

        .ac-hand-summary .ac-hand-summary-hand :is(th, td) {
            color: var(--ac-text);
            font-size: 1.0625rem;
            font-weight: 800;
        }

        .ac-hand-summary .ac-hand-summary-hand .ac-hand-summary-up {
            color: var(--ac-go);
        }

        .ac-hand-summary .ac-hand-summary-hand .ac-hand-summary-down {
            color: var(--ac-bad);
        }

.ac-hand-summary-none {
    color: var(--ac-text-3);
    font-weight: 600;
}

/* A nil on its own lines: the bidder's name (the column is narrow, so it gets the whole width, cut short with an
   ellipsis only if it must be), its points under it */
.ac-hand-summary-nil {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
}

.ac-hand-summary-name {
    overflow: hidden;
    max-width: 100%;
    font-size: 0.8125rem;
    color: var(--ac-text-2);
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* On a phone-sized table the rows close up a little */
@container (max-width: 520px) or (max-height: 440px) {
    .ac-hand-summary {
        font-size: 0.875rem;
    }

        .ac-hand-summary :is(th, td) {
            padding-top: 0.1875rem;
            padding-bottom: 0.1875rem;
        }

        .ac-hand-summary .ac-hand-summary-hand :is(th, td) {
            font-size: 1rem;
        }
}

.ac-answer-cards {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    vertical-align: middle;
}

/* Counting exercises' question (docs/counting-exercises-plan.md, phase 4): a little above the trick, so South's hand,
   which the count leaves out, stays in sight below it */
.ac-count-box {
    top: 42%;
    width: min(24rem, calc(100% - 1.5rem));
}

.ac-count-question {
    color: var(--ac-text);
    font-size: 1.125rem;
    font-weight: 700;
    line-height: 1.4;
}

    .ac-count-question .ac-mini-card {
        vertical-align: middle;
    }

/* The suit asked about on a white chip in the suit's colour, as a mini card has it (phase 8): clubs and spades read on
   the dark box too */
.ac-count-suit {
    display: inline-flex;
    align-items: baseline;
    gap: 0.2em;
    padding: 0 0.35em;
    border-radius: 6px;
    background-color: #fff;
    color: var(--ac-bg);
}

    .ac-count-suit svg {
        width: 0.9em;
        height: 0.9em;
        align-self: center;
        fill: currentColor;
    }

    .ac-count-suit[data-suit="hearts"],
    .ac-count-suit[data-suit="diamonds"] {
        color: #d62828;
    }

.ac-count-hint {
    font-size: 0.875rem;
}

.ac-count-answers {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 0.375rem;
}

.ac-count-holders {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.ac-count-answers > .ac-btn {
    min-width: 0;
    padding-inline: 0.25rem;
}

/* A rank: the suit's small white card, pressed like a button */
.ac-count-rank {
    display: flex;
    padding: 0;
    border: 0;
    border-radius: 6px;
    background: none;
    box-shadow: 0 3px 0 #8f96a1;
    cursor: pointer;
    transition: transform 0.08s, box-shadow 0.08s;
}

    .ac-count-rank .ac-mini-card {
        justify-content: center;
        width: 100%;
        min-width: 0;
        height: 2.375rem;
        padding: 0;
        font-size: 1rem;
    }

    .ac-count-rank:hover .ac-mini-card {
        box-shadow: inset 0 0 0 2px var(--ac-go);
    }

    .ac-count-rank:active {
        transform: translateY(3px);
        box-shadow: 0 0 0 #8f96a1;
    }

    .ac-count-rank:focus-visible {
        outline: 3px solid var(--ac-text);
        outline-offset: 2px;
    }

    .ac-count-rank:disabled {
        cursor: default;
        opacity: 0.55;
    }

/* On a phone-sized table the box closes up, so the question and its answers fit over the felt */
@container (max-width: 520px) or (max-height: 440px) {
    .ac-count-box .ac-table-box-title {
        padding: 0.625rem 1rem;
        font-size: 1.0625rem;
    }

    .ac-count-box .ac-table-box-body {
        gap: 0.625rem;
        padding: 0.75rem 1rem 1rem;
    }

    .ac-count-question {
        font-size: 1rem;
    }

    .ac-count-hint {
        font-size: 0.8125rem;
    }

    .ac-count-answers {
        gap: 0.25rem;
    }

        .ac-count-answers > .ac-btn,
        .ac-count-rank .ac-mini-card {
            min-height: 2.125rem;
            height: 2.125rem;
            font-size: 0.9375rem;
        }
}

/* The message boxes (notifications, confirmations) centre on the felt too; a list in one (the nil exercises' intro)
   reads from the left */
.ac-stage :is(#game-notification-box, #confirmation-box) {
    z-index: 70;
    max-height: calc(100% - 1.5rem);
    overflow: auto;
}

    .ac-stage #game-notification-box .card-body :is(ul, ol) {
        margin: 0.625rem 0 0;
        padding-left: 1.25rem;
        text-align: left;
    }

    .ac-stage #game-notification-box .text-success { color: var(--ac-go) !important; }
    .ac-stage #game-notification-box .text-grey { color: var(--ac-text) !important; }
    .ac-stage #game-notification-box .text-danger { color: var(--ac-bad) !important; }

/* Bidding: the 14 bids as chunky keys on a dark tray over the trick, seven to a row, at a size a thumb can press */
.ac-stage #bidding-button-container {
    --key: clamp(36px, calc(6.6 * var(--u)), 64px);
    --key-gap: calc(0.12 * var(--key));
    top: var(--trick-y, 44%);
    display: grid;
    grid-template-columns: repeat(7, var(--key));
    gap: var(--key-gap);
    width: auto;
    padding: calc(0.3 * var(--key)) calc(0.3 * var(--key)) calc(0.36 * var(--key));
}

    .ac-stage #bidding-button-prompt {
        grid-column: 1 / -1;
        margin: 0 0 calc(0.1 * var(--key));
        font-size: clamp(14px, calc(0.34 * var(--key)), 20px);
    }

    .ac-stage .bidding-button-line-break {
        display: none;
    }

    .ac-stage .bidding-button {
        width: var(--key);
        height: var(--key);
        margin: 0;
        font-size: calc(0.4 * var(--key));
    }

        .ac-stage .bidding-button-text {
            font-size: 1em;
        }

/* A table taller than it's wide (an upright phone or tablet): five to a row, so the tray stays clear of West's and
   East's labels beside it (seven to a row reached over them). Each key spans two half-columns, so the last row's four
   (10 to 13) can sit in the middle. */
@container (aspect-ratio < 1) {
    .ac-stage #bidding-button-container {
        grid-template-columns: repeat(10, calc((var(--key) - var(--key-gap)) / 2));
    }

        .ac-stage .bidding-button {
            grid-column: span 2;
        }

            .ac-stage .bidding-button:nth-of-type(11) {
                grid-column: 2 / span 2;
            }
}

/* ...and on a phone under 381px wide, a little smaller and closer together (each key 34px) */
@container (aspect-ratio < 1) and (max-width: 380px) {
    .ac-stage #bidding-button-container {
        --key: 34px;
        --key-gap: 3px;
        padding: 8px 7px 10px;
    }
}

/* Two-click play's Play button, on your place in the trick: a big target, about 0.4 of the trick card's height */
.ac-stage #confirm-card-button {
    top: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: auto;
    min-width: calc(var(--card-width) * 0.9);
    min-height: calc(var(--card-height) * 0.4);
    padding: 0.7em 1em;
    font-size: clamp(14px, calc(2.4 * var(--u)), 22px);
    line-height: 1.2;
    transition: background-color 0.15s, transform 0.08s, box-shadow 0.08s;
}

    .ac-stage #confirm-card-button:hover {
        top: 50%;
    }

    .ac-stage #confirm-card-button:active {
        top: 50%;
        transform: translate(-50%, calc(-50% + 6px));
    }

/* A live table's clocks, a quiet pill before the name, its figures nearly the name's size; out of time, Flag (yellow)
   or Resign (red) to press */
.ac-stage [id$="-clock"].btn {
    align-items: center;
    gap: 0.25em;
    min-height: 0;
    margin: 0 0.35em 0 0 !important;
    padding: 0.05em 0.5em;
    border: 0;
    border-radius: 999px;
    background-color: rgba(0, 0, 0, 0.4);
    color: #fff;
    font-family: var(--ac-font);
    font-size: 0.85em;
    font-weight: 700;
    line-height: 1.35;
    vertical-align: 0.06em;
    box-shadow: none;
}

    .ac-stage [id$="-clock"].btn img {
        width: 0.95em;
        margin: 0 !important;
    }

    .ac-stage [id$="-clock"].btn-warning {
        background-color: var(--ac-yellow);
        color: #1f1600;
        box-shadow: 0 3px 0 var(--ac-yellow-edge);
        cursor: pointer;
    }

        /* The flag (white) in the dark ink */
        .ac-stage [id$="-clock"].btn-warning img {
            filter: brightness(0);
            opacity: 0.88;
        }

    .ac-stage [id$="-clock"].btn-danger {
        background-color: var(--ac-bad-fill);
        box-shadow: 0 3px 0 #a51d1d;
        cursor: pointer;
    }

/* A bot's thinking bar (docs/bot-thinking-bar-plan.md), in its clock's place while it has the turn: a slim light track
   about as wide as a clock, so a bot's turn pill matches a player's at a timed table, filling with the pill's own dark
   ink as the bot works through its search; no figures. It only shows on the turn's green pill, where dark on light
   reads best (owner's choice over a green fill). The fill is scaled, not sized, and eases over the 250 ms between the
   server's readings (at once with reduced motion); a new turn draws a new bar, so it never runs back. */
.ac-stage .seat-thinking {
    display: inline-block;
    box-sizing: border-box;
    width: 3.6em;
    height: 0.5em;
    margin: 0 0.35em 0 0;
    padding: 0.1em;
    overflow: hidden;
    border-radius: 999px;
    background-color: rgba(255, 255, 255, 0.55);
    vertical-align: 0.1em;
}

    .ac-stage .seat-thinking-fill {
        display: block;
        height: 100%;
        border-radius: inherit;
        background-color: var(--ac-go-ink);
        transform-origin: left center;
    }

@media (prefers-reduced-motion: no-preference) {
    .ac-stage .seat-thinking-fill {
        transition: transform 250ms linear;
    }
}

/* The name stays put as the bar comes and goes with each turn (a centred label would have its name jump about half
   the bar's width every time a bot took the turn): the label moves back by half the room the bar takes (the bar, its
   margin and the space after it), so it grows towards its start (where the dealer chip is) instead. North's and
   yours read left to right; West's turns down the table and East's up it. */
.ac-stage :is(#north-name, #east-name, #south-name, #west-name) {
    --thinking-room: 4.2em;
}

    .ac-stage :is(#north-name, #south-name):has(> .seat-thinking) {
        margin-left: calc(-0.5 * var(--thinking-room));
    }

    .ac-stage #west-name:has(> .seat-thinking) {
        margin-top: calc(-0.5 * var(--thinking-room));
    }

    .ac-stage #east-name:has(> .seat-thinking) {
        margin-top: calc(0.5 * var(--thinking-room));
    }

/* On a phone-sized table West's and East's names have a short column, between North's cards (or, held sideways, the
   corner tabs and the score) and yours or the bottom edge, so a thinking bot's label grows evenly both ways to stay
   clear of them */
@container (max-width: 520px) or (max-height: 440px) {
    .ac-stage :is(#west-name, #east-name):has(> .seat-thinking) {
        margin-top: 0;
    }
}

/* An empty seat's Join button, before a table starts */
.ac-stage [id$="-name-text"] .green-text-button {
    padding: 0.15em 0.9em !important;
    border: 0;
    border-radius: 999px;
    background-color: var(--ac-go);
    color: var(--ac-go-ink);
    font-family: var(--ac-font);
    font-size: 1em;
    font-weight: 800;
    box-shadow: 0 3px 0 var(--ac-go-edge);
    cursor: pointer;
}

    .ac-stage [id$="-name-text"] .green-text-button:hover {
        background-color: var(--ac-go-hover);
    }

/* The Hand Solver's counts: a round badge on each playable card, just beyond the edge of the part of the card that
   shows in the hand, clear of its corner index (green the best, yellow the rest), with its nil chips stacked beyond
   it. The figure fills most of the badge and the white ring is thin (owner, 2026-10-08: the counts were hard to read
   on a phone). A badge is 30% of its card, at least 22px on North's and your cards on a phone and 20px on West's and
   East's, at most 38px (44px on yours); the figure 0.64 of it; a chip 26% of the card, 17px to 30px. */
.ac-stage :is(#north-hand, #south-hand) { --bubble-min: var(--ns-bubble-min); }
.ac-stage :is(#west-hand, #east-hand) { --bubble-min: var(--we-bubble-min); }
.ac-stage #south-hand { --bubble-max: 44px; }

.ac-stage .number-bubble {
    --bubble: clamp(var(--bubble-min, 18px), calc(var(--card-width) * 0.3), var(--bubble-max, 38px));
    --ring: max(1.5px, calc(var(--bubble) * 0.065));
    --chip: clamp(17px, calc(var(--card-width) * 0.26), 30px);
    /* The middle of the part of the card that shows */
    --strip-middle: calc((var(--card-width) + var(--card-spacing-horizontal)) / 2);
}

.ac-stage .number-bubble::before {
    top: calc(var(--bubble) * -0.92);
    left: calc(var(--strip-middle) - var(--bubble) / 2);
    width: var(--bubble);
    height: var(--bubble);
    border: var(--ring) solid #fff;
    font-size: calc(var(--bubble) * 0.64);
    letter-spacing: -0.03em;
    line-height: calc(var(--bubble) - 2 * var(--ring));
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
}

.ac-stage .nil-marker {
    position: absolute;
    bottom: calc(100% + var(--bubble) * 0.98);
    left: calc(var(--strip-middle) - var(--chip) / 2);
    z-index: 10;
    display: flex;
    flex-direction: column-reverse;
    gap: 2px;
}

    .ac-stage #north-hand .nil-chip { transform: rotate(180deg); }
    .ac-stage #west-hand .nil-chip { transform: rotate(270deg); }
    .ac-stage #east-hand .nil-chip { transform: rotate(90deg); }

.nil-chip {
    display: inline-grid;
    place-items: center;
    width: var(--chip, clamp(15px, calc(var(--card-width, 60px) * 0.24), 28px));
    height: var(--chip, clamp(15px, calc(var(--card-width, 60px) * 0.24), 28px));
    border: 1px solid #fff;
    border-radius: 25%;
    color: #fff;
    font-family: var(--ac-font);
    font-size: calc(var(--chip, 22px) * 0.68);
    font-weight: 800;
    line-height: 1;
}

    .nil-chip[data-made="true"] {
        background-color: var(--ac-green);
    }

    .nil-chip[data-made="false"] {
        background-color: var(--ac-bad-fill);
        text-decoration: line-through;
        text-decoration-thickness: max(2px, 0.1em);
    }

.nil-chip-legend {
    --chip: 1.375rem;
}

/* The solver plays any seat: the others' playable cards rise a little under the pointer, as yours do (but for the
   replay's card, raised already, below) */
@media (hover: hover) and (pointer: fine) {
    .ac-board-solver .ac-stage :is(#north-hand, #west-hand, #east-hand) > .card-container:has(.number-bubble) {
        cursor: pointer;
    }

    /* Towards the middle of the table, in each hand's own axes: North's hand and East's are turned round whole
       (lesson.css), so North's cards move to minus y (down the screen) and East's to plus x (left) */
    .ac-board-solver .ac-stage #north-hand > .card-container:has(.number-bubble):not(.card-replay):hover {
        translate: 0 calc(var(--k) * var(--k) * var(--fan-drop) - var(--card-width) * 0.12);
    }

    .ac-board-solver .ac-stage #west-hand > .card-container:has(.number-bubble):not(.card-replay):hover {
        translate: calc(var(--k) * var(--k) * var(--fan-drop) * -1 + var(--card-width) * 0.12) 0;
    }

    .ac-board-solver .ac-stage #east-hand > .card-container:has(.number-bubble):not(.card-replay):hover {
        translate: calc(var(--k) * var(--k) * var(--fan-drop) * -1 + var(--card-width) * 0.12) 0;
    }
}

/* The card the replay plays next, while the cards played follow its line (owner, 2026-10-14), stands raised out of
   its hand towards the middle of the table, in the hand's own axes as above, by --replay-rise of a card's width. It
   stays put under the pointer (your cards rise there by their transform). No ring: that's two-click play's chosen card,
   and green is the best count's colour. Replay Analysis' playout stepped a trick at a time lifts the card it plays next
   the same way (continuation-playout plan A33), as far as your marked card rises there (your pill has room for that). */
.ac-board-analysis .ac-stage > * {
    --replay-rise: 0.25;
}

:is(.ac-board-solver, .ac-board-analysis) .ac-stage :is(#north-hand, #south-hand) > .card-container.card-replay {
    translate: 0 calc(var(--k) * var(--k) * var(--fan-drop) - var(--card-width) * var(--replay-rise));
}

:is(.ac-board-solver, .ac-board-analysis) .ac-stage :is(#west-hand, #east-hand) > .card-container.card-replay {
    translate: calc(var(--k) * var(--k) * var(--fan-drop) * -1 + var(--card-width) * var(--replay-rise)) 0;
}

:is(.ac-board-solver, .ac-board-analysis) .ac-stage #south-hand > .card-container.card-replay {
    transform: none;
}

/* On a short table (a phone held sideways) it rises half as far, as Replay Analysis' marked card does */
@container (max-height: 440px) {
    :is(.ac-board-solver, .ac-board-analysis) .ac-stage > * {
        --replay-rise: 0.125;
    }
}

/* North's, West's or East's name moves out past it, into the seat's own place in the trick (empty until it plays), as
   for the nil chips (your pill keeps room for it, above) */
:is(.ac-board-solver, .ac-board-analysis) .ac-stage:has(#north-hand > .card-replay) > * {
    --north-rise-room: calc(var(--replay-rise) * var(--north-w));
}

:is(.ac-board-solver, .ac-board-analysis) .ac-stage:has(#west-hand > .card-replay) > * {
    --west-rise-room: calc(var(--replay-rise) * var(--side-w));
}

:is(.ac-board-solver, .ac-board-analysis) .ac-stage:has(#east-hand > .card-replay) > * {
    --east-rise-room: calc(var(--replay-rise) * var(--side-w));
}

/* The calculators: South's hand on the felt with Edit Hand over it (no name pill); the picker a sheet over the table,
   the deck by suit in four rows, each card showing its index, and the hand below */
.ac-stage #south-name.ac-edit-hand {
    padding: 0;
    border: 0;
    background: none;
    font-size: 1rem;
}

    /* South deals (the nil calculator's bids): the dealer's chip just left of Edit Hand, which stays centred */
    .ac-stage #south-name.ac-edit-hand.dealer-button::before {
        position: absolute;
        top: 50%;
        right: calc(100% + 0.4em);
        translate: 0 -50%;
    }

/* The nil calculator's bids so far (owner, 2026-10-08; they were in the panel): West's, North's and East's pills where
   each seat's name sits on the other boards, upright on every side (owner: they're controls), each the seat's name and
   its bid, "?" until it has bid, and the dealer's chip before the name. The picker's sheet covers them. */
.ac-stage .ac-seat-bid {
    position: absolute;
    z-index: 20;
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    margin: 0;
    padding: 0.2em 0.2em 0.2em 0.75em;
    border: 1px solid var(--ac-line-strong);
    border-radius: 999px;
    background-color: rgba(17, 19, 22, 0.78);
    color: rgba(255, 255, 255, 0.72);
    font-family: var(--ac-font);
    font-size: min(var(--name-font-size), 22px);
    font-weight: 600;
    line-height: 1.3;
    white-space: nowrap;
}

    .ac-stage .ac-seat-bid.dealer-button {
        padding-left: 0.3em;
    }

    .ac-stage #north-seat {
        top: calc(var(--north-show) + var(--north-gap));
        left: 50%;
        transform: translateX(-50%);
    }

    /* West's and East's level with the trick, their outer edge where the part of a hand that shows would end */
    .ac-stage #west-seat {
        top: var(--side-y);
        left: calc(1.4 * var(--side-show) * var(--side-w) + var(--side-gap));
        transform: translateY(-50%);
    }

    .ac-stage #east-seat {
        top: var(--side-y);
        right: calc(1.4 * var(--side-show) * var(--side-w) + var(--side-gap));
        transform: translateY(-50%);
    }

    /* The bid: a Raised chip with a drawn chevron, the figure bold and tabular; "?" quieter until the seat has bid */
    .ac-stage .ac-seat-bid select {
        appearance: none;
        min-width: 2.9em;
        margin: 0;
        padding: 0.15em 1.45em 0.15em 0.65em;
        border: 1px solid var(--ac-line-strong);
        border-radius: 999px;
        background: var(--ac-raised) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23b0b6c0' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1.5 1.75 6 6.25l4.5-4.5'/%3E%3C/svg%3E") no-repeat right 0.55em center / 0.6em auto;
        color: var(--ac-text-3);
        font: inherit;
        font-weight: 800;
        font-variant-numeric: tabular-nums;
        line-height: 1.3;
        color-scheme: dark;
        cursor: pointer;
        transition: background-color 0.15s, border-color 0.15s;
    }

        .ac-stage .ac-seat-bid select:hover {
            border-color: rgba(255, 255, 255, 0.24);
            background-color: var(--ac-raised-hover);
        }

        .ac-stage .ac-seat-bid select:focus-visible {
            outline: 2px solid var(--ac-go);
            outline-offset: 2px;
        }

    .ac-stage .ac-seat-bid-made {
        color: #fff;
    }

        .ac-stage .ac-seat-bid-made select {
            color: #fff;
        }

/* A thumb's target on touch screens */
@media (pointer: coarse) {
    .ac-stage .ac-seat-bid select {
        min-width: 3.25em;
        min-height: 34px;
    }
}

/* On a phone held upright West's and East's pills keep to the table's edges, well apart (no hands to stand clear of) */
@container ((max-width: 520px) or (max-height: 440px)) and (orientation: portrait) {
    .ac-stage #west-seat { left: 3cqw; }
    .ac-stage #east-seat { right: 3cqw; }
}

/* Held sideways, level with the trick's middle: the sides' middle is low there, beside Edit Hand */
@container ((max-width: 520px) or (max-height: 440px)) and (orientation: landscape) {
    .ac-stage :is(#west-seat, #east-seat) { top: var(--trick-y); }
}

.ac-stage #card-selector {
    --fan-step: 0.6;
    --card-width: max(30px, min(calc((100cqw - 2rem) / 8.2), calc((100cqh - 6.5rem) / 4.75)));
    --card-spacing-horizontal: calc(var(--card-width) * (var(--fan-step) - 1));
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    padding: 1rem;
    border-radius: inherit;
    background: rgba(17, 19, 22, 0.95);
    color: var(--ac-text);
    font-family: var(--ac-font);
}

    .ac-stage #card-selector-card-container {
        display: flex;
        flex-direction: column;
    }

    .ac-stage :is(#club-container, #heart-container, #spade-container) {
        margin-top: calc(var(--card-height) * -0.55);
    }

    .ac-stage #card-selector .card-container {
        cursor: pointer;
        transition: translate 0.15s var(--ac-ease-out);
    }

        .ac-stage #card-selector .card-container:hover {
            translate: 0 calc(var(--card-height) * -0.06);
        }

    .ac-stage #card-selector-player-container {
        position: static;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 0.5rem;
        transform: none;
    }

    .ac-stage .card-selector-hand-head {
        display: flex;
        align-items: center;
        gap: 1rem;
    }

    .ac-stage .card-selector-text {
        margin: 0;
        color: var(--ac-text-2);
        font-size: clamp(0.8125rem, 2.4cqmin, 1rem);
        font-weight: 600;
    }

        .ac-stage .card-selector-text strong {
            color: var(--ac-text);
            font-weight: 800;
        }

/* The Replay Maker (docs/replay-maker-plan.md): all four hands on the felt, and in each seat's name's place its pill, as
   the nil calculator's bids: the dealer's chip, the seat's name, its bid and Edit, which opens the deal editor (the
   picker's sheet, dealing that seat's hand from the one deck). The board's own name labels give way to the pills. */
.ac-board-maker .ac-stage :is(#north-name, #east-name, #south-name, #west-name) {
    display: none;
}

    /* South's where your name pill sits, over the middle of your hand */
    .ac-stage #south-seat {
        bottom: calc(var(--south-show) + var(--south-lift));
        left: 50%;
        transform: translateX(-50%);
    }

    /* Edit: a Raised chip, as the bid's */
    .ac-stage .ac-seat-edit {
        margin: 0;
        padding: 0.15em 0.75em;
        border: 1px solid var(--ac-line-strong);
        border-radius: 999px;
        background-color: var(--ac-raised);
        color: var(--ac-text);
        font: inherit;
        font-weight: 700;
        line-height: 1.3;
        cursor: pointer;
        transition: background-color 0.15s, border-color 0.15s;
    }

        .ac-stage .ac-seat-edit:hover {
            border-color: color-mix(in srgb, var(--ac-text) 24%, transparent);
            background-color: var(--ac-raised-hover);
        }

        .ac-stage .ac-seat-edit:focus-visible {
            outline: 2px solid var(--ac-go);
            outline-offset: 2px;
        }

@media (pointer: coarse) {
    .ac-stage .ac-seat-edit {
        min-height: 34px;
    }
}

/* While the cards are dealt, a click on a hand opens it in the editor */
.ac-maker-dealing .ac-stage :is(#north-hand, #west-hand, #east-hand, #south-hand) > .card-container {
    cursor: pointer;
}

/* The deal editor's deck (deal-editor.tsx), three kinds of card told apart at a glance: one no hand holds face up; one
   in the hand being picked face up too, lifted, ringed in Play green and ticked (DESIGN.md's picked card), the tick
   beside its corner index, in the part the next card leaves showing; one another seat holds face down and faded right
   back, on the sheet's own colour so the cards under it don't show through, and inert. With the keyboard the card
   with the focus rises as under the pointer, in the buttons' white focus ring, outside the green one. */
.ac-stage #card-selector.ac-deal-editor .card-container {
    position: relative;
}

.ac-stage #card-selector.ac-deal-editor .card-container.ac-deal-picked {
    translate: 0 calc(var(--card-height) * -0.1);
}

    .ac-stage #card-selector.ac-deal-editor .ac-deal-picked > .playing-card {
        outline: 3px solid var(--ac-go);
    }

    .ac-stage #card-selector.ac-deal-editor .ac-deal-tick {
        position: absolute;
        z-index: 5;
        top: calc(var(--card-width) * 0.06);
        left: calc(var(--card-width) * 0.27);
        display: grid;
        place-items: center;
        width: calc(var(--card-width) * 0.26);
        aspect-ratio: 1;
        border-radius: 50%;
        background-color: var(--ac-go);
        color: var(--ac-go-ink);
        pointer-events: none;
    }

        .ac-stage #card-selector.ac-deal-editor .ac-deal-tick svg {
            width: 72%;
            height: 72%;
        }

.ac-stage #card-selector.ac-deal-editor .card-container.ac-deal-taken {
    border-radius: var(--card-border-radius);
    background-color: var(--ac-bar);
    cursor: default;
}

    .ac-stage #card-selector.ac-deal-editor .card-container.ac-deal-taken:hover {
        translate: none;
    }

    .ac-stage #card-selector.ac-deal-editor .ac-deal-taken > .playing-card {
        opacity: 0.3;
    }

.ac-stage #card-selector.ac-deal-editor .card-container:focus-visible {
    outline: 3px solid var(--ac-text);
    outline-offset: 3px;
    translate: 0 calc(var(--card-height) * -0.06);
}

    .ac-stage #card-selector.ac-deal-editor .card-container.ac-deal-picked:focus-visible {
        translate: 0 calc(var(--card-height) * -0.1);
    }

    .ac-stage #card-selector.ac-deal-editor .card-container.ac-deal-taken:focus-visible {
        translate: none;
    }

/* Under the hand's count, what a card picked did beyond it (the last hand filled with the cards left), in Play green as
   the picked cards' rings; empty, it has no height */
.ac-stage #card-selector.ac-deal-editor .ac-deal-note {
    color: var(--ac-go);
}

/* The sheet takes the focus from a click between its cards (so Escape still closes it): no ring for that */
.ac-stage #card-selector.ac-deal-editor:focus {
    outline: none;
}

/* The pills against the trick: the frame keeps the trick clear of a name one line tall, North's below North's hand
   and yours above your hand; the pills are taller (a select and Edit in them, 34px tall on touch screens), so the
   trick's room is worked out from their height (--pill-h, the frame's for your pill, now all four's). The pills at the
   left and right stand on their sides beside their hands (below), each as thick as a pill is tall, so the trick keeps
   clear of them sideways too, at every size and shape of table: its West and East cards (tilted, each reaching 0.63 of
   a card's width beyond its place, once played in) stay 8px inside the room the two pills leave, the trick no larger
   than the frame makes it (top of the file). Where there's room to spare the frame's size stands. */
.ac-board-maker .ac-stage > * {
    --pill-type: min(var(--name-font-size), 22px);
    --pill-h: calc(2 * var(--pill-type) + 4px);
    --north-bottom: calc(var(--north-show) + var(--north-gap) + var(--pill-h));
    /* A side pill's outer edge, where the part of a hand that shows would end and a name's gap after it; its middle
       level with its hand's */
    --side-pill-x: calc(1.4 * var(--side-show) * var(--side-w) + var(--side-gap));
    --side-pill-y: var(--side-y);
    --side-pill-room: calc(50cqw - var(--side-pill-x) - var(--pill-h) - 8px);
    --trick-w: min(calc(var(--trick-cap) * var(--south-w)), calc((var(--south-top) - var(--north-bottom) - var(--trick-pad)) / (1.6 + 2 * var(--trick-v))),
        calc(var(--side-pill-room) / (var(--trick-h) + 0.63)));
}

@media (pointer: coarse) {
    .ac-board-maker .ac-stage > * {
        --pill-h: max(2 * var(--pill-type) + 4px, 0.4 * var(--pill-type) + 36px);
    }
}

/* The pills at the left and right of the table on their sides at every size, turned as the names there are on the
   other boards (lesson.css) and as their hands' cards: the left one reads down the table and the right one up it, the
   tops of their letters towards the middle (owner, 2026-10-15; A18). By the place, not the seat, as the board can be
   seen from any seat (A21); :is() with the seats' ids outranks the frame's placing of each seat's pill by its id (the
   nil calculator's keep that, upright). Each moves back half its length and its whole height, then turns a quarter
   about its top corner on the table's edge, so whatever its length it stands its height wide from --side-pill-x, its
   middle at --side-pill-y. A control in it shows its focus ring turned with it; a bid's list opens upright (the
   browser draws it). */
.ac-board-maker .ac-stage .ac-seat-bid-sideways:is(#west-seat, #north-seat, #east-seat, #south-seat) {
    top: var(--side-pill-y);
    bottom: auto;
}

.ac-board-maker .ac-stage .ac-seat-bid-left:is(#west-seat, #north-seat, #east-seat, #south-seat) {
    right: auto;
    left: var(--side-pill-x);
    transform-origin: 0 0;
    transform: rotate(90deg) translate(-50%, -100%);
}

.ac-board-maker .ac-stage .ac-seat-bid-right:is(#west-seat, #north-seat, #east-seat, #south-seat) {
    right: var(--side-pill-x);
    left: auto;
    transform-origin: 100% 0;
    transform: rotate(-90deg) translate(50%, -100%);
}

/* On a phone held upright the trick is drawn tighter (West's and East's cards nearer its middle), so it's as large as
   the frame makes it between the side pills */
@container ((max-width: 520px) or (max-height: 440px)) and (orientation: portrait) {
    .ac-board-maker .ac-stage > * {
        --trick-h: 0.4;
    }
}

/* Held sideways, West's and East's cards are columns down the table's sides and yours lie between them: a side pill's
   middle is halfway from the score's corner down to your cards, so it's clear of both */
@container ((max-width: 520px) or (max-height: 440px)) and (orientation: landscape) {
    .ac-board-maker .ac-stage > * {
        --side-pill-y: calc((var(--corner-h) + 100cqh - var(--south-show)) / 2);
    }
}

/* While the Replay Maker's cards are played: the seat to play's pill in Play green, as your name's is on the game
   pages, and each seat's tricks taken before its bid ("2/3", as the other boards' labels read) */
.ac-stage .ac-seat-bid.ac-seat-bid-turn {
    border-color: transparent;
    background-color: var(--ac-go);
    color: var(--ac-go-ink);
}

.ac-stage .ac-seat-bid-taken {
    font-weight: 800;
    font-variant-numeric: tabular-nums;
}

    .ac-stage .ac-seat-bid-taken::after {
        content: "/";
        margin-left: 0.15em;
        opacity: 0.6;
    }

/* The seat to play's legal cards (the ones not greyed) take a click, and rise a little under the pointer as yours do,
   towards the middle of the table in each hand's own axes (as the solver's playable cards) */
@media (hover: hover) and (pointer: fine) {
    .ac-maker-playing .ac-stage :is(#north-hand, #west-hand, #east-hand, #south-hand) > .card-container:has(> .playing-card:not(.greyed)) {
        cursor: pointer;
    }

    .ac-maker-playing .ac-stage #north-hand > .card-container:has(> .playing-card:not(.greyed)):hover {
        translate: 0 calc(var(--k) * var(--k) * var(--fan-drop) - var(--card-width) * 0.12);
    }

    .ac-maker-playing .ac-stage :is(#west-hand, #east-hand) > .card-container:has(> .playing-card:not(.greyed)):hover {
        translate: calc(var(--k) * var(--k) * var(--fan-drop) * -1 + var(--card-width) * 0.12) 0;
    }
}

/* Once the Replay Maker's hand is complete, Create on the felt too (phase 10, A19): a small Surface card where the trick
   was (empty by then), its middle the trick's, held to the trick's own room (from North's pill down to yours, and
   between the side pills: the sizes above), 8px clear of each pill, so it never covers one on any table. Its type
   from the table, the button the panel's. Above the pills; under the score's editor, the boxes and the spinner. */
.ac-board-maker .ac-stage > .ac-maker-done {
    position: absolute;
    top: var(--trick-y);
    left: 50%;
    z-index: 25;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.5em;
    box-sizing: border-box;
    max-width: calc(2 * var(--side-pill-room));
    max-height: calc(var(--south-top) - var(--north-bottom) - 16px);
    padding: 0.75em 1em 1em;
    border: 1px solid var(--ac-line-strong);
    border-radius: var(--ac-radius-sm);
    background-color: var(--ac-surface);
    color: var(--ac-text);
    font-family: var(--ac-font);
    font-size: clamp(13px, calc(2.2 * var(--u)), 16px);
    text-align: center;
    box-shadow: 0 calc(0.4 * var(--u)) calc(1.6 * var(--u)) rgba(0, 0, 0, 0.3);
    transform: translate(-50%, -50%);
}

    .ac-board-maker .ac-maker-done-title {
        margin: 0;
        font-weight: 700;
        line-height: 1.25;
    }

@media (prefers-reduced-motion: no-preference) {
    .ac-board-maker .ac-stage > .ac-maker-done {
        animation: ac-box-in 0.45s var(--ac-ease-out);
    }
}

/* The Replay Maker's score is a button (A20): one laid over the whole box takes the click (Enter or Space from the
   keyboard), the box lighting up under the pointer and while its editor is open, and its figures dotted underneath,
   as a sign they can be changed where there's no pointer to hover (a phone). The box itself still lets clicks through
   round it (the frame's pointer-events: none), so the button takes them back. */
.ac-board-maker .ac-scoreboard {
    transition: background-color 0.15s, border-color 0.15s;
}

    .ac-board-maker .ac-scoreboard:has(> .ac-scoreboard-edit:not(:disabled):hover),
    .ac-board-maker .ac-scoreboard:has(> .ac-scoreboard-edit[aria-expanded="true"]) {
        border-color: color-mix(in srgb, var(--ac-text) 24%, transparent);
        background-color: color-mix(in srgb, var(--ac-raised) 92%, transparent);
    }

    .ac-board-maker .ac-scoreboard:has(> .ac-scoreboard-edit:not(:disabled)) .ac-scoreboard-score {
        text-decoration: underline dotted color-mix(in srgb, var(--ac-text) 45%, transparent);
        text-decoration-thickness: 1px;
        text-underline-offset: 0.2em;
    }

    .ac-board-maker .ac-scoreboard-edit {
        position: absolute;
        inset: -1px;
        margin: 0;
        padding: 0;
        border: 0;
        border-radius: inherit;
        background: transparent;
        cursor: pointer;
        pointer-events: auto;
    }

        .ac-board-maker .ac-scoreboard-edit:disabled {
            cursor: default;
        }

        .ac-board-maker .ac-scoreboard-edit:focus-visible {
            outline: 2px solid var(--ac-go);
            outline-offset: 2px;
        }

/* The score's editor: a small Surface box dropping from under the score, its right edge on the score's, never wider
   or taller than the table leaves it (the felt clips what leaves it); a title, each score's field with its label
   beside it, and Done. In the panel's type, as it holds the panel's fields. */
.ac-board-maker .ac-score-editor {
    position: absolute;
    top: calc(100% + 0.5rem);
    right: 0;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    box-sizing: border-box;
    width: min(17rem, calc(100cqw - 1rem));
    max-height: calc(100cqh - var(--corner-h) - 1rem);
    overflow: auto;
    padding: 0.875rem 1rem 1rem;
    border: 1px solid var(--ac-line-strong);
    border-radius: var(--ac-radius-sm);
    background-color: var(--ac-surface);
    color: var(--ac-text);
    font-family: var(--ac-font);
    font-size: 1rem;
    line-height: 1.5;
    text-align: left;
    box-shadow: 0 1.25rem 3rem rgba(0, 0, 0, 0.5);
    pointer-events: auto;
}

    .ac-board-maker .ac-score-editor-title {
        margin: 0;
        font-size: 0.9375rem;
        font-weight: 800;
    }

    .ac-board-maker .ac-score-editor .ac-field {
        display: grid;
        grid-template-columns: minmax(0, 1fr) 6rem;
        align-items: center;
        gap: 0.75rem;
    }

        .ac-board-maker .ac-score-editor .ac-field label {
            font-size: 0.875rem;
        }

        .ac-board-maker .ac-score-editor .ac-input {
            color-scheme: dark;
        }

    .ac-board-maker .ac-score-editor > .ac-btn {
        align-self: flex-end;
    }

@media (prefers-reduced-motion: no-preference) {
    .ac-board-maker .ac-score-editor {
        animation: ac-arrive 0.2s var(--ac-ease-out);
    }
}

/* ---- The panels ---- */

.ac-panel-lede {
    color: var(--ac-text-2);
    font-size: 0.9375rem;
    line-height: 1.5;
}

.ac-panel-stat {
    color: var(--ac-text-2);
    font-weight: 600;
}

    .ac-panel-stat strong {
        color: var(--ac-text);
        font-size: 1.125rem;
        font-weight: 800;
    }

/* A panel's own card: the task, the solver's position, the lesson's page */
.ac-panel-card {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    padding: 1rem 1.125rem;
    border: 1px solid var(--ac-line);
    border-radius: var(--ac-radius);
    background-color: var(--ac-surface);
}

    .ac-panel-card h2 {
        font-size: 1.25rem;
        font-weight: 800;
        letter-spacing: -0.02em;
        line-height: 1.2;
    }

    .ac-panel-card > p:not(.ac-panel-h) {
        color: var(--ac-text-2);
        font-size: 0.9375rem;
        line-height: 1.5;
    }

.ac-panel-section {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

    .ac-panel-section > .ac-panel-h {
        margin-bottom: 0 !important;
    }

.ac-panel-actions {
    display: flex;
    gap: 0.75rem;
}

    .ac-panel-actions .ac-btn {
        flex: 1;
    }

/* The puzzle's task: the stage it's at, in the card's top edge colour */
.ac-task {
    box-shadow: inset 0 3px 0 var(--task, var(--ac-line-strong));
}

.ac-task-turn { --task: var(--ac-go); }

.ac-how {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin: 0;
    padding-left: 1.25rem;
    color: var(--ac-text-2);
    font-size: 0.9375rem;
    line-height: 1.5;
}

    .ac-how li::marker {
        color: var(--ac-text-3);
        font-weight: 700;
    }

/* Off the replay's line (the solver): what happened and the way back */
.ac-off-line {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.625rem 1rem;
    padding: 0.75rem 0.875rem;
    border: 1px solid rgba(232, 164, 0, 0.4);
    border-radius: var(--ac-radius-sm);
    background-color: rgba(232, 164, 0, 0.1);
    color: var(--ac-text);
    font-size: 0.9375rem;
    font-weight: 600;
}

/* The solver's colours, explained */
.ac-bubble-key {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.25rem;
    margin: 0;
    padding: 0;
    color: var(--ac-text-2);
    font-size: 0.875rem;
    font-weight: 600;
    list-style: none;
}

    .ac-bubble-key li {
        display: flex;
        align-items: center;
        gap: 0.5rem;
    }

    .ac-bubble-key[hidden] {
        display: none;
    }

.ac-bubble-swatch {
    display: grid;
    place-items: center;
    width: 1.5rem;
    height: 1.5rem;
    border: 1.5px solid #fff;
    border-radius: 50%;
    background-color: var(--ac-yellow);
    color: #1f1600;
    font-size: 0.9375rem;
    font-weight: 800;
    letter-spacing: -0.03em;
}

.ac-bubble-best {
    background-color: var(--ac-go);
    color: var(--ac-go-ink);
}

/* An option: its name, a line on what it does, and its choices as a segmented control of real radio buttons */
.ac-option {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
}

    .ac-option + .ac-option {
        margin-top: 0.5rem;
    }

    .ac-option legend {
        float: none;
        margin: 0;
        padding: 0;
        color: var(--ac-text);
        font-size: 1rem;
        font-weight: 700;
    }

    .ac-option:disabled {
        opacity: 0.55;
    }

.ac-option-note {
    color: var(--ac-text-3);
    font-size: 0.875rem;
}

.ac-seg-radio {
    margin: 0.125rem 0 0;
}

    .ac-seg-radio .ac-seg-item {
        position: relative;
        padding: 0 0.5rem;
        text-align: center;
        cursor: pointer;
    }

    .ac-seg-radio input {
        position: absolute;
        inset: 0;
        margin: 0;
        opacity: 0;
        cursor: inherit;
    }

    .ac-seg-radio .ac-seg-item:has(input:checked) {
        background-color: var(--ac-raised);
        color: var(--ac-text) !important;
        box-shadow: inset 0 0 0 1px var(--ac-go), 0 2px 0 var(--ac-edge);
    }

    .ac-seg-radio .ac-seg-item:has(input:focus-visible) {
        outline: 2px solid var(--ac-go);
        outline-offset: -2px;
    }

    .ac-option:disabled .ac-seg-item {
        cursor: default;
    }

/* The tricks so far on the game, replay and exercise pages: rows that aren't buttons, with who took each */
.ac-trick-row-static {
    cursor: default;
}

    .ac-trick-row-static[aria-current] .ac-trick-num {
        background-color: var(--ac-go);
        color: var(--ac-go-ink);
    }

    .ac-trick-row-static[aria-current] {
        background-color: rgba(107, 214, 43, 0.1);
    }

.ac-trick-winner {
    padding: 0.125rem 0.5rem;
    border-radius: 999px;
    background-color: var(--ac-raised);
    color: var(--ac-text-2);
    font-size: 0.75rem;
    font-weight: 800;
    letter-spacing: 0.02em;
}

.ac-trick-winner-us {
    background-color: rgba(107, 214, 43, 0.14);
    color: var(--ac-go);
}

.ac-trick-empty {
    padding: 1rem 1.125rem;
    border: 1px dashed var(--ac-line-strong);
    border-radius: var(--ac-radius);
    color: var(--ac-text-3);
    font-size: 0.9375rem;
}

/* The last trick on the games, the nil exercises and puzzles (panel.tsx's LastTrickSection; owner, 2026-10-08): the
   trick as it lay on the table, North at the top and West at the left, the cards a diamond as in the trick on the
   felt. The leader's card is ringed in Play Green and marked "Led"; the winner's stands out white and a little
   larger, the others' a shade greyer, with the Us / Them pill. The box keeps one height, empty or not, so the panel
   doesn't move when the first trick ends. */
.ac-last-trick {
    --card-w: 3.125rem;
    --card-h: 4.25rem;
    --tag-h: 1.375rem;
    --cell: calc(var(--card-h) + 0.3125rem + var(--tag-h));
    --box-h: calc(2 * var(--cell) + 0.25rem + 2rem);
    display: flex;
    flex-direction: column;
}

.ac-last-trick-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.5rem;
}

    .ac-last-trick-head .ac-panel-h {
        margin-bottom: 0 !important;
    }

.ac-last-trick-num {
    color: var(--ac-text-3);
    font-size: 0.8125rem;
    font-weight: 600;
    line-height: 1.2;
}

    .ac-last-trick-num strong {
        color: var(--ac-text);
        font-weight: 800;
    }

.ac-last-trick-empty {
    display: grid;
    place-items: center;
    height: var(--box-h);
    padding: 1rem 1.125rem;
    border: 1px dashed var(--ac-line-strong);
    border-radius: var(--ac-radius);
    color: var(--ac-text-3);
    font-size: 0.9375rem;
    text-align: center;
}

/* Four rows of half a seat each: North over the first two, West and East over the middle two, South the last two */
.ac-last-trick-compass {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    grid-template-rows: repeat(4, calc(var(--cell) / 2));
    align-content: center;
    gap: 0.0625rem 1.125rem;
    height: var(--box-h);
    margin: 0;
    padding: 1rem;
    border: 1px solid var(--ac-line);
    border-radius: var(--ac-radius);
    background-color: var(--ac-surface);
    list-style: none;
}

.ac-last-trick-seat {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.3125rem;
    min-width: 0;
}

.ac-last-trick-north { grid-row: 1 / span 2; grid-column: 2; }
.ac-last-trick-west { grid-row: 2 / span 2; grid-column: 1; justify-self: end; }
.ac-last-trick-east { grid-row: 2 / span 2; grid-column: 3; justify-self: start; }
.ac-last-trick-south { grid-row: 3 / span 2; grid-column: 2; }

    .ac-last-trick-seat .ac-mini-card {
        flex-direction: column;
        justify-content: center;
        gap: 0.25rem;
        width: var(--card-w);
        min-width: 0;
        height: var(--card-h);
        padding: 0;
        border-radius: 6px;
        background-color: #d5d9df;
        box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
        font-size: 1.3125rem;
    }

        .ac-last-trick-seat .ac-mini-card svg {
            width: 1.25rem;
            height: 1.25rem;
        }

    .ac-last-trick-won .ac-mini-card {
        background-color: #fff;
        box-shadow: 0 0.375rem 1rem rgba(0, 0, 0, 0.5);
        transform: scale(1.08);
    }

    .ac-last-trick-led .ac-mini-card {
        box-shadow: 0 0 0 2px var(--ac-surface), 0 0 0 4px var(--ac-go), 0 2px 6px rgba(0, 0, 0, 0.35);
    }

    .ac-last-trick-led.ac-last-trick-won .ac-mini-card {
        box-shadow: 0 0 0 2px var(--ac-surface), 0 0 0 4px var(--ac-go), 0 0.375rem 1rem rgba(0, 0, 0, 0.5);
    }

.ac-last-trick-tags {
    display: flex;
    gap: 0.25rem;
    height: var(--tag-h);
    align-items: center;
}

.ac-last-trick-tag {
    padding: 0.125rem 0.5rem;
    color: var(--ac-go);
    font-size: 0.75rem;
    font-weight: 800;
    letter-spacing: 0.02em;
}

/* The nil exercises' scoring */
.ac-outcomes {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 0.9375rem;
    line-height: 1.45;
}

    .ac-outcomes li {
        display: grid;
        grid-template-columns: 3.5rem minmax(0, 1fr);
        align-items: baseline;
        gap: 0.75rem;
        color: var(--ac-text-2);
    }

.ac-outcome {
    justify-self: start;
    padding: 0.0625rem 0.5rem;
    border-radius: 999px;
    font-size: 0.8125rem;
    font-weight: 800;
}

.ac-outcome-win { background-color: rgba(107, 214, 43, 0.14); color: var(--ac-go); }
.ac-outcome-draw { background-color: var(--ac-raised); color: var(--ac-text); }
.ac-outcome-loss { background-color: var(--ac-bad-wash); color: var(--ac-bad); }

/* The lesson's page of text, how far through, and Back / Next */
.ac-lesson-card {
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
    padding: 1.125rem 1.25rem;
    border: 1px solid var(--ac-line);
    border-radius: var(--ac-radius);
    background-color: var(--ac-surface);
}

/* At the end it takes the focus from its buttons (lesson.tsx); it isn't a control, so no ring */
.ac-lesson-card:focus {
    outline: none;
}

.ac-lesson-progress {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    color: var(--ac-text-3);
    font-size: 0.8125rem;
    font-weight: 700;
    white-space: nowrap;
}

.ac-lesson-meter {
    flex: 1;
    height: 0.375rem;
    overflow: hidden;
    border-radius: 999px;
    background-color: var(--ac-bg);
}

    .ac-lesson-meter > span {
        display: block;
        height: 100%;
        border-radius: inherit;
        background-color: var(--ac-go);
        transition: width 0.4s var(--ac-ease-out);
    }

.ac-lesson-text {
    margin: 0;
    color: var(--ac-text);
    font-size: 1.0625rem;
    line-height: 1.6;
}

.ac-lesson-text-waiting {
    color: var(--ac-text-3);
}

.ac-lesson-status {
    color: var(--ac-text-2);
    font-size: 0.875rem;
    font-weight: 700;
}

.ac-lesson-status-quiz {
    color: var(--ac-go);
}

.ac-lesson-buttons {
    display: flex;
    gap: 0.75rem;
}

    .ac-lesson-buttons .ac-btn {
        flex: 1;
        padding-inline: 0.75rem;
    }

/* The text read so far (all of it is on the page for search engines; what's ahead stays hidden) */
.ac-lesson-read #indexable-lesson-text p {
    margin: 0 0 0.75rem;
    padding: 0;
    background: none;
    color: var(--ac-text-2);
    font-size: 0.9375rem;
    line-height: 1.6;
}

/* The calculators: the help folded away, the hand's count, the results */
.ac-help {
    border: 1px solid var(--ac-line);
    border-radius: var(--ac-radius-sm);
    background-color: var(--ac-surface);
}

    .ac-help summary {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 0.75rem;
        padding: 0.75rem 1rem;
        border-radius: inherit;
        font-weight: 700;
        cursor: pointer;
        list-style: none;
    }

        .ac-help summary::-webkit-details-marker {
            display: none;
        }

        .ac-help summary::after {
            content: "";
            flex: none;
            width: 0.5rem;
            height: 0.5rem;
            border-right: 2px solid currentColor;
            border-bottom: 2px solid currentColor;
            transform: rotate(45deg) translateY(-25%);
            transition: transform 0.2s var(--ac-ease-out);
        }

    .ac-help[open] summary::after {
        transform: rotate(-135deg) translateY(-25%);
    }

        .ac-help summary:focus-visible {
            outline: 2px solid var(--ac-go);
            outline-offset: -2px;
        }

.ac-help-body {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0 1rem 1rem;
    color: var(--ac-text-2);
    font-size: 0.9375rem;
    line-height: 1.5;
}

    .ac-help-body h3 {
        margin-top: 0.5rem !important;
        color: var(--ac-text);
        font-size: 0.9375rem;
        font-weight: 700;
    }

    .ac-help-body ol {
        display: flex;
        flex-direction: column;
        gap: 0.375rem;
        margin: 0;
        padding-left: 1.25rem;
    }

.ac-stat-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.5rem;
    margin: 0;
}

    .ac-stat-grid > div {
        display: flex;
        flex-direction: column;
        gap: 0.125rem;
        padding: 0.75rem 0.875rem;
        border: 1px solid var(--ac-line);
        border-radius: var(--ac-radius-sm);
        background-color: var(--ac-surface);
    }

    .ac-stat-grid dt {
        color: var(--ac-text-3);
        font-size: 0.8125rem;
        font-weight: 700;
    }

    .ac-stat-grid dd {
        margin: 0;
        font-size: 1.5rem;
        font-weight: 800;
        letter-spacing: -0.02em;
        line-height: 1.15;
    }

    .ac-stat-grid .ac-stat-word {
        font-size: 1.125rem;
        line-height: 1.5;
    }

    .ac-stat-grid .ac-stat-best {
        border-color: var(--ac-go-line);
        background-color: var(--ac-go-wash);
    }

        .ac-stat-grid .ac-stat-best dd {
            color: var(--ac-go);
        }

.ac-data-table-wrap {
    overflow: hidden;
    border: 1px solid var(--ac-line);
    border-radius: var(--ac-radius-sm);
}

.ac-calc-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9375rem;
    font-variant-numeric: tabular-nums;
}

    .ac-calc-table th,
    .ac-calc-table td {
        padding: 0.4375rem 0.75rem;
        text-align: right;
    }

    .ac-calc-table thead th {
        background-color: var(--ac-raised);
        color: var(--ac-text-2);
        font-size: 0.8125rem;
        font-weight: 700;
    }

    .ac-calc-table tbody th {
        color: var(--ac-text);
        font-weight: 800;
        text-align: center;
    }

    .ac-calc-table thead th:first-child {
        text-align: center;
    }

    .ac-calc-table td {
        color: var(--ac-text-2);
        font-weight: 600;
    }

    .ac-calc-table tbody tr + tr {
        border-top: 1px solid var(--ac-line);
    }

    .ac-calc-table .ac-calc-best {
        background-color: var(--ac-go-wash);
    }

        .ac-calc-table .ac-calc-best :is(th, td) {
            color: var(--ac-go);
            font-weight: 800;
        }

/* Replay Analysis' numbers behind the feedback's suit (admins only, under the feedback): the calculators' table, smaller
 * so five columns fit the grade card, scrolling sideways if they don't */
.ac-suit-tricks .ac-data-table-wrap {
    overflow-x: auto;
}

.ac-suit-tricks .ac-calc-table {
    font-size: 0.8125rem;
}

    .ac-suit-tricks .ac-calc-table :is(th, td) {
        padding: 0.3125rem 0.5rem;
    }

    .ac-suit-tricks .ac-calc-table td {
        white-space: nowrap;
    }

/* Replay Analysis' research view (admins only, under the suit tricks): the two lines' tables side by side where there's
 * room, one over the other in the grade card; small type, each table scrolling sideways if it must */
.ac-explanation .ac-help-body {
    font-size: 0.8125rem;
}

.ac-explanation-hands {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
    gap: 0.25rem 1rem;
    margin: 0;
    padding: 0;
    list-style: none;
    font-variant-numeric: tabular-nums;
}

    .ac-explanation-hands li {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        white-space: nowrap;
    }

    .ac-explanation-hands b {
        width: 1rem;
        color: var(--ac-text);
    }

    .ac-explanation-hands li > span {
        display: inline-flex;
        align-items: center;
        gap: 0.125rem;
    }

.ac-explanation-pbn code {
    color: var(--ac-text-3);
    font-size: 0.75rem;
    word-break: break-all;
}

.ac-explanation-lines {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

    .ac-explanation-lines > .ac-data-table-wrap {
        flex: 1 1 22rem;
        min-width: 0;
        overflow-x: auto;
    }

.ac-ledger {
    font-size: 0.75rem;
}

    .ac-ledger caption {
        caption-side: top;
        padding: 0.375rem 0.5rem;
        color: var(--ac-text);
        font-weight: 700;
        text-align: left;
    }

    .ac-ledger :is(th, td) {
        padding: 0.25rem 0.375rem;
        white-space: nowrap;
    }

    /* A trick that sets a live nil (nil-lines plan A14); a pivot row keeps the pivot's look */
    .ac-ledger tr.ac-ledger-nil-set {
        background-color: var(--ac-bad-wash);
    }

    .ac-ledger tr.ac-ledger-pivot {
        background-color: var(--ac-go-wash);
        box-shadow: inset 3px 0 0 var(--ac-go);
    }

    .ac-ledger sup {
        margin-left: 0.0625rem;
        color: var(--ac-text-3);
        font-size: 0.625rem;
        font-weight: 600;
    }

.ac-ledger-card {
    display: inline-flex;
    align-items: center;
    color: var(--ac-text-2);
}

    .ac-ledger-card svg,
    .ac-explanation-hands svg {
        width: 0.75rem;
        height: 0.75rem;
        fill: var(--suit, var(--ac-text));
    }

/* The red suits' shapes (the ranks stay the text's colour) */
.ac-ledger-hearts,
.ac-ledger-diamonds {
    --suit: var(--ac-red);
}

.ac-ledger-won {
    color: var(--ac-text);
    font-weight: 800;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.ac-ledger-before {
    opacity: 0.5;
}

/* The motif tagger's proposals under the voids (admins, objective best moves only: auto-tagger plan phase 0): each tag a
 * pill with its share, weak ones dimmed and dashed; a chip is a button where the label box is (it adds the tag), and the
 * draft one-liner with Use draft */
.ac-explanation-motifs {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin: 0;
}

.ac-motif-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ac-motif-chip {
    display: inline-flex;
    align-items: baseline;
    gap: 0.3125rem;
    padding: 0.125rem 0.5rem;
    border: 1px solid var(--ac-line-strong);
    border-radius: 999px;
    background-color: var(--ac-raised);
    color: var(--ac-text);
    font: inherit;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    white-space: nowrap;
}

    button.ac-motif-chip {
        cursor: pointer;
    }

        button.ac-motif-chip:hover {
            background-color: var(--ac-raised-hover);
        }

    .ac-motif-chip :is(.ac-motif-share, .ac-motif-side, .ac-motif-probed) {
        color: var(--ac-text-3);
        font-weight: 600;
        font-variant-numeric: tabular-nums;
    }

    .ac-motif-chip .ac-motif-probed {
        font-style: italic;
    }

.ac-motif-weak {
    border-style: dashed;
    color: var(--ac-text-3);
    opacity: 0.75;
}

.ac-explanation-draft {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.375rem 0.75rem;
    margin: 0;
    color: var(--ac-text-2);
}

/* The motif sentence the feedback line says (motif-feedback plan A15), under the chips: the sentence, then its tag, side and
 * certain/hedged in the chips' muted small type; hedged in italics */
.ac-explanation-generated {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.25rem 0.625rem;
    margin: 0;
    color: var(--ac-text-2);
}

    .ac-explanation-generated-note {
        color: var(--ac-text-3);
        font-size: 0.75rem;
        font-weight: 600;
        letter-spacing: 0.02em;
        white-space: nowrap;
    }

    .ac-explanation-generated-hedged {
        font-style: italic;
    }

/* The research view's label box (admins, dev server only: move-explanations plan phase 3), under the voids, and the
 * way on to the next trick to label (also alone in the grade card when there's no research view) */
.ac-explanation-label {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    margin-top: 0.25rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--ac-line);
}

    .ac-explanation-label h3 {
        margin: 0 !important;
        font-size: 0.875rem;
    }

    .ac-explanation-label .ac-field label {
        font-size: 0.8125rem;
    }

    .ac-explanation-label textarea {
        resize: vertical;
    }

    .ac-explanation-label p {
        margin: 0;
    }

.ac-explanation-next {
    margin: 0;
    font-size: 0.8125rem;
}

    .ac-explanation-next a {
        color: var(--ac-go);
        font-weight: 600;
    }

/* The auto-tagger's bulk run over the queue (admins, dev server only: auto-tagger plan phase 3), at the foot of the label
 * box: where it is, its counts, the failures folded, Run the queue with its redo option, or Stop */
.ac-explanation-bulk {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    padding-top: 0.5rem;
    border-top: 1px dashed var(--ac-line);
    font-size: 0.8125rem;
}

    .ac-explanation-bulk .ac-panel-actions {
        flex-wrap: wrap;
        align-items: center;
        gap: 0.5rem 0.875rem;
    }

    .ac-explanation-bulk .ac-check {
        font-size: 0.8125rem;
    }

    .ac-explanation-bulk details summary {
        color: var(--ac-text-2);
        cursor: pointer;
    }

    .ac-explanation-bulk details ul {
        margin: 0.25rem 0 0;
        padding-left: 1.125rem;
        color: var(--ac-text-2);
        overflow-wrap: anywhere;
    }

/* Next to label's tag picker (auto-tagger plan phase 5), before the line it narrows */
.ac-explanation-tag-pick {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem 0.625rem;
    margin: 0;
    font-size: 0.8125rem;
}

    .ac-explanation-tag-pick select {
        width: auto;
        max-width: 100%;
    }

/* The tag report (auto-tagger plan phase 5), folded at the foot of the label box: a row a tag, the owner's own tags in
 * italics, then the labelled positions where the owner's tags and the proposals differ */
.ac-explanation-report {
    padding-top: 0.5rem;
    border-top: 1px dashed var(--ac-line);
    font-size: 0.8125rem;
}

    .ac-explanation-report summary {
        color: var(--ac-text-2);
        cursor: pointer;
    }

    .ac-explanation-report > * + * {
        margin-top: 0.5rem;
    }

    .ac-explanation-report .ac-data-table-wrap {
        overflow-x: auto;
    }

.ac-report-table {
    font-size: 0.75rem;
}

    .ac-report-table :is(th, td) {
        padding: 0.25rem 0.5rem;
        white-space: nowrap;
    }

    .ac-report-table tbody th {
        text-align: left;
    }

    .ac-report-table .ac-report-own th {
        font-style: italic;
        font-weight: 600;
    }

    .ac-report-table a {
        color: var(--ac-go);
        font-weight: 600;
    }

.ac-report-differences {
    margin: 0;
    padding-left: 1.125rem;
    color: var(--ac-text-2);
    overflow-wrap: anywhere;
}

    .ac-report-differences ul {
        margin: 0.125rem 0 0.25rem;
        padding-left: 1.125rem;
    }

    .ac-report-differences b {
        color: var(--ac-text);
    }

    .ac-report-differences a {
        color: var(--ac-go);
        font-weight: 600;
    }

/* The report's mistakes found, folded under the differences (docs/motif-feedback-plan.md A18) */
.ac-explanation-report-mistakes > * + * {
    margin-top: 0.375rem;
}

/* ---- The phone bars of the lessons, puzzles and calculators ---- */

@media (max-width: 899.98px), (orientation: landscape) and (max-height: 500px) {
    /* The lesson's page sits in the bar (owner, 2026-10-07): the panel's copy gives way to it */
    .ac-board-panel > .ac-lesson-card {
        display: none;
    }

    /* Room for three lines of text over the buttons */
    .ac-board-lesson {
        --bar-h: calc(11rem + env(safe-area-inset-bottom));
    }

    /* The bar keeps one height whatever the page's length (upright, the height the table's room leaves for it, below;
       sideways, the rail's), so the table never moves or hides under it: the text takes what's left after the count,
       the status line and the buttons, and scrolls */
    .ac-board-bar .ac-lesson-card-compact {
        height: 100%;
        gap: 0.5rem;
        padding: 0;
        border: 0;
        background: none;
    }

        .ac-lesson-card-compact > :not(.ac-lesson-text) {
            flex: none;
        }

        .ac-lesson-card-compact .ac-lesson-text {
            flex: 1 1 0;
            min-height: 0;
            overflow-y: auto;
            overscroll-behavior: contain;
            font-size: 1rem;
            line-height: 1.6;
        }

        .ac-lesson-card-compact .ac-lesson-status {
            font-size: 0.8125rem;
        }

        /* Side by side while both fit (each its own width), else one over the other: the end's "Back to Lessons"
           and "Next Module" in the sideways rail and on a 320px phone */
        .ac-lesson-card-compact .ac-lesson-buttons {
            flex-wrap: wrap;
        }

            .ac-lesson-card-compact .ac-lesson-buttons .ac-btn {
                flex: 1 1 auto;
                min-height: 2.625rem;
            }

    /* The calculators' and the puzzle's bars: a count or a stage, then the buttons */
    .ac-bar-actions .ac-step-buttons .ac-btn:not(.ac-btn-icon-only) {
        min-height: 2.625rem;
        padding-inline: 1rem;
    }

    .ac-bar-task .ac-step-count {
        min-width: 0;
        overflow: hidden;
        color: var(--ac-text);
        font-weight: 700;
        text-overflow: ellipsis;
    }
}

/* Held sideways, the lesson's bar is a column beside the table, wide enough to read in */
@media (max-width: 899.98px) and (orientation: landscape), (orientation: landscape) and (max-height: 500px) {
    .ac-board-lesson .ac-board-bar {
        width: clamp(14rem, 36vw, 19rem);
        overflow-y: auto;
    }

    .ac-bar-actions .ac-step-buttons {
        flex-direction: column;
    }

    .ac-bar-task .ac-step-count {
        max-width: 5rem;
        white-space: normal;
        text-align: center;
    }
}

/* Upright, the lesson's bar is the height the table's room leaves for it */
@media (max-width: 899.98px) and (orientation: portrait) {
    .ac-board-lesson .ac-board-bar {
        height: var(--bar-h);
    }
}

/* The lesson's text fades out at the bottom while there's more of it below (where scroll-driven animations work;
   elsewhere it simply scrolls) */
@property --ac-more-fade {
    syntax: "<length>";
    inherits: false;
    initial-value: 0px;
}

@keyframes ac-more-below {
    from { --ac-more-fade: 1.6em; }
    to { --ac-more-fade: 0px; }
}

@supports (animation-timeline: scroll()) {
    @media (max-width: 899.98px), (orientation: landscape) and (max-height: 500px) {
        .ac-lesson-card-compact .ac-lesson-text {
            -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - var(--ac-more-fade)), transparent);
            mask-image: linear-gradient(to bottom, #000 calc(100% - var(--ac-more-fade)), transparent);
            animation: ac-more-below linear both;
            animation-timeline: scroll(self);
        }
    }
}

    .ac-trick-row-static:hover:not([aria-current]) {
        background: none !important;
    }

/* The message boxes drop in, as the older boards' did */
@media (prefers-reduced-motion: no-preference) {
    .ac-stage .fade-in-and-down:not(.hidden) {
        animation: fade-in-and-down 0.45s var(--ac-ease-out) both;
    }
}

/* The calculators' hand count above Calculate */
.ac-panel-actions:has(.ac-hand-count) {
    flex-direction: column;
    gap: 0.5rem;
}

    .ac-panel-actions .ac-hand-count {
        font-size: 0.9375rem;
    }

/* A small heading inside a panel card (the nil exercises' scoring) */
.ac-panel-card h2.ac-panel-h {
    margin: 0.25rem 0 0 !important;
    font-size: 0.875rem;
    font-weight: 700;
    letter-spacing: 0;
}

/* On a phone the calculators' bar has the count, Edit Hand and Calculate (or Reset): the panel's copy gives way */
@media (max-width: 899.98px), (orientation: landscape) and (max-height: 500px) {
    .ac-board-calculator .ac-board-panel > .ac-panel-actions {
        display: none;
    }
}

/* A phone-sized table's score stays clear of North's hand down to a 320px phone */
@container (max-width: 380px) {
    .ac-scoreboard {
        top: 6px;
        right: 6px;
        padding: 4px 7px;
        font-size: 11px;
    }
}

/* The Replay Maker's deal in the panel: each seat's count beside the others, a full hand's in the good-news wash */
.ac-maker-counts {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

    .ac-maker-counts > div {
        padding: 0.5rem;
    }

    .ac-maker-counts dd {
        font-size: 1.25rem;
        white-space: nowrap;
    }

    .ac-maker-counts .ac-maker-count-of {
        color: var(--ac-text-3);
        font-size: 0.875rem;
        font-weight: 700;
        letter-spacing: 0;
    }

/* Random deal (Back to the deal once a card is played) across the deal section */
.ac-maker-actions {
    flex-wrap: wrap;
}

    .ac-maker-actions .ac-btn {
        flex: 1 1 auto;
    }

/* Its scores before the hand, side by side */
.ac-maker-scores {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem;
}

    .ac-maker-scores .ac-input {
        color-scheme: dark;
    }

/* Its replay's options, a checkbox a line */
.ac-maker-options {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
}

/* Whom the replay is seen from, and Rotate at the end of the line (phase 11) */
.ac-maker-seen {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem 0.75rem;
}

    .ac-maker-seen .ac-panel-stat {
        margin: 0;
    }

/* Start from a replay (phase 12): the replay's number or link, Load at the end of the line (wide enough for "Loading…"
   and its ring, so the field holds still), and what isn't a replay in the bad-news ink under them */
.ac-maker-load {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

    .ac-maker-load .ac-input {
        flex: 1 1 auto;
        min-width: 0;
    }

    .ac-maker-load .ac-btn {
        flex: none;
        min-width: 7.5rem;
    }

.ac-maker-load-error {
    margin: 0;
    color: var(--ac-bad);
    font-size: 0.875rem;
    font-weight: 600;
}

/* The Admin Lesson Maker (docs/admin-lesson-maker-plan.md): the Replay Maker's frame and pills, whose bids are read
   only (they're the lesson's steps); in the panel the address and data file its details make, its pages listed as
   Replay Analysis' tricks are (the selected one opened under its row: its text, or its steps listed the same way), and
   the export's snippets in a code face */
.ac-stage .ac-seat-bid select:disabled {
    cursor: default;
    opacity: 1;
}

.ac-lesson-maker-paths {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    margin: 0;
    font-size: 0.875rem;
}

    .ac-lesson-maker-paths > div {
        display: flex;
        gap: 0.5rem;
        min-width: 0;
    }

    .ac-lesson-maker-paths dt {
        flex: none;
        width: 5.5rem;
        color: var(--ac-text-3);
        font-weight: 600;
    }

    .ac-lesson-maker-paths dd {
        margin: 0;
        min-width: 0;
        color: var(--ac-text);
        font-family: var(--bs-font-monospace, monospace);
        overflow-wrap: anywhere;
    }

textarea.ac-input.ac-lesson-maker-short {
    min-height: 4.5rem;
}

.ac-lesson-maker-page-summary {
    display: flex;
    flex-direction: column;
    min-width: 0;
    font-size: 0.875rem;
}

    .ac-lesson-maker-page-summary > span {
        overflow: hidden;
        color: var(--ac-text-2);
        text-overflow: ellipsis;
        white-space: nowrap;
    }

.ac-lesson-maker-page {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.25rem 0.875rem 0.75rem;
}

.ac-trick-list ol.ac-lesson-maker-steps {
    border-radius: var(--ac-radius-sm);
    background-color: var(--ac-bg);
}

    .ac-lesson-maker-steps .ac-trick-row {
        min-height: 2.25rem;
        font-size: 0.8125rem;
    }

    .ac-lesson-maker-step {
        overflow-wrap: anywhere;
    }

/* The selected step's form under its row (phase 3); four fields a seat's (or a suit's) side by side */
.ac-lesson-maker-step-form {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.5rem 0.875rem 0.75rem;
    border-top: 1px solid var(--ac-line);
}

.ac-lesson-maker-seats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.5rem;
}

    .ac-lesson-maker-step-form .ac-input {
        color-scheme: dark;
    }

/* Phase 5: Edit / Preview under the panel's title (the sign-in page's two-way switch), and a quiz's cards, the options
   ringed as the switch's choice is */
.ac-lesson-maker-mode {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

    .ac-lesson-maker-mode .ac-seg {
        flex: 1 1 10rem;
        margin: 0;
    }

    .ac-lesson-maker-mode .ac-seg-item {
        min-height: 2.25rem;
    }

.ac-field .ac-lesson-maker-label {
    color: var(--ac-text);
    font-size: 0.9375rem;
    font-weight: 600;
}

.ac-lesson-maker-quiz-cards .ac-btn[aria-pressed="true"] {
    background-color: var(--ac-raised);
    box-shadow: inset 0 0 0 1px var(--ac-go), 0 2px 0 var(--ac-edge);
}

textarea.ac-input.ac-lesson-maker-snippet {
    min-height: 0;
    font-family: var(--bs-font-monospace, monospace);
    font-size: 0.75rem;
    white-space: pre;
    overflow-x: auto;
    resize: none;
}

/* The Replay Maker's panel is a drawer on small screens (BoardFrame's collapsiblePanel) and it has a phone bar too, the
   only board with both: the bar keeps its place along the bottom (held sideways, the rail down the right edge), and the
   table and the drawer take the room beside it. The bar shows only where the drawer does (its sizes are within
   BoardFrame's SMALL_SCREEN), and it takes the safe area, so the drawer's strip doesn't. */
@media (max-width: 899.98px) and (orientation: portrait) {
    .ac-board-drawer.ac-board-has-bar {
        --drawer-strip: var(--drawer-tab);
    }

        .ac-board-drawer.ac-board-has-bar > .ac-board-table {
            height: calc(100% - var(--drawer-strip) - var(--bar-h));
        }

        .ac-board-drawer.ac-board-has-bar > .ac-drawer {
            bottom: var(--bar-h);
            height: calc(100% - var(--bar-h) - 0.2 * (100% - var(--bar-h) - var(--drawer-strip)));
        }

        /* Over the collapsed drawer's hidden part */
        .ac-board-drawer > .ac-board-bar {
            position: absolute;
            inset: auto 0 0;
            z-index: 45;
            box-sizing: border-box;
            height: var(--bar-h);
            margin: 0;
        }
}

@media (max-width: 899.98px) and (orientation: landscape), (orientation: landscape) and (max-height: 500px) {
    .ac-board-drawer.ac-board-has-bar {
        --drawer-strip: var(--drawer-tab);
        --rail-w: 7rem;
    }

        .ac-board-drawer.ac-board-has-bar > .ac-board-table {
            width: calc(100% - var(--drawer-strip) - var(--rail-w));
        }

        .ac-board-drawer.ac-board-has-bar > .ac-drawer {
            right: var(--rail-w);
            width: calc(100% - var(--rail-w) - 0.2 * (100% - var(--rail-w) - var(--drawer-strip)));
        }

        /* The whole height, its Bar fill over the collapsed drawer's hidden part (the rail's own rule, above, starts it
           at the top, and a box placed so takes only its contents' height unless stretched) */
        .ac-board-drawer > .ac-board-bar {
            position: absolute;
            inset: 0 0 0 auto;
            z-index: 45;
            align-self: stretch;
            box-sizing: border-box;
            width: var(--rail-w);
            height: 100%;
            margin: 0;
        }

            /* A long label wraps in the rail ("Random deal"); Undo as wide as Create under it */
            .ac-board-maker .ac-board-bar .ac-step-buttons .ac-btn {
                padding-inline: 0.5rem;
                white-space: normal;
            }

            .ac-board-maker .ac-board-bar .ac-step-buttons .ac-btn-icon-only {
                width: auto;
            }
}
