/* Replay viewer controls.
 *
 * The transport used to be a small draggable bar pinned over the top of the screen, which it had
 * to be: it was floating over a live-looking board with nowhere of its own to sit, so it covered
 * something wherever it landed and the viewer was left to drag it out of the way.
 *
 * Both games already have a region that is guaranteed EMPTY while a replay is playing -- the space
 * a live game fills with your pending choice. A replay never asks the watcher for anything, so
 * that space is free for the whole session:
 *
 *   Dominion  #gameOptions      the select-option box (desktop only -- mobile hides it and
 *                               renders prompts in its own overlay, so mobile keeps the bar)
 *   Monopoly  #mPromptPanel     the centre panel, below the round line
 *
 * Docked there the controls overlap nothing, never move, and stop being something to manage.
 * .replayFloat is the unchanged fallback for anywhere without a host (mobile Dominion).
 */

/* --- Docked ------------------------------------------------------------------------------- */

#replayControls.replayDock {
    /* Fills whichever box hosts it, so the layout follows the host rather than fixed sizes --
     * #gameOptions is 275x275 but the tablet/dynamic stylesheets give it other shapes. */
    position: static;
    width: 100%;
    /* height fills a plain block host (#gameOptions); the flex pair is for Monopoly's centre
     * panel, where the round line above us is a sibling -- shrinking to the space that is left
     * keeps this box out from behind it instead of spanning the whole panel. */
    height: 100%;
    flex: 1 1 auto;
    min-height: 0;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    padding: 2px 4px;
    /* The host may be laid out for prompt text; the panel sets its own scale. */
    font-size: 13px;
    line-height: 1.2;
    text-align: center;
    white-space: normal;
    cursor: default;
    /* Last resort only. Nothing here shrinks (see flex: 0 0 auto below), so if a host is ever
     * too small for the panel the transport stays reachable by scrolling rather than being
     * clipped at both ends by the centring. */
    overflow-y: auto;
    overflow-x: hidden;
}

/* NOT ".replayRow" -- that class already belongs to the replay BROWSER's list rows
 * (Dialog.Expanded.css), whose 14px padding, 10px margin and 20px font silently inflated these
 * rows to 54px for a 24px button and pushed the caption out of the panel. */
#replayControls.replayDock .replayStepRow {
    display: flex;
    gap: 3px;
    align-items: center;
    justify-content: center;
    /* Nothing in the column may be squeezed: as a flex item the caption would otherwise shrink
     * to zero height the moment the content came close to filling the host. */
    flex: 0 0 auto;
}

/* Transport buttons share the row evenly and shrink rather than wrap: four per row is the
 * layout, at any host width. */
#replayControls.replayDock .replayStepRow input[type="button"] {
    flex: 1 1 0;
    min-width: 0;
    /* Sized for a comfortable click rather than the minimum that fits: both hosts have vertical
     * room to spare (Dominion's box is 275px square for ~130px of controls). Still small enough
     * that the tightest host, Monopoly's centre panel, does not need to scroll. */
    padding: 5px 2px;
    font-size: 13px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Play/Pause is the one control here you press repeatedly, so it leads the row and is allowed
 * to be the widest thing on it. */
#replayControls.replayDock .replayPlayButton {
    font-weight: 600;
    min-width: 5.5em;
}

/* The seat picker and the two whole-session buttons (Scores / Exit) are not transport steps,
 * so they get their own row and do not stretch to match it. */
#replayControls.replayDock .replayMetaRow {
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 2px;
}

#replayControls.replayDock .replayMetaRow input[type="button"],
#replayControls.replayDock .replayMetaRow select {
    flex: 0 1 auto;
    font-size: 13px;
    padding: 4px 8px;
    max-width: 100%;
}

/* #mPromptPanel is pointer-events:none so the pre-game board stays reachable behind it, and
 * re-enables only its own inputs -- the seat <select> needs the same. */
#replayControls.replayDock select,
#replayControls.replayDock input {
    pointer-events: auto;
}

/* The recording's short code. Boxed and monospaced like the same code in the lobby list, so the
 * two read as the same thing. user-select:all makes one click select the WHOLE code rather than a
 * character of it -- the point of showing it here is to get it into a chat message. */
