/* ============================================================================
 * single-gallery-inline.css
 *
 * Extracted in v1.1.7 from the inline <style> block at lines 1004-5821 of
 * AltSoundsTV_4.0/single-gallery.php. That block was 4,800 lines and ~185KB
 * of static CSS shipping in the body of EVERY video page render.
 *
 * Why the move helps:
 *   - Inline <style> in HTML body is NEVER browser-cached. Each navigation
 *     re-downloaded ~185KB of identical CSS (or ~30KB gzipped, but still:
 *     repeated on every video page click).
 *   - As a real .css file with proper Cache-Control + ?ver= cache busting,
 *     browsers download it ONCE per release and reuse forever.
 *   - WP-Engine treats it as a static asset → served from edge cache
 *     instantly, never invokes PHP.
 *   - Smaller HTML body → faster TTFB (server has less to write), faster
 *     transfer, less to parse on the client.
 *
 * Enqueued via altsounds-perf/includes/theme-function-overrides.php on
 * is_singular('gallery') only — no overhead on home/archive/admin pages.
 *
 * The original file's section map (preserved verbatim below) was kept so
 * grep / search-by-comment still works.
 * ============================================================================ */

/* ============================================================================
 * single-gallery.php — scoped styles
 *
 * Section map:
 *   1) Base reset + legacy bits (#anchorTop, etc.)
 *   2) Floating chrome — TV-channel-watermark layout
 *      (logo top-left, title bottom-left, I button bottom-right)
 *   3) "I" button breathing pulse animation
 *   4) Cursor auto-hide behavior
 *   5) Info modal overlay — backdrop + blur + scroll container
 *   6) Modal: × close button (outside modal edge)
 *   7) Modal: content shell (80vh, internal scroll, slide-up entrance)
 *   8) Modal: tall hero (backdrop image, dark gradient, burger, artist+title+meta+pills)
 *   9) Modal: CTA row (primary neon + secondary ghost)
 *  10) Modal: About collapsible section (chevron rotate)
 *  11) Modal: You Might Also Like — channel-tile imports + refresh button
 *  12) Modal: bottom keyboard shortcuts strip
 *  13) Responsive tweaks (mobile)
 * ============================================================================ */

/* ---- 1. Base / legacy ---- */
#anchorTop { display: none !important; }

/* ============================================================================
 * 2. FLOATING CHROME — TV-CHANNEL-WATERMARK LAYOUT
 *
 * The only three things visible on the video page itself:
 *   • Logo           top-left    (like a TV channel's corner bug)
 *   • Title          bottom-left (like a lower-third caption)
 *   • "I" info icon  bottom-right (symmetric to the title/logo)
 *
 * Everything else (menu, search, keyboard hints, channel browse) lives
 * inside the info modal now.
 *
 * Each corner has identical padding from its adjacent edges (52px both
 * axes on desktop, 24px on mobile) so the three elements read as parts
 * of one coherent frame.
 * ============================================================================ */

:root {
    /* Fluid chrome padding — scales with viewport so the "115px from edge"
       relationship stays visually proportional on small AND giant screens.
       At 768px viewport: pad-x ~ 30px. At 2560px viewport: pad-x ~ 96px (capped).
       Elements that anchor to edges all use these vars, so logo/title/taunt
       on the left and info button on the right mirror each other automatically. */
    --as-chrome-pad-x: clamp(24px, 3vw, 96px);
    --as-chrome-pad-x-right: calc(var(--as-chrome-pad-x) + 64px); /* match logo's visual left-gap (logo inherits #page padding). */
    --as-chrome-pad-y: clamp(16px, 2.2vh, 40px);   /* v6.4 — tightened the gap between the bottom chrome (title/NP cluster + eyebrow) and the playbar */
}

.as-floating-header {
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    z-index: 1400;
    pointer-events: none; /* pass-through; only children trap clicks */
}

/* Logo — top-left */
.as-chrome-logo-link {
    position: absolute;
    /* Pushed below the 84px top letterbox bar (declared via --as-letterbox).
       Without this the logo's top 32px gets hidden behind the black letterbox,
       which is why the logo appeared to vanish. */
    top: calc(var(--as-letterbox, 84px) + 12px);
    left: var(--as-chrome-pad-x);
    /* z-index here matters when the info modal is open. The blur backdrop
       (.video-info-overlay) is at z:1500 and the modal card (.video-info-content)
       is at z:3500. Logo sits between them at z:2500 — so the backdrop dims/blurs
       around the logo but doesn't cover it, while the modal card, when wide
       enough to reach the top-left corner, covers the logo. */
    z-index: 2500;
    pointer-events: auto;
    transition: opacity 0.35s ease-out;
    text-decoration: none;
    line-height: 0;
}
/* Logo image — force our sizing over theme's legacy .tvlogo2 rules which
   set position:fixed, 6vw size, and left:var(--altsounds-horizontal-gutter).
   We add #page to boost specificity (id is 100x a class in specificity)
   so our !important beats the customizer's !important by raw specificity. */
#page .as-floating-header .as-chrome-logo-link img,
#page .as-floating-header img.tvlogo2,
body.single-gallery .as-floating-header .as-chrome-logo-link img.tvlogo2 {
    display: block !important;
    /* TV-network watermark sizing. Fluid scaling via clamp:
         min 96px (small laptops), max 200px (desktop), ideal 14% of viewport height.
       Gives a big confident network-bug on desktop, comfortable on laptops,
       and automatically scales instead of needing manual breakpoint tuning. */
    height: clamp(96px, 14vh, 200px) !important;
    width: auto !important;
    max-width: none !important;
    position: static !important;
    top: auto !important;
    left: auto !important;
    right: auto !important;
    bottom: auto !important;
    padding: 0 !important;
    margin: 0 !important;
    opacity: 0.9;
    transition: opacity 0.2s ease, transform 0.2s ease;
    /* Three-layer animation system:
       1) Page-load reveal: scale from 0.92→1.0 over 0.5s (runs once per page load
          so each new video feels like "AltSounds is still here")
       2) Ambient breathe: slow 6s opacity cycle 0.86→1.0→0.86 (infinite, very subtle —
          reads as "broadcast is live" without distracting)
       3) Neon flicker: rare brief stutter once per ~40s — classic neon sign
          behavior. Packed into last 2% of a 40s cycle so the bulk of the time
          is completely still. Feels alive without being distracting. */
    animation:
        as-logo-reveal 0.5s cubic-bezier(0.2, 0.8, 0.25, 1.0) 0s 1 both,
        as-logo-breathe 6s ease-in-out 0.6s infinite;
}
.as-chrome-logo-link:hover img {
    opacity: 1;
    transform: scale(1.04);
    /* Pause the ambient breathe on hover — feels more responsive */
    animation-play-state: running, paused;
}
@keyframes as-logo-reveal {
    from { transform: scale(0.92); opacity: 0; }
    to   { transform: scale(1.0);  opacity: 0.9; }
}
@keyframes as-logo-breathe {
    0%, 100% { opacity: 0.86; }
    50%      { opacity: 1.0;  }
}
/* Kill ambient breathe during cinema-mode hide */
body.single-gallery.ui-hidden .as-chrome-logo-link img,
body.single-gallery.as-cursor-hidden .as-chrome-logo-link img {
    animation-play-state: paused, paused;
}
/* Respect reduced-motion preference — no animations for those users */
@media (prefers-reduced-motion: reduce) {
    #page .as-floating-header .as-chrome-logo-link img,
    #page .as-floating-header img.tvlogo2,
    body.single-gallery .as-floating-header .as-chrome-logo-link img.tvlogo2 {
        animation: none !important;
    }
}

/* Title — bottom-left, symmetric to logo.
   Font is intentionally NOT overridden — inherits from the theme so
   we preserve whatever font the main title was using before. We only
   control positioning, sizing hints, and the hide-while-modal-open
   behavior. */
/* =========================================================================
 * CHROME CLUSTER — eyebrow + title + taunt as ONE animated unit
 *
 * The three bottom-left chrome elements are wrapped in .as-chrome-cluster
 * and animate together: sliding up 12px + fading in on chrome wake,
 * sliding down 12px + fading out on chrome hide. Same feel as the header
 * menu and colophon — one confident motion, not three separate pops.
 *
 * Stack order (top→bottom within cluster, bottom→up on screen):
 *   WATCHING [FLOW] MUSIC VIDEOS       ← small uppercase eyebrow
 *   Song Title                          ← big title
 *   [🟣 Have you seen the music video for X by Y?]        ← taste-engine taunt pill
 * ========================================================================= */
/* Footer (keyboard shortcuts + links) — match chrome padding so the
   legend lines up with the logo on the left and the info/eyebrow on the
   right. Higher specificity (html body.single-gallery) + !important to
   beat the inline rule from post-video.inc.php that sets padding:30px 50px. */
html body.single-gallery footer#colophon {
    padding-left:  var(--as-chrome-pad-x-right) !important;
    padding-right: var(--as-chrome-pad-x-right) !important;
    box-sizing: border-box;
}

.as-chrome-cluster {
    position: absolute;
    bottom: var(--as-chrome-pad-y);
    left: var(--as-chrome-pad-x);
    right: auto;
    top: auto;
    max-width: calc(100vw - 160px);
    pointer-events: auto;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;   /* v6.4 — tightened from 16px (title→meta→taunt sit closer) */
    /* Animated-in state (default): visible, resting position */
    opacity: 1;
    transform: translateY(0);
    transition:
        opacity 0.55s cubic-bezier(0.2, 0.8, 0.25, 1.0),
        transform 0.35s cubic-bezier(0.2, 0.8, 0.25, 1.0),
        background 0.2s ease,
        border-color 0.2s ease,
        box-shadow 0.2s ease;
    /* Scale grows from the bottom-right anchor on hover — feels planted
       instead of floating off somewhere. */
    transform-origin: bottom right;
}

/* Hover / focus-within — mirrors the taunt pill's hover feel. Darker
   bg, lime-tinted border, subtle scale-up. focus-within so keyboard
   users tabbing into the × or link get the same feedback. */
.as-chrome-eyebrow:hover,
.as-chrome-eyebrow:focus-within {
    background: rgba(10, 11, 10, 0.82);
    border-color: rgba(191, 255, 0, 0.25);
    box-shadow:
        0 12px 32px rgba(0, 0, 0, 0.55),
        0 0 0 1px rgba(191, 255, 0, 0.08) inset;
    transform: translateY(0) scale(1.035);
}
/* Thumb inside — gets its own lift + lime border on card hover, layered
   on top of the card-level hover. */
.as-chrome-eyebrow:hover .as-eyebrow-upnext-thumb,
.as-chrome-eyebrow:focus-within .as-eyebrow-upnext-thumb {
    border-color: rgba(191, 255, 0, 0.4);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.5);
}
/* Animated-out state: sinks 14px and fades. Same easing whether entering
   or leaving for visual consistency. */
body.single-gallery.ui-hidden .as-chrome-cluster,
body.single-gallery.as-cursor-hidden .as-chrome-cluster,
body.single-gallery.as-modal-open .as-chrome-cluster {
    opacity: 0;
    transform: translateY(14px);
    pointer-events: none;
}

/* =========================================================================
 * EYEBROW — top-right standalone label: "WATCHING RADIOHEAD MUSIC VIDEOS"
 *
 * Only the channel name (the <a class="as-eyebrow-link">) is a link and
 * turns neon on hover. Surrounding "WATCHING" / "MUSIC VIDEOS" strings
 * are plain text and stay white.
 *
 * Positioned top-right, right-aligned — right edge hugs the chrome padding.
 * Does NOT sit inside the info button's vertical column — it's above/across
 * from the logo to balance the top edge visually.
 * ========================================================================= */
/* =========================================================================
 * EYEBROW WIDGET — top-right listening-path display
 *
 * Two-row right-aligned stack anchored below the top letterbox:
 *   1. WATCHING [X] MUSIC VIDEOS     ← current path (clickable term name)
 *   2. UP NEXT: [Song] [×]           ← what plays next (queue state)
 *
 * UP NEXT reflects the single-slot queue (sessionStorage['alts_queue_v1']).
 * Default state populated from AS_UPNEXT_DEFAULT on each page load.
 * User can override via the taunt "+ Queue" button.
 * ========================================================================= */
.as-chrome-eyebrow {
    position: absolute;
    /* Pushed below the 84px top letterbox bar + chrome padding, same as the
       logo. Without this the widget would render under the black bar.
       
       v5 (April 2026): bottom anchor lifted by 32px so the NP widget
       vertically centers with the title cluster on the left. The cluster
       is 3 rows tall (title h1, meta line, taunt) and anchored at the
       same bottom edge, so its top edge naturally sits higher than the
       eyebrow's. Adding 32px of bottom offset shifts the eyebrow up
       roughly half the height delta — making both sides' vertical
       centers line up at the cluster's mid-line.
       
       We use bottom adjustment (not transform) because transform
       would conflict with the chrome-hide animation which uses
       translateY(14px) to slide the eyebrow down on hide. Adjusting
       bottom keeps the transform stack clean for animation. */
    bottom: var(--as-chrome-pad-y);
    right: var(--as-chrome-pad-x-right);
    left: auto;
    top: auto;
    margin: 0;
    padding: 10px 16px 12px;
    max-width: calc(100vw - 320px);
    pointer-events: auto;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    /* v5: vertically center content inside the column, since the column
       may have variable rows (Up Next, flavor pills, etc.) */
    justify-content: center;
    gap: 8px;
    /* v6 (2026-05-14) — Bumped alpha 0.55 → 0.78 so colored blend pills
       inside (BAD OMENS red, 2020s violet, etc) read clearly against
       bright video frames behind. Was reading washed-out / low-contrast
       on most playback footage. */
    background: rgba(10, 11, 10, 0.78);
    backdrop-filter: blur(10px) saturate(1.1);
    -webkit-backdrop-filter: blur(10px) saturate(1.1);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 14px;
    box-shadow:
        0 8px 24px rgba(0, 0, 0, 0.4),
        0 0 0 1px rgba(191, 255, 0, 0.04) inset;
    font-size: clamp(11px, 0.85vw, 14px);
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    line-height: 1.2;
    color: rgba(255, 255, 255, 0.78);
    text-align: right;
    /* Animate in/out with the rest of the chrome — same easing as cluster */
    opacity: 1;
    transform: translateY(0);
    transition:
        opacity 0.55s cubic-bezier(0.2, 0.8, 0.25, 1.0),
        transform 0.55s cubic-bezier(0.2, 0.8, 0.25, 1.0);
}
body.single-gallery.ui-hidden .as-chrome-eyebrow,
body.single-gallery.as-cursor-hidden .as-chrome-eyebrow,
body.single-gallery.as-modal-open .as-chrome-eyebrow {
    opacity: 0;
    transform: translateY(14px); /* slides DOWN on hide (now at bottom) */
    pointer-events: none;
}
/* Flavor swap in progress — force the eyebrow visible AND pause the idle
   auto-hide. The pill handler adds .as-flavor-busy on <body> at click time
   and removes it when the scope fetch resolves (success OR failure).
   Without these overrides, the ambient "hide chrome while watching" logic
   fires as the user waits and the UP NEXT card disappears mid-transition,
   making the whole interaction feel broken.

   Both sides of the hero chrome stay visible — the eyebrow (right, UP
   NEXT) AND the cluster (left, title + station + taunt). The user needs
   context on both sides to judge whether the swap landed where they
   wanted. */
body.single-gallery.as-flavor-busy .as-chrome-eyebrow,
body.single-gallery.as-flavor-busy .as-chrome-cluster {
    opacity: 1 !important;
    transform: none !important;
    pointer-events: auto !important;
}
body.single-gallery.as-flavor-busy.ui-hidden .as-chrome-eyebrow,
body.single-gallery.as-flavor-busy.ui-hidden .as-chrome-cluster,
body.single-gallery.as-flavor-busy.as-cursor-hidden .as-chrome-eyebrow,
body.single-gallery.as-flavor-busy.as-cursor-hidden .as-chrome-cluster {
    opacity: 1 !important;
    transform: none !important;
    pointer-events: auto !important;
}

/* v1.1.6: Mothership trigger button — rendered server-side so it's
   visible from page load (instead of being painted in by guide.js after
   the lazy-loader runs). Mirrors the .as-eyebrow-expand styles in
   guide.css so the button looks identical before AND after guide.css
   has loaded — no FOUC on first interaction. The bootloader's
   document-level click listener picks up [data-alts-guide-trigger]
   and starts the lazy load.
   
   v3 (April 2026 — chrome cleanup): the eyebrow grid-icon Mothership
   trigger is REMOVED. Two reasons:
     1. Redundant — the primary chrome UFO at top-right of the page
        already opens Mothership (and is more visible / branded).
     2. Reads as visual noise more than as an affordance — the small
        4-square glyph appearing on hover next to the up-next card
        feels like UI debris, not a feature.
   
   Done as display:none on a CSS-only rule because the PHP-level
   removal in single-gallery.php hasn't been replacing on the live
   server (plugin entry files are pinned). CSS files DO replace, so
   this fix lands regardless of the deploy state of any PHP file.
   The :hover and :focus-visible reveal rules are also nuked so even
   if some other rule defeats the display:none, the button stays
   invisible and unclickable. */
.as-eyebrow-expand {
    display: none !important;
}
.as-chrome-eyebrow:hover .as-eyebrow-expand,
.as-chrome-eyebrow:focus-within .as-eyebrow-expand,
.as-eyebrow-expand:focus-visible {
    display: none !important;
}
.as-eyebrow-expand:hover,
.as-eyebrow-expand:focus-visible {
    display: none !important;
}

.as-chrome-eyebrow .as-eyebrow-row {
    margin: 0;
    padding: 0;
    display: flex;
    align-items: baseline;
    justify-content: flex-start;
    gap: 6px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}
.as-chrome-eyebrow .as-eyebrow-current {
    padding-bottom: 8px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    width: 100%;
}

/* Icon before WATCHING — record collection glyph echoes the menu. */
.as-chrome-eyebrow .as-eyebrow-icon {
    color: #BFFF00;
    font-size: 1.05em;
    margin-right: 6px;
    opacity: 0.85;
}

/* Row 1 — WATCHING X — small muted hat above the hero title. */
.as-eyebrow-current {
    font-size: 0.78em;
    letter-spacing: 0.2em;
    opacity: 0.82;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-align: left;
    width: 100%;
}
.as-eyebrow-current .as-eyebrow-prefix,
.as-eyebrow-current .as-eyebrow-suffix {
    color: rgba(255, 255, 255, 0.62);
    font-weight: 600;
}
.as-eyebrow-current .as-eyebrow-link {
    color: #ffffff;
    text-decoration: none;
    font-weight: 700;
    transition: color 0.2s ease;
}
.as-eyebrow-current a.as-eyebrow-link:hover,
.as-eyebrow-current a.as-eyebrow-link:focus {
    color: #BFFF00;
    outline: none;
}
.as-eyebrow-current .as-eyebrow-link--nolink {
    cursor: default;
}

/* Row 1.5 — FLAVOR PILLS — third row in the eyebrow, under UP NEXT. Shows
   a tiny "🌶 FLAVOR" label followed by two toggle pills: Classics and New.
   Exactly one or zero are lit at a time. Clicks live-switch flavor (music
   keeps playing, scope + UP NEXT rebuild client-side). Not rendered on
   Year/Decade scopes where flavor would be a no-op. */
.as-eyebrow-flavor {
    font-size: 0.78em;
    letter-spacing: 0.2em;
    text-align: left;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 10px;
    margin-top: 2px;
    flex-wrap: nowrap;
}

.as-eyebrow-flavor .as-eyebrow-flavor-heading {
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
}
.as-eyebrow-flavor .as-eyebrow-flavor-heading-icon {
    font-size: 1.05em;
    line-height: 1;
    color: #BFFF00;
    /* Slight optical nudge so icon aligns with pill text baselines. */
    transform: translateY(-1px);
    transition: color 200ms ease, opacity 200ms ease;
}
/* v1.1.53: heading is-empty — applied server-side when zero pills are
   usable for the active scope. Dims the chili-pepper to signal that
   the flavor system is present but inert here, rather than pretending
   the row works when it can't. Pill row underneath still renders in
   .is-unavailable state via existing rule below. */
.as-eyebrow-flavor .as-eyebrow-flavor-heading.is-empty .as-eyebrow-flavor-heading-icon {
    color: rgba(255, 255, 255, 0.32);
    opacity: 0.7;
}
/* Pill group — two inline toggle buttons. */
.as-eyebrow-flavor .as-eyebrow-flavor-pills {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.as-eyebrow-flavor .as-flavor-pill {
    appearance: none;
    font: inherit;
    font-size: 0.95em;
    letter-spacing: 0.18em;
    padding: 3px 11px;
    border-radius: 999px;
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.22);
    color: rgba(255, 255, 255, 0.72);
    cursor: pointer;
    font-weight: 700;
    line-height: 1.4;
    transition: background 0.16s ease, border-color 0.16s ease, color 0.16s ease, opacity 0.16s ease;
}
.as-eyebrow-flavor .as-flavor-pill:hover,
.as-eyebrow-flavor .as-flavor-pill:focus-visible {
    color: #ffffff;
    border-color: rgba(191, 255, 0, 0.55);
    background: rgba(191, 255, 0, 0.06);
    outline: none;
}
/* Active (lit) state — neon fill, matches the channel-page Play-All button
   language so users recognize "this is on" without having to learn new UI.
   text-shadow reset is important: pills live inside the chrome eyebrow
   which inherits a subtle text-shadow for contrast over the video. On the
   lit (neon) background that inherited shadow makes the dark text look
   smudgy — explicitly kill it here. */
.as-eyebrow-flavor .as-flavor-pill[aria-pressed="true"] {
    color: #0a0f0a;
    background: #BFFF00;
    border-color: #BFFF00;
    text-shadow: none;
}
.as-eyebrow-flavor .as-flavor-pill[aria-pressed="true"]:hover,
.as-eyebrow-flavor .as-flavor-pill[aria-pressed="true"]:focus-visible {
    background: #aaee00;
    border-color: #aaee00;
    color: #0a0f0a;
    text-shadow: none;
}
/* Unavailable state — this flavor has zero videos in the current scope.
   Dimmed, non-interactive, cursor reflects "not-allowed." Kept visible
   (not hidden) so users can SEE that Classics exists as a concept and
   know it's just not applicable on this channel — dropping it entirely
   would make the UI inconsistent across channels. */
.as-eyebrow-flavor .as-flavor-pill.is-unavailable,
.as-eyebrow-flavor .as-flavor-pill[disabled],
.as-eyebrow-flavor .as-flavor-pill[aria-disabled="true"] {
    opacity: 0.35;
    cursor: not-allowed;
    pointer-events: auto; /* still allow hover for title tooltip */
}
.as-eyebrow-flavor .as-flavor-pill.is-unavailable:hover,
.as-eyebrow-flavor .as-flavor-pill[disabled]:hover,
.as-eyebrow-flavor .as-flavor-pill[aria-disabled="true"]:hover {
    /* Suppress the hover "lift" for unavailable pills — no neon tint, no
       border brighten. Stays visually inert so user intuits the state. */
    background: transparent;
    border-color: rgba(255, 255, 255, 0.22);
    color: rgba(255, 255, 255, 0.72);
}
/* Busy state during scope re-fetch — pills dim slightly, cursor becomes
   wait. Short-lived; most fetches return within 200ms from warm cache. */
.as-eyebrow-flavor[data-busy="1"] .as-flavor-pill {
    opacity: 0.7;
    cursor: wait;
}
/* UP NEXT loading state while we swap the scope. Fades the card slightly
   so the user sees "something is happening" without aggressive UI churn. */
.as-eyebrow-upnext[data-busy="1"] {
    opacity: 0.55;
    pointer-events: none;
    transition: opacity 0.12s ease;
}

/* Row 2 — UP NEXT — the hero row. Label + × stacked on their own line,
   then the big title below. Lets long titles wrap naturally. */
.as-eyebrow-upnext {
    display: flex !important;
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
    width: 100%;
    font-size: clamp(10px, 0.75vw, 12px);
}
.as-eyebrow-upnext-labelrow {
    display: flex;
    align-items: center;
    gap: 8px;
    justify-content: flex-start;
}
.as-eyebrow-label {
    color: #BFFF00;
    font-weight: 700;
    letter-spacing: 0.22em;
    font-size: 0.85em;
}
.as-eyebrow-upnext-link {
    color: #ffffff;
    text-decoration: none;
    font-size: 1.25em;
    font-weight: 700;
    letter-spacing: 0.01em;
    text-transform: none;
    line-height: 1.25;
    /* Flex row: [thumb] [textcol]. Text column holds label + 2-line
       title (artist on top, song below). */
    display: inline-flex;
    align-items: center;
    gap: 12px;
    max-width: 100%;
    text-align: left;
    white-space: normal;
    transition: color 0.2s ease;
}
.as-eyebrow-upnext-textcol {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    min-width: 0;
}
.as-eyebrow-upnext-title {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
    line-height: 1.15;
    text-align: left;
    max-width: 100%;
}
.as-eyebrow-upnext-title .as-upnext-artist {
    color: rgba(255, 255, 255, 0.68);
    font-size: 0.62em;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    line-height: 1.2;
}
/* Dash collapsed — artist + song are now on separate lines. */
.as-eyebrow-upnext-title .as-upnext-dash {
    display: none;
}
.as-eyebrow-upnext-title .as-upnext-song {
    color: #ffffff;
    font-weight: 700;
    font-size: 1em;
    line-height: 1.25;
}
/* Square thumbnail of the UP NEXT song. Lazy-loaded, aspect-locked,
   subtle border so it anchors visually without competing. Hidden when
   the thumb src is empty (no thumb available). */
#page .as-eyebrow-upnext-thumb,
.as-eyebrow-upnext-thumb {
    /* #page prefix + !important to beat theme's "#page img { height: auto; max-width: 100% }"
       which was stretching the thumb to fill the flex row. */
    width: clamp(42px, 3.2vw, 56px) !important;
    height: clamp(42px, 3.2vw, 56px) !important;
    max-width: none !important;
    object-fit: cover;
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
    flex-shrink: 0;
    background: rgba(255, 255, 255, 0.04);
    transition: transform 0.2s ease, border-color 0.2s ease;
}
.as-eyebrow-upnext-link:hover .as-eyebrow-upnext-thumb,
.as-eyebrow-upnext-link:focus .as-eyebrow-upnext-thumb {
    transform: scale(1.04);
    border-color: rgba(191, 255, 0, 0.4);
}
/* No thumb available — hide the img so we don't show a broken/empty box. */
.as-eyebrow-upnext-thumb[src=""],
.as-eyebrow-upnext-thumb:not([src]) {
    display: none;
}
.as-eyebrow-upnext-link:hover,
.as-eyebrow-upnext-link:focus {
    color: #BFFF00;
    outline: none;
}
/* Artist / dash / song spans inside the title — dashed typography makes
   the two pieces legible while keeping one line. */
