/*
 * Starlink v2: "Quiet space, loud light".
 *
 * Colour tokens use the names js/theme.js applyCssVariables() writes on :root
 * at boot (§3.1); the values here are the same palette so the page (and dev/ui-lab.html)
 * looks right before or without it. Saturated colour means ownership only, so
 * the chrome itself stays in neutral inks with Azure reserved for the CTA.
 */

:root {
    /* Background */
    --void: #04060D;
    --bg: #070B18;
    --bg-2: #0A1024;

    /* Factions */
    --f-player: #45D0FF;
    --f-player-rgb: 31, 168, 255;
    --f-player-deep: #0B3A5C;
    --f-enemy1: #F4513B;
    --f-enemy1-rgb: 255, 106, 61;
    --f-enemy1-deep: #4A1510;
    --f-enemy2: #A66EFF;
    --f-enemy2-rgb: 139, 92, 246;
    --f-enemy2-deep: #2A1850;
    --f-enemy3: #FFE066;
    --f-enemy3-rgb: 255, 201, 60;
    --f-enemy3-deep: #4A3A0C;

    /* Neutral stars */
    --neutral-fill: #0D1324;
    --neutral-rim: #7D88A1;
    --neutral-ink: #C9D1E0;
    --body-ink: #07101A;

    /* UI */
    --surface: rgba(11, 17, 34, 0.86);
    --surface-solid: #0B1122;
    --surface-raised: rgba(16, 24, 46, 0.94);
    --border: #1E2940;
    --border-2: #2A3754;
    --ink: #E8EEF8;
    --ink-2: #93A0BA;
    --ink-3: #56607A;
    --focus: #FFFFFF;
    --cta: #45D0FF;
    --cta-rgb: 69, 208, 255;
    --cta-ink: #04121C;
    --success: #5BE49B;
    --warning: #FFB547;

    /* Type */
    --font-ui: 'Exo 2', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    --font-wordmark: Orbitron, 'Exo 2', system-ui, sans-serif;

    /* Shape and motion */
    --r-sm: 10px;
    --r-md: 14px;
    --r-lg: 22px;
    --ease-out: cubic-bezier(.2, .8, .2, 1);
    --ease-in: cubic-bezier(.4, 0, 1, 1);
    --ease-back: cubic-bezier(.34, 1.56, .64, 1);
    --t-exit: 180ms;

    /* Safe areas */
    --sat: env(safe-area-inset-top, 0px);
    --sar: env(safe-area-inset-right, 0px);
    --sab: env(safe-area-inset-bottom, 0px);
    --sal: env(safe-area-inset-left, 0px);

    /* HUD geometry (other rules position themselves from these) */
    --hud-gap: 10px;
    --hud-h: 48px;
    --hud-bottom: calc(var(--sat) + var(--hud-gap) + var(--hud-h));
    --pill-h: 54px;

    color-scheme: dark;
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

[hidden] {
    display: none !important;
}

html,
body {
    margin: 0;
    height: 100%;
    background: var(--bg);
    color: var(--ink);
    font-family: var(--font-ui);
    font-weight: 600;
    overscroll-behavior: none;
    -webkit-tap-highlight-color: transparent;
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

body {
    height: 100dvh;
    overflow: hidden;
}

button {
    font: inherit;
    color: inherit;
    touch-action: manipulation;
    -webkit-user-select: none;
    user-select: none;
}

:focus {
    outline: none;
}

:focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: 3px;
}

[data-quiet-focus]:focus-visible {
    outline: none;
}

.ico {
    display: block;
    flex: none;
}

.noscript {
    position: fixed;
    inset: 0;
    display: grid;
    place-items: center;
    margin: 0;
    color: var(--ink-2);
}

/* ------------------------------------------------------------------ */
/* Game shell                                                         */
/* ------------------------------------------------------------------ */

.game {
    position: fixed;
    inset: 0;
    height: 100dvh;
    overflow: hidden;
    background: linear-gradient(180deg, var(--bg) 0%, var(--bg-2) 100%);
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
}

#game-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    touch-action: none;
}

/* The UI root lets pointer events fall through to the canvas; only real
   controls opt back in. */
.ui-root {
    position: absolute;
    inset: 0;
    z-index: 1;
    overflow: hidden;
    pointer-events: none;
    font-family: var(--font-ui);
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
}

.layer {
    position: absolute;
}

/* ------------------------------------------------------------------ */
/* Buttons and controls                                               */
/* ------------------------------------------------------------------ */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    min-height: 48px;
    padding: 0 20px;
    border: 1px solid var(--border-2);
    border-radius: var(--r-md);
    background: rgba(255, 255, 255, 0.04);
    color: var(--ink);
    font-size: 16px;
    font-weight: 700;
    line-height: 1.1;
    cursor: pointer;
    transition: transform .12s var(--ease-out), background-color .15s, border-color .15s, color .15s, box-shadow .2s;
}

.btn:active {
    transform: scale(.97);
}

.btn-primary {
    border-color: transparent;
    background: linear-gradient(180deg, #74DDFF 0%, var(--cta) 55%, #33B8EC 100%);
    color: var(--cta-ink);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .45), 0 10px 28px -10px rgba(var(--cta-rgb), .7);
}

.btn-ghost {
    background: transparent;
}

.btn-danger {
    border-color: transparent;
    background: var(--ink);
    color: #07101A;
}

.btn-wide {
    width: 100%;
}

.icon-btn {
    display: inline-grid;
    place-items: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: 12px;
    background: transparent;
    color: var(--ink-2);
    cursor: pointer;
}

.link-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    padding: 0 14px;
    border: 0;
    border-radius: 12px;
    background: transparent;
    color: var(--ink-2);
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: color .15s, background-color .15s;
}

@media (hover: hover) and (pointer: fine) {
    .btn:hover {
        border-color: #3A4A6E;
        background: rgba(255, 255, 255, 0.07);
    }

    .btn-primary:hover {
        background: linear-gradient(180deg, #8AE3FF 0%, #5AD6FF 55%, #3DBFF0 100%);
        box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5), 0 12px 32px -10px rgba(var(--cta-rgb), .85);
    }

    .btn-ghost:hover {
        background: rgba(255, 255, 255, 0.05);
    }

    .btn-danger:hover {
        background: #FFFFFF;
    }

    .icon-btn:hover,
    .link-btn:hover {
        color: var(--ink);
        background: rgba(255, 255, 255, 0.06);
    }
}

/* Segmented control */
.seg {
    display: inline-grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 4px;
    padding: 4px;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    background: rgba(4, 6, 13, 0.55);
}

.seg-btn {
    position: relative;
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    min-width: 44px;
    min-height: 44px;
    padding: 0 12px;
    border: 0;
    border-radius: var(--r-sm);
    background: transparent;
    color: var(--ink-2);
    font-size: 15px;
    font-weight: 700;
    line-height: 1.1;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color .15s, color .15s, box-shadow .15s;
}

.seg-btn.is-on {
    background: rgba(var(--cta-rgb), .14);
    color: var(--ink);
    box-shadow: inset 0 0 0 1px rgba(var(--cta-rgb), .6);
}

.seg-btn:focus-visible {
    outline-offset: 1px;
}

.seg-sub {
    font-size: 11px;
    font-weight: 600;
    color: var(--ink-3);
}

.seg-btn.is-on .seg-sub {
    color: var(--ink-2);
}

