/* ============================================
   FHM Audio Player
   ============================================

   The custom .cp player, its mini-player, and the two legacy wrappers that
   still use it. Originally extracted from sie-chapter.css so that editorial
   pages could load the player without inheriting 33 KB of chapter furniture,
   including the bare h2/p element selectors that were overpainting the
   Ledger Band.

   This is the ONLY copy. The duplicate in sie-chapter.css has been deleted and
   the 58 chapter pages now load this file alongside it. All 89 pages with a
   player read their styles from here.

   Load it with assets/js/audio-player.js, which builds the .cp DOM. Any new
   stylesheet also needs adding to TRACKED_ASSETS in scripts/cache-bust.js.
   ============================================ */

/* ============================================
   Audio Player Component
   ============================================ */
.audio-player {
    background: var(--fh-surface-inverse);
    border-radius: 8px;
    padding: var(--fh-space-lg);
    margin: var(--fh-space-xl) 0;
    box-shadow: 0 4px 12px color-mix(in srgb, var(--fh-accent-ink) 15%, transparent);
}

.audio-player__header {
    display: flex;
    align-items: center;
    gap: var(--fh-space-md);
    margin-bottom: var(--fh-space-md);
}

.audio-player__icon {
    width: 48px;
    height: 48px;
    background: rgba(255, 255, 255, 0.15);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.audio-player__icon svg {
    width: 24px;
    height: 24px;
    fill: var(--fh-on-inverse);
}

.audio-player__meta {
    flex: 1;
    min-width: 0;
}

.audio-player__label {
    font-family: var(--fh-font-mono);
    font-size: 0.75rem;
    font-weight: 600;
    color: color-mix(in srgb, var(--fh-on-inverse) 70%, transparent);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    margin-bottom: var(--fh-space-xs);
}

.audio-player__title {
    font-family: var(--fh-font-display);
    font-size: 1.125rem;
    font-weight: 500;
    color: var(--fh-on-inverse);
    margin: 0;
    line-height: 1.3;
}

.audio-player__duration {
    font-family: var(--fh-font-mono);
    font-size: 0.875rem;
    color: color-mix(in srgb, var(--fh-on-inverse) 60%, transparent);
    margin-top: var(--fh-space-xs);
}

.audio-player__controls {
    width: 100%;
}

/* Native controls visible as fallback; JS removes [controls] attr when custom player initializes */
.audio-player__controls audio[controls] {
    width: 100%;
    height: 44px;
    border-radius: 4px;
}

.audio-player__controls audio:not([controls]) {
    height: 0;
    display: none;
}

.audio-player__description {
    font-size: 0.875rem;
    color: color-mix(in srgb, var(--fh-on-inverse) 80%, transparent);
    margin-top: var(--fh-space-md);
    line-height: 1.6;
}

.audio-player__description a {
    color: color-mix(in srgb, var(--fh-on-inverse) 90%, transparent);
    text-decoration: underline;
}

/* ============================================
   Custom Audio Player (.cp)
   ============================================ */
.cp {
    width: 100%;
    user-select: none;
    -webkit-user-select: none;
    /* Establish a query container so the control layout responds to the
       player's OWN width, not the viewport. This is what lets the same player
       look right whether it's in a wide editorial column or a narrow card. */
    container-type: inline-size;

    /* ── Tokens — accent + glow derived from the brand green (D-011) ── */
    --cp-accent: var(--fh-accent);
    --cp-accent-soft: color-mix(in srgb, var(--fh-accent) 18%, transparent);
    --cp-fill-glow: color-mix(in srgb, var(--fh-accent) 45%, transparent);
    --cp-track-bg: rgba(255, 255, 255, 0.12);
    --cp-buffer-bg: rgba(255, 255, 255, 0.26);
    --cp-controls-color: rgba(255, 255, 255, 0.65);
    --cp-controls-hover: rgba(255, 255, 255, 0.92);
    --cp-time-color: rgba(255, 255, 255, 0.48);
    --cp-seg-border: rgba(255, 255, 255, 0.14);
    --cp-seg-divider: rgba(255, 255, 255, 0.12);
}

/* ── Zone 1: full-width scrub area ── */
.cp__progress-wrap {
    width: 100%;
    margin-bottom: 0.5rem;
}

/* Hit area — 28px desktop so the bar is easy to grab */
.cp__progress-bar {
    position: relative;
    width: 100%;
    height: 28px;
    cursor: pointer;
    touch-action: none;
    display: flex;
    align-items: center;
}

.cp__progress-bar:focus-visible {
    outline: 2px solid var(--cp-accent);
    outline-offset: 2px;
    border-radius: 3px;
}

/* Track — 6px rest, swells to 10px on interaction */
.cp__track {
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    height: 6px;
    background: var(--cp-track-bg);
    border-radius: 5px;
    transition: height 0.12s ease-out;
    pointer-events: none;
}

.cp__buffered {
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    height: 6px;
    background: var(--cp-buffer-bg);
    border-radius: 5px;
    width: 0;
    pointer-events: none;
    transition: height 0.12s ease-out, width 0.3s ease;
}

.cp__fill {
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    height: 6px;
    background: var(--cp-accent);
    border-radius: 5px;
    width: 0;
    pointer-events: none;
    transition: width 0.05s linear, height 0.12s ease-out, box-shadow 0.15s ease-out;
}

/* Swell on hover / focus / active */
.cp__progress-bar:hover .cp__track,
.cp__progress-bar:focus-visible .cp__track,
.cp__progress-bar:active .cp__track,
.cp__progress-bar:hover .cp__buffered,
.cp__progress-bar:focus-visible .cp__buffered,
.cp__progress-bar:active .cp__buffered,
.cp__progress-bar:hover .cp__fill,
.cp__progress-bar:focus-visible .cp__fill,
.cp__progress-bar:active .cp__fill {
    height: 10px;
}

/* Drag glow on active */
.cp__progress-bar:active .cp__fill {
    box-shadow: 0 0 8px var(--cp-fill-glow);
}

/* Handle — always visible (10px rest, 16px hover), white ring */
.cp__handle {
    position: absolute;
    top: 50%;
    left: 0;
    width: 10px;
    height: 10px;
    background: var(--cp-accent);
    border-radius: 50%;
    transform: translate(-50%, -50%);
    pointer-events: none;
    transition: width 0.12s ease-out, height 0.12s ease-out;
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9), 0 1px 4px rgba(0, 0, 0, 0.4);
}