.as-eyebrow-upnext-title .as-upnext-artist {
    color: rgba(255, 255, 255, 0.68);
    font-weight: 600;
}
.as-eyebrow-upnext-title .as-upnext-dash {
    color: rgba(191, 255, 0, 0.8);
    font-weight: 700;
    margin: 0 0.35em;
}
.as-eyebrow-upnext-title .as-upnext-song {
    color: #ffffff;
    font-weight: 700;
}
/* When a user has explicitly queued, the label text changes but the
   song-name color stays the same — visual noise avoided. */
/* The × unqueue button — only visible when queue is NOT the default.
   Visibility is controlled by the `hidden` HTML attribute set from JS.
   The [hidden] rule below forces display:none when present — without it,
   our display:inline-flex below would override the HTML attribute. */
/* × button — absolutely positioned top-right of the UP NEXT card.
   More visible than when nested in the labelrow, larger hit target,
   clearly a dismiss affordance. */
.as-eyebrow-upnext {
    position: relative;
    /* Reserve space on the right so the title text doesn't run under
       the × button. 36px ≈ 28px button + 8px breathing room. */
    padding-right: 36px;
}
.as-eyebrow-unqueue[hidden] {
    display: none !important;
}
.as-eyebrow-unqueue {
    position: absolute;
    top: 6px;
    right: 6px;
    width: 28px;
    height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.12);
    color: rgba(255, 255, 255, 0.75);
    font-size: 16px;
    font-weight: 400;
    line-height: 1;
    padding: 0;
    border-radius: 50%;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
    z-index: 2;
}
.as-eyebrow-unqueue:hover,
.as-eyebrow-unqueue:focus-visible {
    background: rgba(191, 255, 0, 0.15);
    border-color: rgba(191, 255, 0, 0.55);
    color: #BFFF00;
    transform: scale(1.08);
    outline: none;
}

/* Title — inside cluster, flex child */
.as-chrome-cluster .entry-title {
    position: static;
    margin: 0;
    padding: 0;
    font-size: clamp(28px, 3.4vw, 48px);
    line-height: 1.2;
    color: #ffffff;
    text-shadow: 0 2px 12px rgba(0,0,0,0.55);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

/* v4.3 alignment fix for desktop.
 *
 * The title in the chrome cluster inherits two external offsets that
 * make its visible first glyph sit ~13px to the right of its container's
 * natural left edge:
 *   1. `body.single-gallery h1.entry-title { padding-left: 1.3vw; ... }`
 *      — injected from an inline stylesheet outside this theme file
 *      (likely a plugin / Customizer output), wins on source order over
 *      our `padding: 0` at line 1536.
 *   2. `body.single-gallery .as-floating-header .entry-title { transform:
 *      translateX(-20px); }` — also from the same external source.
 *
 * Net effect on a 2560px viewport: 1.3vw (≈33px) padding-left combined
 * with the -20px translate shifted the title's first character 13px
 * right of the cluster edge, while the STATION pill directly below sat
 * flush with the cluster edge. User read the pill's green box as
 * "closer to the left" than the title.
 *
 * Fix: neutralize both overrides on the chrome-cluster title with
 * higher specificity + !important. Title then sits at the cluster's
 * natural left edge, pill too, both aligned regardless of viewport
 * width (no vw math or breakpoint-specific magic needed — purely
 * zeroing-out the legacy offsets).
 *
 * Scope limited to `.as-chrome-cluster` so the floating-header's
 * standalone title (when cluster isn't involved) keeps its existing
 * behavior. The two selectors cover both the direct-parent shape
 * (.as-chrome-cluster .entry-title) and the newer wrapped shape
 * (.as-chrome-cluster .as-title-row .entry-title).
 */
html body.single-gallery .as-chrome-cluster .entry-title,
html body.single-gallery .as-chrome-cluster .as-title-row .entry-title {
    padding-left: 0 !important;
    transform: none !important;
}
.as-chrome-cluster .entry-title.as-title-hidden {
    opacity: 0;
}

/* Tiny muted year next to the song title — "Song Name · 1992". Inline with
   the title so it reads as one line; slightly transparent and smaller so it
   doesn't fight the title for attention. Hidden on tight mobile breakpoints
   where the title row is already cramped. */
.as-chrome-cluster .entry-title .as-title-year {
    font-weight: 500;
    font-size: 0.58em;
    letter-spacing: 0.04em;
    color: rgba(255, 255, 255, 0.55);
    margin-left: 0.35em;
    vertical-align: baseline;
    white-space: nowrap;
}
.as-chrome-cluster .entry-title .as-title-year-sep {
    display: inline-block;
    margin-right: 0.25em;
    opacity: 0.8;
}
@media (max-width: 680px) {
    .as-chrome-cluster .entry-title .as-title-year { display: none; }
}

/* =========================================================================
 * TASTE-ENGINE TAUNT — "Have you seen the music video for X by Y?  [Now] [+ Queue]"
 *
 * Bottom-left cluster, under the title. Container is now a <div> with
 * thumb + text + two action buttons. Click Now = immediate nav. Click
 * Queue = save to sessionStorage (consumed on video end), toggles state.
 * ========================================================================= */
/* "More by {Artist}" pill — sits between the h1 title and the taunt.
   Uses the same glassy pill language as the taunt for consistency, but
   with a lime icon since it's a personal-preference action (not a
   recommendation). */
/* Wraps h1 + "More by X" pill so they share a row. The title is
   the anchor (left-aligned); the pill sits right of it, vertically
   centered with the title's last line. Wraps onto a new line if
   the title is very long — still reads fine. */
.as-chrome-cluster .as-title-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px;
    max-width: 100%;
}
.as-chrome-cluster .as-title-row .entry-title {
    margin: 0;
    /* Let h1 keep its existing styling — don't flex-grow it, otherwise
       it pushes the button to the next line on wide viewports. */
}