.seg-tall .seg-btn {
    min-height: 56px;
    padding: 6px 8px;
}

.seg-thumbs .seg-btn {
    min-height: 88px;
    gap: 4px;
}

.seg-thumb {
    display: block;
    color: var(--ink-3);
    transition: color .15s;
}

.seg-thumb .thumb {
    display: block;
    width: 44px;
    height: 44px;
}

.seg-btn.is-on .seg-thumb {
    color: var(--cta);
}

.seg-compact {
    padding: 3px;
    border-radius: 12px;
}

.seg-compact .seg-btn {
    min-width: 44px;
    padding: 0 10px;
    font-size: 13px;
    letter-spacing: .06em;
}

@media (hover: hover) and (pointer: fine) {
    .seg-btn:not(.is-on):hover {
        background: rgba(255, 255, 255, 0.05);
        color: var(--ink);
    }
}

/* ------------------------------------------------------------------ */
/* Main menu                                                          */
/* ------------------------------------------------------------------ */

.menu {
    inset: 0;
    z-index: 50;
    pointer-events: auto;
    transition: opacity .32s var(--ease-out);
}

.menu[data-state="enter"] {
    opacity: 0;
}

.menu[data-state="closing"] {
    opacity: 0;
    transition: opacity var(--t-exit) var(--ease-in);
}

.menu[data-state="closing"] .menu-inner {
    translate: 0 -12px;
    scale: .98;
    transition: translate var(--t-exit) var(--ease-in), scale var(--t-exit) var(--ease-in);
}

/* The attract-mode match plays on the canvas underneath: dim and blur it just
   enough that the menu reads first and the battle reads as mood. */
.menu-scrim {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(ellipse 70% 60% at 50% 42%, rgba(7, 11, 24, .30) 0%, rgba(4, 6, 13, .48) 100%),
        linear-gradient(180deg, rgba(4, 6, 13, .25) 0%, rgba(4, 6, 13, 0) 30%, rgba(4, 6, 13, .32) 100%);
    -webkit-backdrop-filter: blur(5px) saturate(1.15);
    backdrop-filter: blur(5px) saturate(1.15);
}

.menu-scroll {
    position: absolute;
    inset: 0;
    display: grid;
    align-items: safe center;
    justify-items: center;
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    touch-action: pan-y;
    padding:
        max(28px, calc(var(--sat) + 20px)) max(16px, calc(var(--sar) + 16px)) max(24px, calc(var(--sab) + 16px)) max(16px, calc(var(--sal) + 16px));
}

.menu-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: clamp(18px, 3.4vh, 30px);
    width: min(680px, 100%);
    text-align: center;
    animation: menu-in .7s var(--ease-out) both;
}

@keyframes menu-in {
    from {
        opacity: 0;
        translate: 0 14px;
    }
}

/* Hero */
.hero {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
}

.wordmark {
    position: relative;
    margin: 0;
    /* Letter-spacing adds trailing space after the last glyph; pad the left by
       the same amount so the word is optically centred. */
    padding-left: .16em;
    font-family: var(--font-wordmark);
    font-weight: 800;
    font-size: clamp(34px, 10.4vw, 78px);
    line-height: 1;
    letter-spacing: .16em;
    white-space: nowrap;
}

.wordmark-text {
    position: relative;
    display: block;
    background: linear-gradient(100deg, #D8F3FF 0%, #FFFFFF 22%, #A9E6FF 44%, #45D0FF 70%, #D8F3FF 100%);
    background-size: 220% 100%;
    background-position: 0% 50%;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    animation: wordmark-sheen 9s ease-in-out infinite alternate;
}

.wordmark-glow {
    position: absolute;
    inset: 0 0 0 .16em;
    display: block;
    color: var(--cta);
    filter: blur(18px);
    opacity: .45;
    animation: wordmark-glow 4.8s ease-in-out infinite alternate;
    pointer-events: none;
}

@keyframes wordmark-glow {
    from {
        opacity: .28;
        scale: .985;
    }

    to {
        opacity: .62;
        scale: 1.015;
    }
}

@keyframes wordmark-sheen {
    to {
        background-position: 100% 50%;
    }
}

.hero-rule {
    position: relative;
    width: min(220px, 60%);
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(var(--cta-rgb), .55), transparent);
}

.hero-rule-dot {
    position: absolute;
    top: -2px;
    left: 0;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: #FFFFFF;
    box-shadow: 0 0 8px 2px rgba(var(--cta-rgb), .9);
    animation: rule-dot 6s ease-in-out infinite alternate;
}

@keyframes rule-dot {
    from {
        left: 18%;
    }

    to {
        left: calc(82% - 5px);
    }
}

.tagline {
    margin: 0;
    color: var(--ink-2);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .32em;
    padding-left: .32em;
    text-transform: uppercase;
}

/* PLAY */
.play-btn {
    position: relative;
    isolation: isolate;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    width: min(340px, 100%);
    height: 68px;
    padding: 0 36px;
    border: 0;
    border-radius: 20px;
    background: linear-gradient(180deg, #7FE0FF 0%, var(--cta) 52%, #2FB3E8 100%);
    color: var(--cta-ink);
    font-size: 22px;
    font-weight: 700;
    letter-spacing: .18em;
    text-transform: uppercase;
    cursor: pointer;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, .55),
        inset 0 -2px 0 rgba(4, 18, 28, .18),
        0 16px 44px -14px rgba(var(--cta-rgb), .85);
    transition: transform .14s var(--ease-out), box-shadow .2s, filter .2s;
}

/* A slow breathing halo behind PLAY: the one element on the screen that is
   asking for attention. */
.play-btn::before {
    content: '';
    position: absolute;
    inset: -1px;
    z-index: -1;
    border-radius: inherit;
    box-shadow: 0 0 0 0 rgba(var(--cta-rgb), .45);
    animation: play-halo 2.8s ease-out infinite;
}

@keyframes play-halo {
    0% {
        box-shadow: 0 0 0 0 rgba(var(--cta-rgb), .40);
    }

    70%,
    100% {
        box-shadow: 0 0 0 16px rgba(var(--cta-rgb), 0);
    }
}

.play-label {
    padding-left: .18em;
}

.play-icon {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: rgba(4, 18, 28, .14);
}

.play-btn:active {
    transform: scale(.975);
}

.play-btn:focus-visible {
    outline-offset: 4px;
}

@media (hover: hover) and (pointer: fine) {
    .play-btn:hover {
        filter: brightness(1.06);
        transform: translateY(-1px);
        box-shadow:
            inset 0 1px 0 rgba(255, 255, 255, .6),
            inset 0 -2px 0 rgba(4, 18, 28, .18),
            0 20px 50px -14px rgba(var(--cta-rgb), 1);
    }
}

/* Summary chips */
.chips {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
    max-width: 660px;
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    padding: 0 16px 0 12px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface);
    color: var(--ink);
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: border-color .15s, background-color .15s, transform .12s;
}

.chip-ico {
    display: grid;
    place-items: center;
    color: var(--ink-2);
}

.chip-custom {
    border-color: rgba(var(--cta-rgb), .38);
    color: var(--cta);
}

.chip-custom .chip-ico {
    color: var(--cta);
}

.chip:active {
    transform: scale(.97);
}

@media (hover: hover) and (pointer: fine) {
    .chip:hover {
        border-color: #3A4A6E;
        background: var(--surface-raised);
    }

    .chip-custom:hover {
        border-color: rgba(var(--cta-rgb), .7);
    }
}

