/*
video.css
Role: video digest styles.
Responsibility: split-pane video queue/player layout and compact video cards.
Note: Modify only from the latest local file.
*/

.video-content {
    display: flex;
    flex-direction: column;
    min-height: 0;
    height: 100%;
    padding-top: 0;
    padding-bottom: var(--space-sm);
}


.video-digest-shell {
    display: grid;
    grid-template-columns: var(--video-queue-width, 213px) 10px minmax(0, 1fr);
    align-items: stretch;
    gap: var(--space-sm) 0;
    min-height: 0;
    height: 100%;
    flex: 1 1 auto;
}

.video-digest-shell.is-live-scope {
    grid-template-columns: minmax(0, 1fr);
}

.video-digest-shell.is-live-scope .video-queue-panel,
.video-digest-shell.is-live-scope .queue-resize-handle {
    display: none;
}

/* .video-queue-panel, .video-player-panel visual skin → shared via .rail-panel in layout.css */

.video-queue-panel {
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    overflow: hidden;
}

.video-queue-header {
    padding: var(--space-sm);
    border-bottom: 1px solid var(--border);
}

.video-queue-title,
.video-player-title {
    margin: 0;
    font-size: var(--text-panel);
}

.video-player-title {
    border-bottom: 1px solid var(--border);
    padding-bottom: var(--space-xs);
    margin-bottom: var(--space-xs);
}

.video-player-byline {
    text-align: center;
}

.video-queue-subtitle,
.video-player-byline {
    margin-top: 6px;
    color: var(--muted);
    font-size: var(--text-base);
}

.video-player-byline.is-live-header {
    margin-top: 0;
    font-size: var(--text-panel);
    font-weight: 700;
    color: var(--text);
}

.video-queue-list {
    min-height: 0;
    overflow: auto;
    overflow-x: hidden;
    padding: var(--space-sm);
    display: grid;
    grid-template-columns: 1fr;
    align-content: start;
    gap: 6px;
}

.video-queue-item {
    display: flex;
    align-items: stretch;
    width: 100%;
    max-width: 100%;
    min-width: 0;
    border: 1px solid transparent;
    border-radius: var(--radius);
    background: color-mix(in srgb, var(--panel-soft) 50%, transparent 50%);
    box-sizing: border-box;
    box-shadow: 2px 5px 8px rgba(0,0,0,0.65), 1px 2px 3px rgba(0,0,0,0.5);
    transition: background-color 140ms ease, border-color 140ms ease, box-shadow 140ms ease, transform 140ms ease;
}

.video-queue-item-trigger {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    flex: 1 1 auto;
    min-width: 0;
    padding: 6px;
    border: none;
    background: transparent;
    color: inherit;
    text-align: left;
    cursor: pointer;
    font: inherit;
    gap: 4px;
    box-sizing: border-box;
    border-radius: var(--radius);
}

.video-queue-item:hover {
    background: var(--link-bg);
    color: var(--link-text);
    border-color: color-mix(in srgb, var(--border-accent) 45%, transparent 55%);
}

.video-queue-item.is-active {
    background: color-mix(in srgb, var(--link-bg) 78%, var(--panel) 22%);
    color: var(--link-text);
    border-color: var(--border-accent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--border-accent) 55%, transparent 45%), 0 0 0 2px color-mix(in srgb, var(--border-accent) 20%, transparent 80%);
    transform: translateX(2px);
}

.video-queue-item.is-active .video-queue-card-title {
    font-weight: 700;
}

.video-queue-thumb-wrap {
    width: 100%;
    aspect-ratio: 16 / 10;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--image-bg);
}

.video-queue-thumb {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.video-queue-body {
    min-width: 0;
    max-width: 100%;
    display: flex;
    flex-direction: column;
    gap: 4px;
    overflow: hidden;
}

.video-queue-card-title {
    font-size: var(--text-base);
    line-height: var(--leading-heading);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-overflow: ellipsis;
    overflow-wrap: anywhere;
    hyphens: auto;
}

.video-queue-card-meta {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    font-size: var(--text-sm);
    color: var(--muted);
    overflow: hidden;
    border-top: 1px solid var(--border);
    padding-top: var(--space-xs);
    margin-top: var(--space-xs);
}

.video-queue-item.is-active .video-queue-card-meta {
    color: color-mix(in srgb, var(--link-text) 78%, var(--muted) 22%);
}

.video-queue-status-dot {
    flex: 0 0 auto;
    width: 7px;
    height: 7px;
    border-radius: 999px;
    background: var(--border);
    transition: background-color 300ms ease, box-shadow 300ms ease;
}

.video-queue-item.is-live-ok .video-queue-status-dot {
    background: #22c55e;
    box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.22);
}