.as-chrome-cluster .as-more-by-artist {
    position: static;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 7px 14px 7px 12px;
    background: rgba(10, 10, 10, 0.55);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 999px;
    color: rgba(255, 255, 255, 0.9);
    /* v1.6.15 — Mono-caps to match the NP WIDGET blend pill recipe. */
    font: 700 9px/1 var(--alts-mono, 'IBM Plex Mono', monospace);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    cursor: pointer;
    pointer-events: auto;
    max-width: 100%;
    transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
    transform-origin: left center;
}
.as-chrome-cluster .as-more-by-artist i {
    /* v1.5.18 — Inactive icon stays AS green so the chrome reads
       consistently with the rest of the site (AS green is the
       brand accent for affordable-icon state pre-engagement).
       v1.6.17 — Explicit line-height + display so the icon's
       intrinsic line-box doesn't drift the row off-center; mono-
       caps 9px text has line-height 1, the icon needs to match. */
    color: #BFFF00;
    font-size: 13px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    align-self: center;
}
.as-chrome-cluster .as-more-by-artist .as-more-by-artist-text {
    line-height: 1;
    align-self: center;
    display: inline-flex;
    align-items: center;
}
.as-chrome-cluster .as-more-by-artist .as-more-by-artist-label {
    color: rgba(255, 255, 255, 0.65);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    font-size: 10px;
}
.as-chrome-cluster .as-more-by-artist .as-more-by-artist-name {
    color: #ffffff;
    font-weight: 700;
}
.as-chrome-cluster .as-more-by-artist:hover,
.as-chrome-cluster .as-more-by-artist:focus-visible {
    background: rgba(10, 10, 10, 0.85);
    border-color: color-mix(in srgb, var(--blend-color, #BFFF00) 40%, transparent);
    transform: scale(1.035);
    outline: none;
}
/* v1.5.17 — Active "is-queued" state now uses the per-term blend color
   instead of hardcoded AS green. The button represents a single-scope
   artist blend, so the highlight should match that blend's palette
   color (Spike Jonze → mint, Bad Omens → red, etc). Falls back to AS
   green if --blend-color isn't set (very early in page lifecycle). */
.as-chrome-cluster .as-more-by-artist.is-queued {
    background: var(--blend-color, #BFFF00);
    border-color: var(--blend-color, #BFFF00);
    color: #0a0f0a;
    text-shadow: none;
}
.as-chrome-cluster .as-more-by-artist.is-queued i {
    color: #0a0f0a;
}
.as-chrome-cluster .as-more-by-artist.is-queued .as-more-by-artist-label {
    color: rgba(10, 15, 10, 0.7);
}
.as-chrome-cluster .as-more-by-artist.is-queued .as-more-by-artist-name {
    color: #0a0f0a;
    text-shadow: none;
}
.as-chrome-cluster .as-more-by-artist.is-queued:hover,
.as-chrome-cluster .as-more-by-artist.is-queued:focus-visible {
    background: color-mix(in srgb, var(--blend-color, #BFFF00) 88%, #000);
    border-color: color-mix(in srgb, var(--blend-color, #BFFF00) 88%, #000);
}

.as-chrome-cluster .as-taunt {
    position: static;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 6px 8px 6px 6px;
    background: rgba(10, 10, 10, 0.55);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 999px;
    color: rgba(255, 255, 255, 0.78);
    font-size: 12px;
    line-height: 1;
    pointer-events: auto;
    max-width: 100%;
    transition: background 0.2s ease, border-color 0.2s ease;
}

/* v1.0.2 — Taunt rail moved into NP rail (see guide.css for styles).
   Removed the .as-chrome-cluster placement — single-gallery keeps
   the singleton taunt only. */
.as-chrome-cluster .as-taunt:hover,
.as-chrome-cluster .as-taunt:focus-within {
    background: rgba(10, 10, 10, 0.85);
    border-color: rgba(191, 255, 0, 0.25);
}
.as-chrome-cluster .as-taunt-thumb {
    width: 28px !important;
    height: 28px !important;
    border-radius: 50%;
    object-fit: cover;
    flex: 0 0 auto;
    display: block;
    background: #000;
    max-width: none !important;
    max-height: none !important;
    transition: transform 0.2s ease;
}
.as-chrome-cluster .as-taunt:hover .as-taunt-thumb {
    transform: scale(1.08);
}
.as-chrome-cluster .as-taunt-text {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    padding-right: 4px;
}
.as-chrome-cluster .as-taunt-artist {
    color: #BFFF00;
    font-weight: 600;
}
.as-chrome-cluster .as-taunt-song {
    color: #ffffff;
    font-weight: 600;
    font-style: italic;
}

/* Taunt buttons — tight, right edge of pill */
.as-chrome-cluster .as-taunt-actions {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex: 0 0 auto;
    margin-left: 2px;
}
.as-chrome-cluster .as-taunt-btn {
    appearance: none;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.12);
    color: rgba(255, 255, 255, 0.82);
    font-size: 11px;
    font-weight: 600;
    font-family: inherit;
    letter-spacing: 0.04em;
    padding: 5px 10px;
    border-radius: 999px;
    cursor: pointer;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.1s ease;
}
.as-chrome-cluster .as-taunt-btn i {
    font-size: 9px;
}
.as-chrome-cluster .as-taunt-btn:hover,
.as-chrome-cluster .as-taunt-btn:focus {
    background: rgba(191, 255, 0, 0.12);
    border-color: rgba(191, 255, 0, 0.5);
    color: #BFFF00;
    outline: none;
}
.as-chrome-cluster .as-taunt-btn:active {
    transform: scale(0.96);
}
/* Queue button in queued state — persistent green */
.as-chrome-cluster .as-taunt-btn.is-queued {
    background: rgba(191, 255, 0, 0.18);
    border-color: rgba(191, 255, 0, 0.6);
    color: #BFFF00;
}

/* v1.5.8.5 — Taunt queue button "held by repeat" state. The user has
   queued a song AND turned on repeat — the queue is parked until repeat
   finishes. Visually softer than .is-queued: muted accent, no fill,
   slightly faded text. Communicates "queued but not next" without
   removing the visual association with the queue family. */
.as-chrome-cluster .as-taunt-btn.is-held-by-repeat {
    background: rgba(191, 255, 0, 0.06);
    border-color: rgba(191, 255, 0, 0.18);
    color: rgba(191, 255, 0, 0.55);
    box-shadow: none;
}

/* ── AltSounds Premiere badge (on the video page, above the title) ──────
   Shows when the current video is an active editor-flagged premiere. AS-green
   pill so it reads as the brand "this is a premiere" cue. */
.alts-premiere-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: #BFFF00;
    color: #0a0b0a;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    text-shadow: none;
    padding: 4px 10px;
    border-radius: 6px;
    line-height: 1;
    box-shadow: 0 2px 12px rgba(191, 255, 0, 0.28);
}
.alts-premiere-badge i { font-size: 0.92em; }
/* Desktop: above the title in the chrome cluster. */
.as-chrome-cluster .alts-premiere-badge { margin: 0 0 10px; }
/* Mobile: eyebrow atop the NP row (above the artist line), left-aligned. */
.alts-mobile-nprow .alts-premiere-badge { align-self: flex-start; margin: 0 0 7px; font-size: 10px; padding: 3px 8px; }

/* ── PREMIERE taunt (v1.6.5) ───────────────────────────────────────────
   An editor-flagged premiere riding in the taunt slot. PREMIERE badge +
   an optional band-defined CTA button (3rd action). The badge is the only
   colour cue; keeps the card legible over bright video. */
.as-chrome-cluster .as-taunt-premiere-badge {
    display: inline-block;
    align-self: center;
    background: #BFFF00;
    color: #0a0b0a;
    font-size: 9px;
    font-weight: 800;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    text-shadow: none;
    padding: 3px 7px;
    border-radius: 5px;
    margin-right: 6px;
    line-height: 1;
    flex: 0 0 auto;
}
/* The band CTA — visually distinct from Play/Queue: filled AS green so it
   reads as the "do something for the artist" action. */
.as-chrome-cluster .as-taunt-btn.as-taunt-cta {
    background: #BFFF00;
    border-color: #BFFF00;
    color: #0a0b0a;
    text-decoration: none;
    font-weight: 700;
    text-shadow: none;
}
.as-chrome-cluster .as-taunt-btn.as-taunt-cta:hover,
.as-chrome-cluster .as-taunt-btn.as-taunt-cta:focus {
    background: #d4ff4d;
    border-color: #d4ff4d;
    color: #0a0b0a;
}

/* Reduced motion: drop the transform, keep opacity only */
@media (prefers-reduced-motion: reduce) {
    .as-chrome-cluster,
    body.single-gallery.ui-hidden .as-chrome-cluster,
    body.single-gallery.as-cursor-hidden .as-chrome-cluster,
    body.single-gallery.as-modal-open .as-chrome-cluster,
    .as-chrome-eyebrow,
    body.single-gallery.ui-hidden .as-chrome-eyebrow,
    body.single-gallery.as-cursor-hidden .as-chrome-eyebrow,
    body.single-gallery.as-modal-open .as-chrome-eyebrow {
        transform: none !important;
        transition: opacity 0.35s ease !important;
    }
}

/* ===========================================================================
 * INFO BUTTON — override positions it near the title (bottom-left cluster)
 * instead of the original bottom-right corner. All JS wiring, breathing
 * animations, and modal triggers remain intact — this is pure reposition.
 * =========================================================================== */
/* "I" info toggle — top-right, symmetric to the logo */
body.single-gallery .video-info-toggle {
    position: absolute !important;
    /* Top-right — symmetric with the logo top-left. The bottom-right
       corner now belongs to the UP NEXT eyebrow card.
       Higher specificity (body.single-gallery prefix) + !important to beat
       the legacy "position: fixed; bottom: 7vw; right: 1vw" rule that
       comes from post-video.inc.php's inline stylesheet. */
    top: calc(var(--as-letterbox, 84px) + var(--as-chrome-pad-y)) !important;
    right: var(--as-chrome-pad-x-right) !important;
    bottom: auto !important;
    left: auto !important;

    /* Fluid sizing — min 56px (small screens), max 80px (desktop), ideal 5vw.
       Keeps the button feeling like a consistent UI weight at any viewport. */
    width:  clamp(56px, 5vw, 80px);
    height: clamp(56px, 5vw, 80px);
    font-size: clamp(24px, 2.2vw, 34px);

    padding: 0; margin: 0;
    background: rgba(15, 15, 15, 0.55);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: 1px solid rgba(255,255,255,0.22);
    border-radius: 50%;
    color: #ffffff;
    cursor: pointer;
    pointer-events: auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.2s ease, background 0.2s ease, border-color 0.2s ease;
    line-height: 1;
}
.video-info-toggle i {
    color: #ffffff;
    line-height: 1;
}
.video-info-toggle:hover {
    background: rgba(191, 255, 0, 0.18);
    border-color: #BFFF00;
    transform: scale(1.06);
}
.video-info-toggle:hover i {
    color: #BFFF00;
}

/* ---- 3. BREATHING PULSE on the "I" button ----
 * Two modes — both ensure the button always has SOME attention draw, but
 * calibrated to experience level:
 *
 *   STRONG ONBOARDING PULSE (.as-breathing, without .as-breathing-seen):
 *     2.4s cycle, ring grows to 1.45x, opacity 0→0.65→0
 *     First visit only — teaches new users where the primary action lives
 *
 *   AMBIENT PERSISTENT PULSE (.as-breathing-seen):
 *     5s cycle, ring grows to 1.25x, opacity 0→0.3→0
 *     Much subtler — runs forever so experienced users don't forget the
 *     button is there after 100+ videos. Like a slow heartbeat.
 *
 *   Both pause in cinema mode (.ui-hidden or .as-cursor-hidden on body)
 *   and while the modal is actively open (.active on the button).
 */
.video-info-toggle.as-breathing::before {
    content: '';
    position: absolute;
    inset: -4px;
    border-radius: 50%;
    border: 2px solid #BFFF00;
    opacity: 0;
    pointer-events: none;
    animation: asBreatheStrong 2.4s ease-out infinite;
}
@keyframes asBreatheStrong {
    0%   { transform: scale(0.95); opacity: 0.0; }
    25%  { opacity: 0.65; }
    100% { transform: scale(1.45); opacity: 0.0; }
}

/* Returning users — strong pulse swaps to the ambient one */
.video-info-toggle.as-breathing.as-breathing-seen::before {
    animation: asBreatheAmbient 5s ease-in-out infinite;
    border-width: 1px;
}
@keyframes asBreatheAmbient {
    0%, 100% { transform: scale(0.98); opacity: 0.0; }
    50%      { transform: scale(1.18); opacity: 0.30; }
}

/* Completely suppress pulses while modal is open (.active) — we don't
   need to draw attention to something the user is currently using. */
.video-info-toggle.active::before {
    animation: none;
    opacity: 0;
}

/* Pause both pulses in cinema mode — no point breathing when chrome is hidden */
body.single-gallery.ui-hidden .video-info-toggle.as-breathing::before,
body.single-gallery.as-cursor-hidden .video-info-toggle.as-breathing::before {
    animation-play-state: paused;
}

/* Info button fades out with the rest of the chrome in cinema mode.
   Logo is the ONLY thing that stays visible (brand anchor). Cursor-hidden
   doesn't fade the button — just ui-hidden does, so users who move their
   mouse bring it back along with the rest of the chrome.
   v1.5.8.4 — :not(.as-modal-open) carve-out so the UFO stays visible
   while the info modal is open. The user is reading the modal; they may
   want to jump from info → Mothership without first moving their mouse
   to wake the chrome up. The cinema fade only applies in actual cinema
   (no modal stacked on top). */
body.single-gallery.ui-hidden:not(.as-modal-open) .video-info-toggle {
    opacity: 0 !important;
    pointer-events: none;
    transition: opacity 0.55s ease !important;
}
/* Hide info button when its modal is already open — the button IS the
   trigger, and an open modal means the info is already being shown.
   v1.5.8.2 — UPDATED. The top-right button is now a Mothership opener,
   not an info-modal trigger. Hide it only when the Mothership panel
   is open (it'd be redundant), not when the info modal is open. */
body.single-gallery.alts-guide-open .video-info-toggle {
    opacity: 0 !important;
    pointer-events: none !important;
    transition: opacity 0.25s ease !important;
}

/* Reduced-motion: no pulse at all (accessibility) */
@media (prefers-reduced-motion: reduce) {
    .video-info-toggle::before { animation: none !important; }
}

/* ---- 4. CURSOR AUTO-HIDE ----
   After .as-cursor-hidden is added to body (by JS, 3s of no movement),
   the cursor disappears over plain page surface. But interactive
   elements (links, buttons, form controls) should ALWAYS show a
   pointer so users can click them even in cinema mode. Movement
   removes the class. Modal-open forces the cursor visible regardless.
*/
body.single-gallery.as-cursor-hidden,
body.single-gallery.as-cursor-hidden #content,
body.single-gallery.as-cursor-hidden .as-floating-header {
    cursor: none;
}
/* Interactive elements: always get a pointer, even in cursor-hidden mode */
body.single-gallery.as-cursor-hidden a,
body.single-gallery.as-cursor-hidden button,
body.single-gallery.as-cursor-hidden input,
body.single-gallery.as-cursor-hidden select,
body.single-gallery.as-cursor-hidden textarea,
body.single-gallery.as-cursor-hidden [role="button"],
body.single-gallery.as-cursor-hidden .video-info-toggle,
body.single-gallery.as-cursor-hidden .as-chrome-logo-link,
body.single-gallery.as-cursor-hidden .as-chrome-logo-link img {
    cursor: pointer !important;
}
/* When modal is open, show normal cursor on the modal surface and
   pointer on interactive elements. */
body.single-gallery.as-modal-open { cursor: auto !important; }
body.single-gallery.as-modal-open a,
body.single-gallery.as-modal-open button,
body.single-gallery.as-modal-open input,
body.single-gallery.as-modal-open select,
body.single-gallery.as-modal-open textarea,
body.single-gallery.as-modal-open [role="button"] {
    cursor: pointer !important;
}

@media (min-width: 769px) {
    /* Retain the old .ui-hidden behavior (cinema chrome fadeout).
       Same interactive-pointer carve-out applies. */
    /* Cursor disappears whenever chrome is ui-hidden. Extend to page
   + main content so the cursor hides over ALL non-interactive surfaces,
   not just body. Users asked for cursor to hide with chrome fadeout. */
body.single-gallery.ui-hidden:not(.as-modal-open),
body.single-gallery.ui-hidden:not(.as-modal-open) #page,
body.single-gallery.ui-hidden:not(.as-modal-open) #content,
body.single-gallery.ui-hidden:not(.as-modal-open) .as-floating-header,
body.single-gallery.ui-hidden:not(.as-modal-open) iframe,
body.single-gallery.ui-hidden:not(.as-modal-open) .entry-video,
body.single-gallery.ui-hidden:not(.as-modal-open) div {
    cursor: none !important;
}
    body.single-gallery.ui-hidden:not(.as-modal-open) a,
    body.single-gallery.ui-hidden:not(.as-modal-open) button,
    body.single-gallery.ui-hidden:not(.as-modal-open) input,
    body.single-gallery.ui-hidden:not(.as-modal-open) [role="button"],
    body.single-gallery.ui-hidden:not(.as-modal-open) .video-info-toggle,
    body.single-gallery.ui-hidden:not(.as-modal-open) .as-chrome-logo-link,
    body.single-gallery.ui-hidden:not(.as-modal-open) .as-chrome-logo-link img {
        cursor: pointer !important;
    }
}

/* ============================================================================
 * 5. INFO MODAL — backdrop + scroll container
 *
 * Two-layer structure:
 *   .video-info-wrapper  → full-viewport, pointer-events pass-through
 *   .video-info-overlay  → the actual dim/blur backdrop (captures clicks,
 *                          click-outside-to-close)
 *
 * Hidden by default. Becomes visible when .active is added to .video-info-overlay.
 * Entrance animation: backdrop fades (0.2s) + content slides up (0.35s).
 * ============================================================================ */

.video-info-wrapper {
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    /* No z-index on the wrapper — we want its children (.overlay below the
       logo, .content above the logo) to participate in the parent stacking
       context rather than be capped inside a wrapper-level context. This is
       what lets the logo poke through the blur backdrop while the modal
       content card still covers the logo's corner when it's wide enough. */
    pointer-events: none;
}
/* When logged in with the WP admin bar visible, shift the modal wrapper
   down 32px so the modal centers inside the actually-visible viewport
   area (below the admin bar). Public visitors are unaffected. */
body.admin-bar .video-info-wrapper {
    top: 32px;
}
@media screen and (max-width: 782px) {
    body.admin-bar .video-info-wrapper { top: 46px; }
}

.video-info-overlay {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    max-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5vh 10px;
    pointer-events: none;
    opacity: 0;
    background: rgba(8, 10, 10, 0.72);
    backdrop-filter: blur(24px) saturate(1.1);
    -webkit-backdrop-filter: blur(24px) saturate(1.1);
    transition: opacity 0.2s ease-out;
    overflow: hidden;
    box-sizing: border-box;
    z-index: 1500;   /* BELOW the logo (z:2500) — blur backdrop can dim but not cover the logo */
}

.video-info-overlay.active {
    opacity: 1;
    pointer-events: auto;
}

/* ============================================================================
 * 6. MODAL × CLOSE BUTTON — top-right of hero
 *
 * The only chrome element on the modal. Same visual language as the page's
 * "I" button (round, dark glassy, neon on hover).
 * ============================================================================ */

.video-info-content .as-modal-close {
    /* Absolute positioning inside .video-info-content (which is position:
       relative). Sits in the modal's top-right corner with generous padding
       from the edge. z-index forces it above all other modal content and
       the hero's blurred backdrop pseudo-elements. */
    position: absolute !important;
    top: 20px !important;
    right: 20px !important;
    left: auto !important;
    bottom: auto !important;
    width: 44px;
    height: 44px;
    padding: 0;
    background: rgba(10, 11, 10, 0.75);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 50%;
    color: #ffffff;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
    z-index: 100 !important;
    transition: transform 0.2s ease, background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
    pointer-events: auto;
}
.video-info-content .as-modal-close:hover {
    background: rgba(191, 255, 0, 0.18);
    border-color: #BFFF00;
    color: #BFFF00;
    transform: scale(1.08) rotate(90deg);
}

/* ============================================================================
 * 7. MODAL CONTENT SHELL
 *
 * 80vh max height (video page never scrolls; modal has internal scroll).
 * Dark container, subtle neon-tinted inner glow.
 * Entry animation: slide-up + fade.
 * ============================================================================ */

.video-info-overlay .video-info-content {
    position: relative;
    z-index: 3500;   /* ABOVE the logo (z:2500) — modal card covers logo when wide enough */
    width: 100%;
    max-width: 1100px;
    max-height: 80vh;  /* hard cap at 80% of viewport height, per user spec */
    margin: 0;
    background: #0a0b0a;
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 16px;
    box-shadow:
        0 24px 72px rgba(0,0,0,0.7),
        0 0 0 1px rgba(191, 255, 0, 0.05) inset;
    overflow-x: hidden;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    transform: translateY(20px) scale(0.985);
    opacity: 0;
    transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1),
                opacity 0.25s ease-out;
    scrollbar-width: thin;
    scrollbar-color: rgba(191, 255, 0, 0.3) transparent;
    /* isolate so ::before/::after don't bleed up to the overlay */
    isolation: isolate;
}
/* Full-modal blurred backdrop — the poster image, softened, saturating
   the whole modal with that song's color. Absolute-positioned to fill
   the entire scroll area regardless of content height. */
.video-info-overlay .video-info-content::before {
    content: '';
    position: absolute;
    inset: 0;
    background-image: var(--alts-hero-bg, none);
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    filter: blur(44px) brightness(0.55) saturate(1.15);
    transform: scale(1.15);
    z-index: 0;
    pointer-events: none;
}
/* Uniform dark tint overlay — consistent ambient darkening across the
   whole modal for text/tile contrast. No gradient that could create
   visible banding. */
.video-info-overlay .video-info-content::after {
    content: '';
    position: absolute;
    inset: 0;
    background: rgba(10, 10, 10, 0.45);
    z-index: 0;
    pointer-events: none;
}
/* All direct children of .video-info-content must sit above the backdrop.
   Exception: .as-modal-close uses absolute positioning to anchor top-right. */
.video-info-overlay .video-info-content > *:not(.as-modal-close) {
    position: relative;
    z-index: 1;
}
.video-info-overlay .video-info-content::-webkit-scrollbar {
    width: 8px;
}
.video-info-overlay .video-info-content::-webkit-scrollbar-track {
    background: transparent;
}
.video-info-overlay .video-info-content::-webkit-scrollbar-thumb {
    background: rgba(191, 255, 0, 0.25);
    border-radius: 4px;
}
.video-info-overlay .video-info-content::-webkit-scrollbar-thumb:hover {
    background: rgba(191, 255, 0, 0.45);
}
.video-info-overlay.active .video-info-content {
    transform: translateY(0) scale(1);
    opacity: 1;
}

/* ============================================================================
 * 8. HERO OVERRIDES — when .alts-channel-hero is inside the modal
 *
 * The channel-page hero CSS does almost all the work for us. We only
 * override a few things for the modal context:
 *   - Tighter min-height (modal has a height budget)
 *   - No hero top/bottom rounding (we clip it via .video-info-content)
 *   - Title can drop a bit if it's a long video name
 * ============================================================================ */

.video-info-content .alts-channel-hero.as-modal-hero-in-modal {
    padding: 44px 36px 28px !important;
    flex: 0 0 auto;
    border-top-left-radius: 16px;
    border-top-right-radius: 16px;
}
.as-modal-hero-in-modal .alts-channel-hero-inner {
    max-width: none;
    width: 100%;
}

/* (Title sizing is handled in .video-info-content .alts-channel-title below) */

/* Eyebrow link (artist name). Matches channel eyebrow style but
   hoverable since it's a link. */
.as-modal-hero-in-modal .alts-channel-eyebrow {
    margin-bottom: 14px;
}
.as-modal-eyebrow-link {
    color: inherit !important;
    text-decoration: none !important;
    border-bottom: 1px solid transparent;
    transition: border-color 0.2s ease;
    padding-bottom: 1px;
}
.as-modal-eyebrow-link:hover,
.as-modal-eyebrow-link:focus {
    border-bottom-color: currentColor;
}

/* Meta row in modal: smaller than channel, but same typography. */
.as-modal-hero-in-modal .as-modal-meta {
    margin-bottom: 22px;
    font-size: 13px;
}
/* Hide empty meta items (YT stats not populated yet) to avoid leading
   separators. Adjacent-sibling logic handles the separator hiding. */
.as-modal-meta > span:empty { display: none; }
.as-modal-meta > span:empty + .alts-channel-meta-sep { display: none; }

/* "Directed by" appended inside the meta row. Slightly muted vs. the
   other meta items to keep the numbers (year/duration/views/likes)
   as the primary scan targets. */
.as-meta-directed {
    color: rgba(255, 255, 255, 0.85);
}
.as-meta-directed a,
.as-modal-directed-link {
    color: rgba(255, 255, 255, 1) !important;
    text-decoration: none !important;
    border-bottom: none;   /* v6.x — drop the underline on the director link */
    transition: color 0.2s ease;
}
.as-meta-directed a:hover,
.as-modal-directed-link:hover {
    color: var(--alts-accent, #BFFF00) !important;
}
/* v6.x — Year + decade links in the modal meta row (tax-hop to Mothership). */
.video-info-content .as-modal-meta-link {
    color: inherit;
    text-decoration: none !important;
    border-bottom: none;
    transition: color 0.2s ease;
    cursor: pointer;
}
.video-info-content .as-modal-meta-link:hover {
    color: var(--alts-accent, #BFFF00) !important;
}
/* v6.x — calendar (year) + time-travel (decade) glyphs stay AS-green. */
.video-info-content .as-modal-meta-link .as-modal-meta-ico {
    color: var(--alts-accent, #BFFF00);
    margin-right: 5px;
    font-size: 0.92em;
}

/* Actions row: play button only now (grey channel button removed). */
.as-modal-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin-top: 8px;
    margin-bottom: 14px;
}

/* Pills row sits between the meta row and description.
   Each pill plays a random video from that channel. */
.as-modal-pills-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    justify-content: center;
    margin: 0 auto 18px;
    max-width: 860px;
}

/* Description in hero — full content, no truncation.
   This is the only place users see full song info, so we show it all.
   Constrained by max-width for readability; uses the hero's bg-blur
   for legibility over the thumbnail. */
.as-modal-description {
    color: rgba(255, 255, 255, 0.82);
    font-size: 14px;
    line-height: 1.55;
    max-width: 780px;
    margin: 0 auto 18px;
    padding: 0 25px;
    text-align: left;
    text-shadow: 0 2px 24px rgba(0, 0, 0, 0.7);
}
.as-modal-description p {
    margin: 0 0 8px !important;
    color: inherit;
    font-size: inherit;
    line-height: inherit;
}
.as-modal-description p:last-child { margin-bottom: 0 !important; }
.as-modal-description a {
    color: #BFFF00 !important;
    text-decoration: none;
}
.as-modal-description a:hover {
    text-decoration: underline;
}

/* (Play button sizing is handled in the base .alts-channel-play-btn rule
   inside the CHANNEL-PAGE CSS block further below — see that section.) */

/* ============================================================================
 * 9. MODAL BODY — YMAL container
 *
 * No longer scrolls internally — the whole .video-info-content scrolls now.
 * Transparent bg so the blurred backdrop below shows through.
 * ============================================================================ */

.as-modal-body {
    flex: 1 1 auto;
    padding: 18px 36px 24px;
    background: transparent;
}

/* ============================================================================
 * 10. COLLAPSIBLE SECTIONS (About this video)
 *
 * Chevron rotation on open (matches channel "About" section behavior).
 * Content is always in the DOM for SEO; max-height transition reveals it.
 * ============================================================================ */

.as-modal-section {
    border-top: 1px solid rgba(255,255,255,0.08);
    margin: 0;
}
.as-modal-section:first-child { border-top: 0; }

.as-modal-section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    background: transparent;
    border: 0;
    padding: 18px 0;
    color: #ffffff;
    font: 500 14px/1 Montserrat, sans-serif;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    cursor: pointer;
    transition: color 0.2s ease;
}
.as-modal-section-header:hover { color: #BFFF00; }

.as-modal-section-title { flex: 1 1 auto; text-align: left; }

.as-modal-chevron {
    font-size: 12px;
    transition: transform 0.25s ease;
    color: rgba(255,255,255,0.55);
}
.as-modal-section-header[aria-expanded="true"] .as-modal-chevron {
    transform: rotate(180deg);
    color: #BFFF00;
}

.as-modal-section-body {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.35s ease;
    color: rgba(255,255,255,0.85);
    font: 400 14px/1.55 Montserrat, sans-serif;
}
.as-modal-section-body.as-expanded {
    max-height: 1000px; /* generous; real height capped by modal scroll */
    padding-bottom: 18px;
}

.as-modal-about-text p { margin: 0 0 10px; }
.as-modal-about-text a { color: #BFFF00; }

.as-modal-uploaded {
    margin: 8px 0 0;
    font-size: 12px;
    color: rgba(255,255,255,0.55);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.as-modal-uploaded:empty { display: none; }

/* ============================================================================
 * 11. YOU MIGHT ALSO LIKE — channel-tile cards + refresh button
 *
 * Uses the .alts-channel-tile markup/classes so visual language matches
 * channel pages. A .as-modal-tile modifier just tightens sizing for the
 * modal's narrower grid.
 * ============================================================================ */

.as-modal-ymal {
    /* No top border — cleaner separation comes from padding alone. */
    padding-top: 8px;
}

.as-modal-ymal-title {
    margin: 0 0 20px;  /* more breathing room before the tiles */
    color: #ffffff;
    font: 500 14px/1 Montserrat, sans-serif;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.as-modal-ymal-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 24px;  /* more space between tiles (was 18px) */
    padding-bottom: 8px;  /* room below last row of tiles */
    transition: opacity 0.2s ease;
}
.as-modal-ymal-grid.as-refreshing { opacity: 0.4; }

/* Channel-tile styling is inherited from taxonomy.php (enqueued globally).
   We don't redefine any .alts-channel-tile or .alts-tile-* rules here —
   the modal uses the exact same visual language as channel pages. */

/* ============================================================================
 * 12. KEYBOARD SHORTCUTS STRIP — bottom bar, always visible, muted
 * ============================================================================ */

.as-modal-shortcuts {
    flex: 0 0 auto;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 4px 12px;
    padding: 12px 20px;
    border-top: 1px solid rgba(255,255,255,0.06);
    background: rgba(255,255,255,0.02);
    font: 400 11px/1 Montserrat, sans-serif;
    color: rgba(255,255,255,0.45);
    letter-spacing: 0.02em;
}
.as-kbd-group {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    white-space: nowrap;
}
.as-modal-shortcuts kbd {
    display: inline-block;
    padding: 2px 6px;
    margin: 0 1px;
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: 4px;
    font: 500 10px/1 "SF Mono", Menlo, Consolas, monospace;
    color: rgba(255,255,255,0.75);
    letter-spacing: 0.02em;
    vertical-align: middle;
}
.as-kbd-sep { color: rgba(255,255,255,0.2); }

/* ============================================================================
 * 13. RESPONSIVE (mobile)
 * ============================================================================ */

@media (max-width: 768px) {
    /* Note: chrome padding vars (--as-chrome-pad-x/y) and logo size are now
       fluid via clamp() in :root — they scale smoothly down without needing
       a hard breakpoint override. */

    .as-floating-header .entry-title {
        max-width: calc(100vw - 100px);
    }

    .as-floating-header .as-taunt {
        padding: 4px 10px 4px 4px;
        font-size: 11px;
        gap: 8px;
        max-width: calc(100vw - 60px);
    }
    .as-floating-header .as-taunt-thumb {
        width: 24px !important;
        height: 24px !important;
    }

    .video-info-toggle {
        width: 52px; height: 52px;
        font-size: 22px;
    }

    .video-info-overlay { padding: 2vh 12px; }
    .video-info-overlay .video-info-content {
        max-height: 90vh;
        border-radius: 14px;
    }

    /* Close + burger: sit inside hero top-right/left, tighter padding */
    .as-modal-close,
    .as-modal-burger {
        top: 10px;
        width: 38px;
        height: 38px;
    }
    .as-modal-close  { right: 10px; }
    .as-modal-burger { left:  10px; }

    /* Hero in modal: tighter on mobile */
    .as-modal-hero-in-modal {
        min-height: 260px;
        max-height: 60vh;
        padding: 56px 20px 30px;
    }
    .as-modal-hero-in-modal .as-modal-title-hero {
        font-size: clamp(26px, 8vw, 40px);
    }

    .as-modal-body { padding: 18px 20px 16px; }

    /* YMAL: single column on mobile. */
    .as-modal-ymal-grid {
        grid-template-columns: 1fr;
        gap: 14px;
    }

    .as-modal-shortcuts {
        font-size: 10px;
        padding: 10px 14px;
        gap: 3px 8px;
    }
    .as-modal-shortcuts kbd { font-size: 9px; padding: 1px 4px; }
}

/* ============================================================================
 * CHANNEL-PAGE CSS — imported into the modal for styling parity
 *
 * These rules come straight from taxonomy.php. Without them, the channel
 * classes (.alts-channel-hero, .alts-channel-title, .alts-channel-play-btn,
 * .alts-decade-pill, .alts-channel-tile, .alts-tile-*) have no styling
 * because taxonomy.php's CSS is only loaded on taxonomy archive pages.
 *
 * All rules are scoped under .video-info-content so they don't leak out
 * to the theme's other pages. The root CSS variables are re-declared on
 * the modal container itself.
 * ============================================================================ */

.video-info-content {
    --alts-accent: #BFFF00;
    --alts-accent-dark: #9AE600;
    --alts-text-primary: #fff;
    --alts-text-secondary: #d4d4d4;
    --alts-text-muted: #9a9a9a;
    --alts-surface: #0a0a0a;
    --alts-surface-raised: #141414;
    --alts-border-subtle: rgba(255, 255, 255, 0.08);
    --alts-border-strong: rgba(255, 255, 255, 0.22);
    color: #fff;
}

/* -------- HERO -------- */
.video-info-content .alts-channel-hero {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 44px 24px 24px;
    overflow: hidden;
    background-color: transparent;
}
/* Hero-specific top vignette: adds a subtle darker band across the top of
   the modal for depth and "poster" feel. Only affects the top ~50% of the
   hero and fades to transparent, so it doesn't fight the full-modal
   backdrop or create the padding illusion of before. */
.video-info-content .alts-channel-hero::after {
    content: '';
    position: absolute;
    inset: 0;
    background:
        linear-gradient(180deg, rgba(0,0,0,0.35) 0%, rgba(0,0,0,0.15) 35%, rgba(0,0,0,0) 70%);
    pointer-events: none;
    z-index: 1;
}
.video-info-content .alts-channel-hero-inner {
    position: relative;
    z-index: 2;
    max-width: 860px;
    margin: 0 auto;
    text-align: center;
}

/* Eyebrow: neon accent bar + label, links welcomed */
.video-info-content .alts-channel-eyebrow {
    color: var(--alts-accent);
    font-size: 11px;
    letter-spacing: 3px;
    text-transform: uppercase;
    margin: 0 0 20px;
    font-weight: 700;
    display: inline-block;
    position: relative;
    padding: 0 16px;
}
.video-info-content .alts-channel-eyebrow::before,
.video-info-content .alts-channel-eyebrow::after {
    content: '';
    position: absolute;
    top: 50%;
    width: 20px;
    height: 1px;
    background: var(--alts-accent);
    opacity: 0.5;
}
.video-info-content .alts-channel-eyebrow::before { right: 100%; }
.video-info-content .alts-channel-eyebrow::after  { left: 100%; }
.video-info-content .alts-channel-eyebrow a,
.video-info-content .as-modal-eyebrow-link {
    color: inherit !important;
    text-decoration: none !important;
    border-bottom: 1px solid transparent;
    transition: border-color 0.2s ease;
    padding-bottom: 1px;
}
.video-info-content .alts-channel-eyebrow a:hover,
.video-info-content .as-modal-eyebrow-link:hover {
    border-bottom-color: currentColor;
}
/* Em dash separator between artist and genre in the eyebrow */
.video-info-content .as-modal-eyebrow-sep {
    margin: 0 6px;
    opacity: 0.55;
}

/* Big title — smaller and less dominant on a modal vs. a full channel page */
.video-info-content .alts-channel-title {
    color: var(--alts-text-primary) !important;
    font-size: clamp(22px, 2.8vw, 34px);
    line-height: 1.1;
    margin: 0 0 12px;
    padding: 0 !important;
    font-weight: 700;
    letter-spacing: -0.02em;
    text-shadow: 0 4px 40px rgba(0, 0, 0, 0.9);
}

/* Meta row */
.video-info-content .alts-channel-meta {
    color: var(--alts-text-secondary);
    font-size: 13px;
    margin: 0 0 28px;
    display: inline-flex;
    gap: 12px;
    align-items: center;
    flex-wrap: wrap;
    justify-content: center;
    letter-spacing: 0.02em;
}
.video-info-content .alts-channel-meta > span { white-space: nowrap; }
.video-info-content .alts-channel-meta-sep {
    color: var(--alts-accent);
    opacity: 0.6;
    font-weight: 700;
}
/* Hide empty meta items + their trailing separators */
.video-info-content .alts-channel-meta > span:empty { display: none; }
.video-info-content .alts-channel-meta > span:empty + .alts-channel-meta-sep { display: none; }

.video-info-content .alts-channel-hero-actions {
    margin-top: 8px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 14px 10px;
}

/* -------- PLAY BUTTON (primary CTA) -------- */
.video-info-content .alts-channel-play-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: var(--alts-accent) !important;
    color: #000 !important;
    padding: 10px 20px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    text-decoration: none !important;
    transition: transform 0.18s ease, background 0.18s ease, box-shadow 0.18s ease;
    border: none;
    cursor: pointer;
    box-shadow:
        0 0 0 1px rgba(191, 255, 0, 0.2),
        0 6px 24px rgba(191, 255, 0, 0.2);
}
.video-info-content .alts-channel-play-btn:hover,
.video-info-content .alts-channel-play-btn:focus {
    background: #d4ff30 !important;
    transform: scale(1.03);
    color: #000 !important;
    text-decoration: none !important;
    box-shadow:
        0 0 0 1px rgba(191, 255, 0, 0.4),
        0 8px 32px rgba(191, 255, 0, 0.35);
}
.video-info-content .alts-channel-play-btn-icon {
    display: inline-flex;
    align-items: center;
}
.video-info-content .alts-channel-play-btn-icon svg { width: 14px; height: 14px; }

/* -------- PILLS -------- */
.video-info-content .alts-decade-pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 11px 4px 8px;
    background: rgba(191, 255, 0, 0.1);
    color: #bbff00 !important;
    border: 1px solid rgba(191, 255, 0, 0.3);
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-decoration: none !important;
    line-height: 1;
    transition: background 0.15s ease, color 0.15s ease,
                border-color 0.15s ease, transform 0.15s ease;
    white-space: nowrap;
}
.video-info-content .alts-decade-pill:hover,
.video-info-content .alts-decade-pill:focus {
    background: #bbff00;
    color: #000 !important;
    border-color: #bbff00;
    transform: translateY(-1px);
    outline: none;
}
.video-info-content .alts-decade-pill-icon {
    flex-shrink: 0;
    opacity: 0.85;
    transition: transform 0.15s ease, opacity 0.15s ease;
}
.video-info-content .alts-decade-pill:hover .alts-decade-pill-icon {
    transform: scale(1.15);
    opacity: 1;
}

/* -------- CHANNEL TILES (You Might Also Like) -------- */
.video-info-content .alts-channel-tile {
    background: var(--alts-surface-raised);
    border-radius: 14px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    /* No transform/box-shadow on the tile itself — image + play-btn
       handle the hover response. Matches channel-page behavior exactly. */
}
.video-info-content .alts-tile-media {
    position: relative;
    display: block;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background: #000;
    text-decoration: none !important;
}
.video-info-content .alts-tile-media-link {
    position: absolute;
    inset: 0;
    z-index: 1;
    display: block;
    text-decoration: none !important;
    background: transparent;
}
.video-info-content .alts-tile-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.55s cubic-bezier(0.2, 0.8, 0.2, 1), filter 0.25s ease !important;
    filter: brightness(0.82);
    /* v6.x — Safari smooth-zoom: explicit at-rest 2D scale(1) + GPU layer
       (will-change). Rest + hover must be the SAME 2D matrix form — a 2D rest
       with a 3D scale3d hover makes Safari jump between matrix forms. */
    transform: scale(1);
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
    will-change: transform;
}
.video-info-content .alts-channel-tile:hover .alts-tile-img {
    transform: scale(1.08);
    filter: brightness(1);
}
.video-info-content .alts-tile-play {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0.85);
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    backdrop-filter: blur(6px) saturate(1.2);
    border: 2px solid rgba(255, 255, 255, 0.85);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: opacity 0.22s ease, transform 0.22s ease,
                background 0.22s ease, color 0.22s ease, border-color 0.22s ease !important;
    pointer-events: none;
    box-shadow: 0 4px 18px rgba(0, 0, 0, 0.35);
    z-index: 2;
}
.video-info-content .alts-channel-tile:hover .alts-tile-play {
    transform: translate(-50%, -50%) scale(1.1);
    background: var(--alts-accent);
    color: #000;
    border-color: var(--alts-accent);
    box-shadow: 0 10px 40px rgba(191, 255, 0, 0.55);
}
.video-info-content .alts-tile-play svg { margin-left: 3px; }
.video-info-content .alts-tile-year {
    position: absolute;
    top: 12px;
    right: 12px;
    background: rgba(0, 0, 0, 0.72);
    color: #fff !important;
    padding: 4px 10px;
    border-radius: 4px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-decoration: none !important;
    backdrop-filter: blur(6px);
    z-index: 3;  /* above the .alts-tile-media-link overlay so click lands on year */
    transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease !important;
    cursor: pointer;
}
.video-info-content .alts-tile-year:hover,
.video-info-content .alts-tile-year:focus {
    background: var(--alts-accent);
    color: #000 !important;
    transform: scale(1.08);
    text-decoration: none !important;
}
.video-info-content .alts-tile-year i.fa-calendar {
    font-size: 11px;
    margin-right: 1px;
}
/* v6.x — calendar icon turns BLACK on hover (was AS-green on the green hover
   bg → invisible). Both this scope + the html-body !important rule (line ~4254). */
.video-info-content .alts-tile-year:hover i.fa-calendar,
.video-info-content .alts-tile-year:focus i.fa-calendar,
html body .alts-tile-year:hover i.fa-calendar,
html body .alts-tile-year:focus i.fa-calendar {
    color: #000 !important;
}
/* v6.x — hovering the year chip should NOT light up the centre play button
   ("when I hover date, it also hovers the play button"). When the tile
   is hovered AND the year is the hovered element, hold the play button at rest. */
html body .video-info-content .alts-channel-tile:hover:has(.alts-tile-year:hover) span.alts-tile-play,
html body .alts-channel-tile:hover:has(.alts-tile-year:hover) span.alts-tile-play {
    transform: translate(-50%, -50%) scale(0.85) !important;
    background: rgba(0, 0, 0, 0.25) !important;
    background-color: rgba(0, 0, 0, 0.25) !important;
    color: #bfff00 !important;
    border-color: #bfff00 !important;
    box-shadow: none !important;
}
html body .alts-channel-tile:hover:has(.alts-tile-year:hover) span.alts-tile-play svg,
html body .alts-channel-tile:hover:has(.alts-tile-year:hover) span.alts-tile-play svg path {
    color: #bfff00 !important;
    fill: currentColor !important;
}
.video-info-content .alts-tile-body {
    padding: 16px 16px 18px;
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.video-info-content .alts-tile-title {
    font-size: 15px !important;
    line-height: 1.3 !important;
    margin: 0 !important;
    padding: 0 !important;
    font-weight: 600 !important;
    letter-spacing: -0.005em;
}
.video-info-content .alts-tile-title a {
    color: #fff !important;
    text-decoration: none !important;
    display: block;
    transition: color 0.18s ease;
}
.video-info-content .alts-tile-title a:hover {
    color: var(--alts-accent) !important;
}
.video-info-content .alts-tile-director {
    color: var(--alts-text-muted);
    font-size: 12px;
    margin: -4px 0 0 !important;
    padding: 0 !important;
    line-height: 1.4;
    min-height: 17px;
}
.video-info-content .alts-tile-director a {
    color: var(--alts-text-secondary) !important;
    text-decoration: none !important;
    border-bottom: 1px solid transparent;
    transition: border-color 0.15s ease, color 0.15s ease;
}
.video-info-content .alts-tile-director a:hover {
    color: var(--alts-accent) !important;
    border-bottom-color: var(--alts-accent);
}
.video-info-content .alts-tile-director-empty { visibility: hidden; }

/* Second meta line on tiles: year · duration · views.
   Year comes from PHP; duration/views are populated client-side by the
   YT stats lookup into .alts-tile-meta-duration / .alts-tile-meta-views.
   :empty rule hides the whole line if nothing loads. */
.video-info-content .alts-tile-meta {
    color: var(--alts-text-muted);
    font-size: 11px !important;
    line-height: 1.3 !important;
    margin: 4px 0 0 !important;
    padding: 0 !important;
    letter-spacing: 0.03em;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    min-height: 14px;
}
.video-info-content .alts-tile-meta:empty { min-height: 0; }
.video-info-content .alts-tile-meta > span { white-space: nowrap; }
.video-info-content .alts-tile-meta > span:empty { display: none; }
.video-info-content .alts-tile-meta-sep {
    color: var(--alts-accent);
    opacity: 0.4;
    font-weight: 700;
}
.video-info-content .alts-tile-meta > span:empty + .alts-tile-meta-sep { display: none; }

/* ========================================================================
 * TWO-COLUMN HERO LAYOUT
 *
 * .as-modal-two-col turns the hero-inner into a flex row:
 *   [square thumbnail | content column]
 *
 * The thumbnail uses aspect-ratio: 1 and align-self: stretch so it scales
 * to match the right column's actual rendered height. The text column
 * holds everything else (eyebrow, title, meta, pills, description)
 * left-aligned since a centered row with art on the left would look odd.
 *
 * Mobile (< 720px): art hides to save vertical space. On a phone, the
 * blurred hero backdrop already provides the visual flavor.
 * ======================================================================== */
.alts-channel-hero-inner.as-modal-two-col {
    display: flex;
    flex-direction: row;
    align-items: stretch;
    gap: 28px;
    max-width: none;
    width: 100%;
    text-align: left;
}

/* Left column: clean thumbnail, matches right column's height */
.as-modal-hero-art {
    flex: 0 0 auto;
    /* Image stretches vertically to match the right column's rendered
       height. Width is fixed; height flows. Image inside uses object-fit:
       cover to crop elegantly regardless of whether the column is short
       (square-ish) or tall (portrait). */
    width: 280px;
    align-self: stretch;
    border-radius: 12px;
    overflow: hidden;
    background: #000;
    box-shadow:
        0 12px 40px rgba(0, 0, 0, 0.5),
        0 0 0 1px rgba(255, 255, 255, 0.06) inset;
}
/* The img needs !important + high specificity to beat theme rules like
   `#page img { height: auto; max-width: 100% }` which would otherwise
   let the image render at its intrinsic aspect ratio (16:9 or 4:3)
   with black space above/below in our 1:1 square. */
.video-info-content .as-modal-hero-art .as-modal-hero-art-img {
    display: block !important;
    width: 100% !important;
    height: 100% !important;
    max-width: none !important;
    max-height: none !important;
    object-fit: cover !important;
    object-position: center !important;
}

/* Right column: all the existing text content */
.as-modal-hero-text {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

/* In two-column layout, left-align content items that were previously
   centered. High specificity (.as-modal-two-col .alts-channel-X) beats
   the base centered rules. */
.as-modal-two-col .alts-channel-eyebrow,
.as-modal-two-col .alts-channel-title,
.as-modal-two-col .alts-channel-meta,
.as-modal-two-col .as-modal-pills-row,
.as-modal-two-col .as-modal-description {
    text-align: left;
    justify-content: flex-start;
    margin-left: 0;
    margin-right: auto;
}
/* Eyebrow accent bars: hide BOTH in the two-column left-aligned layout.
   The right-side ::after bar visually reads as a trailing em dash next to
   the real em dash separator between artist and genre — confusing. The
   left-side ::before bar looks odd hanging off a left-aligned heading.
   Remove both; the real em dash between artist and genre is enough. */
.as-modal-two-col .alts-channel-eyebrow::before,
.as-modal-two-col .alts-channel-eyebrow::after { display: none !important; }
.as-modal-two-col .alts-channel-eyebrow {
    padding-left: 0;
    padding-right: 0;
    display: inline-block;
}
.as-modal-two-col .alts-channel-meta { justify-content: flex-start; }
.as-modal-two-col .as-modal-pills-row {
    justify-content: flex-start;
    max-width: none;
    margin-left: 0;
}
.as-modal-two-col .as-modal-description {
    padding: 0;
    max-width: none;
}

/* Mobile: stack vertically, hide the art for more content space.
   Blurred bg still provides visual flavor on phones. */
@media (max-width: 720px) {
    .alts-channel-hero-inner.as-modal-two-col {
        flex-direction: column;
        align-items: stretch;
    }
    .as-modal-hero-art { display: none; }
    .as-modal-two-col .alts-channel-eyebrow,
    .as-modal-two-col .alts-channel-title,
    .as-modal-two-col .alts-channel-meta,
    .as-modal-two-col .as-modal-pills-row,
    .as-modal-two-col .as-modal-description {
        text-align: center;
    }
    .as-modal-two-col .alts-channel-meta,
    .as-modal-two-col .as-modal-pills-row {
        justify-content: center;
    }
    .as-modal-two-col .alts-channel-eyebrow {
        padding: 0;
    }
}
/* ============================================================================
 * MOBILE — PORTRAIT (≤768px, portrait orientation)
 * Stack: video → UP NEXT → station pill → inline modal content.
 * Desktop chrome (cluster, info btn, footer) hides. Burger from plugin shows.
 * ========================================================================= */
@media (max-width: 991px) {
  /* MOBILE — FIXED-ZONE LAYOUT: header+video pinned top, content scrolls in bounded region below. */

  /* Body/html scroll normally — video + header are position:fixed so they don't move. */
  html, html body.single-gallery {
    overflow-x: hidden !important;
    overflow-y: auto !important;
    height: auto !important;
    max-height: none !important;
    touch-action: auto !important;
  }

  /* CRITICAL: kill all padding/margin on theme containers so video clearance comes ONLY from floating-header
     padding-top, not doubled by main/page/article paddings. */
  html body.single-gallery #page,
  html body.single-gallery #main,
  html body.single-gallery #main.clearfix,
  html body.single-gallery #main.zIndex,
  html body.single-gallery #single-page,
  html body.single-gallery #primary,
  html body.single-gallery article.post,
  html body.single-gallery article[id^="post-"] {
    padding: 0 !important;
    margin: 0 !important;
    min-height: 0 !important;
  }

  /* Hide desktop chrome */
  body.single-gallery .video-info-toggle,
  body.single-gallery .as-chrome-cluster,
  body.single-gallery .as-chrome-logo-link,
  body.single-gallery footer,
  body.single-gallery footer#colophon,
  body.single-gallery .footer-info,
  body.single-gallery .footer-navigation,
  body.single-gallery .as-viewport-letterbox,
  body.single-gallery #scanlines,
  body.single-gallery .overlay-carbon,
  body.single-gallery #colophon,
  body.single-gallery .site-footer,
  body.single-gallery #secondary,
  body.single-gallery .widget-area,
  body.single-gallery .sidebar,
  body.single-gallery aside.sidebar,
  body.single-gallery .site-branding,
  body.single-gallery .related-posts,
  body.single-gallery .comments-area { display: none !important; }

  /* Nav override: beat the competing html body.single-gallery nav#navigation rule */
  html body.single-gallery header.main-header nav#navigation,
  html body.single-gallery.nav-full-width header.main-header nav#navigation,
  html body.single-gallery header.main-header #navigation.clearfix,
  html body.single-gallery nav#navigation.clearfix {
    display: none !important;
    height: 0 !important;
    overflow: hidden !important;
    visibility: hidden !important;
  }

  /* FIXED TOP ZONE — video pinned, same position:fixed as desktop (no breakpoint reload) */

  html body.single-gallery .entry-video {
    position: relative !important;
    top: auto !important;
    left: auto !important;
    width: 100% !important;
    max-width: 100% !important;
    aspect-ratio: 16 / 9;
    height: auto !important;
    padding: 0 !important;
    margin: 72px 0 0 0 !important; /* 72px clears the fixed chrome (burger+logo) at top */
    z-index: 4950 !important;
    isolation: isolate;
    /* No mask — clean video edges */
  }
  html body.admin-bar.single-gallery .entry-video {
    margin-top: 134px !important; /* clear chrome + admin bar */
  }
  html body.single-gallery .entry-video iframe,
  html body.single-gallery .entry-video embed,
  html body.single-gallery .entry-video object,
  html body.single-gallery #asplayer,
  html body.single-gallery iframe#asplayer {
    position: absolute !important;
    inset: 0 !important;
    width: 100% !important;
    height: 100% !important;
    display: block !important;
    opacity: 1 !important;
    visibility: visible !important;
    z-index: 1 !important;
  }

  /* Old chrome-pinned rule removed — chrome now scrolls with content */
  html body.single-gallery .alts-burger,
  html body.single-gallery.alts-chrome-hidden .alts-burger,
  html body.single-gallery.alts-chrome-hidden .alts-burger:not(.is-open) { right: 20px !important; }
  html body.single-gallery .alts-mobile-logo,
  html body.single-gallery.alts-chrome-hidden .alts-mobile-logo { left: 20px !important; }

  /* Logo on single-gallery mobile: image only, no glassy frame */
  html body.single-gallery .alts-mobile-logo {
    background: transparent !important;
    border: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    border-radius: 0 !important;
    padding: 0 !important;
    width: auto !important;
    height: auto !important;
  }
  html body.single-gallery .alts-mobile-logo img { width: 40px !important; height: 40px !important; }

  /* Disable the desktop click/mouse capture layers on mobile — they steal touch */
  html body.single-gallery #as-click-capture,
  html body.single-gallery #as-mousemove-catcher {
    pointer-events: none !important;
    display: none !important;
  }

  /* SCROLLABLE REGION — .as-floating-header becomes our bounded scroll container */
  /* Floating-header flows in the document normally. Padding-top clears the fixed video zone above. */
  html body.single-gallery article[id^="post-"] > .as-floating-header {
    box-sizing: border-box !important;
    position: relative !important;
    width: 100% !important;
    padding: 24px 16px 120px 16px !important;  /* Big bottom for readability past bottom scrim */
    margin: 0 !important;
    z-index: 2 !important;
    background: transparent !important;
    display: block !important;
    overflow: visible !important;
    height: auto !important;
    /* min-height removed — empty space after content was wasted real estate */
  }
  html body.admin-bar.single-gallery article[id^="post-"] > .as-floating-header {
    /* admin-bar fh padding-top removed (not needed when video is in flow) */
  }

  /* admin-bar fh variant merged into main rule above */

  /* Neutralize modal chrome inside scrollable region */
  html body.single-gallery .video-info-wrapper {
    position: static !important;
    z-index: auto !important;
    width: 100% !important;
    height: auto !important;
    background: transparent !important;
  }
  html body.single-gallery .video-info-overlay {
    position: static !important;
    inset: auto !important;
    transform: none !important;
    opacity: 1 !important;
    visibility: visible !important;
    pointer-events: auto !important;
    background: transparent !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    width: 100% !important;
    max-width: 100% !important;
    height: auto !important;
    max-height: none !important;
    padding: 0 0 8px 0 !important; /* horizontal padding is on floating-header parent now */
    margin: 0 !important;
    overflow: visible !important;
    z-index: auto !important;
  }
  html body.single-gallery .video-info-overlay .video-info-content,
  html body.single-gallery .video-info-overlay .as-modal-content {
    position: static !important;
    transform: none !important;
    opacity: 1 !important;
    width: 100% !important;
    max-width: 100% !important;
    height: auto !important;
    max-height: none !important;
    padding: 0 !important;
    margin: 0 !important;
    background: transparent !important;
    box-shadow: none !important;
    border-radius: 0 !important;
    overflow: visible !important;
  }
  html body.single-gallery .video-info-overlay .as-modal-close,
  html body.single-gallery .video-info-overlay .video-info-close,
  html body.single-gallery .video-info-overlay button[aria-label*="close" i] { display: none !important; }

  /* Content alignment */
  html body.single-gallery .video-info-overlay .alts-channel-eyebrow { text-align: center !important; }
  html body.single-gallery .video-info-overlay .alts-channel-title,
  html body.single-gallery .video-info-overlay .as-modal-title-hero,
  html body.single-gallery .video-info-overlay h1,
  html body.single-gallery .video-info-overlay h2 { text-align: left !important; }
  html body.single-gallery .video-info-overlay .alts-channel-meta,
  html body.single-gallery .video-info-overlay .as-modal-meta,
  html body.single-gallery .video-info-overlay .as-modal-pills-row {
    text-align: left !important;
    justify-content: flex-start !important;
    flex-wrap: wrap !important;
  }
  html body.single-gallery .video-info-overlay .as-modal-description,
  html body.single-gallery .video-info-overlay .alts-channel-description,
  html body.single-gallery .video-info-overlay .as-modal-ymal,
  html body.single-gallery .video-info-overlay .as-modal-ymal-title { text-align: left !important; }

  /* YMAL hidden on mobile — too much clutter. UP NEXT + Station + search cover discovery. */
  html body.single-gallery .video-info-overlay .as-modal-ymal {
    display: none !important;
  }

  /* Section dividers — subtle hairlines between main content zones */
  html body.single-gallery .video-info-overlay .alts-channel-meta,
  html body.single-gallery .video-info-overlay .as-modal-meta {
    padding-bottom: 18px !important;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1) !important;
    margin-bottom: 18px !important;
  }
  html body.single-gallery .video-info-overlay .as-modal-pills-row {
    padding-bottom: 18px !important;
    margin-bottom: 18px !important;
  }

  /* Bottom-padding reset with selective restore on text blocks */
  html body.single-gallery .video-info-overlay *,
  html body.single-gallery .video-info-overlay .as-modal-ymal > *:last-child {
    margin-bottom: 0 !important;
    padding-bottom: 0 !important;
  }
  html body.single-gallery .video-info-overlay p,
  html body.single-gallery .video-info-overlay .alts-channel-eyebrow,
  html body.single-gallery .video-info-overlay .alts-channel-title,
  html body.single-gallery .video-info-overlay .alts-channel-meta,
  html body.single-gallery .video-info-overlay .as-modal-description { margin-bottom: 16px !important; }
  html body.single-gallery .video-info-overlay .as-modal-pills-row { margin-bottom: 20px !important; }

  /* Mobile typography breathing room — tighter line-heights feel stacked at mobile */
  html body.single-gallery .video-info-overlay .alts-channel-title,
  html body.single-gallery .video-info-overlay .as-modal-title-hero,
  html body.single-gallery .video-info-overlay h1,
  html body.single-gallery .video-info-overlay h2 {
    line-height: 1.25 !important;
  }
  html body.single-gallery .video-info-overlay .as-modal-description {
    line-height: 1.7 !important;
  }

  /* Pill line-height fix: font-size 11px + line-height 11px = no room for descenders,
     which causes visual asymmetry (text crowds bottom). Use 1.3 so descenders fit. */
  html body.single-gallery .video-info-overlay .alts-decade-pill {
    line-height: 1.3 !important;
    padding: 5px 10px 6px 10px !important;
    height: auto !important;
    display: inline-flex !important;
    align-items: center !important;
  }
  /* Pills row: give it a little gap between wrapped rows too */
  html body.single-gallery .video-info-overlay .as-modal-pills-row {
    row-gap: 8px !important;
    column-gap: 6px !important;
  }

  /* Neutralize cursor auto-hide on mobile */
  html body.single-gallery.ui-hidden .as-chrome-eyebrow,
  html body.single-gallery.ui-hidden .video-info-overlay,
  html body.single-gallery.ui-hidden .entry-title { opacity: 1 !important; }
  html body.single-gallery.ui-hidden { cursor: auto !important; }
    /* Drawer + backdrop grow to fill viewport at any size (prevents black bottom on resize) */
    html body.single-gallery div#alts-mobile-drawer,
    html body.single-gallery div#alts-mobile-drawer .alts-drawer-overlay,
    html body.single-gallery div#alts-mobile-drawer .alts-drawer-backdrop,
    html body.single-gallery .alts-drawer-overlay,
    html body.single-gallery .alts-drawer-backdrop {
      position: fixed !important;
      top: 0 !important;
      left: 0 !important;
      right: 0 !important;
      bottom: 0 !important;
      width: 100vw !important;
      min-width: 100vw !important;
      height: 100vh !important;
      height: 100dvh !important;
      min-height: 100vh !important;
      min-height: 100dvh !important;
      max-width: none !important;
      max-height: none !important;
    }
/* Kill horizontal padding/margin on inner wrappers so fh's 16px is the ONLY horizontal inset */
    html body.single-gallery .video-info-wrapper,
    html body.single-gallery .video-info-content,
    html body.single-gallery .video-info-content > *,
    html body.single-gallery .as-modal-hero-text,
    html body.single-gallery .video-info-overlay {
      box-sizing: border-box !important;
      max-width: 100% !important;
      width: 100% !important;
      padding-left: 0 !important;
      padding-right: 0 !important;
      margin-left: 0 !important;
      margin-right: 0 !important;
    }

    /* Chrome (burger + logo) scrolls with page — position absolute, match specificity with any alts-chrome-hidden variant */
    html body.single-gallery .alts-burger,
    html body.single-gallery .alts-mobile-logo,
    html body.single-gallery.alts-chrome-hidden .alts-burger,
    html body.single-gallery.alts-chrome-hidden .alts-burger:not(.is-open),
    html body.single-gallery.alts-chrome-hidden .alts-mobile-logo {
      position: absolute !important;
      top: 24px !important;
      transform: none !important;
      opacity: 1 !important;
      visibility: visible !important;
    }

    /* Nuclear: kill any injected scrim div if it somehow persists */
    html body.single-gallery .as-mobile-scroll-scrim { display: none !important; }

    /* Hide the non-curved .as-modal-body wrapper (redundant — curved .alts-channel-hero already serves this role) */
    html body.single-gallery .video-info-overlay .as-modal-body { display: none !important; }

    /* Curved text container: constrain width so it doesn't overflow viewport */
    html body.single-gallery .video-info-overlay .alts-channel-hero,
    html body.single-gallery .video-info-overlay .as-modal-hero-in-modal {
      box-sizing: border-box !important;
      width: auto !important;
      max-width: none !important;
      margin: 0 8px !important;
    }

    /* Stronger chrome scroll rule — specificity war vs plugin's inline styles */
    html body.single-gallery div.alts-burger,
    html body.single-gallery div.alts-mobile-logo,
    html body.single-gallery button.alts-burger,
    html body.single-gallery a.alts-mobile-logo {
      position: absolute !important;
    }

    /* Stronger scrim kill + remove from DOM via CSS content reset */
    html body.single-gallery div.as-mobile-scroll-scrim,
    html body div.as-mobile-scroll-scrim,
    div.as-mobile-scroll-scrim {
      display: none !important;
      visibility: hidden !important;
      opacity: 0 !important;
      pointer-events: none !important;
      height: 0 !important;
      background: transparent !important;
    }
  
    /* Curved holder: symmetric padding all around + proper width */
    html body.single-gallery .video-info-overlay .alts-channel-hero,
    html body.single-gallery .video-info-overlay .as-modal-hero-in-modal {
      padding: 20px !important;
      box-sizing: border-box !important;
      width: calc(100% - 32px) !important;
      max-width: calc(100% - 32px) !important;
      margin-left: 16px !important;
      margin-right: 16px !important;
    }

    /* Chrome scrolls away with content — completely unfix */
    html body.single-gallery .alts-burger,
    html body.single-gallery div.alts-burger,
    html body.single-gallery button.alts-burger,
    html body.single-gallery .alts-mobile-logo,
    html body.single-gallery div.alts-mobile-logo,
    html body.single-gallery a.alts-mobile-logo {
      position: absolute !important;
      background: transparent !important;
      backdrop-filter: none !important;
      -webkit-backdrop-filter: none !important;
      border: none !important;
      box-shadow: none !important;
    }
  
    /* Video wrapper + ALL its wrappers: full viewport width, no padding */
    html body.single-gallery .entry-video-wrapper,
    html body.single-gallery #content .entry-video-wrapper,
    html body.single-gallery div.entry-video-wrapper,
    html body.single-gallery .entry-video,
    html body.single-gallery .entry-video iframe {
      box-sizing: border-box !important;
      width: 100% !important;
      max-width: 100% !important;
      margin-left: 0 !important;
      margin-right: 0 !important;
      padding-left: 0 !important;
      padding-right: 0 !important;
    }

    /* Also ensure #content wrapper is viewport-bounded */
    html body.single-gallery article[id^="post-"] > #content {
      box-sizing: border-box !important;
      width: 100% !important;
      max-width: 100vw !important;
      overflow-x: hidden !important;
    }
  
    /* #content wrapper: zero all theme padding (was 10px 30px 30px, pushing video off-center) */
    html body.single-gallery article[id^="post-"] > div#content,
    html body.single-gallery article[id^="post-"] > #content,
    html body.single-gallery #primary article[id^="post-"] #content,
    html body.single-gallery div#content {
      padding: 0 !important;
      margin: 0 !important;
      box-sizing: border-box !important;
      width: 100% !important;
      max-width: 100% !important;
    }

    /* Kill ONLY the square dark tint overlay (::after). Keep ::before (colorful poster bg). */
    html body.single-gallery .video-info-content::after {
      display: none !important;
      content: none !important;
      background: none !important;
    }
  
    /* ── FIXES FROM USER FEEDBACK ── */

    /* Fix 1: Text padding asymmetric (left > right) */
    /* Text at x_l=72, x_r=602, viewport=636 → 72 left vs 34 right. Curved holder child adds 20px extra left. */
    /* Zero out padding on curved-holder inner wrappers so text aligns to hero s 20px padding evenly */
    html body.single-gallery .alts-channel-hero-inner,
    html body.single-gallery .as-modal-two-col,
    html body.single-gallery .as-modal-hero-text {
      padding: 0 !important;
      margin: 0 !important;
      width: 100% !important;
      max-width: 100% !important;
      box-sizing: border-box !important;
    }

    /* Fix 2: Meta line-height shrink (13px × 1.3 = 16.9px instead of 20.8px) */
    html body.single-gallery .video-info-overlay .alts-channel-meta,
    html body.single-gallery .video-info-overlay .as-modal-meta {
      line-height: 1.3 !important;
    }

    /* Fix 3: Halve bottom space (fh padding-bottom: 32px → 16px) */
    html body.single-gallery article[id^="post-"] > .as-floating-header {
      padding-bottom: 16px !important;
    }

    /* Fix 4: Video starts exactly at y=72 (chrome zone = 72px) */
    html body.single-gallery .entry-video {
      margin-top: 72px !important;
      margin-bottom: 0 !important;
    }

    /* Fix 6: Per-video colorful background — use the song poster as page bg with blur.
       Apply it to .alts-drawer-overlay (the page-wide bg layer) via inheriting from .video-info-content::before. */
    html body.single-gallery .alts-drawer-overlay {
      /* Inherit the song poster image set by the theme/plugin inline-style on video-info-content::before */
      background-image: var(--song-poster-bg, inherit), radial-gradient(at 50% 0%, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0.85) 100%) !important;
      background-size: cover, cover !important;
      background-position: center center, center center !important;
      background-repeat: no-repeat, no-repeat !important;
      filter: blur(0) !important;
    }

    /* The .alts-drawer-backdrop is positioned above overlay — use IT to show the blurred poster */
    html body.single-gallery .alts-drawer-backdrop {
      background: inherit !important;
      backdrop-filter: blur(60px) saturate(1.4) !important;
      -webkit-backdrop-filter: blur(60px) saturate(1.4) !important;
    }
  
    /* ── ROUND 2 FIXES ── */

    /* Fix 1: fh must be positioned at (0,0) on mobile — theme sets left: var() and bottom: 4vw which breaks horizontal alignment */
    html body.single-gallery article[id^="post-"] > .as-floating-header,
    html body.single-gallery .as-floating-header {
      left: 0 !important;
      right: 0 !important;
      bottom: 0 !important;
      top: 0 !important;
    }

    /* Fix 2: Meta line-height needs !important to win. 13×1.3 = 16.9px */
    html body.single-gallery .video-info-overlay p.alts-channel-meta,
    html body.single-gallery .video-info-overlay p.as-modal-meta,
    html body.single-gallery .video-info-overlay .alts-channel-meta,
    html body.single-gallery .video-info-overlay .as-modal-meta,
    html body.single-gallery p.alts-channel-meta,
    html body.single-gallery p.as-modal-meta {
      line-height: 1.3 !important;
      font-size: 13px !important;
    }

    /* Fix 3: Eyebrow gets top padding equal to left/right (curved holder has 20px padding all sides;
       eyebrow sits at the top of that, so padding-top 20px on eyebrow would DOUBLE. Instead: keep curved holder 20px all sides which already gives eyebrow 20px above, and ensure eyebrow margin-top is 0. Bottom 2x → add padding-bottom 40px to curved holder) */
    html body.single-gallery .video-info-overlay .alts-channel-hero,
    html body.single-gallery .video-info-overlay .as-modal-hero-in-modal {
      padding: 20px 20px 40px 20px !important;
      margin-left: 8px !important;
      margin-right: 8px !important;
    }
    html body.single-gallery .video-info-overlay .alts-channel-eyebrow {
      margin-top: 0 !important;
    }

    /* Fix 4: Chrome zone = 72px total, video must start at y=72. Chrome at top:24 h:48 = ends at y=72. Video margin-top=0 and relies on chrome zone above. */
    /* Move chrome top from 24 → 12 so chrome zone is 12+48+12=72 total with burger centered. Video margin-top: 72 */
    /* Actually simpler: keep chrome at top:24, but video must be at y=72 meaning margin-top remains 72 */
    /* No change needed — video is at y=82 now because wrapper has 10px top padding. Find and zero it. */
    html body.single-gallery article[id^="post-"] > #content,
    html body.single-gallery article[id^="post-"] > div#content {
      padding-top: 0 !important;
    }

    /* Fix 5: Drawer overlay + backdrop should show song poster as page-wide bg with blur
       Use the --song-poster-bg CSS var set by extractPoster IIFE */
    html body.single-gallery .alts-drawer-overlay {
      background-image: var(--song-poster-bg, linear-gradient(180deg, #1a1a1a 0%, #0a0a0a 100%)) !important;
      background-size: cover !important;
      background-position: center center !important;
      background-repeat: no-repeat !important;
      background-color: #0a0a0a !important;
    }
    /* Heavy blur overlay that sits above poster */
    html body.single-gallery .alts-drawer-backdrop {
      background-color: rgba(10, 10, 10, 0.35) !important;
      backdrop-filter: blur(80px) saturate(1.6) !important;
      -webkit-backdrop-filter: blur(80px) saturate(1.6) !important;
    }
  
    /* ── CRITICAL FIX: kill desktop-modal flex-center behavior that clips content ── */
    /* Desktop behavior was: flex container with max-height + overflow hidden + vertical center.
       On mobile this clips content and hides eyebrow/title when viewport shrinks.
       Fix: revert all these to normal block flow so content sizes to its own height. */
    html body.single-gallery .video-info-overlay,
    html body.single-gallery .video-info-content,
    html body.single-gallery .alts-channel-hero,
    html body.single-gallery .as-modal-hero-in-modal,
    html body.single-gallery article[id^="post-"] > .as-floating-header {
      display: block !important;
      align-items: initial !important;
      justify-content: initial !important;
      max-height: none !important;
      min-height: 0 !important;
      height: auto !important;
      overflow: visible !important;
    }
  
    /* ═══ PAGE BG: per-video poster as full-viewport backdrop, behind everything ═══ */
    /* Use ::before on body to paint poster image fixed across entire viewport */
    html body.single-gallery::before {
      content: "" !important;
      position: fixed !important;
      top: 0 !important;
      left: 0 !important;
      right: 0 !important;
      bottom: 0 !important;
      width: 100vw !important;
      height: 100vh !important;
      height: 100dvh !important;
      background-image: var(--alts-drawer-bg, linear-gradient(180deg, #1a1a1a 0%, #0a0a0a 100%)) !important;
      background-size: cover !important;
      background-position: center center !important;
      background-repeat: no-repeat !important;
      background-color: #0a0a0a !important;
      z-index: -2 !important;
      pointer-events: none !important;
    }
    /* Darkening + blur layer on top of poster so content is readable */
    html body.single-gallery::after {
      content: "" !important;
      position: fixed !important;
      top: 0 !important;
      left: 0 !important;
      right: 0 !important;
      bottom: 0 !important;
      width: 100vw !important;
      height: 100vh !important;
      height: 100dvh !important;
      background:
        radial-gradient(ellipse at top, rgba(0, 0, 0, 0.35) 0%, rgba(0, 0, 0, 0.75) 100%),
        linear-gradient(180deg, rgba(10, 10, 10, 0.2) 0%, rgba(10, 10, 10, 0.6) 100%) !important;
      backdrop-filter: blur(40px) saturate(1.3) !important;
      -webkit-backdrop-filter: blur(40px) saturate(1.3) !important;
      z-index: -1 !important;
      pointer-events: none !important;
    }

    /* Curved container: fully rounded corners all around (not just top) */
    html body.single-gallery .video-info-overlay .alts-channel-hero,
    html body.single-gallery .video-info-overlay .as-modal-hero-in-modal {
      border-radius: 16px !important;
    }

    /* Chrome: subtle button-chip look. Not black, not glassy — just a gentle border + light bg that works with colored page bg */
    html body.single-gallery .alts-burger,
    html body.single-gallery .alts-mobile-logo {
      background: rgba(255, 255, 255, 0.08) !important;
      border: 1px solid rgba(255, 255, 255, 0.15) !important;
      backdrop-filter: blur(20px) saturate(1.3) !important;
      -webkit-backdrop-filter: blur(20px) saturate(1.3) !important;
    }
  
    /* 50px scrim at bottom of video fading from black → transparent */
    html body.single-gallery .entry-video {
      position: relative !important;
    }
    html body.single-gallery .entry-video::after {
      content: "" !important;
      position: absolute !important;
      left: 0 !important;
      right: 0 !important;
      bottom: -50px !important;  /* extend below video edge */
      height: 50px !important;
      pointer-events: none !important;
      background: linear-gradient(to bottom, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0) 100%) !important;
      z-index: 2 !important;
    }

    /* Drawer overlay: remove per-video bg image (revert to original see-through look user liked) */
    html body.single-gallery .alts-drawer-overlay {
      background-image: none !important;
      background:
        radial-gradient(ellipse at top, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0.85) 100%),
        linear-gradient(180deg, rgba(4, 4, 4, 0.4) 0%, rgba(4, 4, 4, 0.92) 100%) !important;
    }
    html body.single-gallery .alts-drawer-backdrop {
      background-image: none !important;
      background: transparent !important;
      backdrop-filter: blur(24px) saturate(1.2) !important;
      -webkit-backdrop-filter: blur(24px) saturate(1.2) !important;
    }

    /* ══════ LIVE PREVIEW SHIP — FLAT CONTENT STYLE ══════ */
    /* Baked from live-page iteration. Full-bleed darker content area, no curved holder box,
       text padded symmetrically at 20px (matches burger/logo inset), fading neon scanline under pills. */
    
    /* Body bg transparent so body::before (per-video poster) shows through */
    html body.single-gallery {
      background-color: transparent !important;
    }
    
    /* Body::after darkening overlay — uniform flat tint, not radial */
    html body.single-gallery.single-gallery::after,
    html body.single-gallery.single::after,
    body.single-gallery::after {
      background: rgba(0, 0, 0, 0.5) !important;
      background-image: none !important;
    }
    
    /* Kill fh's top padding so darker container bg sits flush under video */
    html body.single-gallery article[id^="post-"] > header.as-floating-header,
    html body.single-gallery header.as-floating-header {
      padding-top: 0 !important;
      padding-left: 0 !important;
      padding-right: 0 !important;
    }
    
    /* Content wrappers full-bleed */
    html body.single-gallery div.video-info-wrapper,
    html body.single-gallery div.video-info-overlay,
    html body.single-gallery div.video-info-content {
      padding-left: 0 !important;
      padding-right: 0 !important;
      margin-left: 0 !important;
      margin-right: 0 !important;
      width: 100% !important;
      max-width: 100% !important;
    }
    
    /* Curved holder stripped: no bg, no border, no margin. Keep ONLY inner top padding for breathing room. */
    html body.single-gallery section.alts-channel-hero,
    html body.single-gallery.single-gallery section.alts-channel-hero,
    html body.single-gallery .video-info-overlay section.alts-channel-hero,
    html body.single-gallery .video-info-content section.alts-channel-hero,
    html body.single-gallery section.as-modal-hero-in-modal {
      padding: 48px 0 0 0 !important;
      margin: 0 !important;
      border-radius: 0 !important;
      background: transparent !important;
      box-shadow: none !important;
      border: none !important;
      width: 100% !important;
      max-width: 100% !important;
    }
    html body.single-gallery div.alts-channel-hero-inner,
    html body.single-gallery div.as-modal-two-col,
    html body.single-gallery div.as-modal-hero-text {
      padding: 0 !important;
      margin: 0 !important;
      background: transparent !important;
      width: 100% !important;
      max-width: 100% !important;
    }
    
    /* Curved ::after — extended 120px below bounds so gradient has room to fade smoothly to transparent */
    html body.single-gallery.single-gallery .video-info-content section.alts-channel-hero::after,
    html body.single-gallery .video-info-content section.alts-channel-hero::after,
    html body.single-gallery section.alts-channel-hero::after,
    html body.single-gallery section.as-modal-hero-in-modal::after,
    html body.single-gallery .video-info-content .alts-channel-hero::after,
    html body.single-gallery .alts-channel-hero::after,
    html body.single-gallery .as-modal-hero-in-modal::after {
      bottom: -120px !important;
      background: linear-gradient(to bottom,
        rgba(0, 0, 0, 0.55) 0%,
        rgba(0, 0, 0, 0.48) 20%,
        rgba(0, 0, 0, 0.38) 40%,
        rgba(0, 0, 0, 0.25) 60%,
        rgba(0, 0, 0, 0.12) 78%,
        rgba(0, 0, 0, 0) 100%
      ) !important;
      background-image: linear-gradient(to bottom,
        rgba(0, 0, 0, 0.55) 0%,
        rgba(0, 0, 0, 0.48) 20%,
        rgba(0, 0, 0, 0.38) 40%,
        rgba(0, 0, 0, 0.25) 60%,
        rgba(0, 0, 0, 0.12) 78%,
        rgba(0, 0, 0, 0) 100%
      ) !important;
    }
    /* Ensure curved doesn't clip the extended pseudo */
    html body.single-gallery section.alts-channel-hero,
    html body.single-gallery section.as-modal-hero-in-modal {
      overflow: visible !important;
    }
    
    /* Text blocks: 20px gutter — aligns with burger/logo 20px from viewport edges */
    html body.single-gallery .alts-channel-eyebrow,
    html body.single-gallery .alts-channel-title,
    html body.single-gallery .alts-channel-meta,
    html body.single-gallery .as-modal-title-hero,
    html body.single-gallery .as-modal-meta,
    html body.single-gallery .as-modal-description,
    html body.single-gallery .alts-channel-description,
    html body.single-gallery .as-modal-pills-row,
    html body.single-gallery .alts-channel-pills {
      padding-left: 20px !important;
      padding-right: 20px !important;
    }
    
    /* Meta: tighter line-height + tighter row-gap when "Director" wraps. Line moved from meta to pills */
    html body.single-gallery .video-info-overlay p.alts-channel-meta,
    html body.single-gallery .video-info-overlay p.as-modal-meta,
    html body.single-gallery .video-info-overlay .alts-channel-meta,
    html body.single-gallery .video-info-overlay .as-modal-meta,
    html body.single-gallery .video-info-overlay .alts-channel-meta span,
    html body.single-gallery .video-info-overlay .as-modal-meta span,
    html body.single-gallery .video-info-overlay p.alts-channel-meta span,
    html body.single-gallery .video-info-overlay p.as-modal-meta span {
      line-height: 1.15 !important;
    }
    html body.single-gallery .video-info-overlay p.alts-channel-meta,
    html body.single-gallery .video-info-overlay p.as-modal-meta,
    html body.single-gallery p.alts-channel-meta,
    html body.single-gallery p.as-modal-meta {
      row-gap: 2px !important;
      gap: 6px !important;
      border-bottom: none !important;
      padding-bottom: 10px !important;
    }
    
    /* Pills: straight border-bottom removed, replaced with fading neon scanline via ::after */
    html body.single-gallery .video-info-overlay div.as-modal-pills-row,
    html body.single-gallery .video-info-overlay div.alts-channel-pills,
    html body.single-gallery div.as-modal-pills-row,
    html body.single-gallery div.alts-channel-pills {
      border-bottom: none !important;
      padding-bottom: 32px !important;
      margin-bottom: 20px !important;
      position: relative !important;
    }
    html body.single-gallery .video-info-overlay .as-modal-pills-row::after,
    html body.single-gallery .video-info-overlay .alts-channel-pills::after,
    html body.single-gallery .as-modal-pills-row::after,
    html body.single-gallery .alts-channel-pills::after {
      content: "" !important;
      display: block !important;
      position: absolute !important;
      left: 0 !important;
      right: 0 !important;
      bottom: 0 !important;
      height: 1px !important;
      background: linear-gradient(90deg, transparent, rgba(191, 255, 0, 0.5) 50%, transparent) !important;
      pointer-events: none !important;
    }
    /* ══════ END LIVE PREVIEW SHIP ══════ */

    /* ══════ ROUND 2 LIVE SHIP ══════ */
    
    /* Push video further down from chrome — video margin-top 72px → 96px */
    html body.single-gallery .entry-video,
    html body.single-gallery .entry-video-wrapper > .entry-video {
      margin-top: 96px !important;
    }
    
    /* moved out of MQ — see outside block */
    
    /* Fix 40px bottom rectangle: extend body::after darkening uniformly to cover full doc height,
       not just viewport — use height 100vh + position fixed means it always matches viewport.
       Hack: make curved::after gradient extend all the way to bottom of the fh so no visible seam.
       Actually simplest: remove the body::after flat 0.5 darkening (duplicates curved's gradient)
       and let curved gradient be the only darkening layer — it fades to transparent at bottom of curved,
       page bg then shows through equally above and below. */
    html body.single-gallery::after {
      background: transparent !important;
      background-image: none !important;
    }
    /* But we still need SOME darkening for readability — add a subtle gradient fade at top 
       (matches old radial) instead of flat */
    html body.single-gallery::before {
      /* keep poster — no changes needed */
    }
    
    /* ══════ END ROUND 2 LIVE SHIP ══════ */

  }

  /* ═══ MOBILE LAYOUT: FULL WIDTH + VIDEO SIZING + CONTENT PADDING ═══ */
  @media (max-width: 991px) {
    /* Full width for wrappers (kill sidebar gap) */
    html body.single-gallery #main,
    html body.single-gallery #single-page,
    html body.single-gallery #primary,
    html body.single-gallery #single-page.left-sidebar,
    html body.single-gallery #single-page > #primary {
      width: 100% !important;
      max-width: 100% !important;
      margin: 0 !important;
      padding: 0 !important;
      float: none !important;
    }
    html body.single-gallery #secondary,
    html body.single-gallery aside.sidebar,
    html body.single-gallery .sidebar {
      display: none !important;
    }
    
    /* Article & content: full width */
    html body.single-gallery article[id^="post-"],
    html body.single-gallery article[id^="post-"] > #content,
    html body.single-gallery .entry-video-wrapper,
    html body.single-gallery .entry-video {
      width: 100% !important;
      max-width: 100% !important;
      margin: 0 !important;
      padding: 0 !important;
    }
    
    /* Video container: 16:9 aspect ratio */
    html body.single-gallery .entry-video {
      position: relative !important;
      padding-bottom: 56.25% !important;
      height: 0 !important;
      overflow: hidden !important;
    }
    
    /* Iframe: lock to parent size (contain:size prevents YouTube overriding width) */
    html body.single-gallery .entry-video iframe#asplayer,
    html body.single-gallery iframe#asplayer {
      position: absolute !important;
      top: 0 !important;
      left: 0 !important;
      width: 100% !important;
      height: 100% !important;
      max-width: 100% !important;
      max-height: 100% !important;
      min-width: 0 !important;
      min-height: 0 !important;
      transform: none !important;
      contain: size !important;
    }
    
    /* Content block (floating header) — full width with 40px padding all sides.
       High specificity to beat article[id^="post-"] > header rule */
    html body.single-gallery article[id^="post-"] > header.as-floating-header,
    html body.single-gallery article[id^="post-"] > .as-floating-header,
    html body.single-gallery header.as-floating-header {
      padding: 40px !important;
      box-sizing: border-box !important;
      width: 100% !important;
      max-width: 100% !important;
    }
    
    /* Hero inside: no extra padding/margin, full width */
    html body.single-gallery article[id^="post-"] > header.as-floating-header section.alts-channel-hero,
    html body.single-gallery article[id^="post-"] .as-floating-header section.alts-channel-hero,
    html body.single-gallery section.alts-channel-hero,
    html body.single-gallery .as-floating-header .alts-channel-hero {
      padding: 0 !important;
      margin: 0 !important;
      width: 100% !important;
      max-width: 100% !important;
    }
    html body.single-gallery .alts-channel-hero .alts-channel-hero-inner {
      width: 100% !important;
      max-width: 100% !important;
    }
  }
  /* ═══ END MOBILE LAYOUT ═══ */

  /* Title ↔ UP NEXT collision hide — watcher (in plugin) adds body class when gap < 30px */
  html body.single-gallery.alts-title-eyebrow-near .as-chrome-eyebrow {
    opacity: 0 !important;
    visibility: hidden !important;
    pointer-events: none !important;
    transition: opacity 0.35s ease !important;
  }

  /* ═══ MOBILE LAYOUT: CSS flex-order swap (no DOM reorder, no iframe reload) ═══ */
  /* Make article a flex container so children can be reordered via CSS */
  html body.single-gallery article[id^="post-"] {
    display: flex !important;
    flex-direction: column !important;
  }
  html body.single-gallery article[id^="post-"] > .as-floating-header { order: 0; }
  html body.single-gallery article[id^="post-"] > #content { order: 1; }
  
  /* Mobile: swap visually — video (#content) comes BEFORE header */
  @media (max-width: 991px) {
    html body.single-gallery article[id^="post-"] > .as-floating-header { order: 1 !important; }
    html body.single-gallery article[id^="post-"] > #content { order: 0 !important; }
  }
  /* ═══ END MOBILE LAYOUT SWAP ═══ */

  /* ═══ MOBILE FULLWIDTH VIDEO + CONTENT BLOCK (below 991px) ═══ */
  @media (max-width: 991px) {
    /* Full viewport width — kill sidebar gap */
    html body.single-gallery #main,
    html body.single-gallery #single-page,
    html body.single-gallery #primary,
    html body.single-gallery #single-page.left-sidebar,
    html body.single-gallery #single-page > #primary {
      width: 100% !important;
      max-width: 100% !important;
      margin: 0 !important;
      padding: 0 !important;
      float: none !important;
    }
    html body.single-gallery #secondary,
    html body.single-gallery aside.sidebar,
    html body.single-gallery .sidebar {
      display: none !important;
    }
    
    /* Article / content wrappers fill viewport */
    html body.single-gallery article[id^="post-"],
    html body.single-gallery article[id^="post-"] > #content {
      width: 100% !important;
      max-width: 100% !important;
      margin: 0 !important;
      padding: 0 !important;
    }
    html body.single-gallery .entry-video-wrapper {
      width: 100% !important;
      max-width: 100% !important;
      margin: 0 !important;
      padding: 96px 0 32px !important;
    }
    
    /* Video: 16:9 aspect-ratio box that grows with viewport */
    html body.single-gallery .entry-video {
      position: relative !important;
      width: 100% !important;
      max-width: 100% !important;
      margin: 0 !important;
      padding: 0 0 56.25% 0 !important;
      height: 0 !important;
      overflow: hidden !important;
    }
    html body.single-gallery .entry-video iframe#asplayer,
    html body.single-gallery iframe#asplayer {
      position: absolute !important;
      top: 0 !important;
      left: 0 !important;
      width: 100% !important;
      height: 100% !important;
      max-width: 100% !important;
      max-height: 100% !important;
      min-width: 0 !important;
      min-height: 0 !important;
      transform: none !important;
      contain: size !important;
    }
    
    /* Content block (floating header): 40px padding all sides, full width */
    html body.single-gallery article[id^="post-"] > header.as-floating-header,
    html body.single-gallery article[id^="post-"] > .as-floating-header,
    html body.single-gallery header.as-floating-header {
      padding: 40px !important;
      box-sizing: border-box !important;
      width: 100% !important;
      max-width: 100% !important;
    }
    html body.single-gallery article[id^="post-"] > header.as-floating-header section.alts-channel-hero,
    html body.single-gallery article[id^="post-"] .as-floating-header section.alts-channel-hero,
    html body.single-gallery section.alts-channel-hero,
    html body.single-gallery .as-floating-header .alts-channel-hero {
      padding: 0 !important;
      margin: 0 !important;
      width: 100% !important;
      max-width: 100% !important;
    }
    html body.single-gallery .alts-channel-hero .alts-channel-hero-inner {
      width: 100% !important;
      max-width: 100% !important;
    }
  }
  /* ═══ END MOBILE FULLWIDTH ═══ */

  /* ═══ MOBILE CONTENT CLEANUP (below 991px) ═══ */
  @media (max-width: 991px) {
    /* Kill leftover video margin-top from old chrome-aware layout */
    html body.single-gallery .entry-video,
    html body.single-gallery .entry-video-wrapper > .entry-video,
    html body.single-gallery article[id^="post-"] .entry-video {
      margin: 0 !important;
      margin-top: 0 !important;
    }
    
    /* Hide desktop UP NEXT eyebrow on mobile */
    html body.single-gallery header.as-floating-header .as-chrome-eyebrow,
    html body.single-gallery article[id^="post-"] .as-floating-header .as-chrome-eyebrow,
    html body.single-gallery article[id^="post-"] > header.as-floating-header > .as-chrome-eyebrow {
      display: none !important;
    }
    
    /* Floating header: pass-through container (no padding/bg, inner modal handles styling) */
    html body.single-gallery article[id^="post-"] > header.as-floating-header,
    html body.single-gallery header.as-floating-header {
      padding: 0 !important;
      background: transparent !important;
      border-radius: 0 !important;
      margin: 0 !important;
      width: 100% !important;
      max-width: 100% !important;
    }
    
    /* Modal wrapper/overlay: inline static, no fixed positioning on mobile */
    html body.single-gallery header.as-floating-header .video-info-wrapper {
      position: static !important;
      display: block !important;
      width: 100% !important;
      height: auto !important;
    }
    html body.single-gallery header.as-floating-header .video-info-overlay,
    html body.single-gallery header.as-floating-header .video-info-overlay.active {
      position: static !important;
      display: block !important;
      width: 100% !important;
      height: auto !important;
      background: transparent !important;
      backdrop-filter: none !important;
      -webkit-backdrop-filter: none !important;
      padding: 0 !important;
      margin: 0 !important;
    }
    
    /* Content card: glass bg, rounded corners, 20px margin, 40px padding */
    html body.single-gallery header.as-floating-header .video-info-content {
      position: static !important;
      display: block !important;
      width: 100% !important;
      max-width: 100% !important;
      margin: 0 !important;
      padding: 30px 24px 40px !important;
      box-sizing: border-box !important;
      background: transparent !important;
      background-color: transparent !important;
      backdrop-filter: none !important;
      -webkit-backdrop-filter: none !important;
      border: none !important;
      border-radius: 0 !important;
      box-shadow: none !important;
      max-height: none !important;
      overflow: visible !important;
    }
    /* Restore thumbnail bg pseudo + gradient overlay on mobile (blurred colored backdrop) */
    html body.single-gallery header.as-floating-header .video-info-content::before,
    html body.single-gallery .video-info-content::before {
      display: block !important;
      content: "" !important;
      position: absolute !important;
      /* Extend above + sides so blur fade falls outside visible area */
      top: -60px !important;
      left: -40px !important;
      right: -40px !important;
      bottom: -40px !important;
      inset: auto !important;
      background-image: var(--alts-hero-bg, none) !important;
      background-size: cover !important;
      background-position: center !important;
      background-repeat: no-repeat !important;
      filter: blur(44px) brightness(0.55) saturate(1.15) !important;
      transform: scale(1.15) !important;
      z-index: 0 !important;
      pointer-events: none !important;
    }
    html body.single-gallery .alts-channel-hero::after,
    html body.single-gallery section.alts-channel-hero::after {
      display: block !important;
      content: "" !important;
      position: absolute !important;
      inset: 0 !important;
      background: linear-gradient(180deg, rgba(0,0,0,0.35) 0%, rgba(0,0,0,0.15) 35%, rgba(0,0,0,0) 70%) !important;
      pointer-events: none !important;
      z-index: 1 !important;
    }
    /* Ensure content card is positioning context + above pseudos */
    html body.single-gallery header.as-floating-header .video-info-content {
      position: relative !important;
      isolation: isolate !important;
      overflow: hidden !important;
    }
    html body.single-gallery .video-info-content > *:not(.as-modal-close) {
      position: relative !important;
      z-index: 2 !important;
    }
    
    /* Hero inside content card: fill, no padding */
    html body.single-gallery .video-info-content section.alts-channel-hero,
    html body.single-gallery section.alts-channel-hero.as-modal-hero-in-modal,
    html body.single-gallery .as-floating-header .alts-channel-hero,
    html body.single-gallery article[id^="post-"] section.alts-channel-hero {
      width: 100% !important;
      max-width: 100% !important;
      padding: 0 !important;
      margin: 0 !important;
    }

    /* ═══ MOBILE UP NEXT CARD ═══ */
    html body.single-gallery .entry-video .alts-mobile-upnext-card {
      position: absolute !important;
      bottom: 12px !important;
      right: 12px !important;
      left: auto !important;
      top: auto !important;
      display: flex !important;
      align-items: center !important;
      gap: 10px !important;
      width: auto !important;
      max-width: calc(100% - 24px) !important;
      height: auto !important;
      padding: 8px 12px 8px 8px !important;
      background: rgba(0,0,0,0.55) !important;
      backdrop-filter: blur(10px) saturate(1.2) !important;
      -webkit-backdrop-filter: blur(10px) saturate(1.2) !important;
      border: 1px solid rgba(255,255,255,0.12) !important;
      border-radius: 10px !important;
      box-shadow:
        inset 0 1px 0 rgba(255,255,255,0.08),
        inset 0 -1px 0 rgba(0,0,0,0.25),
        0 6px 20px rgba(0,0,0,0.35) !important;
      color: #fff !important;
      text-decoration: none !important;
      opacity: 0 !important;
      transform: translateY(8px) !important;
      pointer-events: none !important;
      transition: opacity 0.25s ease, transform 0.25s ease !important;
      z-index: 10 !important;
      font-family: 'Inter', system-ui, sans-serif !important;
    }
    html body.single-gallery .entry-video .alts-mobile-upnext-card.alts-upnext-visible {
      opacity: 1 !important;
      transform: translateY(0) !important;
      pointer-events: auto !important;
    }
    html body.single-gallery .alts-mobile-upnext-card .alts-mobile-upnext-thumb {
      flex: 0 0 auto !important;
      width: 72px !important;
      height: 42px !important;
      border-radius: 4px !important;
      overflow: hidden !important;
      background: #222 !important;
    }
    html body.single-gallery .alts-mobile-upnext-card .alts-mobile-upnext-thumb img {
      width: 100% !important;
      height: 100% !important;
      object-fit: cover !important;
      display: block !important;
    }
    html body.single-gallery .alts-mobile-upnext-card .alts-mobile-upnext-text {
      display: flex !important;
      flex-direction: column !important;
      gap: 2px !important;
      min-width: 0 !important;
      max-width: 180px !important;
    }
    html body.single-gallery .alts-mobile-upnext-card .alts-mobile-upnext-label {
      font-family: 'IBM Plex Mono', ui-monospace, monospace !important;
      font-size: 9px !important;
      font-weight: 500 !important;
      color: #BFFF00 !important;
      letter-spacing: 0.18em !important;
      text-transform: uppercase !important;
      line-height: 1 !important;
    }
    html body.single-gallery .alts-mobile-upnext-card .alts-mobile-upnext-title {
      font-family: 'Inter', system-ui, sans-serif !important;
      font-size: 12px !important;
      font-weight: 600 !important;
      color: #fff !important;
      line-height: 1.3 !important;
      white-space: nowrap !important;
      overflow: hidden !important;
      text-overflow: ellipsis !important;
    }
    html body.single-gallery .alts-mobile-upnext-card .as-upnext-artist { color: #fff !important; }
    html body.single-gallery .alts-mobile-upnext-card .as-upnext-dash { color: rgba(255,255,255,0.55) !important; margin: 0 3px !important; }
    html body.single-gallery .alts-mobile-upnext-card .as-upnext-song { color: rgba(255,255,255,0.75) !important; font-weight: 400 !important; }
    /* Ensure .entry-video is positioning context for the card */
    html body.single-gallery .entry-video {
      position: relative !important;
    }
    /* ═══ YMAL + OVERLAY FIX ═══ */
    /* Kill heavy black overlay on hero — keep background visible */
    html body.single-gallery.single-gallery .video-info-content section.alts-channel-hero::after,
    html body.single-gallery .video-info-content section.alts-channel-hero::after {
      background: transparent !important;
    }
    /* Show modal body (parent of YMAL) */
    html body.single-gallery header.as-floating-header .video-info-content .as-modal-body {
      display: block !important;
      width: 100% !important;
    }
    /* YMAL — match + exceed hiding rule specificity */
    html body.single-gallery header.as-floating-header .video-info-overlay .as-modal-ymal,
    html body.single-gallery .video-info-overlay .as-modal-ymal {
      display: none !important;
    }
    html body.single-gallery .video-info-overlay .as-modal-ymal-title {
      display: block !important;
      font-family: 'IBM Plex Mono', ui-monospace, monospace !important;
      font-size: 10px !important;
      font-weight: 500 !important;
      color: #BFFF00 !important;
      letter-spacing: 0.2em !important;
      text-transform: uppercase !important;
      margin: 0 0 12px !important;
    }
    /* YMAL grid — 1 column on mobile */
    html body.single-gallery .video-info-overlay .as-modal-ymal-grid,
    html body.single-gallery .as-modal-ymal-grid.alts-channel-grid {
      display: grid !important;
      grid-template-columns: 1fr !important;
      gap: 12px !important;
    }
    /* ═══ HIDE VIEWPORT LETTERBOXES ON MOBILE ═══ */
    html body.single-gallery div.as-viewport-letterbox,
    html body.single-gallery div.as-viewport-letterbox.top,
    html body.single-gallery div.as-viewport-letterbox.bottom,
    html body div.as-viewport-letterbox,
    html body div.as-viewport-letterbox.top,
    html body div.as-viewport-letterbox.bottom {
      display: none !important;
      opacity: 0 !important;
      visibility: hidden !important;
      pointer-events: none !important;
    }
    /* ═══ LIQUID GLASS CONTENT MODULE ═══ */
    html body.single-gallery .alts-channel-hero .alts-channel-hero-inner {
      background: rgba(0, 0, 0, 0.35) !important;
      backdrop-filter: blur(14px) saturate(1.2) !important;
      -webkit-backdrop-filter: blur(14px) saturate(1.2) !important;
      border: 1px solid rgba(255, 255, 255, 0.075) !important;
      border-radius: 12px !important;
      box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.08),
        inset 0 -1px 0 rgba(0, 0, 0, 0.25),
        0 8px 30px rgba(0, 0, 0, 0.4) !important;
      padding: 30px 16px 20px !important;
      box-sizing: border-box !important;
    }
    /* ═══ END YMAL + OVERLAY FIX ═══ */

    /* ═══ END MOBILE UP NEXT CARD ═══ */
  }
  /* ═══ END MOBILE CONTENT CLEANUP ═══ */

  /* ═══ NARROW VIEWPORT PROTECTIONS + MODAL POLISH ═══ */
  
  /* BASELINE: modal always scrolls when content overflows */
  html body .as-floating-header .video-info-content,
  html body .as-floating-header .video-info-overlay .video-info-content,
  html body header.as-floating-header .video-info-content,
  html body header.as-floating-header div.video-info-content,
  html body .video-info-wrapper .video-info-overlay .video-info-content {
    overflow: auto !important;
    overflow-x: hidden !important;
    overflow-y: auto !important;
    box-sizing: content-box !important;
    max-width: min(1100px, calc(100vw - 160px)) !important;
  }
  
  /* Close X: absolute, pinned top-right circle */
  html body .video-info-content .as-modal-close,
  html body button.as-modal-close {
    position: absolute !important;
    top: 20px !important;
    right: 20px !important;
    float: none !important;
    width: 44px !important;
    height: 44px !important;
    min-width: 44px !important;
    min-height: 44px !important;
    flex: none !important;
    aspect-ratio: 1 / 1 !important;
    border-radius: 50% !important;
    z-index: 100 !important;
    margin: 0 !important;
    align-self: auto !important;
  }
  
  /* SHORT viewport (≤1040px tall): cap modal height, anchor below nav, respect no-touch */
  @media (max-height: 1040px) {
    html body .as-floating-header .video-info-content,
    html body header.as-floating-header .video-info-content,
    html body header.as-floating-header div.video-info-content,
    html body .video-info-wrapper .video-info-overlay .video-info-content {
      max-height: calc(100vh - 230px) !important;
    }
    html body .video-info-wrapper .video-info-overlay {
      align-items: flex-start !important;
      padding-top: 130px !important;
      padding-bottom: 30px !important;
    }
    /* Footer hidden on short viewports */
    html body.single-gallery.wp-singular.as-modal-open footer#colophon,
    html body.single-gallery.wp-singular.as-modal-open footer#colophon.as-autohide,
    html body.single-gallery.single.as-modal-open footer#colophon,
    html body.single-gallery.wp-singular footer#colophon,
    html body.single-gallery.single footer#colophon {
      opacity: 0 !important;
      pointer-events: none !important;
      visibility: hidden !important;
    }
  }
  
  /* NARROW viewport (<1408px wide): footer hidden (cramped shortcuts), YMAL stays, title/eyebrow collision protected */
  @media (max-width: 1408px) {
    html body.single-gallery.wp-singular.as-modal-open footer#colophon,
    html body.single-gallery.wp-singular.as-modal-open footer#colophon.as-autohide,
    html body.single-gallery.single.as-modal-open footer#colophon,
    html body.single-gallery.wp-singular footer#colophon,
    html body.single-gallery.single footer#colophon {
      opacity: 0 !important;
      pointer-events: none !important;
      visibility: hidden !important;
    }
  }
  
  /* VERY NARROW viewport (<1200px wide): hide UP NEXT eyebrow (overlaps title) */
  @media (max-width: 1200px) {
    html body.single-gallery.as-modal-open .as-chrome-eyebrow,
    html body.single-gallery.as-modal-open.alts-chrome-hidden .as-chrome-eyebrow,
    html body.single-gallery.as-modal-open.ui-hidden .as-chrome-eyebrow {
      opacity: 0 !important;
      visibility: hidden !important;
      pointer-events: none !important;
      transition: opacity 0.35s ease !important;
    }
  }
  /* ═══ END NARROW VIEWPORT PROTECTIONS ═══ */

  

  /* ═══ RESPONSIVE PROTECTIONS + FINAL POLISH ═══ */
  
  /* "You Might Also Like" heading — shifted 10px right */
  html body .as-modal-ymal-title,
  html body h3.as-modal-ymal-title {
    padding-left: 10px !important;
    font-family: "IBM Plex Mono", ui-monospace, Menlo, monospace !important;
    font-size: 11px !important;
    font-weight: 700 !important;
    letter-spacing: 3px !important;
    text-transform: uppercase !important;
    color: rgba(255, 255, 255, 0.55) !important;
  }
  
  /* YMAL tile typography — smidge bigger */
  html body .alts-channel-tile .alts-tile-title,
  html body article.alts-channel-tile .alts-tile-title {
    font-size: 19px !important;
    line-height: 1.25 !important;
  }
  html body .alts-channel-tile .alts-tile-director,
  html body article.alts-channel-tile .alts-tile-director {
    font-size: 14px !important;
  }
  html body .alts-channel-tile .alts-tile-year,
  html body article.alts-channel-tile .alts-tile-year {
    font-size: 13px !important;
  }
  
  /* Title drop shadow — dispersed wide halo (updated from earlier tighter version) */
  html body.single-gallery h1.entry-title,
  html body.single-gallery h1.entry-title a,
  html body.single-gallery .as-chrome-cluster .entry-title,
  html body.single-gallery .as-floating-header .entry-title {
    text-shadow: none !important;
    filter:
      drop-shadow(0 0 120px rgba(0, 0, 0, 0.5))
      drop-shadow(0 0 80px rgba(0, 0, 0, 0.35))
      drop-shadow(0 0 40px rgba(0, 0, 0, 0.25))
      drop-shadow(0 8px 30px rgba(0, 0, 0, 0.35)) !important;
  }
  
  /* FOOTER HARD RULE: ONLY visible when .as-modal-open is on body — beats .as-autohide !important */
  html body.single-gallery footer#colophon.as-autohide,
  html body.single-gallery footer#colophon {
    opacity: 0 !important;
    pointer-events: none !important;
    visibility: hidden !important;
  }
  html body.single-gallery.as-modal-open footer#colophon.as-autohide,
  html body.single-gallery.as-modal-open footer#colophon {
    opacity: 1 !important;
    pointer-events: auto !important;
    visibility: visible !important;
  }
  
  /* Responsive: hide logo during modal on narrow viewports where it would collide */
  @media (max-width: 1500px) {
    html body.single-gallery.as-modal-open header.as-floating-header .as-chrome-logo-link,
    html body.single-gallery.as-modal-open a.as-chrome-logo-link,
    html body.single-gallery.as-modal-open.alts-chrome-hidden a.as-chrome-logo-link,
    html body.single-gallery.as-modal-open.ui-hidden a.as-chrome-logo-link {
      opacity: 0 !important;
      visibility: hidden !important;
      pointer-events: none !important;
      transition: opacity 0.35s ease, visibility 0s linear 0.35s !important;
    }
  }
  
  /* Responsive: fade footer menu on narrow viewports where shortcuts would be cramped */
  @media (max-width: 1408px) {
    html body.single-gallery footer#colophon,
    html body.single-gallery.as-modal-open footer#colophon,
    html body.single-gallery.as-modal-open.alts-chrome-hidden footer#colophon,
    html body.single-gallery.as-modal-open.ui-hidden footer#colophon {
      opacity: 0 !important;
      pointer-events: none !important;
      visibility: hidden !important;
      transition: opacity 0.35s ease, visibility 0s linear 0.35s !important;
    }
  }
  
  /* Responsive: cap modal height so it fits between top/bottom bars + footer */
  html body header.as-floating-header .video-info-content,
  html body header.as-floating-header div.video-info-content,
  html body .video-info-wrapper .video-info-overlay .video-info-content {
    max-height: calc(100vh - 360px) !important;
    overflow-y: auto !important;
  }
  /* Thin custom scrollbar on modal when content overflows */
  html body .video-info-content::-webkit-scrollbar {
    width: 6px !important;
  }
  html body .video-info-content::-webkit-scrollbar-track {
    background: transparent !important;
  }
  html body .video-info-content::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.15) !important;
    border-radius: 3px !important;
  }
  /* ═══ END RESPONSIVE PROTECTIONS ═══ */

  /* ═══ UNIFIED LIQUID GLASS (light top, dark bottom) ═══ */
  
  /* MODAL outline — 60% intensity */
  html body header.as-floating-header .video-info-content,
  html body header.as-floating-header div.video-info-content,
  html body .video-info-wrapper .video-info-overlay .video-info-content {
    border: 1px solid rgba(255, 255, 255, 0.18) !important;
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.3),
      inset 0 -1px 0 rgba(0, 0, 0, 0.18),
      inset 1px 0 0 rgba(255, 255, 255, 0.05),
      inset -1px 0 0 rgba(0, 0, 0, 0.15),
      0 20px 60px rgba(0, 0, 0, 0.45),
      0 4px 20px rgba(0, 0, 0, 0.25) !important;
  }
  
  /* YMAL tiles — 30% intensity */
  html body .as-modal-ymal article.alts-channel-tile,
  html body .as-modal-ymal-grid article.alts-channel-tile,
  html body .video-info-content article.alts-channel-tile,
  html body article.alts-channel-tile.as-modal-tile,
  html body article.alts-channel-tile {
    border: 1px solid rgba(255, 255, 255, 0.075) !important;
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.135),
      inset 0 -1px 0 rgba(0, 0, 0, 0.075),
      inset 1px 0 0 rgba(255, 255, 255, 0.04),
      inset -1px 0 0 rgba(0, 0, 0, 0.075),
      0 4px 20px rgba(0, 0, 0, 0.15) !important;
  }
  html body .as-modal-ymal article.alts-channel-tile:hover,
  html body .as-modal-ymal-grid article.alts-channel-tile:hover,
  html body .video-info-content article.alts-channel-tile:hover,
  html body article.alts-channel-tile.as-modal-tile:hover,
  html body article.alts-channel-tile:hover {
    border-color: rgba(255, 255, 255, 0.12) !important;
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.24),
      inset 0 -1px 0 rgba(0, 0, 0, 0.12),
      inset 1px 0 0 rgba(255, 255, 255, 0.06),
      inset -1px 0 0 rgba(0, 0, 0, 0.09),
      0 8px 32px rgba(0, 0, 0, 0.2) !important;
  }
  
  /* Station / Taunt button — glass outline only + slightly transparent bg so video bleeds through */
  html body button.as-more-by-artist,
  html body .as-chrome-cluster button.as-more-by-artist,
  html body button.as-taunt,
  html body .as-chrome-cluster button.as-taunt {
    background-color: rgba(10, 10, 10, 0.25) !important;
    border: 1px solid rgba(255, 255, 255, 0.075) !important;
    /* v1.5.27 — Explicit white text. Reported:the standard
       state was rendering BLACK because some global button reset
       was inheriting through. Force white at this specificity
       level to win cleanly. */
    color: rgba(255, 255, 255, 0.95) !important;
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.135),
      inset 0 -1px 0 rgba(0, 0, 0, 0.075),
      inset 1px 0 0 rgba(255, 255, 255, 0.04),
      inset -1px 0 0 rgba(0, 0, 0, 0.075),
      0 4px 20px rgba(0, 0, 0, 0.15) !important;
  }
  html body button.as-more-by-artist:hover,
  html body .as-chrome-cluster button.as-more-by-artist:hover,
  html body button.as-taunt:hover,
  html body .as-chrome-cluster button.as-taunt:hover {
    background-color: rgba(10, 10, 10, 0.35) !important;
    border-color: rgba(191, 255, 0, 0.45) !important;
    /* v1.5.27 — Hover gets AS green text + brand-accent border so
       there's visible engagement feedback. Was a no-op color-wise. */
    color: #BFFF00 !important;
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.24),
      inset 0 -1px 0 rgba(0, 0, 0, 0.12),
      inset 1px 0 0 rgba(255, 255, 255, 0.06),
      inset -1px 0 0 rgba(0, 0, 0, 0.09),
      0 8px 32px rgba(0, 0, 0, 0.2) !important;
  }
  /* v1.5.27 — Hover icon also flips to AS green so the whole pill
     reads as a brand-engaged state on cursor enter. */
  html body button.as-more-by-artist:hover i,
  html body .as-chrome-cluster button.as-more-by-artist:hover i {
    color: #BFFF00 !important;
  }

  /* v1.6.17 — Drop shadow gone (Flagged:it as noise; pill
     reads cleanly on its own at this size). var(--blend-color)
     stays for bg/border so the pill paints the blend's color. */
  html body button.as-more-by-artist.is-queued,
  html body .as-chrome-cluster button.as-more-by-artist.is-queued {
    background-color: var(--blend-color, #5a5e58) !important;
    border-color: var(--blend-color, #5a5e58) !important;
    box-shadow: none !important;
    color: #0a0f0a !important;
    text-shadow: none !important;
  }
  html body button.as-more-by-artist.is-queued:hover,
  html body .as-chrome-cluster button.as-more-by-artist.is-queued:hover,
  html body button.as-more-by-artist.is-queued:focus-visible,
  html body .as-chrome-cluster button.as-more-by-artist.is-queued:focus-visible {
    background-color: color-mix(in srgb, var(--blend-color, #5a5e58) 88%, #000) !important;
    border-color: color-mix(in srgb, var(--blend-color, #5a5e58) 88%, #000) !important;
    color: #0a0f0a !important;
  }
  html body button.as-more-by-artist.is-queued i,
  html body .as-chrome-cluster button.as-more-by-artist.is-queued i {
    color: #0a0f0a !important;
  }
  html body button.as-more-by-artist.is-queued .as-more-by-artist-label,
  html body .as-chrome-cluster button.as-more-by-artist.is-queued .as-more-by-artist-label {
    color: rgba(10, 15, 10, 0.7) !important;
  }
  html body button.as-more-by-artist.is-queued .as-more-by-artist-name,
  html body .as-chrome-cluster button.as-more-by-artist.is-queued .as-more-by-artist-name {
    color: #0a0f0a !important;
    text-shadow: none !important;
  }
  
  /* UP NEXT outer chrome container — full glass card */
  html body .as-chrome-eyebrow {
    background-color: rgba(0, 0, 0, 0.3) !important;
    backdrop-filter: blur(14px) saturate(1.2) !important;
    -webkit-backdrop-filter: blur(14px) saturate(1.2) !important;
    border: 1px solid rgba(255, 255, 255, 0.075) !important;
    border-radius: 8px !important;
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.135),
      inset 0 -1px 0 rgba(0, 0, 0, 0.075),
      inset 1px 0 0 rgba(255, 255, 255, 0.04),
      inset -1px 0 0 rgba(0, 0, 0, 0.075),
      0 4px 20px rgba(0, 0, 0, 0.15) !important;
    overflow: hidden !important;
  }
  
  /* UP NEXT inner (no duplicate bg/border) */
  html body .as-eyebrow-upnext {
    background: transparent !important;
    background-color: transparent !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    border: none !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    padding: 0 !important;
    margin: 0 !important;
    box-sizing: border-box !important;
    max-width: 100% !important;
  }
  html body .as-eyebrow-upnext-link {
    padding: 0 !important;
    margin: 0 !important;
    gap: 14px !important;
  }
  
  /* UP NEXT bigger thumbnail (76 → 92px) */
  html body #page img.as-eyebrow-upnext-thumb,
  html body img.as-eyebrow-upnext-thumb,
  html body .as-chrome-eyebrow img.as-eyebrow-upnext-thumb {
    width: clamp(64px, 4.8vw, 92px) !important;
    height: clamp(64px, 4.8vw, 92px) !important;
    max-width: 92px !important;
    max-height: 92px !important;
  }
  
  /* UP NEXT artist + song: Inter 700 tight tracking (main title font) */
  html body .as-upnext-artist {
    font-family: "Inter", system-ui, sans-serif !important;
    font-weight: 700 !important;
    font-size: 14px !important;
    letter-spacing: -0.02em !important;
    line-height: 1.2 !important;
    text-transform: none !important;
    color: rgba(255, 255, 255, 0.75) !important;
  }
  html body .as-upnext-song {
    font-family: "Inter", system-ui, sans-serif !important;
    font-weight: 700 !important;
    font-size: 20px !important;
    letter-spacing: -0.02em !important;
    line-height: 1.2 !important;
    text-transform: none !important;
    color: #fff !important;
  }
  html body .as-eyebrow-upnext-title {
    font-family: "Inter", system-ui, sans-serif !important;
    font-weight: 700 !important;
    letter-spacing: -0.02em !important;
  }
  
  /* Main title: smaller + wide soft halo via filter drop-shadow (like logo) */
  html body.single-gallery h1.entry-title,
  html body.single-gallery h1.entry-title a,
  html body.single-gallery .as-chrome-cluster .entry-title,
  html body.single-gallery .as-floating-header .entry-title {
    font-size: clamp(24px, 4vh, 56px) !important;
    text-shadow: none !important;
    filter:
      drop-shadow(0 0 60px rgba(0, 0, 0, 0.4))
      drop-shadow(0 0 30px rgba(0, 0, 0, 0.3))
      drop-shadow(0 4px 20px rgba(0, 0, 0, 0.35)) !important;
  }
  html body.single-gallery .as-chrome-cluster {
    filter: none !important;
  }
  
  /* v1.5.8.2 — Beam tractor under the UFO icon.
     The icon is fa-solid fa-ufo (no built-in beams). We render a beam
     as a CSS pseudo-element below the saucer:
       - clip-path: trapezoidal triangle (narrow top under the saucer
         widening to wider bottom) — looks like a tractor beam
       - linear gradient (accent green → transparent) so the beam
         fades out at its tip
       - blur for that "light haze" feel
       - opacity pulse on a 3.2s cycle, matching the existing breathing
         ambient timing so the saucer's behaviors feel coordinated
     This replaces the old asVinylSpinNudge rotation that pre-dated the
     icon swap (the rotation made sense for an info "i" but reads as a
     glitch on a UFO). */
  @keyframes asUfoBeam {
    0%, 100% { opacity: 0.30; transform: translateX(-50%) scaleY(0.92); }
    50%      { opacity: 0.85; transform: translateX(-50%) scaleY(1.05); }
  }
  html body .video-info-toggle.as-breathing {
    animation: none !important;
  }
  html body .video-info-toggle::after {
    content: '';
    position: absolute;
    left: 50%;
    /* Sits about 60% down from the top of the button — meaning the
       beam emerges from just under the saucer's hull. */
    top: 62%;
    width: 60%;
    height: 50%;
    transform-origin: 50% 0%;
    transform: translateX(-50%);
    /* Trapezoid: 38–62% top edge (narrow, tucked under saucer),
       10–90% bottom edge (wide flare). */
    clip-path: polygon(38% 0%, 62% 0%, 90% 100%, 10% 100%);
    background: linear-gradient(
      180deg,
      rgba(191, 255, 0, 0.55) 0%,
      rgba(191, 255, 0, 0.15) 60%,
      rgba(191, 255, 0, 0.00) 100%
    );
    filter: blur(1.2px);
    opacity: 0;
    pointer-events: none;
    animation: asUfoBeam 3.2s ease-in-out infinite;
    z-index: -1;
  }
  /* Pause the beam in cinema mode + when Mothership is open (the
     button is hidden in that state anyway, but stopping the animation
     also stops repaints). Reduced-motion: stop entirely. */
  html body.single-gallery.ui-hidden .video-info-toggle::after,
  html body.single-gallery.as-cursor-hidden .video-info-toggle::after,
  html body.alts-guide-open .video-info-toggle::after {
    animation-play-state: paused;
    opacity: 0;
  }
  @media (prefers-reduced-motion: reduce) {
    html body .video-info-toggle::after { animation: none !important; opacity: 0.4; }
  }
  /* ═══ END UFO BEAM ═══ */

  /* ═══ UP NEXT WIDGET POLISH ═══ */
  
  /* Container: bigger widget feel with more breathing room */
  html body .as-eyebrow-upnext {
    padding: 10px 14px !important;
    gap: 18px !important;
  }
  html body .as-eyebrow-upnext-link {
    gap: 18px !important;
    padding: 4px 8px !important;
  }
  html body .as-eyebrow-upnext-textcol {
    gap: 6px !important;
    padding: 2px 0 !important;
  }
  
  /* Thumbnail: scaled up (56 → 76px) with bigger responsive clamp */
  html body #page img.as-eyebrow-upnext-thumb,
  html body img.as-eyebrow-upnext-thumb,
  html body .as-chrome-eyebrow img.as-eyebrow-upnext-thumb {
    width: clamp(56px, 4.2vw, 76px) !important;
    height: clamp(56px, 4.2vw, 76px) !important;
    max-width: 76px !important;
    max-height: 76px !important;
  }
  
  /* "UP NEXT" label: match modal eyebrow style (IBM Plex Mono, 11px, 700, 3px tracking, uppercase, green) */
  html body .as-eyebrow-upnext .as-eyebrow-label,
  html body .as-eyebrow-upnext-labelrow .as-eyebrow-label {
    font-family: "IBM Plex Mono", ui-monospace, Menlo, monospace !important;
    font-size: 11px !important;
    font-weight: 700 !important;
    letter-spacing: 3px !important;
    text-transform: uppercase !important;
    color: #bfff00 !important;
  }
  
  /* v6 (April 2026): match the .as-chrome-cluster bottom anchor so the
     NP widget eyebrow column ends at the same y-coordinate as the title
     cluster on the left, and let the column size to its content. Pre-v6
     the rule below set bottom:70px (lifted 28px above the cluster) which
     left the eyebrow visibly higher than the cluster's bottom edge.
     v6.1 dropped a `min-height: 166px` we briefly tried — pinning the
     column to the cluster's full height left ~50px of empty space below
     the WATCHING + NP widget content, which read as awkward padding.
     Final state: bottom anchored to cluster bottom, no min-height, content
     vertically centered inside the auto-sized column. The column is now
     SHORTER than the cluster (cluster ~166px, eyebrow ~130px) but they
     share the same baseline — the cluster's title extends above the
     eyebrow which is fine asymmetry. */
  html body .as-chrome-eyebrow {
    box-sizing: border-box !important;
    bottom: var(--as-chrome-pad-y) !important;
    min-height: 0 !important;
    justify-content: center !important;
    margin-top: 0 !important;
  }
  /* ═══ END UP NEXT WIDGET POLISH ═══ */

  /* ═══ FOOTER ICON SIZE + SEPARATOR + TITLE + LIQUID GLASS UNIFIED ═══ */
  
  /* Function icons bigger (M removed, room to breathe) */
  html body #colophon .as-legend .as-item i.as-muted,
  html body #colophon .as-legend .as-item svg.as-muted,
  html body #colophon .as-legend .as-item > i,
  html body #colophon .as-legend .as-item > svg {
    font-size: 20px !important;
  }
  html body #colophon .as-legend .lead i,
  html body #colophon .as-legend .lead svg,
  html body #colophon .as-legend .lead i.fa-keyboard {
    font-size: 22px !important;
  }
  html body #colophon .as-legend .as-key i,
  html body #colophon .as-legend .as-key svg {
    font-size: 11px !important;
  }
  
  /* Player separator — subtle vertical line between utility and player groups */
  html body #colophon .as-legend .as-player-sep {
    display: inline-block !important;
    width: 1px !important;
    height: 18px !important;
    background: rgba(255, 255, 255, 0.2) !important;
    margin: 0 4px !important;
    flex-shrink: 0 !important;
  }
  
  /* Main title — responsive size scales with viewport height.
     v1.5.8.4 — line-height bumped from 1.1 to 1.25. The previous 1.1
     was tight enough that bold descenders (g, p, q, y) clipped at the
     overflow:hidden box (.as-chrome-cluster .entry-title sets
     overflow:hidden for ellipsis truncation, and h1.entry-title's box
     was sized to exactly line-height × font-size). 1.25 gives the
     letterforms enough room for descenders to clear, and the title
     row visually still reads as one tight line because we only ever
     render a single line (white-space: nowrap on the cluster rule). */
  html body.single-gallery h1.entry-title {
    font-size: clamp(28px, 5vh, 72px) !important;
    font-weight: 700 !important;
    line-height: 1.25 !important;
    letter-spacing: -0.02em !important;
    margin: 0 !important;
  }
  
  /* MODAL: unified liquid glass — bright top edge, dark bottom, side sheen */
  html body .as-floating-header .video-info-content {
    border: 1px solid rgba(255, 255, 255, 0.2) !important;
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.35),
      inset 0 -1px 0 rgba(0, 0, 0, 0.35),
      inset 1px 0 0 rgba(255, 255, 255, 0.12),
      inset -1px 0 0 rgba(255, 255, 255, 0.12),
      0 20px 60px rgba(0, 0, 0, 0.5),
      0 4px 20px rgba(0, 0, 0, 0.3) !important;
  }
  
  /* YMAL container: no bg, extends to hero container width */
  html body .as-modal-ymal {
    background: transparent !important;
    background-color: transparent !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    border: none !important;
    box-shadow: none !important;
    margin-left: -36px !important;
    margin-right: -36px !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
  }
  html body .as-modal-ymal::before,
  html body .as-modal-ymal::after {
    display: none !important;
  }
  
  /* Individual YMAL tiles: matching liquid glass + dark glass bg */
  html body .alts-channel-tile,
  html body article.alts-channel-tile {
    background-color: rgba(0, 0, 0, 0.3) !important;
    backdrop-filter: blur(14px) saturate(1.2) !important;
    -webkit-backdrop-filter: blur(14px) saturate(1.2) !important;
    border: 1px solid rgba(255, 255, 255, 0.2) !important;
    border-radius: 8px !important;
    overflow: hidden !important;
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.35),
      inset 0 -1px 0 rgba(0, 0, 0, 0.35),
      inset 1px 0 0 rgba(255, 255, 255, 0.12),
      inset -1px 0 0 rgba(255, 255, 255, 0.12),
      0 4px 20px rgba(0, 0, 0, 0.35) !important;
    transition: border-color 0.3s ease, box-shadow 0.3s ease, background-color 0.3s ease !important;
  }
  html body .alts-channel-tile:hover,
  html body article.alts-channel-tile:hover {
    background-color: rgba(0, 0, 0, 0.4) !important;
    border-color: rgba(255, 255, 255, 0.3) !important;
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.45),
      inset 0 -1px 0 rgba(0, 0, 0, 0.4),
      inset 1px 0 0 rgba(255, 255, 255, 0.18),
      inset -1px 0 0 rgba(255, 255, 255, 0.18),
      0 8px 32px rgba(0, 0, 0, 0.5) !important;
  }
  /* ═══ END UNIFIED LIQUID GLASS + FOOTER POLISH ═══ */

  /* ═══ YMAL TILE POLISH + MODAL BEHAVIOR REFINEMENTS ═══ */
  
  /* Tile director: clapperboard icon (open/regular) + AltSounds green */
  html body .alts-tile-director {
    display: inline-flex !important;
    align-items: center !important;
    gap: 8px !important;
  }
  html body .alts-tile-director i.fa-clapperboard {
    color: #bfff00 !important;
    font-size: 14px !important;
    flex-shrink: 0 !important;
  }
  /* Tile year: calendar icon (regular) + AltSounds green */
  html body .alts-tile-year {
    display: inline-flex !important;
    align-items: center !important;
    gap: 6px !important;
  }
  html body .alts-tile-year i.fa-calendar {
    color: #bfff00 !important;
    font-size: 13px !important;
    flex-shrink: 0 !important;
  }
  /* Top director clapperboard stays green */
  html body .as-meta-directed i.fa-clapperboard,
  html body .as-modal-meta-directed i.fa-clapperboard,
  html body .alts-meta-directed i.fa-clapperboard {
    color: #bfff00 !important;
  }
  
  /* YMAL tile images: darker static (55%), full brightness on hover + smooth scale */
  html body .alts-channel-tile .alts-tile-media img,
  html body .alts-channel-tile .alts-tile-img,
  html body article.alts-channel-tile .alts-tile-media img,
  html body article.alts-channel-tile .alts-tile-img,
  html body .video-info-content .alts-channel-tile .alts-tile-media img,
  html body .video-info-content .alts-channel-tile .alts-tile-img {
    filter: brightness(0.55) !important;
    transition: filter 0.4s ease, transform 0.5s cubic-bezier(0.22, 1, 0.36, 1) !important;
  }
  html body .alts-channel-tile:hover .alts-tile-media img,
  html body .alts-channel-tile:hover .alts-tile-img,
  html body article.alts-channel-tile:hover .alts-tile-media img,
  html body article.alts-channel-tile:hover .alts-tile-img,
  html body .video-info-content .alts-channel-tile:hover .alts-tile-media img,
  html body .video-info-content .alts-channel-tile:hover .alts-tile-img {
    filter: brightness(1) !important;
  }
  
  /* YMAL tile play button: outlined green + subtle blur, fills on tile hover ONLY */
  html body .alts-channel-tile span.alts-tile-play,
  html body .video-info-content span.alts-tile-play,
  html body article span.alts-tile-play,
  html body span.alts-tile-play {
    background-color: rgba(0, 0, 0, 0.25) !important;
    border: 2px solid #bfff00 !important;
    color: #bfff00 !important;
    backdrop-filter: blur(6px) saturate(1.2) !important;
    -webkit-backdrop-filter: blur(6px) saturate(1.2) !important;
    box-shadow: none !important;
  }
  html body span.alts-tile-play svg,
  html body span.alts-tile-play svg path {
    color: #bfff00 !important;
    fill: currentColor !important;
  }
  /* Hover: scoped strictly to .alts-channel-tile (not global anchor hover) */
  html body .alts-channel-tile:hover span.alts-tile-play,
  html body .video-info-content .alts-channel-tile:hover span.alts-tile-play,
  html body article.alts-channel-tile:hover span.alts-tile-play {
    background-color: #bfff00 !important;
    background: #bfff00 !important;
    color: #000 !important;
  }
  html body .alts-channel-tile:hover span.alts-tile-play svg,
  html body .alts-channel-tile:hover span.alts-tile-play svg path,
  html body article.alts-channel-tile:hover span.alts-tile-play svg,
  html body article.alts-channel-tile:hover span.alts-tile-play svg path {
    color: #000 !important;
    fill: currentColor !important;
  }
  
  /* Letterbox bars: transparent + no blur during modal (modal handles its own backdrop) */
  html body.single-gallery.as-modal-open div.as-viewport-letterbox.top,
  html body.single-gallery.as-modal-open div.as-viewport-letterbox.bottom,
  html body.single-gallery.as-modal-open.alts-chrome-hidden div.as-viewport-letterbox.top,
  html body.single-gallery.as-modal-open.alts-chrome-hidden div.as-viewport-letterbox.bottom,
  html body.single-gallery.as-modal-open.ui-hidden div.as-viewport-letterbox.top,
  html body.single-gallery.as-modal-open.ui-hidden div.as-viewport-letterbox.bottom {
    background: transparent !important;
    background-image: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    opacity: 1 !important;
    transform: translateY(0) !important;
  }
  html body.single-gallery.as-modal-open div.as-viewport-letterbox.top::before,
  html body.single-gallery.as-modal-open div.as-viewport-letterbox.bottom::before,
  html body.single-gallery.as-modal-open.alts-chrome-hidden div.as-viewport-letterbox.top::before,
  html body.single-gallery.as-modal-open.alts-chrome-hidden div.as-viewport-letterbox.bottom::before {
    display: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    background: transparent !important;
  }
  /* Bars: gradual background/blur transition (1.2s) for elegant reappearance on modal close */
  html body.single-gallery div.as-viewport-letterbox.top,
  html body.single-gallery div.as-viewport-letterbox.bottom,
  html body.single-gallery.alts-chrome-hidden div.as-viewport-letterbox.top,
  html body.single-gallery.alts-chrome-hidden div.as-viewport-letterbox.bottom {
    transition:
      opacity 0.5s cubic-bezier(0.4, 0, 0.2, 1),
      transform 0.5s cubic-bezier(0.4, 0, 0.2, 1),
      background 1.2s ease,
      background-color 1.2s ease,
      backdrop-filter 1.2s ease,
      -webkit-backdrop-filter 1.2s ease !important;
  }
  html body.single-gallery div.as-viewport-letterbox.top::before,
  html body.single-gallery div.as-viewport-letterbox.bottom::before {
    transition: backdrop-filter 1.2s ease, -webkit-backdrop-filter 1.2s ease, background 1.2s ease, opacity 1.2s ease !important;
  }
  
  /* Main-header transition sync to match bars/nav (0.5s cubic-bezier) */
  html body.single-gallery header.main-header,
  html body.single-gallery .main-header,
  html body.single-gallery header.main-header.as-autohide,
  html body.single-gallery .main-header.as-autohide {
    transition: opacity 0.5s cubic-bezier(0.4, 0, 0.2, 1), transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) !important;
  }
  /* ═══ END YMAL + MODAL REFINEMENTS ═══ */

  /* ═══ MODAL-AS-EXPERIENCE: footer reveal, chrome control, liquid glass, positioning ═══ */
  
  /* NAV pulled down 20px from top — reads as in-experience chrome not edge-of-screen */
  html body.single-gallery nav#navigation,
  html body.single-gallery.alts-chrome-hidden nav#navigation,
  html body.single-gallery.ui-hidden nav#navigation,
  html body.single-gallery.as-modal-open nav#navigation,
  html body.single-gallery.as-modal-open.alts-chrome-hidden nav#navigation {
    top: 20px !important;
  }
  
  /* FOOTER: hidden on page load, slides up + fades in ONLY when modal is open */
  html body.single-gallery footer#colophon,
  html body.single-gallery.alts-chrome-hidden footer#colophon,
  html body.single-gallery.ui-hidden footer#colophon,
  html body.single-gallery.alts-chrome-hidden.ui-hidden footer#colophon {
    opacity: 0 !important;
    pointer-events: none !important;
    visibility: hidden !important;
    bottom: 50px !important;
    transform: translateY(30px) !important;
    transition: opacity 0.35s ease, transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), visibility 0s linear 0.4s !important;
  }
  html body.single-gallery.as-modal-open footer#colophon,
  html body.single-gallery.as-modal-open.alts-chrome-hidden footer#colophon,
  html body.single-gallery.as-modal-open.ui-hidden footer#colophon,
  html body.single-gallery.as-modal-open.alts-chrome-hidden.ui-hidden footer#colophon {
    opacity: 1 !important;
    pointer-events: auto !important;
    visibility: visible !important;
    bottom: 50px !important;
    transform: translateY(0) !important;
    transition: opacity 0.45s ease 0.15s, transform 0.5s cubic-bezier(0.22, 1, 0.36, 1) 0.1s, visibility 0s linear 0s !important;
  }
  
  /* LETTERBOX BARS stay visible during modal (regardless of chrome-hidden) */
  html body.single-gallery.as-modal-open .as-viewport-letterbox.top,
  html body.single-gallery.as-modal-open .as-viewport-letterbox.bottom,
  html body.single-gallery.as-modal-open.alts-chrome-hidden .as-viewport-letterbox.top,
  html body.single-gallery.as-modal-open.alts-chrome-hidden .as-viewport-letterbox.bottom {
    transform: translateY(0) !important;
    opacity: 1 !important;
  }
  
  /* TOP NAV + MAIN HEADER stay visible during modal */
  html body.single-gallery.as-modal-open.alts-chrome-hidden nav#navigation,
  html body.single-gallery.as-modal-open.ui-hidden nav#navigation,
  html body.single-gallery.as-modal-open.alts-chrome-hidden.ui-hidden nav#navigation,
  html body.single-gallery.as-modal-open nav#navigation {
    opacity: 1 !important;
    visibility: visible !important;
    transform: translateY(0) !important;
    pointer-events: auto !important;
  }
  html body.single-gallery.as-modal-open .main-header,
  html body.single-gallery.as-modal-open header.main-header,
  html body.single-gallery.as-modal-open.alts-chrome-hidden .main-header,
  html body.single-gallery.as-modal-open.alts-chrome-hidden header.main-header,
  html body.single-gallery.as-modal-open.ui-hidden .main-header,
  html body.single-gallery.as-modal-open.ui-hidden header.main-header {
    opacity: 1 !important;
    visibility: visible !important;
    transform: translateY(0) !important;
    pointer-events: auto !important;
  }
  
  /* OTHER CHROME (burger, logo, eyebrow, cluster) stay visible during modal */
  html body.single-gallery.as-modal-open .alts-burger,
  html body.single-gallery.as-modal-open .as-chrome-logo-link,
  html body.single-gallery.as-modal-open .as-chrome-eyebrow,
  html body.single-gallery.as-modal-open .as-chrome-cluster,
  html body.single-gallery.as-modal-open.alts-chrome-hidden .alts-burger,
  html body.single-gallery.as-modal-open.alts-chrome-hidden .as-chrome-logo-link,
  html body.single-gallery.as-modal-open.alts-chrome-hidden .as-chrome-eyebrow,
  html body.single-gallery.as-modal-open.alts-chrome-hidden .as-chrome-cluster,
  html body.single-gallery.as-modal-open.ui-hidden .alts-burger,
  html body.single-gallery.as-modal-open.ui-hidden .as-chrome-logo-link,
  html body.single-gallery.as-modal-open.ui-hidden .as-chrome-eyebrow,
  html body.single-gallery.as-modal-open.ui-hidden .as-chrome-cluster {
    opacity: 1 !important;
    visibility: visible !important;
    transform: translateY(0) !important;
    pointer-events: auto !important;
  }
  
  /* i BUTTON: hidden when MOTHERSHIP is open (the panel IS the discovery
     surface there — showing the UFO trigger over it would be redundant).
     v1.5.8.2 — was previously gated on as-modal-open back when this
     button was an info-modal toggle. Now it opens Mothership, so we
     gate on alts-guide-open instead. */
  html body.single-gallery.alts-guide-open .video-info-toggle,
  html body.single-gallery.alts-guide-open.alts-chrome-hidden .video-info-toggle,
  html body.single-gallery.alts-guide-open.ui-hidden .video-info-toggle {
    opacity: 0 !important;
    pointer-events: none !important;
    visibility: hidden !important;
  }
  
  /* MODAL: liquid glass outline — 1px translucent border + layered glows for depth */
  html body .as-floating-header .video-info-content {
    border: 1px solid rgba(255, 255, 255, 0.12) !important;
    box-shadow:
      0 0 0 1px rgba(255, 255, 255, 0.04),
      inset 0 1px 0 rgba(255, 255, 255, 0.18),
      inset 0 -1px 0 rgba(0, 0, 0, 0.3),
      inset 0 0 0 1px rgba(255, 255, 255, 0.03),
      0 24px 80px rgba(0, 0, 0, 0.55),
      0 4px 20px rgba(0, 0, 0, 0.3),
      0 0 80px rgba(255, 255, 255, 0.04) !important;
  }
  
  /* MODAL scroll: content can exceed viewport on tall videos with lots of
     meta — the whole card scrolls internally. Earlier "content sizes
     naturally" intent got inverted: when content is SHORT, natural sizing
     works; when content is TALL, we need scroll OR it clips and the user
     can't reach the bottom. overflow-y: auto gives both behaviors.
     Fixed in drop 8 after user reported tall modals were unscrollable. */
  html body .as-floating-header .video-info-content,
  html body .as-floating-header .video-info-overlay .video-info-content {
      overflow-x: hidden !important;
      overflow-y: auto !important;
      height: auto !important;
      flex: none !important;
      flex-shrink: 0 !important;
  }
  /* Kill .as-modal-body extra padding-bottom — vic's 40px handles it */
  html body .as-floating-header .video-info-content .as-modal-body,
  html body .video-info-content .as-modal-body {
    padding-bottom: 0 !important;
  }
  /* ═══ END MODAL-AS-EXPERIENCE ═══ */

  /* ═══ LOGO DROP SHADOW + FOOTER SHORTCUT MENU POLISH ═══ */
  
  /* Logo drop shadow — soft diffused halo to protect against varied video backgrounds */
  html body .as-floating-header .as-chrome-logo-link img,
  html body .as-floating-header .as-chrome-logo-link img.tvlogo2,
  html body img.tvlogo2 {
    filter:
      drop-shadow(0 0 60px rgba(0, 0, 0, 0.35))
      drop-shadow(0 0 30px rgba(0, 0, 0, 0.25))
      drop-shadow(0 4px 20px rgba(0, 0, 0, 0.3)) !important;
  }
  
  /* Hide right-side informational footer nav on single-gallery (distracts from experience) */
  html body.single-gallery #colophon .footer-navigation,
  html body.single-gallery #colophon #menu-footer-menu {
    display: none !important;
  }
  
  /* Footer container — center horizontally */
  html body.single-gallery #colophon {
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
  }
  /* Footer info container — match modal width (1182px) and center */
  html body.single-gallery #colophon .footer-info {
    display: flex !important;
    justify-content: center !important;
    align-items: center !important;
    width: min(1182px, calc(100vw - 80px)) !important;
    max-width: 1182px !important;
    margin: 0 auto !important;
    flex: 0 0 auto !important;
    box-sizing: border-box !important;
  }
  
  /* Keyboard shortcut legend — refined typography, spread to match modal */
  html body #colophon .as-legend {
    gap: 16px !important;
    width: min(1182px, calc(100vw - 80px)) !important;
    max-width: 1182px !important;
    margin: 0 auto !important;
    justify-content: space-between !important;
    padding-left: 0 !important;
    font-family: "Inter", "Montserrat", system-ui, sans-serif !important;
    font-size: 12px !important;
    font-weight: 500 !important;
    letter-spacing: 0.02em !important;
    color: rgba(255, 255, 255, 0.65) !important;
    text-transform: uppercase !important;
  }

  /* v1.5.8 — Hide the footer (info container + keyboard shortcut legend)
     whenever the info modal or Mothership panel is open. Both surfaces
     are full-attention experiences; the chrome strip below distracts and,
     on shorter viewports, can poke up through the modal's bottom edge. */
  html body.as-modal-open #colophon .footer-info,
  html body.as-modal-open #colophon .as-legend,
  html body.alts-guide-open #colophon .footer-info,
  html body.alts-guide-open #colophon .as-legend {
    display: none !important;
  }
  
  /* Remove "|" separators */
  html body #colophon .as-legend > *:not(:last-child)::after {
    content: '' !important;
  }
  html body #colophon .as-legend .as-sep,
  html body #colophon .as-legend > span:not([class]) {
    display: none !important;
  }
  
  /* "Shortcuts:" lead label */
  html body #colophon .as-legend .lead {
    color: #bfff00 !important;
    font-weight: 600 !important;
    font-size: 11px !important;
    letter-spacing: 0.08em !important;
    opacity: 0.85 !important;
    gap: 8px !important;
    align-items: center !important;
  }
  /* Bigger keyboard icon in lead */
  html body #colophon .as-legend .lead i,
  html body #colophon .as-legend .lead svg,
  html body #colophon .as-legend .lead .fa-keyboard,
  html body #colophon .as-legend .lead i.fa-keyboard {
    font-size: 18px !important;
    opacity: 1 !important;
    margin-right: 2px !important;
    color: #bfff00 !important;
  }
  
  /* Shortcut items — clickable interactive feel */
  html body #colophon .as-legend .as-item {
    gap: 8px !important;
    color: rgba(255, 255, 255, 0.7) !important;
    font-weight: 500 !important;
    cursor: pointer !important;
    user-select: none !important;
    transition: transform 0.15s ease, color 0.15s ease !important;
  }
  html body #colophon .as-legend .as-item:hover {
    transform: translateY(-1px) !important;
    color: rgba(255, 255, 255, 0.95) !important;
  }
  html body #colophon .as-legend .as-item:active {
    transform: translateY(0) scale(0.97) !important;
  }
  
  /* Function icons BIGGER for at-a-glance clarity */
  html body #colophon .as-legend .as-item i.as-muted,
  html body #colophon .as-legend .as-item svg.as-muted,
  html body #colophon .as-legend .as-item > i,
  html body #colophon .as-legend .as-item > svg {
    font-size: 16px !important;
    color: rgba(255, 255, 255, 0.85) !important;
    opacity: 1 !important;
  }
  
  /* Keyboard key pill — frosted glass, premium */
  html body #colophon .as-legend .as-key {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    min-width: 22px !important;
    padding: 4px 9px !important;
    background: rgba(255, 255, 255, 0.06) !important;
    border: 1px solid rgba(255, 255, 255, 0.14) !important;
    border-radius: 6px !important;
    color: rgba(255, 255, 255, 0.95) !important;
    font-family: "SF Mono", ui-monospace, Menlo, monospace !important;
    font-size: 11px !important;
    font-weight: 600 !important;
    letter-spacing: 0.04em !important;
    line-height: 1 !important;
    text-transform: uppercase !important;
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.08),
      inset 0 -1px 0 rgba(0, 0, 0, 0.2),
      0 1px 2px rgba(0, 0, 0, 0.4) !important;
    backdrop-filter: blur(4px) !important;
    -webkit-backdrop-filter: blur(4px) !important;
    transition: all 0.2s ease !important;
  }
  html body #colophon .as-legend .as-key i,
  html body #colophon .as-legend .as-key svg {
    font-size: 11px !important;
  }
  
  /* "Curated by RIOT" styled like eyebrow label */
  html body #colophon .as-legend .as-item.as-curated {
    font-family: "Inter", system-ui, sans-serif !important;
    font-size: 11px !important;
    font-weight: 700 !important;
    letter-spacing: 2.5px !important;
    text-transform: uppercase !important;
    color: rgba(255, 255, 255, 0.5) !important;
    cursor: default !important;
    transform: none !important;
  }
  html body #colophon .as-legend .as-item.as-curated:hover {
    transform: none !important;
    color: rgba(255, 255, 255, 0.65) !important;
  }
  html body #colophon .as-legend .as-item.as-curated a {
    color: #bfff00 !important;
    text-decoration: none !important;
    transition: opacity 0.2s ease !important;
  }
  html body #colophon .as-legend .as-item.as-curated a:hover {
    opacity: 0.8 !important;
  }
  /* ═══ END FOOTER SHORTCUT MENU POLISH ═══ */

  /* ═══ LETTERBOX BARS + FULL-BLEED VIDEO + FOOTER CLEANUP ═══ */
  /* Heavy-blur frosted bars with feathered gradient masks. Two-layer blur (primary + pseudo extension)
     creates graduated blur from heavy at outer edge to clear video. Sync with chrome auto-hide. */
  
  /* TOP BAR — 180px, blur 80px, heavy tint, full gradient mask */
  html body.single-gallery div.as-viewport-letterbox.top,
  html body div.as-viewport-letterbox.top,
  html body .as-viewport-letterbox.top {
    display: block !important;
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    height: 180px !important;
    background: rgba(0, 0, 0, 0.15) !important;
    background-image: none !important;
    backdrop-filter: blur(80px) saturate(1.3) !important;
    -webkit-backdrop-filter: blur(80px) saturate(1.3) !important;
    mask-image: linear-gradient(to bottom, black 0%, transparent 100%) !important;
    -webkit-mask-image: linear-gradient(to bottom, black 0%, transparent 100%) !important;
    opacity: 1 !important;
    transform: translateY(0) !important;
    transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.5s cubic-bezier(0.4, 0, 0.2, 1) !important;
    pointer-events: none !important;
  }
  html body.single-gallery div.as-viewport-letterbox.top::before,
  html body div.as-viewport-letterbox.top::before,
  html body .as-viewport-letterbox.top::before {
    content: '' !important;
    position: absolute !important;
    top: 100% !important;
    left: 0 !important;
    right: 0 !important;
    height: 80px !important;
    backdrop-filter: blur(25px) saturate(1.2) !important;
    -webkit-backdrop-filter: blur(25px) saturate(1.2) !important;
    mask-image: linear-gradient(to bottom, black 0%, transparent 100%) !important;
    -webkit-mask-image: linear-gradient(to bottom, black 0%, transparent 100%) !important;
    pointer-events: none !important;
  }
  
  /* BOTTOM BAR — 160px + 100px pseudo, blur 120/40 */
  html body.single-gallery div.as-viewport-letterbox.bottom,
  html body div.as-viewport-letterbox.bottom,
  html body .as-viewport-letterbox.bottom {
    display: block !important;
    position: fixed !important;
    bottom: 0 !important;
    left: 0 !important;
    right: 0 !important;
    height: 160px !important;
    background: rgba(0, 0, 0, 0.15) !important;
    background-image: none !important;
    backdrop-filter: blur(120px) saturate(1.3) !important;
    -webkit-backdrop-filter: blur(120px) saturate(1.3) !important;
    mask-image: linear-gradient(to top, black 0%, transparent 100%) !important;
    -webkit-mask-image: linear-gradient(to top, black 0%, transparent 100%) !important;
    opacity: 1 !important;
    transform: translateY(0) !important;
    transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.5s cubic-bezier(0.4, 0, 0.2, 1) !important;
    pointer-events: none !important;
  }
  html body.single-gallery div.as-viewport-letterbox.bottom::before,
  html body div.as-viewport-letterbox.bottom::before,
  html body .as-viewport-letterbox.bottom::before {
    content: '' !important;
    position: absolute !important;
    bottom: 100% !important;
    left: 0 !important;
    right: 0 !important;
    height: 100px !important;
    backdrop-filter: blur(40px) saturate(1.2) !important;
    -webkit-backdrop-filter: blur(40px) saturate(1.2) !important;
    mask-image: linear-gradient(to top, black 0%, transparent 100%) !important;
    -webkit-mask-image: linear-gradient(to top, black 0%, transparent 100%) !important;
    pointer-events: none !important;
  }
  
  /* Sync with chrome auto-hide (bars slide out + fade when UI idle) */
  html body.alts-chrome-hidden:not(.alts-video-ending) .as-viewport-letterbox.top {
    transform: translateY(-100%) !important;
    opacity: 0 !important;
  }
  html body.alts-chrome-hidden:not(.alts-video-ending) .as-viewport-letterbox.bottom {
    transform: translateY(100%) !important;
    opacity: 0 !important;
  }
  html body.alts-video-ending .as-viewport-letterbox.top,
  html body.alts-video-ending .as-viewport-letterbox.bottom {
    transform: translateY(0) !important;
    opacity: 1 !important;
  }
  
  /* Full-bleed iframe */
  body.single-gallery iframe#asplayer {
    width: 100vw !important;
    height: 56.25vw !important;
    min-width: 177.78vh !important;
    min-height: 100vh !important;
    position: fixed !important;
    top: 50% !important;
    left: 50% !important;
    transform: translate(-50%, -50%) !important;
    pointer-events: none !important;
  }
  body #as-mousemove-catcher {
    z-index: 100 !important;
    pointer-events: auto !important;
  }
  
  /* Logo pushed down for breathing room */
  html body .as-floating-header .as-chrome-logo-link {
    top: 128px !important;
  }
  /* i button aligned with logo's vertical center */
  html body .as-floating-header .video-info-toggle,
  html body .video-info-toggle {
    top: 180px !important;
  }
  
  /* Kill navigation's own black gradient — blur bar handles backdrop */
  html body #navigation,
  html body nav#navigation,
  html body nav#navigation.clearfix {
    background: transparent !important;
    background-image: none !important;
  }
  
  /* Footer cleanup: kill gradient backdrop and green accent line */
  html body.single-gallery footer#colophon,
  html body.single-gallery footer#colophon.as-autohide,
  html body footer#colophon.as-autohide {
    background: transparent !important;
    background-image: none !important;
  }
  html body #colophon::before,
  html body footer#colophon::before,
  html body footer#colophon.as-autohide::before {
    display: none !important;
    content: none !important;
    background: transparent !important;
    background-image: none !important;
    height: 0 !important;
  }
  /* ═══ END LETTERBOX BARS ═══ */

  

  

  /* ═══ DESKTOP MODAL: interior info holder gets equal padding on all 4 sides ═══ */
  /* Was 30px top/bottom, 40px left/right → all 40px */
  html body .as-floating-header .video-info-content {
    padding: 40px !important;
  }

  /* Meta icons AltSounds green — universal (desktop modal + mobile single-gallery) */
  html body.single-gallery .alts-channel-meta i,
  html body.single-gallery .as-modal-meta i,
  html body.single-gallery .alts-channel-meta svg,
  html body.single-gallery .as-modal-meta svg,
  body .video-info-overlay .alts-channel-meta i,
  body .video-info-overlay .as-modal-meta i,
  body .video-info-overlay .alts-channel-meta svg,
  body .video-info-overlay .as-modal-meta svg {
    color: #bfff00 !important;
    fill: #bfff00 !important;
  }