/* Footer */
.menu-footer {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
}

.footer-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 8px 14px;
}

.footer-lang {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--ink-3);
}

.career {
    margin: 0;
    line-height: 1.45;
    color: var(--ink-3);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------------ */
/* Custom sheet                                                       */
/* ------------------------------------------------------------------ */

.sheet {
    inset: 0;
    z-index: 5;
    display: grid;
    align-items: end;
    justify-items: center;
    pointer-events: auto;
}

.sheet-scrim {
    position: absolute;
    inset: 0;
    background: rgba(4, 6, 13, .62);
    transition: opacity .28s var(--ease-out);
}

.sheet-card {
    position: relative;
    display: flex;
    flex-direction: column;
    width: min(580px, 100%);
    max-height: calc(100dvh - var(--sat) - 12px);
    border: 1px solid var(--border);
    border-bottom: 0;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    background: var(--surface-solid);
    box-shadow: 0 -24px 70px rgba(0, 0, 0, .55);
    transition: translate .32s var(--ease-out), opacity .32s var(--ease-out);
}

.sheet[data-state="enter"] .sheet-scrim,
.sheet[data-state="closing"] .sheet-scrim {
    opacity: 0;
}

.sheet[data-state="enter"] .sheet-card,
.sheet[data-state="closing"] .sheet-card {
    translate: 0 40px;
    opacity: 0;
}

.sheet[data-state="closing"] .sheet-card,
.sheet[data-state="closing"] .sheet-scrim {
    transition-duration: var(--t-exit);
    transition-timing-function: var(--ease-in);
}

.sheet-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 12px 6px 22px;
}

.sheet-title {
    margin: 0;
    font-size: 20px;
    font-weight: 700;
}

.sheet-body {
    display: grid;
    gap: 18px;
    padding: 8px 22px 18px;
    overflow-y: auto;
    overscroll-behavior: contain;
    touch-action: pan-y;
    /* Fade the last line so a clipped group reads as "scroll for more". */
    -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - 18px), transparent);
    mask-image: linear-gradient(180deg, #000 calc(100% - 18px), transparent);
}

.group {
    min-width: 0;
}

.group-title {
    margin: 0 0 8px;
    color: var(--ink-2);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
}

.group .seg {
    display: grid;
    width: 100%;
}

.group-hint {
    margin: 8px 2px 0;
    color: var(--ink-2);
    font-size: 13px;
    line-height: 1.4;
}

.sheet-foot {
    display: flex;
    gap: 10px;
    padding: 14px 22px max(16px, calc(var(--sab) + 12px));
    border-top: 1px solid var(--border);
}

.sheet-foot .btn {
    flex: 1;
    min-height: 52px;
}

.sheet-foot .btn-primary {
    flex: 1.4;
}

/* Reserve two lines on phones so switching hints doesn't jump the layout. */
@media (max-width: 560px) {
    .group-hint {
        min-height: 2.8em;
    }
}

/* Desktop / tablet: a centred panel instead of a bottom sheet. */
@media (min-width: 720px) and (min-height: 640px) {
    .sheet {
        align-items: center;
        padding: 24px;
    }

    .sheet-card {
        max-height: calc(100dvh - 48px);
        border-bottom: 1px solid var(--border);
        border-radius: var(--r-lg);
        box-shadow: 0 30px 90px rgba(0, 0, 0, .6);
    }

    .sheet-foot {
        padding-bottom: 16px;
    }
}

/* Landscape phones: two columns so the sheet doesn't need a long scroll. */
@media (min-width: 640px) and (max-height: 639px) {
    .sheet {
        align-items: center;
        padding: max(8px, var(--sat)) max(12px, var(--sar)) max(8px, var(--sab)) max(12px, var(--sal));
    }

    .sheet-card {
        width: min(820px, 100%);
        max-height: calc(100dvh - 16px - var(--sat) - var(--sab));
        border-bottom: 1px solid var(--border);
        border-radius: var(--r-lg);
    }

    .sheet-head {
        padding-top: 8px;
        padding-bottom: 0;
    }

    .sheet-body {
        grid-template-columns: 1fr 1fr;
        gap: 12px 22px;
        padding-bottom: 10px;
    }

    .group-hint {
        min-height: 0;
        font-size: 12px;
    }

    .sheet-foot {
        padding: 10px 22px;
    }

    .sheet-foot .btn {
        min-height: 46px;
    }
}

/* Short screens (landscape phones): tighten the menu so it fits without
   scrolling where possible. */
@media (max-height: 520px) {
    .menu-inner {
        gap: 14px;
    }

    .wordmark {
        font-size: clamp(30px, 7vh, 48px);
    }

    .hero {
        gap: 6px;
    }

    .play-btn {
        height: 56px;
        font-size: 20px;
    }

    .tagline {
        font-size: 12px;
    }
}

/* ------------------------------------------------------------------ */
/* HUD                                                                */
/* ------------------------------------------------------------------ */

.hud {
    inset: 0;
    z-index: 10;
}

.hud-strip {
    position: absolute;
    top: calc(var(--sat) + var(--hud-gap));
    left: calc(var(--sal) + 12px);
    right: calc(var(--sar) + 12px);
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 8px;
    transition: opacity .25s var(--ease-out), translate .25s var(--ease-out);
}

.hud[data-state="enter"] .hud-strip,
.hud[data-state="closing"] .hud-strip {
    opacity: 0;
    translate: 0 -10px;
}

.hud[data-state="enter"] .send-pill,
.hud[data-state="closing"] .send-pill {
    opacity: 0;
    translate: 0 10px;
}

.hud[data-state="closing"] .hud-strip,
.hud[data-state="closing"] .send-pill {
    transition-duration: var(--t-exit);
    transition-timing-function: var(--ease-in);
}

.hud-chip,
.hud-controls {
    pointer-events: auto;
    display: flex;
    align-items: center;
    height: var(--hud-h);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    background: var(--surface);
    box-shadow: 0 6px 22px rgba(0, 0, 0, .28);
}

.hud-chip {
    flex: 0 1 auto;
    min-width: 0;
    gap: 12px;
    padding: 0 14px 0 12px;
}

.hud-stars {
    display: flex;
    align-items: baseline;
    gap: 6px;
    /* Sized for '99 stars' / '99 звёзд', so the territory bar beside it
       doesn't slide sideways as the count changes. */
    min-width: 7.2em;
    white-space: nowrap;
}

.hud-dot {
    align-self: center;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--f-player);
    box-shadow: 0 0 10px var(--me, var(--f-player));
}

