/* REGISTERED, so the script can read a length rather than a token.
   `getComputedStyle(el).getPropertyValue('--x')` returns the SPECIFIED value of
   an unregistered custom property — for this one, the literal string
   "clamp(14px, 1.25vmin, 24px)". `Number.parseFloat` of that is NaN, so
   `thumbWidthPx()` fell through to its 18px default and the "one source of
   truth" it was written to establish never actually read this value: at a phone
   page box the real thumb is 14px and at 4K it is 24px, and the press-to-value
   mapping was computed from 18 in both. Registering it makes the computed value
   an absolute length, which is what `getPropertyValue` then returns. */
@property --mf-audio-slider-thumb {
    syntax: '<length>';
    inherits: true;
    initial-value: 18px;
}

/* ==========================================================================
   Audio settings control — a compact glass trigger that opens a popover with
   two fully independent channels (Music + Sound Effects). Each channel has a
   labeled slider whose value IS the actual playback level, plus a discoverable
   per-channel mute. The container id is reused by lobby.css / tutorial.css and
   by the in-game JS positioner (UI.AudioSettings.reposition).
   ========================================================================== */

/* Default resting position: top-right, aligned with the Moon Foundry tab bar
   so it sits identically across lobby and foundry. In-game placement is driven
   by JS (centered under the End Turn button). */
#audio-volume-control {
    position: fixed;
    top: var(--mf-rail-top);
    /* One slot inboard of the outer edge, leaving the corner to the
       full-screen trigger; the slot collapses to 0 where that control cannot
       exist, and this returns to the corner. */
    right: calc(var(--mf-rail-edge) + var(--mf-rail-fullscreen-slot));
    z-index: 1000;

    color: #eedbf1;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    pointer-events: auto;
}

/* Keep the visible in-game audio control above the mulligan veil. Tutorial
   messages intentionally rise above it so their text is never obscured. */
body.game-active #audio-volume-control {
    z-index: 10002;
}

/* --- Compact trigger --- */
.audio-settings-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--mf-rail-btn);
    height: var(--mf-rail-btn);
    padding: 0;
    margin: 0;
    border-radius: 999px;
    border: 1px solid rgba(238, 219, 241, 0.4);
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
    color: inherit;
    cursor: pointer;
    transition: transform 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}

.audio-settings-toggle:hover {
    background: rgba(0, 0, 0, 0.7);
    border-color: rgba(238, 219, 241, 0.7);
    transform: scale(1.05);
}

.audio-settings-toggle:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(238, 219, 241, 0.45);
}

.audio-settings-glyph {
    font-size: clamp(1rem, 1.55vmin, 1.95rem);
    line-height: 1;
    -webkit-user-select: none;
    user-select: none;
}

/* --- Popover panel --- */
.audio-settings-panel {
    position: absolute;
    /* Horizontal position is set by JS (positionPanel): the panel centers on the
       trigger and clamps within the viewport. */
    width: clamp(224px, 26vmin, 340px);
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    gap: clamp(0.65rem, 1vmin, 1.1rem);
    padding: clamp(0.85rem, 1.3vmin, 1.5rem);

    background: rgba(14, 8, 20, 0.86);
    border: 1px solid rgba(238, 219, 241, 0.35);
    border-radius: clamp(12px, 1.1vmin, 18px);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    box-shadow: 0 12px 34px rgba(0, 0, 0, 0.55);

    animation: audio-panel-in 0.14s ease;
}

/* A short landscape battle has enough vertical room for one channel row, not
   two stacked rows. Keep the popover above the shared command stack. */
body.game-active .audio-settings-panel {
    width: min(430px, calc(100vw - 16px));
    flex-direction: row;
    align-items: stretch;
    gap: 8px;
    padding: 5px 8px;
}

body.game-active .audio-channel-row {
    flex: 1 1 0;
    min-width: 0;
}

.audio-settings-panel[hidden] {
    display: none;
}

.audio-settings-panel--below {
    top: calc(100% + clamp(0.35rem, 0.7vmin, 0.7rem));
    bottom: auto;
}