/* ============================================================================
 * MOBILE — LANDSCAPE
 * Video fills viewport via CSS. Desktop-style chrome scaled. No info btn.
 * No footer, no menu. If user wants info, they go portrait.
 * ========================================================================= */
@media (max-width: 1024px) and (orientation: landscape) and (max-height: 500px) {
  body.single-gallery footer#colophon,
  body.single-gallery .main-header,
  body.single-gallery .video-info-toggle,
  body.single-gallery .alts-burger {
    display: none !important;
  }
  body.single-gallery #page,
  body.single-gallery #main,
  body.single-gallery #primary,
  body.single-gallery #content {
    padding: 0 !important; margin: 0 !important;
    max-width: 100vw !important; width: 100vw !important;
  }
  body.single-gallery .entry-video {
    position: fixed !important;
    inset: 0 !important;
    width: 100vw !important;
    height: 100vh !important;
    padding: 0 !important;
    margin: 0 !important;
    z-index: 1;
  }
  body.single-gallery .entry-video iframe {
    width: 100% !important;
    height: 100% !important;
    position: absolute !important;
    inset: 0 !important;
  }
  body.single-gallery .as-chrome-logo-link img {
    width: 72px !important;
    height: auto !important;
  }
  body.single-gallery .as-chrome-eyebrow {
    font-size: 12px;
    padding: 8px 10px;
    bottom: 16px !important;
    right: 16px !important;
  }
  body.single-gallery .as-eyebrow-upnext-thumb {
    width: 42px !important;
    height: 42px !important;
  }
  body.single-gallery .as-chrome-cluster {
    bottom: 16px !important;
    left: 16px !important;
    max-width: 40vw;
  }
  body.single-gallery .entry-title,
  body.single-gallery h1.entry-title {
    font-size: clamp(16px, 2.4vw, 22px) !important;
  }
  body.single-gallery .video-info-overlay { display: none !important; }
}