.hud-count {
    font-size: 20px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

.hud-count {
    min-width: 2ch;
}

.hud-count-label {
    color: var(--ink-2);
    font-size: 12px;
    line-height: 1.3;
}

.hud-terr {
    display: flex;
    flex-direction: column;
    gap: 5px;
    width: clamp(64px, 20vw, 220px);
    min-width: 0;
}

.terr-bar {
    display: flex;
    gap: 1px;
    height: 6px;
    border-radius: 3px;
    overflow: hidden;
    background: rgba(125, 136, 161, .2);
}

.terr-seg {
    height: 100%;
    flex: none;
    transition: width .3s var(--ease-out);
}

.terr-seg:first-child {
    border-radius: 3px 0 0 3px;
}

.hud-units {
    overflow: hidden;
    color: var(--ink-2);
    font-size: 12px;
    /* overflow:hidden clips at the line box: 1.3 keeps the descenders of
       'ships' / 'корабль' inside it. */
    line-height: 1.3;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.hud-controls {
    flex: none;
    gap: 2px;
    padding: 0 2px;
}

.hud-btn {
    display: inline-grid;
    place-items: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: 11px;
    background: transparent;
    color: var(--ink-2);
    cursor: pointer;
    transition: background-color .15s, color .15s;
}

.hud-btn.is-muted {
    color: var(--ink-3);
}

.hud-btn:active {
    background: rgba(255, 255, 255, .08);
}

.speed-cycle {
    display: none;
    font-size: 14px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--ink);
}

.seg-hud {
    gap: 2px;
    margin: 0 2px;
    padding: 0 4px;
    border: 0;
    border-left: 1px solid var(--border);
    border-right: 1px solid var(--border);
    border-radius: 0;
    background: transparent;
}

.seg-hud .seg-btn {
    min-width: 40px;
    min-height: 40px;
    padding: 0 6px;
    font-size: 14px;
    font-variant-numeric: tabular-nums;
}

.seg-hud .seg-btn.is-on {
    background: rgba(255, 255, 255, .09);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .16);
}

@media (hover: hover) and (pointer: fine) {
    .hud-btn:hover {
        background: rgba(255, 255, 255, .07);
        color: var(--ink);
    }
}

/* Phones: the speed control collapses to one cycling button. Landscape
   phones too, whose strip also holds the mode pill (and the PAUSED badge):
   with the ½×–3× segment the pill kept ~60 px for its text at 740 px, and a
   notched iPhone loses ~90 px more to the safe areas. */
@media (max-width: 599px), (orientation: landscape) and (max-height: 500px) {
    .speed-seg {
        display: none;
    }

    .speed-cycle {
        display: inline-grid;
        box-shadow: inset 1px 0 0 var(--border), inset -1px 0 0 var(--border);
        border-radius: 0;
    }
}

@media (max-width: 400px) {
    .hud-strip {
        gap: 6px;
        left: calc(var(--sal) + 8px);
        right: calc(var(--sar) + 8px);
    }

    .hud-count-label {
        display: none;
    }

    .hud-stars {
        min-width: 0;
    }

    .hud-chip {
        gap: 10px;
        padding: 0 10px;
    }

    .hud-terr {
        flex: 1;
        width: auto;
        min-width: 48px;
    }
}

/* Mode pill (Hill / Timed). It sits in the strip's DOM so the compact
   landscape layout can drop it into the strip's centre gap; everywhere else
   it hangs centred just under the strip. */