.cp__progress-bar:hover .cp__handle,
.cp__progress-bar:focus-visible .cp__handle,
.cp__progress-bar:active .cp__handle {
    width: 16px;
    height: 16px;
}

/* Split time — current left, total right */
.cp__time {
    display: flex;
    justify-content: space-between;
    font-family: var(--fh-font-mono, 'IBM Plex Mono', monospace);
    font-size: 0.72rem;
    color: var(--cp-time-color);
    font-variant-numeric: tabular-nums;
    margin-top: 0.3rem;
}

.cp__current,
.cp__total {
    font-variant-numeric: tabular-nums;
}

.cp__sep {
    /* hidden — time split to corners, no separator needed */
    display: none;
}

/* ── Zone 2: transport row ── */
/* Default (narrow containers, e.g. audio-library cards): stack — transport
   centered, speed segments centered on their own row below. The wide
   pinned-right layout is opted into via @container below. */
.cp__controls {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    margin-top: 0.65rem;
}

.cp__transport {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.25rem;
}

/* ── Buttons — base ── */
.cp__btn {
    appearance: none;
    -webkit-appearance: none;
    border: none;
    background: none;
    color: var(--cp-controls-color);
    cursor: pointer;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    transition:
        color 0.15s,
        opacity 0.15s,
        transform 0.15s;
    -webkit-tap-highlight-color: transparent;
}

.cp__btn:hover {
    color: var(--cp-controls-hover);
    transform: scale(1.08);
}

.cp__btn:active {
    transform: scale(0.95);
}

.cp__btn:focus-visible {
    outline: 2px solid var(--cp-accent);
    outline-offset: 3px;
    border-radius: 4px;
}

/* Play button — 56px, gold gradient fill */
.cp__play {
    width: 56px;
    height: 56px;
    background: var(--cp-accent);
    border-radius: 50%;
    color: var(--fh-accent-ink);
    transition:
        background 0.15s,
        transform 0.15s,
        opacity 0.15s;
}

.cp__play:hover {
    transform: scale(1.06);
    opacity: 0.9;
    color: var(--fh-accent-ink);
}

.cp__play:active {
    transform: scale(0.96);
}