#replayControls .replayUidChip {
    flex: 0 0 auto;
    align-self: center;
    font-family: "Courier New", monospace;
    font-weight: bold;
    font-size: 13px;
    letter-spacing: 0.14em;
    padding: 1px 7px;
    border: 1px solid rgba(128, 128, 128, 0.55);
    border-radius: 4px;
    white-space: nowrap;
    cursor: text;
    user-select: all;
    -webkit-user-select: all;
}

/* Code + caption on one row. The caption's height is FIXED at two lines (see .replayCaption below)
 * and one line is what it normally uses, so putting the code beside it spends space that was
 * already reserved -- on its own row it cost Monopoly's 218px panel 12px it does not have. */
#replayControls .replayCaptionRow {
    display: flex;
    align-items: flex-start;
    justify-content: center;
    gap: 5px;
    flex: 0 0 auto;
    min-width: 0;
    max-width: 100%;
}

/* min-width:0 again, on the caption itself: as a flex item its default min-width:auto would floor
 * it at its content width and push the code out of the row on a long step description. */
#replayControls.replayDock .replayCaptionRow .replayCaption {
    flex: 1 1 auto;
    min-width: 0;
}

/* The floating bar puts the caption at the FAR END of the strip (order: 2). That order now belongs
 * to the row, not the caption -- a caption nested inside a wrapper is no longer a flex item of the
 * bar, so the rule below would be ignored and the pair would jump to the front of the buttons. */
#replayControls.replayFloat .replayCaptionRow {
    order: 2;
    align-items: center;
    margin-left: 10px;
}

#replayControls.replayDock .replayCaption {
    display: block;
    flex: 0 0 auto;
    max-width: 100%;
    font-size: 12px;
    opacity: 0.85;
    /* A FIXED two lines, not max-height. The caption is rewritten on every step and is the one
     * part whose length is not ours to control (card and player names), so letting it size to
     * its content moved every button 13-17px down the moment it wrapped to a second line --
     * under the cursor of someone stepping through a game. Reserving both lines up front means
     * the transport never moves, which is the whole point of docking it. */
    height: 2.6em;
    overflow: hidden;
    white-space: normal;
    word-break: break-word;
}

/* Monopoly pins its round line ("ROUND 3 - Carol's turn") to the top of the prompt panel with
 * position:absolute, so it occupies NO space in the flex flow and the transport lays out
 * underneath it. Reserve its height (40px + its 8px margin) rather than relying on the panel's
 * vertical centring to keep clear of it, which a two-line caption would defeat. */
#mPromptPanel #replayControls.replayDock {
    padding-top: 48px;
}

/* Dominion's host is a plain box on the board; a hairline separates the panel from the table
 * felt behind it. Monopoly's host is already a bordered card, so it needs nothing. */
#gameOptions #replayControls.replayDock {
    border-top: 1px solid rgba(128, 128, 128, 0.35);
    border-bottom: 1px solid rgba(128, 128, 128, 0.35);
}

/* --- Victory points, all seats (replay only) ----------------------------------------------- */

/* Sits at the top of the Victory Points tab, above the watched seat's usual card breakdown. */
.replayVpTable {
    margin-bottom: 6px;
}

.replayVpRow {
    display: flex;
    align-items: baseline;
    gap: 8px;
}

.replayVpRow .replayVpName {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Fixed columns so the numbers line up in a column rather than drifting with name length. */
.replayVpRow .replayVpActual {
    flex: 0 0 3.5em;
    text-align: right;
    font-weight: 700;
}

.replayVpRow .replayVpSaw {
    flex: 0 0 6.5em;
    text-align: right;
    opacity: 0.75;
}

.replayVpHead {
    opacity: 0.6;
    font-size: 0.85em;
}

/* The seat being watched, so the row the breakdown below belongs to is obvious. */
.replayVpWatching {
    font-weight: 700;
}

.replayVpNote {
    margin-top: 4px;
    opacity: 0.7;
    font-size: 0.85em;
}

/* --- Floating fallback (mobile Dominion, or any host that is missing/hidden) --------------- */

#replayControls.replayFloat {
    position: fixed;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    z-index: 9999;
    background: rgba(0, 0, 0, 0.85);
    color: #fff;
    padding: 5px 10px;
    border-radius: 0 0 8px 8px;
    text-align: center;
    font-size: 13px;
    white-space: nowrap;
    cursor: move;
    /* One horizontal strip, as it has always been -- the row grouping is a docked-layout idea. */
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 4px;
}