.mode-pill {
    position: absolute;
    top: calc(100% + 8px);
    left: 0;
    right: 0;
    width: max-content;
    max-width: 100%;
    margin: 0 auto;
    display: flex;
    align-items: center;
    gap: 8px;
    height: 32px;
    padding: 0 12px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.mode-ico {
    display: grid;
    color: var(--mode, var(--ink-2));
}

.mode-text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Time to the holder's win: never shortened, the name gives way instead. */
.mode-time {
    flex: none;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.mode-time::before {
    content: '·';
    margin-right: 6px;
    font-weight: 400;
    color: var(--ink-3);
}

.mode-time[hidden] {
    display: none;
}

.mode-track {
    flex: none;
    width: 64px;
    height: 4px;
    border-radius: 2px;
    overflow: hidden;
    background: rgba(255, 255, 255, .1);
}

.mode-fill {
    display: block;
    height: 100%;
    background: var(--mode, var(--ink-2));
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform .3s var(--ease-out);
}

/* In the Send pill's slot (see Hud.refreshPausedBadge): the board is already
   laid out around it, so the badge never covers a star. */
.paused-badge {
    position: absolute;
    bottom: calc(var(--sab) + 12px);
    left: 0;
    right: 0;
    width: max-content;
    margin: 0 auto;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 18px 10px 14px;
    border: 1px solid var(--border-2);
    border-radius: 999px;
    background: var(--surface);
    color: var(--ink);
    font-size: 14px;
    font-weight: 700;
    letter-spacing: .22em;
    text-transform: uppercase;
    animation: fade-in .2s var(--ease-out);
}

@keyframes fade-in {
    from {
        opacity: 0;
    }
}

.hud.is-paused .send-pill {
    visibility: hidden;
}

/* Send % pill: bottom centre, above the home indicator, in the thumb zone. */
.send-pill {
    position: absolute;
    bottom: calc(var(--sab) + 12px);
    left: 0;
    right: 0;
    width: max-content;
    margin: 0 auto;
    pointer-events: auto;
    transition: opacity .25s var(--ease-out), translate .25s var(--ease-out);
}

.seg-send {
    gap: 3px;
    padding: 4px;
    border-radius: 16px;
    background: var(--surface);
    box-shadow: 0 8px 26px rgba(0, 0, 0, .35);
}

.seg-send .seg-btn {
    min-width: 60px;
    min-height: 44px;
    border-radius: 12px;
    font-size: 15px;
    font-variant-numeric: tabular-nums;
}

.seg-send .seg-btn.is-on {
    background: var(--cta);
    color: var(--cta-ink);
    box-shadow: 0 4px 14px -4px rgba(var(--cta-rgb), .8);
}

/* Desktop hint: the 1-4 keys pick the share. */
@media (hover: hover) and (pointer: fine) {
    .seg-send .seg-btn::after {
        content: attr(data-key);
        position: absolute;
        top: 3px;
        right: 5px;
        font-size: 11px;
        line-height: 1;
        font-weight: 700;
        color: var(--ink-3);
    }

    .seg-send .seg-btn.is-on::after {
        color: rgba(4, 18, 28, .55);
    }
}

@media (max-width: 360px) {
    .seg-send .seg-btn {
        min-width: 54px;
    }
}

/* The share that would win the current aim: a static outline plus two soft
   pulses (the pulses drop out under reduced motion, the outline stays). */
.seg-send .seg-btn.is-hint {
    box-shadow: inset 0 0 0 2px rgba(var(--cta-rgb), .9);
    color: var(--ink);
    animation: send-hint .7s var(--ease-out) 2;
}

.seg-send .seg-btn.is-hint.is-on {
    box-shadow: 0 4px 14px -4px rgba(var(--cta-rgb), .8);
}

@keyframes send-hint {
    50% {
        box-shadow: inset 0 0 0 2px rgba(var(--cta-rgb), .9), 0 0 0 6px rgba(var(--cta-rgb), .22);
    }
}

/* Short landscape phones: every row of HUD costs a quarter of the board, so
   the mode pill joins the strip's centre gap and the Send pill docks as a
   vertical control at the right edge. Keep in sync with LANDSCAPE_COMPACT in
   js/ui/Hud.js. */
@media (orientation: landscape) and (max-height: 500px) {
    .mode-pill {
        position: static;
        flex: 0 1 auto;
        min-width: 0;
        align-self: center;
        margin: 0;
    }

    .mode-track {
        width: 40px;
    }

    .hud-terr {
        width: clamp(64px, 14vw, 160px);
    }

    /* The chip gives the mode pill its room: the count alone says it. */
    .hud-stars {
        min-width: 0;
    }

    .hud-count-label {
        display: none;
    }

    /* Paused: the badge takes the mode pill's place in the strip (the Send
       pill stays: it is at the side here and covers no board). */
    .paused-badge {
        top: calc(var(--sat) + var(--hud-gap));
        bottom: auto;
        height: var(--hud-h);
        padding-top: 0;
        padding-bottom: 0;
    }

    .hud.is-paused .send-pill {
        visibility: visible;
    }

    .hud.is-paused .mode-pill {
        visibility: hidden;
    }

    .send-pill {
        top: calc(var(--hud-bottom) + 8px);
        bottom: calc(var(--sab) + 8px);
        left: auto;
        right: calc(var(--sar) + 8px);
        height: max-content;
        margin: auto 0;
    }

    .hud[data-state="enter"] .send-pill,
    .hud[data-state="closing"] .send-pill {
        translate: 10px 0;
    }

    .seg-send {
        grid-auto-flow: row;
        grid-auto-rows: 1fr;
    }

    .seg-send .seg-btn {
        min-width: 52px;
        min-height: 44px;
        padding: 0 6px;
    }
}

/* Narrow landscape phones (iPhone SE and 5 at 568, most Androids at 640):
   the strip is tight even with the one speed button, so the chip and the
   pill give up some padding and the pill's progress track shortens; the
   status text ('Аметист на холме') keeps the room. */
@media (orientation: landscape) and (max-height: 500px) and (max-width: 700px) {
    .hud-strip {
        gap: 6px;
    }

    .hud-chip {
        gap: 8px;
        padding: 0 10px 0 9px;
    }

    .mode-pill {
        gap: 6px;
        padding: 0 10px;
    }

    .mode-track {
        width: 24px;
    }
}

/* 568 px: the track goes (the countdown beside the name says the same) and
   the territory column keeps just the room for '120 кораблей'. */
@media (orientation: landscape) and (max-height: 500px) and (max-width: 600px) {
    .hud-strip {
        gap: 4px;
    }

    .hud-chip {
        gap: 6px;
        padding: 0 8px;
    }

    .hud-terr {
        width: 78px;
    }

    .mode-pill {
        gap: 5px;
        padding: 0 8px;
    }

    .mode-track {
        display: none;
    }
}

/* ------------------------------------------------------------------ */
/* Context ring                                                       */
/* ------------------------------------------------------------------ */

.ring {
    left: 0;
    top: 0;
    /* Above the coach card and the toasts: an opened ring is what the player
       is doing now (and its docked hint shares the toasts' row). */
    z-index: 41;
    width: 0;
    height: 0;
}

.ring-btn {
    position: absolute;
    left: -24px;
    top: -24px;
    width: 48px;
    height: 48px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--ink);
    cursor: pointer;
    pointer-events: auto;
    transform: translate(var(--dx, 0px), var(--dy, 0px));
    transition:
        transform .26s var(--ease-back) calc(var(--i, 0) * 28ms),
        opacity .18s var(--ease-out) calc(var(--i, 0) * 28ms);
}

.ring[data-state="enter"] .ring-btn {
    opacity: 0;
    transform: translate(0, 0) scale(.4);
}

.ring[data-state="closing"] .ring-btn {
    opacity: 0;
    transform: translate(calc(var(--dx, 0px) * .6), calc(var(--dy, 0px) * .6)) scale(.7);
    transition-duration: var(--t-exit);
    transition-delay: 0ms;
    transition-timing-function: var(--ease-in);
}

.ring-disc {
    position: relative;
    display: grid;
    place-items: center;
    width: 48px;
    height: 48px;
    overflow: hidden;
    border: 1.5px solid rgba(232, 238, 248, .24);
    border-radius: 50%;
    background: var(--surface-solid);
    box-shadow: 0 8px 22px rgba(0, 0, 0, .5);
    transition: border-color .15s, color .15s, background-color .15s;
}

.ring-ico {
    position: relative;
    display: grid;
}

/* Cooldown: the part of the dial still recharging is shaded, sweeping
   clockwise from 12 o'clock. */
.ring-cd {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: conic-gradient(rgba(4, 6, 13, .82) calc(var(--cd, 0) * 1turn), transparent 0);
}

.ring-btn.is-cooling .ring-ico {
    color: var(--ink-3);
}

.ring-sub {
    position: absolute;
    top: 38px;
    left: 50%;
    translate: -50% 0;
    min-width: 22px;
    height: 18px;
    padding: 0 6px;
    border-radius: 9px;
    background: var(--ink);
    color: #07101A;
    font-size: 11px;
    font-weight: 700;
    line-height: 18px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Captions sit on the outward side of the fan (Ring.place sets data-side),
   so they never land on the ringed star's number. Offsets match the CAP_*
   constants in js/ui/Ring.js. */
.ring-cap {
    position: absolute;
    top: 60px;
    left: 50%;
    translate: -50% 0;
    padding: 2px 7px;
    border-radius: 7px;
    background: var(--surface-solid);
    color: var(--ink);
    font-size: 12px;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
}

.ring-btn[data-side="top"] .ring-cap {
    top: auto;
    bottom: 52px;
}

/* What the special star's ability does, one line past the fan's outer edge. */
.ring-hint {
    position: absolute;
    left: 0;
    top: 0;
    width: max-content;
    max-width: min(280px, calc(100vw - 16px));
    margin: 0;
    padding: 4px 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface-solid);
    color: var(--ink-2);
    font-size: 12px;
    font-weight: 600;
    line-height: 1.3;
    text-align: center;
    pointer-events: none;
    transform: translate(var(--dx, 0px), var(--dy, 0px));
    transition: opacity .18s var(--ease-out) 80ms;
}

/* No clear spot beside the fan: a card centred under the HUD (or above the
   bottom chrome), which may wrap to two lines. */
.ring-hint.is-docked {
    max-width: min(320px, calc(100vw - 32px));
    padding: 6px 12px;
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .45);
}

.ring[data-state="enter"] .ring-hint,
.ring[data-state="closing"] .ring-hint {
    opacity: 0;
    transition-delay: 0ms;
}

.ring-btn.is-disabled {
    cursor: not-allowed;
}

.ring-btn.is-disabled .ring-disc {
    border-color: rgba(232, 238, 248, .1);
    color: var(--ink-3);
}

.ring-btn.is-disabled .ring-sub {
    background: #2A3754;
    color: var(--ink-2);
}

.ring-btn.is-disabled .ring-cap {
    color: var(--ink-2);
}

.ring-btn:focus-visible {
    outline: none;
}

.ring-btn:focus-visible .ring-disc {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
}

.ring-btn:not(.is-disabled):active .ring-disc {
    background: rgba(var(--cta-rgb), .18);
}

@media (hover: hover) and (pointer: fine) {
    .ring-btn:not(.is-disabled):hover .ring-disc {
        border-color: var(--cta);
        color: var(--cta);
    }
}

/* ------------------------------------------------------------------ */
/* Intel tooltip                                                      */
/* ------------------------------------------------------------------ */

.tip {
    left: 0;
    top: 0;
    z-index: 36;
    width: max-content;
    min-width: 168px;
    max-width: min(260px, calc(100vw - 16px));
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface-solid);
    box-shadow: 0 12px 34px rgba(0, 0, 0, .5);
    pointer-events: none;
    transition: opacity .15s var(--ease-out), scale .15s var(--ease-out);
}