/* ============================================================================
 * REHYDRATION SKELETON (v1.1.8)
 *
 * When the server-rendered channel context (the post's primary term) differs
 * from the user's preferred term stored in alts_flow_v1, the page enters a
 * brief "settling" state: html.alts-rehydrating + body.alts-rehydrating is
 * applied, term-dependent chrome elements are hidden, and skeleton bars take
 * their place. The class is removed (~50-150ms typically) when the scope-API
 * call resolves, at which point chrome reveals in its correct final state.
 *
 * Without this, switching channel context client-side would briefly flash
 * the wrong text ("WATCHING HIP-HOP" → "WATCHING BEASTIE BOYS") which is
 * worse UX than a fast settle.
 *
 * Affected elements:
 *   - .as-eyebrow-current → "WATCHING X MUSIC VIDEOS" text strip
 *   - .as-eyebrow-upnext  → UP NEXT preview card (depends on scope)
 *   - .as-eyebrow-flavor  → flavor pill row (availability depends on scope)
 *
 * The skeletons are subtle thin bars matching the dimensions of what they
 * replace, so the layout doesn't shift when revealed.
 * ========================================================================== */

/* Hide the term-dependent text/elements during rehydration */
html.alts-rehydrating .as-eyebrow-current .as-eyebrow-prefix,
html.alts-rehydrating .as-eyebrow-current .as-eyebrow-link,
html.alts-rehydrating .as-eyebrow-current .as-eyebrow-suffix,
body.alts-rehydrating .as-eyebrow-current .as-eyebrow-prefix,
body.alts-rehydrating .as-eyebrow-current .as-eyebrow-link,
body.alts-rehydrating .as-eyebrow-current .as-eyebrow-suffix {
    visibility: hidden;
    position: relative;
}

