/* ─── Live: Voice | Translate mode switch + translate two-pane stage ────────
   Shared base CSS (vars, header, halo, dock, status pill, ctrl-btn, ended
   overlay, reconnect banner, lmsg transcript, PiP, settings sheet) lives in
   the inline <style> of index.html. This file holds only the mode toggle,
   stage visibility, and the translate-specific two-pane layout. */

/* ── Mode toggle (header segmented control) ─────────────────────────────── */
.live-mode-toggle {
    display: inline-flex;
    padding: 3px;
    border-radius: 9999px;
    background: var(--live-surface-dim);
    border: 1px solid var(--live-outline);
}
.live-mode-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 14px;
    border-radius: 9999px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--live-on-surface-variant);
    cursor: pointer;
    border: 1px solid transparent;
    background: transparent;
    transition: all 150ms var(--md-easing-standard);
    white-space: nowrap;
}
.live-mode-btn .material-symbols-outlined { font-size: 16px; }
.live-mode-btn:hover { color: var(--live-on-surface); }
.live-mode-btn[aria-pressed="true"] {
    background: var(--live-accent);
    color: var(--live-on-accent);
}

/* ── Stage visibility ────────────────────────────────────────────────────── */
.live-stage-pane {
    position: relative;
    flex: 1 1 100%;
    min-width: 0;
    min-height: 0;
    display: none;
    flex-direction: column;
}
body[data-live-mode="voice"] #voiceStage { display: flex; }
body[data-live-mode="translate"] #translateStage { display: flex; }
body[data-live-mode="music"] #musicStage { display: flex; }

/* Header controls + voice-only dock affordances are hidden per mode. */
body[data-live-mode="voice"] #translateHeaderControls,
body[data-live-mode="voice"] #musicHeaderControls { display: none; }
body[data-live-mode="translate"] #voiceHeaderControls,
body[data-live-mode="translate"] #musicHeaderControls { display: none; }
/* Music has a single fixed model, so neither the provider/model pair nor the
   translate echo+language pair applies. Without this they both leaked into the
   music header (the mode was added to the two rules above but never given its
   own). */
body[data-live-mode="music"] #voiceHeaderControls,
body[data-live-mode="music"] #translateHeaderControls { display: none; }
body[data-live-mode="translate"] #voiceDockSlot,
body[data-live-mode="translate"] #settingsBtn,
body[data-live-mode="translate"] #cameraBtn,
body[data-live-mode="translate"] #screenBtn,
body[data-live-mode="translate"] #settingsSheet,
body[data-live-mode="music"] #voiceDockSlot,
body[data-live-mode="music"] #settingsBtn,
body[data-live-mode="music"] #cameraBtn,
body[data-live-mode="music"] #screenBtn,
body[data-live-mode="music"] #micBtn,
body[data-live-mode="music"] #settingsSheet { display: none !important; }

/* ── Translate: twin-pane bilingual transcript ──────────────────────────── */
.live-select-wrap--lang { width: 200px; }