.tip::before {
    content: '';
    position: absolute;
    top: 12px;
    bottom: 12px;
    left: -1px;
    width: 2px;
    border-radius: 2px;
    background: var(--tip, var(--neutral-rim));
}

.tip[data-state="enter"],
.tip[data-state="closing"] {
    opacity: 0;
    scale: .96;
}

.tip[data-state="closing"] {
    transition-duration: var(--t-exit);
}

.tip-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
    font-size: 14px;
    font-weight: 700;
}

.tip-dot {
    flex: none;
    width: 8px;
    height: 8px;
    border-radius: 50%;
}

.tip-rows {
    display: grid;
    grid-template-columns: auto auto;
    gap: 4px 16px;
    margin: 0;
    font-size: 13px;
}

.tip-rows dt {
    color: var(--ink-2);
}

.tip-rows dd {
    margin: 0;
    color: var(--ink);
    font-weight: 700;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.tip-note {
    margin: 8px 0 0;
    color: var(--ink-2);
    font-size: 12px;
    font-weight: 600;
    line-height: 1.35;
}

.tip-verdict {
    margin: 10px 0 0;
    padding-top: 9px;
    border-top: 1px solid var(--border);
    color: var(--ink-2);
    font-size: 13px;
    font-weight: 700;
    line-height: 1.35;
}

.tip-verdict[data-tone="ok"],
.tip-verdict[data-tone="good"] {
    color: var(--success);
}

.tip-verdict[data-tone="warn"],
.tip-verdict[data-tone="close"] {
    color: var(--warning);
}

/* Failure is white with a cross, never a faction colour. */
.tip-verdict[data-tone="bad"] {
    color: var(--ink);
}

.tip-verdict[data-tone="bad"]::before {
    content: '\2715\00a0';
}

/* ------------------------------------------------------------------ */
/* Coach                                                              */
/* ------------------------------------------------------------------ */

.coach {
    left: 0;
    right: 0;
    bottom: calc(var(--sab) + 12px + var(--pill-h) + 12px);
    z-index: 30;
    display: flex;
    justify-content: center;
    padding: 0 max(12px, var(--sar)) 0 max(12px, var(--sal));
    transition: opacity .25s var(--ease-out), translate .25s var(--ease-out);
}

.coach[data-state="enter"],
.coach[data-state="closing"] {
    opacity: 0;
    translate: 0 12px;
}

.coach[data-state="closing"] {
    transition-duration: var(--t-exit);
    transition-timing-function: var(--ease-in);
}

/* The board is laid out above the card (UI.insets), but touches still pass
   through it so a star near the band edge is never blocked; only Skip is
   interactive. */
.coach-card {
    display: flex;
    gap: 12px;
    width: min(480px, 100%);
    padding: 14px 8px 6px 14px;
    border: 1px solid rgba(var(--cta-rgb), .34);
    border-radius: 16px;
    background: var(--surface-solid);
    box-shadow: 0 14px 40px rgba(0, 0, 0, .5);
    pointer-events: none;
}

.coach-ico {
    flex: none;
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: rgba(var(--cta-rgb), .12);
    color: var(--cta);
}

.coach-main {
    position: relative;
    flex: 1;
    min-width: 0;
}

.coach-text {
    /* Two lines reserved, so the card (and the board laid out above it) keeps
       its height from one step to the next. */
    min-height: 2.84em;
    margin: 5px 6px 0 0;
    color: var(--ink);
    font-size: 15px;
    line-height: 1.42;
    transition: opacity .14s, translate .14s;
}

/* Step change: the old sentence (a copy laid over the new one) fades out
   while the new one fades in. */
.coach-text.is-entering {
    animation: coach-text-in .26s var(--ease-out) both;
}

.coach-text.is-ghost {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    animation: coach-text-out .2s var(--ease-in) both;
}

@keyframes coach-text-in {
    from {
        opacity: 0;
        translate: 0 4px;
    }
}

@keyframes coach-text-out {
    to {
        opacity: 0;
        translate: 0 -4px;
    }
}

.coach-row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 4px;
}

.coach-dots {
    display: flex;
    gap: 4px;
}

.coach-dots i {
    width: 6px;
    height: 6px;
    border-radius: 3px;
    background: var(--ink-3);
    transition: width .25s var(--ease-out), background-color .25s;
}

.coach-dots i.is-done {
    background: var(--ink-2);
}

.coach-dots i.is-on {
    width: 16px;
    background: var(--cta);
}

.coach-progress {
    color: var(--ink-3);
    font-size: 12px;
    white-space: nowrap;
}

.coach-skip {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    min-height: 44px;
    margin-left: auto;
    padding: 0 8px 0 12px;
    border: 0;
    border-radius: 10px;
    background: transparent;
    color: var(--ink-2);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    pointer-events: auto;
}

@media (hover: hover) and (pointer: fine) {
    .coach-skip:hover {
        color: var(--ink);
        background: rgba(255, 255, 255, .05);
    }
}

/* Phones: a compact card (≤ 88 px tall) of two lines of text and one row of
   dots, progress and Skip, so the board above it keeps most of the screen.
   Skip keeps a 44 px target by overhanging the row. */
@media (max-width: 480px), (max-height: 500px) {
    .coach {
        padding: 0 max(8px, var(--sar)) 0 max(8px, var(--sal));
    }

    .coach-card {
        padding: 10px 6px 8px 12px;
        border-radius: 14px;
    }

    .coach-ico {
        display: none;
    }

    .coach-text {
        display: -webkit-box;
        margin: 0 6px 0 0;
        overflow: hidden;
        min-height: 2.6em;
        font-size: 14px;
        line-height: 1.3;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 2;
        line-clamp: 2;
    }

    .coach-row {
        height: 24px;
        margin-top: 6px;
    }

    .coach-skip {
        margin-top: -10px;
        margin-bottom: -10px;
    }
}

@media (max-width: 400px) {
    .coach-progress {
        display: none;
    }
}

/* Compact landscape: height is what the board is short of, so the card is one
   row (text, then dots and Skip beside it) at the bottom-left, clear of the
   Send pill docked at the right. Two text lines are reserved, like on phones,
   so the card, and the board laid out above it, keeps its height from step to
   step: about 46 px, 52 px with its gap. One line would cut the teaching
   sentence at this width. */
@media (orientation: landscape) and (max-height: 500px) {
    .coach {
        left: 0;
        right: auto;
        bottom: calc(var(--sab) + 6px);
        width: min(60vw, 600px);
        justify-content: flex-start;
        padding: 0 0 0 max(12px, var(--sal));
    }

    .coach-card {
        width: 100%;
        align-items: center;
        gap: 8px;
        padding: 5px 2px 5px 12px;
        border-radius: 12px;
    }

    /* The two lines are reserved on the row, not the text, so a one-line
       sentence sits centred beside Skip instead of hanging from the top. */
    .coach-main {
        display: flex;
        align-items: center;
        gap: 8px;
        min-height: 32.5px;
    }

    .coach-text {
        flex: 1;
        min-width: 0;
        min-height: 0;
        margin: 0;
        font-size: 13px;
        line-height: 1.25;
    }

    .coach-text.is-ghost {
        bottom: 0;
        height: fit-content;
        margin: auto 0;
    }

    .coach-row {
        flex: none;
        height: auto;
        margin: 0;
        gap: 6px;
    }

    .coach-progress {
        display: none;
    }

    /* A 44 px touch target that overhangs the slim card. */
    .coach-skip {
        min-height: 44px;
        margin: -8px 0;
        padding: 0 6px 0 8px;
    }
}