/* Skeleton bar in place of the eyebrow text. Sized so layout doesn't shift.
 *
 * v4 fix (April 2026): added `position: relative` to .as-eyebrow-current
 * during rehydration so the absolute-positioned ::after resolves against
 * the eyebrow row (22px tall, the header strip with the cassette icon),
 * NOT against the entire NP widget container (130px tall — which placed
 * top:50% at y≈65px, dropping the skeleton on top of the song/artist
 * rows below).
 *
 * The author's top:50% / translateY(-50%) math was already perfect —
 * it just needed the right positioning context. .as-eyebrow-current is
 * `display:flex` and was static-positioned by default; one-line fix. */
body.alts-rehydrating .as-eyebrow-current,
html.alts-rehydrating .as-eyebrow-current {
    position: relative;
}
body.alts-rehydrating .as-eyebrow-current::after {
    content: '';
    position: absolute;
    left: 38px;          /* clear the icon */
    top: 50%;
    transform: translateY(-50%);
    width: 220px;
    height: 12px;
    border-radius: 4px;
    background: linear-gradient(90deg,
        rgba(255,255,255,0.06) 0%,
        rgba(255,255,255,0.14) 50%,
        rgba(255,255,255,0.06) 100%);
    background-size: 200% 100%;
    animation: alts-rehydrate-shimmer 1.4s ease-in-out infinite;
    pointer-events: none;
}