#replayControls.replayFloat .replayStepRow,
#replayControls.replayFloat .replayMetaRow {
    display: flex;
    align-items: center;
    gap: 4px;
    order: 1;
}

/* The caption is written first in the markup because that is the order the docked panel wants;
 * floating it belongs at the far end of the strip, where it has always been and where its
 * changing width does not shove the buttons sideways mid-session. */
#replayControls.replayFloat .replayCaption {
    order: 2;
}

#replayControls.replayFloat input[type="button"] {
    margin: 0 2px;
}

#replayControls.replayFloat .replayCaption {
    display: inline-block;
    vertical-align: middle;
    margin-left: 10px;
    max-width: 520px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* --- Phone: a full-width bottom bar --------------------------------------------------------
 *
 * Both games use this on a phone; neither docks. A host box is a region of the game canvas, and
 * that canvas is scaled to fit a ~400px-tall screen, so a docked panel arrives at about half size --
 * which is the "too small to press" problem the dock exists to solve on desktop, reintroduced.
 *
 * The sizes come from custom properties rather than literals because this bar is inside <body>,
 * the element Scaling.js transforms, and position:fixed does not opt out of a transformed
 * ancestor. Its CSS pixels are therefore CANVAS pixels: at the ~0.47 scale a landscape phone gets,
 * a literal 44px row would land at 21px under a thumb. Replay.js divides the real targets by the
 * live scale into --replayTouch/--replayFont/--replayGap and refreshes them on every re-fit. The
 * fallbacks are the unscaled values, so a missing variable degrades to merely small rather than
 * to nothing.
 *
 * Bottom rather than top: fixed inside the transform resolves against the canvas, so this pins to
 * the bottom of the board -- away from the hand and the supply, and under the thumbs already
 * holding a phone in landscape. */
html.mobileUI #replayControls.replayFloat {
    /* left / width / top are written by replaySizeMobileBar() from the viewport corners -- see there
     * for why `bottom: 0` cannot be used. These only clear the desktop centring.
     *
     * border-box so the width written there is the whole bar: as content-box the padding was added
     * on top and the bar came out a little wider than the screen. */
    transform: none;
    max-width: none;
    box-sizing: border-box;
    border-radius: 0;
    padding: var(--replayGap, 6px);
    gap: var(--replayGap, 6px);
    /* Wrap, so the seat picker and caption drop to a second line rather than squeezing the
     * transport buttons below a thumb's width. */
    flex-wrap: wrap;
    justify-content: center;
    cursor: default;
    background: rgba(0, 0, 0, 0.9);
}

html.mobileUI #replayControls.replayFloat .replayStepRow,
html.mobileUI #replayControls.replayFloat .replayMetaRow {
    gap: var(--replayGap, 6px);
    flex-wrap: wrap;
    justify-content: center;
}

html.mobileUI #replayControls.replayFloat input[type="button"],
html.mobileUI #replayControls.replayFloat select {
    min-height: var(--replayTouch, 44px);
    font-size: var(--replayFont, 15px);
    padding: 0 calc(var(--replayGap, 6px) * 2);
    margin: 0;
    box-sizing: border-box;
}

/* The caption is prose, not a target, so it takes the type size without the 44px floor -- and it
 * elides rather than pushing the transport off the bar. */
html.mobileUI #replayControls.replayFloat .replayCaption {
    font-size: var(--replayFont, 15px);
    max-width: 100%;
    margin-left: 0;
}

/* Monopoly on a phone parks the CAPTION in the empty centre panel; every control is in the dock.
 *
 * #mPromptPanel is the slot a live game fills with the choice it is waiting on, and a replay never
 * asks for one, so it is free all session. An earlier version put Play and the speed here instead
 * and left the steppers on a bottom bar; the panel is only 378 design px wide with the round line
 * taking its top third, so a real 44px control spilled out of it -- and the bar still cost 80px of
 * a 430px screen. See the .replayPhoneDock block at the end of this file for what replaced it.
 *
 * Layout only; the type and overflow are set with the dock, which is where they have to be reasoned
 * about together. */