.video-queue-item.is-stream-dead .video-queue-status-dot {
    background: #d97706;
    box-shadow: 0 0 0 2px rgba(217, 119, 6, 0.22);
}



.video-player-panel {
    display: grid;
    grid-template-rows: auto auto auto;
    gap: 0;
    /* overflow-y:auto (not hidden): a long story body below the player must be able to scroll
       into view, not get clipped by the viewport-height panel. min-height:0 lets this grid cell
       shrink within the shell so its own scroll engages. */
    overflow-y: auto;
    overflow-x: hidden;
    min-height: 0;
    align-content: start;
}

.video-player-stage {
    position: relative;
    padding: 0;
    background: color-mix(in srgb, var(--panel-soft) 72%, transparent 28%);
}

.video-player-host,
.video-player-stream,
.video-player-empty {
    width: 100%;
    aspect-ratio: 16 / 9;
    max-height: calc(100vh - 290px);
    max-height: calc(100svh - 290px);
    margin: 0 auto;
    border-radius: var(--radius) var(--radius) 0 0;
    background: #000;
    overflow: hidden;
}

.video-player-host iframe {
    width: 100%;
    height: 100%;
    border: none;
    display: block;
}

.video-player-stream {
    display: block;
}

.video-player-host[hidden],
.video-player-stream[hidden],
.video-player-empty[hidden] {
    display: none !important;
}

.video-player-empty {
    display: none;
}

/* Playback facade — session-gated YouTube autoplay (privacy contract, see CLAUDE.md).
   Rendered into .video-player-empty by videos.js/tv.js; .is-facade overrides the
   default display:none above. */
.video-player-empty.is-facade {
    display: flex;
    position: relative;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-sm);
    padding: var(--space-md);
}

.video-facade-thumb {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0.45;
}

.video-facade-title {
    position: relative;
    max-width: 80%;
    color: #fff;
    font-size: var(--text-ui);
    text-align: center;
    text-shadow: var(--text-shadow-title);
}

.video-facade-play {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    padding: 9px 10px;
    border: 1px solid var(--border-accent);
    border-radius: var(--radius);
    background: var(--panel);
    color: var(--text);
    font-size: var(--text-ui);
    cursor: pointer;
    box-shadow: var(--shadow);
    transition: box-shadow 0.15s, transform 0.15s;
}

.video-facade-play:hover {
    background: var(--link-bg);
    box-shadow: var(--shadow);
    transform: translateY(-1px);
}

.video-facade-note {
    position: relative;
    color: #d6d6da;
    font-size: var(--text-sm);
    text-shadow: var(--text-shadow-title);
}

.video-player-controls[hidden],
.video-player-meta[hidden] { display: none; }

.video-player-controls {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-sm);
    padding: 8px var(--space-sm);
    flex-wrap: wrap;
    background: color-mix(in srgb, var(--panel-soft) 72%, transparent 28%);
}

.video-player-controls-primary {
    display: flex;
    gap: 8px;
    align-items: center;
}

.video-player-control-button {
    border: 1px solid var(--border);
    background: var(--button-bg);
    color: var(--button-text);
    border-radius: var(--radius);
    padding: 8px 12px;
    font: inherit;
    cursor: pointer;
    width: 108px;
    text-align: center;
    box-shadow: 2px 5px 8px rgba(0,0,0,0.65), 1px 2px 3px rgba(0,0,0,0.5);
}

.video-player-control-button:hover {
    background: var(--button-bg-hover);
}