.twin-panes {
    flex: 1;
    min-height: 0;
    display: grid;
    grid-template-columns: 1fr 1fr;
}
.pane {
    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    overflow-y: auto;
    padding: 20px max(14px, calc((100% - 36rem) / 2)) 24px;
    gap: 12px;
    overscroll-behavior: contain;
}
.pane--source { border-right: 1px solid var(--live-outline); }
.pane-head {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 8px;
    margin: -20px max(14px, calc((100% - 36rem) / 2)) 4px;
    padding: 14px max(14px, calc((100% - 36rem) / 2)) 6px;
    background: color-mix(in srgb, var(--live-surface-dim) 92%, transparent);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
}
.pane-head .material-symbols-outlined { font-size: 18px; color: var(--live-on-surface-variant); }
.pane-title {
    font-family: "Space Grotesk", system-ui, sans-serif;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--live-on-surface-variant);
}
.pane-lang {
    margin-left: auto;
    font-size: 11px;
    font-weight: 600;
    background: var(--live-accent-container);
    color: var(--live-on-accent-container);
    padding: 2px 9px;
    border-radius: 9999px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.pane-line {
    font-size: 15px;
    line-height: 1.55;
    color: var(--live-on-surface);
    word-break: break-word;
}
.pane--source .pane-line { color: var(--live-on-surface-variant); }
.pane--target .pane-line { color: var(--live-on-surface); font-weight: 500; }
.pane-line--streaming::after {
    content: '';
    display: inline-block;
    width: 7px;
    height: 14px;
    margin-left: 4px;
    vertical-align: text-bottom;
    border-radius: 2px;
    background: var(--live-accent);
    animation: caret-blink 1s steps(2, start) infinite;
}

/* Translate empty state: halo shown while no pane lines exist. The panes
   always hold their sticky .pane-head, so :empty can't detect "no content". */
#translateStage:not([data-has-transcript="true"]) .live-empty { display: flex; }
#translateStage:not([data-has-transcript="true"]) .live-tools { opacity: 0; pointer-events: none; }

/* ── Music mode (Lyria Realtime) ───────────────────────────────────────── */
.music-model-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border-radius: 9999px;
    background: var(--live-accent-container);
    color: var(--live-on-accent-container);
    font-size: 12px;
    font-weight: 500;
}
.music-model-badge .material-symbols-outlined { font-size: 16px; }

.music-stage {
    /* Don't redeclare `display: flex` here — both `.live-stage-pane` and
       `.music-stage` are single-class selectors with equal specificity, so
       whichever comes later wins. Setting `display: flex` here would override
       `.live-stage-pane { display: none }` and make the Lyria UI leak into the
       voice/translate tabs. The body-attribute rule above is more specific
       (`body[data-live-mode="music"] #musicStage`) and only fires in music
       mode, which is exactly what we want. */
    overflow-y: auto;
    padding: 18px max(16px, calc((100% - 46rem) / 2)) 28px;
    gap: 14px;
    flex-direction: column;
    overscroll-behavior: contain;
}
.music-panel {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 14px 16px;
    border-radius: 16px;
    background: var(--live-surface);
    border: 1px solid var(--live-outline);
}
.music-panel-head {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
.music-panel-head .material-symbols-outlined {
    font-size: 18px;
    color: var(--live-on-surface-variant);
}
.music-panel-title {
    font-family: "Space Grotesk", system-ui, sans-serif;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--live-on-surface-variant);
}
.music-panel-hint {
    margin-left: auto;
    font-size: 11.5px;
    color: var(--live-on-surface-variant);
    opacity: 0.85;
}

/* Prompt rows: text input + weight slider + remove button */
.music-prompt-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.music-prompt-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 130px 36px 36px;
    gap: 8px;
    align-items: center;
}
.music-prompt-input,
.music-prompt-weight {
    font-size: 14px;
    border-radius: 10px;
    padding: 8px 10px;
    background: var(--live-surface-dim);
    color: var(--live-on-surface);
    border: 1px solid var(--live-outline);
}
.music-prompt-input:focus,
.music-prompt-weight:focus {
    outline: none;
    border-color: var(--live-accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--live-accent) 18%, transparent);
}
.music-prompt-weight {
    padding: 0;
    height: 36px;
    /* Without this the weight slider renders in the browser's default blue
       while every slider in the config panel is accent-tinted. */
    accent-color: var(--live-accent);
}
.music-prompt-weight-value {
    font-variant-numeric: tabular-nums;
    font-size: 13px;
    color: var(--live-on-surface-variant);
    text-align: center;
}
.music-prompt-remove {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: 1px solid var(--live-outline);
    background: var(--live-surface);
    color: var(--live-on-surface-variant);
    cursor: pointer;
    transition: all 150ms var(--md-easing-standard);
}
.music-prompt-remove:hover { color: var(--live-recording); border-color: var(--live-recording); }
.music-prompt-remove .material-symbols-outlined { font-size: 18px; }

.music-add-prompt-btn {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 14px;
    border-radius: 9999px;
    background: var(--live-accent-container);
    color: var(--live-on-accent-container);
    border: 1px solid color-mix(in srgb, var(--live-accent) 20%, transparent);
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: all 150ms var(--md-easing-standard);
}
.music-add-prompt-btn:hover { background: color-mix(in srgb, var(--live-accent-container) 80%, var(--live-accent)); }
.music-add-prompt-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.music-add-prompt-btn .material-symbols-outlined { font-size: 16px; }