html.mobileUI .replayCentreGroup {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--replayGap, 6px);
    margin-top: var(--replayGap, 6px);
}

/* Board controls the phone replay dock sits over. Chat, End Turn and the action counter all mean
 * nothing in a replay, and covering Monopoly chat is explicitly acceptable here -- hiding them beats
 * having the bar overlap live-looking controls.
 *
 * !important is load-bearing rather than lazy: the replay re-draws the whole Monopoly board on every
 * step and that redraw writes inline display back onto these elements, so End Turn reappeared under
 * the bar within a single step. Only a declaration that outranks an inline style survives a redraw
 * this file does not own. Scoped to the class, which exists only for the duration of a phone
 * Monopoly replay. */
html.replayHidesBoardControls #monopolyChatDiv,
html.replayHidesBoardControls #monopolyEndTurnButton,
html.replayHidesBoardControls #mTurnActionCount {
    display: none !important;
}

/* Each group keeps its natural width on the phone bar, so an over-full bar WRAPS to a second line
 * rather than shrinking every group past its buttons. As shrinkable flex items the three groups
 * squeezed instead of wrapping, and with the bar centred that clipped the outermost buttons at both
 * ends -- "|<" and "Exit Replay" lost their edges. Vertical room is the one thing a bottom bar has. */
html.mobileUI #replayControls.replayFloat > .replayStepRow {
    flex: 0 0 auto;
}

/* --- Phone, Monopoly: docked into the board's own free strip -------------------------------
 *
 * Replaces the full-width bottom bar for Monopoly. That bar was 80px of a 430px screen and it
 * landed on the watched player's hand -- the one thing a replay exists to show. This fills the
 * strip the chat pane, End Turn and the action counter occupy in a live game, all three of which a
 * replay hides anyway, so the transport costs the board nothing.
 *
 * The slot is 730x205 DESIGN px and cannot grow: #mMyMat, the watched player's own property row,
 * ends at y=803 and runs the full width of the canvas, so every pixel above 805 is board. In real
 * pixels that is 308x87 on a 932-wide phone and 221x62 on a 568-wide one.
 *
 * Placed by replaySizeMonopolyDock, which writes left/top/width/height straight from that slot --
 * so unlike .replayFloat there is no scale division here and the grid tracks the board at every
 * scale. Everything therefore sizes off the box (flex: 1 1 0) rather than off a fixed px target:
 * a constant 44px row does not fit in 87, let alone 62. Twelve cells at 51x41 real px (37x31 on the
 * smallest landscape phone) is what the slot affords, and it holds the WHOLE transport. */
html.mobileUI #replayControls.replayPhoneDock {
    /* position is set per-variant in this file rather than on a bare #replayControls rule, so a
     * class swap that drops .replayFloat drops the positioning with it -- the dock rendered static
     * at the canvas origin until this line existed. */
    position: fixed;
    z-index: 60;
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    box-sizing: border-box;
    transform: none;
    max-width: none;
    border-radius: 8px;
    padding: 6px;
    gap: 6px;
    cursor: default;
    background: rgba(0, 0, 0, 0.72);
}

/* Two rows of six sharing the height equally. Columns 1-4 are the mirrored stepper grid the bar
 * already had (back row above, forward row below); columns 5-6 hold Play + speed over seat + Exit,
 * moved here from the meta row by replayMonopolyPhoneSplit. */
html.mobileUI #replayControls.replayPhoneDock > .replayStepRow {
    display: flex;
    flex: 1 1 0;
    min-height: 0;
    gap: 6px;
}

html.mobileUI #replayControls.replayPhoneDock > .replayStepRow > input[type="button"],
html.mobileUI #replayControls.replayPhoneDock > .replayStepRow > select {
    flex: 1 1 0;
    min-width: 0;
    width: auto;
    height: 100%;
    min-height: 0;
    margin: 0;
    padding: 0 2px;
    box-sizing: border-box;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
    /* min() caps what the labels may take out of a fixed-height slot. --replayFont is pre-divided
     * by the scale to hold a constant REAL size, which in a box that does NOT grow with the screen
     * would overflow the cells on a small phone; there the design-px ceiling wins and the type
     * shrinks with the board instead. 28px design is what keeps "<< Round" inside a cell. */
    font-size: min(var(--replayFont, 15px), 28px);
}