/* UP NEXT row: blank out title + thumb during rehydration. */
body.alts-rehydrating .as-eyebrow-upnext-title,
body.alts-rehydrating .as-eyebrow-upnext-thumb {
    visibility: hidden;
    position: relative;
}
body.alts-rehydrating .as-eyebrow-upnext-thumb::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: linear-gradient(90deg,
        rgba(255,255,255,0.06) 0%,
        rgba(255,255,255,0.14) 50%,
        rgba(255,255,255,0.06) 100%);
    background-size: 200% 100%;
    animation: alts-rehydrate-shimmer 1.4s ease-in-out infinite;
    visibility: visible;
}
body.alts-rehydrating .as-eyebrow-upnext-title::after {
    content: '';
    position: absolute;
    left: 0; top: 50%;
    transform: translateY(-50%);
    width: 160px;
    height: 11px;
    border-radius: 4px;
    background: linear-gradient(90deg,
        rgba(255,255,255,0.06) 0%,
        rgba(255,255,255,0.14) 50%,
        rgba(255,255,255,0.06) 100%);
    background-size: 200% 100%;
    animation: alts-rehydrate-shimmer 1.4s ease-in-out infinite;
    visibility: visible;
}

/* Flavor pills: dim during rehydration so users don't tap them while
   availability is in flight. Pills become tappable again the moment the
   class is removed. */