.audio-settings-panel--above {
    bottom: calc(100% + clamp(0.35rem, 0.7vmin, 0.7rem));
    top: auto;
}

@keyframes audio-panel-in {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    .audio-settings-panel {
        animation: none;
    }
}

/* --- One channel row: [mute] [label + slider] [percent] --- */
.audio-channel-row {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    column-gap: clamp(0.5rem, 0.8vmin, 0.9rem);
}

.audio-channel-main {
    display: flex;
    flex-direction: column;
    gap: clamp(0.2rem, 0.4vmin, 0.4rem);
    min-width: 0;
}

.audio-channel-label {
    font-size: clamp(0.72rem, 1.05vmin, 1.05rem);
    font-weight: 600;
    letter-spacing: 0.01em;
    color: rgba(238, 219, 241, 0.92);
    cursor: pointer;
    -webkit-user-select: none;
    user-select: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.audio-channel-pct {
    font-size: clamp(0.68rem, 1vmin, 1rem);
    font-variant-numeric: tabular-nums;
    color: rgba(238, 219, 241, 0.7);
    min-width: 3ch;
    text-align: right;
    -webkit-user-select: none;
    user-select: none;
}

.audio-channel-row--muted .audio-slider,
.audio-channel-row--muted .audio-channel-pct,
.audio-channel-row--muted .audio-channel-label {
    opacity: 0.45;
}

/* --- Per-channel mute button --- */
.audio-mute-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: clamp(28px, 2.4vmin, 44px);
    height: clamp(28px, 2.4vmin, 44px);
    padding: 0;
    margin: 0;
    border-radius: 50%;
    border: 1px solid transparent;
    background: rgba(238, 219, 241, 0.08);
    color: inherit;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
}

.audio-mute-btn:hover {
    background: rgba(238, 219, 241, 0.18);
}

.audio-mute-btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(238, 219, 241, 0.45);
}

.audio-mute-btn[aria-pressed="true"] {
    border-color: rgba(238, 219, 241, 0.3);
}

.audio-mute-glyph {
    font-size: clamp(0.85rem, 1.25vmin, 1.5rem);
    line-height: 1;
    -webkit-user-select: none;
    user-select: none;
}

/* --- Slider (value == playback level) --- */
.audio-slider {
    /* ONE SOURCE OF TRUTH FOR THE THUMB. `audio-settings.js` drives the value
       from the pointer (a track tap seeks; iOS WebKit's native slider does not),
       and the usable travel is the track MINUS one thumb — so the script reads
       this instead of re-typing the size. */
    --mf-audio-slider-thumb: clamp(14px, 1.25vmin, 24px);
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: clamp(5px, 0.46vmin, 9px);
    background: transparent;
    border-radius: 999px;
    outline: none;
    cursor: pointer;
    margin: 0;
    /* The INK is 5-9px; the HIT AREA must not be. With appearance:none the
       input's box is exactly its height, so a tap that missed the hairline
       by 3px did nothing — "it only works by dragging the dot". Vertical
       padding is pure hit area (content-box keeps the drawn track at its
       ink height), so tapping anywhere on the strip sets the value there,
       exactly like the native control everywhere else. */
    padding: 10px 0;
    box-sizing: content-box;
    /* The seek gesture is ours end to end, so the browser must not also try to
       pan or scroll with it — without this a touch drag along the bar is taken
       over by the page and arrives as `pointercancel`. */
    touch-action: none;
}

.audio-slider:focus-visible {
    box-shadow: 0 0 0 3px rgba(238, 219, 241, 0.45);
    border-radius: 999px;
}

.audio-slider::-webkit-slider-runnable-track {
    height: clamp(5px, 0.46vmin, 9px);
    background: rgba(238, 219, 241, 0.22);
    border-radius: 999px;
    border: none;
}

.audio-slider::-moz-range-track {
    height: clamp(5px, 0.46vmin, 9px);
    background: rgba(238, 219, 241, 0.22);
    border-radius: 999px;
    border: none;
}