/* Play is the one pressed over and over, so it reads as the primary control rather than a
 * twelfth identical cell. */
html.mobileUI #replayControls.replayPhoneDock #replayPlayButton {
    font-weight: 700;
}

/* Emptied by replayMonopolyPhoneSplit: its four controls are now cells in the grid above and the
 * caption has gone to the centre panel. Hidden rather than deleted so the split stays a move. */
html.mobileUI #replayControls.replayPhoneDock > .replayMetaRow {
    display: none;
}

/* The other half of the split: the caption, in #mPromptPanel. It is prose rather than a target, so
 * it is the part that does not need a finger-sized box -- and the panel already carries the round
 * line, which it reads as a continuation of. Sized off --replayFont, so it holds a constant real
 * 15px however far the canvas has been scaled.
 *
 * Given a box WIDER than its host and allowed to overflow it, because the panel is 378 design px
 * and a step description ("Step 111/169 - Turn 3 - AI 0 gives up 3 card(s) - watching AI 0") is not
 * a 378px string -- inside the panel it elided after "Turn 3". Overflowing is safe for this element
 * specifically: the panel is pointer-events:none and grants it back only to its own inputs, so the
 * caption cannot swallow a tap meant for the board, and what it spills into is the middle of the
 * board, which no card occupies. Two lines, then elide. */
html.replayHidesBoardControls.mobileUI .replayCentreGroup {
    width: 1200px;
    max-width: none;
    margin-top: 0;
    /* min() caps the type in DESIGN px, which is what keeps this to one line on a small phone: a
     * constant real 15px is a much larger share of a 320px-tall screen than of a 430px one, and at
     * 568x320 it wrapped and the second line was read over the property row. The cap costs ~3px of
     * real type there and nothing at all on a 932-wide phone, where --replayFont is already under
     * the ceiling. */
    font-size: min(var(--replayFont, 15px), 40px);
    line-height: 1.25;
    text-align: center;
    /* One line, elided. The panel has the round line above it and #mMyMat starts 2px below, so
     * there is no second line to spend -- wrapping put the overflow straight onto a card. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

html.replayHidesBoardControls.mobileUI .replayCentreGroup .replayCaption {
    margin-left: 0;
    max-width: 100%;
}

/* On the phone the code takes the group's capped type rather than a fixed 13px, so it scales with
 * the caption beside it instead of dwarfing it on a small screen. flex:0 0 auto (set above) is what
 * keeps it whole when a long caption competes for the row -- the caption is the part that elides. */
html.replayHidesBoardControls.mobileUI .replayCentreGroup .replayUidChip {
    font-size: inherit;
    padding: 0px 5px;
    letter-spacing: 0.1em;
}

/* --- Phone, Dominion: a row in the mobile client's own layout ------------------------------
 *
 * Dominion on a phone is played on the mobile client (#mobile-game), so a replay is watched there
 * too -- the desktop canvas shrunk to fit was never the board the viewer knows. That client is a
 * flex COLUMN inside an 844x390 design canvas, which makes this the one dock in the file that can
 * add layout instead of taking it: the transport is a fifth row, and the other four reflow rather
 * than being covered. Everything here is in design px, like the rest of Game.Mobile.css.
 *
 * Sizes are literal rather than the --replay* custom properties: those pre-divide by the canvas
 * scale to hold a constant REAL size, which is right for a bar sitting on a transformed <body> and
 * wrong here -- #mg-inner has its own transform, and matching the surrounding UI is what keeps the
 * row from looking bolted on. */
#mg-inner.replayMobileDock > #replayControls.replayMobileRow {
    position: static;
    flex: 0 0 40px;
    height: 40px;
    width: 100%;
    max-width: none;
    transform: none;
    box-sizing: border-box;
    display: flex;
    flex-direction: row;
    align-items: stretch;
    gap: 4px;
    padding: 4px 6px;
    border-radius: 0;
    border-top: 1px solid var(--mg-border);
    background: #1a1a1a;
    cursor: default;
}

/* The three groups the markup builds are only a grouping, not a layout, once this is a single row:
 * display:contents drops the wrappers so all thirteen controls are direct flex items sharing the
 * width evenly, instead of three blocks competing for it. */
