/**
 * The recording screen.
 *
 * 📐 Canonical doc: docs/features/media-capture.md W5
 *
 * ⛔ **FIXED DARK IN BOTH THEMES, THE WAY A VIEWFINDER IS.** Every colour here
 * comes from the palette's fixed base steps (`--ink-1`, `--paper-0`,
 * `--sage-*`) rather than the semantic tokens, because those are remapped per
 * theme and this surface must not follow. A recording screen that turns pale in
 * light mode is a different screen, not the same one lit differently.
 *
 * ⭐ **IT HOLDS THE WAVEFORM AND THE TIMER AND NOTHING ELSE**, which is W5's own
 * argument: "so speaking does not feel like filling in a form". Anything added
 * here should have to justify itself against that sentence.
 */

.voice-recorder {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    flex-direction: column;
    background: var(--ink-1);
    color: var(--paper-0);
    /* Below the OS status bar and above the home indicator in both shells. */
    padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);
}

.voice-recorder[hidden] {
    display: none;
}

/* ⚠️ The composer underneath must not scroll while this is open — on iOS a
   fixed overlay does not stop the page behind it moving under a drag. */
body.is-recording {
    overflow: hidden;
}

.voice-recorder__top {
    flex-shrink: 0;
    display: flex;
    justify-content: flex-end;
    padding: var(--space-lg);
}

.voice-recorder__cancel {
    background: none;
    border: none;
    padding: var(--space-2xs) var(--space-sm);
    font-size: 0.9375rem;
    font-family: inherit;
    color: var(--sage-300);
    cursor: pointer;
}

.voice-recorder__stage {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-2xl);
    padding: 0 var(--space-2xl);
    text-align: center;
}

.voice-recorder__state {
    margin: 0;
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--accent);
}

/* ⭐ Large, light and quiet. It is the one number she glances at, and a heavy
   weight here would read as a stopwatch rather than a companion. */
.voice-recorder__timer {
    margin: 0;
    font-family: var(--font-heading);
    font-size: 3.25rem;
    font-weight: 300;
    letter-spacing: -0.02em;
    line-height: 1;
    color: var(--paper-0);
    /* Stops the layout jitter every digit change would otherwise cause. */
    font-variant-numeric: tabular-nums;
}

/* ── The waveform ────────────────────────────────────────────────────────────
 * Bars are sized in JS from the real input level, so the only thing this needs
 * to answer is "is it hearing me". The gradient across the row is decoration:
 * dim at the edges, bright in the middle, so the shape reads as one object.
 */
.voice-recorder__wave {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 3px;
    height: 80px;
    width: 100%;
}

.voice-recorder__wave span {
    width: 3px;
    height: 14px;
    border-radius: 2px;
    background: var(--sage-deep);
    transition: height var(--duration-quick) var(--ease-out);
}

.voice-recorder__wave span:nth-child(n + 4) { background: var(--primary); }
.voice-recorder__wave span:nth-child(n + 6) { background: var(--sage-400); }
.voice-recorder__wave span:nth-child(n + 8) { background: var(--sage-300); }
.voice-recorder__wave span:nth-child(n + 12) { background: var(--sage-400); }
.voice-recorder__wave span:nth-child(n + 14) { background: var(--primary); }
.voice-recorder__wave span:nth-child(n + 16) { background: var(--sage-deep); }

/* ⚠️ Someone who has asked for less motion still needs to see it is listening,
   so the bars keep changing height -- they just stop animating between values. */
@media (prefers-reduced-motion: reduce) {
    .voice-recorder__wave span {
        transition: none;
    }
}

.voice-recorder__copy {
    margin: 0;
    max-width: 280px;
    font-family: var(--font-serif);
    font-style: italic;
    font-size: 1.0625rem;
    line-height: 1.6;
    color: var(--sage-300);
}

/* ⚠️ Quieter than the copy above it and still present: a disclosure she has to
   squint at is a disclosure that was not made. Sits below the invitation so the
   first thing she reads is the reassurance, not the paperwork. */
.voice-recorder__disclosure {
    margin: 0;
    max-width: 300px;
    font-size: 0.8125rem;
    line-height: 1.5;
    color: var(--sage-400);
}

