/* ==========================================================================
   Replay Viewer — Minimap replay visualization
   ========================================================================== */

/* Loading overlay shown during reference / auto-load / Review-Similar
   replay fetches. Intentionally decoupled from .replay-upload-zone so
   the "Loading..." state never reveals the empty-state browse grid
   behind it — the previous UX showed both at once because the drop
   zone was repurposed as a spinner container.

   Inline in the page content (not full-screen) so the top nav stays
   clickable; the user can always bail to LEARN / PLAYERS / COACH
   mid-load. Sits in the same vertical real estate as the drop zone
   would have occupied. */
.replay-loading-overlay {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 60vh;
    padding: 2rem;
    pointer-events: auto;
}

.replay-loading-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    padding: 28px 40px;
    background: rgba(12, 16, 28, 0.85);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 14px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
    max-width: 320px;
}

.replay-loading-spinner {
    width: 34px;
    height: 34px;
    border: 3px solid rgba(255, 255, 255, 0.14);
    border-top-color: #5aa0ff;
    border-radius: 50%;
    animation: replay-loading-spin 0.9s linear infinite;
}

@keyframes replay-loading-spin {
    to { transform: rotate(360deg); }
}

.replay-loading-msg {
    margin: 0;
    color: #cbd5e1;
    font-size: 14px;
    text-align: center;
    letter-spacing: 0.01em;
}

/* Upload Zone — kept compact so the featured-replays grid below gets
   prime real estate on the intro screen. Used to be min-height: 60vh,
   which pushed the featured cards below the fold. */
.replay-upload-zone {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 160px;
    margin: 1.5rem auto 0.5rem;
    max-width: 560px;
    border: 2px dashed rgba(0, 212, 255, 0.3);
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.03);
    backdrop-filter: blur(10px);
    transition: border-color 0.2s, background 0.2s;
    cursor: pointer;
}

.replay-upload-zone.dragover {
    border-color: var(--primary-color, #00d4ff);
    background: rgba(0, 212, 255, 0.06);
}

.replay-upload-content {
    text-align: center;
    padding: 1rem 1.5rem;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    flex-wrap: wrap;
}

.replay-upload-icon {
    font-size: 1.75rem;
    color: var(--primary-color, #00d4ff);
    margin: 0;
    opacity: 0.7;
    line-height: 1;
}

.replay-upload-title {
    font-size: 1.1rem;
    font-weight: 600;
    color: #e0e0e0;
    margin: 0;
}

.replay-upload-sub {
    color: #888;
    margin: 0;
    font-size: 0.82rem;
}

.replay-upload-progress {
    text-align: center;
    padding: 2rem;
}

.replay-upload-progress p {
    margin-top: 1rem;
    color: #aaa;
}

/* =============================================================
   Featured replays (intro-screen card grid)
   ----
   Rendered below the upload zone. Each card is a compact tile
   showing matchup / player-vs-opponent / map / duration / date.
   Click loads via loadReferenceReplayById and flips the viewer
   on in-place.
   ============================================================= */

.replay-featured {
    max-width: 1200px;
    margin: 1rem auto 3rem;
    padding: 0 1rem;
}

.replay-featured-head {
    text-align: center;
    margin-bottom: 1rem;
}

.replay-featured-title {
    font-size: 1.15rem;
    font-weight: 600;
    color: #e0e0e0;
    letter-spacing: 0.02em;
    margin: 0 0 0.25rem;
}

.replay-featured-sub {
    color: #6e7687;
    font-size: 0.85rem;
    margin: 0;
}

.replay-featured-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 12px;
}

/* Card: matches FloatCard aesthetic (translucent + blur) so the intro
   page and the in-viewer rails feel like one family. */
.replay-featured-card {
    all: unset;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 14px 14px 12px;
    background: rgba(15, 19, 28, 0.75);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: 10px;
    cursor: pointer;
    color: #e6e9ef;
    font-family: 'Inter', system-ui, sans-serif;
    transition: border-color 0.15s ease, transform 0.15s ease, background 0.15s ease;
}

.replay-featured-card:hover {
    border-color: rgba(86, 194, 255, 0.5);
    background: rgba(22, 28, 42, 0.85);
    transform: translateY(-2px);
}

.replay-featured-card:focus-visible {
    outline: 2px solid #56c2ff;
    outline-offset: 2px;
}

.rf-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.rf-matchup {
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 14px;
    font-weight: 700;
    letter-spacing: 0.08em;
    display: inline-flex;
    gap: 2px;
    align-items: baseline;
}

.rf-vs {
    color: #6e7687;
    font-size: 11px;
    font-weight: 500;
}

/* Per-player row: glyph on the left, name + MMR pill on the top line,
   build-order/archetype tucked beneath the name. Each card has two of
   these (when both perspectives are known) so the MMR pills line up
   vertically and each player gets equal visual weight. */
.rf-prow {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    min-width: 0;
}

.rf-prow-body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.rf-prow-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    min-width: 0;
    font-size: 13px;
}

.rf-build {
    color: #8a93a3;
    font-size: 11px;
    font-style: italic;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.rf-mmr-pill {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
    font-size: 10px;
    color: #fbbf24;
    background: rgba(251, 191, 36, 0.10);
    border: 1px solid rgba(251, 191, 36, 0.30);
    border-radius: 3px;
    padding: 2px 6px;
    font-weight: 600;
    letter-spacing: 0.04em;
    flex-shrink: 0;
}

.rf-glyph {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 3px;
    font-size: 11px;
    font-weight: 700;
    color: #fff;
    flex-shrink: 0;
    font-family: 'Rajdhani', sans-serif;
    margin-top: 1px;
}

.rf-name {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-weight: 500;
    min-width: 0;
    flex: 1 1 auto;
}

.rf-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 5px;
    font-size: 11px;
    color: #6e7687;
    margin-top: 2px;
}

.rf-map {
    color: #aab3c2;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1 1 auto;
    min-width: 0;
}

.rf-sep { opacity: 0.45; }
.rf-dur, .rf-date {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}

/* Matchup filter — row of chips above the card grid. Clicking a chip
   filters the grid client-side; "All" is the default. Hidden until the
   JS populates it from the replay set so we don't show chips for matchups
   we don't actually have data for. */
.replay-featured-filter {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px;
    margin: 0 auto 1rem;
    padding: 0 1rem;
    max-width: 900px;
}

.rf-filter-chip {
    all: unset;
    box-sizing: border-box;
    cursor: pointer;
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.06em;
    color: #aab3c2;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: 14px;
    padding: 4px 12px;
    transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}

.rf-filter-chip:hover {
    color: #e6e9ef;
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.20);
}

.rf-filter-chip.is-active {
    color: #56c2ff;
    background: rgba(86, 194, 255, 0.10);
    border-color: rgba(86, 194, 255, 0.50);
}

.rf-filter-chip:focus-visible {
    outline: 2px solid #56c2ff;
    outline-offset: 2px;
}

/* Viewer Layout — fills the viewport below the app header so the map
   canvas can use the full browser width/height by default. The sidebar
   is positioned as a draggable/resizable overlay rather than a flex
   sibling. --app-header-h is measured on page init by replay.js. */
.replay-viewer {
    position: fixed;
    top: var(--app-header-h, 64px);
    left: 0;
    right: 0;
    bottom: 0;
    max-width: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    background: #060610;
    z-index: 5;
}

/* Player Header */
.replay-header {
    margin-bottom: 1rem;
}

.replay-players {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.75rem 1.25rem;
    background: rgba(255, 255, 255, 0.04);
    border-radius: 10px;
    backdrop-filter: blur(8px);
}

.replay-player-info {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.95rem;
    font-weight: 500;
    min-width: 0;
}

.replay-player-info .player-color-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
}

.replay-player-info .player-name {
    color: #e0e0e0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.replay-player-info .player-race {
    color: #888;
    font-size: 0.8rem;
}

.replay-map-info {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.15rem;
    color: #999;
    font-size: 0.8rem;
    flex-shrink: 0;
}

#replay-map-name {
    color: #bbb;
    font-weight: 500;
}

/* SC2-feel heading font */
.font-heading {
    font-family: 'Rajdhani', system-ui, sans-serif;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* Top Bar — title row above the canvas. Sits flush at the top of the
   replay viewport; the canvas-container flexes to fill remaining space. */
.replay-topbar {
    flex-shrink: 0;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 1rem;
    padding: 0.45rem 0.85rem;
    margin: 0;
    background: rgba(8, 12, 24, 0.92);
    border: none;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 0;
    font-size: 0.85rem;
    z-index: 6;
    /* Shared transition used by the autohide mode below. */
    transition: transform 0.2s ease, opacity 0.2s ease;
}

/* Topbar autohide mode — mirrors the dock-autohide pattern but
   slides UP instead of DOWN. Position: absolute lifts the bar out
   of the flex flow so the canvas below immediately claims the
   freed vertical space; translateY then slides the bar upward
   leaving a 6px sliver visible as an affordance. The ::before
   pseudo extends the hover hit zone downward into the canvas so
   the reveal triggers before the user has to chase a 6px sliver. */
.replay-viewer.topbar-autohide .replay-topbar {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    transform: translateY(calc(-100% + 6px));
    opacity: 0.45;
    z-index: 6;
}
.replay-viewer.topbar-autohide .replay-topbar::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -28px;
    height: 28px;
    background: transparent;
    pointer-events: auto;
}
.replay-viewer.topbar-autohide .replay-topbar:hover {
    transform: translateY(0);
    opacity: 1;
}
.replay-topbar > .replay-topbar-info { justify-self: start; }
.replay-topbar > #replay-topbar-stats { justify-self: center; }
.replay-topbar > .replay-topbar-actions { justify-self: end; }

.replay-topbar-info {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    color: #aaa;
    min-width: 0;
    flex-wrap: nowrap;
}

/* Centered inline per-player live stats (name · race · Sup · Army ·
   top-5 unit icons). Each row is a button that toggles the "my player"
   perspective — highlighted while fog is in selected mode for that
   player. Replaces both the old centered "PLAYER STATS" popover and
   the redundant player-names line below the map name. */
.replay-topbar-stats {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    font-family: 'Rajdhani', 'Inter', system-ui, sans-serif;
}

.replay-topbar-stats .rts-player {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 3px 10px 3px 10px;
    background: transparent;
    border: 1px solid transparent;
    border-left: 2px solid var(--player-color, rgba(255, 255, 255, 0.2));
    border-radius: 4px;
    color: inherit;
    font: inherit;
    cursor: pointer;
    min-width: 0;
    transition: background 0.12s, border-color 0.12s;
}

.replay-topbar-stats .rts-player:hover {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.10);
    border-left-color: var(--player-color, rgba(255, 255, 255, 0.2));
}

.replay-topbar-stats .rts-player.active {
    background: rgba(153, 102, 204, 0.12);
    border-color: rgba(199, 155, 255, 0.55);
    border-left-color: var(--player-color, rgba(255, 255, 255, 0.2));
}

.replay-topbar-stats .rts-name {
    font-weight: 700;
    font-size: 18px;
    letter-spacing: 0.02em;
    max-width: 200px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.replay-topbar-stats .rts-race {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 13px;
    color: #8891a0;
}

.replay-topbar-stats .rts-stat {
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
}

.replay-topbar-stats .rts-label {
    font-size: 11px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #6e7687;
}

.replay-topbar-stats .rts-value {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
    color: #e6e9ef;
    font-weight: 600;
    font-size: 17px;
}

@media (max-width: 1400px) {
    .replay-topbar-stats .rts-name { max-width: 140px; }
}

/* -------------------------------------------------------------------------
 * End-of-game winner highlight
 *
 * When playback reaches state.duration, replay.js toggles `.game-ended` on
 * #replay-topbar-stats. The class drives three coordinated effects on the
 * stable container so the animation re-fires on each entry but doesn't
 * thrash on the per-tick stats re-render:
 *   1. Loser row fades & desaturates so the eye lands on the winner.
 *   2. Winner row gains a glowing border in their player color (replaces
 *      the 1px transparent border + 2px left accent with a 1px ring).
 *   3. WINNER badge slides in from the right, dwells, and stays.
 * The badge element is always rendered for the winning player but is
 * `display:none` until the parent has `.game-ended`, so the entry
 * animation is clean and we don't need to manage badge insertion in JS.
 * ------------------------------------------------------------------------- */

.rts-winner-badge { display: none; }

#replay-topbar-stats.game-ended .rts-player {
    transition: opacity 0.6s ease, filter 0.6s ease,
                border-color 0.6s ease, background 0.6s ease;
}

#replay-topbar-stats.game-ended .rts-player.rts-loser {
    opacity: 0.42;
    filter: saturate(0.35);
}