#mg-inner.replayMobileDock > #replayControls.replayMobileRow > .replayStepRow {
    display: contents;
}

#mg-inner.replayMobileDock > #replayControls.replayMobileRow input[type="button"],
#mg-inner.replayMobileDock > #replayControls.replayMobileRow select {
    flex: 1 1 0;
    min-width: 0;
    width: auto;
    height: 100%;
    min-height: 0;
    margin: 0;
    padding: 0 2px;
    box-sizing: border-box;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 13px;
    line-height: 1;
}

/* Play is the one pressed over and over. */
#mg-inner.replayMobileDock > #replayControls.replayMobileRow #replayPlayButton {
    font-weight: 700;
}

/* A <select> spends part of its cell on the drop-down arrow, so an equal share is not an equal
 * amount of TEXT -- at 1fr the speed read "Nor...". Half a share more each covers the arrow. */
#mg-inner.replayMobileDock > #replayControls.replayMobileRow select {
    flex-grow: 1.5;
}

/* "Seat:" is decoration the picker already carries, and a cell is too narrow to spend on it. */
#mg-inner.replayMobileDock > #replayControls.replayMobileRow #replaySeatLabel {
    display: none;
}

/* The 40px the row costs comes out of the middle, not the hand: the supply grid and the log both
 * scroll, so they lose height gracefully, while the hand does not scroll and was what the old
 * floating bar covered. Four rules because the height is restated down the middle's subtree; each
 * outranks Game.Mobile.css on specificity (id + class) rather than on load order, which it would
 * lose -- Game.Mobile.css is linked after this file. */
#mg-inner.replayMobileDock .mg-middle {
    flex-basis: 204px;
    height: 204px;
}

/* Height ONLY for the two columns inside it. .mg-middle is a flex ROW, so flex-basis on its
 * children is their WIDTH -- setting it here collapsed the supply column from 580px to 204px and
 * clipped the kingdom grid to two columns. */
#mg-inner.replayMobileDock .mg-supply-section,
#mg-inner.replayMobileDock .mg-log-col {
    height: 204px;
}

#mg-inner.replayMobileDock .mg-supply-tiles {
    max-height: 204px;
}

/* Dead in a replay: there is no turn to end, no treasure to play, and no one to chat to. Hidden
 * with a class because the mobile client re-asserts its own inline display on every rebuild, and a
 * replay rebuilds on every step. */
html.replayHidesMobileControls #mg-play-treasures,
html.replayHidesMobileControls #mg-end-turn,
html.replayHidesMobileControls #mg-chat-btn {
    display: none !important;
}

/* The two flex-grow spacers that held those buttons apart go too, or they split the space they
 * just freed three ways with the caption and it elided after "Step 41/152" with 180px sitting
 * empty beside it. */
html.replayHidesMobileControls #mg-inner .mg-hdr > .mg-hdr-spacer {
    display: none;
}

/* Scores opens the mobile client's end-of-game panel (the desktop #endOfGameDialog renders too but
 * sits under the overlay, which is why the mobile twin exists). Its "Return To Lobby" button calls
 * returnToLobby(), and that calls game.server.surrender() -- a live server call from inside a
 * replay that has no game on the server, and one that would not run replayExit() either, leaving
 * isReplayMode and this dock's classes set for the next game in the page.
 *
 * Hiding it is the mobile equivalent of what replayShowScores does to #endOfGameDialogButtons on
 * the desktop, and it costs nothing: "View Final Board" still dismisses the panel, and leaving is
 * what the transport row's own Exit is for. Undone automatically -- the class goes on exit. */
html.replayHidesMobileControls #mg-eog-lobby {
    display: none;
}

/* Reads in the space those three gave up, at the right-hand end of the stats row. It elides:
 * "Step 41/152" is the part that is not already on screen and it comes first, while the turn and
 * the watched seat are both readable from the stats row and the seat picker. */
html.replayHidesMobileControls #mg-inner .mg-hdr > .replayCaption {
    flex: 1 1 0;
    min-width: 0;
    margin-left: 8px;
    text-align: right;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 13px;
    opacity: 0.85;
}