body.alts-rehydrating .as-eyebrow-flavor {
    opacity: 0.35;
    pointer-events: none;
    transition: opacity 0.18s ease;
}

@keyframes alts-rehydrate-shimmer {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

/* ============================================================================
   TITLE META LINE (April 2026 — v4 chrome cleanup)
   ----------------------------------------------------------------------------
   Second line under the entry title showing director (clapper icon) and
   release year (calendar icon). Replaces the inline "Title · 2005" span
   that used to live at the end of the H1. Director name links to that
   director's channel browse URL when the term lookup resolves.
   ============================================================================ */
.as-title-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin: -2px 0 8px 0;      /* v6.4 — title→meta ~8px (cluster gap 10 + this
                                  -2 top). v6.5 — added 8px bottom so meta→taunt
                                  is ~18px (gap 10 + 8): clearer break before the
                                  taunt than the title→meta gap, . */
    padding: 0;
    font-size: 17px;
    font-weight: 400;
    line-height: 1.3;
    color: rgba(255, 255, 255, 0.75);
    letter-spacing: 0.01em;
    /* Stacked halo so the meta line stays legible on bright/low-contrast
       video frames (white walls, daylight scenes, etc). Same vibe as the
       title's drop-shadow stack above, scaled down for smaller text. */
    filter:
        drop-shadow(0 0 30px rgba(0, 0, 0, 0.45))
        drop-shadow(0 0 14px rgba(0, 0, 0, 0.35))
        drop-shadow(0 2px 8px rgba(0, 0, 0, 0.45));
}
/* v6.0.22 — Blend pill next to the title. Replaces the previous
   colored-meta-item that lived inside the director/year line.
   Sits in .as-title-row right after the H1; background is the blend's
   palette color, icon + name in white so the pill reads as a chip
   rather than tinted text. Injected by altsounds-np.js's
   syncTitleBlendPill when the playing track came from an active blend. */
/* v1.6.15 — Mirrors the NP widget blend chip recipe: dark text +
   icon on the blend's palette color, mono-caps 9px, no drop shadow.
   Extra left margin separates it from the director/year cluster so
   the pill reads as its own scope tag, not part of the meta line. */
.as-title-blend-pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 10px;
    border-radius: 999px;
    background: #888;  /* overridden inline with the blend color */
    color: #0a0b0a;
    text-decoration: none;
    cursor: pointer;
    line-height: 1;
    text-shadow: none;
    transition: filter 0.15s ease, transform 0.15s ease;
    flex: 0 0 auto;
    margin-left: 18px;
}
.as-title-blend-pill:hover,
.as-title-blend-pill:focus-visible {
    filter: brightness(0.92);
    transform: translateY(-1px);
    outline: none;
}
.as-title-blend-pill__icon {
    font-size: 11px;
    color: #0a0b0a !important;
    text-shadow: none;
}
.as-title-blend-pill__name {
    color: #0a0b0a;
    font: 700 9px/1 var(--alts-mono, 'IBM Plex Mono', monospace);
    letter-spacing: 0.12em;
    text-transform: uppercase;
}
.as-title-meta-icon {
    font-size: 14px;
    color: rgba(255, 255, 255, 0.55);
    flex: 0 0 auto;
}
.as-title-meta-genre,
.as-title-meta-director,
.as-title-meta-director-link {
    /* v5 (April 2026): matched to year. Was 500 weight + 0.88 alpha — too
       heavy next to the year. Now both director and year share the same
       weight (400) and color (0.78 alpha) so they read as one balanced
       metadata line, neither competing with the title above.
       v2.18 — genre joins the row (leading item) and shares the exact same
       text treatment so the line reads as one balanced run. */
    color: rgba(255, 255, 255, 0.78);
    font-weight: 400;
    text-decoration: none;
    transition: color 0.15s ease;
}
.as-title-meta-director-link:hover,
.as-title-meta-director-link:focus-visible {
    color: #BFFF00;
    outline: none;
}
/* v2.18.x — transparent wrapper that makes a meta item (genre / director /
   year) clickable as a Stage tax-hop WITHOUT changing its look. It's a flex
   box with the SAME 10px gap as the parent .as-title-meta, so the icon↔text
   spacing is byte-identical to the un-wrapped version; it inherits the meta
   color and carries no underline. Only the cursor signals it's a link. */
.as-title-meta-link {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    color: inherit;
    text-decoration: none;
    cursor: pointer;
}
.as-title-meta-link:hover,
.as-title-meta-link:focus-visible { color: inherit; text-decoration: none; outline: none; }
.as-title-meta-sep {
    color: rgba(255, 255, 255, 0.35);
    margin: 0 2px;
}
.as-title-meta-year {
    /* Match director's weight and color — see note above. */
    color: rgba(255, 255, 255, 0.78);
    font-weight: 400;
    font-variant-numeric: tabular-nums;
}

/* v6.0.2 (April 2026): views as a third meta item, populated by JS at
   runtime via the YT Data API hydrator (post-video.inc.php). Matches
   director and year visually — same weight, same color, tabular-nums
   so the digits align across pages. The compact format "234M views"
   keeps the line tight enough to fit the cluster column even with a
   long director name. */
.as-title-meta-views {
    color: rgba(255, 255, 255, 0.78);
    font-weight: 400;
    font-variant-numeric: tabular-nums;
}
/* v2.18 — Admin-only edit pencil, inline at the END of the meta row (same
   line as genre · director · year · views). Subtle by default (quieter than
   the meta text so it never competes), lifts to brand lime on hover/focus.
   Only rendered server-side for users who can edit. */
.as-title-meta-edit {
    display: inline-flex;
    align-items: center;
    margin-left: 8px;
    color: rgba(255, 255, 255, 0.45);
    font-size: 13px;
    text-decoration: none;
    transition: color 0.15s ease;
}
.as-title-meta-edit:hover,
.as-title-meta-edit:focus-visible {
    color: #BFFF00;
    outline: none;
}
/* Hide the entire (icon + sep + span) views fragment until the JS
   hydrator fills the span. Without this, the user would briefly see
   "Director · 1990 ·  👁 " (orphan icon + dangling separator) before
   stats arrive, then content snap in. With it, the line shows just
   "Director · 1990" until stats arrive, then "Director · 1990 · 👁 234M
   views" appears as one atomic update. The :empty + adjacent-sibling
   selectors target the icon and the separator that immediately precede
   an empty .as-title-meta-views. */
.as-title-meta .as-title-meta-views:empty {
    display: none;
}
.as-title-meta .as-title-meta-icon--eye {
    /* Hide the eye icon while views span is empty. Uses :has() so we
       only hide when the views span IS empty. Modern browser fallback
       below for non-:has browsers. */
    transition: opacity 0.18s ease;
}
.as-title-meta:has(.as-title-meta-views:empty) .as-title-meta-icon--eye {
    display: none;
}
.as-title-meta:has(.as-title-meta-views:empty) .as-title-meta-icon--eye + .as-title-meta-views {
    /* belt-and-braces; the :empty rule above already handles this */
    display: none;
}
/* Also hide the separator immediately preceding the eye icon when
   views are empty, so we don't get a dangling " · " at the end. */
.as-title-meta:has(.as-title-meta-views:empty) .as-title-meta-icon--eye {
    display: none;
}
.as-title-meta:has(.as-title-meta-views:empty) > .as-title-meta-sep:nth-last-of-type(1) {
    display: none;
}
/* Fallback for browsers without :has() — the icon stays visible briefly
   (until JS populates the span) but the empty span itself is hidden so
   it doesn't take horizontal space. The :has() rule wins on supporting
   browsers. */

/* ============================================================================
   MOBILE CONTROLS — DESKTOP KILL (v5, April 2026)
   ----------------------------------------------------------------------------
   Defense-in-depth for the mobile-only nav buttons (#alts-mobile-controls).
   The injection is now gated on viewport width in mobile-menu.js, but if
   the buttons somehow land in the DOM at >991px (cached state, ResizeObserver
   timing, manual injection from console, etc.), this rule keeps them hidden.
   The mobile media query later in this file re-shows them via display: flex.
   ============================================================================ */
#alts-mobile-controls {
    display: none;
}
@media (max-width: 991px) {
    #alts-mobile-controls {
        display: flex;
    }
}

/* ============================================================================
 * v1.1.20 — Station pill (.as-more-by-artist)
 * ============================================================================
 * Replaces the taunt pill on artist pages where the artist has 5+ videos.
 * Same visual footprint as the taunt so the layout doesn't shift, but the
 * affordance is "tune in to this artist's station" — clicking turns the
 * queue into an artist-station mode that keeps playing this artist's
 * catalog. Pressed-state mirrors the NP rail's station toggle.
 * ========================================================================== */

.as-chrome-cluster .as-more-by-artist {
    appearance: none;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 16px 9px 12px;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 999px;
    color: rgba(255, 255, 255, 0.92);
    font-family: inherit;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition:
        background 0.18s ease,
        border-color 0.18s ease,
        color 0.18s ease,
        transform 0.18s ease;
    /* Match taunt's spatial position: sits inline below the title in the
       chrome cluster. No max-width — the artist name dictates length. */
    line-height: 1;
}

html body .as-chrome-cluster .as-more-by-artist,
html body button.as-more-by-artist {
    display: none !important;
}

.as-chrome-cluster .as-more-by-artist:hover,
.as-chrome-cluster .as-more-by-artist:focus-visible {
    background: rgba(191, 255, 0, 0.10);
    border-color: rgba(191, 255, 0, 0.40);
    color: #BFFF00;
    outline: none;
    transform: translateY(-1px);
}

.as-chrome-cluster .as-more-by-artist i.fa-tower-broadcast {
    font-size: 14px;
    color: #BFFF00;
    transition: transform 0.18s ease;
}

.as-chrome-cluster .as-more-by-artist:hover i.fa-tower-broadcast {
    transform: scale(1.08);
}

/* v1.6.14 — Active blend pill paints in the BLEND'S palette color,
   not hardcoded AS green. The previous v1.1.22 rule predated the
   station→blend rename and locked the active state to #BFFF00;
   single-gallery-queue.js was setting --blend-color correctly all
   along but this more-specific rule was overriding it. Now the
   color flows through the var so Bring Me The Horizon paints red,
   Bad Omens paints whatever its palette resolves to, etc. The halo
   animation is dropped — the colored pill is already a strong
   enough "this is on" signal, and an AS-green halo around a red
   pill was the mixed-signal kept flagging. */
.as-chrome-cluster .as-more-by-artist[aria-pressed="true"],
html[data-queue-station-active="1"] .as-chrome-cluster .as-more-by-artist {
    background: var(--blend-color, #BFFF00);
    border-color: var(--blend-color, #BFFF00);
    color: #0a0d0a;
    box-shadow: none;
}
.as-chrome-cluster .as-more-by-artist[aria-pressed="true"] i,
html[data-queue-station-active="1"] .as-chrome-cluster .as-more-by-artist i {
    color: #0a0d0a;
}
/* v1.6.14 — Full text, no truncation. Decision: long blend
   names should read in full ("Bring Me The Horizon Blend
   Activated"), not ellipsize at a fixed pixel width. The pill
   sits on a flex row that wraps, so a longer pill pushes itself
   to the next line cleanly rather than overflowing. */
.as-chrome-cluster .as-more-by-artist-text {
    white-space: normal;
    overflow: visible;
}

/* ============================================================================
 * v1.1.20 — Info modal description: Inter font
 * ============================================================================
 * The .as-modal-description block in the info modal was inheriting IBM Plex
 * Mono from a parent rule. Force Inter (the AltSounds primary sans) so
 * editorial copy reads as prose, not as code.
 * ========================================================================== */
.as-modal-description,
.as-modal-description p,
.as-modal-description li {
    font-family: "Inter", system-ui, -apple-system, sans-serif !important;
    font-size: 15px;
    line-height: 1.65;
}
.as-modal-description h1,
.as-modal-description h2,
.as-modal-description h3,
.as-modal-description h4,
.as-modal-description h5,
.as-modal-description h6,
.as-modal-description strong,
.as-modal-description em {
    font-family: "Inter", system-ui, -apple-system, sans-serif !important;
}

/* ============================================================================
 * v1.1.28 — SAFARI BLACK-BAR FIX, CONFIRMED VIA LIVE TEST
 * ============================================================================
 *
 * The breakthrough: in Safari, on single-gallery, the body element
 * was naturally only ~582px tall (most content is position:fixed and
 * removed from layout flow). Below 582px, Safari fell back to the
 * system canvas (light grey) regardless of body bg. The iframe's
 * paint region didn't extend to fill the gap.
 *
 * Fix (3-part, all required):
 *   A. body.single-gallery: transparent (don't double-paint with html)
 *   B. html (when single-gallery): #000 (canvas color)
 *   C. body.single-gallery: min-height:100vh + height:100vh
 *      → body now extends the full viewport height. With body
 *        transparent and html #000, the entire viewport is reliably
 *        #000 wherever the iframe doesn't paint.
 *
 * The iframe stays center-anchored (top:50%; left:50%; transform:
 * translate(-50%,-50%)) — this hides YouTube's title chrome above
 * the visible viewport. Top:0 anchoring exposed it.
 * ============================================================================ */

body.single-gallery {
    background: transparent !important;
    background-color: transparent !important;
}
html.single-gallery,
html:has(body.single-gallery) {
    background: #000 !important;
    background-color: #000 !important;
}
body.single-gallery {
    min-height: 100vh !important;
    height: 100vh !important;
    min-height: 100dvh !important;
}

/* ============================================================================
 * v1.1.29 — SAFARI TITLE-BACKGROUND FIX
 * ============================================================================
 *
 * Diagnosis from Safari live DOM probe: the dark band behind the title
 * is the YouTube iframe's own background-image — the per-video poster
 * JPG.
 *
 * Origin: post-video.inc.php sets `<div id="asplayer" style="background:
 * url(POSTER) center center / cover no-repeat;">` so the user sees the
 * poster image BEFORE YouTube's player JS loads. After YouTube swaps
 * #asplayer for its actual iframe, the inline `background: url(...)`
 * stays on the new iframe element. Chrome's iframe compositor paints
 * fully-opaque so this bg is hidden behind YouTube's content. Safari
 * leaves the iframe's transparent edge regions visible, exposing the
 * poster bg-image, which reads as a "dark band" behind the title text.
 *
 * Fix: kill the background-image on iframe#asplayer specifically. The
 * div#asplayer (pre-iframe placeholder) retains its bg — same selector
 * but `iframe` qualifier means the rule only kicks in after YouTube
 * swaps the div for an iframe. So:
 *   - BEFORE play: div#asplayer shows the poster (good)
 *   - AFTER YouTube swap: iframe#asplayer has no bg-image (Safari band gone)
 * No timing logic, no JS. Pure CSS targeting.
 * ============================================================================ */

body.single-gallery iframe#asplayer {
    background: transparent !important;
    background-image: none !important;
}

/* ============================================================================
 * v1.1.30 — SAFARI TITLE-SHADOW + AS PLAY BUTTON ALIGNMENT
 * ============================================================================
 *
 * Two final Safari fixes:
 *
 * (A) TITLE "DARK BAND" — root cause identified.
 *
 * The dark rectangle that sticks to the title and resizes with viewport
 * is NOT the iframe poster. It's the title's own `filter: drop-shadow`
 * stack rendering as a hard composited rectangle in Safari instead of
 * a per-glyph soft halo (which Chrome does correctly).
 *
 * Origin: line 3941 stacks three `drop-shadow` filters on h1.entry-title
 * including a 60px-blur outer halo. Safari's filter compositor falls back
 * to a rectangular bounding-box shadow when stacked drop-shadows exceed
 * its per-glyph budget — producing a dark rounded-rectangle that tracks
 * the title's bounding box at every viewport size.
 *
 * Fix: replace `filter: drop-shadow(...)` with `text-shadow` on Safari
 * by overriding to text-shadow stack at higher specificity. text-shadow
 * is per-glyph in every browser. Visual is functionally identical (soft
 * dark halo for legibility on bright video frames) but Safari renders
 * it correctly. The filter:none on .as-chrome-cluster is preserved
 * (no change in behavior at the wrapper level).
 *
 * (B) AS PLAY BUTTON ALIGNMENT — re-anchor to iframe, not viewport.
 *
 * The `.as-fullscreen-play` overlay is `position: fixed; inset: 0` —
 * centered in the VIEWPORT. YouTube's red play button is centered in
 * the IFRAME minus YouTube's own internal chrome (top title bar +
 * bottom controls strip). With the iframe centered via translate(-50%,
 * -50%), YouTube's play button sits a few px above viewport center
 * because its internal chrome biases the visible area downward.
 *
 * Fix: anchor the AS play button to .entry-video (iframe parent) and
 * shift it down by ~6vh to match YouTube's actual play-button center.
 * This way both buttons align regardless of viewport size or aspect
 * ratio.
 * ============================================================================ */

/* ============================================================================
 * v1.1.31 — CORRECTING v1.1.30 OVERSHOOTS
 * ============================================================================
 *
 * (A) Shadow: v1.1.30's text-shadow used same numeric values as the
 * original drop-shadow (60/30/20px blur, 0.4-0.55 alpha). text-shadow
 * blur radii are perceptually 3-4× stronger than drop-shadow blur
 * radii at the same px value, so the result was a giant haze around
 * the title — visible even on light backgrounds.
 *
 * Fix: scale blur radii down to ~1/3 and lower alpha. Keeps the
 * "soft dark halo for legibility on bright video frames" intent
 * without bleeding the shadow across half the screen.
 *
 * (B) AS play button: v1.1.30 added align-items:flex-start +
 * padding-top:50vh + translateY(-50% + 1.5vh) — too clever, broke
 * positioning. Revert to clean viewport-center: the iframe is
 * already viewport-centered, YouTube's play button is iframe-
 * centered, so they should naturally coincide if AS button is also
 * viewport-centered. Just reset to the base inset:0 + center flex.
 * If they STILL don't align, that's a YT-internal-chrome offset
 * issue we'll measure with a probe rather than guess at.
 * ============================================================================ */

/* (A) Title shadow — softer values, won't bleed across the screen */
html body.single-gallery h1.entry-title,
html body.single-gallery h1.entry-title a,
html body.single-gallery .as-chrome-cluster .entry-title,
html body.single-gallery .as-floating-header .entry-title {
    filter: none !important;
    text-shadow:
        0 2px 8px rgba(0, 0, 0, 0.55),
        0 0 16px rgba(0, 0, 0, 0.35) !important;
}

/* (B) AS play button — revert v1.1.30 positioning hacks */
html body.single-gallery .as-fullscreen-play {
    align-items: center !important;
    padding-top: 0 !important;
}
html body.single-gallery .as-fullscreen-play .btn {
    transform: none !important;
}

/* ============================================================================
 * v1.1.32 — KILL THE FONT SWAP SHIFT
 * ============================================================================
 *
 * Root cause: altsounds-guide/assets/guide.css declares Inter and
 * IBM Plex Mono webfaces with `font-display: swap`. On every fresh
 * page load:
 *   1. System fallback (system-ui) renders title/meta immediately
 *   2. ~200-500ms later, Inter woff2 finishes downloading
 *   3. Browser swaps to Inter → letter widths/heights shift
 *   4. User sees the title and meta visibly reflow
 *
 * Fix: override every @font-face for Inter and IBM Plex Mono to use
 * `font-display: optional` instead. Behavior:
 *   - 100ms invisible block period (text hidden while font tries to load)
 *   - Within 100ms → use the font (no swap, nothing was painted yet)
 *   - Past 100ms → use fallback and DO NOT swap for this page load
 *
 * After first visit, the font is browser-cached and arrives in <10ms
 * on every subsequent load → Inter from the start, zero shift, ever.
 * First visit on a fresh device may briefly show fallback, but no
 * mid-page jump. This is the YouTube/Twitter approach for stable
 * typography on text-critical pages.
 * ============================================================================ */

@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 400;
    font-display: optional;
    src: url('/wp-content/plugins/altsounds-guide/assets/fonts/inter-400.woff2') format('woff2');
}
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 500;
    font-display: optional;
    src: url('/wp-content/plugins/altsounds-guide/assets/fonts/inter-500.woff2') format('woff2');
}
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 600;
    font-display: optional;
    src: url('/wp-content/plugins/altsounds-guide/assets/fonts/inter-600.woff2') format('woff2');
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: optional;
    src: url('/wp-content/plugins/altsounds-guide/assets/fonts/ibm-plex-mono-400.woff2') format('woff2');
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 500;
    font-display: optional;
    src: url('/wp-content/plugins/altsounds-guide/assets/fonts/ibm-plex-mono-500.woff2') format('woff2');
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 600;
    font-display: optional;
    src: url('/wp-content/plugins/altsounds-guide/assets/fonts/ibm-plex-mono-600.woff2') format('woff2');
}