.audio-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: var(--mf-audio-slider-thumb);
    height: var(--mf-audio-slider-thumb);
    border-radius: 50%;
    background: #eedbf1;
    border: 1px solid rgba(238, 219, 241, 0.85);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
    margin-top: clamp(-8px, -0.4vmin, -4px);
    cursor: pointer;
    transition: transform 0.15s ease, background 0.15s ease;
}

.audio-slider::-moz-range-thumb {
    width: var(--mf-audio-slider-thumb);
    height: var(--mf-audio-slider-thumb);
    border-radius: 50%;
    background: #eedbf1;
    border: 1px solid rgba(238, 219, 241, 0.85);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
    cursor: pointer;
    transition: transform 0.15s ease, background 0.15s ease;
}

.audio-slider:hover::-webkit-slider-thumb,
.audio-slider:active::-webkit-slider-thumb {
    transform: scale(1.18);
    background: #fff5fa;
}

.audio-slider:hover::-moz-range-thumb,
.audio-slider:active::-moz-range-thumb {
    transform: scale(1.18);
    background: #fff5fa;
}

/* NO IN-GAME FADE. The trigger used to drop to `opacity: 0.4` during a match
   and inside the Foundry so it would "stay out of the way".

   That made sense when the corner held four buttons; it does not now. This is
   the only chrome on the screen, the owner asked for it to look the same in the
   lobby and in a match, and a control at 40% opacity in a corner is a control a
   player has to hunt for. It is one small disc — it is already out of the way.
   (The Foundry does not paint it at all any more, so that half was dead too.) */

/* Keep the desktop popover visually compact while giving mobile viewports and
   touch hardware a full-size box around mute and the native range control. */
@media (hover: none), (pointer: coarse),
       (orientation: portrait) and (max-width: 768px),
       (orientation: landscape) and (max-height: 560px) {
    .audio-mute-btn {
        min-width: 44px;
        min-height: 44px;
        touch-action: manipulation;
    }

    .audio-slider {
        min-height: 44px;
        /* NOT `manipulation`: that still permits panning, so the browser claims
           the horizontal drag as a page gesture and hands the range input only
           taps — the slider jumps to wherever you poke it and cannot be dragged.
           A horizontal range owns its own drag, so the page must not compete
           for it. `none` is what makes the thumb followable. */
        touch-action: none;
    }
}

/* Narrow lobby chrome: stack below the language selector before the fixed
   account row can collide with the control. The in-page Foundry surface keeps
   the deliberate tab-bar-aligned base placement. */
@media (max-width: 1100px) {
    body:not(.foundry-surface-active) {
        --mf-rail-top: 3rem;
        --mf-rail-edge: 1rem;
    }

    body:not(.foundry-surface-active) .audio-settings-panel {
        width: min(80vw, 300px);
    }
}

@media (max-width: 480px) {
    body:not(.foundry-surface-active) {
        --mf-rail-top: 5.5rem;
    }
}

/* The art chooser owns the screen while it is open, and a floating volume
   puck over a modal that is asking the player to pick an appearance reads as a
   stray control rather than chrome. Scope it out of that ONE surface — the rest
   of Moon Fuse/Foundry keeps its audio control.

   `:has()` rather than a body class so the rule cannot drift out of sync with
   the modal's own open/close state; it is supported across every browser
   Moonfall targets (Safari 16.4+ is the floor). */
body:has(#discovery-modal:not(.hidden) #art-options:not(.hidden)) #audio-volume-control {
    display: none;
}

/* Autoplay blocked notice */
.autoplay-notice {
    position: fixed;
    bottom: 20px;
    left: 70px;
    background: rgba(0, 0, 0, 0.7);
    color: #eedbf1;
    border: 1px solid rgba(238, 219, 241, 0.5);
    border-radius: 8px;
    padding: 15px;
    z-index: 1000;
    max-width: 300px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);
}

.autoplay-notice p {
    margin-bottom: 10px;
}

.autoplay-notice button {
    background: rgba(238, 219, 241, 0.3);
    color: #eedbf1;
    border: 1px solid rgba(238, 219, 241, 0.5);
    padding: 5px 10px;
    border-radius: 4px;
    cursor: pointer;
}

.autoplay-notice button:hover {
    background: rgba(238, 219, 241, 0.5);
}