/* Narrow landscape phones (640 px and less): a wider card for the text, and
   the dots give way to it. */
@media (orientation: landscape) and (max-height: 500px) and (max-width: 700px) {
    .coach {
        width: 72vw;
    }

    .coach-dots {
        display: none;
    }
}

/* ------------------------------------------------------------------ */
/* Toasts                                                             */
/* ------------------------------------------------------------------ */

.toasts {
    position: absolute;
    top: calc(var(--hud-bottom) + 8px);
    left: 12px;
    right: 12px;
    z-index: 40;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    pointer-events: none;
}

.toast {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    max-width: 100%;
    min-height: 36px;
    padding: 7px 16px 7px 12px;
    border: 1px solid var(--border-2);
    /* Half the one-line height: a pill for one line, a rounded card for two. */
    border-radius: 18px;
    background: var(--surface-solid);
    box-shadow: 0 10px 28px rgba(0, 0, 0, .45);
    font-size: 14px;
    transition: opacity .22s var(--ease-out), translate .22s var(--ease-out), scale .22s var(--ease-out);
}

.toast[data-state="enter"] {
    opacity: 0;
    translate: 0 -8px;
}

.toast[data-state="closing"] {
    opacity: 0;
    translate: 0 -6px;
    transition-duration: var(--t-exit);
}

.toast.is-bump {
    animation: toast-bump .3s var(--ease-back);
}

@keyframes toast-bump {
    50% {
        scale: 1.05;
    }
}

/* Tone is the icon's shape; success/warning colours belong to the aim label
   and the intel verdict (§3.1), so only plain info takes the CTA accent. */
.toast-ico {
    display: grid;
    color: var(--ink-2);
}

.toast[data-tone="info"] .toast-ico {
    color: var(--cta);
}

/* Under the mode pill while it is showing (it has its own row except in the
   compact landscape layout). */
.ui-root.has-mode-pill .toasts {
    top: calc(var(--hud-bottom) + 48px);
}

@media (orientation: landscape) and (max-height: 500px) {
    .ui-root.has-mode-pill .toasts {
        top: calc(var(--hud-bottom) + 8px);
    }
}

/* Up to two lines on a phone: the teaching toasts are whole sentences, and a
   cut one teaches nothing. (The copy is written to fit two lines at 360 px.) */
.toast-text {
    display: -webkit-box;
    overflow: hidden;
    line-height: 1.3;
    text-align: left;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
}

/* ------------------------------------------------------------------ */
/* Dialogs (pause, game over)                                         */
/* ------------------------------------------------------------------ */

.dialog {
    inset: 0;
    pointer-events: auto;
}

.pause {
    z-index: 70;
}

.gameover {
    z-index: 60;
}

.dialog-scrim {
    position: absolute;
    inset: 0;
    background: rgba(4, 6, 13, .72);
    transition: opacity .32s var(--ease-out);
}

.dialog-scroll {
    position: absolute;
    inset: 0;
    display: grid;
    align-items: safe center;
    justify-items: center;
    overflow-y: auto;
    overscroll-behavior: contain;
    touch-action: pan-y;
    padding:
        max(16px, calc(var(--sat) + 12px)) max(16px, calc(var(--sar) + 12px)) max(16px, calc(var(--sab) + 12px)) max(16px, calc(var(--sal) + 12px));
    pointer-events: none;
}

.dialog-card {
    position: relative;
    width: min(400px, 100%);
    padding: 22px;
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    background: rgba(11, 17, 34, .97);
    box-shadow: 0 30px 90px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 255, 255, .04);
    pointer-events: auto;
    transition: opacity .32s var(--ease-out), translate .32s var(--ease-out);
}

.dialog[data-state="enter"] .dialog-scrim,
.dialog[data-state="closing"] .dialog-scrim {
    opacity: 0;
}

.dialog[data-state="enter"] .dialog-card,
.dialog[data-state="closing"] .dialog-card {
    opacity: 0;
    translate: 0 16px;
}

.dialog[data-state="closing"] .dialog-scrim,
.dialog[data-state="closing"] .dialog-card {
    transition-duration: var(--t-exit);
    transition-timing-function: var(--ease-in);
}

.dialog-head {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 18px;
}

.dialog-badge {
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: rgba(var(--cta-rgb), .12);
    color: var(--cta);
}

.dialog-title {
    margin: 0;
    font-size: 22px;
    font-weight: 700;
}

.dialog-list {
    display: grid;
    gap: 8px;
}

.btn-row,
.row-static {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 12px;
    width: 100%;
    min-height: 54px;
    padding: 0 14px;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    background: rgba(255, 255, 255, .025);
    font-size: 16px;
    font-weight: 600;
    text-align: left;
}

.row-static {
    padding-right: 6px;
}

.btn-primary.btn-wide {
    justify-content: center;
    min-height: 56px;
    font-size: 17px;
}

.row-ico {
    display: grid;
    color: var(--ink-2);
}

.btn-primary .row-ico {
    color: inherit;
}

.row-label {
    flex: 1;
    min-width: 0;
}

.btn-primary .row-label {
    flex: none;
}

.row-static .seg {
    flex: none;
}

.switch {
    position: relative;
    flex: none;
    width: 42px;
    height: 26px;
    border-radius: 13px;
    background: var(--ink-3);
    transition: background-color .2s;
}

.switch i {
    position: absolute;
    top: 3px;
    left: 3px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--ink);
    box-shadow: 0 2px 6px rgba(0, 0, 0, .35);
    transition: translate .2s var(--ease-out);
}

.switch.is-on {
    background: var(--cta);
}

.switch.is-on i {
    translate: 16px 0;
}

.confirm {
    display: grid;
    justify-items: center;
    gap: 6px;
    text-align: center;
    animation: fade-in .18s var(--ease-out);
}

.confirm-ico {
    display: grid;
    place-items: center;
    width: 52px;
    height: 52px;
    margin-bottom: 4px;
    border-radius: 50%;
    background: rgba(255, 255, 255, .06);
    color: var(--ink);
}

.confirm-title {
    margin: 0;
    font-size: 20px;
    font-weight: 700;
}

.confirm-text {
    margin: 0 0 6px;
    color: var(--ink-2);
    font-size: 14px;
}

.confirm-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    width: 100%;
    margin-top: 6px;
}

/* Icon and label centred together; a long label ('Начать заново') wraps
   rather than overflowing the half-width button. */
.confirm-actions .btn {
    justify-content: center;
    gap: 8px;
    padding: 0 10px;
}

.confirm-actions .row-label {
    flex: 0 1 auto;
}

/* Phones: the half-width buttons can't fit 'Начать заново' beside an icon. */
@media (max-width: 400px) {
    .confirm-actions .row-ico {
        display: none;
    }
}

/* A grey icon on the white Quit button read as disabled. */
.btn-danger .row-ico,
.btn-ghost .row-ico {
    color: inherit;
}

/* Short landscape: the pause list must fit a 390px-tall phone. */
@media (max-height: 500px) {
    .pause-card {
        padding: 14px 16px;
    }

    .pause-card .dialog-head {
        margin-bottom: 10px;
    }

    .pause-card .dialog-badge {
        width: 32px;
        height: 32px;
    }

    .pause-card .dialog-title {
        font-size: 19px;
    }

    .pause-card .dialog-list {
        gap: 6px;
    }

    .pause-card .btn-row,
    .pause-card .row-static,
    .pause-card .btn-primary.btn-wide {
        min-height: 46px;
    }

    .pause-card .row-static .seg-btn {
        min-height: 36px;
    }
}