.voice-recorder__problem {
    margin: 0;
    max-width: 320px;
    font-size: 0.9375rem;
    line-height: 1.5;
    color: var(--terra-300);
}

.voice-recorder__problem[hidden] {
    display: none;
}

/* ── The controls ───────────────────────────────────────────────────────── */
.voice-recorder__controls {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 var(--space-2xl) var(--space-2xl);
}

/* ⛔ **THE NATIVE TAB BAR IS PAINTED OVER THIS OVERLAY, AND NO `z-index` CAN
   REACH IT.** The recorder is `position: fixed; inset: 0; z-index: 1000`, which
   is enough to cover the WEB bottom nav — but the shells' tab bar is a UIKit /
   Android view outside the document, so it sits on top of everything the page
   can draw. Gabriel, 2026-09-10, from an iPad: *"the recording button is
   covered by the menu on the bottom."* Stop is the only way to keep a
   recording, so this was the whole feature, unreachable.

   ⚠️ **`env(safe-area-inset-bottom)` ON THE CONTAINER WAS NOT ENOUGH AND NEVER
   COULD BE** — that inset is the home indicator, and it knows nothing about a
   tab bar. Both are needed, which is what `--bottom-bar` is for.

   ⚠️ **BOTH SHELLS, NOT ONLY iOS.** iOS overlays for certain (measured from
   Gabriel's screenshot). On Android the tab bar is a `BottomNavigationView`
   outside the WebView, so the clearance is probably redundant there — but the
   cost of being wrong is a stop button a little higher up, against a stop
   button that cannot be pressed. Redundant padding is the safe direction. */
[data-native-shell] .voice-recorder__controls {
    padding-bottom: calc(var(--bottom-bar) + var(--space-2xl));
}

.voice-recorder__side {
    width: 52px;
    height: 52px;
    border-radius: 50%;
    border: var(--border-width) solid rgba(231, 234, 224, 0.2);
    background: none;
    color: var(--sage-300);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.voice-recorder__side--empty {
    border-color: transparent;
    pointer-events: none;
}

/* ⭐ The biggest thing on the screen, because it is the only one she is
   looking for while she is talking. */
.voice-recorder__stop {
    width: 76px;
    height: 76px;
    border: none;
    border-radius: 50%;
    background: var(--sage-300);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.voice-recorder__stop-mark {
    width: 26px;
    height: 26px;
    border-radius: 6px;
    background: var(--ink-0);
    display: block;
}

/* ⭐ **RETRY STANDS WHERE STOP STOOD**, because by the time it appears stop is
   inert and the eye is already on that spot. It carries words rather than a
   glyph: a circular arrow beside a failure message asks her to guess whether it
   re-records or re-sends, and those are very different things to a person who
   has just spoken for three minutes.
   ⚠️ Wider than stop and not a circle — a 76px round button cannot hold a
   label at a readable size, and shrinking the text to fit is how a control
   nobody can read gets shipped. 📐 media-stress-readiness.md R2, H14/H10. */
.voice-recorder__retry {
    width: auto;
    height: 56px;
    padding: 0 26px;
    border-radius: 28px;
    font-family: inherit;
    font-size: 1rem;
    font-weight: 600;
    color: var(--ink-0);
    letter-spacing: -0.01em;
}

/* ⛔ **`hidden` DOES NOTHING TO EITHER OF THESE WITHOUT THIS RULE, AND THE
   BROWSER TEST IS WHAT FOUND IT.** The UA stylesheet's `[hidden] { display:
   none }` is a plain element-level default, so ANY explicit `display` in a
   class rule beats it — and both controls declare `display: inline-flex`. The
   markup said `hidden`, the DOM said `hidden`, and Chromium rendered the button
   anyway: retry sat on screen through every recording, and stop stayed beside
   it in the failed state. ⚠️ Exactly the trap `onboarding-tour.css` already
   carries a note about; a second component walked into it. */
.voice-recorder__stop[hidden],
.voice-recorder__retry[hidden] {
    display: none;
}

.voice-recorder__cancel:focus-visible,
.voice-recorder__side:focus-visible,
.voice-recorder__stop:focus-visible {
    outline: var(--border-width-md) solid var(--paper-0);
    outline-offset: 3px;
}