.cp__play svg {
    width: 20px;
    height: 20px;
    fill: var(--fh-accent-ink);
}

/* Skip buttons — 44px touch target, 34px glyph */
.cp__skip {
    min-width: 44px;
    min-height: 44px;
    opacity: 0.75;
}

.cp__skip:hover {
    opacity: 1;
}

.cp__skip svg {
    width: 34px;
    height: 34px;
    fill: currentColor;
}

/* Playing state */
.cp--playing .cp__play {
    opacity: 1;
}

/* ── Segmented speed control ── */
.cp__speed-segs {
    display: flex;
    align-items: center;
    border: 1px solid var(--cp-seg-border);
    border-radius: 6px;
    overflow: hidden;
}

.cp__speed-seg {
    appearance: none;
    -webkit-appearance: none;
    background: none;
    border: none;
    cursor: pointer;
    color: var(--cp-controls-color);
    font-family: var(--fh-font-mono, 'IBM Plex Mono', monospace);
    font-size: 0.7rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    padding: 0 9px;
    min-height: 40px;
    text-align: center;
    transition: color 0.15s, background 0.15s;
    -webkit-tap-highlight-color: transparent;
}

.cp__speed-seg + .cp__speed-seg {
    border-left: 1px solid var(--cp-seg-divider);
}

.cp__speed-seg:hover {
    color: var(--cp-controls-hover);
}

.cp__speed-seg:focus-visible {
    outline: 2px solid var(--cp-accent);
    outline-offset: -2px;
}

.cp__speed-seg.active {
    /* On the dark player the accent fill is 4.3:1 as text; lift it toward
       white so it clears 4.5 and still reads green. */
    color: color-mix(in srgb, var(--cp-accent) 65%, white);
    background: var(--cp-accent-soft);
}

/* ── Wide container: transport centered, speed pinned right ──
   Triggers on the PLAYER's own width (not viewport). The 1fr/auto/1fr grid
   needs ~484px to seat the speed segments without squeezing the transport,
   so 500px gives a safe margin. Below this, the stacked default applies —
   which is why the narrow audio-library cards no longer overlap. */
@container (min-width: 500px) {
    .cp__controls {
        display: grid;
        grid-template-columns: 1fr auto 1fr;
        flex-direction: row;
        gap: 0;
        align-items: center;
    }

    .cp__transport {
        grid-column: 2;
    }

    .cp__speed-segs {
        grid-column: 3;
        justify-self: end;
    }
}

/* Retain legacy .cp__speed selector so editorial.css overrides aren't broken
   (editorial.css scopes its rules to .ed-audio .cp__speed; those pages won't
   have this element but the rules simply won't match — harmless) */
.cp__speed {
    display: none; /* replaced by .cp__speed-segs */
}

/* ── Editorial context overrides (.ed-audio wrapper = light bg) ── */
/* sie-chapter.css loads last so these win over editorial.css's .cp rules */
.ed-audio .cp {
    --cp-track-bg: rgba(0, 0, 0, 0.08);
    --cp-buffer-bg: rgba(0, 0, 0, 0.14);
    --cp-controls-color: rgba(0, 0, 0, 0.55);
    --cp-controls-hover: rgba(0, 0, 0, 0.85);
    --cp-time-color: rgba(0, 0, 0, 0.45);
    --cp-seg-border: rgba(0, 0, 0, 0.14);
    --cp-seg-divider: rgba(0, 0, 0, 0.1);
    /* accent stays the brand green; the play button carries accent-ink text */
}

.ed-audio .cp__speed-seg.active {
    /* accent-soft over paper lands near 4.1:1 for accent-text; tint clears 4.5 */
    background: var(--fh-tint);
    color: var(--fh-accent-text);
}

.ed-audio .cp__play {
    background: var(--cp-accent);
    color: var(--fh-accent-ink);
}

.ed-audio .cp__handle {
    background: var(--cp-accent);
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9), 0 1px 4px rgba(0, 0, 0, 0.3);
}

[data-theme="night"] .ed-audio .cp {
    --cp-track-bg: rgba(255, 255, 255, 0.12);
    --cp-buffer-bg: rgba(255, 255, 255, 0.26);
    --cp-controls-color: rgba(255, 255, 255, 0.65);
    --cp-controls-hover: rgba(255, 255, 255, 0.92);
    --cp-time-color: rgba(255, 255, 255, 0.48);
    --cp-seg-border: rgba(255, 255, 255, 0.14);
    --cp-seg-divider: rgba(255, 255, 255, 0.12);
}