/* ------------------------------------------------------------------ */
/* Game over                                                          */
/* ------------------------------------------------------------------ */

.go-card {
    width: min(480px, 100%);
    padding: 26px 22px 18px;
    text-align: center;
    --accent: var(--ink);
}

.go-card::before {
    content: '';
    position: absolute;
    inset: 0 0 auto;
    height: 140px;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    background: radial-gradient(ellipse 60% 100% at 50% 0%, color-mix(in srgb, var(--accent) 22%, transparent), transparent 70%);
    pointer-events: none;
}

.go-card[data-outcome="defeat"]::before {
    background: radial-gradient(ellipse 60% 100% at 50% 0%, rgba(232, 238, 248, .07), transparent 70%);
}

.go-head {
    position: relative;
    display: grid;
    justify-items: center;
    gap: 6px;
}

.go-kicker {
    margin: 0;
    color: var(--ink-3);
    font-size: 12px;
    letter-spacing: .16em;
    text-transform: uppercase;
}

.go-title {
    margin: 0;
    font-size: clamp(34px, 10vw, 46px);
    font-weight: 700;
    line-height: 1.05;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--ink);
}

.go-card[data-outcome="victory"] .go-title {
    color: var(--accent);
    text-shadow: 0 0 34px color-mix(in srgb, var(--accent) 45%, transparent);
}

.go-card[data-outcome="rival"] .go-title {
    font-size: clamp(28px, 8vw, 38px);
}

.go-sub {
    margin: 0;
    color: var(--ink-2);
    font-size: 15px;
    line-height: 1.35;
    text-wrap: balance;
}

.go-rating {
    display: flex;
    gap: 6px;
    margin-top: 6px;
}

.go-star {
    display: grid;
    color: var(--ink-3);
}

.go-star.is-on {
    color: var(--ink);
    filter: drop-shadow(0 0 8px rgba(255, 255, 255, .35));
    animation: star-pop .46s var(--ease-back) both;
    animation-delay: calc(360ms + var(--i) * 140ms);
}

@keyframes star-pop {
    from {
        opacity: 0;
        scale: 0;
    }

    60% {
        opacity: 1;
        scale: 1.3;
    }
}

.go-body {
    display: grid;
    gap: 12px;
    margin-top: 18px;
}

.go-chart-wrap {
    margin: 0;
    padding: 10px 12px 8px;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    background: rgba(4, 6, 13, .5);
}

.go-chart-title {
    margin: 0 0 8px;
    color: var(--ink-2);
    font-size: 11px;
    letter-spacing: .12em;
    text-align: left;
    text-transform: uppercase;
}

.go-chart svg {
    display: block;
    width: 100%;
    height: 92px;
    border-radius: 6px;
}

.go-chart-bg {
    fill: rgba(125, 136, 161, .08);
}

.go-axis {
    display: flex;
    justify-content: space-between;
    margin-top: 5px;
    color: var(--ink-3);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}

.go-legend {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 2px 14px;
    margin: 6px 0 0;
    padding: 0;
    list-style: none;
    color: var(--ink-2);
    font-size: 12px;
}

.go-legend li {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
}

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

.go-stats {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 6px;
    margin: 0;
}

.go-stat {
    min-width: 0;
    padding: 10px 4px 9px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: rgba(255, 255, 255, .025);
}

.go-stat dt {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    color: var(--ink-2);
    font-size: 11px;
    line-height: 1.15;
}

.go-stat-ico {
    display: grid;
    color: var(--ink-3);
}

.go-val {
    margin: 5px 0 0;
    color: var(--ink);
    font-size: 19px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.go-actions {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 10px;
    margin-top: 18px;
}

.go-actions .btn {
    min-height: 56px;
}

.go-actions .go-primary {
    font-size: 17px;
}

/* With 'Try Normal' on offer, the primary takes the full first row and the
   offer shares the second with Menu (wrapping to two lines if it must). */
.go-actions.has-try {
    grid-template-columns: 1fr auto;
}

.go-actions.has-try .go-primary {
    grid-column: 1 / -1;
}

.go-actions .go-try {
    padding: 0 14px;
    font-size: 15px;
    white-space: normal;
    text-align: center;
}

.go-career {
    text-align: center;
    line-height: 1.45;
    margin: 14px 0 0;
    color: var(--ink-3);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
}

.career-part {
    white-space: nowrap;
}

.go-career .ico,
.career .ico {
    display: inline-block;
    margin-right: 6px;
    vertical-align: -3px;
}

@media (max-width: 440px) {
    .go-stats {
        grid-template-columns: repeat(6, 1fr);
    }

    .go-stat {
        grid-column: span 2;
    }

    .go-stat:nth-child(4),
    .go-stat:nth-child(5) {
        grid-column: span 3;
    }

    .go-actions {
        grid-template-columns: 1fr;
    }

    .go-actions .go-menu,
    .go-actions .go-try {
        min-height: 48px;
    }
}

@media (max-height: 700px) and (max-width: 440px) {
    .go-card {
        padding: 18px 16px 14px;
    }

    .go-title {
        font-size: 34px;
    }

    .go-stat-ico {
        display: none;
    }

    .go-stat {
        padding: 8px 4px 7px;
    }

    .go-val {
        margin-top: 3px;
        font-size: 18px;
    }

    .go-actions {
        grid-template-columns: 1fr auto;
    }

    .go-actions .btn,
    .go-actions .go-menu {
        min-height: 52px;
    }

    .go-body {
        margin-top: 12px;
        gap: 8px;
    }

    .go-chart svg {
        height: 64px;
    }

    .go-actions {
        margin-top: 12px;
    }

    .go-career {
        margin-top: 10px;
    }
}

/* Landscape phones: title and actions on the left, the story on the right. */
@media (min-width: 640px) and (max-height: 560px) {
    .go-card {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
        grid-template-rows: auto 1fr auto;
        column-gap: 24px;
        width: min(820px, 100%);
        padding: 18px 20px 14px;
    }

    .go-head {
        grid-column: 1;
        grid-row: 1;
        align-self: end;
    }

    .go-body {
        grid-column: 2;
        grid-row: 1 / span 3;
        margin-top: 0;
        align-self: center;
    }

    .go-actions {
        grid-column: 1;
        grid-row: 2;
        grid-template-columns: 1fr;
        align-self: start;
        gap: 8px;
        margin-top: 14px;
    }

    .go-actions .btn {
        min-height: 48px;
    }

    .go-career {
        grid-column: 1;
        grid-row: 3;
        margin-top: 8px;
    }

    .go-chart svg {
        height: 72px;
    }

    .go-title {
        font-size: 36px;
    }
}

/* ------------------------------------------------------------------ */
/* Reduced motion: keep state changes, drop travel and loops.         */
/* ------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {

    *,
    *::before,
    *::after {
        animation-duration: 1ms !important;
        animation-iteration-count: 1 !important;
        animation-delay: 0ms !important;
        transition-duration: 1ms !important;
        transition-delay: 0ms !important;
        scroll-behavior: auto !important;
    }

    .menu-scrim {
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        background: rgba(4, 6, 13, .7);
    }
}