/* Config grid (sliders + scale) */
.music-config-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 10px 18px;
}
/* Label and its readout share the top line; the control spans the full width
   underneath. The scale row has no readout, so its `value` column collapses to
   zero and the select still lines up with the sliders above/below it. */
.music-config-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
        "label value"
        "control control";
    gap: 6px 10px;
    align-items: center;
}
.music-config-label {
    grid-area: label;
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--live-on-surface-variant);
}
.music-config-row input[type="range"] {
    grid-area: control;
    width: 100%;
    accent-color: var(--live-accent);
}
/* initializeCustomSelects() wraps the native <select> in .custom-select-wrapper
   and inserts it as a sibling, so the wrapper is what the grid places. */
.music-config-row .custom-select-wrapper,
.music-config-row select {
    grid-area: control;
    min-width: 0;
}
.music-config-value {
    grid-area: value;
    font-variant-numeric: tabular-nums;
    font-size: 13px;
    color: var(--live-on-surface);
    text-align: right;
}

/* Transport row */
.music-transport-status {
    margin-left: auto;
    font-size: 12px;
    font-weight: 500;
    padding: 4px 10px;
    border-radius: 9999px;
    background: var(--live-surface-dim);
    color: var(--live-on-surface-variant);
    border: 1px solid var(--live-outline);
}
.music-transport {
    display: flex;
    gap: 10px;
    align-items: center;
    flex-wrap: wrap;
}
.music-transport-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    border: 1px solid var(--live-outline);
    background: var(--live-surface);
    color: var(--live-on-surface-variant);
    cursor: pointer;
    transition: all 150ms var(--md-easing-standard);
}
.music-transport-btn:hover:not(:disabled) {
    color: var(--live-accent);
    border-color: var(--live-accent);
}
.music-transport-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.music-transport-btn--active {
    background: var(--live-accent);
    color: var(--live-on-accent);
    border-color: transparent;
}
.music-transport-btn .material-symbols-outlined { font-size: 22px; }
.music-hint {
    font-size: 12.5px;
    color: var(--live-on-surface-variant);
    line-height: 1.55;
    margin: 0;
}

/* Log pane */
.music-log-tools {
    margin-left: auto;
    display: flex;
    gap: 6px;
}
.music-log-pane {
    min-height: 90px;
    max-height: 220px;
    overflow-y: auto;
    padding: 10px 12px;
    border-radius: 12px;
    background: var(--live-surface-dim);
    border: 1px solid var(--live-outline);
    font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
    font-size: 12.5px;
    line-height: 1.55;
}
.music-log-line--err { color: var(--live-recording); }
.music-log-line--sys { color: var(--live-on-surface-variant); }

/* Music empty state. `.live-empty` is `position: absolute; inset: 0` — that is
   right for voice/translate (one scrolling transcript, empty until it isn't)
   but wrong here: the music stage always renders prompt/config/transport
   panels, so an inset-0 overlay parks the halo over the transport hint and the
   headline over the log. Flatten it back into normal flow and let it stand in
   for the log pane while there are no lines. */
.music-empty {
    position: static;
    inset: auto;
    padding: 16px 12px 20px;
    gap: 12px;
}
.music-empty .live-halo { width: 64px; height: 64px; }
.music-empty h2 { font-size: 1.05rem; }
.music-empty p { font-size: 12.5px; max-width: 44ch; }

#musicStage:not([data-has-log="true"]) .music-empty { display: flex; }
#musicStage:not([data-has-log="true"]) #musicLogPane { display: none; }
#musicStage:not([data-has-log="true"]) .music-log-tools { opacity: 0; pointer-events: none; }

/* ── Echo toggle (translate header affordance) ──────────────────────────── */
.echo-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border-radius: 9999px;
    border: 1px solid var(--live-outline);
    background: var(--live-surface);
    color: var(--live-on-surface-variant);
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    transition: all 150ms var(--md-easing-standard);
}
.echo-toggle .material-symbols-outlined { font-size: 16px; }
.echo-toggle[aria-pressed="true"] {
    background: var(--live-accent-container);
    color: var(--live-on-accent-container);
    border-color: color-mix(in srgb, var(--live-accent) 25%, transparent);
}