/* --- Dominion, desktop: the roomy dock ------------------------------------------------------
 *
 * #gameOptions is 275px, which fits the eight transport buttons only as a 4x2 block -- and in that
 * block the two halves of a pair are DIAGONAL neighbours ("< Action" sits above "Turn >"), so the
 * button beside the one you want is never the one you meant. Stepping through a game is the task
 * you repeat a hundred times, so that is the wrong place to have to aim.
 *
 * The room to fix it is directly above: the chat column is 680px for a log that is not being
 * written to during a replay, which is not a conversation. Borrowing 180px of it buys a row per
 * unit, back beside forward, at a size worth aiming at.
 *
 * Everything here is scoped to html.replayWideDock, added only for THIS host and dropped on exit
 * (replayExit), so a live game's chat is never left short. It is deliberately not applied to the
 * tablet or dynamic stylesheets: they give these two boxes quite different geometry, and a fixed
 * borrow would land #gameOptions somewhere it does not belong. See replayDesktopExpanded.
 *
 * Placed at the END of this file on purpose. The compact rules above match at the SAME specificity
 * (one id, two classes, one attribute), so order is what decides -- an override written earlier
 * would silently lose. */
html.replayWideDock #gameChat {
    height: 455px;
}

html.replayWideDock #gameChatMessages {
    height: 425px;
}

/* 460 + 500 = 960, the canvas floor, and the 5px gap above matches the one the live layout keeps.
   Sized so the column has SLACK left over after its rows: that slack is what margin-top:auto on the
   exit row spends to push Exit to the floor, and with none the row just stacks. */
html.replayWideDock #gameOptions {
    top: 460px;
    height: 500px;
}

/* Room enough that the panel no longer has to centre itself against a shortage: start at the top
   and let the rows breathe downward instead. */
#replayControls.replayWideDock {
    justify-content: flex-start;
    gap: 6px;
    padding: 6px 8px;
}

/* Back on the left, forward on the right, both halves the same size so neither reads as primary. */
#replayControls.replayWideDock .replayPairRow {
    gap: 10px;
}

#replayControls.replayWideDock .replayStepRow input[type="button"] {
    flex: 1 1 0;
    min-width: 0;
    padding: 14px 4px;
    font-size: 16px;
}

/* The ends of the game are pressed once, not repeatedly, so they are set apart from the stepping
   rhythm rather than continuing it -- and that gap is what keeps a mis-aimed "<< Round" from
   landing on "back to the start" mid-session. */
#replayControls.replayWideDock .replayEndsRow {
    margin-top: 14px;
}

#replayControls.replayWideDock .replayEndsRow input[type="button"] {
    padding: 9px 4px;
    font-size: 14px;
    opacity: 0.85;
}

/* The non-stepping controls keep to their own scale; they are not part of the aiming problem. */
#replayControls.replayWideDock .replayMetaRow {
    margin-top: 14px;
    gap: 6px;
}

#replayControls.replayWideDock .replayMetaRow input[type="button"],
#replayControls.replayWideDock .replayMetaRow select {
    flex: 0 1 auto;
    padding: 6px 10px;
    font-size: 14px;
}

/* The caption has width to spare here, so it no longer needs two reserved lines to stay still. */
#replayControls.replayWideDock .replayCaption {
    font-size: 13px;
}

/* Scores and Exit each on their own line here (see metaRows in replayShowControls). Written after
   the stepper rule above, which matches at the same specificity -- order is what makes these win. */
#replayControls.replayWideDock .replayScoresRow input[type="button"],
#replayControls.replayWideDock .replayExitRow input[type="button"] {
    flex: 1 1 auto;
    min-width: 0;
    max-width: 100%;
    padding: 9px 10px;
    font-size: 14px;
}

#replayControls.replayWideDock .replayScoresRow {
    margin-top: 10px;
}

/* Pushed to the FLOOR of the panel: margin-top:auto absorbs whatever slack the column has left, so
   leaving is always the last thing on it and never sits against a button being pressed repeatedly.
   Falls back to sitting under Scores if the panel is ever too short to have slack. */
#replayControls.replayWideDock .replayExitRow {
    margin-top: auto;
    padding-top: 12px;
}

#replayControls.replayWideDock .replayExitRow input[type="button"] {
    opacity: 0.9;
}