#replay-topbar-stats.game-ended .rts-player.rts-winner {
    border-color: var(--player-color, rgba(255, 255, 255, 0.4));
    background: color-mix(in srgb, var(--player-color, #fff) 10%, transparent);
    animation: rtsWinnerPulse 2.4s cubic-bezier(0.4, 0, 0.6, 1) 0.15s 2 both;
}

#replay-topbar-stats.game-ended .rts-player.rts-winner .rts-name {
    text-shadow: 0 0 12px color-mix(in srgb, var(--player-color, #fff) 70%, transparent);
}

#replay-topbar-stats.game-ended .rts-winner-badge {
    display: inline-flex;
    align-items: center;
    margin-left: 6px;
    padding: 2px 8px 2px 9px;
    border-radius: 3px;
    background: var(--player-color, #fff);
    color: #0b0e14;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.12em;
    line-height: 1;
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--player-color, #fff) 60%, transparent),
                0 0 14px color-mix(in srgb, var(--player-color, #fff) 55%, transparent);
    transform-origin: left center;
    animation: rtsBadgeSlideIn 0.55s cubic-bezier(0.2, 0.8, 0.25, 1) 0.35s both;
}

#replay-topbar-stats.game-ended .rts-winner-badge-text {
    display: inline-block;
    animation: rtsBadgeTextFade 0.35s ease 0.6s both;
}

@keyframes rtsWinnerPulse {
    0%, 100% {
        box-shadow: 0 0 0 0 color-mix(in srgb, var(--player-color, #fff) 0%, transparent);
    }
    50% {
        box-shadow: 0 0 18px 2px color-mix(in srgb, var(--player-color, #fff) 45%, transparent);
    }
}

@keyframes rtsBadgeSlideIn {
    0%   { transform: translateX(-6px) scaleX(0.2); opacity: 0; }
    60%  { transform: translateX(0) scaleX(1.04); opacity: 1; }
    100% { transform: translateX(0) scaleX(1); opacity: 1; }
}

@keyframes rtsBadgeTextFade {
    from { opacity: 0; letter-spacing: 0.04em; }
    to   { opacity: 1; letter-spacing: 0.12em; }
}

@media (prefers-reduced-motion: reduce) {
    #replay-topbar-stats.game-ended .rts-player.rts-winner { animation: none; }
    #replay-topbar-stats.game-ended .rts-winner-badge,
    #replay-topbar-stats.game-ended .rts-winner-badge-text { animation: none; }
    /* Match-finisher overlay: replay.js short-circuits past the finisher
       entirely when reduced-motion matches, so the overlay should never
       mount — these rules are belt-and-suspenders for any path that
       might still reach them. */
    .match-finisher-overlay,
    .match-finisher-overlay * { animation: none !important; transform: none !important; filter: none !important; }
    .canvas-wrapper.mf-shake { animation: none !important; transform: none !important; filter: none !important; }
    .match-intro-overlay,
    .match-intro-overlay * { animation: none !important; transform: none !important; filter: none !important; }
    .canvas-wrapper.mi-shake { animation: none !important; transform: none !important; filter: none !important; }
    .post-match-modal.pm-entering .pm-backdrop,
    .post-match-modal.pm-entering .pm-card { animation: none !important; }
}

.replay-topbar-home {
    color: #888;
    text-decoration: none;
    font-size: 0.78rem;
    letter-spacing: 0.05em;
    font-weight: 600;
}

.replay-topbar-home:hover { color: #fff; }

.replay-topbar-divider { color: #444; }

.replay-topbar-map {
    color: #56c2ff;
    font-family: 'Rajdhani', system-ui, sans-serif;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 1.05rem;
}

.replay-topbar-badge {
    padding: 1px 7px;
    border-radius: 4px;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    font-family: 'Rajdhani', system-ui, sans-serif;
    border: 1px solid currentColor;
    text-transform: uppercase;
}
.replay-topbar-badge.badge-lotv { color: #f4c542; background: rgba(244, 197, 66, 0.12); }
.replay-topbar-badge.badge-hots { color: #b78bff; background: rgba(183, 139, 255, 0.12); }
.replay-topbar-badge.badge-wol  { color: #56c2ff; background: rgba(86, 194, 255, 0.12); }
.replay-topbar-badge.badge-reference { color: #56c2ff; background: rgba(86, 194, 255, 0.14); border-color: rgba(86, 194, 255, 0.55); }

.replay-topbar-matchup {
    color: #ddd;
    font-style: italic;
    font-size: 0.82rem;
}

/* Map thumbnail in topbar */
.replay-topbar-thumb {
    width: 44px;
    height: 44px;
    border-radius: 6px;
    background: #060614 center/cover no-repeat;
    border: 1px solid rgba(255, 255, 255, 0.1);
    flex-shrink: 0;
}

.replay-topbar-actions {
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

.replay-toggle-btn {
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.1);
    color: #ccc;
    padding: 0.3rem 0.6rem;
    border-radius: 6px;
    font-size: 0.74rem;
    font-weight: 600;
    cursor: pointer;
    letter-spacing: 0.04em;
    transition: all 0.15s;
}

.replay-toggle-btn:hover { background: rgba(255,255,255,0.1); border-color: rgba(255,255,255,0.2); color: #fff; }

.replay-toggle-btn.active {
    background: rgba(0, 212, 255, 0.16);
    border-color: var(--primary-color, #00d4ff);
    color: var(--primary-color, #00d4ff);
}

/* Canvas Container — fills all remaining space under the topbar. The
   sidebar is positioned absolutely inside this container so dragging
   is scoped to the replay area rather than the whole page. */
.replay-canvas-container {
    position: relative;
    flex: 1;
    min-height: 0;
    width: 100%;
    background: transparent;
    border-radius: 0;
    overflow: hidden;
    border: none;
}

.replay-canvas-container .canvas-wrapper {
    width: 100%;
    height: 100%;
    background: #0a0a14;
    border: none;
    border-radius: 0;
    overflow: hidden;
    position: relative;
    display: block;
}

#replay-canvas {
    display: block;
    width: 100%;
    height: 100%;
    /* Buffer dimensions are set by _sizeCanvas() via canvas.width/height.
       The map content inside is drawn at its natural aspect, centered in the
       inset rect — dark space around it is the rotation grip. */
}

/* Bottom toggle strip on the canvas (Fog/Bldg/Heat/Wrk + legend) */
.replay-canvas-toggles {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    bottom: 80px;
    z-index: 7;
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.35rem 0.75rem;
    background: rgba(8, 12, 24, 0.85);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 10px;
    font-size: 0.72rem;
    color: #ccc;
}

.replay-canvas-legend {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding-right: 0.6rem;
    border-right: 1px solid rgba(255,255,255,0.1);
}

.replay-canvas-legend .legend-item {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    color: #ddd;
}

.replay-canvas-legend .legend-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
}

.replay-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    cursor: pointer;
    user-select: none;
}

.replay-toggle input[type="checkbox"] {
    width: 12px;
    height: 12px;
    margin: 0;
    cursor: pointer;
    accent-color: var(--primary-color, #00d4ff);
}

/* Right sidebar — floating overlay. Positioned in the top-right by
   default; user can drag it anywhere via the tab strip, and resize it
   via the bottom-left grip. Initial dimensions come from JS state so
   the layout survives a viewer tear-down/rebuild. */
.replay-sidebar {
    position: absolute;
    top: 12px;
    right: 12px;
    width: 360px;
    height: calc(100% - 24px);
    max-height: calc(100% - 24px);
    min-width: 260px;
    min-height: 240px;
    display: flex;
    flex-direction: column;
    background: rgba(8, 12, 24, 0.88);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.45);
    z-index: 10;
}

.replay-sidebar.dragging {
    transition: none;
    user-select: none;
    cursor: grabbing;
}

/* Bottom-left resize grip (SW corner — doesn't conflict with the right-
   anchored default position). Uses a diagonal gradient as the visual cue. */
.replay-sidebar-resize {
    position: absolute;
    left: 0;
    bottom: 0;
    width: 16px;
    height: 16px;
    cursor: nwse-resize;
    background:
      linear-gradient(45deg,
        transparent 0%, transparent 40%,
        rgba(255,255,255,0.35) 40%, rgba(255,255,255,0.35) 50%,
        transparent 50%, transparent 60%,
        rgba(255,255,255,0.35) 60%, rgba(255,255,255,0.35) 70%,
        transparent 70%);
    opacity: 0.55;
    z-index: 12;
    transform: scaleX(-1);  /* flip diagonals so they point toward the SW corner */
}

.replay-sidebar-resize:hover { opacity: 0.9; }

.replay-sidebar-tabs {
    display: flex;
    border-bottom: 1px solid rgba(255,255,255,0.08);
    background: rgba(0,0,0,0.3);
    flex-shrink: 0;
    cursor: grab;
    user-select: none;
}

.replay-sidebar-tabs:active { cursor: grabbing; }

.rs-tab {
    flex: 1;
    background: none;
    border: none;
    color: #888;
    padding: 0.7rem 0.4rem;
    font-family: 'Rajdhani', system-ui, sans-serif;
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
}

.rs-tab:hover { color: #ddd; background: rgba(255,255,255,0.04); }

.rs-tab.active {
    color: var(--primary-color, #00d4ff);
    border-bottom-color: var(--primary-color, #00d4ff);
    background: rgba(0, 212, 255, 0.05);
}

.rs-tab-count {
    color: #f4c542;
    font-weight: 700;
    background: rgba(244, 197, 66, 0.12);
    border-radius: 999px;
    padding: 1px 6px;
    font-size: 0.65rem;
    min-width: 1.2em;
}

.rs-tab-count:empty { display: none; }

.replay-sidebar-body {
    flex: 1;
    min-height: 0;
    overflow: hidden;
    position: relative;
}

.rs-pane {
    display: none;
    height: 100%;
    overflow-y: auto;
    padding: 0.75rem;
    scrollbar-width: thin;
    scrollbar-color: rgba(255,255,255,0.12) transparent;
}

.rs-pane::-webkit-scrollbar { width: 4px; }
.rs-pane::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.14); border-radius: 2px; }

.rs-pane.active { display: block; }

#rs-pane-build { padding: 0; }
.rs-build-cols {
    display: flex;
    height: 100%;
    gap: 1px;
    background: rgba(255,255,255,0.04);
}
.rs-build-cols .build-order-panel {
    flex: 1;
    border-radius: 0;
    width: auto;
    min-width: 0;
    height: 100%;
    max-height: 100%;
}

/* ====================================================================
   Mistake Compass panel (Overview tab)
   ==================================================================== */

.rs-compass-panel {
    margin-bottom: 1rem;
    background: linear-gradient(135deg, rgba(255, 107, 107, 0.04), rgba(86, 194, 255, 0.04));
    border: 1px solid rgba(255, 107, 107, 0.18);
    border-radius: 8px;
    padding: 0.55rem 0.65rem 0.7rem;
    overflow: hidden;
}

.rs-compass-header {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.4rem;
}
.rs-compass-icon { font-size: 0.95rem; }
.rs-compass-title {
    font-family: 'Rajdhani', system-ui, sans-serif;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: #ddd;
}
.rs-compass-count {
    margin-left: auto;
    font-size: 0.65rem;
    font-weight: 700;
    background: rgba(255, 107, 107, 0.18);
    color: #ff8f8f;
    padding: 1px 7px;
    border-radius: 999px;
}

.rs-compass-section-label {
    font-family: 'Rajdhani', system-ui, sans-serif;
    font-size: 0.62rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: #666;
    font-weight: 600;
    margin: 0.4rem 0 0.2rem;
}
.rs-compass-section-active { color: #ff8f8f; }

.rs-compass-row {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    padding: 0.35rem 0.4rem;
    margin-bottom: 0.25rem;
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.02);
    border: 1px solid rgba(255, 255, 255, 0.04);
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}
.rs-compass-row:hover {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(255, 255, 255, 0.1);
}
.rs-compass-active {
    background: rgba(255, 107, 107, 0.1);
    border-color: rgba(255, 107, 107, 0.35);
    box-shadow: 0 0 12px rgba(255, 107, 107, 0.15);
}
.rs-compass-past {
    opacity: 0.5;
}

.rs-compass-dot {
    flex-shrink: 0;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--hint-color, #888);
    box-shadow: 0 0 8px var(--hint-color, #888);
    margin-top: 0.35rem;
}
.rs-compass-active .rs-compass-dot {
    animation: compassPulse 1.4s ease-in-out infinite;
}
@keyframes compassPulse {
    0%, 100% { transform: scale(1); opacity: 1; }
    50% { transform: scale(1.35); opacity: 0.7; }
}

.rs-compass-body { flex: 1; min-width: 0; }
.rs-compass-label {
    font-size: 0.82rem;
    color: #ddd;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.rs-compass-detail {
    font-size: 0.68rem;
    color: #999;
    margin-top: 2px;
    line-height: 1.35;
}

.rs-compass-time {
    flex-shrink: 0;
    font-family: monospace;
    font-size: 0.72rem;
    color: #888;
    margin-top: 0.15rem;
}

/* Per-player overview cards (Overview tab) */
.rs-player {
    position: relative;
    margin-bottom: 0.85rem;
    padding: 0.5rem 0.6rem 0.85rem 1rem;
    border-bottom: 1px solid rgba(255,255,255,0.06);
}
.rs-player:last-child { border-bottom: none; }

/* 4px colored gradient rail on the left edge — fades horizontally for HUD vibe */
.rs-player::before {
    content: '';
    position: absolute;
    left: 0; top: 4px; bottom: 4px;
    width: 4px;
    background: var(--player-color, #888);
    border-radius: 2px;
    box-shadow: 0 0 12px var(--player-color, #888);
}
.rs-player::after {
    content: '';
    position: absolute;
    left: 4px; top: 4px; bottom: 4px;
    width: 80px;
    pointer-events: none;
    background: linear-gradient(to right, var(--player-color, #888) -50%, transparent 100%);
    opacity: 0.12;
}

.rs-player-header {
    display: flex;
    align-items: baseline;
    gap: 0.45rem;
    margin-bottom: 0.55rem;
    position: relative;
    z-index: 1;
}

.rs-player-name {
    font-family: 'Rajdhani', system-ui, sans-serif;
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: 0.02em;
}

.rs-player-race {
    color: #888;
    font-size: 0.78rem;
    font-style: italic;
}

.rs-player-stats {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.55rem 0.85rem;
    margin-bottom: 0.65rem;
    position: relative;
    z-index: 1;
}

.rs-stat {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
}

.rs-stat-label {
    color: #888;
    font-family: 'Rajdhani', system-ui, sans-serif;
    font-size: 0.7rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    font-weight: 600;
}

.rs-stat-value {
    color: #fff;
    font-family: 'Rajdhani', system-ui, sans-serif;
    font-weight: 700;
    font-size: 1.25rem;
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
    letter-spacing: 0.01em;
}

.rs-comp-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin-top: 0.25rem;
}

/* SC2 chip / icon — used by sc2-icons.js */
.sc2-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--icon-size, 22px);
    height: var(--icon-size, 22px);
    border-radius: 4px;
    border: 1.5px solid currentColor;
    background: rgba(0,0,0,0.4);
    overflow: hidden;
    flex-shrink: 0;
    font-family: 'Inter', system-ui, sans-serif;
    font-weight: 700;
    color: #fff;
    line-height: 1;
}

.sc2-chip img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

.sc2-chip.sc2-chip-procedural {
    color: #fff;
    text-shadow: 0 1px 2px rgba(0,0,0,0.6);
}

.sc2-comp-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 999px;
    padding: 2px 8px 2px 2px;
    font-size: 0.78rem;
    color: #ddd;
    font-variant-numeric: tabular-nums;
}

.sc2-comp-chip-count {
    font-weight: 700;
    color: #fff;
}

/* Charts (Economy, Army tabs) */
.rs-chart-card {
    margin-bottom: 0.9rem;
    background: rgba(0, 0, 0, 0.25);
    border: 1px solid rgba(255,255,255,0.05);
    border-radius: 8px;
    padding: 0.55rem 0.65rem 0.4rem;
}
.rs-chart-card-title {
    color: #aaa;
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    font-weight: 700;
    margin-bottom: 0.35rem;
}
.rs-chart-canvas {
    width: 100% !important;
    height: 130px !important;
}

/* ====================================================================
   Tree tab — Branch Surfer
   ==================================================================== */

.rs-tab-tree { position: relative; }
.rs-tab-pulse {
    display: none;
    width: 6px; height: 6px; border-radius: 50%;
    background: #56c2ff;
    box-shadow: 0 0 8px #56c2ff;
    margin-left: 2px;
}
.rs-tab-has-data .rs-tab-pulse {
    display: inline-block;
    animation: rsTreePulse 1.5s ease-in-out infinite;
}
@keyframes rsTreePulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.4; transform: scale(1.2); }
}

.rs-tree-empty {
    text-align: center;
    padding: 2rem 1rem;
    color: #bbb;
}
.rs-tree-empty-glyph { font-size: 2.5rem; margin-bottom: 0.5rem; filter: saturate(0.7); }
.rs-tree-empty-title {
    font-family: 'Rajdhani', system-ui, sans-serif;
    font-size: 1.1rem; letter-spacing: 0.04em;
    margin: 0 0 0.5rem; color: #ddd;
}
.rs-tree-empty-sub { font-size: 0.8rem; line-height: 1.5; color: #888; margin: 0 0 1rem; }

.rs-tree-head {
    display: flex; align-items: center; gap: 0.75rem;
    margin-bottom: 0.75rem;
    padding: 0.65rem;
    background: linear-gradient(135deg, rgba(86, 194, 255, 0.08), transparent);
    border: 1px solid rgba(86, 194, 255, 0.18);
    border-radius: 8px;
}

.rs-tree-score {
    flex-shrink: 0;
    display: flex; flex-direction: column; align-items: center;
    min-width: 60px; padding: 0.35rem 0.5rem;
    border: 2px solid currentColor; border-radius: 8px;
    font-family: 'Rajdhani', system-ui, sans-serif;
}
.rs-tree-score-good { color: #4caf50; }
.rs-tree-score-ok   { color: #f4c542; }
.rs-tree-score-poor { color: #f44336; }
.rs-tree-score-num { font-size: 1.7rem; font-weight: 700; line-height: 1; }
.rs-tree-score-label {
    font-size: 0.55rem; letter-spacing: 0.15em;
    opacity: 0.8; margin-top: 0.15rem;
}

.rs-tree-identity { flex: 1; min-width: 0; }
.rs-tree-archetype {
    font-family: 'Rajdhani', system-ui, sans-serif;
    font-size: 0.95rem; font-weight: 700;
    letter-spacing: 0.03em; color: #fff;
}
.rs-tree-branch {
    font-size: 0.78rem; color: #ccc; margin-top: 2px;
}
.rs-tree-branch-meta {
    display: flex; flex-wrap: wrap; gap: 0.4rem 0.7rem;
    font-size: 0.68rem; color: #999; margin-top: 0.3rem;
}
.rs-tree-branch-meta b { color: #ddd; }

.rs-tree-stats {
    display: flex; flex-wrap: wrap; gap: 0.3rem; margin-bottom: 0.85rem;
}
.rs-tree-pill {
    padding: 2px 8px; border-radius: 999px;
    font-size: 0.68rem; font-weight: 700;
    letter-spacing: 0.04em;
}
.rs-tree-pill.on-time   { background: rgba(76, 175, 80, 0.12); color: #81c784; }
.rs-tree-pill.ahead     { background: rgba(86, 194, 255, 0.12); color: #93d5ff; }
.rs-tree-pill.late      { background: rgba(244, 197, 66, 0.12); color: #f4c542; }
.rs-tree-pill.very-late { background: rgba(244, 67, 54, 0.12); color: #e57373; }
.rs-tree-pill.missing   { background: rgba(120, 120, 120, 0.15); color: #bbb; }

.rs-tree-section-label {
    font-family: 'Rajdhani', system-ui, sans-serif;
    font-size: 0.7rem; letter-spacing: 0.1em;
    text-transform: uppercase; color: #888;
    font-weight: 600; margin: 0.85rem 0 0.4rem;
}

.rs-tree-path {
    position: relative;
    padding-left: 1.2rem;
    border-left: 2px solid rgba(255,255,255,0.08);
    margin-left: 0.3rem;
}
.rs-tree-node {
    position: relative;
    padding: 0.35rem 0.5rem;
    margin-bottom: 0.3rem;
    border-radius: 6px;
    cursor: pointer;
    background: rgba(255,255,255,0.02);
    transition: background 0.15s;
}
.rs-tree-node:hover { background: rgba(255,255,255,0.06); }
.rs-tree-node-dot {
    position: absolute;
    left: -1.55rem; top: 0.55rem;
    width: 9px; height: 9px; border-radius: 50%;
    background: #888; border: 2px solid #0a0a14;
}
.rs-tree-node.comp-on-time .rs-tree-node-dot    { background: #4caf50; box-shadow: 0 0 6px #4caf50; }
.rs-tree-node.comp-late .rs-tree-node-dot       { background: #f4c542; box-shadow: 0 0 6px #f4c542; }
.rs-tree-node.comp-very-late .rs-tree-node-dot  { background: #f44336; box-shadow: 0 0 6px #f44336; }
.rs-tree-node.comp-missing .rs-tree-node-dot    { background: #555; border-style: dashed; }
.rs-tree-node-title {
    font-size: 0.82rem; font-weight: 500; color: #ddd;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rs-tree-node-time {
    display: flex; gap: 0.55rem; margin-top: 2px;
    font-size: 0.68rem; font-family: monospace; color: #777;
}
.rs-tree-node-expected { color: #56c2ff; }
.rs-tree-node-actual { color: #ddd; }
.rs-tree-node-delta {
    margin-left: auto; font-weight: 700;
}
.rs-tree-node.comp-on-time .rs-tree-node-delta    { color: #81c784; }
.rs-tree-node.comp-late .rs-tree-node-delta       { color: #f4c542; }
.rs-tree-node.comp-very-late .rs-tree-node-delta  { color: #e57373; }

.rs-tree-divergences { display: flex; flex-direction: column; gap: 0.4rem; }
.rs-tree-divergence {
    display: flex; gap: 0.55rem; padding: 0.5rem;
    background: rgba(244, 67, 54, 0.05);
    border: 1px solid rgba(244, 67, 54, 0.2);
    border-left: 3px solid #f44336;
    border-radius: 6px;
    cursor: pointer;
    transition: background 0.15s;
}
.rs-tree-divergence:hover { background: rgba(244, 67, 54, 0.1); }
.rs-tree-div-icon {
    font-size: 1.1rem; line-height: 1;
    align-self: flex-start; margin-top: 0.1rem;
    filter: saturate(1.3);
}
.rs-tree-div-body { flex: 1; min-width: 0; }
.rs-tree-div-title {
    font-size: 0.82rem; color: #ddd; font-weight: 600;
}
.rs-tree-div-sub {
    font-size: 0.68rem; color: #999; margin-top: 2px;
    font-family: monospace;
}
.rs-tree-miss-tag {
    background: rgba(244, 67, 54, 0.2);
    color: #e57373; padding: 1px 5px;
    border-radius: 3px; font-size: 0.58rem;
    font-weight: 700; letter-spacing: 0.1em;
}
.rs-tree-cta-row {
    margin-top: 1rem;
    text-align: center;
}

/* Battles tab */
.rs-battle-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.55rem;
    margin-bottom: 0.3rem;
    background: rgba(255,255,255,0.03);
    border: 1px solid rgba(255,255,255,0.05);
    border-left: 3px solid #ff9800;
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.78rem;
    transition: background 0.15s;
}
.rs-battle-row:hover { background: rgba(255,255,255,0.07); }

.rs-battle-time {
    color: #ddd;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    min-width: 3em;
}
.rs-battle-summary { flex: 1; color: #bbb; min-width: 0; }
.rs-battle-outcome {
    font-weight: 700;
    font-size: 0.7rem;
    letter-spacing: 0.06em;
}

.rs-empty {
    color: #777;
    font-style: italic;
    text-align: center;
    padding: 1.6rem 0.8rem;
    font-size: 0.85rem;
}

/* ====================================================================
   Auto-Highlight Reel — cinematic overlay
   ==================================================================== */

.highlight-reel {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transition: opacity 0.35s ease;
    font-family: 'Rajdhani', system-ui, sans-serif;
}
.highlight-reel.visible { opacity: 1; }

.highlight-reel-backdrop {
    position: absolute; inset: 0;
    background: radial-gradient(ellipse at center, rgba(8, 12, 24, 0.75) 0%, rgba(2, 2, 10, 0.95) 100%);
    backdrop-filter: blur(6px);
}

.highlight-reel-card {
    position: relative;
    width: min(620px, 92vw);
    padding: 2.2rem 2.4rem 1.4rem;
    background: linear-gradient(135deg, rgba(20, 28, 48, 0.95), rgba(8, 14, 28, 0.95));
    border: 1px solid rgba(86, 194, 255, 0.35);
    border-radius: 14px;
    box-shadow:
        0 0 40px rgba(86, 194, 255, 0.25),
        0 20px 60px rgba(0, 0, 0, 0.5);
    animation: hrSlideIn 0.5s cubic-bezier(0.2, 0.8, 0.25, 1);
}
@keyframes hrSlideIn {
    from { transform: translateY(16px); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
}

.highlight-reel-progress {
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 3px;
    background: rgba(255, 255, 255, 0.05);
    border-radius: 14px 14px 0 0;
    overflow: hidden;
}
.highlight-reel-progress-bar {
    height: 100%;
    width: 0%;
    background: linear-gradient(90deg, #56c2ff, #a24dff);
    box-shadow: 0 0 10px rgba(86, 194, 255, 0.7);
    transition: width 0.4s ease;
}

.highlight-reel-counter {
    position: absolute; top: 1rem; right: 3.5rem;
    font-size: 0.7rem;
    color: #888;
    font-weight: 700;
    letter-spacing: 0.14em;
}

.highlight-reel-kicker {
    font-size: 0.72rem;
    color: #56c2ff;
    font-weight: 700;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    margin-bottom: 0.35rem;
    display: inline-block;
    padding: 0.2rem 0.65rem;
    border: 1px solid rgba(86, 194, 255, 0.4);
    border-radius: 4px;
    background: rgba(86, 194, 255, 0.08);
}

.highlight-reel-time {
    display: inline-block;
    margin-left: 0.6rem;
    font-family: monospace;
    font-size: 0.75rem;
    color: #888;
    letter-spacing: 0.1em;
}

.highlight-reel-title {
    font-family: 'Rajdhani', system-ui, sans-serif;
    font-size: 2rem;
    font-weight: 700;
    color: #fff;
    letter-spacing: 0.01em;
    margin: 0.55rem 0 0.75rem;
    line-height: 1.15;
    text-shadow: 0 2px 12px rgba(86, 194, 255, 0.3);
}

.highlight-reel-body {
    color: #ccc;
    font-size: 1rem;
    line-height: 1.55;
    margin: 0 0 1.6rem;
    font-family: -apple-system, system-ui, sans-serif;
}

.highlight-reel-actions {
    display: flex;
    gap: 0.6rem;
    justify-content: flex-end;
    align-items: center;
}

.highlight-reel-btn {
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.12);
    color: #ddd;
    padding: 0.5rem 1rem;
    border-radius: 6px;
    font-family: 'Rajdhani', system-ui, sans-serif;
    font-weight: 600;
    font-size: 0.85rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    cursor: pointer;
    transition: all 0.15s;
}
.highlight-reel-btn:hover {
    background: rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.22);
    color: #fff;
}
.highlight-reel-btn-secondary {
    color: #888;
    background: transparent;
    border-color: rgba(255, 255, 255, 0.08);
}
.highlight-reel-btn-primary {
    background: linear-gradient(135deg, #56c2ff, #4aa5de);
    border-color: transparent;
    color: #04111f;
    font-weight: 700;
}
.highlight-reel-btn-primary:hover {
    background: linear-gradient(135deg, #79d0ff, #5bb4e8);
    box-shadow: 0 4px 12px rgba(86, 194, 255, 0.4);
    color: #04111f;
}

.highlight-reel-close {
    position: absolute;
    top: 0.65rem;
    right: 0.85rem;
    background: none;
    border: none;
    color: #666;
    font-size: 1.35rem;
    cursor: pointer;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    transition: color 0.15s, background 0.15s;
}
.highlight-reel-close:hover {
    color: #fff;
    background: rgba(255, 255, 255, 0.08);
}

/* Highlights button in the topbar — make it POP */
#replay-highlights {
    background: linear-gradient(135deg, #a24dff, #56c2ff);
    color: #04111f;
    font-weight: 700;
    border: none;
    padding: 0.45rem 0.95rem;
    border-radius: 6px;
    letter-spacing: 0.04em;
    box-shadow: 0 0 18px rgba(86, 194, 255, 0.28);
    cursor: pointer;
    transition: all 0.2s;
}
#replay-highlights:hover {
    box-shadow: 0 0 24px rgba(86, 194, 255, 0.5);
    transform: translateY(-1px);
    color: #04111f;
}

/* View mode segmented toggle (Top / Tactical) */
.replay-viewmode-group {
    display: inline-flex;
    background: rgba(0, 0, 0, 0.3);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 6px;
    overflow: hidden;
    padding: 1px;
}
.replay-viewmode-btn {
    background: transparent;
    border: none;
    color: #888;
    padding: 0.35rem 0.65rem;
    font-family: 'Rajdhani', system-ui, sans-serif;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    cursor: pointer;
    border-radius: 4px;
    transition: all 0.2s;
}
.replay-viewmode-btn:hover {
    color: #ddd;
    background: rgba(255, 255, 255, 0.05);
}
.replay-viewmode-btn.active {
    background: linear-gradient(135deg, rgba(86, 194, 255, 0.2), rgba(162, 77, 255, 0.18));
    color: #56c2ff;
    box-shadow: inset 0 0 10px rgba(86, 194, 255, 0.12);
}

/* Share button — pairs with Highlights, cooler tone */
.replay-share-btn {
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(86, 194, 255, 0.4);
    color: #56c2ff;
    padding: 0.45rem 0.85rem;
    border-radius: 6px;
    font-family: 'Rajdhani', system-ui, sans-serif;
    font-weight: 700;
    font-size: 0.78rem;
    letter-spacing: 0.06em;
    cursor: pointer;
    transition: all 0.2s;
}
.replay-share-btn:hover {
    background: rgba(86, 194, 255, 0.12);
    box-shadow: 0 0 14px rgba(86, 194, 255, 0.25);
    color: #79d0ff;
}

/* ====================================================================
   Share modal
   ==================================================================== */

.share-modal {
    position: fixed;
    inset: 0;
    z-index: 2100;
    display: flex;
    align-items: center;
    justify-content: center;
}
.share-modal-backdrop {
    position: absolute; inset: 0;
    background: radial-gradient(ellipse at center, rgba(8, 12, 24, 0.85) 0%, rgba(2, 2, 10, 0.97) 100%);
    backdrop-filter: blur(8px);
}

.share-modal-card {
    position: relative;
    width: min(640px, 94vw);
    background: linear-gradient(135deg, rgba(22, 30, 52, 0.97), rgba(8, 14, 28, 0.97));
    border: 1px solid rgba(86, 194, 255, 0.35);
    border-radius: 14px;
    box-shadow:
        0 0 40px rgba(86, 194, 255, 0.2),
        0 20px 60px rgba(0, 0, 0, 0.55);
    padding: 2rem 2.2rem 1.6rem;
    font-family: 'Rajdhani', system-ui, sans-serif;
    animation: hrSlideIn 0.35s cubic-bezier(0.2, 0.8, 0.25, 1);
}

.share-modal-close {
    position: absolute;
    top: 0.55rem;
    right: 0.75rem;
    background: none; border: none;
    color: #666;
    font-size: 1.4rem;
    cursor: pointer;
    width: 30px; height: 30px;
    border-radius: 50%;
    line-height: 1;
    transition: all 0.15s;
}
.share-modal-close:hover { color: #fff; background: rgba(255,255,255,0.08); }

.share-stage { text-align: center; }

.share-icon { font-size: 2.2rem; margin-bottom: 0.4rem; }

.share-title {
    font-family: 'Rajdhani', system-ui, sans-serif;
    font-size: 1.7rem;
    font-weight: 700;
    color: #fff;
    margin: 0 0 0.5rem;
    letter-spacing: 0.02em;
}

.share-body {
    color: #bbb;
    font-size: 0.95rem;
    line-height: 1.5;
    margin: 0 auto 1.4rem;
    max-width: 460px;
    font-family: -apple-system, system-ui, sans-serif;
}

.share-actions {
    display: flex;
    gap: 0.5rem;
    justify-content: center;
    flex-wrap: wrap;
    align-items: center;
}

/* Recording state */
.share-recording-dot {
    width: 18px;
    height: 18px;
    background: #ff4747;
    border-radius: 50%;
    margin: 0 auto 0.7rem;
    box-shadow: 0 0 0 0 rgba(255, 71, 71, 0.7);
    animation: shareRecPulse 1.2s ease-out infinite;
}
@keyframes shareRecPulse {
    0%   { box-shadow: 0 0 0 0 rgba(255, 71, 71, 0.75); }
    70%  { box-shadow: 0 0 0 18px rgba(255, 71, 71, 0);   }
    100% { box-shadow: 0 0 0 0 rgba(255, 71, 71, 0);      }
}

.share-progress {
    height: 6px;
    background: rgba(255, 255, 255, 0.05);
    border-radius: 3px;
    overflow: hidden;
    margin: 1rem auto 0.75rem;
    max-width: 420px;
}
.share-progress-bar {
    height: 100%;
    width: 0;
    background: linear-gradient(90deg, #56c2ff, #a24dff);
    box-shadow: 0 0 10px rgba(86, 194, 255, 0.6);
    transition: width 0.3s ease;
}

/* Preview state */
.share-preview {
    width: 100%;
    max-height: 50vh;
    border-radius: 8px;
    background: #000;
    margin-bottom: 0.8rem;
    border: 1px solid rgba(255, 255, 255, 0.06);
}

.share-meta {
    font-family: monospace;
    font-size: 0.72rem;
    color: #777;
    margin-bottom: 0.85rem;
    letter-spacing: 0.05em;
}

/* Reuse highlight-reel-btn styling for consistency; these modifiers just
   apply link styling to the anchor variant. */
a.highlight-reel-btn { text-decoration: none; display: inline-flex; align-items: center; }


/* Attribution footer — floated over the bottom-right corner so it doesn't
   steal canvas height from the flex layout. */
.replay-footer-attribution {
    position: absolute;
    right: 12px;
    bottom: 4px;
    text-align: right;
    color: #555;
    font-size: 0.66rem;
    padding: 0;
    margin: 0;
    pointer-events: none;
    z-index: 4;
    max-width: 60%;
    opacity: 0.7;
}
.replay-footer-attribution a { pointer-events: auto; }
.replay-footer-attribution a {
    color: #888;
    text-decoration: none;
}
.replay-footer-attribution a:hover { color: #ccc; text-decoration: underline; }

/* Responsive: scale the overlay sidebar down on narrow viewports so it
   doesn't eat most of the map area. */
@media (max-width: 900px) {
    .replay-sidebar {
        width: min(320px, calc(100% - 24px));
        height: min(60vh, calc(100% - 24px));
    }
}

/* Transport Controls */
.replay-controls,
.replay-canvas-controls {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.75rem 1rem;
    background: rgba(255, 255, 255, 0.04);
    border-radius: 10px;
    backdrop-filter: blur(8px);
}

.replay-controls {
    margin-top: 0.75rem;
}

.replay-canvas-controls {
    position: absolute;
    left: 12px;
    right: 12px;
    bottom: 12px;
    z-index: 8;
    background: rgba(8, 12, 24, 0.86);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 14px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35);
}

.replay-transport {
    display: flex;
    gap: 0.25rem;
    flex-shrink: 0;
}

.transport-btn {
    background: none;
    border: 1px solid rgba(255, 255, 255, 0.1);
    color: #ccc;
    width: 32px;
    height: 32px;
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.85rem;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s, border-color 0.15s;
}

.transport-btn:hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.2);
}

.transport-btn.play-btn {
    width: 38px;
    height: 38px;
    font-size: 1rem;
    border-color: var(--primary-color, #00d4ff);
    color: var(--primary-color, #00d4ff);
}

.transport-btn.play-btn:hover {
    background: rgba(0, 212, 255, 0.12);
}

/* Annotation / drawing tools — toggle button lives in the main control
   row; the options strip (size slider, color, undo, clear) reveals only
   once draw mode is active so the bar isn't cluttered the rest of the
   time. */
.replay-draw-tools {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-left: 2px;
}

.transport-btn.draw-toggle-btn.active {
    background: rgba(255, 59, 48, 0.18);
    border-color: rgba(255, 59, 48, 0.7);
    color: #ff6b5a;
}

/* Pathing overlay toggle — compact text label sitting next to DRAW in the
   transport row. Same base style as other transport buttons; ACTIVE uses
   a soft red wash consistent with the no-path tile color so the button
   reads as "the red overlay is on" at a glance. */
.transport-btn.path-toggle-btn {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    padding: 4px 10px;
    min-width: 0;
}

.transport-btn.path-toggle-btn.active {
    background: rgba(255, 80, 80, 0.18);
    border-color: rgba(255, 80, 80, 0.7);
    color: #ff8a80;
}

.replay-draw-options {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 2px 6px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 8px;
}

.replay-draw-options[hidden] {
    display: none;
}

.replay-draw-size {
    -webkit-appearance: none;
    appearance: none;
    width: 90px;
    height: 4px;
    background: rgba(255, 255, 255, 0.12);
    border-radius: 2px;
    outline: none;
    cursor: pointer;
}

.replay-draw-size::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #ff6b5a;
    border: 2px solid #1a1a2a;
    cursor: pointer;
}

.replay-draw-size::-moz-range-thumb {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #ff6b5a;
    border: 2px solid #1a1a2a;
    cursor: pointer;
}

.replay-draw-color {
    width: 24px;
    height: 24px;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 4px;
    background: transparent;
    cursor: pointer;
}

.replay-draw-color::-webkit-color-swatch-wrapper { padding: 2px; }
.replay-draw-color::-webkit-color-swatch { border: none; border-radius: 2px; }
.replay-draw-color::-moz-color-swatch { border: none; border-radius: 2px; }

.transport-btn.draw-aux-btn {
    width: 26px;
    height: 26px;
    font-size: 0.8rem;
}

/* Timeline Slider */
.replay-timeline {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: 1;
    min-width: 0;
}

.replay-time-label {
    color: #aaa;
    font-size: 0.8rem;
    font-family: monospace;
    min-width: 3.5em;
    text-align: center;
    flex-shrink: 0;
}

.replay-slider {
    flex: 1;
    -webkit-appearance: none;
    appearance: none;
    height: 6px;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 3px;
    outline: none;
    cursor: pointer;
}

.replay-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--primary-color, #00d4ff);
    cursor: pointer;
    border: none;
    box-shadow: 0 0 6px rgba(0, 212, 255, 0.4);
}

.replay-slider::-moz-range-thumb {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--primary-color, #00d4ff);
    cursor: pointer;
    border: none;
    box-shadow: 0 0 6px rgba(0, 212, 255, 0.4);
}

/* Speed Buttons */
.replay-speed {
    display: flex;
    gap: 0.2rem;
    flex-shrink: 0;
}

.speed-btn {
    background: none;
    border: 1px solid rgba(255, 255, 255, 0.08);
    color: #888;
    padding: 0.25rem 0.5rem;
    border-radius: 4px;
    cursor: pointer;
    font-size: 0.75rem;
    font-weight: 500;
    transition: all 0.15s;
}

.speed-btn:hover {
    color: #ccc;
    border-color: rgba(255, 255, 255, 0.2);
}

.speed-btn.active {
    color: var(--primary-color, #00d4ff);
    border-color: var(--primary-color, #00d4ff);
    background: rgba(0, 212, 255, 0.08);
}

/* Top-bar fog toggle — master on/off for fog of war. Perspective switching
   happens by clicking a player name in the top bar, not here. */
.replay-topbar-fog-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.35rem 0.65rem;
    margin-left: 0.5rem;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.12);
    color: #8a92a0;
    border-radius: 4px;
    cursor: pointer;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    transition: all 0.15s;
}

.replay-topbar-fog-btn:hover {
    color: #ccc;
    border-color: rgba(255, 255, 255, 0.25);
}

.replay-topbar-fog-btn.active {
    color: #c79bff;
    border-color: rgba(199, 155, 255, 0.55);
    background: rgba(153, 102, 204, 0.10);
}

/* "Fog: Selected" state uses an amber tint so it's visually distinct from
   the default "Fog: Both" purple — matches the mental model of zooming
   in on a single player's POV. "Fog: Off" drops back to the inactive
   gray via the missing .active class. */
.replay-topbar-fog-btn[data-mode="selected"] {
    color: #fbbf24;
    border-color: rgba(251, 191, 36, 0.55);
    background: rgba(251, 191, 36, 0.08);
}

.replay-topbar-fog-btn .fog-icon { font-size: 0.95rem; line-height: 1; }

/* Top-bar player names double as the perspective switcher. Rendered as
   buttons so keyboard + click focus behaves correctly; visually they
   keep the dot + name + race marker. Active = currently selected POV. */
.p-player-name {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.15rem 0.4rem;
    margin: 0 0.1rem;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 4px;
    color: inherit;
    font: inherit;
    cursor: pointer;
    transition: all 0.12s;
}

.p-player-name:hover {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.10);
}

.p-player-name.active {
    background: rgba(153, 102, 204, 0.12);
    border-color: rgba(199, 155, 255, 0.55);
    color: #e6e9ef;
}

/* Footer */
.replay-footer {
    text-align: center;
    margin-top: 1rem;
    padding-bottom: 2rem;
}

/* ==========================================================================
   Build Order Panels
   ========================================================================== */

.build-order-panel {
    width: 220px;
    min-width: 0;
    overflow-y: auto;
    overflow-x: hidden;
    background: rgba(0, 0, 0, 0.35);
    border: 1px solid rgba(255, 255, 255, 0.06);
    font-size: 0.8rem;
    font-family: monospace;
    scrollbar-width: thin;
    scrollbar-color: rgba(255,255,255,0.12) transparent;
}

.build-order-panel::-webkit-scrollbar { width: 4px; }
.build-order-panel::-webkit-scrollbar-thumb {
    background: rgba(255,255,255,0.12);
    border-radius: 2px;
}

#build-order-p1 { border-radius: 10px 0 0 10px; }
#build-order-p2 { border-radius: 0 10px 10px 0; }

.bo-panel-header {
    position: sticky;
    top: 0;
    padding: 0.5rem 0.6rem;
    background: rgba(8, 8, 18, 0.95);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    font-weight: 600;
    font-size: 0.82rem;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    color: #ccc;
}

.bo-panel-header .player-color-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}

/* Build order items */
.bo-item {
    display: flex;
    align-items: center;
    padding: 2px 0.6rem;
    gap: 0.45rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.025);
    color: #999;
    transition: background 0.15s;
}

.bo-item.bo-latest {
    background: rgba(255, 255, 255, 0.07);
    color: #fff;
}

.bo-supply {
    color: #666;
    min-width: 2em;
    text-align: right;
    font-size: 0.75rem;
}

.bo-name {
    flex: 1;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.bo-compare {
    display: none;
    min-width: 3.8em;
    padding: 1px 0.35rem;
    border-radius: 999px;
    font-size: 0.68rem;
    font-weight: 700;
    line-height: 1.35;
    text-align: right;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.01em;
}

.bo-item.has-comp .bo-compare {
    display: inline-block;
}

.bo-time {
    color: #555;
    font-size: 0.7rem;
    min-width: 3.2em;
    text-align: right;
}

/* Cancelled-building badges (Engineering Bay block, Pylon cancel, etc.) */
.bo-cancel-badge {
    display: inline-block;
    margin-left: 0.4em;
    padding: 0 0.35em;
    border-radius: 3px;
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    vertical-align: middle;
    line-height: 1.4;
    background: rgba(220, 53, 69, 0.18);
    color: #ff6b7a;
    border: 1px solid rgba(220, 53, 69, 0.35);
}

.bo-item.bo-cancel-ebay_block .bo-cancel-badge,
.bo-item.bo-cancel-pylon_cancel .bo-cancel-badge {
    background: rgba(220, 53, 69, 0.22);
    color: #ff6b7a;
    border-color: rgba(220, 53, 69, 0.45);
}

.bo-item.bo-cancel-proxy_cancel .bo-cancel-badge {
    background: rgba(240, 173, 78, 0.18);
    color: #f3b55b;
    border-color: rgba(240, 173, 78, 0.35);
}

.bo-item.bo-cancel-gas_steal .bo-cancel-badge {
    background: rgba(153, 102, 204, 0.22);
    color: #c79bff;
    border-color: rgba(153, 102, 204, 0.4);
}

.bo-item.bo-cancel-normal .bo-cancel-badge,
.bo-item.bo-cancel-bunker_cancel .bo-cancel-badge {
    background: rgba(150, 150, 150, 0.15);
    color: #bbb;
    border-color: rgba(150, 150, 150, 0.3);
}

.bo-item.bo-cancel .bo-name {
    text-decoration: line-through;
    text-decoration-color: rgba(255, 107, 122, 0.5);
    text-decoration-thickness: 1px;
}

/* Type-based styling */
.bo-building .bo-name { font-weight: 600; color: #ddd; }
.bo-upgrade .bo-name { color: var(--accent-color, #7b2ff7); font-style: italic; }
.bo-unit .bo-name { color: #aaa; }

.bo-item.bo-latest.bo-building .bo-name { color: #fff; }
.bo-item.bo-latest.bo-unit .bo-name { color: #ddd; }

/* Battle summary cards */
.bo-battle {
    margin: 4px 5px;
    padding: 5px 7px;
    background: rgba(255, 152, 0, 0.06);
    border: 1px solid rgba(255, 152, 0, 0.2);
    border-radius: 5px;
    font-size: 0.72rem;
}

.bo-battle-header {
    font-weight: 700;
    color: #ff9800;
    margin-bottom: 2px;
    font-size: 0.75rem;
}

.bo-battle-losses {
    color: #bbb;
    line-height: 1.4;
}

.bo-battle-supply {
    color: #999;
    font-size: 0.68rem;
    margin-top: 1px;
}

.bo-battle-outcome {
    margin-top: 3px;
    font-weight: 700;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.outcome-win { color: #4caf50; }
.outcome-loss { color: #f44336; }
.outcome-trade { color: #ff9800; }

/* Harassment cards */
.bo-harass {
    margin: 4px 5px;
    padding: 5px 7px;
    border-radius: 5px;
    font-size: 0.72rem;
}

.bo-harass-victim {
    background: rgba(244, 67, 54, 0.08);
    border: 1px solid rgba(244, 67, 54, 0.25);
}

.bo-harass-attacker {
    background: rgba(76, 175, 80, 0.08);
    border: 1px solid rgba(76, 175, 80, 0.25);
}

.bo-harass-header {
    font-weight: 700;
    font-size: 0.75rem;
}

.bo-harass-victim .bo-harass-header { color: #f44336; }
.bo-harass-attacker .bo-harass-header { color: #4caf50; }

.bo-harass-count {
    color: #bbb;
    margin-top: 1px;
}

/* Battle detail modal */
.battle-modal {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.7);
    backdrop-filter: blur(4px);
}

.battle-modal-content {
    position: relative;
    background: rgba(15, 15, 30, 0.97);
    border: 1px solid rgba(255, 152, 0, 0.3);
    border-radius: 12px;
    padding: 1.5rem 2rem;
    max-width: 560px;
    width: 90%;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6), 0 0 20px rgba(255, 152, 0, 0.08);
}

.battle-modal-close {
    position: absolute;
    top: 0.6rem;
    right: 0.8rem;
    background: none;
    border: none;
    color: #888;
    font-size: 1.4rem;
    cursor: pointer;
    line-height: 1;
}

.battle-modal-close:hover { color: #fff; }

.battle-modal-title {
    text-align: center;
    color: #ff9800;
    font-weight: 700;
    font-size: 1.1rem;
    margin-bottom: 1rem;
}

.battle-modal-versus {
    display: flex;
    gap: 1.5rem;
    align-items: flex-start;
}

.battle-modal-side {
    flex: 1;
    min-width: 0;
}

.battle-side-header {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-weight: 600;
    font-size: 0.9rem;
    margin-bottom: 0.5rem;
    color: #ddd;
}

.battle-side-header .player-color-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}

.battle-side-losses {
    font-size: 0.82rem;
    line-height: 1.6;
    color: #bbb;
    font-family: monospace;
}

.battle-side-losses .unit-loss {
    display: flex;
    justify-content: space-between;
    padding: 1px 0;
}

.battle-side-total {
    margin-top: 0.4rem;
    padding-top: 0.4rem;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
    font-weight: 600;
    font-size: 0.85rem;
}

.battle-side-total.positive { color: #4caf50; }
.battle-side-total.negative { color: #f44336; }

.battle-modal-divider {
    width: 1px;
    background: rgba(255, 255, 255, 0.1);
    align-self: stretch;
    flex-shrink: 0;
}

.battle-modal-outcome {
    text-align: center;
    margin-top: 1rem;
    font-weight: 700;
    font-size: 0.9rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

/* Responsive */
@media (max-width: 900px) {
    .build-order-panel { display: none; }
}

@media (max-width: 700px) {
    .replay-controls,
    .replay-canvas-controls {
        flex-wrap: wrap;
        justify-content: center;
    }

    .replay-timeline {
        order: 3;
        width: 100%;
    }

    .replay-players {
        flex-direction: column;
        gap: 0.5rem;
    }

    .replay-canvas-topbar {
        flex-direction: column;
        align-items: stretch;
    }

    .replay-inline-comparison {
        max-width: none;
    }

    .replay-canvas-actions {
        justify-content: stretch;
    }

    .replay-canvas-actions .btn-primary,
    .replay-canvas-actions .btn-secondary {
        flex: 1;
    }
}

/* ── Comparison Panel ── */
.replay-comparison {
    background: rgba(15, 23, 42, 0.95);
    border: 1px solid #334155;
    border-radius: 12px;
    padding: 1.25rem;
    margin-top: 0.75rem;
}
.comparison-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
}
.comparison-header h3 {
    color: #f8fafc;
    font-size: 1.1rem;
    margin: 0;
}
.btn-sm { padding: 0.25rem 0.6rem; font-size: 0.85rem; }
.spinner-sm { width: 18px; height: 18px; border: 2px solid #3b82f6; border-top-color: transparent; border-radius: 50%; animation: spin 0.6s linear infinite; display: inline-block; margin-right: 0.5rem; }
@keyframes spin { to { transform: rotate(360deg); } }
#comparison-loading { align-items: center; color: #94a3b8; font-size: 0.9rem; }

.comparison-cards {
    display: flex;
    gap: 1rem;
    margin-bottom: 0.75rem;
}
.comp-card {
    flex: 1;
    background: rgba(30, 41, 59, 0.8);
    border: 1px solid #334155;
    border-radius: 10px;
    padding: 0.85rem;
    text-align: center;
}
.comp-card-value { font-size: 1.6rem; font-weight: 700; color: #f8fafc; }
.comp-card-label { font-size: 0.75rem; color: #94a3b8; margin-top: 0.25rem; }
.comp-archetype { font-size: 1rem; }
.comp-score.good .comp-card-value { color: #34d399; }
.comp-score.ok .comp-card-value { color: #fbbf24; }
.comp-score.poor .comp-card-value { color: #f87171; }

.comparison-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}
.comp-stat {
    font-size: 0.8rem;
    padding: 0.2rem 0.6rem;
    border-radius: 9999px;
    background: rgba(51, 65, 85, 0.6);
    color: #cbd5e1;
}
.comp-stat.on-time { border: 1px solid #34d399; color: #6ee7b7; }
.comp-stat.late { border: 1px solid #fbbf24; color: #fde68a; }
.comp-stat.very-late { border: 1px solid #f87171; color: #fca5a5; }
.comp-stat.missing { border: 1px solid #64748b; color: #94a3b8; }

.comparison-deviation {
    background: rgba(251, 191, 36, 0.1);
    border: 1px solid rgba(251, 191, 36, 0.3);
    border-radius: 8px;
    padding: 0.6rem 0.85rem;
    font-size: 0.85rem;
    color: #fde68a;
    margin-bottom: 0.75rem;
}
.comparison-error {
    color: #f87171;
    font-size: 0.9rem;
    padding: 0.5rem;
}

/* Step list */
.comp-steps-list {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    max-height: 320px;
    overflow-y: auto;
}
.comp-step {
    display: grid;
    grid-template-columns: 8px 1fr 50px 50px 55px;
    gap: 0.5rem;
    align-items: center;
    padding: 0.35rem 0.5rem;
    border-radius: 6px;
    font-size: 0.8rem;
    color: #cbd5e1;
    background: rgba(15, 23, 42, 0.4);
}
.comp-step:hover { background: rgba(30, 41, 59, 0.8); }
.comp-step-indicator {
    width: 8px; height: 8px; border-radius: 50%;
}
.comp-step.on_track .comp-step-indicator { background: #34d399; }
.comp-step.late .comp-step-indicator { background: #fbbf24; }
.comp-step.very_late .comp-step-indicator { background: #f87171; }
.comp-step.missing .comp-step-indicator { background: #64748b; }
.comp-step-desc { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.comp-step-expected { color: #64748b; text-align: right; font-variant-numeric: tabular-nums; }
.comp-step-actual { text-align: right; font-variant-numeric: tabular-nums; }
.comp-step-delta { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
.comp-step.on_track .comp-step-delta { color: #34d399; }
.comp-step.late .comp-step-delta { color: #fbbf24; }
.comp-step.very_late .comp-step-delta { color: #f87171; }
.comp-step.missing .comp-step-delta { color: #64748b; }

.comp-steps-list::-webkit-scrollbar { width: 5px; }
.comp-steps-list::-webkit-scrollbar-track { background: transparent; }
.comp-steps-list::-webkit-scrollbar-thumb { background: rgba(100, 116, 139, 0.4); border-radius: 3px; }

/* Build panel item overlays */
/* Commit 3: addon-swap event row in the build sidebar. Distinct from the
   regular bo-item so it reads as a flow annotation between build steps. */
.bo-swap {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.3rem 0.55rem;
    margin: 0.2rem 0;
    border-radius: 4px;
    background: rgba(86, 194, 255, 0.06);
    border-left: 2px solid var(--race-t, #56c2ff);
    color: #b9e2ff;
    font-family: var(--ui, 'Inter', sans-serif);
    font-size: 0.72rem;
    line-height: 1.2;
}

.bo-swap-time {
    font-family: var(--mono, 'JetBrains Mono', monospace);
    color: var(--text-dim, #aab3c2);
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
    min-width: 2.8ch;
}

.bo-swap-arrow {
    color: var(--race-t, #56c2ff);
    font-size: 0.85rem;
    line-height: 1;
    flex-shrink: 0;
}

.bo-swap-label {
    color: var(--text, #e6e9ef);
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.bo-item.comp-on-time { border-left: 3px solid #34d399; }
.bo-item.comp-ahead { border-left: 3px solid #56c2ff; }
.bo-item.comp-late { border-left: 3px solid #fbbf24; }
.bo-item.comp-very-late { border-left: 3px solid #f87171; }
.bo-item.comp-missing { border-left: 3px solid #64748b; }
.bo-item.comp-on-time .bo-compare { background: rgba(52, 211, 153, 0.12); color: #6ee7b7; }
.bo-item.comp-ahead .bo-compare { background: rgba(86, 194, 255, 0.12); color: #93d5ff; }
.bo-item.comp-late .bo-compare { background: rgba(251, 191, 36, 0.14); color: #fde68a; }
.bo-item.comp-very-late .bo-compare { background: rgba(248, 113, 113, 0.14); color: #fca5a5; }
.bo-item.comp-missing .bo-compare { background: rgba(100, 116, 139, 0.18); color: #cbd5e1; }

/* Production cycle annotations */
.bo-item.comp-cycle-good { border-left: 3px solid #60a5fa; }
.bo-item.comp-cycle-ok { border-left: 3px solid #a78bfa; }
.bo-item.comp-cycle-slow { border-left: 3px solid #fb923c; }
.bo-item.comp-cycle-good .bo-compare { background: rgba(96, 165, 250, 0.12); color: #93c5fd; }
.bo-item.comp-cycle-ok .bo-compare { background: rgba(167, 139, 250, 0.12); color: #c4b5fd; }
.bo-item.comp-cycle-slow .bo-compare { background: rgba(251, 146, 60, 0.14); color: #fdba74; }

/* Benchmark timing annotations (supply, gas, defensive, upgrades) */
.bo-item.comp-bench-on-time { border-left: 3px solid #34d399; opacity: 0.85; }
.bo-item.comp-bench-early { border-left: 3px solid #22d3ee; }
.bo-item.comp-bench-late { border-left: 3px solid #fbbf24; opacity: 0.85; }
.bo-item.comp-bench-very-late { border-left: 3px solid #f87171; opacity: 0.85; }
.bo-item.comp-bench-on-time .bo-compare { background: rgba(52, 211, 153, 0.10); color: #6ee7b7; font-size: 0.75em; }
.bo-item.comp-bench-early .bo-compare { background: rgba(34, 211, 238, 0.10); color: #67e8f9; font-size: 0.75em; }
.bo-item.comp-bench-late .bo-compare { background: rgba(251, 191, 36, 0.10); color: #fde68a; font-size: 0.75em; }
.bo-item.comp-bench-very-late .bo-compare { background: rgba(248, 113, 113, 0.10); color: #fca5a5; font-size: 0.75em; }

/* =========================================================================
   Insights Panel — Macro / Micro / Win% / Scouting
   ========================================================================= */

/* Player Picker */
.player-picker {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    padding: 1.25rem;
    margin-bottom: 0.5rem;
    background: rgba(15, 15, 30, 0.6);
    border: 1px solid rgba(100, 116, 139, 0.2);
    border-radius: 8px;
    backdrop-filter: blur(8px);
}
.picker-title {
    color: #e0e0e0;
    font-size: 0.95rem;
    margin: 0;
}
.picker-buttons {
    display: flex;
    gap: 0.75rem;
}
.picker-btn {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.6rem 1.2rem;
    background: rgba(30, 30, 60, 0.8);
    border: 1px solid rgba(100, 116, 139, 0.3);
    border-radius: 6px;
    color: #e0e0e0;
    font-size: 0.9rem;
    cursor: pointer;
    transition: border-color 0.2s, background 0.2s;
}
.picker-btn:hover {
    border-color: #00d4ff;
    background: rgba(0, 212, 255, 0.08);
}

/* Canvas wrapper for overlay */
.canvas-wrapper {
    flex: 1;
    min-width: 0;
    display: flex;
    position: relative;
    overflow: hidden;
}
/* Canvas size is set by JS via _sizeCanvas() with explicit
   width/height style. No CSS override needed. */

.replay-canvas-topbar {
    position: absolute;
    top: 12px;
    left: 12px;
    right: 12px;
    z-index: 8;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    pointer-events: none;
}

.replay-inline-comparison,
.replay-canvas-actions {
    pointer-events: auto;
}

.replay-canvas-actions {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
}

.replay-canvas-actions .btn-primary,
.replay-canvas-actions .btn-secondary {
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.18);
}

.replay-inline-comparison {
    position: relative;
    max-width: min(360px, 45%);
    max-height: min(240px, 38vh);
    overflow-y: auto;
    padding: 0.6rem 0.75rem;
    background: rgba(5, 10, 20, 0.82);
    border: 1px solid rgba(125, 211, 252, 0.18);
    border-radius: 12px;
    backdrop-filter: blur(12px);
    box-shadow: 0 12px 30px rgba(0, 0, 0, 0.32);
    font-size: 0.78rem;
}
.inline-comp-close {
    position: absolute;
    top: 6px;
    right: 8px;
    background: none;
    border: none;
    color: #94a3b8;
    font-size: 1.1rem;
    cursor: pointer;
    line-height: 1;
    padding: 2px 6px;
    border-radius: 4px;
    pointer-events: auto;
}
.inline-comp-close:hover {
    color: #f8fafc;
    background: rgba(255,255,255,0.1);
}
.inline-comp-grades {
    margin-top: 0.6rem;
    padding-top: 0.6rem;
    border-top: 1px solid rgba(100, 116, 139, 0.2);
}
.inline-comp-grade-overall {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 0.5rem;
}
.inline-comp-grade-overall .grade-letter {
    font-size: 1.2rem;
    font-weight: 800;
}
.inline-comp-grade-feedback {
    font-size: 0.75rem;
    color: #94a3b8;
}
.inline-comp-grade-cats {
    display: flex;
    gap: 0.5rem;
}
/* Insights toolbar when inside canvas topbar */
.insights-toolbar-canvas {
    padding: 0;
    pointer-events: auto;
}

.inline-comp-head {
    display: flex;
    align-items: center;
    gap: 0.8rem;
}

.inline-comp-score {
    min-width: 2.9rem;
    padding: 0.35rem 0.55rem;
    border-radius: 10px;
    background: rgba(15, 23, 42, 0.9);
    font-size: 1.15rem;
    font-weight: 800;
    text-align: center;
    line-height: 1.1;
    color: #f8fafc;
}

.inline-comp-score.good { color: #34d399; }
.inline-comp-score.ok { color: #fbbf24; }
.inline-comp-score.poor { color: #f87171; }

.inline-comp-meta {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.inline-comp-title {
    color: #f8fafc;
    font-size: 0.9rem;
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.inline-comp-sub {
    color: #94a3b8;
    font-size: 0.75rem;
}

.inline-comp-branch {
    color: #7cb4e6;
    font-size: 0.8rem;
    font-weight: 600;
}

.inline-comp-branch-meta {
    color: #94a3b8;
    font-weight: 400;
    margin-left: 0.3rem;
}

.inline-comp-stats,
.inline-comp-missing {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: 0.6rem;
}

.inline-comp-pill,
.inline-comp-missing-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.22rem 0.55rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 600;
    background: rgba(30, 41, 59, 0.72);
    color: #cbd5e1;
}

.inline-comp-pill.on-time { border: 1px solid rgba(52, 211, 153, 0.4); color: #6ee7b7; }
.inline-comp-pill.ahead { border: 1px solid rgba(86, 194, 255, 0.4); color: #93d5ff; }
.inline-comp-pill.late { border: 1px solid rgba(251, 191, 36, 0.4); color: #fde68a; }
.inline-comp-pill.very-late { border: 1px solid rgba(248, 113, 113, 0.4); color: #fca5a5; }
.inline-comp-pill.missing { border: 1px solid rgba(148, 163, 184, 0.35); color: #cbd5e1; }

.inline-comp-first {
    margin-top: 0.65rem;
    padding-top: 0.6rem;
    border-top: 1px solid rgba(148, 163, 184, 0.18);
    color: #e2e8f0;
    font-size: 0.76rem;
}

.inline-comp-first strong {
    color: #f8fafc;
}

.inline-comp-missing-chip {
    background: rgba(51, 65, 85, 0.65);
    border: 1px solid rgba(100, 116, 139, 0.3);
}

.inline-comp-hint {
    margin-top: 0.55rem;
    color: #7dd3fc;
    font-size: 0.68rem;
    letter-spacing: 0.02em;
}

.replay-comparison-overlay {
    position: absolute;
    top: 92px;
    right: 12px;
    z-index: 8;
    width: min(440px, calc(100% - 24px));
    max-height: calc(100% - 176px);
    margin-top: 0;
    overflow: hidden;
    box-shadow: 0 18px 42px rgba(0, 0, 0, 0.42);
    backdrop-filter: blur(12px);
}

.replay-comparison-overlay .comparison-steps {
    min-height: 0;
}

.replay-comparison-overlay .comp-steps-list {
    max-height: min(360px, calc(100vh - 320px));
}

/* Grade Colors (shared) */
.grade-color-gold   { color: #ffd700; }
.grade-color-green  { color: #34d399; }
.grade-color-blue   { color: #60a5fa; }
.grade-color-yellow { color: #fbbf24; }
.grade-color-orange { color: #fb923c; }
.grade-color-red    { color: #f87171; }

/* Grade Banner */
.grade-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    padding: 0.75rem 1.25rem;
    margin-bottom: 0.25rem;
    background: rgba(15, 15, 30, 0.7);
    border: 1px solid rgba(100, 116, 139, 0.2);
    border-radius: 8px;
    backdrop-filter: blur(8px);
}
.grade-overall {
    display: flex;
    align-items: center;
    gap: 1rem;
}
.grade-letter {
    font-size: 2.2rem;
    font-weight: 800;
    line-height: 1;
    min-width: 2.5rem;
    text-align: center;
}
.grade-overall-info {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}
.grade-overall-label {
    color: #e0e0e0;
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.grade-overall-feedback {
    color: #a0a0b0;
    font-size: 0.78rem;
    line-height: 1.3;
    max-width: 380px;
}
.grade-categories {
    display: flex;
    gap: 0.75rem;
}
.grade-pill {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.15rem;
    padding: 0.35rem 0.6rem;
    background: rgba(20, 20, 45, 0.6);
    border: 1px solid rgba(100, 116, 139, 0.15);
    border-radius: 6px;
    min-width: 3.5rem;
}
.grade-pill-letter {
    font-size: 1.2rem;
    font-weight: 700;
    line-height: 1;
}
.grade-pill-label {
    font-size: 0.65rem;
    color: #64748b;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/* Toolbar grade badges */
.toolbar-grade {
    font-size: 0.65rem;
    font-weight: 700;
    margin-left: 0.35rem;
}

/* Eval bar toggle button */
.eval-toggle-btn.active {
    color: #2ecc71;
    border-color: rgba(46, 204, 113, 0.4);
}

/* Grade header inside insight panels */
.insights-grade-header {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.6rem 0.75rem;
    margin-bottom: 0.75rem;
    background: rgba(15, 15, 35, 0.5);
    border: 1px solid rgba(100, 116, 139, 0.12);
    border-radius: 6px;
}
.grade-header-letter {
    font-size: 1.6rem;
    font-weight: 800;
    line-height: 1;
    min-width: 2rem;
    text-align: center;
}
.grade-header-body {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    flex: 1;
}
.grade-header-score {
    color: #64748b;
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
}
.grade-header-feedback {
    color: #c0c0d0;
    font-size: 0.8rem;
    line-height: 1.4;
    margin: 0;
}

@media (max-width: 700px) {
    .grade-banner {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.75rem;
    }
}

/* Insights Toolbar */
.insights-toolbar {
    display: flex;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.5rem 0;
}
.insights-btn {
    padding: 0.4rem 1rem;
    background: #1a1a2e;
    border: 1px solid rgba(100, 116, 139, 0.3);
    border-radius: 20px;
    color: #a0a0b0;
    font-size: 0.8rem;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.2s;
}
.insights-btn:hover {
    border-color: #00d4ff;
    color: #e0e0e0;
}
.insights-btn.active {
    background: rgba(0, 212, 255, 0.15);
    border-color: #00d4ff;
    color: #00d4ff;
    box-shadow: 0 0 8px rgba(0, 212, 255, 0.2);
}

/* Insights Panel Container */
/* Insights Panel — overlays the canvas area */
.insights-panel {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 20;
    background: rgba(6, 6, 16, 0.92);
    border-radius: 8px;
    padding: 1rem 1.5rem;
    overflow-y: auto;
    backdrop-filter: blur(12px);
}
.insights-panel::-webkit-scrollbar { width: 5px; }
.insights-panel::-webkit-scrollbar-track { background: transparent; }
.insights-panel::-webkit-scrollbar-thumb { background: rgba(100, 116, 139, 0.4); border-radius: 3px; }

.insights-close-btn {
    position: absolute;
    top: 0.5rem;
    right: 0.75rem;
    background: none;
    border: none;
    color: #a0a0b0;
    font-size: 1.4rem;
    cursor: pointer;
    z-index: 2;
    line-height: 1;
    padding: 0.2rem 0.4rem;
    border-radius: 4px;
    transition: color 0.15s, background 0.15s;
}
.insights-close-btn:hover {
    color: #e0e0e0;
    background: rgba(255,255,255,0.08);
}

.insights-empty {
    color: #64748b;
    text-align: center;
    padding: 1.5rem;
    font-size: 0.9rem;
}

/* Chart containers — taller for readability */
.insights-chart-container {
    position: relative;
    height: 280px;
    margin-bottom: 1rem;
    background: rgba(6, 6, 16, 0.5);
    border-radius: 6px;
    padding: 0.5rem;
}

/* Insight Cards */
.insights-card {
    background: rgba(15, 15, 35, 0.6);
    border: 1px solid rgba(100, 116, 139, 0.15);
    border-radius: 8px;
    padding: 0.75rem 1rem;
    margin-bottom: 0.75rem;
}
.insights-card-title {
    color: #e0e0e0;
    font-size: 0.85rem;
    font-weight: 600;
    margin-bottom: 0.5rem;
}
.insights-card-value {
    color: #00d4ff;
    font-size: 1.3rem;
    font-weight: 700;
}
.insights-card-detail {
    color: #a0a0b0;
    font-size: 0.8rem;
    margin-top: 0.25rem;
}
.insights-card-list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: 0.5rem;
}
.insights-card-hint {
    color: #64748b;
    font-size: 0.75rem;
    margin-top: 0.5rem;
    font-style: italic;
}
.insights-warn-card {
    border-left: 3px solid #f87171;
}

/* Stats row (horizontal stat display) */
.insights-stats-row {
    display: flex;
    gap: 1.5rem;
    flex-wrap: wrap;
}
.insights-stat {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.15rem;
}
.stat-value {
    font-size: 1.1rem;
    font-weight: 700;
    color: #e0e0e0;
    font-variant-numeric: tabular-nums;
}
.stat-label {
    font-size: 0.7rem;
    color: #64748b;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/* Macro card */
.insights-macro-card {
    border-left: 3px solid #00d4ff;
}

/* Badges */
.insights-badge {
    display: inline-block;
    padding: 0.15rem 0.5rem;
    border-radius: 10px;
    font-size: 0.7rem;
    font-weight: 600;
}
.badge-green { background: rgba(52, 211, 153, 0.2); color: #34d399; }
.badge-yellow { background: rgba(251, 191, 36, 0.2); color: #fbbf24; }
.badge-red { background: rgba(248, 113, 113, 0.2); color: #f87171; }

/* Engagement list */
.insights-engagement-list {
    max-height: 240px;
    overflow-y: auto;
    margin-top: 0.5rem;
}
.insights-engagement-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.4rem 0.6rem;
    border-left: 3px solid transparent;
    border-radius: 4px;
    cursor: pointer;
    font-size: 0.8rem;
    color: #c0c0d0;
    transition: background 0.15s;
}
.insights-engagement-row:hover {
    background: rgba(255, 255, 255, 0.04);
}
.eng-time {
    color: #64748b;
    font-variant-numeric: tabular-nums;
    min-width: 3rem;
}
.eng-badge {
    padding: 0.1rem 0.4rem;
    border-radius: 4px;
    font-size: 0.7rem;
    font-weight: 600;
    color: #000;
}
.eng-detail { flex: 1; }
.eng-armies {
    color: #64748b;
    font-size: 0.75rem;
}

/* Win rate toggle */
/* Legacy — kept for potential future use */
.insights-toggle {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0;
    color: #a0a0b0;
    font-size: 0.8rem;
    cursor: pointer;
}
.insights-toggle input[type="checkbox"] {
    accent-color: #00d4ff;
}

/* Key moments */
.insights-moments-list {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    margin-top: 0.4rem;
}
.insights-moment-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.3rem 0.5rem;
    border-radius: 4px;
    cursor: pointer;
    font-size: 0.8rem;
    color: #c0c0d0;
    transition: background 0.15s;
}
.insights-moment-row:hover {
    background: rgba(255, 255, 255, 0.04);
}
.moment-time {
    color: #64748b;
    font-variant-numeric: tabular-nums;
    min-width: 3rem;
}
.moment-arrow { font-size: 0.7rem; }
.moment-pct {
    font-weight: 600;
    min-width: 2.5rem;
    text-align: right;
}
.moment-desc {
    color: #a0a0b0;
    font-size: 0.75rem;
}

/* Scouting section */
.insights-scout-section {
    margin-bottom: 1rem;
}
.insights-scout-card {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    padding: 0.5rem 0.75rem;
    background: rgba(15, 15, 35, 0.4);
    border: 1px solid rgba(100, 116, 139, 0.1);
    border-radius: 6px;
    margin-bottom: 0.4rem;
    cursor: pointer;
    transition: background 0.15s;
}
.insights-scout-card:hover {
    background: rgba(20, 20, 45, 0.6);
}
.scout-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.8rem;
}
.scout-time {
    color: #64748b;
    font-variant-numeric: tabular-nums;
}
.scout-unit {
    color: #e0e0e0;
    font-weight: 500;
}
.scout-alive { color: #34d399; font-weight: bold; }
.scout-dead { color: #f87171; font-weight: bold; }
.scout-info {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}
.info-item {
    padding: 0.1rem 0.4rem;
    border-radius: 4px;
    font-size: 0.7rem;
    background: rgba(100, 116, 139, 0.15);
    color: #c0c0d0;
}
.info-item.info-critical {
    background: rgba(248, 113, 113, 0.15);
    color: #f87171;
}
.info-item.info-important {
    background: rgba(251, 191, 36, 0.15);
    color: #fbbf24;
}
.scout-summary {
    color: #c8c8d8;
    font-size: 0.8rem;
    line-height: 1.35;
    margin: 0.15rem 0 0.25rem;
    font-style: italic;
}
.scout-areas {
    font-size: 0.7rem;
    color: #64748b;
}

/* Responsive */
@media (max-width: 900px) {
    .insights-stats-row {
        gap: 1rem;
    }
    .insights-chart-container {
        height: 220px;
    }
}

/* -------------------------------------------------------------------------
 * FloatCard — translucent blur panel with collapsible header.
 * Primitive for the Analyst replay variant's floating rails. Design tokens
 * match design_handoff_sc2tree_ui/README.md (backdrop colors, border,
 * radius, shadow) so the visual language stays consistent across pages.
 * ------------------------------------------------------------------------- */

.replay-float-card {
    pointer-events: auto;
    display: flex;
    flex-direction: column;
    min-height: 44px;
    max-height: 44px;
    background: rgba(15, 19, 28, 0.82);
    -webkit-backdrop-filter: blur(16px);
    backdrop-filter: blur(16px);
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 10px;
    box-shadow: 0 24px 48px -12px rgba(0, 0, 0, 0.6);
    overflow: hidden;
    transition: max-height 0.25s cubic-bezier(.4, .2, .2, 1),
                background 0.15s ease;
    color: #e6e9ef;
    font-family: 'Inter', system-ui, sans-serif;
}

.replay-float-card.expanded {
    max-height: min(540px, 70vh);
    background: rgba(15, 19, 28, 0.94);
}

/* The right-rail card in Analyst mode hosts Production + the 4-row Tracker
   stacked together, which easily clears 540px when both are populated.
   Let it fill its parent rail (rail already reserves the scrubber gap via
   `bottom: 72px`), so the tracker fits without a scrollbar cutting off
   the Buildings Lost row. */
.replay-viewer.variant-analyst .replay-analyst-rail-right .replay-float-card.expanded {
    max-height: 100%;
}

.replay-float-card-header {
    display: flex;
    align-items: center;
    width: 100%;
    flex-shrink: 0;
    background: transparent;
    /* Previously a <button>; now a flex row containing a collapse button
       and an actions slot. Keep the wrapper transparent — hover state
       lives on the collapse button only, so clicking in the actions
       area doesn't visually flash a "collapsing" intent. */
}

/* Collapse button: fills the header row up to the actions slot. */
.replay-float-card-collapse {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 14px;
    background: transparent;
    border: 0;
    color: inherit;
    text-align: left;
    cursor: pointer;
    font: inherit;
    min-width: 0;  /* allow title to shrink before actions do */
}

.replay-float-card.align-right .replay-float-card-collapse {
    text-align: right;
    flex-direction: row-reverse;
}

.replay-float-card-collapse:hover {
    background: rgba(255, 255, 255, 0.03);
}

/* Header action slot — inline controls (filter toggles, mode switchers).
   Rendered between the collapse button and the right edge of the header. */
.replay-float-card-actions {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 0 8px 0 2px;       /* tightened so the title gets more room */
    flex-shrink: 0;
}
.replay-float-card-actions[hidden] { display: none; }

/* Compact styling for the "Compare to Pro Build" button when it's been
   relocated into the Build Order card's header slot (from the topbar).
   Shares a row with the Streamlined/All toggle and the card title, so
   every pixel shaved here gives the title more room before it hits
   the ellipsis. */
.build-card-compare {
    padding: 2px 7px;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    line-height: 1.4;
    border-radius: 4px;
    cursor: pointer;
    white-space: nowrap;
}

.replay-float-card-title {
    flex: 1 1 auto;
    min-width: 0;               /* allow title to shrink inside a cramped header */
    white-space: nowrap;        /* don't wrap "BUILD ORDER" onto two lines */
    overflow: hidden;
    text-overflow: ellipsis;    /* truncate cleanly when actions steal space */
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #e6e9ef;
}

.replay-float-card-title.accent-amber  { color: #fbbf24; }
.replay-float-card-title.accent-accent { color: #56c2ff; }
.replay-float-card-title.accent-green  { color: #4ade80; }
.replay-float-card-title.accent-red    { color: #f87171; }

.replay-float-card-count {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
    font-size: 10px;
    color: #6e7687;
    background: #141821;
    border: 1px solid rgba(255, 255, 255, 0.08);
    padding: 1px 6px;
    border-radius: 10px;
}

.replay-float-card-chevron {
    font-size: 9px;
    color: #6e7687;
    transition: transform 0.15s ease;
}

.replay-float-card.expanded .replay-float-card-chevron {
    transform: rotate(180deg);
}

.replay-float-card-body {
    border-top: 1px solid rgba(255, 255, 255, 0.08);
    overflow: hidden auto;
    flex: 1 1 auto;
    min-height: 0;
    display: none;
}

.replay-float-card.expanded .replay-float-card-body {
    display: block;
}

/* -------------------------------------------------------------------------
 * Analyst variant shell — full-bleed map with floating rails.
 * Scoped to .replay-viewer.variant-analyst so Refined stays untouched.
 * ------------------------------------------------------------------------- */

/* Rails are hidden by default; only Analyst mode shows them. */
.replay-analyst-rail {
    display: none;
}

.replay-viewer.variant-analyst .replay-analyst-rail {
    display: flex;
    flex-direction: column;
    gap: 8px;
    position: absolute;
    top: 12px;
    /* Leave headroom for the bottom transport bar so floating cards
       never overlap the scrubber even when fully expanded. */
    bottom: 72px;
    width: 340px;
    z-index: 5;
    /* Outer wrapper is click-through; individual FloatCards re-enable
       pointer-events so only the panels themselves catch clicks. */
    pointer-events: none;
}

.replay-viewer.variant-analyst .replay-analyst-rail-left  { left: 12px; }
.replay-viewer.variant-analyst .replay-analyst-rail-right { right: 12px; }

/* Hide the docked sidebar in Analyst mode — rails replace it. The sidebar
   element stays in the DOM so tab state and chart instances survive a
   variant switch; we just suppress it visually. */
.replay-viewer.variant-analyst #replay-sidebar,
.replay-viewer.variant-analyst #replay-toggle-sidebar {
    display: none !important;
}

/* In Refined the canvas-container reserves room for the sidebar via its
   flex layout. In Analyst we want the canvas to fill the container. */
.replay-viewer.variant-analyst .canvas-wrapper {
    flex: 1 1 auto;
    width: 100%;
}

/* Narrow screens: collapse rails to a slimmer width so both still fit. */
@media (max-width: 1400px) {
    .replay-viewer.variant-analyst .replay-analyst-rail {
        width: 300px;
    }
}

@media (max-width: 1100px) {
    .replay-viewer.variant-analyst .replay-analyst-rail {
        width: 260px;
    }
}

/* --- Analyst row primitive (shared across battle/build/hint rows) --- */

.analyst-row {
    display: grid;
    grid-template-columns: 44px 1fr auto;
    gap: 8px;
    align-items: center;
    width: 100%;
    padding: 8px 12px;
    background: transparent;
    border: 0;
    border-left: 2px solid transparent;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    color: #e6e9ef;
    text-align: left;
    cursor: pointer;
    font: inherit;
    opacity: 0.4;  /* default = "in the future" */
    transition: background 100ms ease, opacity 150ms ease;
}

.analyst-row:hover {
    background: rgba(255, 255, 255, 0.035);
}

.analyst-row.passed {
    opacity: 1;
}

.analyst-row.active {
    background: rgba(86, 194, 255, 0.07);
    border-left-color: #56c2ff;
}

.analyst-row-time {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
    font-size: 11px;
    color: #6e7687;
}

.analyst-row-main {
    font-size: 12px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Outcome / severity badges */
.analyst-badge {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 2px 5px;
    border-radius: 3px;
    border: 1px solid currentColor;
}

.analyst-badge.outcome-win   { color: #4ade80; background: rgba(74, 222, 128, 0.08); }
.analyst-badge.outcome-loss  { color: #f87171; background: rgba(248, 113, 113, 0.08); }
.analyst-badge.outcome-trade { color: #fbbf24; background: rgba(251, 191, 36, 0.08); }

.analyst-empty {
    padding: 18px 14px;
    color: #6e7687;
    font-size: 12px;
    text-align: center;
}

/* --- Braided build rows: flip grid direction per player ---
   Four grid slots per row: name (stretch) · dot (8px) · meta (76px) ·
   delta (32px). The delta slot hosts the comparison severity chip; it's
   still there even when empty so widths match between rows with and
   without comparison data. Each side mirrors the column order so the
   player's name sits on THEIR side of the braided layout. */

.analyst-build-row {
    grid-template-columns: 1fr 8px 76px 32px;
    padding: 5px 12px;
    border-left: 0;
    border-right: 2px solid transparent;
    gap: 6px;
    align-items: center;
}

.analyst-build-row.side-p1 {
    grid-template-columns: 32px 76px 8px 1fr;
    border-left: 2px solid transparent;
    border-right: 0;
    text-align: left;
}

.analyst-build-row.side-p0 {
    text-align: right;
}

.analyst-build-row.active.side-p0 { border-right-color: #56c2ff; }
.analyst-build-row.active.side-p1 { border-left-color: #56c2ff; }

/* Comparison severity tints on analyst build rows (analogue of the
   refined-mode .bo-item.comp-* classes). Left-bar coloring for side-p1,
   right-bar coloring for side-p0 so the severity reads alongside the
   player's own side of the braided layout. */
.analyst-build-row.has-comp { background: rgba(255, 255, 255, 0.02); }
.analyst-build-row.comp-on-time.side-p0  { box-shadow: inset -3px 0 0 #4ade80; }
.analyst-build-row.comp-on-time.side-p1  { box-shadow: inset 3px 0 0 #4ade80; }
.analyst-build-row.comp-ahead.side-p0    { box-shadow: inset -3px 0 0 #56c2ff; }
.analyst-build-row.comp-ahead.side-p1    { box-shadow: inset 3px 0 0 #56c2ff; }
.analyst-build-row.comp-late.side-p0     { box-shadow: inset -3px 0 0 #fbbf24; }
.analyst-build-row.comp-late.side-p1     { box-shadow: inset 3px 0 0 #fbbf24; }
.analyst-build-row.comp-very-late.side-p0 { box-shadow: inset -3px 0 0 #f87171; }
.analyst-build-row.comp-very-late.side-p1 { box-shadow: inset 3px 0 0 #f87171; }
.analyst-build-row.comp-missing.side-p0  { box-shadow: inset -3px 0 0 #c2558c; opacity: 0.75; }
.analyst-build-row.comp-missing.side-p1  { box-shadow: inset 3px 0 0 #c2558c; opacity: 0.75; }

.analyst-build-delta {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
    font-size: 10px;
    color: #8a92a0;
    min-width: 2.5em;
    text-align: center;
}
.analyst-build-row.comp-on-time   .analyst-build-delta { color: #4ade80; }
.analyst-build-row.comp-ahead     .analyst-build-delta { color: #56c2ff; }
.analyst-build-row.comp-late      .analyst-build-delta { color: #fbbf24; }
.analyst-build-row.comp-very-late .analyst-build-delta { color: #f87171; }
.analyst-build-row.comp-missing   .analyst-build-delta { color: #c2558c; }

/* Comparison summary header inside the Build card (analyst mode). Replaces
   the floating overlay that used to pop up in the middle of the canvas.
   Sticky to the top of the card body so the score + archetype title stays
   visible while the user scrolls the build-order rows below. Solid backdrop
   (layered on top of the card's own rgba(15,19,28,0.94) expanded bg) so
   scrolling rows don't bleed through from behind. */
.analyst-build-comp-header {
    position: sticky;
    top: 0;
    z-index: 2;
    padding: 10px 12px;
    margin: 0 -6px 8px -6px;
    background:
        linear-gradient(180deg, rgba(153, 102, 204, 0.12), rgba(255, 255, 255, 0.03)),
        rgba(15, 19, 28, 0.96);
    border-radius: 6px;
    border: 1px solid rgba(199, 155, 255, 0.25);
}
.analyst-build-comp-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 6px;
}
.analyst-build-comp-score {
    font-family: 'Rajdhani', sans-serif;
    font-size: 28px;
    font-weight: 700;
    line-height: 1;
    min-width: 42px;
    text-align: center;
    color: #fbbf24;
}
.analyst-build-comp-score.good { color: #4ade80; }
.analyst-build-comp-score.ok   { color: #fbbf24; }
.analyst-build-comp-score.poor { color: #f87171; }
.analyst-build-comp-title {
    font-size: 13px;
    font-weight: 700;
    color: #e6e9ef;
}
.analyst-build-comp-archetype-link,
.inline-comp-archetype-link {
    color: inherit;
    text-decoration: none;
    border-bottom: 1px dashed rgba(255,255,255,0.25);
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s;
}
.analyst-build-comp-archetype-link:hover,
.inline-comp-archetype-link:hover {
    color: #c79bff;
    border-bottom-color: #c79bff;
}
.analyst-build-comp-sub {
    font-size: 11px;
    color: #8a92a0;
}
.analyst-build-comp-branch {
    font-size: 11px;
    color: #c79bff;
    margin-top: 2px;
}
.analyst-build-comp-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-bottom: 4px;
}
.analyst-build-comp-pill {
    font-size: 10px;
    padding: 2px 6px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.10);
    color: #aab0bd;
}
.analyst-build-comp-pill.on-time   { color: #4ade80; border-color: rgba(74, 222, 128, 0.35); }
.analyst-build-comp-pill.ahead     { color: #56c2ff; border-color: rgba(86, 194, 255, 0.35); }
.analyst-build-comp-pill.late      { color: #fbbf24; border-color: rgba(251, 191, 36, 0.35); }
.analyst-build-comp-pill.very-late { color: #f87171; border-color: rgba(248, 113, 113, 0.35); }
.analyst-build-comp-pill.missing   { color: #c2558c; border-color: rgba(194, 85, 140, 0.35); }
.analyst-build-comp-first {
    font-size: 11px;
    color: #aab0bd;
    margin-top: 4px;
}
.analyst-build-comp-first strong { color: #e6e9ef; }

.analyst-build-name {
    font-size: 12px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.analyst-build-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
}

.analyst-build-meta {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
    font-size: 10px;
    color: #6e7687;
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    white-space: nowrap;
}

/* Keep the timestamp muted — it's chronological scaffolding. Supply is
   the signal the user actually wants to read at a glance, so bump its
   color, weight, and size to roughly match the build-item name. */
.analyst-build-time {
    color: #6e7687;
}

.analyst-build-supply {
    color: #e6e9ef;
    font-weight: 600;
    font-size: 11px;
    padding: 1px 5px;
    border-radius: 3px;
    background: rgba(255, 255, 255, 0.06);
    letter-spacing: 0.02em;
}

/* Pack meta contents toward the dot (inner edge of the braided layout).
   side-p0: meta sits to the RIGHT of the dot → flex-end in row-reverse
   puts items at the LEFT edge of the meta cell (right next to the dot).
   side-p1: meta sits to the LEFT of the dot → flex-end in a normal row
   puts items at the RIGHT edge of the meta cell (right next to the dot).
   Net effect: supply pill is always adjacent to its player's dot. */
.analyst-build-row.side-p0 .analyst-build-meta {
    flex-direction: row-reverse;
    justify-content: flex-end;
}
.analyst-build-row.side-p1 .analyst-build-meta {
    justify-content: flex-end;
}

/* Halve the visual gap between the dot and the supply pill. Grid gap is
   6px across all columns; a -3px margin on the meta cell on its
   dot-facing edge tightens just that pair without compressing
   name↔dot or meta↔delta. */
.analyst-build-row.side-p0 .analyst-build-meta { margin-left: -3px; }
.analyst-build-row.side-p1 .analyst-build-meta { margin-right: -3px; }

/* --- Coaching Hints rows (left rail) --- */

/* Right-rail view toggle — single button in the merged Build Order /
   Production card header. Label reads "Queue" when showing Build Order
   (click → Production) and "Full" when showing Production (click →
   full Build Order). Styled as a compact pill to match the header row. */
.analyst-right-toggle {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 3px 10px;
    color: #c79bff;
    background: rgba(153, 102, 204, 0.10);
    border: 1px solid rgba(199, 155, 255, 0.55);
    border-radius: 4px;
    cursor: pointer;
    transition: background 0.12s, border-color 0.12s, color 0.12s;
    font-family: inherit;
}
.analyst-right-toggle:hover {
    background: rgba(153, 102, 204, 0.22);
    border-color: rgba(199, 155, 255, 0.8);
}
.analyst-right-toggle:focus-visible {
    outline: 2px solid #56c2ff;
    outline-offset: 2px;
}

/* Merged right-rail card hosts both views in one container. Flip is
   driven by display:none on the inactive view — keeps scroll/highlight
   state alive on the one you flip back to. */
.analyst-right-view-host {
    display: block;
}
.analyst-right-view { display: block; }

/* Streamlined mode: non-windowed rows are hidden. In the card transitions
   are handled via display:none since the list can shrink to zero rows. */
.analyst-hint-row.streamlined-hidden {
    display: none;
}

/* Active (currently-firing) hint in streamlined mode gets a gentle pulse
   so it feels alive — it's usually alone on screen so the visual weight
   is fine. */
[data-hint-mode="streamlined"] .analyst-hint-row.active {
    animation: analyst-hint-pulse 2.4s ease-in-out infinite;
}
@keyframes analyst-hint-pulse {
    0%, 100% { box-shadow: inset 3px 0 0 var(--hint-color, #fbbf24), 0 0 0 0 rgba(251, 191, 36, 0); }
    50%      { box-shadow: inset 3px 0 0 var(--hint-color, #fbbf24), 0 0 12px 2px rgba(251, 191, 36, 0.18); }
}

.analyst-hint-row {
    grid-template-columns: 40px 1fr auto;
    align-items: start;
    padding: 9px 12px;
    border-left-width: 2px;
}

.analyst-hint-row.active {
    background: rgba(255, 255, 255, 0.05);
    border-left-color: var(--hint-color, #fbbf24);
}

.analyst-hint-text {
    min-width: 0;
}

.analyst-hint-title {
    font-size: 12px;
    font-weight: 600;
    color: #fff;
    display: flex;
    gap: 6px;
    align-items: center;
    min-width: 0;
}

.analyst-hint-title > :not(.analyst-hint-dot) {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.analyst-hint-dot {
    flex-shrink: 0;
    width: 5px;
    height: 5px;
    border-radius: 50%;
}

.analyst-hint-body {
    font-size: 11px;
    color: #aab3c2;
    line-height: 1.4;
    margin-top: 2px;
}

.analyst-grade-chip {
    font-family: 'Rajdhani', sans-serif;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 2px 6px;
    border-radius: 3px;
    border: 1px solid currentColor;
    align-self: flex-start;
    background: rgba(255, 255, 255, 0.03);
}

/* --- Live Stats body --- */

.analyst-stats {
    display: block;
    padding-bottom: 4px;
}

.analyst-stats-head {
    display: grid;
    grid-template-columns: 70px 1fr 1fr;
    padding: 10px 14px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    font-size: 10px;
    color: #6e7687;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    font-weight: 600;
    gap: 8px;
}

.analyst-stats-row {
    display: grid;
    grid-template-columns: 70px 1fr 1fr;
    padding: 10px 12px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    align-items: center;
    gap: 8px;
}

/* Row labels — match the theme's display/uppercase treatment used by
   track labels + .replay-float-card-title (Rajdhani weight 600,
   spaced caps). Previously rendered in default sans at 11px which
   clashed with the rest of the analyst chrome. */
.analyst-stats-label {
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #aab3c2;
}

/* Player-name chips promoted into the float-card header row. Two
   chips (one per player) in the same bullet + name format the old
   dedicated stats-head row used. Each chip gets its own player
   color via inline style from the renderer. Kept compact so the
   card header doesn't grow taller than it was. */
.analyst-stats-headtags {
    display: flex;
    align-items: center;
    gap: 10px;
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
.analyst-stats-headtag {
    white-space: nowrap;
}

.analyst-stats-cell {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    overflow: hidden;
}

.analyst-stats-value {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
    font-size: 15px;
    color: #fff;
    font-weight: 600;
    min-width: 30px;
    flex-shrink: 0;
    transition: color 0.15s ease, text-shadow 0.15s ease;
}

/* Supply-blocked glow — fires when food_used >= food_made. Amber tint
   plus a soft text-shadow + subtle pulse so the user's eye is drawn to
   the row while they're bleeding tempo. Animation is applied only while
   the class is active so it doesn't burn GPU on idle cards. */
.analyst-stats-value.supply-blocked {
    color: #fbbf24;
    text-shadow: 0 0 8px rgba(251, 191, 36, 0.75),
                 0 0 14px rgba(251, 191, 36, 0.45);
    animation: analyst-supply-pulse 1.4s ease-in-out infinite;
}

@keyframes analyst-supply-pulse {
    0%, 100% { text-shadow: 0 0 8px rgba(251, 191, 36, 0.75), 0 0 14px rgba(251, 191, 36, 0.45); }
    50%      { text-shadow: 0 0 12px rgba(251, 191, 36, 1.0),  0 0 22px rgba(251, 191, 36, 0.70); }
}

/* Delta vs opponent — small micro text between the primary value and the
   sparkline. Sits at roughly half the weight of the main number so the
   eye reads "value, delta, trend" in that order. */
.analyst-stats-delta {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
    font-size: 10px;
    font-weight: 500;
    color: #6e7687;
    flex-shrink: 0;
    min-width: 14px;
    text-align: left;
}
.analyst-stats-delta.delta-pos { color: #4ade80; }
.analyst-stats-delta.delta-neg { color: #f87171; }

/* Worker-kill slap — fires on real worker deaths (not Zerg morphs).
   Two CSS custom properties drive intensity:
     --slap-scale (1.0–2.8x) scales the text size + drop-shadow
     --slap-shake (2–8px)    scales the shake amplitude
   Both come from analyst-layout.js sized by the kill count so a
   4-worker drop reads visibly heavier than a 2-worker nip.
   The cell shakes in sync so the "impact" lands on the number the
   user is watching, not just on the floating slap text. */
.analyst-stats-slap {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%) scale(0);
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-weight: 800;
    color: #f87171;
    text-shadow: 0 0 8px rgba(248, 113, 113, 0.85),
                 0 0 18px rgba(248, 113, 113, 0.55),
                 0 2px 0 rgba(0, 0, 0, 0.6);
    pointer-events: none;
    white-space: nowrap;
    letter-spacing: 0.02em;
    font-size: 18px;
    opacity: 0;
    z-index: 3;
    --slap-scale: 1;
    --slap-shake: 2px;
}

/* Slap cells anchor the absolutely-positioned "-N" + allow the child
   shake animation to overflow without clipping. */
.analyst-stats-row .analyst-stats-cell:has(.analyst-stats-slap) {
    position: relative;
    overflow: visible;
}

.analyst-stats-slap.is-firing {
    animation: analyst-slap-pop 900ms cubic-bezier(.2, .9, .25, 1) forwards;
}

@keyframes analyst-slap-pop {
    0% {
        transform: translate(-50%, -50%) scale(calc(var(--slap-scale) * 0.4)) rotate(-6deg);
        opacity: 0;
    }
    15% {
        transform: translate(-50%, -50%) scale(calc(var(--slap-scale) * 1.25)) rotate(4deg);
        opacity: 1;
    }
    35% {
        transform: translate(-50%, -50%) scale(var(--slap-scale)) rotate(-2deg);
        opacity: 1;
    }
    70% {
        transform: translate(-50%, -55%) scale(var(--slap-scale)) rotate(0);
        opacity: 0.9;
    }
    100% {
        transform: translate(-50%, -70%) scale(calc(var(--slap-scale) * 0.95)) rotate(0);
        opacity: 0;
    }
}

/* The Workers-row cell itself shakes when a slap fires — small but
   deliberate so the number the user is watching visibly reacts.
   Using the :has() sibling selector keeps the shake tied to the
   slap's animation lifetime without extra JS. */
.analyst-stats-cell:has(.analyst-stats-slap.is-firing) .analyst-stats-value {
    animation: analyst-slap-shake 400ms cubic-bezier(.2, .7, .3, 1);
    color: #f87171;
}

@keyframes analyst-slap-shake {
    0%, 100% { transform: translateX(0); }
    10%      { transform: translateX(calc(var(--slap-shake) * -1)); }
    25%      { transform: translateX(var(--slap-shake)); }
    40%      { transform: translateX(calc(var(--slap-shake) * -0.7)); }
    55%      { transform: translateX(calc(var(--slap-shake) * 0.5)); }
    70%      { transform: translateX(calc(var(--slap-shake) * -0.3)); }
    85%      { transform: translateX(calc(var(--slap-shake) * 0.15)); }
}

.analyst-sparkline {
    flex: 1 1 auto;
    min-width: 0;
    height: 22px;
    overflow: visible;
}

/* --- Race-aware macro row in Live Stats --- */

.analyst-stats-row-macro {
    border-top: 1px solid rgba(255, 255, 255, 0.14);
}

.analyst-stats-cell-macro {
    gap: 10px;
    flex-wrap: wrap;
    justify-content: flex-start;
}

/* Each race-macro metric (MULE/SCN, INJ/CRP, CB) is its own chip — pairs
   sit side-by-side so Terran/Zerg get two readings in one cell. */
.analyst-macro-chip {
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
}

.analyst-macro-tag {
    font-family: 'Rajdhani', sans-serif;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

/* =============================================================
   Production card (left rail, sits underneath Live Stats)
   ----
   Mirrors the in-game SC2 Production tab: shows units / buildings /
   upgrades currently in progress, one lane per player, with a progress
   bar per item and a CB badge for chronoboosted rows.
   ============================================================= */

.analyst-production {
    display: block;
    padding-bottom: 4px;
}

.analyst-production-head {
    display: grid;
    grid-template-columns: 1fr 1fr;
    padding: 8px 12px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    font-size: 10px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    font-weight: 600;
    gap: 8px;
}

.analyst-production-side {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.analyst-production-lanes {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px;
    padding: 8px 10px;
}

.analyst-production-lane {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
    min-height: 32px;
    /* Bound each lane independently so a 20-item queue on one side doesn't
       push the card past the rail's 72px-from-bottom limit and overlap the
       transport dock. Scroll inside the lane instead. 240px ≈ 8 rows, which
       matches the in-game SC2 Production tab's visible capacity. */
    max-height: 240px;
    overflow-y: auto;
    /* Thin scrollbar to save horizontal space in the narrow rail. */
    scrollbar-width: thin;
}

.analyst-production-lane::-webkit-scrollbar {
    width: 4px;
}
.analyst-production-lane::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.18);
    border-radius: 2px;
}

.analyst-production-empty {
    font-size: 10px;
    color: #6e7687;
    font-style: italic;
    padding: 2px 4px;
}

.analyst-production-row {
    all: unset;
    display: grid;
    /* Icon now 32px — grew from 20px once we dropped the inline name
       label. Progress bar takes the rest of the row. */
    grid-template-columns: 32px 1fr;
    align-items: center;
    gap: 8px;
    padding: 5px 7px;
    border-radius: 5px;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.06);
    font-size: 11px;
    cursor: pointer;
    color: #e6e9ef;
    min-width: 0;
}

.analyst-production-row:hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.14);
}

.analyst-production-row.cb-flag {
    border-color: rgba(251, 191, 36, 0.35);
    background: linear-gradient(90deg, rgba(251, 191, 36, 0.10), rgba(255, 255, 255, 0.03) 50%);
}

/* cb-live glows brighter than cb-flag — a chrono cast is firing *right now*
   on a building that could be producing this item. */
.analyst-production-row.cb-live {
    box-shadow: 0 0 0 1px rgba(251, 191, 36, 0.55) inset, 0 0 10px rgba(251, 191, 36, 0.35);
    border-color: rgba(251, 191, 36, 0.6);
}

.analyst-production-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Matches PRODUCTION_ICON_SIZE in analyst-layout.js — sprite
       rendered at 30px, the 32px slot adds 1px of breathing room. */
    width: 32px;
    height: 32px;
    flex-shrink: 0;
}

/* sc2-chip inside a production row — neutralize the default 1.5px border
   (the row already has its own border + focus ring) and drop the dark
   backdrop so the sprite reads cleanly against the row background. */
.analyst-production-icon .sc2-chip {
    border: none;
    background: transparent;
    border-radius: 3px;
}

.analyst-production-icon .sc2-chip-procedural {
    /* Keep the race-colored fill for the letter-chip fallback so procedural
       icons still pop — just clip the border we stripped above. */
    background: var(--fallback-race, rgba(255, 255, 255, 0.08));
}

.analyst-production-main {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    min-width: 0;
}

/* ×N suffix: small corner badge when a unit queue has more than one
   item. Only visible when group.count > 1 (JS toggles the `hidden`
   attribute). Sits above the progress bar, right-aligned. */
.analyst-production-count {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
    font-size: 10px;
    color: #fbbf24;
    align-self: flex-end;
    opacity: 0.9;
}
.analyst-production-count[hidden] {
    display: none;
}

.analyst-production-bar {
    display: block;
    position: relative;
    width: 100%;
    /* Taller bar now that it's the dominant element in the row —
       reads as the primary progress affordance rather than a thin
       strip under the name. */
    height: 8px;
    background: rgba(255, 255, 255, 0.08);
    border-radius: 3px;
    overflow: hidden;
}

.analyst-production-fill {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    background: #56c2ff;
    border-radius: 3px;
    transition: width 120ms linear;
}

/* Chronoboost visual state lives on the row itself (border + glow) rather
   than a separate "CB" text chip, so the row keeps a compact 2-column grid
   with no reserved right-side column to crowd the name. */
@keyframes analyst-cb-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(251, 191, 36, 0.0); }
    50%      { box-shadow: 0 0 0 2px rgba(251, 191, 36, 0.35); }
}

.analyst-production-row.cb-live {
    animation: analyst-cb-pulse 1.2s ease-in-out infinite;
}

/* ================= Tracker (under Production lanes) =================
   Four rows — Units / Upgrades / Units Lost / Buildings Lost — each with a
   per-player cell. Chips show a 16px icon + count; empty cells show '—'.
   Lives inside the Production view only (the full Build Order toggle hides
   the whole production wrapper, so we don't need a separate scope rule).
   =================================================================== */

.analyst-tracker {
    display: flex;
    flex-direction: column;
    padding: 0;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
}

/* Each section stacks a full-width horizontal label header over a 2-column
   cell row (one column per player). The label doubles as a visual divider
   between sections — no separate <hr> needed. */
.analyst-tracker-section {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.analyst-tracker-section + .analyst-tracker-section {
    border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.analyst-tracker-label {
    font-size: 10px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-weight: 600;
    color: #9aa4b3;
    padding: 6px 10px 4px;
    background: rgba(255, 255, 255, 0.02);
}

.analyst-tracker-cells {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0;
    min-width: 0;
    padding: 4px 0 6px;
}

/* Thin divider between the two player columns so the eye can tell which
   side owns which icons without reading the color. */
.analyst-tracker-cells > .analyst-tracker-cell:first-child {
    border-right: 1px solid rgba(255, 255, 255, 0.06);
}

.analyst-tracker-cell {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    align-items: center;
    align-content: flex-start;
    min-width: 0;
    padding: 0 10px;
    /* Chips are 24px icons + ~4px vertical padding. Match so the empty
       placeholder stays vertically centered at row height. */
    min-height: 28px;
    /* Cap the per-cell height so a hundred-stalker deathball doesn't push
       the tracker past the card — scroll inside the cell instead. Tuned
       to fit ~3 rows of 24px chips before scrolling. */
    max-height: 128px;
    overflow-y: auto;
    scrollbar-width: thin;
}
.analyst-tracker-cell::-webkit-scrollbar {
    width: 3px;
}
.analyst-tracker-cell::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.18);
    border-radius: 2px;
}

.analyst-tracker-empty {
    font-size: 10px;
    color: #5b6372;
    font-style: italic;
}

.analyst-tracker-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 6px 2px 3px;
    border-radius: 4px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.06);
    font-size: 12px;
    line-height: 1;
    max-width: 100%;
}

.analyst-tracker-chip .sc2-chip {
    border: none;
    background: transparent;
    border-radius: 3px;
}

.analyst-tracker-chip .sc2-chip-procedural {
    background: var(--fallback-race, rgba(255, 255, 255, 0.08));
}

.analyst-tracker-chip-count {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
    color: #e6e9ef;
    font-weight: 600;
    font-size: 12px;
}

/* Upgrade chip is icon-only — the sprite is recognizable at a glance
   and the tooltip carries the full name. Matches the unit/lost chips
   visually except for the missing count (upgrades are binary). */
.analyst-tracker-chip.analyst-tracker-upgrade {
    padding: 2px 3px;
}

/* Paint the "Lost" sections with a subtle red wash on each chip so the
   eye can tell at a glance which section tracks losses vs current state. */
.analyst-tracker-section[data-section="unitsLost"] .analyst-tracker-chip,
.analyst-tracker-section[data-section="buildingsLost"] .analyst-tracker-chip {
    background: rgba(248, 113, 113, 0.08);
    border-color: rgba(248, 113, 113, 0.18);
}

/* Lost section labels get a faint red tint too so the header and chips
   read as a single unit without being visually loud. */
.analyst-tracker-section[data-section="unitsLost"] .analyst-tracker-label,
.analyst-tracker-section[data-section="buildingsLost"] .analyst-tracker-label {
    color: #f8b4b4;
}

/* ================= Macro Pulse (bottom-left readiness strip) ================= */

.replay-analyst-macro-pulse {
    display: none;
}

/* ---------------------------------------------------------------------
 * Analyst player-stats toggle
 * ---------------------------------------------------------------------
 * The pill sits inline with the other controls in .replay-canvas-topbar
 * so it doesn't hover over the minimap. Clicking it expands a compact
 * side-by-side player panel just below the top bar — thin enough to
 * leave most of the map visible underneath.
 * ------------------------------------------------------------------- */

/* Mount root holds the panel only; the pill is moved into the top bar. */
.replay-analyst-stats-topbar {
    display: none;
}

.replay-viewer.variant-analyst .replay-analyst-stats-topbar:not([hidden]) {
    position: absolute;
    top: 52px;                     /* clears the top-bar row */
    left: 50%;
    transform: translateX(-50%);
    z-index: 6;
    display: block;
    pointer-events: none;          /* panel opts back in */
}

/* When a cinematic coaching card is visible, push the stats panel below
   it so the two don't stack on top of each other at top-center.
   .replay-analyst-cinematic is unhidden (removes the [hidden] attribute)
   only when an active hint surfaces — the :has() check reacts instantly
   to both appear and disappear without any JS plumbing. */
.replay-viewer.variant-analyst:has(.replay-analyst-cinematic:not([hidden])) .replay-analyst-stats-topbar:not([hidden]) {
    top: 110px;
}

/* Pill button. Rendered into .replay-canvas-topbar by analyst-layout. */
.analyst-stats-topbar-pill {
    pointer-events: auto;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 14px;
    background: rgba(15, 19, 28, 0.80);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 14px;
    color: #e6e9ef;
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.10em;
    text-transform: uppercase;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.analyst-stats-topbar-pill:hover {
    background: rgba(25, 30, 42, 0.90);
    border-color: rgba(255, 255, 255, 0.22);
    color: #ffffff;
}

.analyst-stats-topbar-pill.open {
    background: rgba(153, 102, 204, 0.18);
    border-color: rgba(199, 155, 255, 0.55);
    color: #c79bff;
}

.analyst-stats-topbar-chevron {
    font-size: 8px;
    color: inherit;
    transition: transform 0.15s ease;
}

.analyst-stats-topbar-pill.open .analyst-stats-topbar-chevron {
    transform: rotate(180deg);
}

/* Panel: compact side-by-side player cards. Fixed width, ~160px tall
   so the minimap stays readable underneath. */
.analyst-stats-topbar-panel {
    pointer-events: auto;
    width: min(720px, calc(100vw - 760px));
    min-width: 520px;
    max-height: 200px;
    overflow-y: auto;
    padding: 8px 10px;
    background: rgba(15, 19, 28, 0.92);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: 10px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px 12px;
}

.analyst-stats-topbar-panel[hidden] {
    display: none;
}

/* Narrow screens / narrow canvas (left+right rails are 352px each in
   analyst mode) — fall back to a stacked layout but keep each player
   row tight so neither row exceeds ~90px. */
@media (max-width: 1600px) {
    .analyst-stats-topbar-panel {
        width: min(560px, calc(100vw - 760px));
    }
}
@media (max-width: 1240px) {
    .analyst-stats-topbar-panel {
        grid-template-columns: 1fr;
        width: min(440px, calc(100vw - 680px));
        min-width: 320px;
    }
}

.analyst-stats-topbar-panel .rs-player-compact {
    padding: 6px 6px 6px 10px;
    border-left: 3px solid var(--player-color, rgba(255,255,255,0.2));
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.rs-player-head-compact {
    display: flex;
    align-items: baseline;
    gap: 8px;
    line-height: 1.1;
}
.rs-player-head-compact .rs-player-name {
    font-weight: 700;
    font-size: 12px;
}
.rs-player-head-compact .rs-player-race {
    font-size: 10px;
    color: #8891a0;
    font-style: italic;
}

.rs-player-stats-compact {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 10px;
}
.rs-stat-inline {
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
    font-size: 11px;
}
.rs-stat-inline .rs-stat-label {
    font-size: 9px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #6e7687;
}
.rs-stat-inline .rs-stat-value {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
    color: #e6e9ef;
    font-weight: 600;
}

.rs-comp-chips-compact {
    display: flex;
    flex-wrap: wrap;
    gap: 3px;
}
.rs-comp-chips-compact .comp-chip {
    transform: scale(0.95);
    transform-origin: left center;
}
.rs-comp-empty {
    font-size: 10px;
    color: #5a6372;
    font-style: italic;
}

.replay-viewer.variant-analyst .replay-analyst-macro-pulse:not([hidden]) {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    position: absolute;
    left: 372px;           /* clear the left rail + 20px gutter */
    bottom: 120px;         /* sit just above the dock tracks */
    padding: 6px 10px;
    background: rgba(15, 19, 28, 0.76);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: 6px;
    pointer-events: none;
    z-index: 5;
    color: #e6e9ef;
    font-family: 'Inter', sans-serif;
}

@media (max-width: 1400px) {
    .replay-viewer.variant-analyst .replay-analyst-macro-pulse:not([hidden]) {
        left: 332px;
    }
}

@media (max-width: 1100px) {
    .replay-viewer.variant-analyst .replay-analyst-macro-pulse:not([hidden]) {
        left: 292px;
    }
}

.pulse-label {
    font-family: 'Rajdhani', sans-serif;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: #6e7687;
}

.pulse-chips {
    display: inline-flex;
    gap: 8px;
}

.pulse-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 8px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 4px;
    transition: background 160ms ease, border-color 160ms ease,
                box-shadow 160ms ease;
}

.pulse-chip-tag {
    font-family: 'Rajdhani', sans-serif;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #aab3c2;
}

.pulse-chip-value {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
    font-size: 12px;
    color: #fff;
    font-weight: 600;
}

.pulse-chip.pulse-active {
    background: rgba(251, 191, 36, 0.14);
    border-color: rgba(251, 191, 36, 0.45);
    box-shadow: 0 0 12px rgba(251, 191, 36, 0.30);
    animation: pulseGlow 1.6s ease-in-out infinite;
}

.pulse-chip.pulse-active .pulse-chip-tag { color: #fbbf24; }

@keyframes pulseGlow {
    0%, 100% { box-shadow: 0 0 12px rgba(251, 191, 36, 0.30); }
    50%      { box-shadow: 0 0 20px rgba(251, 191, 36, 0.55); }
}

/* Hidden by filter — keeps layout slot free of whitespace so scroll
   position stays sane when users toggle categories mid-game. */
.analyst-hint-row.cat-hidden {
    display: none !important;
}

/* --- Analyst top-bar category pills --- */

.replay-analyst-cats {
    display: none;
    gap: 4px;
    margin-right: 8px;
}

.replay-viewer.variant-analyst .replay-analyst-cats {
    display: inline-flex;
}

.replay-analyst-cat {
    font-family: 'Inter', sans-serif;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: #aab3c2;
    padding: 4px 10px;
    border-radius: 4px;
    border: 1px solid transparent;
    background: transparent;
    cursor: pointer;
    transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}

.replay-analyst-cat:hover {
    color: #e6e9ef;
    background: rgba(255, 255, 255, 0.04);
}

.replay-analyst-cat.active {
    color: #56c2ff;
    border-color: rgba(86, 194, 255, 0.40);
    background: rgba(86, 194, 255, 0.10);
}

/* ================= Analyst bottom dock ================= */

.replay-analyst-dock {
    display: none;
}

.replay-viewer.variant-analyst .replay-analyst-dock {
    display: flex;
    flex-direction: column;
    align-items: center;  /* center the 800px-max content horizontally */
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 10px 14px 12px;
    background: rgba(10, 13, 20, 0.92);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border-top: 1px solid rgba(255, 255, 255, 0.08);
    z-index: 4;
    pointer-events: auto;
    color: #e6e9ef;
    font-family: 'Inter', sans-serif;
    transition: transform 220ms ease, opacity 180ms ease;
}

/* Dock visibility modes (toggle cycles shown → autohide → hidden) */
.replay-viewer.variant-analyst.dock-hidden .replay-analyst-dock {
    display: none;
}
/* Auto-hide: tuck the dock off-screen except for a thin sliver, slide
 * back up when the user hovers the dock or the bottom hover strip
 * (the ::before pseudo extends the hot zone above the visible sliver
 * so the reveal triggers before the user has to chase it). */
.replay-viewer.variant-analyst.dock-autohide .replay-analyst-dock {
    transform: translateY(calc(100% - 6px));
    opacity: 0.45;
}
.replay-viewer.variant-analyst.dock-autohide .replay-analyst-dock::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: -28px;
    height: 28px;
    background: transparent;
    pointer-events: auto;
}
.replay-viewer.variant-analyst.dock-autohide .replay-analyst-dock:hover {
    transform: translateY(0);
    opacity: 1;
}

/* Keep the dock content readable on ultra-wide monitors. The outer strip
   still spans edge-to-edge (so the blurred backdrop fills the bottom
   band), but the tracks + transport row are capped to 800px and centered
   so the scrubber isn't stretched across 2000+px of canvas. */
.replay-viewer.variant-analyst .replay-analyst-dock > .analyst-dock-tracks,
.replay-viewer.variant-analyst .replay-analyst-dock > .analyst-dock-transport {
    width: 100%;
    max-width: 800px;
}

/* Win-probability toggle in the dock transport row. Mirrors dock-speed-btn
   sizing so it fits the row without special-casing flex/gap. Active
   (map-edge mode) gets the same accent treatment as a selected speed
   pill since "map" is the default/preferred placement. */
.dock-wr-btn {
    appearance: none;
    -webkit-appearance: none;
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.10);
    color: #aab3c2;
    font: 600 11px/1 'Rajdhani', 'Inter', sans-serif;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 5px 10px;
    border-radius: 4px;
    cursor: pointer;
    transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.dock-wr-btn:hover {
    color: #e6e9ef;
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.20);
}
/* Analyst dock draw tools: pencil toggle plus a popover (positioned
   above the button) with brush size, color, undo, and clear. The
   popover reveals only when draw mode is active. */
.dock-draw-wrap {
    position: relative;
    display: inline-flex;
    align-items: center;
}

.dock-draw-btn.active {
    color: #ff6b5a;
    border-color: rgba(255, 107, 90, 0.55);
    background: rgba(255, 59, 48, 0.14);
}

/* PATH toggle — same button geometry as DRAW, red wash when active to
   match the no-path tile tint. Hidden via [hidden] when the current
   map has no pathing data available. */
.dock-path-btn.active {
    color: #ff8a80;
    border-color: rgba(255, 80, 80, 0.55);
    background: rgba(255, 80, 80, 0.14);
}

/* "Review Similar" button — purple-tinted on hover to distinguish it
   from the toggle buttons (EVAL/DRAW/PATH) since it's a one-shot
   action, not a persistent state. Disabled state dims it while the
   load is in flight so the user gets feedback before the rails
   rebuild. */
.dock-similar-btn:hover:not(:disabled) {
    color: #d4b3ff;
    border-color: rgba(180, 140, 255, 0.55);
    background: rgba(160, 110, 240, 0.14);
}
.dock-similar-btn:disabled {
    opacity: 0.55;
    cursor: progress;
}

/* AUTO toggle — inherits .dock-wr-btn sizing. Purple wash when active
   so it reads as paired with the purple-tinted NEXT button (both
   relate to the continuous-pro-replay-watching feature). */
.dock-auto-btn:hover:not(:disabled) {
    color: #d4b3ff;
    border-color: rgba(180, 140, 255, 0.55);
    background: rgba(160, 110, 240, 0.14);
}
.dock-auto-btn.active {
    color: #ebdcff;
    border-color: rgba(180, 140, 255, 0.7);
    background: rgba(160, 110, 240, 0.22);
}

/* Dock layout: chapter row + 4-lane scrubber span the dock's full
   width (no side columns competing for horizontal space), with all
   controls on a single horizontal bar BELOW the tracks. Mirrors the
   layout pattern of every modern video player — seek bar on top,
   control row below — instead of the side-column experiment that
   strangled the timeline. */

/* Tracks now take the full dock width unconditionally. */
.replay-viewer.variant-analyst .replay-analyst-dock > .analyst-dock-tracks {
    width: 100%;
}

/* Single horizontal control bar. Clusters are first-class flex
   children so each group reads as a tight unit; the gap between
   clusters is wider than the gap between buttons inside a cluster,
   making the visual grouping obvious. flex-wrap lets the bar fall
   onto multiple rows on narrow viewports without breaking layout. */
.dock-control-bar {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    margin-top: 6px;
    padding: 4px 0;
}

/* Cluster: a tight group of related controls (e.g. all 5 transport
   buttons + time). Inner gap is small so the group reads as one;
   outer gaps (.dock-control-bar) separate clusters. */
.dock-cluster {
    display: flex;
    align-items: center;
    gap: 4px;
}

/* Filter cluster floats to the right edge of the bar via auto
   margin, leaving the playback / view / action clusters tightly
   grouped on the left. */
.dock-cluster-filter {
    margin-left: auto;
}

/* Inline AUTO filter container — single horizontal row inside the
   filter cluster. Compact enough that the whole control bar fits
   on a single line at typical viewport widths; flex-wrap on the
   parent .dock-control-bar handles the narrow-viewport fallback. */
.dock-auto-filters {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: nowrap;
    font-size: 11px;
    color: #cbd5e1;
}

/* Matchup chips stay on a single horizontal line — the width is
   bounded by the 6 chips (~150px) and the parent control bar
   wraps the whole filter cluster down a row if there's no room. */
.dock-auto-filters .auto-filter-matchups {
    flex-wrap: nowrap;
}

.dock-auto-filters .auto-filter-players {
    width: 130px;
    box-sizing: border-box;
}

.dock-auto-filters select,
.dock-auto-filters input[type="number"],
.dock-auto-filters input[type="text"] {
    background: rgba(20, 24, 36, 0.8);
    color: #e2e8f0;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 6px;
    padding: 3px 6px;
    font-size: 11px;
    font-family: inherit;
    height: 24px;
    box-sizing: border-box;
}
.dock-auto-filters select:focus,
.dock-auto-filters input:focus {
    outline: none;
    border-color: rgba(180, 140, 255, 0.55);
}
.dock-auto-filters .auto-filter-date {
    width: 56px;
}
.dock-auto-filters .auto-filter-mmr {
    display: flex;
    align-items: center;
    gap: 4px;
}
.dock-auto-filters .auto-filter-mmr-min,
.dock-auto-filters .auto-filter-mmr-max {
    width: 58px;
    /* Hide the native spinner — cramped in this row */
    -moz-appearance: textfield;
}
.dock-auto-filters .auto-filter-mmr-min::-webkit-inner-spin-button,
.dock-auto-filters .auto-filter-mmr-max::-webkit-inner-spin-button,
.dock-auto-filters .auto-filter-mmr-min::-webkit-outer-spin-button,
.dock-auto-filters .auto-filter-mmr-max::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
.dock-auto-filters .auto-filter-mmr-dash {
    color: #64748b;
}
.dock-auto-filters .auto-filter-players {
    width: 130px;
}

.dock-auto-filters .auto-filter-matchups {
    display: flex;
    gap: 3px;
}
.dock-auto-filters .auto-filter-chip {
    cursor: pointer;
    user-select: none;
    display: flex;
    align-items: center;
    padding: 3px 7px;
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.03em;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 6px;
    background: rgba(20, 24, 36, 0.8);
    color: #64748b;  /* muted when unchecked */
    transition: color 0.12s, background 0.12s, border-color 0.12s;
}
.dock-auto-filters .auto-filter-chip:has(input:checked) {
    color: #d4b3ff;
    border-color: rgba(180, 140, 255, 0.55);
    background: rgba(160, 110, 240, 0.14);
}
.dock-auto-filters .auto-filter-chip input[type="checkbox"] {
    /* Visually hidden — the label background does the toggling. */
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
    pointer-events: none;
}

.dock-draw-popover {
    position: absolute;
    left: 50%;
    bottom: calc(100% + 8px);
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 8px;
    background: rgba(12, 16, 28, 0.96);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 8px;
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.45);
    white-space: nowrap;
    z-index: 30;
}

.dock-draw-popover[hidden] { display: none; }

.dock-draw-size {
    -webkit-appearance: none;
    appearance: none;
    width: 96px;
    height: 4px;
    background: rgba(255, 255, 255, 0.14);
    border-radius: 2px;
    outline: none;
    cursor: pointer;
}
.dock-draw-size::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #ff6b5a;
    border: 2px solid #1a1a2a;
    cursor: pointer;
}
.dock-draw-size::-moz-range-thumb {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #ff6b5a;
    border: 2px solid #1a1a2a;
    cursor: pointer;
}

.dock-draw-color {
    width: 24px;
    height: 24px;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 4px;
    background: transparent;
    cursor: pointer;
}
.dock-draw-color::-webkit-color-swatch-wrapper { padding: 2px; }
.dock-draw-color::-webkit-color-swatch { border: none; border-radius: 2px; }
.dock-draw-color::-moz-color-swatch { border: none; border-radius: 2px; }

.dock-draw-aux {
    appearance: none;
    -webkit-appearance: none;
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.12);
    color: #c0c6d2;
    font: 600 12px/1 'Inter', sans-serif;
    width: 24px;
    height: 24px;
    border-radius: 4px;
    cursor: pointer;
    transition: background 120ms ease, color 120ms ease;
}
.dock-draw-aux:hover {
    color: #ffffff;
    background: rgba(255, 255, 255, 0.06);
}

.dock-wr-btn.active {
    color: #56c2ff;
    border-color: rgba(86, 194, 255, 0.55);
    background: rgba(86, 194, 255, 0.10);
}
.dock-wr-btn:focus-visible {
    outline: 2px solid #56c2ff;
    outline-offset: 2px;
}

/* Sidebar variant of the win-probability bar — pinned to the viewer's
   left edge so users who prefer the classic HUD placement can still see
   the tug-of-war without it being painted onto the map canvas. Height %
   values on the two fills are written directly in JS (updateSidebarEvalBar);
   the stacked flex column handles layout so the split follows. */
.replay-wr-sidebar {
    position: absolute;
    left: 0;
    top: var(--app-header-h, 64px);
    bottom: 0;
    width: 10px;
    display: flex;
    flex-direction: column;
    background: rgba(0, 0, 0, 0.45);
    border-right: 1px solid rgba(255, 255, 255, 0.10);
    z-index: 6;
    pointer-events: none;
    overflow: hidden;
}
.wr-sidebar-opp {
    width: 100%;
    transition: height 160ms ease;
}
.wr-sidebar-my {
    width: 100%;
    transition: height 160ms ease;
}
.wr-sidebar-mid {
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    height: 1px;
    background: rgba(255, 255, 255, 0.20);
    pointer-events: none;
}

/* In Analyst the old transport/toggles strip is replaced by the dock. */
.replay-viewer.variant-analyst .replay-canvas-controls,
.replay-viewer.variant-analyst .replay-canvas-toggles {
    display: none !important;
}

.replay-viewer.variant-analyst .replay-analyst-rail {
    bottom: 108px;  /* leave room for the dock's full height */
}

/* --- Stacked category tracks --- */

.analyst-dock-tracks {
    display: flex;
    flex-direction: column;
    gap: 3px;
    margin-bottom: 8px;
    padding-left: 60px;   /* align track lanes with the scrubber below */
    padding-right: 52px;
}

.dock-track {
    display: grid;
    grid-template-columns: 60px 1fr;
    gap: 8px;
    align-items: center;
    transition: opacity 120ms ease;
}

.dock-track.cat-dim { opacity: 0.35; }

.dock-track-label {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-align: left;
    /* Reset button chrome — label is a <button> so it can act as the
       category filter toggle, but it should read as a plain heading. */
    background: transparent;
    border: 0;
    padding: 2px 4px;
    margin: 0;
    cursor: pointer;
    border-radius: 3px;
    transition: background 0.12s, opacity 0.12s;
    font-family: inherit;
}

.dock-track-label:hover {
    background: rgba(255, 255, 255, 0.06);
}

.dock-track-label.active,
.dock-track-label[aria-pressed="true"] {
    background: rgba(255, 255, 255, 0.10);
}

/* When a category is solo'd, keep the dimmed track's label readable
   so the filter is easy to undo. `.dock-track.cat-dim` is declared
   above and already applies opacity to the whole track. */
.dock-track.cat-dim .dock-track-label { opacity: 0.85; }

.dock-track-lane {
    position: relative;
    height: 10px;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 2px;
}

.dock-marker {
    position: absolute;
    top: -2px;
    bottom: -2px;
    width: 7px;
    margin-left: -3.5px;
    border: 0;
    border-radius: 2px;
    cursor: pointer;
    padding: 0;
    transition: transform 100ms ease;
}

.dock-marker:hover { transform: scaleX(1.4); }
.dock-marker.severity-good { background: #4ade80; box-shadow: 0 0 8px rgba(74,222,128,0.5); }
.dock-marker.severity-warn { background: #fbbf24; box-shadow: 0 0 8px rgba(251,191,36,0.5); }
.dock-marker.severity-bad  { background: #f87171; box-shadow: 0 0 8px rgba(248,113,113,0.55); }

.dock-track-playhead {
    position: absolute;
    top: -3px;
    bottom: -3px;
    width: 1px;
    background: rgba(255, 255, 255, 0.4);
    pointer-events: none;
    left: 0;
}

/* --- Transport row --- */

.analyst-dock-transport {
    display: flex;
    align-items: center;
    justify-content: center;   /* center all transport controls below the tracks */
    gap: 12px;
}

.dock-transport-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 4px;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.08);
    color: #e6e9ef;
    font-size: 12px;
    padding: 0;
    cursor: pointer;
    transition: background 100ms ease, border-color 100ms ease;
}

.dock-transport-btn:hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.18);
}

.dock-transport-btn.primary {
    color: #56c2ff;
    background: rgba(86, 194, 255, 0.12);
    border-color: rgba(86, 194, 255, 0.35);
}

.dock-time-label {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
    font-size: 13px;
    color: #fff;
    width: 52px;
    font-weight: 600;
    flex-shrink: 0;
}

.dock-time-total {
    color: #6e7687;
    font-weight: 400;
    text-align: right;
}

.dock-scrub-col {
    flex: 1;
    position: relative;
    min-width: 0;
}

/* Chapter row mirrors the .dock-track grid so the chapters align with
   the lane x-axis. Without the 60px label spacer, the 0% chapter landed
   at the dock's left edge instead of the first lane pixel, which at
   short replay durations piled every chapter label on top of each other
   into unreadable overlap. */
.dock-chapter-row {
    display: grid;
    grid-template-columns: 60px 1fr;
    gap: 8px;
    align-items: center;
    margin-bottom: 4px;
    padding-left: 60px;    /* match .analyst-dock-tracks outer padding */
    padding-right: 52px;
}

.dock-chapter-spacer {
    /* Blank cell — just claims the 60px label column so the rail below
       lines up with the lanes. */
}

.dock-chapter-rail {
    position: relative;
    height: 12px;
}

.dock-chapter {
    position: absolute;
    top: 0;
    font-size: 9px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #6e7687;
    font-weight: 600;
    padding-left: 5px;
    border-left: 1px solid rgba(255, 255, 255, 0.10);
    line-height: 12px;
    white-space: nowrap;
}

/* Battle markers on each lane — without this they'd render as default
   inline buttons stacked at the lane's start (that was the column of
   grey dots the user saw clustered on the left of every track). */
.dock-lane-battle {
    position: absolute;
    top: -3px;
    bottom: -3px;
    width: 3px;
    margin-left: -1.5px;
    background: rgba(255, 255, 255, 0.55);
    border: 0;
    border-radius: 1px;
    padding: 0;
    cursor: pointer;
    transition: transform 100ms ease, background 100ms ease;
}
.dock-lane-battle:hover {
    transform: scaleX(1.8);
    background: #fff;
}

.dock-scrubber {
    position: relative;
    height: 20px;
    background: #141821;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 5px;
    cursor: pointer;
}

.dock-scrubber-fill {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    background: linear-gradient(90deg, rgba(86,194,255,0.14), rgba(86,194,255,0.30));
    border-radius: 4px 0 0 4px;
    pointer-events: none;
    width: 0;
}

.dock-scrubber-battle {
    position: absolute;
    top: 3px;
    bottom: 3px;
    width: 2px;
    margin-left: -1px;
    background: rgba(255, 255, 255, 0.55);
    cursor: pointer;
    border: 0;
    padding: 0;
}

.dock-scrubber-battle:hover { background: #fff; }

.dock-scrubber-playhead {
    position: absolute;
    top: -4px;
    bottom: -4px;
    width: 2px;
    margin-left: -1px;
    background: #fff;
    pointer-events: none;
    box-shadow: 0 0 10px rgba(255,255,255,0.6);
    left: 0;
}

.dock-scrubber-hover {
    position: absolute;
    bottom: calc(100% + 6px);
    transform: translateX(-50%);
    padding: 3px 7px;
    background: #242b38;
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: 4px;
    color: #fff;
    font-size: 11px;
    pointer-events: none;
    white-space: nowrap;
}

.dock-speed {
    display: inline-flex;
    gap: 2px;
}

.dock-speed-btn {
    font-size: 11px;
    padding: 4px 8px;
    border-radius: 3px;
    border: 1px solid rgba(255, 255, 255, 0.08);
    background: transparent;
    color: #aab3c2;
    cursor: pointer;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
}

.dock-speed-btn:hover { color: #e6e9ef; background: rgba(255, 255, 255, 0.04); }

.dock-speed-btn.active {
    color: #56c2ff;
    background: rgba(86, 194, 255, 0.12);
    border-color: rgba(86, 194, 255, 0.35);
}

/* ================= Analyst cinematic active-hint overlay ================= */

.replay-analyst-cinematic {
    display: none;
}

.replay-viewer.variant-analyst .replay-analyst-cinematic[hidden] {
    display: none;
}

.replay-viewer.variant-analyst .replay-analyst-cinematic {
    position: absolute;
    top: 52px;               /* clears the top-bar row (pill lives at 12px) */
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 18px;
    background: rgba(10, 13, 20, 0.94);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 1px solid var(--cinematic-color, #fbbf24);
    border-radius: 10px;
    box-shadow:
        0 12px 32px rgba(0, 0, 0, 0.6),
        0 0 32px color-mix(in srgb, var(--cinematic-color, #fbbf24) 20%, transparent);
    max-width: 560px;
    z-index: 6;
    pointer-events: none;
    color: #e6e9ef;
    font-family: 'Inter', sans-serif;
}

.replay-viewer.variant-analyst .replay-analyst-cinematic.drop-in {
    animation: cinematicDrop 0.3s cubic-bezier(.4, .2, .2, 1);
}

@keyframes cinematicDrop {
    from { opacity: 0; transform: translate(-50%, -8px); }
    to   { opacity: 1; transform: translate(-50%, 0); }
}

.cinematic-grade {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 6px;
    color: #000;
    font-family: 'Rajdhani', sans-serif;
    font-size: 14px;
    font-weight: 700;
    flex-shrink: 0;
}

.cinematic-meta {
    min-width: 0;
}

.cinematic-eyebrow {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--cinematic-color, #fbbf24);
}

.cinematic-dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--cinematic-color, #fbbf24);
}

.cinematic-sep { color: #6e7687; }

.cinematic-cat { color: var(--cinematic-color, #fbbf24); }

.cinematic-title {
    font-size: 14px;
    font-weight: 600;
    color: #fff;
    margin-top: 1px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* =================================================================
 * Analyst adoption pass: restyle / reposition / hide the remaining
 * legacy chrome so nothing overlaps the floating rails or fights the
 * design tokens. Only rules scoped to .variant-analyst here — Refined
 * is untouched.
 * ================================================================= */

/* The on-canvas top bar hosts the inline comparison + the old insights
   toolbar. In Analyst the insights toolbar is redundant (top-bar pills
   replace it) and the inline comparison needs to clear the floating
   left/right rails. Center the strip between the rails. */
.replay-viewer.variant-analyst .replay-canvas-topbar {
    left: 352px;   /* left rail (340) + gutter (12) */
    right: 352px;
    justify-content: center;
}

@media (max-width: 1400px) {
    .replay-viewer.variant-analyst .replay-canvas-topbar {
        left: 312px;
        right: 312px;
    }
}

@media (max-width: 1100px) {
    .replay-viewer.variant-analyst .replay-canvas-topbar {
        left: 272px;
        right: 272px;
    }
}

.replay-viewer.variant-analyst #insights-toolbar {
    display: none !important;
}

/* Inline "Compare to Pro Build" result: swap to design-token chrome
   (blur + border-strong + 10px radius) so it reads as a peer of the
   FloatCards. Keep it auto-width, never wider than the center channel. */
.replay-viewer.variant-analyst .replay-inline-comparison {
    max-width: min(460px, calc(100vw - 720px));
    max-height: min(320px, 50vh);
    padding: 12px 14px;
    background: rgba(15, 19, 28, 0.94);
    -webkit-backdrop-filter: blur(16px);
    backdrop-filter: blur(16px);
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 10px;
    box-shadow: 0 24px 48px -12px rgba(0, 0, 0, 0.6);
    font-family: 'Inter', sans-serif;
    font-size: 12px;
    color: #e6e9ef;
}

.replay-viewer.variant-analyst .inline-comp-close {
    color: #aab3c2;
    font-size: 14px;
    top: 8px;
    right: 10px;
}

.replay-viewer.variant-analyst .inline-comp-close:hover {
    color: #fff;
    background: rgba(255, 255, 255, 0.08);
}

/* Tighter internal type inside the Analyst comparison card so the
   header row + pill chips stop feeling cramped next to the rails. */
.replay-viewer.variant-analyst .inline-comp-grade-feedback,
.replay-viewer.variant-analyst .inline-comp-head { font-size: 12px; }
.replay-viewer.variant-analyst .inline-comp-grades {
    border-top-color: rgba(255, 255, 255, 0.08);
}

/* Top-bar buttons (Highlights / Share / Compare / Fit) + grade chips
   sit in the fixed 52px top bar above the canvas, so they never overlap
   the floating rails. Keep them — just match the Analyst spacing. */
.replay-viewer.variant-analyst .replay-topbar-actions {
    gap: 6px;
}

/* ============================================================
   Post-match summary modal
   ============================================================
   Shown when playback reaches the end of a replay. Dismissable via
   backdrop click, close button, Esc, or Review-Similar button. */

.post-match-modal {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 32px;
}
.pm-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(4, 6, 12, 0.72);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}

/* Entrance animation: handed off from match-finisher.js mid-exit-wipe so
   the backdrop establishes during the wipe, then the card scales up. */
@keyframes pmBackdropIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}
@keyframes pmCardIn {
    from {
        opacity: 0;
        transform: translateY(20px) scale(0.92);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}
.post-match-modal.pm-entering .pm-backdrop {
    animation: pmBackdropIn 600ms ease-out both;
}
.post-match-modal.pm-entering .pm-card {
    animation: pmCardIn 500ms cubic-bezier(0.2, 0.8, 0.25, 1.05) 150ms both;
}

.pm-card {
    position: relative;
    width: min(960px, calc(100vw - 40px));
    max-height: calc(100vh - 60px);
    overflow-y: auto;
    background: linear-gradient(180deg, rgba(14, 18, 30, 0.98), rgba(10, 14, 22, 0.98));
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: 16px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
    padding: 24px 28px 22px;
    font-family: 'Inter', sans-serif;
    color: #e2e8f0;
}
.pm-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 18px;
}
.pm-title-eyebrow {
    display: block;
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 11px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: #5aa0ff;
    font-weight: 600;
    margin-bottom: 4px;
}
.pm-title-match {
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 22px;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: #f1f5f9;
}
.pm-title-match .pm-vs {
    color: #64748b;
    font-weight: 500;
    margin: 0 6px;
}
.pm-close {
    background: transparent;
    border: none;
    color: #94a3b8;
    font-size: 24px;
    line-height: 1;
    cursor: pointer;
    padding: 4px 10px;
    border-radius: 8px;
}
.pm-close:hover {
    background: rgba(255, 255, 255, 0.06);
    color: #e2e8f0;
}

/* Grade hero: letter + one-liner headline. Grade colour keyed to the
   letter so A reads green / confident, D reads red / urgent. */
.pm-grade-row {
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 14px;
    margin-bottom: 20px;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 12px;
}
.pm-grade-box {
    flex-shrink: 0;
    width: 88px;
    height: 88px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    border-radius: 12px;
    background: rgba(20, 26, 40, 0.85);
    border: 1px solid rgba(255, 255, 255, 0.08);
}
.pm-grade-letter {
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 44px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0.02em;
}
.pm-grade-caption {
    font-size: 10px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: #64748b;
    margin-top: 4px;
}
.pm-grade-a .pm-grade-letter { color: #4ade80; }
.pm-grade-b .pm-grade-letter { color: #86efac; }
.pm-grade-c .pm-grade-letter { color: #fbbf24; }
.pm-grade-d .pm-grade-letter { color: #f87171; }
.pm-grade-a { border-color: rgba(74, 222, 128, 0.4); }
.pm-grade-b { border-color: rgba(134, 239, 172, 0.3); }
.pm-grade-c { border-color: rgba(251, 191, 36, 0.35); }
.pm-grade-d { border-color: rgba(248, 113, 113, 0.4); }
.pm-grade-copy {
    flex: 1;
    min-width: 0;
}
.pm-grade-headline {
    font-size: 17px;
    font-weight: 600;
    color: #e2e8f0;
    margin-bottom: 6px;
}
.pm-grade-sub {
    font-size: 13px;
    line-height: 1.5;
    color: #94a3b8;
}

/* Coaching block — wraps the controls bar + the rerenderable body
   that holds either the three-up severity layout or the chronological
   list view. */
.pm-coach-block {
    margin-bottom: 20px;
}

/* Sort + filter pill controls. Two groups: sort (severity ↔ time)
   and category filter (All / Macro / Micro / Scouting / Build).
   Layout wraps onto a second line on narrow viewports so neither
   group ever clips. */
.pm-coach-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px;
    margin-bottom: 12px;
    padding: 8px 10px;
    background: rgba(255, 255, 255, 0.02);
    border: 1px solid rgba(255, 255, 255, 0.05);
    border-radius: 8px;
}
.pm-coach-control-group {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
}
.pm-coach-control-label {
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 10px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: #64748b;
    margin-right: 4px;
}
.pm-coach-pill {
    padding: 4px 10px;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, 0.10);
    background: transparent;
    color: #94a3b8;
    font-family: 'Inter', sans-serif;
    font-size: 11px;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.pm-coach-pill:hover {
    color: #cbd5e1;
    border-color: rgba(255, 255, 255, 0.20);
}
.pm-coach-pill.is-active {
    color: #cfe5ff;
    border-color: rgba(90, 160, 255, 0.55);
    background: rgba(90, 160, 255, 0.16);
}

/* Three-column grid for Strengths / Mistakes / Opportunities. Wraps
   to single column on narrow viewports. */
.pm-sections {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 14px;
}
.pm-section {
    background: rgba(255, 255, 255, 0.02);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 10px;
    padding: 12px 14px;
    /* Scrollable so the user can review every hint, not just the top 3.
       Max-height keeps the modal compact; the inner list scrolls when
       a section runs long. */
    max-height: 340px;
    overflow-y: auto;
}
/* The chronological-mode "All Hints" section gets a slightly taller
   max-height since it holds the union of all three buckets. */
.pm-section-time {
    max-height: 460px;
}

/* Severity-colored left rail on every hint row, plus a category chip
   at the head so the chronological view stays scannable. */
.pm-hint {
    border-left: 3px solid transparent;
    padding-left: 8px;
}
.pm-hint-good { border-left-color: rgba(74, 222, 128, 0.6); }
.pm-hint-warn { border-left-color: rgba(251, 191, 36, 0.6); }
.pm-hint-bad  { border-left-color: rgba(248, 113, 113, 0.6); }
.pm-hint-cat {
    margin-left: auto;
    padding: 1px 7px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.06);
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 9px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: #94a3b8;
    font-weight: 600;
}
.pm-section-good { border-left: 3px solid #4ade80; }
.pm-section-warn { border-left: 3px solid #fbbf24; }
.pm-section-bad  { border-left: 3px solid #f87171; }
.pm-section-title {
    margin: 0 0 10px 0;
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #cbd5e1;
    display: flex;
    align-items: center;
    gap: 8px;
}
.pm-section-count {
    font-size: 11px;
    padding: 1px 7px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.08);
    color: #94a3b8;
    font-weight: 500;
    letter-spacing: 0;
}
.pm-section-empty-msg {
    margin: 0;
    font-size: 12px;
    color: #64748b;
    line-height: 1.45;
}
.pm-hint-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.pm-hint-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 3px;
}
.pm-hint-time {
    font-family: 'JetBrains Mono', monospace;
    font-size: 11px;
    color: #64748b;
    flex-shrink: 0;
}
.pm-hint-label {
    font-size: 13px;
    font-weight: 500;
    color: #e2e8f0;
}
.pm-hint-detail {
    margin: 0;
    font-size: 12px;
    line-height: 1.45;
    color: #94a3b8;
}

/* Build orders — both players side by side. On narrow viewports wraps
   to stacked. */
.pm-builds {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 14px;
    margin-bottom: 18px;
}
.pm-build {
    background: rgba(255, 255, 255, 0.02);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 10px;
    padding: 12px 14px;
}
.pm-build-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 10px;
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.pm-build-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
}
.pm-build-name-head {
    color: inherit;
}
.pm-build-race {
    color: #64748b;
    font-size: 11px;
    letter-spacing: 0.08em;
}
.pm-build-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
    font-size: 12px;
}
.pm-build-list li {
    display: flex;
    align-items: center;
    gap: 10px;
    color: #cbd5e1;
}
.pm-build-t {
    font-family: 'JetBrains Mono', monospace;
    font-size: 11px;
    color: #64748b;
    width: 40px;
    flex-shrink: 0;
}

/* Footer buttons */
.pm-footer {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    padding-top: 14px;
    border-top: 1px solid rgba(255, 255, 255, 0.05);
}
.pm-btn {
    padding: 8px 18px;
    border-radius: 8px;
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    cursor: pointer;
    border: 1px solid transparent;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.pm-btn-secondary {
    background: transparent;
    border-color: rgba(255, 255, 255, 0.12);
    color: #cbd5e1;
}
.pm-btn-secondary:hover {
    border-color: rgba(255, 255, 255, 0.24);
    color: #f1f5f9;
}
.pm-btn-primary {
    background: rgba(90, 160, 255, 0.18);
    border-color: rgba(90, 160, 255, 0.55);
    color: #cfe5ff;
}
.pm-btn-primary:hover {
    background: rgba(90, 160, 255, 0.28);
    border-color: rgba(90, 160, 255, 0.8);
    color: #f0f8ff;
}

/* Archetype line — sits under the grade copy, showing the matched
   archetype + sub-branch from the tree comparison. Subtle eyebrow
   + colored archetype name (the selected player's color would be
   too loud; we keep it neutral accent cyan). */
.pm-archetype {
    margin-top: 8px;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    font-size: 12px;
    color: #cbd5e1;
}
.pm-archetype-label {
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 10px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: #5aa0ff;
    font-weight: 600;
}
.pm-archetype-name {
    font-weight: 600;
    color: #e2e8f0;
}
.pm-archetype-sep {
    color: #64748b;
}
.pm-archetype-branch {
    color: #94a3b8;
}

/* Build-order strip (top of summary) — compact two-column layout
   mirroring the existing .pm-builds block but with icon chips so
   the user can scan the opener at a glance. */
.pm-build-item {
    display: grid;
    grid-template-columns: 40px 22px 1fr;
    align-items: center;
    gap: 8px;
}
.pm-build-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
}
.pm-build-icon .sc2-chip {
    border: none;
    background: transparent;
    border-radius: 3px;
}

/* ============================================================
   Bottom: three-up comparison grid (Units Lost / Upgrades / Fights)
   Replaces the duplicate build-orders panel the user flagged. */
.pm-stat-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 14px;
    margin-bottom: 18px;
}
.pm-stat-card {
    background: rgba(255, 255, 255, 0.02);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 10px;
    padding: 12px 14px;
    min-width: 0;
}
.pm-stat-title {
    margin: 0 0 10px 0;
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #cbd5e1;
}

/* Split: two player columns sitting side-by-side inside a stat card. */
.pm-stat-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}
.pm-stat-side {
    min-width: 0;
}
.pm-stat-side-head {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 8px;
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
.pm-stat-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}
.pm-stat-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: inherit;
}
.pm-stat-total {
    font-family: 'JetBrains Mono', monospace;
    font-size: 11px;
    color: #94a3b8;
    letter-spacing: 0;
}

/* Unit-loss chips: icon + count badge, wrapping to multi-row if
   needed. The chip background tint separates them from the card
   background. */
.pm-unit-chips,
.pm-upgrade-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.pm-unit-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 7px 3px 3px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 6px;
}
.pm-unit-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
}
.pm-unit-icon .sc2-chip {
    border: none;
    background: transparent;
    border-radius: 3px;
}
.pm-unit-count {
    font-family: 'JetBrains Mono', monospace;
    font-size: 12px;
    color: #e2e8f0;
    min-width: 16px;
    text-align: center;
}
.pm-upgrade-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 6px;
}
.pm-upgrade-chip .sc2-chip {
    border: none;
    background: transparent;
    border-radius: 4px;
}
.pm-empty {
    font-size: 12px;
    color: #64748b;
    font-style: italic;
}

/* Biggest-fights list: one row per engagement with a dual-color bar
   showing relative supply losses. Green-left border on wins, red on
   losses, neutral on even trades. */
.pm-eng-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.pm-eng {
    display: grid;
    grid-template-columns: 40px 1fr 48px;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 6px;
    border-left-width: 3px;
}
.pm-eng-won  { border-left-color: #4ade80; }
.pm-eng-lost { border-left-color: #f87171; }
.pm-eng-even { border-left-color: #fbbf24; }
.pm-eng-time {
    font-family: 'JetBrains Mono', monospace;
    font-size: 11px;
    color: #94a3b8;
}
.pm-eng-bar {
    display: flex;
    height: 16px;
    border-radius: 3px;
    overflow: hidden;
    background: rgba(255, 255, 255, 0.04);
}
.pm-eng-side {
    flex: 1 1 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'JetBrains Mono', monospace;
    font-size: 10px;
    font-weight: 600;
    color: rgba(0, 0, 0, 0.85);
    min-height: 16px;
}
/* Show losses as proportionally-sized halves so a 40/10 fight reads
   visually distinct from a 10/40 fight. Width hint via CSS var could
   refine this; simple flex:1 is close-enough for the summary card. */
.pm-eng-swing {
    text-align: right;
    font-family: 'JetBrains Mono', monospace;
    font-size: 12px;
    font-weight: 600;
    color: #cbd5e1;
}

/* Responsive: narrow viewports stack the three-up sections into a
   single column. */
@media (max-width: 720px) {
    .pm-sections,
    .pm-builds,
    .pm-stat-grid {
        grid-template-columns: 1fr;
    }
    .pm-stat-split {
        grid-template-columns: 1fr;
    }
}

/* ============================================================
   Match finisher overlay  (Persona 5-style winner reveal)
   ============================================================
   Mounted by match-finisher.js inside .canvas-wrapper at end of replay,
   ~1.2s sequence then handoff to the post-match modal. Lives above the
   minimap canvas (z-index 50) but below the modal (z-index 1000). */

.match-finisher-overlay {
    position: absolute;
    inset: 0;
    z-index: 50;
    pointer-events: none;
    overflow: hidden;
    perspective: 1200px;
    --mf-primary: #5aa0ff;
    --mf-accent:  #5aa0ff;
}

/* Brief shake + intensify on the canvas wrapper itself during the slash
   phase. Pairs with the slash-in to read as a "freeze frame slam". */
.canvas-wrapper.mf-shake {
    animation: mfShake 180ms cubic-bezier(0.36, 0, 0.66, -0.56) both;
    filter: contrast(1.12) saturate(1.25);
}
@keyframes mfShake {
    0%   { transform: translate(0, 0); }
    20%  { transform: translate(-2px, 1px); }
    40%  { transform: translate(2px, -1px); }
    60%  { transform: translate(-1px, 2px); }
    80%  { transform: translate(1px, -2px); }
    100% { transform: translate(0, 0); }
}

/* Diagonal black slash wedges — one wipes in from top-left, the other
   from bottom-right. Together they pinch the canvas into a P5-style
   letterbox before the word slams. They stay on screen until the exit
   wipe takes everything out. */
.mf-slash {
    position: absolute;
    inset: 0;
    background: #050505;
    opacity: 0;
}
.mf-slash-tl {
    clip-path: polygon(0 0, 100% 0, 0 60%);
    transform: translate(-100%, -100%);
    animation: mfSlashInTL 220ms cubic-bezier(0.5, 0, 0.5, 1) both;
}
.mf-slash-br {
    clip-path: polygon(100% 100%, 100% 40%, 0 100%);
    transform: translate(100%, 100%);
    animation: mfSlashInBR 220ms cubic-bezier(0.5, 0, 0.5, 1) 30ms both;
}
@keyframes mfSlashInTL {
    from { transform: translate(-100%, -100%); opacity: 0; }
    to   { transform: translate(0, 0);          opacity: 1; }
}
@keyframes mfSlashInBR {
    from { transform: translate(100%, 100%); opacity: 0; }
    to   { transform: translate(0, 0);       opacity: 1; }
}

/* Halftone dot field — flickers behind the word during the slam.
   Repeating radial gradient is a cheap, GPU-friendly way to fake the
   classic comic-book dot pattern. */
.mf-halftone {
    position: absolute;
    inset: 0;
    background-image: radial-gradient(circle at 2px 2px, var(--mf-primary) 1.4px, transparent 1.6px);
    background-size: 14px 14px;
    mix-blend-mode: screen;
    opacity: 0;
    animation: mfHalftoneStrobe 900ms steps(8, end) 200ms both;
}
@keyframes mfHalftoneStrobe {
    0%   { opacity: 0;    transform: scale(0.94); }
    15%  { opacity: 0.55; transform: scale(1.0); }
    30%  { opacity: 0.22; transform: scale(1.02); }
    45%  { opacity: 0.62; transform: scale(1.0); }
    60%  { opacity: 0.18; transform: scale(1.03); }
    78%  { opacity: 0.35; transform: scale(1.01); }
    100% { opacity: 0;    transform: scale(1.04); }
}

/* The big slammed word — VICTORY / DEFEAT / MATCH END. Rendered twice:
   a colored "front" layer and a near-black offset "shadow" behind it
   for the dual-layer P5 look. */
.mf-word-stack {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}
.mf-word {
    position: absolute;
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-weight: 900;
    font-style: italic;
    font-size: clamp(96px, 16vw, 220px);
    line-height: 0.85;
    letter-spacing: 0.01em;
    text-transform: uppercase;
    transform: skew(-8deg) scale(1.18);
    opacity: 0;
    white-space: nowrap;
    will-change: transform, opacity, letter-spacing;
}
.mf-word-front {
    color: var(--mf-primary);
    text-shadow:
        0 0 22px color-mix(in srgb, var(--mf-primary) 55%, transparent),
        0 6px 0 rgba(0, 0, 0, 0.35);
    animation: mfWordSlam 400ms cubic-bezier(0.18, 0.84, 0.3, 1.12) 220ms both;
}
.mf-word-shadow {
    color: #0a0a12;
    transform: skew(-8deg) translate(10px, 12px) scale(1.18);
    mix-blend-mode: normal;
    animation: mfWordSlamShadow 400ms cubic-bezier(0.18, 0.84, 0.3, 1.12) 220ms both;
}
@keyframes mfWordSlam {
    0%   { opacity: 0; transform: skew(-8deg) scale(1.45); letter-spacing: 0.18em; filter: blur(6px); }
    55%  { opacity: 1; transform: skew(-8deg) scale(0.97); letter-spacing: 0.0em;  filter: blur(0); }
    72%  {              transform: skew(-8deg) scale(1.04); letter-spacing: 0.01em; }
    100% { opacity: 1; transform: skew(-8deg) scale(1.0);  letter-spacing: 0.01em; filter: blur(0); }
}
@keyframes mfWordSlamShadow {
    0%   { opacity: 0; transform: skew(-8deg) translate(28px, 30px) scale(1.45); }
    55%  { opacity: 0.85; transform: skew(-8deg) translate(10px, 12px) scale(0.97); }
    100% { opacity: 0.85; transform: skew(-8deg) translate(10px, 12px) scale(1.0); }
}

/* Winner card — slides in from offscreen-left after the word lands,
   anchored to the lower portion of the canvas. Race color sits in the
   left stripe; player color provides the right accent line. */
.mf-card {
    position: absolute;
    left: 5%;
    bottom: 14%;
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 22px 14px 14px;
    background: linear-gradient(135deg, rgba(8, 10, 18, 0.96), rgba(20, 24, 38, 0.96));
    border-left: 5px solid var(--mf-primary);
    border-right: 2px solid var(--mf-accent);
    border-radius: 4px;
    box-shadow: 0 14px 32px rgba(0, 0, 0, 0.55);
    transform: translateX(-130%) skew(-6deg);
    opacity: 0;
    animation: mfCardSlide 500ms cubic-bezier(0.2, 0.8, 0.25, 1.05) 1000ms both;
    clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 100%, 0 100%);
    min-width: 240px;
}
@keyframes mfCardSlide {
    0%   { transform: translateX(-130%) skew(-6deg); opacity: 0; }
    65%  { transform: translateX(2%)    skew(-6deg); opacity: 1; }
    100% { transform: translateX(0)     skew(-6deg); opacity: 1; }
}
.mf-card-glyph {
    flex: 0 0 auto;
    width: 56px;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-weight: 900;
    font-style: italic;
    font-size: 38px;
    line-height: 1;
    color: #050505;
    background: var(--mf-primary);
    border-radius: 4px;
    transform: skew(6deg);
    text-shadow: 0 1px 0 rgba(255, 255, 255, 0.18);
}
.mf-card-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    transform: skew(6deg);
}
.mf-card-eyebrow {
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 10px;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--mf-primary);
    font-weight: 700;
}
.mf-card-name {
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 22px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #f4f6fb;
    line-height: 1;
}
.mf-card-meta {
    font-family: 'JetBrains Mono', 'Inter', monospace;
    font-size: 10px;
    letter-spacing: 0.08em;
    color: #9aa3b8;
    margin-top: 4px;
    text-transform: uppercase;
}
.mf-card-sep { margin: 0 6px; color: #4a5168; }

/* Diagonal exit wipe — covers everything behind it as it sweeps from
   top-right to bottom-left, handing off to the modal entrance which
   fires mid-wipe so the modal backdrop establishes underneath. */
.mf-exit-wipe {
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg, #050510 0%, #0a0a18 60%, #14182a 100%);
    transform: translateX(120%);
    opacity: 0;
    animation: mfExitWipe 500ms cubic-bezier(0.33, 0, 0.2, 1) 2600ms both;
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}
@keyframes mfExitWipe {
    0%   { transform: translateX(120%); opacity: 0.0; }
    30%  { transform: translateX(40%);  opacity: 0.85; }
    100% { transform: translateX(0);    opacity: 1.0; }
}

/* ============================================================
   Match intro overlay  (Persona 5-style start-of-match countdown)
   ============================================================
   Mirrors the finisher visually but shows matchup info + a 3-2-1-GO!
   countdown before autoplay begins. Mounted by match-intro.js inside
   .canvas-wrapper, ~3s sequence then the play() handoff fires. Skippable
   — clicking anywhere on the overlay aborts the countdown and starts
   playback immediately. */

.match-intro-overlay {
    position: absolute;
    inset: 0;
    z-index: 50;
    pointer-events: auto;
    cursor: pointer;
    overflow: hidden;
    perspective: 1200px;
    --mi-p1: #5aa0ff;
    --mi-p2: #ff6a4a;
}

.canvas-wrapper.mi-shake {
    animation: miShake 180ms cubic-bezier(0.36, 0, 0.66, -0.56) both;
    filter: contrast(1.12) saturate(1.25);
}
@keyframes miShake {
    0%   { transform: translate(0, 0); }
    20%  { transform: translate(-2px, 1px); }
    40%  { transform: translate(2px, -1px); }
    60%  { transform: translate(-1px, 2px); }
    80%  { transform: translate(1px, -2px); }
    100% { transform: translate(0, 0); }
}

.mi-slash {
    position: absolute;
    inset: 0;
    background: #050505;
    opacity: 0;
}
.mi-slash-tl {
    clip-path: polygon(0 0, 100% 0, 0 60%);
    transform: translate(-100%, -100%);
    animation: miSlashInTL 220ms cubic-bezier(0.5, 0, 0.5, 1) both;
}
.mi-slash-br {
    clip-path: polygon(100% 100%, 100% 40%, 0 100%);
    transform: translate(100%, 100%);
    animation: miSlashInBR 220ms cubic-bezier(0.5, 0, 0.5, 1) 30ms both;
}
@keyframes miSlashInTL {
    from { transform: translate(-100%, -100%); opacity: 0; }
    to   { transform: translate(0, 0);          opacity: 1; }
}
@keyframes miSlashInBR {
    from { transform: translate(100%, 100%); opacity: 0; }
    to   { transform: translate(0, 0);       opacity: 1; }
}

/* Halftone field — pulses a few times under the countdown digits.
   Long-running so each digit has some flicker behind it. */
.mi-halftone {
    position: absolute;
    inset: 0;
    background-image: radial-gradient(circle at 2px 2px, rgba(255, 255, 255, 0.55) 1.4px, transparent 1.6px);
    background-size: 14px 14px;
    mix-blend-mode: screen;
    opacity: 0;
    animation: miHalftoneStrobe 2400ms steps(20, end) 200ms both;
}
@keyframes miHalftoneStrobe {
    0%   { opacity: 0;    transform: scale(0.96); }
    8%   { opacity: 0.30; transform: scale(1.0); }
    25%  { opacity: 0.18; transform: scale(1.02); }
    35%  { opacity: 0.32; transform: scale(1.0); }
    55%  { opacity: 0.20; transform: scale(1.02); }
    65%  { opacity: 0.34; transform: scale(1.0); }
    85%  { opacity: 0.18; transform: scale(1.02); }
    92%  { opacity: 0.42; transform: scale(1.0); }
    100% { opacity: 0;    transform: scale(1.04); }
}

/* Matchup banner — slides in once the slashes settle. P1 from left,
   P2 from right, VS pops in the middle, optional map name underneath. */
.mi-matchup {
    position: absolute;
    top: 11%;
    left: 50%;
    transform: translateX(-50%);
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 18px;
    width: min(680px, calc(100% - 80px));
}
.mi-player {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    background: linear-gradient(135deg, rgba(8, 10, 18, 0.96), rgba(20, 24, 38, 0.96));
    border-radius: 4px;
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.5);
    opacity: 0;
    clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 100%, 0 100%);
    will-change: transform, opacity;
}
.mi-player-left {
    border-left: 4px solid var(--mi-side);
    transform: translateX(-110%) skew(-6deg);
    animation: miPlayerLeftIn 460ms cubic-bezier(0.2, 0.8, 0.25, 1.05) 220ms both;
}
.mi-player-right {
    border-right: 4px solid var(--mi-side);
    transform: translateX(110%) skew(-6deg);
    flex-direction: row-reverse;
    text-align: right;
    clip-path: polygon(12px 0, 100% 0, 100% 100%, 0 100%);
    animation: miPlayerRightIn 460ms cubic-bezier(0.2, 0.8, 0.25, 1.05) 280ms both;
}
@keyframes miPlayerLeftIn {
    0%   { transform: translateX(-110%) skew(-6deg); opacity: 0; }
    65%  { transform: translateX(2%)    skew(-6deg); opacity: 1; }
    100% { transform: translateX(0)     skew(-6deg); opacity: 1; }
}
@keyframes miPlayerRightIn {
    0%   { transform: translateX(110%)  skew(-6deg); opacity: 0; }
    65%  { transform: translateX(-2%)   skew(-6deg); opacity: 1; }
    100% { transform: translateX(0)     skew(-6deg); opacity: 1; }
}
.mi-player-glyph {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-weight: 900;
    font-style: italic;
    font-size: 28px;
    line-height: 1;
    color: #050505;
    background: var(--mi-side);
    border-radius: 4px;
    transform: skew(6deg);
}
.mi-player-info { display: flex; flex-direction: column; gap: 2px; transform: skew(6deg); }
.mi-player-name {
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 18px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #f4f6fb;
    line-height: 1;
}
.mi-player-meta {
    font-family: 'JetBrains Mono', 'Inter', monospace;
    font-size: 9px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #9aa3b8;
    margin-top: 3px;
}
.mi-player-mmr { margin-left: 6px; color: #cbd5e1; }
.mi-vs {
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-weight: 900;
    font-style: italic;
    font-size: 28px;
    color: #f4f6fb;
    letter-spacing: 0.04em;
    text-shadow: 0 0 16px rgba(255, 255, 255, 0.35);
    opacity: 0;
    transform: scale(1.6);
    animation: miVsIn 320ms cubic-bezier(0.2, 0.8, 0.25, 1.1) 380ms both;
}
@keyframes miVsIn {
    from { opacity: 0; transform: scale(1.6); }
    to   { opacity: 1; transform: scale(1.0); }
}
.mi-map {
    grid-column: 1 / -1;
    text-align: center;
    margin-top: 10px;
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-size: 12px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: #5aa0ff;
    opacity: 0;
    animation: miMapIn 320ms ease-out 540ms both;
}
@keyframes miMapIn {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 0.85; transform: translateY(0); }
}

/* Countdown digits — four absolutely-positioned big slams, only one
   visible at a time via staggered animation delays. The "GO!" hold is
   shorter; it stays visible until the exit wipe takes everything. */
.mi-count-stack {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}
.mi-count {
    position: absolute;
    font-family: 'Rajdhani', 'Inter', sans-serif;
    font-weight: 900;
    font-style: italic;
    font-size: clamp(140px, 22vw, 280px);
    line-height: 0.85;
    letter-spacing: 0.01em;
    color: #f4f6fb;
    text-shadow:
        0 0 28px rgba(255, 255, 255, 0.35),
        0 6px 0 rgba(0, 0, 0, 0.45);
    opacity: 0;
    transform: scale(1.4) skew(-8deg);
    will-change: transform, opacity, letter-spacing;
}
.mi-count-1 { animation: miCountPop 500ms cubic-bezier(0.18, 0.84, 0.3, 1.12) 800ms both; }
.mi-count-2 { animation: miCountPop 500ms cubic-bezier(0.18, 0.84, 0.3, 1.12) 1300ms both; }
.mi-count-3 { animation: miCountPop 500ms cubic-bezier(0.18, 0.84, 0.3, 1.12) 1800ms both; }
.mi-count-go {
    color: var(--mi-p2);
    text-shadow:
        0 0 32px color-mix(in srgb, var(--mi-p2) 60%, transparent),
        0 6px 0 rgba(0, 0, 0, 0.55);
    animation: miGoPop 600ms cubic-bezier(0.18, 0.84, 0.3, 1.12) 2300ms both;
}
@keyframes miCountPop {
    0%   { opacity: 0; transform: scale(1.5)  skew(-8deg); letter-spacing: 0.18em; filter: blur(6px); }
    35%  { opacity: 1; transform: scale(0.95) skew(-8deg); letter-spacing: 0;      filter: blur(0); }
    55%  { opacity: 1; transform: scale(1.0)  skew(-8deg); letter-spacing: 0.01em; }
    100% { opacity: 0; transform: scale(0.75) skew(-8deg); letter-spacing: 0.04em; filter: blur(2px); }
}
@keyframes miGoPop {
    0%   { opacity: 0; transform: scale(1.7)  skew(-8deg); letter-spacing: 0.22em; filter: blur(8px); }
    40%  { opacity: 1; transform: scale(0.92) skew(-8deg); letter-spacing: 0;      filter: blur(0); }
    65%  { opacity: 1; transform: scale(1.04) skew(-8deg); letter-spacing: 0.02em; }
    100% { opacity: 1; transform: scale(1.0)  skew(-8deg); letter-spacing: 0.02em; }
}

.mi-exit-wipe {
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg, #050510 0%, #0a0a18 60%, #14182a 100%);
    transform: translateX(-120%);
    opacity: 0;
    animation: miExitWipe 400ms cubic-bezier(0.55, 0, 0.7, 0.4) 2700ms both;
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}
@keyframes miExitWipe {
    0%   { transform: translateX(-120%); opacity: 0.0; }
    50%  { transform: translateX(0);     opacity: 1.0; }
    100% { transform: translateX(120%);  opacity: 0.0; }
}