@media (prefers-reduced-motion: reduce) {
    .pane-line--streaming::after { animation: none !important; }
}

/* ═══ Responsive layer ══════════════════════════════════════════════════════
   This file is linked after index.html's inline <style>, so equal-specificity
   rules below win — base values declared inline are deliberately re-declared
   here when they only exist to serve a layout. Breakpoints:

     ≤ 1024px  transcript clears the floating tool cluster
     ≤ 820px   header stacks: brand + mode toggle, selects on their own row
     ≤ 900px   dock select narrows
     ≤ 640px   dock stacks; twin panes become rows; PiP shrinks
     ≤ 480px   primary call button takes a full-width row
     short landscape  everything compresses back into one dock row
     pointer: coarse  touch-target floors
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Header ─────────────────────────────────────────────────────────────── */
.live-header {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    column-gap: 10px;
    row-gap: 8px;
    min-height: 3.5rem;
    padding: calc(6px + env(safe-area-inset-top))
             max(12px, env(safe-area-inset-right)) 6px
             max(12px, env(safe-area-inset-left));
}
@media (min-width: 768px) {
    .live-header {
        padding-right: max(16px, env(safe-area-inset-right));
        padding-left: max(16px, env(safe-area-inset-left));
    }
}
.live-header-brand { flex: 1 1 auto; min-width: 0; }
.live-header-actions { display: contents; }
.live-mode-toggle { flex: none; }

@media (max-width: 820px) {
    .live-header-brand { order: 1; }
    .live-mode-toggle { order: 2; }
    /* Full-width select row. The custom-select menu is sized from its trigger
       (js/shared/ui-utils.js), so widening the trigger also widens the menu —
       which is what makes the two-line options readable on a phone. */
    #voiceHeaderControls,
    #translateHeaderControls { flex: 1 1 100%; order: 3; min-width: 0; }
    /* The music badge needs the same ordering or it defaults to order 0 and
       renders *before* the back arrow and title. It's a fixed-width badge, not
       a control cluster, so it stays flex:none and wraps on its own. */
    #musicHeaderControls { flex: none; order: 3; }
    .live-select-wrap--model,
    .live-select-wrap--lang { width: auto; }
    #voiceHeaderControls .live-select-wrap { flex: 1 1 0; min-width: 0; }
    #voiceHeaderControls .live-select-wrap--model { flex-grow: 1.7; }
    #translateHeaderControls .live-select-wrap--lang { flex: 1 1 auto; min-width: 0; }
    #echoToggle { flex: none; }
}

/* ── Stage: keep content clear of the floating tool cluster ─────────────── */
.live-halo { width: clamp(88px, 22vw, 128px); height: clamp(88px, 22vw, 128px); }

/* Voice tools sit top-right; the transcript column only clears them once the
   viewport is wide enough to push the column inward (46rem + 2×134px). */
@media (max-width: 1024px) {
    #transcript { padding-top: 52px; }
}
/* Translate has no PiP, so its tools drop to the bottom-right instead — that
   avoids the sticky .pane-head lang badge at every width. */
#translateStage .live-tools { top: auto; bottom: 14px; }
.pane--target { padding-bottom: 60px; }

/* ── Dock ───────────────────────────────────────────────────────────────── */
.live-dock {
    padding-right: max(12px, env(safe-area-inset-right));
    padding-left: max(12px, env(safe-area-inset-left));
}
/* Without this the controls row overflows the dock as soon as the voice select
   appears (it mounts only once a session connects). */
.live-dock-controls { flex-wrap: wrap; justify-content: flex-end; }

@media (max-width: 900px) {
    .live-select-wrap--voice { width: 180px; }
}