/* ── Zone 0: collapsed bar (reading pages only) ──
   Spec: dev/design-review/mobile-ux/deep-dive.html, "Player bar" — the
   193px card shouldn't sit between a reader and the essay/chapter. Starts
   collapsed to this 56px bar; the .cp__bar itself stays visible even once
   expanded (as a slim title/collapse header) so there's always a way back
   without hunting for a control buried in the full transport. */
.cp--collapsible .cp__bar {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 56px;
    cursor: pointer;
}
.cp--collapsible:not(.cp--collapsed) .cp__bar {
    margin-bottom: 0.5rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--cp-seg-border);
}
.cp__bar-play {
    width: 44px;
    height: 44px;
    background: var(--cp-accent);
    border-radius: 50%;
    color: var(--fh-accent-ink);
    flex-shrink: 0;
}
.cp__bar-play svg {
    width: 18px;
    height: 18px;
    fill: var(--fh-accent-ink);
}
/* Expanded: the full transport's play button is doing the job; showing
   both reads as a bug, not a feature. */
.cp--collapsible:not(.cp--collapsed) .cp__bar-play {
    display: none;
}
.cp__bar-title {
    flex: 1;
    min-width: 0;
    font-family: var(--fh-font-display);
    font-size: 0.95rem;
    font-weight: 500;
    color: var(--cp-controls-hover);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.cp__toggle {
    width: 32px;
    height: 32px;
    flex-shrink: 0;
}
.cp__toggle svg {
    width: 18px;
    height: 18px;
    transition: transform 0.2s ease;
}
.cp--collapsible:not(.cp--collapsed) .cp__toggle svg {
    transform: rotate(180deg);
}
.cp--collapsible.cp--collapsed .cp__progress-wrap,
.cp--collapsible.cp--collapsed .cp__controls {
    display: none;
}

/* The wrapper's own header (icon, label, title, duration) collapses in
   lockstep with .cp__bar — see the comment in audio-player.js where
   audio-wrap--collapsed is toggled. Without this, collapsing .cp still
   left the full header standing, which both defeats the point (the
   header alone is most of the 193px this feature exists to avoid) and
   shows the track title twice (once here, once in .cp__bar). */
.audio-wrap--collapsed .audio-player__header,
.audio-wrap--collapsed .ed-audio__header {
    display: none;
}
.audio-player.audio-wrap--collapsed {
    padding: var(--fh-space-sm) var(--fh-space-md);
}
.ed-audio.audio-wrap--collapsed {
    padding: var(--fh-space-sm) var(--fh-space-md);
}

/* ── Seek-recovery state ──
   Shown for the fetch-and-reblob fallback in audio-player.js, which only
   ever runs against real Cloudflare Pages traffic where a seek silently
   didn't land — see verifySeek()/recoverUnseekable(). A few seconds of
   "getting this ready to seek" reads better than a scrub bar that snaps
   back to where it started with no explanation. */
.cp--recovering .cp__progress-bar {
    cursor: wait;
    opacity: 0.5;
}
.cp--recovering .cp__fill {
    animation: cp-recovering-pulse 1s ease-in-out infinite;
}
@keyframes cp-recovering-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.4; }
}

/* ── Mobile ── */
@media (max-width: 600px) {
    /* Bigger hit area on touch */
    .cp__progress-bar {
        height: 44px;
    }

    /* Handle grows to 16px rest, 20px active */
    .cp__handle {
        width: 16px;
        height: 16px;
    }

    .cp__progress-bar:hover .cp__handle,
    .cp__progress-bar:focus-visible .cp__handle,
    .cp__progress-bar:active .cp__handle {
        width: 20px;
        height: 20px;
    }

    /* Controls already stack by default; just enlarge speed segments for touch */
    .cp__speed-seg {
        min-height: 44px;
        padding: 0 14px;
    }
}

/* ============================================
   Audio Card Player Wrapper
   ============================================ */
.audio-card__player {
    background: var(--fh-surface-inverse);
    border-radius: 6px;
    padding: var(--fh-space-sm) var(--fh-space-md);
}