.video-player-volume-group {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.video-player-volume-slider {
    width: 108px;
}

.video-player-speed-select {
    border: 1px solid var(--border);
    background: var(--button-bg);
    color: var(--button-text);
    border-radius: var(--radius);
    padding: 8px 10px 8px 5px;
    font: inherit;
    cursor: pointer;
    width: 69px;
    text-align: center;
    box-shadow: 2px 5px 8px rgba(0,0,0,0.65), 1px 2px 3px rgba(0,0,0,0.5);
}

.video-player-speed-select:hover {
    background: var(--button-bg-hover);
}

.video-player-speed-select:disabled {
    opacity: 0.4;
    cursor: default;
}

.video-player-meta {
    padding: 4px var(--space-sm) var(--space-sm) var(--space-sm);
}

.video-player-summary {
    margin-top: 8px;
    color: var(--text-soft);
    font-size: var(--text-ui);
    line-height: var(--leading-prose);
}

@media (max-width: 1180px) {
    .video-digest-shell {
        grid-template-columns: 1fr;
    }

    .video-queue-resize-handle {
        display: none;
    }

    .video-queue-panel {
        max-height: 420px;
    }
}

/* ════════════════════════════════════════════════════════════════════════════════════════════
   TV — LANDSCAPE FULL-BLEED (phone held sideways)
   Trigger: landscape + short viewport + coarse pointer = a phone in landscape (never a desktop/
   tablet, which are tall). The player goes full-bleed (topbar hidden); the channel rail and the
   header each return as a slide-in OVERLAY toggled ONLY by their handle TAP (edge-swipes were
   dropped — they fought the phone/browser's own edge gestures). The handles auto-dim to subtle
   when idle and go full-opacity while pressed or while their overlay is open. Gated by html.tv-active
   (a JS class set in tv.js, NOT :has() — more robust across browsers) so the topbar/header hooks
   work even on engines without :has, and scoped to .reader-shell--tv so no other reader mode is
   touched. Handles are display:none outside this query.
   ════════════════════════════════════════════════════════════════════════════════════════════ */
.tv-handle { display: none; }

@media (orientation: landscape) and (max-height: 500px) and (pointer: coarse) {
    /* Topbar hidden by default → slides DOWN as an overlay when tv-header-open. */
    html.tv-active .topbar-shell {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        transform: translateY(-100%);
        transition: transform 0.25s ease;
        z-index: 1180;
    }
    html.tv-active.tv-header-open .topbar-shell {
        transform: translateY(0);
    }

    /* Single column; player fills the viewport. */
    .reader-shell--tv {
        grid-template-columns: minmax(0, 1fr);
        padding-left: 0;
        height: 100svh;
    }
    .reader-shell--tv .source-rail-divider { display: none; }

    .reader-shell--tv .video-content { height: 100svh; padding: 0; }
    .reader-shell--tv .video-player-panel { height: 100svh; }
    .reader-shell--tv .video-player-stage {
        height: 100svh;
        display: flex;
        align-items: center;
        justify-content: center;
        background: #000;
    }
    .reader-shell--tv .video-player-host,
    .reader-shell--tv .video-player-stream,
    .reader-shell--tv .video-player-empty {
        height: 100svh;
        max-height: 100svh;
        width: 100%;
        aspect-ratio: auto;
        object-fit: contain;
        border-radius: 0;
        margin: 0;
    }
    .reader-shell--tv .video-player-meta { display: none; }

    /* Channel rail → LEFT slide-in overlay (hidden by default). Higher specificity than the
       <=820 `.source-rail{display:none}` so it wins regardless of file order. */
    .reader-shell--tv .source-rail {
        display: block;
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        width: min(280px, 72vw);
        transform: translateX(-100%);
        transition: transform 0.25s ease;
        z-index: 1200;
        background: var(--panel);
        box-shadow: var(--shadow-float);
        overflow-y: auto;
        overscroll-behavior: contain;
    }
    .reader-shell--tv.tv-rail-open .source-rail { transform: translateX(0); }

    /* Visible handles (tap affordance) — dimmed-but-visible when idle, ride their overlay's edge
       when open. They get a full-opacity "wake" on entering landscape (tv-wake, removed by tv.js
       after a beat) and a long dim transition so the user has time to notice them before they
       settle back. */
    .tv-handle {
        display: flex;
        align-items: center;
        justify-content: center;
        position: fixed;
        z-index: 1205;
        padding: 0;
        cursor: pointer;
        color: var(--text);
        background: color-mix(in srgb, var(--panel) 86%, transparent);
        border: 1px solid var(--border);
        box-shadow: var(--shadow-float);
        opacity: 0.55;   /* dimmed but clearly visible when idle */
        transition: opacity 0.8s ease, left 0.25s ease, top 0.25s ease;   /* slow dim */
    }
    .tv-handle:active,
    .tv-handle.tv-wake { opacity: 1; }   /* full while pressed / freshly woken */
    .tv-handle-chev { font-size: 1.1rem; line-height: 1; transition: transform 0.25s ease; }

    .tv-rail-handle {
        left: 0;
        top: 50%;
        transform: translateY(-50%);
        width: 32px;
        height: 64px;
        border-left: none;
        border-radius: 0 var(--radius) var(--radius) 0;
    }
    .reader-shell--tv.tv-rail-open .tv-rail-handle { left: min(280px, 72vw); opacity: 1; }
    .reader-shell--tv.tv-rail-open .tv-rail-handle .tv-handle-chev { transform: rotate(180deg); }

    .tv-header-handle {
        top: 0;
        left: 50%;
        transform: translateX(-50%);
        width: 64px;
        height: 32px;
        border-top: none;
        border-radius: 0 0 var(--radius) var(--radius);
    }
    html.tv-active.tv-header-open .tv-header-handle { top: var(--topbar-h, 56px); opacity: 1; }
    html.tv-active.tv-header-open .tv-header-handle .tv-handle-chev { transform: rotate(180deg); }
}

/* ════════════════════════════════════════════════════════════════════════════════════════════
   TV — PORTRAIT (phone held upright): sticky player on top, channel list below
   At <=820px portrait the channel rail (hidden at this width by responsive.css) returns as a
   PERSISTENT list BELOW the player — the standard mobile "video up top, list under it" pattern
   (no handle/toggle; it's always there). The player is PINNED (sticky, below the sticky topbar)
   while the list scrolls under it. Landscape uses the full-bleed overlay above; this is portrait-
   only. Scoped to .reader-shell--tv so no other reader mode is touched.
   ════════════════════════════════════════════════════════════════════════════════════════════ */
@media (max-width: 820px) and (orientation: portrait) {
    .reader-shell--tv {
        display: flex;
        flex-direction: column;
        padding-left: 0;
    }
    /* Player pinned at the top (below the sticky topbar); the list scrolls under it. */
    .reader-shell--tv .video-content {
        order: 0;
        height: auto;
        position: sticky;
        top: var(--topbar-h, 56px);
        z-index: 5;
        background: var(--bg);
        border-bottom: 1px solid var(--border);
    }
    /* Channel list below the player — un-hide (overrides the <=820 `.source-rail{display:none}`)
       and drop the desktop sticky so it flows in the page scroll. */
    .reader-shell--tv .source-rail {
        display: block;
        order: 1;
        position: static;
        width: 100%;
        align-self: stretch;
    }
    /* Let the channel list grow in the PAGE scroll instead of nesting its own scroll
       (the desktop rail-panel is overflow-y:auto for its sticky-full-height column). */
    .reader-shell--tv .source-rail-inner { height: auto; }
    .reader-shell--tv .rail-panel { overflow: visible; height: auto; }
    .reader-shell--tv .source-rail-divider { display: none; }
}

/* ════════════════════════════════════════════════════════════════════════════════════════════
   VIDEOS — PHONE (portrait + landscape): sticky player + horizontal queue strip
   Video-first page. On phone (portrait <=820 OR landscape-short) the topbar is hidden, the player
   + a sideways-scrolling strip of small queue cards pin to the top, and the player's redundant
   controls/meta are dropped. The SOURCE RAIL differs by orientation: stacked BELOW in portrait
   (page scroll), fly-in from the LEFT in landscape. Two fading handles (top = recall header; left
   = source rail, landscape only) mirror TV; tapping the video goes native fullscreen (landscape).
   Driven by the JS `videos-active` class + videos-header-open / videos-rail-open toggles.
   ════════════════════════════════════════════════════════════════════════════════════════════ */
.videos-handle { display: none; }   /* shown only in the phone @media below */

/* ── Shared across BOTH phone orientations ── */
@media (max-width: 820px) and (orientation: portrait),
       (orientation: landscape) and (max-height: 500px) and (pointer: coarse) {
    /* Topbar hidden → slides DOWN as an overlay on the header handle (videos-header-open). */
    html.videos-active .topbar-shell {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        transform: translateY(-100%);
        transition: transform 0.25s ease;
        z-index: 1180;
    }
    html.videos-active.videos-header-open .topbar-shell { transform: translateY(0); }

    .reader-shell--videos {
        display: flex;
        flex-direction: column;
        padding-left: 0;
    }
    /* Player + queue strip pinned to the very top (topbar hidden → top:0). */
    .reader-shell--videos .video-content {
        order: 0;
        position: sticky;
        top: 0;
        z-index: 5;
        height: auto;
        min-height: 0;
        background: var(--bg);
        border-bottom: 1px solid var(--border);
    }
    .reader-shell--videos .source-rail-divider { display: none; }

    /* Digest shell: player on top, queue strip below (drop the queue|handle|player grid). */
    .reader-shell--videos .video-digest-shell {
        display: flex;
        flex-direction: column;
        height: auto;
        gap: 0;
    }
    .reader-shell--videos .video-player-panel { order: 0; height: auto; }
    .reader-shell--videos .video-queue-panel  { order: 1; }
    .reader-shell--videos .video-queue-resize-handle { display: none; }

    /* Drop the redundant controls bar + title/byline/summary (the player has its own controls). */
    .reader-shell--videos .video-player-controls { display: none; }
    .reader-shell--videos .video-player-meta { display: none; }

    /* Queue → sideways-scrolling strip of small cards. */
    .reader-shell--videos .video-queue-panel {
        display: block;          /* drop the grid */
        max-height: none;
        overflow: visible;
        border-top: 1px solid var(--border);
    }
    .reader-shell--videos .video-queue-header { display: none; }   /* reclaim vertical room */
    .reader-shell--videos .video-queue-list {
        display: flex;
        flex-direction: row;
        overflow-x: auto;
        overflow-y: hidden;
        gap: var(--space-sm);
        padding: var(--space-sm);
        overscroll-behavior-x: contain;
    }
    .reader-shell--videos .video-queue-item {
        flex: 0 0 72px;
        width: 72px;
        box-shadow: var(--shadow-sm);
    }
    .reader-shell--videos .video-queue-card-title { font-size: var(--text-sm); }
    .reader-shell--videos .video-queue-card-meta { display: none; }       /* keep cards small */
    .reader-shell--videos .video-queue-item.is-active { transform: none; } /* no sideways nudge in a row */

    /* Fading handles (top = recall header; left = source rail in landscape). Auto-dimmed when idle,
       full opacity while pressed or freshly woken (is-wake, set by videos.js). */
    .videos-handle {
        display: flex;
        align-items: center;
        justify-content: center;
        position: fixed;
        z-index: 1205;
        padding: 0;
        cursor: pointer;
        color: var(--text);
        background: color-mix(in srgb, var(--panel) 86%, transparent);
        border: 1px solid var(--border);
        box-shadow: var(--shadow-float);
        opacity: 0.55;
        transition: opacity 0.8s ease, top 0.25s ease, left 0.25s ease;
    }
    .videos-handle:active,
    .videos-handle.is-wake { opacity: 1; }
    .videos-handle-chev { font-size: 1.1rem; line-height: 1; transition: transform 0.25s ease; }
    .videos-header-handle {
        top: 0;
        left: 50%;
        transform: translateX(-50%);
        width: 64px;
        height: 32px;
        border-top: none;
        border-radius: 0 0 var(--radius) var(--radius);
    }
    html.videos-active.videos-header-open .videos-header-handle { top: var(--topbar-h, 56px); opacity: 1; }
    html.videos-active.videos-header-open .videos-header-handle .videos-handle-chev { transform: rotate(180deg); }
}

/* ── Portrait only: source rail stacked below, scrolling in the page ── */
@media (max-width: 820px) and (orientation: portrait) {
    .reader-shell--videos .source-rail {
        display: block;
        order: 1;
        position: static;
        width: 100%;
        align-self: stretch;
    }
    .reader-shell--videos .source-rail-inner { height: auto; }
    .reader-shell--videos .rail-panel { overflow: visible; height: auto; }
    .videos-rail-handle { display: none; }   /* rail is stacked — no handle needed */
}

/* ── Landscape only: source rail flies in from the left; player height-capped so the queue fits ── */
@media (orientation: landscape) and (max-height: 500px) and (pointer: coarse) {
    /* Source rail → left slide-in overlay (hidden by default). */
    .reader-shell--videos .source-rail {
        display: block;
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        width: min(280px, 72vw);
        transform: translateX(-100%);
        transition: transform 0.25s ease;
        z-index: 1200;
        background: var(--panel);
        box-shadow: var(--shadow-float);
        overflow-y: auto;
        overscroll-behavior: contain;
    }
    .reader-shell--videos.videos-rail-open .source-rail { transform: translateX(0); }

    /* Player height-capped + centered (letterboxed) so the queue strip fits the short viewport. */
    .reader-shell--videos .video-player-stage {
        display: flex;
        align-items: center;
        justify-content: center;
        background: #000;
    }
    .reader-shell--videos .video-player-host,
    .reader-shell--videos .video-player-stream,
    .reader-shell--videos .video-player-empty {
        height: 58svh;
        max-height: 58svh;
        width: auto;
        max-width: 100%;
        aspect-ratio: 16 / 9;
        margin: 0 auto;
        object-fit: contain;
        border-radius: 0;
    }

    /* Left rail handle (rides the rail's edge when open). */
    .videos-rail-handle {
        left: 0;
        top: 50%;
        transform: translateY(-50%);
        width: 32px;
        height: 64px;
        border-left: none;
        border-radius: 0 var(--radius) var(--radius) 0;
    }
    .reader-shell--videos.videos-rail-open .videos-rail-handle { left: min(280px, 72vw); opacity: 1; }
    .reader-shell--videos.videos-rail-open .videos-rail-handle .videos-handle-chev { transform: rotate(180deg); }
}