@media (max-width: 640px) {
    .live-dock { flex-direction: column; align-items: stretch; gap: 10px; }
    .live-dock-status { justify-content: center; }
    .live-dock-controls { width: 100%; margin: 0; justify-content: center; gap: 8px; }
    #voiceDockSlot { order: -1; flex: 1 0 100%; justify-content: center; }
    #voiceDockSlot .live-select-wrap--voice { flex: 1 1 auto; width: auto; min-width: 0; }
    .live-round-btn { width: 46px; height: 46px; }
    .live-round-btn--mic { width: 56px; height: 56px; }
    .live-round-btn--mic .material-symbols-outlined { font-size: 24px; }
    #connectBtn.live-ctrl-btn--primary { padding: 12px 20px; font-size: 14px; }

    #transcript { padding-right: 14px; padding-left: 14px; padding-bottom: 20px; }
    .lmsg { max-width: 88%; }
    .live-tools { top: 10px; right: 10px; gap: 5px; }
    #translateStage .live-tools { top: auto; bottom: 10px; }
    .live-pip { right: 10px; bottom: 10px; }
    .live-pip-tile { width: clamp(112px, 32vw, 160px); }

    .twin-panes { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; }
    .pane--source { border-right: none; border-bottom: 1px solid var(--live-outline); }
    .pane { padding: 16px 14px 20px; }
    /* Negative side margins let the blurred sticky head bleed to the pane edge
       while its content stays aligned with the lines below it. */
    .pane-head { margin: -16px -14px 4px; padding: 12px 14px 6px; }
    .pane--target { padding-bottom: 56px; }

    .live-sheet-inner { padding: 12px 14px 14px; }

    /* Four columns leave ~110px for the prompt text on a phone. Drop the weight
       slider onto its own line so the text input gets the full width. */
    .music-prompt-row {
        grid-template-columns: minmax(0, 1fr) auto;
        grid-template-areas:
            "text   remove"
            "weight value";
        gap: 8px 10px;
    }
    .music-prompt-input { grid-area: text; }
    .music-prompt-remove { grid-area: remove; }
    .music-prompt-weight { grid-area: weight; }
    .music-prompt-weight-value { grid-area: value; text-align: right; }

    .music-stage { padding-left: 14px; padding-right: 14px; }
    .music-panel { padding: 12px 14px; }
}

@media (max-width: 480px) {
    .live-dock-controls { gap: 6px; }
    /* Primary action earns its own full-width row rather than being squeezed. */
    #connectBtn { flex: 1 0 100%; }
    #connectBtn.live-ctrl-btn--primary { padding: 13px 20px; }
}

/* ── Short landscape (phone on its side): height is the scarce axis ─────── */
@media (max-height: 520px) and (orientation: landscape) {
    .live-header { min-height: 3rem; }
    .live-empty { gap: 10px; padding: 12px; }
    .live-halo { width: 64px; height: 64px; }
    .live-empty h2 { font-size: 1.05rem; }
    .live-empty p { display: none; }

    .live-dock { flex-direction: row; align-items: center; gap: 8px; padding-top: 6px; }
    .live-dock-controls { width: auto; margin-left: auto; justify-content: flex-end; }
    #voiceDockSlot { order: 0; flex: 0 1 auto; }
    #connectBtn { flex: 0 1 auto; }
    .live-round-btn { width: 42px; height: 42px; }
    .live-round-btn--mic { width: 50px; height: 50px; }
    #connectBtn.live-ctrl-btn--primary { padding: 10px 18px; }

    /* Side-by-side beats stacked when there are only ~200px of pane height. */
    .twin-panes { grid-template-columns: 1fr 1fr; grid-template-rows: 1fr; }
    .pane--source { border-right: 1px solid var(--live-outline); border-bottom: none; }

    .live-pip { flex-direction: row; }
    .live-pip-tile { width: clamp(96px, 18vw, 140px); }
}

/* ── Touch targets ──────────────────────────────────────────────────────── */
@media (pointer: coarse) {
    .live-mode-btn { min-height: 40px; padding-left: 16px; padding-right: 16px; }
    .echo-toggle { min-height: 40px; }
    .live-tool-btn, .live-voice-preview { width: 42px; height: 42px; }
    /* 16px is the threshold below which iOS Safari zooms on focus. */
    .live-sheet textarea { font-size: 16px; }
}