/* Native controls visible as fallback; JS removes [controls] attr when custom player initializes */
.audio-card__player audio[controls] {
    width: 100%;
    height: 44px;
    border-radius: 4px;
}

.audio-card__player audio:not([controls]) {
    height: 0;
    display: none;
}
/* ============================================
   Sticky Mini Player
   ============================================ */
.mini-player {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 100;
    background: var(--fh-surface-inverse);
    box-shadow: 0 -2px 12px color-mix(in srgb, var(--fh-accent-ink) 30%, transparent);
    transform: translateY(100%);
    transition: transform 0.3s ease;
}

.mini-player.visible {
    transform: translateY(0);
}

.mini-player[hidden] {
    display: block;
}

.mini-player__inner {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 var(--fh-space-md);
    height: 56px;
    max-width: 780px;
    margin: 0 auto;
}

.mini-player__play {
    width: 44px;
    height: 44px;
    background: rgba(255, 255, 255, 0.18);
    border-radius: 50%;
    flex-shrink: 0;
}

.mini-player__play svg {
    width: 20px;
    height: 20px;
}

.mini-player__info {
    flex: 1;
    min-width: 0;
}

.mini-player__title {
    font-family: var(--fh-font-display);
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--fh-on-inverse);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    display: block;
    line-height: 1.3;
}

.mini-player__progress {
    height: 3px;
    background: rgba(255, 255, 255, 0.15);
    border-radius: 2px;
    margin-top: 4px;
    overflow: hidden;
}

.mini-player__progress-fill {
    height: 100%;
    background: var(--fh-accent);
    border-radius: 2px;
    width: 0;
    transition: width 0.3s linear;
}

.mini-player__speed {
    font-family: var(--fh-font-mono, 'IBM Plex Mono', monospace);
    font-size: 0.7rem;
    font-weight: 600;
    background: rgba(255, 255, 255, 0.15);
    border-radius: 4px;
    padding: 3px 6px;
    min-width: 32px;
    text-align: center;
    flex-shrink: 0;
    color: var(--fh-on-inverse);
}

.mini-player__close {
    width: 44px;
    height: 44px;
    opacity: 0.6;
    flex-shrink: 0;
}

.mini-player__close:hover {
    opacity: 1;
}

.mini-player__close svg {
    width: 18px;
    height: 18px;
}

/* ============================================
   Night Mode: Audio Player & Cards
   ============================================
   .audio-player, .audio-card__player and .mini-player are now flat
   --fh-surface-inverse, which does not flip, so their old navy-gradient night
   pairs are gone: there is nothing left to re-tint. */
[data-theme="night"] .audio-card {
    border-color: var(--fh-gray-300);
}

[data-theme="night"] .audio-card:hover {
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
}

/* D-011: one accent, no colour-coding exams by hue. The three chapter tags
   (s7/sie/s63) get the same badge treatment; the day-mode base rule for
   .audio-card__chapter lives outside this file. */
[data-theme="night"] .audio-card__chapter,
[data-theme="night"] .audio-card__chapter--s7,
[data-theme="night"] .audio-card__chapter--sie,
[data-theme="night"] .audio-card__chapter--s63 {
    background: var(--fh-tint);
    color: var(--fh-accent-text);
}

[data-theme="night"] .mini-player {
    box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.4);
}

/* ============================================
   Responsive - Mobile
   ============================================ */
@media (max-width: 640px) {
    .audio-player {
        padding: var(--fh-space-md);
    }

    .audio-player__header {
        flex-direction: column;
        align-items: flex-start;
        gap: var(--fh-space-sm);
    }

    .audio-player__icon {
        width: 40px;
        height: 40px;
    }

    .audio-player__title {
        font-size: 1rem;
    }

    .audio-card__player {
        padding: var(--fh-space-sm);
    }

    /* Mini Player Mobile */
    .mini-player__inner {
        padding: 0 var(--fh-space-sm);
        gap: 8px;
    }

    .mini-player__title {
        font-size: 0.75rem;
    }
}

/* Editorial pages that embed the chapter-style .audio-player wrapper: their
   prose rules (.ed-prose p, .ed-article p) would otherwise paint the title and
   description in secondary ink on the inverse surface. */
.audio-player .audio-player__title,
.audio-player .audio-player__description,
.audio-player .audio-player__label,
.audio-player .audio-player__duration {
    color: var(--fh-on-inverse);
}
