/* Immersion: Hero canvas nebula + Memorial cursor glow */
@layer components {
    .hero-canvas-nebula {
        position: absolute;
        inset: 0;
        z-index: 2;
        pointer-events: none;
        width: 100%;
        height: 100%;
    }

    .memorial-cursor-glow {
        position: fixed;
        top: 0;
        left: 0;
        width: 20px;
        height: 20px;
        border-radius: 50%;
        background: radial-gradient(circle, oklch(0.82 0.14 85 / 0.08) 0%, transparent 70%);
        pointer-events: none;
        z-index: 9999;
        will-change: transform;
        opacity: 0;
        transition: opacity 0.3s;
        mix-blend-mode: screen;
    }
}

@media (prefers-reduced-motion: reduce) {
    .hero-canvas-nebula,
    .memorial-cursor-glow {
        display: none !important;
    }
}
/* ==========================================================================
   Scroll Motion — Lenis smooth-scroll & GSAP integration styles
   ========================================================================== */

/* Lenis requirements */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }

/* Prevent double-animation: when GSAP manages reveals, disable CSS versions */
.gsap-managed [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
    animation-timeline: none !important;
}
.gsap-managed .scroll-reveal,
.gsap-managed .scroll-reveal-scale,
.gsap-managed .scroll-reveal-left {
    animation: none !important;
    animation-timeline: none !important;
}

/* Reduced motion: undo Lenis classes */
@media (prefers-reduced-motion: reduce) {
    .lenis.lenis-smooth { scroll-behavior: smooth; }
    html.lenis, html.lenis body { height: auto; }
    .gsap-managed [data-reveal] { opacity: 1 !important; transform: none !important; }
}
/* Player Waveform Canvas - v1.0.0 */
.pw-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
  border-radius: inherit;
}

/* Hover time tooltip via data attribute */
.smp-progress-bar[data-hover-time]:not([data-hover-time=""])::before {
  content: attr(data-hover-time);
  position: absolute;
  bottom: calc(100% + 6px);
  left: var(--hover-x, 50%);
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.85);
  color: #fff;
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 3px;
  pointer-events: none;
  z-index: 10;
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  .pw-canvas { opacity: 0.5; }
}
/* Player Skin — Frosted Glass Concert Stage v1.0
   CSS-only cinematic overlay for SimpleMusicPlayer (.smp-*)
   -------------------------------------------------------- */

/* === CONTAINER === */
.smp-player {
    background: linear-gradient(135deg, rgba(20,20,22,0.92), rgba(30,30,36,0.88));
    backdrop-filter: blur(24px) saturate(1.8);
    -webkit-backdrop-filter: blur(24px) saturate(1.8);
    border-top: 1px solid rgba(255,255,255,0.06);
    box-shadow: 0 -8px 32px rgba(0,0,0,0.4), 0 -1px 0 rgba(220,38,38,0.1);
}

/* === ALBUM ART === */
.smp-art {
    box-shadow: 0 4px 20px rgba(0,0,0,0.5), 0 0 40px rgba(220,38,38,0.08);
    border-color: rgba(255,255,255,0.08);
    transition: box-shadow 0.4s var(--ease-standard, cubic-bezier(0.4,0,0.2,1)),
                border-color 0.3s ease;
}
.smp-art img {
    transition: transform 0.8s var(--ease-standard, cubic-bezier(0.4,0,0.2,1));
}
.smp-art.playing img {
    transform: scale(1.05);
}
.smp-art.playing {
    box-shadow: 0 4px 24px rgba(0,0,0,0.5), 0 0 48px rgba(220,38,38,0.15);
    border-color: rgba(220,38,38,0.25);
}

/* === PLAY BUTTON — The Star === */
.smp-btn-play {
    background: linear-gradient(135deg, #dc2626, #b91c1c);
    box-shadow: 0 2px 12px rgba(220,38,38,0.3);
    transition: transform var(--duration-standard, 300ms) var(--ease-standard, cubic-bezier(0.4,0,0.2,1)),
                box-shadow var(--duration-standard, 300ms) var(--ease-standard, cubic-bezier(0.4,0,0.2,1));
}
.smp-btn-play:hover {
    transform: scale(1.08);
    box-shadow: 0 4px 24px rgba(220,38,38,0.5);
    background: linear-gradient(135deg, #ef4444, #dc2626);
}
.smp-btn-play:active {
    transform: scale(0.95);
}
.smp-btn-play.playing {
    animation: player-pulse 2s ease-in-out infinite;
}
@keyframes player-pulse {
    0%, 100% { box-shadow: 0 2px 12px rgba(220,38,38,0.3); }
    50%      { box-shadow: 0 4px 28px rgba(220,38,38,0.6); }
}

/* === CONTROL BUTTONS === */
.smp-btn {
    color: rgba(255,255,255,0.5);
    transition: color var(--duration-standard, 300ms) ease,
                transform var(--duration-standard, 300ms) ease,
                background var(--duration-standard, 300ms) ease;
}
.smp-btn:hover {
    color: rgba(255,255,255,0.9);
    transform: scale(1.1);
}
.smp-btn:active {
    transform: scale(0.9);
}
.smp-btn-mode.active {
    color: var(--color-primary, #dc2626);
    background: rgba(220,38,38,0.12);
}

/* === PROGRESS BAR === */
.smp-progress-bar {
    background: rgba(255,255,255,0.06);
    border-radius: 4px;
    transition: height 0.2s ease;
}
.smp-progress-bar:hover,
.smp-progress-bar.dragging {
    height: 10px;
}
.smp-progress-fill {
    background: linear-gradient(90deg, #dc2626, #ef4444);
    border-radius: 4px;
}
.smp-progress-fill::after {
    background: #fff;
    box-shadow: 0 0 8px rgba(220,38,38,0.5);
    opacity: 0;
    transition: opacity 0.2s ease, transform 0.15s ease;
}
.smp-progress-bar:hover .smp-progress-fill::after,
.smp-progress-bar.dragging .smp-progress-fill::after {
    opacity: 1;
}

/* === TRACK INFO === */
.smp-title {
    font-weight: 600;
    font-size: 0.9rem;
    letter-spacing: 0.01em;
}
.smp-artist {
    font-size: 0.75rem;
    color: rgba(255,255,255,0.45);
    letter-spacing: 0.03em;
}

/* === VOLUME SLIDER === */
.smp-volume-slider-vertical {
    -webkit-appearance: none;
    appearance: none;
    background: rgba(255,255,255,0.1);
    border-radius: 2px;
}
.smp-volume-slider-vertical::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 0 6px rgba(0,0,0,0.3);
    cursor: pointer;
}
.smp-volume-slider-vertical::-moz-range-thumb {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 0 6px rgba(0,0,0,0.3);
    border: none;
    cursor: pointer;
}

/* === PLAYLIST === */
.smp-playlist {
    background: rgba(15,15,18,0.95);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border-top: 1px solid rgba(255,255,255,0.04);
}
.smp-track-item {
    transition: background var(--duration-standard, 300ms) ease;
    border-radius: 6px;
}
.smp-track-item:hover {
    background: rgba(255,255,255,0.04);
}
.smp-track-item.active {
    background: rgba(220,38,38,0.08);
    border-left: 2px solid var(--color-primary, #dc2626);
}

/* === MINI MODE === */
.smp-player.smp-mini .smp-mini-art {
    width: 40px;
    height: 40px;
}

/* === LIGHT THEME === */
[data-theme="light"] .smp-player {
    background: linear-gradient(135deg, rgba(255,255,255,0.92), rgba(245,245,250,0.88));
    border-top-color: rgba(0,0,0,0.08);
    box-shadow: 0 -4px 20px rgba(0,0,0,0.1);
}
[data-theme="light"] .smp-title { color: #1a1a1a; }
[data-theme="light"] .smp-artist { color: rgba(0,0,0,0.5); }
[data-theme="light"] .smp-btn { color: rgba(0,0,0,0.4); }
[data-theme="light"] .smp-btn:hover { color: rgba(0,0,0,0.8); }
[data-theme="light"] .smp-progress-bar { background: rgba(0,0,0,0.08); }
[data-theme="light"] .smp-playlist {
    background: rgba(255,255,255,0.95);
    border-top-color: rgba(0,0,0,0.06);
}
[data-theme="light"] .smp-track-item:hover {
    background: rgba(0,0,0,0.04);
}
[data-theme="light"] .smp-track-item.active {
    background: rgba(220,38,38,0.06);
}

/* === RESPONSIVE === */
@media (max-width: 640px) {
    .smp-volume-section .smp-volume-wrapper { display: none; }
    .smp-art { width: 48px; height: 48px; }
}

/* === REDUCED MOTION === */
@media (prefers-reduced-motion: reduce) {
    .smp-btn-play.playing { animation: none; }
    .smp-btn:hover, .smp-btn:active { transform: none; }
    .smp-btn-play:hover, .smp-btn-play:active { transform: none; }
    .smp-art.playing img { transform: none; }
}
/* =============================================================
   Text Choreography — Splitting.js animations
   - Word-by-word h2 reveal
   - Glitch-title char scramble on hover
   - Scroll-driven variable font weight for hero
   ============================================================= */

/* --- Word-by-word reveal for section headings --- */
main h2 .word {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 0.5s cubic-bezier(0.16, 1, 0.3, 1),
                transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
    transition-delay: calc(var(--word-index, 0) * 0.06s);
}
main h2.text-fx-visible .word {
    opacity: 1;
    transform: translateY(0);
}

/* --- Glitch-title char scramble on hover (desktop) --- */
.glitch-title.splitting .char {
    display: inline-block;
    transition: transform 0.2s ease;
}
.glitch-title:hover .char {
    animation: char-glitch 0.3s ease forwards;
    animation-delay: calc(var(--char-index, 0) * 0.02s);
}
@keyframes char-glitch {
    0%, 100% { transform: translate(0); }
    25%  { transform: translate(
               calc(-2px + var(--char-index, 0) * 0.5px),
               calc( 1px - var(--char-index, 0) * 0.3px)); }
    75%  { transform: translate(
               calc( 1px - var(--char-index, 0) * 0.3px),
               calc(-1px + var(--char-index, 0) * 0.5px)); }
}

/* --- Scroll-driven variable font weight for hero --- */
.hero-title[style*="--scroll-weight"] {
    font-variation-settings: 'wght' var(--scroll-weight, 700);
    transition: font-variation-settings 0.1s linear;
}

/* --- Reduced motion: disable all choreography --- */
@media (prefers-reduced-motion: reduce) {
    main h2 .word {
        opacity: 1;
        transform: none;
        transition: none;
    }
    .glitch-title:hover .char {
        animation: none;
    }
    .hero-title[style*="--scroll-weight"] {
        font-variation-settings: 'wght' 700;
        transition: none;
    }
}
/**
 * Micro-Interactions & Layout Polish
 * Button press, link underlines, 3D card tilt, editorial gallery,
 * focus glow, selection. @layer for cascade isolation.
 */
@layer micro-interactions {

    /* a) Button Press */
    .btn-primary, .btn-secondary, button:not([disabled]) {
        transition: transform var(--duration-standard) var(--ease-standard);
    }
    .btn-primary:active, .btn-secondary:active, button:not([disabled]):active {
        transform: scale(0.97);
    }

    /* b) Link Underline Draw-In */
    main a:not(.btn-primary):not(.btn-secondary):not(.bento-card):not(.album-card):not([class*="nav"]):not(.skip-link),
    .site-footer a:not(.btn-primary):not(.btn-secondary) {
        text-decoration: none;
        background-image: linear-gradient(var(--color-primary), var(--color-primary));
        background-size: 0% 1px;
        background-position: 0 100%;
        background-repeat: no-repeat;
        transition: background-size 0.3s var(--ease-hero);
    }
    main a:not(.btn-primary):not(.btn-secondary):not(.bento-card):not(.album-card):not([class*="nav"]):not(.skip-link):hover,
    .site-footer a:not(.btn-primary):not(.btn-secondary):hover {
        background-size: 100% 1px;
    }

    /* d) Image Scale Inside Cards */
    .card-image-wrapper img, .album-cover img {
        transition: transform 0.5s var(--ease-standard);
    }

    /* e) Album Card 3D Perspective Tilt */
    .album-card {
        perspective: 800px;
    }
    .album-card .album-cover {
        transform-style: preserve-3d;
        transition: transform 0.4s var(--ease-hero);
    }
    .album-card:hover .album-cover {
        transform: rotateY(-3deg) rotateX(2deg) scale(1.08);
    }

    /* f) Navigation .scrolled — adds saturate to existing glassmorphism */
    .site-header.scrolled {
        -webkit-backdrop-filter: blur(12px) saturate(1.5);
        backdrop-filter: blur(12px) saturate(1.5);
    }

    /* g) Gallery Editorial Grid (opt-in via .gallery-grid--editorial) */
    @supports (display: grid) {
        .gallery-grid--editorial {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
            gap: var(--space-md);
        }
        @media (min-width: 768px) {
            .gallery-grid--editorial > :nth-child(5n+1) { grid-column: span 2; }
            .gallery-grid--editorial > :nth-child(7n+4) { grid-row: span 2; }
        }
    }

    /* h) Focus Visible Glow */
    :focus-visible {
        outline: 2px solid var(--color-primary);
        outline-offset: 2px;
        border-radius: 4px;
    }

    /* i) Custom Selection Color */
    ::selection {
        background: var(--color-primary-glow);
        color: #fff;
    }

    /* j) Reduced Motion */
    @media (prefers-reduced-motion: reduce) {
        .btn-primary, .btn-secondary, button,
        .bento-card, .album-card,
        .card-image-wrapper img, .album-cover img,
        main a, .site-footer a,
        .album-card .album-cover {
            transition: none !important;
        }
        .album-card:hover .album-cover {
            transform: none !important;
        }
    }

    /* k) Light Theme Adjustments */
    [data-theme="light"] ::selection {
        background: oklch(0.55 0.22 25 / 0.15);
        color: #1a1a1a;
    }
    [data-theme="light"] :focus-visible {
        outline-color: var(--color-primary-hover);
    }
}
/* Cinematic Lightbox — dark cinema photo viewer */
.cl-dialog{position:fixed;inset:0;width:100vw;height:100vh;max-width:100vw;max-height:100vh;border:0;padding:0;background:transparent;z-index:9999;display:flex;flex-direction:column;align-items:center;justify-content:center}
.cl-dialog::backdrop{background:rgba(0,0,0,.95);backdrop-filter:blur(20px)}
.cl-dialog:not([open]){display:none}
.cl-close{position:absolute;top:1rem;right:1rem;z-index:2;width:48px;height:48px;border:0;border-radius:50%;background:rgba(255,255,255,.1);color:#fff;font-size:1.75rem;line-height:1;cursor:pointer;transition:background .2s,color .2s}
.cl-close:hover,.cl-close:focus-visible{background:var(--color-primary,#dc2626);color:#fff;outline:none}
.cl-prev,.cl-next{position:absolute;top:50%;transform:translateY(-50%);z-index:2;width:56px;height:56px;border:0;border-radius:50%;background:rgba(255,255,255,.08);color:#fff;font-size:2.25rem;line-height:1;cursor:pointer;transition:background .2s,color .2s}
.cl-prev{left:1rem}.cl-next{right:1rem}
.cl-prev:hover,.cl-prev:focus-visible,.cl-next:hover,.cl-next:focus-visible{background:var(--color-primary,#dc2626);outline:none}
.cl-figure{display:flex;flex-direction:column;align-items:center;gap:.5rem;max-width:90vw;max-height:80vh;margin:0;z-index:1}
.cl-image{max-width:90vw;max-height:80vh;object-fit:contain;border-radius:4px;user-select:none;-webkit-user-drag:none}
.cl-dialog[open] .cl-image{animation:cl-in .4s cubic-bezier(.16,1,.3,1) both}
.cl-caption{text-align:center;max-width:600px;font-size:.875rem;color:rgba(255,255,255,.7);padding:0 1rem}
.cl-counter{position:absolute;top:1.25rem;left:50%;transform:translateX(-50%);font-size:.8rem;color:rgba(255,255,255,.6);text-shadow:0 1px 4px rgba(0,0,0,.8);z-index:2;pointer-events:none}
.cl-filmstrip{position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:4px;max-width:80vw;overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;padding:4px;z-index:2;-ms-overflow-style:none;scrollbar-width:none}
.cl-filmstrip::-webkit-scrollbar{display:none}
.cl-thumb{width:48px;height:48px;object-fit:cover;border-radius:4px;cursor:pointer;opacity:.5;transition:opacity .2s,border-color .2s;border:2px solid transparent;scroll-snap-align:center;flex-shrink:0}
.cl-thumb:hover{opacity:.8}
.cl-thumb--active{opacity:1;border-color:var(--color-primary,#dc2626)}
@keyframes cl-in{from{opacity:0;transform:scale(.85)}to{opacity:1;transform:scale(1)}}

/* Mobile */
@media(max-width:480px){
    .cl-filmstrip{display:none}
    .cl-prev,.cl-next{width:40px;height:40px;font-size:1.5rem}
    .cl-prev{left:.5rem}.cl-next{right:.5rem}
    .cl-close{top:.5rem;right:.5rem;width:40px;height:40px;font-size:1.25rem}
}

/* Reduced motion */
@media(prefers-reduced-motion:reduce){
    .cl-dialog[open] .cl-image{animation:none}
}
/* Horizontal Timeline — GSAP ScrollTrigger pinned horizontal scroll.
   Only activates when JS adds .ht-active to .timeline */

.timeline.ht-active {
    overflow: hidden;
    height: 100vh;
    width: 100%;
    position: relative;
    transition: background-color 0.8s ease;
}
.ht-track {
    display: flex;
    align-items: center;
    height: 100%;
    padding: 0 10vw;
    will-change: transform;
}

/* Cards */
.ht-active .timeline-item {
    flex: 0 0 clamp(280px, 38vw, 480px);
    margin-right: 3vw;
    padding: 2rem;
    background: rgba(255,255,255,0.03);
    border: 1px solid rgba(255,255,255,0.06);
    border-radius: 12px;
    backdrop-filter: blur(6px);
    opacity: 1; transform: none; animation: none;
}
.ht-active .timeline-item.memorial {
    border-color: rgba(220,38,38,0.2);
    background: rgba(220,38,38,0.05);
}

/* Era markers */
.ht-active .timeline-era {
    flex: 0 0 160px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 2vw;
}
.ht-active .timeline-era span {
    font-size: clamp(1.8rem, 3.5vw, 3rem);
    font-family: var(--font-display, 'Bebas Neue', sans-serif);
    letter-spacing: 0.06em;
    color: var(--color-primary, #dc2626);
    background: transparent;
    writing-mode: vertical-lr;
    text-orientation: mixed;
    white-space: nowrap;
}

/* Remove vertical line & dots */
.ht-active::before,
.ht-active .timeline-item::before { display: none; }

/* Progress bar */
.ht-progress {
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 3px;
    background: rgba(255,255,255,0.08);
    z-index: 10;
}
.ht-progress-bar {
    height: 100%;
    width: 0%;
    background: var(--color-primary, #dc2626);
    will-change: width;
}

/* Mobile + reduced motion: stay vertical */
@media (max-width: 767px) {
    .timeline.ht-active { overflow: visible; height: auto; }
    .ht-track { display: block; padding: 0; }
    .ht-active .timeline-item { flex: none; margin-right: 0; }
    .ht-progress { display: none; }
}
@media (prefers-reduced-motion: reduce) {
    .ht-progress { display: none; }
}
/* Album Quick-Preview Panel — expand-in-place on discography grid */
.aqp-panel {
    grid-column: 1 / -1;
    background: linear-gradient(135deg, rgba(20,20,26,0.95), rgba(30,30,38,0.90));
    backdrop-filter: blur(16px);
    border: 1px solid rgba(255,255,255,0.05);
    border-radius: 12px;
    padding: clamp(1.5rem, 3vw, 2.5rem);
    margin: 0.75rem 0;
    overflow: hidden;
    position: relative;
}
.aqp-panel--loading { display: flex; align-items: center; justify-content: center; }
.aqp-loader { width: 24px; height: 24px; border: 2px solid rgba(255,255,255,0.15); border-top-color: #dc2626; border-radius: 50%; animation: aqp-spin 0.6s linear infinite; }
@keyframes aqp-spin { to { transform: rotate(360deg); } }
.aqp-panel--error { padding: 1.5rem; text-align: center; }
.aqp-error { color: rgba(255,255,255,0.5); margin: 0; }

.aqp-close { position: absolute; top: 0.75rem; right: 0.75rem; background: none; border: none; color: rgba(255,255,255,0.35); font-size: 1.5rem; cursor: pointer; transition: color 0.2s; line-height: 1; padding: 0.25rem; z-index: 1; }
.aqp-close:hover, .aqp-close:focus-visible { color: #fff; }

.aqp-header { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem 1rem; margin-bottom: 0.5rem; }
.aqp-title { margin: 0; font-size: clamp(1.1rem, 2vw, 1.4rem); font-weight: 700; color: #fff; }
.aqp-year { font-size: 0.85rem; color: #dc2626; font-weight: 600; }
.aqp-meta { font-size: 0.8rem; color: rgba(255,255,255,0.4); }
.aqp-description { font-size: 0.85rem; color: rgba(255,255,255,0.55); line-height: 1.5; margin: 0 0 1rem; max-height: 4.5em; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; }

.aqp-actions { display: flex; align-items: center; gap: 1rem; margin-bottom: 1rem; }
.aqp-play-all { background: linear-gradient(135deg, #dc2626, #b91c1c); color: #fff; border: none; padding: 0.5rem 1.25rem; border-radius: 8px; font-weight: 600; font-size: 0.85rem; cursor: pointer; transition: transform 0.2s, box-shadow 0.2s; }
.aqp-play-all:hover { transform: translateY(-1px); box-shadow: 0 4px 16px rgba(220,38,38,0.3); }
.aqp-play-all:active { transform: scale(0.97); }
.aqp-view-full { font-size: 0.8rem; color: rgba(255,255,255,0.5); text-decoration: none; transition: color 0.2s; }
.aqp-view-full:hover { color: #fff; }

.aqp-tracklist { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 2px; }
.aqp-track { display: flex; align-items: center; gap: 0.6rem; padding: 0.45rem 0.75rem; border-radius: 6px; cursor: pointer; transition: background 0.2s; }
.aqp-track:hover { background: rgba(220,38,38,0.08); }
.aqp-track-num { color: rgba(255,255,255,0.2); font-size: 0.75rem; width: 1.5rem; text-align: right; font-variant-numeric: tabular-nums; flex-shrink: 0; }
.aqp-track-title { flex: 1; font-size: 0.82rem; color: rgba(255,255,255,0.8); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.aqp-track-duration { font-size: 0.75rem; color: rgba(255,255,255,0.25); font-variant-numeric: tabular-nums; flex-shrink: 0; }
.aqp-track-lyrics { font-size: 0.7rem; color: rgba(220,38,38,0.6); flex-shrink: 0; }
.aqp-track:hover .aqp-track-num::before { content: "\25b6"; font-size: 0.6rem; }
.aqp-track:hover .aqp-track-num { color: #dc2626; font-size: 0; }

/* Light theme */
[data-theme="light"] .aqp-panel { background: linear-gradient(135deg, rgba(250,250,252,0.97), rgba(240,240,245,0.95)); border-color: rgba(0,0,0,0.08); }
[data-theme="light"] .aqp-title { color: #111; }
[data-theme="light"] .aqp-description { color: rgba(0,0,0,0.6); }
[data-theme="light"] .aqp-track-title { color: rgba(0,0,0,0.75); }
[data-theme="light"] .aqp-track:hover { background: rgba(220,38,38,0.05); }
[data-theme="light"] .aqp-close { color: rgba(0,0,0,0.3); }
[data-theme="light"] .aqp-close:hover { color: #111; }

/* Mobile */
@media (max-width: 600px) {
    .aqp-panel { padding: 1rem; border-radius: 8px; }
    .aqp-tracklist { grid-template-columns: 1fr; }
    .aqp-header { gap: 0.25rem 0.75rem; }
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
    .aqp-panel { transition: none; }
    .aqp-loader { animation-duration: 1.5s; }
}
/* Members Cinematic Profile Cards — documentary portrait treatment */

/* Entrance stagger */
.members-grid .member-card {
  opacity: 0; transform: translateY(18px);
  position: relative;
  transition: transform var(--duration-standard, 300ms) var(--ease-hero, cubic-bezier(.16,1,.3,1)),
              box-shadow var(--duration-standard, 300ms) ease;
}
.members-grid .member-card.mc-visible {
  animation: mcEnter .5s var(--ease-hero, cubic-bezier(.16,1,.3,1)) forwards;
}
@keyframes mcEnter { to { opacity: 1; transform: translateY(0); } }
.members-grid .member-card:nth-child(2) { animation-delay: .06s; }
.members-grid .member-card:nth-child(3) { animation-delay: .12s; }
.members-grid .member-card:nth-child(4) { animation-delay: .18s; }
.members-grid .member-card:nth-child(5) { animation-delay: .24s; }
.members-grid .member-card:nth-child(6) { animation-delay: .30s; }
.members-grid .member-card:nth-child(n+7) { animation-delay: .36s; }

/* Spotlight pseudo-element (positioned via JS --mx/--my) */
.members-grid .member-card::after {
  content: ""; position: absolute; inset: 0;
  border-radius: inherit; opacity: 0; pointer-events: none;
  transition: opacity var(--duration-standard, 300ms) ease;
  background: radial-gradient(circle at var(--mx,50%) var(--my,50%),
    rgba(220,38,38,.12) 0%, transparent 60%);
}
.members-grid .member-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 8px 24px rgba(0,0,0,.35);
}
.members-grid .member-card:hover::after { opacity: 1; }

/* Portrait desaturation */
.members-grid .member-photo-container img {
  filter: grayscale(.3);
  transition: filter var(--duration-standard, 300ms) ease;
}
.members-grid .member-card:hover .member-photo-container img { filter: grayscale(0); }

/* Name typography — dynamic letter-spacing on hover */
.members-grid .member-name {
  letter-spacing: .02em;
  transition: letter-spacing var(--duration-standard, 300ms) ease;
}
.members-grid .member-card:hover .member-name { letter-spacing: .04em; }

/* Role: display font, uppercase, primary color */
.members-grid .member-role {
  font-family: var(--font-display, 'Bebas Neue', 'Arial Black', sans-serif);
  text-transform: uppercase; letter-spacing: .08em;
  color: var(--color-primary, #dc2626);
}

/* Years: tabular numbers */
.members-grid .member-years { font-variant-numeric: tabular-nums; }

/* Deceased memorial treatment — warm amber instead of red */
.members-grid .member-card.deceased { border-color: rgba(245,158,11,.25); }
.members-grid .member-card.deceased::after {
  background: radial-gradient(circle at var(--mx,50%) var(--my,50%),
    rgba(245,158,11,.12) 0%, transparent 60%);
}
.members-grid .member-card.deceased:hover {
  box-shadow: 0 8px 24px rgba(245,158,11,.15);
}
.members-grid .member-card.deceased .member-photo-container img { filter: grayscale(.35); }
.members-grid .member-card.deceased:hover .member-photo-container img { filter: grayscale(.2); }
.members-grid .member-card.deceased .member-name { color: var(--color-amber, #f59e0b); }

/* Initials avatar gradient */
.members-grid .member-initials-avatar {
  background: linear-gradient(135deg,
    hsl(var(--avatar-hue,0) 50% 25%), hsl(var(--avatar-hue,0) 60% 15%));
}

/* Page header */
.members-page-header h1 {
  font-family: var(--font-display, 'Bebas Neue', 'Arial Black', sans-serif);
  letter-spacing: .06em;
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .members-grid .member-card { opacity: 1; transform: none; animation: none !important; }
  .members-grid .member-card:hover { transform: none; }
  .members-grid .member-card::after { display: none; }
}

/* Light theme */
[data-theme="light"] .members-grid .member-card:hover { box-shadow: 0 8px 24px rgba(0,0,0,.12); }
[data-theme="light"] .members-grid .member-card.deceased:hover { box-shadow: 0 8px 24px rgba(245,158,11,.1); }
[data-theme="light"] .members-grid .member-initials-avatar {
  background: linear-gradient(135deg,
    hsl(var(--avatar-hue,0) 55% 72%), hsl(var(--avatar-hue,0) 50% 60%));
}

/* Mobile — no hover lift */
@media (max-width: 600px) {
  .members-grid .member-card:hover { transform: none; }
}
/**
 * Ambient Sound Toggle Button
 * Small floating control (bottom-left) to enable/disable atmospheric sounds.
 * Positioned above cookie consent area.
 *
 * @version 1.0.0
 */

/* ========================================
   TOGGLE BUTTON
   ======================================== */

.ambient-sound-toggle {
    position: fixed;
    bottom: 5rem;
    left: 1rem;
    z-index: 900;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    border: 1px solid oklch(0.35 0.02 260 / 0.5);
    border-radius: 50%;
    background: oklch(0.15 0.01 260 / 0.85);
    color: oklch(0.6 0.02 260);
    cursor: pointer;
    backdrop-filter: blur(6px);
    transition: color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}

/* Fallback for browsers without oklch */
@supports not (color: oklch(0.15 0.01 260)) {
    .ambient-sound-toggle {
        background: rgba(20, 22, 30, 0.85);
        border-color: rgba(60, 65, 80, 0.5);
        color: #8a8f9f;
    }
}

.ambient-sound-toggle:hover {
    color: oklch(0.85 0.01 260);
    border-color: oklch(0.5 0.02 260 / 0.7);
}

@supports not (color: oklch(0.85 0.01 260)) {
    .ambient-sound-toggle:hover {
        color: #d0d3db;
        border-color: rgba(90, 95, 110, 0.7);
    }
}

.ambient-sound-toggle:focus-visible {
    outline: 2px solid oklch(0.65 0.25 25);
    outline-offset: 2px;
}

@supports not (color: oklch(0.65 0.25 25)) {
    .ambient-sound-toggle:focus-visible {
        outline-color: #e74c3c;
    }
}

/* ========================================
   ACTIVE STATE — subtle pulse
   ======================================== */

.ambient-sound-toggle--active {
    color: oklch(0.65 0.25 25);
    border-color: oklch(0.65 0.25 25 / 0.5);
    animation: ambient-pulse 3s ease-in-out infinite;
}

@supports not (color: oklch(0.65 0.25 25)) {
    .ambient-sound-toggle--active {
        color: #e74c3c;
        border-color: rgba(231, 76, 60, 0.5);
    }
}

@keyframes ambient-pulse {
    0%, 100% {
        box-shadow: 0 0 0 0 oklch(0.65 0.25 25 / 0.15);
    }
    50% {
        box-shadow: 0 0 8px 2px oklch(0.65 0.25 25 / 0.2);
    }
}

@supports not (color: oklch(0.65 0.25 25)) {
    @keyframes ambient-pulse {
        0%, 100% {
            box-shadow: 0 0 0 0 rgba(231, 76, 60, 0.15);
        }
        50% {
            box-shadow: 0 0 8px 2px rgba(231, 76, 60, 0.2);
        }
    }
}

/* ========================================
   REDUCED MOTION
   ======================================== */

@media (prefers-reduced-motion: reduce) {
    .ambient-sound-toggle {
        display: none !important;
    }
}

/* ========================================
   MOBILE
   ======================================== */

@media (max-width: 640px) {
    .ambient-sound-toggle {
        bottom: 6rem;
        width: 2.5rem;
        height: 2.5rem;
    }
}

/* ========================================
   PRINT
   ======================================== */

@media print {
    .ambient-sound-toggle {
        display: none !important;
    }
}
/* ==========================================================================
   Magnetic Cursor — pull effect, 3D tilt, gallery cursor trail
   ========================================================================== */

/* Magnetic element base — spring-back transition */
[data-magnetic],
.album-card-modern {
    transition: transform 0.3s cubic-bezier(0.23, 1, 0.32, 1);
}

/* Active magnetic pull — bypass transition for live tracking */
.magnetic-active {
    will-change: transform;
    transition: none;
}

/* Restore spring-back when cursor leaves */
[data-magnetic]:not(.magnetic-active),
.album-card-modern:not(.magnetic-active) {
    transition: transform 0.45s cubic-bezier(0.23, 1, 0.32, 1);
}

/* Cursor trail dots */
.magnetic-trail-dot {
    position: fixed;
    top: 0;
    left: 0;
    border-radius: 50%;
    pointer-events: none;
    z-index: 9999;
    background: radial-gradient(
        circle,
        var(--accent-red, #dc2626) 0%,
        rgba(220, 38, 38, 0.4) 50%,
        transparent 100%
    );
    mix-blend-mode: screen;
    will-change: transform;
}

/* Gallery page: hide native cursor when trail active */
body.magnetic-trail-active,
body.magnetic-trail-active * {
    cursor: none;
}
@supports not (cursor: none) {
    body.magnetic-trail-active,
    body.magnetic-trail-active * { cursor: crosshair; }
}

/* Reduced motion: disable everything */
@media (prefers-reduced-motion: reduce) {
    [data-magnetic],
    .album-card-modern {
        transition: none !important;
        transform: none !important;
    }
    .magnetic-trail-dot { display: none !important; }
    body.magnetic-trail-active,
    body.magnetic-trail-active * { cursor: auto; }
}
/* =============================================================
   Lyric Reveal — Cinematic blockquote / pull-quote animations
   - Word-by-word staggered reveal with blur + translateY
   - Typewriter mode for memorial contexts
   - Decorative underline after full reveal
   ============================================================= */

/* --- Word initial & revealed states --- */
.lyric-word {
    display: inline-block;
    opacity: 0;
    transform: translateY(20px);
    filter: blur(4px);
    transition: opacity 0.5s var(--ease-hero, cubic-bezier(0.16, 1, 0.3, 1)),
                transform 0.5s var(--ease-hero, cubic-bezier(0.16, 1, 0.3, 1)),
                filter 0.5s var(--ease-hero, cubic-bezier(0.16, 1, 0.3, 1));
    transition-delay: var(--word-delay, 0ms);
}
.lyric-word.revealed {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
}

/* --- Pull-quote styling --- */
.pull-quote,
blockquote[data-lyric],
[data-lyric] {
    position: relative;
    font-family: var(--font-editorial, 'Playfair Display', Georgia, serif);
    font-style: italic;
    font-size: var(--text-xl, 1.35rem);
    line-height: 1.7;
    padding: 1.5rem 1.5rem 1.5rem 2rem;
    margin: 2rem 0;
    border-left: 4px solid transparent;
    border-image: linear-gradient(to bottom,
        var(--color-primary, oklch(0.55 0.22 25)),
        var(--color-amber, oklch(0.82 0.14 85))) 1;
    transform: rotate(-0.5deg);
    color: var(--color-neutral, oklch(0.75 0.015 260));
}

/* --- Decorative underline (draws in after full reveal) --- */
blockquote::after,
.pull-quote::after,
[data-lyric]::after {
    content: '';
    display: block;
    width: 0;
    height: 2px;
    margin: 1.25rem auto 0;
    background: linear-gradient(90deg, transparent,
        var(--color-primary, oklch(0.55 0.22 25)),
        var(--color-amber, oklch(0.82 0.14 85)), transparent);
    transition: width 0.8s var(--ease-memorial, cubic-bezier(0.22, 0.61, 0.36, 1)) 0.2s;
}
blockquote.lyric-revealed::after,
.pull-quote.lyric-revealed::after,
[data-lyric].lyric-revealed::after {
    width: 60%;
}

/* --- Typewriter cursor --- */
.lyric-cursor {
    display: inline-block;
    width: 2px;
    height: 1.1em;
    background: var(--color-amber, oklch(0.82 0.14 85));
    margin-left: 1px;
    vertical-align: text-bottom;
    animation: lyric-blink 0.7s steps(2) infinite;
}
.lyric-cursor--done {
    animation: lyric-blink 0.7s steps(2) 3;
    animation-fill-mode: forwards;
    opacity: 0;
}
@keyframes lyric-blink {
    0% { opacity: 1; }
    100% { opacity: 0; }
}

/* --- Memorial quotes: softer amber glow --- */
.memorial-page blockquote,
.memorial-section blockquote,
.memorial-content blockquote {
    color: var(--color-amber-light, oklch(0.88 0.1 85));
    text-shadow: 0 0 20px oklch(0.82 0.14 85 / 0.15);
    border-image: linear-gradient(to bottom,
        var(--color-amber, oklch(0.82 0.14 85)),
        oklch(0.65 0.08 85)) 1;
}

/* --- Light theme variants --- */
[data-theme="light"] .pull-quote,
[data-theme="light"] blockquote[data-lyric],
[data-theme="light"] [data-lyric] { color: oklch(0.3 0.01 260); }
[data-theme="light"] .memorial-page blockquote,
[data-theme="light"] .memorial-section blockquote { color: oklch(0.35 0.08 60); text-shadow: none; }
[data-theme="light"] .lyric-cursor { background: oklch(0.45 0.14 85); }

/* --- Reduced motion: instant reveal, no stagger, no typewriter --- */
@media (prefers-reduced-motion: reduce) {
    .lyric-word { opacity: 1; transform: none; filter: none; transition: none; }
    blockquote::after, .pull-quote::after,
    [data-lyric]::after { width: 60%; transition: none; }
    .lyric-cursor { animation: none; display: none; }
}
/* ============================================================
   Floating Contextual Action Bar
   Frosted glass pill at bottom-center of article/album/memorial pages.
   z-index: 900 (below modals 1000+, above content)
   ============================================================ */

.floating-actions {
    position: fixed;
    bottom: 100px; /* above music player */
    left: 50%;
    translate: -50% 0;
    z-index: 900;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 18px;
    border-radius: 999px;
    background: rgba(17, 24, 39, 0.75);
    backdrop-filter: blur(20px) saturate(180%);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    border: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
    transform: translateY(120%);
    opacity: 0;
    pointer-events: none;
    transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1),
                opacity 0.3s ease;
    overflow: hidden;
}

.floating-actions--visible {
    transform: translateY(0);
    opacity: 1;
    pointer-events: auto;
}

/* ---- Reading progress bar (thin accent line at top) ---- */
.floating-actions__progress {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 2px;
    background: rgba(255, 255, 255, 0.06);
    border-radius: 999px 999px 0 0;
    overflow: hidden;
}

.floating-actions__progress-fill {
    height: 100%;
    width: 0%;
    background: var(--accent, #dc2626);
    border-radius: inherit;
    transition: width 0.15s linear;
}

/* ---- Reading progress percent ---- */
.floating-actions__percent {
    font-size: 0.7rem;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.55);
    min-width: 2.2em;
    text-align: center;
    letter-spacing: 0.02em;
    font-variant-numeric: tabular-nums;
}

/* ---- Action buttons ---- */
.floating-actions__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.08);
    color: rgba(255, 255, 255, 0.85);
    cursor: pointer;
    transition: transform 0.2s ease, background 0.2s ease;
    flex-shrink: 0;
}

.floating-actions__btn:hover {
    background: rgba(255, 255, 255, 0.15);
    transform: scale(1.1);
}

.floating-actions__btn:active {
    transform: scale(0.95);
}

.floating-actions__btn:focus-visible {
    outline: 2px solid var(--accent, #dc2626);
    outline-offset: 2px;
}

/* Accent variant (Play All) */
.floating-actions__btn--accent {
    background: var(--accent, #dc2626);
    color: #fff;
}
.floating-actions__btn--accent:hover {
    background: #ef4444;
}

/* Warm variant (Candle) */
.floating-actions__btn--warm {
    background: rgba(245, 158, 11, 0.2);
    color: #f59e0b;
}
.floating-actions__btn--warm:hover {
    background: rgba(245, 158, 11, 0.35);
}

/* ---- Track count badge ---- */
.floating-actions__badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 0.75rem;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.6);
    padding: 4px 10px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.06);
    white-space: nowrap;
    letter-spacing: 0.01em;
}

/* ---- Year counter (memorial) ---- */
.floating-actions__years {
    font-size: 0.75rem;
    font-weight: 700;
    color: rgba(255, 255, 255, 0.5);
    letter-spacing: 0.05em;
    padding: 0 4px;
    white-space: nowrap;
}

/* ---- Inline toast ---- */
.floating-actions-toast {
    position: fixed;
    bottom: 160px;
    left: 50%;
    translate: -50% 0;
    z-index: 901;
    padding: 8px 20px;
    border-radius: 999px;
    background: rgba(17, 24, 39, 0.9);
    color: #fff;
    font-size: 0.8rem;
    font-weight: 500;
    opacity: 0;
    transform: translateY(10px);
    transition: opacity 0.25s ease, transform 0.25s ease;
    pointer-events: none;
}
.floating-actions-toast--visible {
    opacity: 1;
    transform: translateY(0);
}

/* ---- Font size utility classes on main-content ---- */
.font-size-small  { font-size: 0.9rem; }
.font-size-medium { font-size: 1rem; }
.font-size-large  { font-size: 1.15rem; }

/* ---- Mobile: full width at bottom ---- */
@media (max-width: 640px) {
    .floating-actions {
        left: 8px;
        right: 8px;
        translate: 0 0;
        width: auto;
        bottom: calc(80px + env(safe-area-inset-bottom, 0px));
        justify-content: center;
        padding: 8px 14px;
    }
    .floating-actions-toast {
        bottom: calc(140px + env(safe-area-inset-bottom, 0px));
    }
}

/* ---- Reduced motion ---- */
@media (prefers-reduced-motion: reduce) {
    .floating-actions {
        transition: opacity 0.15s ease;
        transform: none;
    }
    .floating-actions--visible {
        transform: none;
    }
    .floating-actions__btn {
        transition: none;
    }
    .floating-actions__progress-fill {
        transition: none;
    }
}

/* ---- Light theme variant ---- */
[data-theme="light"] .floating-actions {
    background: rgba(255, 255, 255, 0.8);
    border-color: rgba(0, 0, 0, 0.08);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
}

[data-theme="light"] .floating-actions__btn {
    background: rgba(0, 0, 0, 0.06);
    color: rgba(0, 0, 0, 0.75);
}

[data-theme="light"] .floating-actions__btn:hover {
    background: rgba(0, 0, 0, 0.12);
}

[data-theme="light"] .floating-actions__percent,
[data-theme="light"] .floating-actions__badge,
[data-theme="light"] .floating-actions__years {
    color: rgba(0, 0, 0, 0.5);
}

[data-theme="light"] .floating-actions__badge {
    background: rgba(0, 0, 0, 0.05);
}

[data-theme="light"] .floating-actions__progress {
    background: rgba(0, 0, 0, 0.06);
}

[data-theme="light"] .floating-actions-toast {
    background: rgba(0, 0, 0, 0.85);
}
/**
 * Vinyl Spin Component — Enhanced vinyl record animation
 * Provides spinning vinyl, tonearm movement, groove texture,
 * light reflection overlay, and needle-drop bounce.
 *
 * Works with the existing .vinyl-record element in album.ejs
 * and the companion vinyl-spin.component.js.
 *
 * @version 1.0.0
 */

/* ===========================================
   KEYFRAMES
   =========================================== */

@keyframes vinyl-spin-enhanced {
    from { transform: translate(var(--vinyl-tx, 40%), -50%) rotate(0deg); }
    to   { transform: translate(var(--vinyl-tx, 40%), -50%) rotate(360deg); }
}

@keyframes vinyl-light-counter-rotate {
    from { transform: rotate(0deg); }
    to   { transform: rotate(-360deg); }
}

@keyframes tonearm-bounce {
    0%   { transform: rotate(-12deg); }
    40%  { transform: rotate(1.5deg); }
    60%  { transform: rotate(-0.8deg); }
    80%  { transform: rotate(0.3deg); }
    100% { transform: rotate(0deg); }
}

/* ===========================================
   VINYL RECORD — ENHANCED STATES
   =========================================== */

/* When the component enhances, the vinyl receives a canvas groove bg */
.vinyl-record.vs-enhanced {
    --vinyl-tx: 40%;
}

.vinyl-record.vs-enhanced.spinning {
    animation: vinyl-spin-enhanced 1.8s linear infinite;
}

/* Deceleration: widen the period and ease out */
.vinyl-record.vs-enhanced.decelerating {
    animation: vinyl-spin-enhanced 4s cubic-bezier(0.35, 0, 0.25, 1) 1;
    animation-fill-mode: forwards;
}

/* Light reflection overlay — conic gradient that counter-rotates */
.vinyl-record.vs-enhanced::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: conic-gradient(
        from 0deg,
        transparent 0deg,
        rgba(255, 255, 255, 0.06) 40deg,
        transparent 80deg,
        transparent 180deg,
        rgba(255, 255, 255, 0.03) 220deg,
        transparent 260deg
    );
    mix-blend-mode: overlay;
    z-index: 3;
    pointer-events: none;
    animation: vinyl-light-counter-rotate 3.6s linear infinite;
    animation-play-state: paused;
}

.vinyl-record.vs-enhanced.spinning::before {
    animation-play-state: running;
}

.vinyl-record.vs-enhanced.decelerating::before {
    animation-duration: 8s;
    animation-play-state: running;
}

/* Album cover shrinks slightly to reveal grooves when playing */
.album-artwork-large.vs-playing > img {
    transform: scale(0.85);
    transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}

.album-artwork-large > img {
    transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}

/* ===========================================
   TONEARM
   =========================================== */

.vinyl-tonearm {
    position: absolute;
    top: -8%;
    right: 4%;
    width: 45%;
    height: 6px;
    z-index: 10;
    transform-origin: 92% 50%;
    transform: rotate(-30deg);
    transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
    pointer-events: none;
}

/* Arm shaft */
.vinyl-tonearm__arm {
    position: absolute;
    top: 50%;
    left: 0;
    right: 0;
    height: 3px;
    background: linear-gradient(90deg, #888 0%, #aaa 40%, #666 100%);
    border-radius: 2px;
    transform: translateY(-50%);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}

/* Headshell at the needle end */
.vinyl-tonearm__head {
    position: absolute;
    left: -2px;
    top: 50%;
    width: 14px;
    height: 10px;
    background: #999;
    border-radius: 2px 0 0 2px;
    transform: translateY(-50%);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
}

/* Needle / stylus */
.vinyl-tonearm__head::after {
    content: '';
    position: absolute;
    bottom: -4px;
    left: 2px;
    width: 2px;
    height: 6px;
    background: #ccc;
    border-radius: 0 0 1px 1px;
}

/* Pivot point (bearing) */
.vinyl-tonearm__pivot {
    position: absolute;
    right: -4px;
    top: 50%;
    width: 12px;
    height: 12px;
    background: radial-gradient(circle, #777 30%, #444 100%);
    border-radius: 50%;
    transform: translateY(-50%);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
}

/* States */
.vinyl-tonearm.playing {
    transform: rotate(0deg);
}

.vinyl-tonearm.lifted {
    transform: rotate(-30deg);
}

.vinyl-tonearm.dropping {
    animation: tonearm-bounce 0.5s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

/* ===========================================
   CENTER LABEL — RETRO ENHANCEMENT
   =========================================== */

.vinyl-record.vs-enhanced .vinyl-label {
    overflow: hidden;
}

.vinyl-label__title {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 70%;
    transform: translate(-50%, -50%);
    text-align: center;
    font-size: 0.45em;
    font-weight: 700;
    color: rgba(255, 255, 255, 0.75);
    line-height: 1.2;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    pointer-events: none;
    z-index: 1;
}

/* Subtle noise texture on label */
.vinyl-record.vs-enhanced .vinyl-label::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100' height='100' filter='url(%23n)' opacity='0.08'/%3E%3C/svg%3E");
    background-size: 50px 50px;
    z-index: 2;
    pointer-events: none;
    mix-blend-mode: overlay;
}

/* ===========================================
   GROOVE TEXTURE — CSS FALLBACK
   (Canvas version replaces this at runtime)
   =========================================== */

.vinyl-record.vs-enhanced .vinyl-grooves {
    background: repeating-radial-gradient(
        circle at center,
        transparent 0px,
        transparent 1.8px,
        rgba(255, 255, 255, 0.035) 2px,
        transparent 2.2px
    );
}

/* ===========================================
   MOBILE — SMALLER, NO TONEARM
   =========================================== */

@media (max-width: 640px) {
    .vinyl-tonearm {
        display: none;
    }

    .album-artwork-large.vs-playing > img {
        transform: scale(0.92);
    }
}

/* ===========================================
   REDUCED MOTION — STATIC EVERYTHING
   =========================================== */

@media (prefers-reduced-motion: reduce) {
    .vinyl-record.vs-enhanced,
    .vinyl-record.vs-enhanced.spinning,
    .vinyl-record.vs-enhanced.decelerating {
        animation: none !important;
    }

    .vinyl-record.vs-enhanced::before {
        animation: none !important;
    }

    .vinyl-tonearm,
    .vinyl-tonearm.playing,
    .vinyl-tonearm.lifted,
    .vinyl-tonearm.dropping {
        transition: none !important;
        animation: none !important;
    }

    .album-artwork-large.vs-playing > img {
        transform: none !important;
        transition: none !important;
    }
}
/* ==========================================================
   Page Morph — View Transitions & FLIP Clone Fallback
   Customizes the morph-hero transition for SPA navigations.
   ========================================================== */

/* --- View Transition: group timing --- */
::view-transition-group(morph-hero) {
    animation-duration: 400ms;
    animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}

/* --- Old snapshot: shrink + fade --- */
::view-transition-old(morph-hero) {
    animation: morph-hero-out 300ms cubic-bezier(0.4, 0, 0.2, 1) both;
}

@keyframes morph-hero-out {
    from {
        opacity: 1;
        transform: scale(1);
    }
    to {
        opacity: 0;
        transform: scale(0.92);
    }
}

/* --- New snapshot: grow + fade in --- */
::view-transition-new(morph-hero) {
    animation: morph-hero-in 400ms cubic-bezier(0.4, 0, 0.2, 1) both;
}

@keyframes morph-hero-in {
    from {
        opacity: 0;
        transform: scale(0.85);
    }
    to {
        opacity: 1;
        transform: scale(1);
    }
}

/* --- GSAP fallback: clone element --- */
.morph-clone {
    position: fixed;
    z-index: 9999;
    pointer-events: none;
    will-change: transform, width, height, top, left, opacity;
    object-fit: cover;
    border-radius: 8px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
}

/* --- Page exit: content fades down --- */
.page-exit {
    opacity: 0.3;
    transition: opacity 200ms ease-out;
}

/* --- Page enter: content slides up + fades in --- */
.page-enter {
    animation: page-enter-anim 300ms ease-out both;
}

@keyframes page-enter-anim {
    from {
        opacity: 0;
        transform: translateY(20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* --- Reduced motion: instant, no animation --- */
@media (prefers-reduced-motion: reduce) {
    ::view-transition-group(morph-hero),
    ::view-transition-old(morph-hero),
    ::view-transition-new(morph-hero) {
        animation-duration: 0ms;
    }

    .page-exit {
        transition-duration: 0ms;
    }

    .page-enter {
        animation-duration: 0ms;
    }

    .morph-clone {
        transition-duration: 0ms !important;
    }
}
/**
 * Parallax Depth Component Styles
 * GPU hints, 3D perspective container, and mouse-active depth enhancement.
 * Pairs with parallax-depth.component.js.
 * @version 1.0.0
 */

/* ---- GPU acceleration hints for parallax targets ---- */
[data-parallax],
.hero-content,
.aurora-bg,
.hero-bg {
    will-change: transform;
    transform-style: preserve-3d;
}

/* Background-position parallax targets */
.articles-hero-modern,
.albums-hero-modern {
    will-change: background-position;
}

/* ---- 3D perspective container ---- */
.parallax-container {
    overflow: hidden;
    perspective: 1000px;
    transform-style: preserve-3d;
}

/* ---- Mouse-driven depth enhancement ---- */
.parallax-mouse-active {
    transform: scale(1.02);
    transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.parallax-mouse-active .hero-content {
    transition: transform 0.15s ease-out;
}

/* ---- Reduced motion: disable everything ---- */
@media (prefers-reduced-motion: reduce) {
    [data-parallax],
    .hero-content,
    .aurora-bg,
    .hero-bg,
    .articles-hero-modern,
    .albums-hero-modern {
        will-change: auto;
        transform: none !important;
        background-position: center center !important;
    }

    .parallax-container {
        perspective: none;
        transform-style: flat;
    }

    .parallax-mouse-active {
        transform: none !important;
        transition: none;
    }
}
/* ==========================================================================
   Editorial Typography
   Typographic enhancements for article long-form content:
   drop caps, pull quotes, section dividers, hanging punctuation.
   ========================================================================== */

/* ------------------------------------------------------------------
   Drop Cap
   ------------------------------------------------------------------ */

.drop-cap {
    float: left;
    font-size: 4.5em;
    line-height: 0.8;
    padding-right: 0.08em;
    margin-top: 0.05em;
    color: var(--color-primary);
    font-family: var(--font-display, 'Bebas Neue', 'Arial Black', sans-serif);
    font-weight: 700;
    user-select: text;
}

/* Cyrillic characters are often wider — nudge sizing down slightly */
.drop-cap--cyrillic {
    font-size: 4.2em;
    padding-right: 0.1em;
}

/* ------------------------------------------------------------------
   Auto Pull Quote
   ------------------------------------------------------------------ */

.auto-pull-quote {
    font-size: 1.4em;
    font-style: italic;
    line-height: 1.5;
    border-left: 3px solid;
    border-image: linear-gradient(
        to bottom,
        var(--color-primary, #dc2626),
        var(--color-amber, #f59e0b)
    ) 1;
    padding-left: 1.5rem;
    margin: 2rem 0;
    color: var(--color-neutral, #b0b3bc);
    position: relative;
}

.auto-pull-quote::before {
    content: none; /* avoid duplicate decoration if quotes already present */
}

/* ------------------------------------------------------------------
   Editorial Divider
   ------------------------------------------------------------------ */

.editorial-divider {
    border: none;
    border-top: 2px solid transparent;
    border-image: linear-gradient(
        to right,
        transparent,
        var(--color-primary, #dc2626),
        transparent
    ) 1;
    max-width: 60px;
    margin: 3rem auto;
    position: relative;
}

.editorial-divider::before {
    content: '\u25C6'; /* black diamond */
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 0.65rem;
    color: var(--color-primary, #dc2626);
    background: var(--color-bg-base, #141416);
    padding: 0 0.5rem;
    line-height: 1;
}

/* ------------------------------------------------------------------
   Hanging Punctuation
   ------------------------------------------------------------------ */

.hanging-punct {
    text-indent: -0.4em;
}

/* ------------------------------------------------------------------
   Responsive — Mobile
   ------------------------------------------------------------------ */

@media (max-width: 768px) {
    .drop-cap {
        font-size: 3em;
        line-height: 0.85;
    }

    .drop-cap--cyrillic {
        font-size: 2.8em;
    }

    .auto-pull-quote {
        font-size: 1.2em;
        margin: 1.5rem 0;
        padding-left: 1rem;
    }

    .editorial-divider {
        margin: 2rem auto;
    }
}

/* ------------------------------------------------------------------
   Light Theme
   ------------------------------------------------------------------ */

[data-theme="light"] .drop-cap {
    color: var(--color-primary-hover, #b91c1c);
}

[data-theme="light"] .auto-pull-quote {
    color: var(--color-neutral-dim, #7f828a);
}

[data-theme="light"] .editorial-divider::before {
    background: #fff;
}

/* ------------------------------------------------------------------
   Print
   ------------------------------------------------------------------ */

@media print {
    .drop-cap {
        color: #000;
        float: left;
        font-size: 3.5em;
    }

    .auto-pull-quote {
        border-left: 2px solid #333;
        border-image: none;
        color: #333;
        font-size: 1.2em;
    }

    .editorial-divider {
        border-image: none;
        border-top: 1px solid #999;
        max-width: 40px;
    }

    .editorial-divider::before {
        display: none;
    }

    .hanging-punct {
        text-indent: 0;
    }
}
/**
 * Gallery Enhance Styles
 * Staggered reveal, hover effects, info panels, blur-up fallback,
 * keyboard focus, vignette overlay, and masonry gap tuning.
 *
 * Companion to gallery-enhance.component.js
 * @version 1.0.0
 */

/* ========================================
   STAGGERED REVEAL
   ======================================== */

.gallery-item-reveal {
    opacity: 0;
    transform: translateY(30px);
    transition: opacity 0.6s ease var(--reveal-delay, 0ms),
                transform 0.6s ease var(--reveal-delay, 0ms);
}

.gallery-item-reveal.visible {
    opacity: 1;
    transform: translateY(0);
}

/* ========================================
   HOVER: IMAGE SCALE + VIGNETTE
   ======================================== */

.photo-masonry-item .photo-masonry-item__img-wrap {
    position: relative;
    overflow: hidden;
}

.photo-masonry-item .photo-masonry-item__img {
    transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.photo-masonry-item:hover .photo-masonry-item__img,
.photo-masonry-item.ge-focused .photo-masonry-item__img {
    transform: scale(1.06);
}

/* Vignette overlay on hover */
.photo-masonry-item .photo-masonry-item__img-wrap::after {
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(
        ellipse at center,
        transparent 40%,
        rgba(0, 0, 0, 0.35) 100%
    );
    opacity: 0;
    transition: opacity 0.4s ease;
    pointer-events: none;
    z-index: 1;
}

.photo-masonry-item:hover .photo-masonry-item__img-wrap::after,
.photo-masonry-item.ge-focused .photo-masonry-item__img-wrap::after {
    opacity: 1;
}

/* ========================================
   INFO PANEL (slide-up from bottom)
   ======================================== */

.ge-info-panel {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 2;
    padding: 1.5rem 1rem 1rem;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.3) 60%, transparent 100%);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    transform: translateY(100%);
    transition: transform 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94);
    pointer-events: none;
}

.photo-masonry-item:hover .ge-info-panel,
.photo-masonry-item.ge-focused .ge-info-panel {
    transform: translateY(0);
    pointer-events: auto;
}

/* ========================================
   BLUR-UP FALLBACK (no .blur-up wrapper)
   ======================================== */

.ge-blur-up {
    filter: blur(20px);
    transform: scale(1.05);
    transition: filter 0.5s ease, transform 0.5s ease;
}

.ge-blur-up.ge-blur-loaded {
    filter: blur(0);
    transform: scale(1);
}

/* ========================================
   KEYBOARD FOCUS
   ======================================== */

.photo-masonry-item.ge-focused,
.photo-masonry-item:focus-visible {
    outline: 2px solid var(--accent-red, #dc2626);
    outline-offset: 2px;
    z-index: 3;
}

.photo-grid-masonry:focus-visible {
    outline: 2px solid var(--accent-red, #dc2626);
    outline-offset: 4px;
    border-radius: 8px;
}

/* ========================================
   MASONRY GAP TUNING
   ======================================== */

.photo-grid-masonry {
    column-gap: 16px;
}

.photo-masonry-item {
    margin-bottom: 16px;
}

@media (max-width: 768px) {
    .photo-grid-masonry {
        column-gap: 8px;
    }

    .photo-masonry-item {
        margin-bottom: 8px;
    }
}

/* ========================================
   REDUCED MOTION
   ======================================== */

@media (prefers-reduced-motion: reduce) {
    .gallery-item-reveal {
        opacity: 1;
        transform: none;
        transition: none;
    }

    .photo-masonry-item .photo-masonry-item__img {
        transition: none;
    }

    .photo-masonry-item:hover .photo-masonry-item__img,
    .photo-masonry-item.ge-focused .photo-masonry-item__img {
        transform: none;
    }

    .photo-masonry-item .photo-masonry-item__img-wrap::after {
        transition: none;
    }

    .ge-info-panel {
        transition: none;
    }

    .ge-blur-up {
        filter: none;
        transform: none;
        transition: none;
    }
}
/* Footer Spectrum Visualizer -- canvas positioning & edge masks */

.site-footer.footer-modern {
    position: relative;
}

.site-footer.footer-modern > .container,
.site-footer.footer-modern > .footer-grid,
.site-footer.footer-modern > .footer-bottom {
    position: relative;
    z-index: 1;
}

.footer-spectrum-canvas {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 60px;
    pointer-events: none;
    z-index: 0;
    opacity: 0.7;
    /* Fade edges to transparent at left/right 10% */
    -webkit-mask-image: linear-gradient(
        to right,
        transparent 0%,
        black 10%,
        black 90%,
        transparent 100%
    );
    mask-image: linear-gradient(
        to right,
        transparent 0%,
        black 10%,
        black 90%,
        transparent 100%
    );
}

/* Reduced motion: hide animated canvas entirely */
@media (prefers-reduced-motion: reduce) {
    .footer-spectrum-canvas {
        opacity: 0.3;
    }
}
/**
 * Atmospheric Fog Layers
 * Drifting mist that adds depth and mood across the site.
 * Intensified on memorial page, subtle hero-only on homepage.
 */

/* ── Base fog layer ─────────────────────────────────────────── */
.fog-layer {
    position: fixed;
    top: 0;
    left: 0;
    width: 200%;
    height: 100vh;
    pointer-events: none;
    opacity: 0.02;
    will-change: transform;
    transition: opacity 0.6s ease-out;
}

/* Depth layering */
.fog-layer--back  { z-index: 0; }
.fog-layer--mid   { z-index: 1; }
.fog-layer--front { z-index: 50; }

/* Gradient blobs — each layer has a distinct pattern */
.fog-layer--back {
    background:
        radial-gradient(ellipse 40% 50% at 15% 30%, rgba(255,255,255,0.35) 0%, transparent 70%),
        radial-gradient(ellipse 35% 45% at 70% 60%, rgba(255,255,255,0.25) 0%, transparent 65%);
    animation: fog-drift-1 60s linear infinite;
}

.fog-layer--mid {
    background:
        radial-gradient(ellipse 50% 40% at 40% 45%, rgba(255,255,255,0.30) 0%, transparent 60%),
        radial-gradient(ellipse 30% 55% at 80% 25%, rgba(255,255,255,0.20) 0%, transparent 70%);
    animation: fog-drift-2 45s linear infinite;
}

.fog-layer--front {
    background:
        radial-gradient(ellipse 45% 35% at 25% 55%, rgba(255,255,255,0.18) 0%, transparent 65%),
        radial-gradient(ellipse 55% 30% at 65% 35%, rgba(255,255,255,0.22) 0%, transparent 60%);
    animation: fog-drift-3 75s linear infinite;
}

/* ── Keyframes ──────────────────────────────────────────────── */
@keyframes fog-drift-1 {
    0%   { transform: translateX(0); }
    100% { transform: translateX(-50%); }
}

@keyframes fog-drift-2 {
    0%   { transform: translateX(-50%); }
    100% { transform: translateX(0); }
}

@keyframes fog-drift-3 {
    0%   { transform: translateX(-25%); }
    50%  { transform: translateX(-50%); }
    100% { transform: translateX(-25%); }
}

/* ── Memorial variant — warm amber, denser, slower ──────────── */
body[data-page="memorial"] .fog-layer--back {
    background:
        radial-gradient(ellipse 40% 50% at 15% 30%, rgba(245,158,11,0.12) 0%, transparent 70%),
        radial-gradient(ellipse 35% 45% at 70% 60%, rgba(245,158,11,0.08) 0%, transparent 65%);
    animation-duration: 90s;
}

body[data-page="memorial"] .fog-layer--mid {
    background:
        radial-gradient(ellipse 50% 40% at 40% 45%, rgba(245,158,11,0.10) 0%, transparent 60%),
        radial-gradient(ellipse 30% 55% at 80% 25%, rgba(245,158,11,0.06) 0%, transparent 70%);
    animation-duration: 70s;
}

body[data-page="memorial"] .fog-layer--front {
    background:
        radial-gradient(ellipse 45% 35% at 25% 55%, rgba(245,158,11,0.06) 0%, transparent 65%),
        radial-gradient(ellipse 55% 30% at 65% 35%, rgba(245,158,11,0.08) 0%, transparent 60%);
    animation-duration: 110s;
}

/* ── Hero-only variant (homepage) — contained within hero ──── */
.fog-layer--hero {
    position: absolute;
    z-index: 2;
}

/* ── Reduced motion ─────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    .fog-layer {
        animation-play-state: paused !important;
        opacity: 0.01;
    }

    body[data-page="memorial"] .fog-layer {
        opacity: 0.03;
    }
}
/**
 * Scroll Progress Nav Styles
 * Top progress bar + vertical section navigation dots.
 * JS drives --scroll-progress (0..1) and .active on dots.
 * @version 1.0.0
 */

/* -- Top progress bar ---------------------------------------------- */
.scroll-progress-bar {
    position: fixed;
    top: 0; left: 0;
    width: 100%; height: 3px;
    z-index: 1000;
    pointer-events: none;
    transform-origin: left center;
    transform: scaleX(var(--scroll-progress, 0));
    background: linear-gradient(90deg, var(--color-primary, #dc2626) 0%, var(--color-amber, #f59e0b) 100%);
    will-change: transform;
    transition: transform 0.08s linear;
}
.scroll-progress-bar::after {
    content: '';
    position: absolute;
    inset: 0; height: 6px;
    background: inherit;
    opacity: 0.35;
    filter: blur(4px);
}

/* -- Section navigation dots --------------------------------------- */
.section-nav-dots {
    position: fixed;
    right: 20px; top: 50%;
    transform: translateY(-50%);
    z-index: 800;
    display: flex; flex-direction: column; gap: 12px;
    list-style: none;
    margin: 0; padding: 8px 4px;
}
.section-dot {
    position: relative;
    width: 10px; height: 10px;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.3);
    background: transparent;
    cursor: pointer;
    transition: background-color 0.25s ease, border-color 0.25s ease, transform 0.25s ease;
    padding: 0;
    -webkit-appearance: none; appearance: none;
    outline: none;
}
.section-dot:hover { border-color: rgba(255, 255, 255, 0.6); }
.section-dot:focus-visible { outline: 2px solid var(--color-primary, #dc2626); outline-offset: 3px; }
.section-dot.active {
    background: var(--color-primary, #dc2626);
    border-color: var(--color-primary, #dc2626);
    transform: scale(1.3);
}

/* -- Dot tooltip --------------------------------------------------- */
.section-dot__tooltip {
    position: absolute;
    right: 24px; top: 50%;
    transform: translateY(-50%);
    white-space: nowrap;
    background: rgba(0, 0, 0, 0.8);
    backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
    color: #f0f0f0;
    padding: 4px 10px; border-radius: 4px;
    font-size: 0.75rem; line-height: 1.4;
    opacity: 0; pointer-events: none;
    transition: opacity 0.2s ease;
}
.section-dot:hover .section-dot__tooltip,
.section-dot:focus-visible .section-dot__tooltip { opacity: 1; }

/* -- Mobile: hide dots, keep bar ----------------------------------- */
@media (max-width: 768px) {
    .section-nav-dots { display: none; }
    .scroll-progress-bar { height: 2px; }
}

/* -- Light theme --------------------------------------------------- */
[data-theme="light"] .section-dot { border-color: rgba(0, 0, 0, 0.2); }
[data-theme="light"] .section-dot:hover { border-color: rgba(0, 0, 0, 0.45); }
[data-theme="light"] .section-dot__tooltip { background: rgba(255, 255, 255, 0.9); color: #1a1a1a; }

/* -- Reduced motion ------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
    .scroll-progress-bar { transition: none; }
    .section-dot { transition: none; }
    .section-dot__tooltip { transition: none; }
}

/* -- Print --------------------------------------------------------- */
@media print {
    .scroll-progress-bar,
    .section-nav-dots { display: none !important; }
}
/**
 * Counter Animate Component
 * Slot-machine digit columns with cinematic spin effect.
 * Works with any parent text color context.
 * @version 1.0.0
 */

/* Base: tabular nums for stable column widths */
.counter-animated {
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum';
    display: inline-flex;
    align-items: flex-end;
    flex-wrap: nowrap;
    color: inherit;
}

/* Individual digit column (the slot reel viewport) */
.counter-digit {
    display: inline-block;
    overflow: hidden;
    height: 1em;
    line-height: 1;
    vertical-align: bottom;
}

.counter-digit__inner {
    display: flex;
    flex-direction: column;
    will-change: transform;
}

.counter-digit__char {
    display: block;
    height: 1em;
    line-height: 1;
    text-align: center;
}

/* Static characters: separators, colons, dashes */
.counter-static-char {
    display: inline-block;
    vertical-align: bottom;
    line-height: 1;
    white-space: pre;
}

/* Completion: subtle brightness pulse */
.counter-complete {
    animation: counter-settle 0.6s ease-out;
}

@keyframes counter-settle {
    0%   { filter: brightness(1); }
    40%  { filter: brightness(1.4); text-shadow: 0 0 12px currentColor; }
    100% { filter: brightness(1); text-shadow: none; }
}

/* Large counter variant */
.counter-lg {
    font-size: clamp(2rem, 5vw, 3rem);
    font-weight: 800;
    letter-spacing: -0.03em;
}

/* Reduced motion: no overflow clip, no transforms, no glow */
@media (prefers-reduced-motion: reduce) {
    .counter-digit { overflow: visible; }
    .counter-digit__inner { transform: none !important; }
    .counter-complete { animation: none; }
}

/* High contrast: skip the glow animation */
@media (prefers-contrast: high) {
    .counter-complete { animation: none; }
}
/* ==========================================================================
   Album Sidebar — Sticky floating mini-player for album detail pages
   Shows mini cover + tracklist when user scrolls past the main artwork.
   Collapses to cover-only; expands on hover.
   ========================================================================== */

.album-sidebar {
    position: fixed;
    right: 16px;
    left: auto;
    top: 50%;
    /* slide in from the right instead of left */
    transform: translateY(-50%) translateX(120%);
    z-index: 800;
    max-width: 220px;
    width: 220px;
    background: rgba(17, 24, 39, 0.92);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 12px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.04);
    padding: 10px;
    overflow: hidden;
    transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1),
                width 0.3s cubic-bezier(0.22, 1, 0.36, 1),
                opacity 0.3s ease;
    opacity: 0;
    pointer-events: none;
}

.album-sidebar--visible {
    transform: translateY(-50%) translateX(0);
    opacity: 1;
    pointer-events: auto;
}

/* Collapsed: just mini cover + title peek */
.album-sidebar--collapsed {
    width: 70px;
}

.album-sidebar--collapsed .album-sidebar__tracklist,
.album-sidebar--collapsed .album-sidebar__now-playing {
    opacity: 0;
    visibility: hidden;
    max-height: 0;
    margin: 0;
    padding: 0;
    /* smooth collapse */
    transition: opacity 0.25s ease, max-height 0.3s ease, margin 0.2s ease;
}

/* Expanded on hover */
.album-sidebar--collapsed:hover {
    width: 220px;
}

.album-sidebar--collapsed:hover .album-sidebar__tracklist,
.album-sidebar--collapsed:hover .album-sidebar__now-playing {
    opacity: 1;
    visibility: visible;
    max-height: 300px;
    margin-top: 8px;
    transition: opacity 0.25s ease 0.1s, max-height 0.3s ease 0.05s, margin 0.2s ease;
}

/* -- Header: cover + title -- */
.album-sidebar__header {
    display: flex;
    align-items: center;
    gap: 8px;
}

.album-sidebar__cover {
    width: 50px;
    height: 50px;
    border-radius: 6px;
    object-fit: cover;
    flex-shrink: 0;
}

.album-sidebar__title {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-primary, #e0e0f0);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1.2;
    min-width: 0;
}

/* -- Now playing indicator -- */
.album-sidebar__now-playing {
    font-size: 0.7rem;
    color: var(--accent-red, #dc2626);
    font-weight: 600;
    margin-top: 8px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: opacity 0.2s, visibility 0.2s, max-height 0.3s;
}

/* -- Mini tracklist -- */
.album-sidebar__tracklist {
    margin-top: 8px;
    max-height: 240px;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.15) transparent;
    transition: opacity 0.2s, visibility 0.2s, max-height 0.3s;
}

.album-sidebar__track {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 6px;
    border-radius: 4px;
    cursor: pointer;
    transition: background 0.15s;
    border-left: 2px solid transparent;
}

.album-sidebar__track:hover {
    background: rgba(255, 255, 255, 0.06);
}

.album-sidebar__track--active {
    border-left-color: var(--accent-red, #dc2626);
    background: rgba(220, 38, 38, 0.08);
}

.album-sidebar__track--active .album-sidebar__track-name {
    color: var(--text-primary, #e0e0f0);
    font-weight: 600;
}

.album-sidebar__track-num {
    font-size: 0.65rem;
    color: var(--text-muted, rgba(255, 255, 255, 0.35));
    min-width: 1.4em;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.album-sidebar__track-name {
    font-size: 0.75rem;
    color: var(--text-secondary, rgba(255, 255, 255, 0.6));
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

/* -- Light theme -- */
[data-theme="light"] .album-sidebar {
    background: rgba(255, 255, 255, 0.88);
    border-color: rgba(0, 0, 0, 0.08);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 0, 0.04);
}

[data-theme="light"] .album-sidebar__track:hover {
    background: rgba(0, 0, 0, 0.04);
}

[data-theme="light"] .album-sidebar__track--active {
    background: rgba(220, 38, 38, 0.06);
}

/* -- Hidden below 1024px -- */
@media (max-width: 1023px) {
    .album-sidebar {
        display: none !important;
    }
}

/* -- Reduced motion -- */
@media (prefers-reduced-motion: reduce) {
    .album-sidebar {
        transition: none;
    }
    .album-sidebar--visible {
        transform: translateY(-50%) translateX(0);
    }
    .album-sidebar--collapsed:hover {
        transition: none;
    }
    .album-sidebar--collapsed:hover .album-sidebar__tracklist,
    .album-sidebar--collapsed:hover .album-sidebar__now-playing {
        transition: none;
    }
}
/**
 * Film Grain / Noise Texture Overlay
 * Full-viewport noise layer for cinematic atmosphere.
 * Opacity controlled via --noise-opacity custom property (set by JS per page).
 */

/* -- Overlay container -------------------------------------------------- */
.noise-overlay {
    position: fixed;
    inset: 0;
    z-index: 9998;
    pointer-events: none;
    opacity: var(--noise-opacity, 0.03);
    mix-blend-mode: overlay;
    background-repeat: repeat;
    background-size: 256px 256px;
    will-change: opacity;
    transition: opacity 0.6s ease-out;
}

/* -- Light theme: softer blend, reduced opacity ------------------------- */
[data-theme="light"] .noise-overlay,
.light-theme .noise-overlay {
    mix-blend-mode: multiply;
    opacity: calc(var(--noise-opacity, 0.03) * 0.6);
}

/* -- Print: hide entirely ----------------------------------------------- */
@media print {
    .noise-overlay {
        display: none !important;
    }
}

/* -- Reduced motion: halve opacity (JS also halves, this is a fallback) - */
@media (prefers-reduced-motion: reduce) {
    .noise-overlay {
        opacity: calc(var(--noise-opacity, 0.03) * 0.5);
    }
}
/**
 * Candle Particles Component Styles
 * Canvas overlay, hover detection, and ambient glow for memorial candle.
 * @version 1.0.0
 */

/* Ensure container is a positioning context (already set in memorial.css,
   repeated here defensively for standalone use) */
.candle-container {
    position: relative;
}

/* Canvas overlay — covers the entire candle container */
.candle-particles-canvas {
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    display: block;
}

/* Invisible hover detection area — larger than the candle for easy interaction */
.candle-particles-hover {
    position: absolute;
    top: -30%;
    left: -60%;
    width: 220%;
    height: 130%;
    z-index: 3;
    pointer-events: auto;
    cursor: default;
    /* Debug: uncomment to visualize */
    /* background: rgba(255, 0, 0, 0.08); */
}

/* Warm ambient glow pulsing behind the candle */
.candle-container::after {
    content: '';
    position: absolute;
    top: -20%;
    left: 50%;
    transform: translateX(-50%);
    width: 180%;
    height: 70%;
    border-radius: 50%;
    background: radial-gradient(
        ellipse at center,
        rgba(255, 170, 50, 0.18) 0%,
        rgba(255, 130, 30, 0.08) 40%,
        transparent 70%
    );
    pointer-events: none;
    z-index: 0;
    animation: candle-glow-pulse 3s ease-in-out infinite;
}

@keyframes candle-glow-pulse {
    0%, 100% { opacity: 0.7; transform: translateX(-50%) scale(1); }
    50%      { opacity: 1;   transform: translateX(-50%) scale(1.08); }
}

/* --------------------------------------------------------
   prefers-reduced-motion: hide canvas, show static glow
   -------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .candle-particles-canvas {
        display: none;
    }

    .candle-container::after {
        animation: none;
        opacity: 0.9;
        width: 200%;
        height: 80%;
        background: radial-gradient(
            ellipse at center,
            rgba(255, 180, 60, 0.25) 0%,
            rgba(255, 140, 30, 0.10) 45%,
            transparent 75%
        );
    }
}
/**
 * 3D Card Hover Effect
 * Perspective tilt, dynamic light tracking, prismatic border glare,
 * and press feedback. Desktop only — disabled on touch and reduced-motion.
 * @version 1.0.0
 */

.card-3d-active {
  position: relative;
  transform-style: preserve-3d;
  will-change: transform;
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 0.5s cubic-bezier(0.22, 1, 0.36, 1);
  --light-x: 50%;
  --light-y: 50%;
  --tilt-shadow-x: 0px;
  --tilt-shadow-y: 0px;
}

/* Faster response while pointer is over the card */
.card-3d-active:hover {
  transition: transform 0.15s ease-out, box-shadow 0.15s ease-out;
  box-shadow:
    var(--tilt-shadow-x, 0px) var(--tilt-shadow-y, 0px) 24px -6px oklch(0 0 0 / 0.45),
    0 2px 6px oklch(0 0 0 / 0.25);
}

/* Light spot overlay */
.card-3d-active::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(
    circle at var(--light-x, 50%) var(--light-y, 50%),
    oklch(1 0 0 / 0.35) 0%, transparent 60%
  );
  transition: opacity 0.3s ease;
  mix-blend-mode: soft-light;
}

.card-3d-active:hover::before { opacity: 0.08; }

/* Prismatic border glare */
.card-3d-active::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 3;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  padding: 2px;
  background: conic-gradient(
    oklch(0.75 0.18 0) 0deg,   oklch(0.75 0.18 60) 60deg,
    oklch(0.75 0.18 120) 120deg, oklch(0.75 0.18 180) 180deg,
    oklch(0.75 0.18 270) 270deg, oklch(0.75 0.18 330) 330deg,
    oklch(0.75 0.18 0) 360deg
  );
  mask: linear-gradient(#000, #000) content-box, linear-gradient(#000, #000);
  mask-composite: exclude;
  -webkit-mask: linear-gradient(#000, #000) content-box, linear-gradient(#000, #000);
  -webkit-mask-composite: xor;
  transition: opacity 0.3s ease;
}

.card-3d-active:hover::after { opacity: 0.15; }

/* Press feedback */
.card-3d-pressed {
  transform: perspective(800px) scale(0.97) !important;
  transition: transform 0.08s ease-in !important;
}

/* Light theme: stronger light */
[data-theme="light"] .card-3d-active:hover::before,
.light-mode .card-3d-active:hover::before {
  opacity: 0.12;
}

/* Reduced motion: disable all effects */
@media (prefers-reduced-motion: reduce) {
  .card-3d-active {
    will-change: auto;
    transition: none;
  }
  .card-3d-active:hover {
    transition: none;
    box-shadow: none;
  }
  .card-3d-active::before,
  .card-3d-active::after { display: none; }
  .card-3d-pressed {
    transform: none !important;
    transition: none !important;
  }
}
/**
 * Logo Animate - Self-drawing SVG wordmark for header & hero
 * Stroke-dasharray draw-in animation, fill fade, hover glow, easter egg
 * @version 1.0.0
 */

/* --- Header logo (compact 32x32 "OK") --- */
.logo-svg {
  display: inline-block;
  vertical-align: middle;
  flex-shrink: 0;
  overflow: visible;
}

.logo-svg path {
  fill: transparent;
  stroke: #dc2626;
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: var(--path-len, 200);
  stroke-dashoffset: var(--path-len, 200);
  animation: logo-draw 1.5s cubic-bezier(0.65, 0, 0.35, 1) forwards;
}

.logo-svg path.logo-fill-in {
  fill: #dc2626;
  animation: logo-draw 1.5s cubic-bezier(0.65, 0, 0.35, 1) forwards,
             logo-fill 0.5s ease forwards 1.5s;
}

@keyframes logo-draw {
  to { stroke-dashoffset: 0; }
}

@keyframes logo-fill {
  from { fill-opacity: 0; }
  to   { fill-opacity: 1; }
}

/* --- Hover glow --- */
.logo-svg:hover {
  filter: drop-shadow(0 0 6px rgba(220, 38, 38, 0.7))
          drop-shadow(0 0 14px rgba(220, 38, 38, 0.35));
  transition: filter 0.3s ease;
}

/* --- Hero variant (larger, full band name) --- */
.logo-hero-svg {
  display: block;
  margin: 0 auto 0.75rem;
  overflow: visible;
}

.logo-hero-svg path {
  fill: transparent;
  stroke: #dc2626;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: var(--path-len, 400);
  stroke-dashoffset: var(--path-len, 400);
  animation: logo-draw 2.5s cubic-bezier(0.65, 0, 0.35, 1) forwards;
}

.logo-hero-svg path.logo-fill-in {
  fill: #dc2626;
  animation: logo-draw 2.5s cubic-bezier(0.65, 0, 0.35, 1) forwards,
             logo-fill 0.6s ease forwards 2.5s;
}

/* --- Easter egg: rock-on bounce/rotate --- */
.logo-rock-on {
  animation: rock-on-bounce 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) !important;
}

@keyframes rock-on-bounce {
  0%   { transform: scale(1) rotate(0deg); }
  20%  { transform: scale(1.3) rotate(-8deg); }
  40%  { transform: scale(0.9) rotate(6deg); }
  60%  { transform: scale(1.15) rotate(-4deg); }
  80%  { transform: scale(0.97) rotate(2deg); }
  100% { transform: scale(1) rotate(0deg); }
}

/* --- Reduced motion: skip all animations, show final state --- */
@media (prefers-reduced-motion: reduce) {
  .logo-svg path,
  .logo-hero-svg path {
    stroke-dashoffset: 0 !important;
    fill: #dc2626;
    fill-opacity: 1;
    animation: none !important;
  }
  .logo-rock-on {
    animation: none !important;
  }
}
/**
 * News Card Expand — hover expansion for bento grid cards
 * Classes: .card-expanded (hovered), .card-dimmed (siblings)
 * @version 1.0.0
 */

/* Base transition (opt-in via .nce-ready) */
.nce-ready .bento-card {
    transition:
        transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1),
        opacity 0.3s ease,
        filter 0.3s ease,
        box-shadow 0.3s ease;
    will-change: transform, opacity;
}

/* Expanded card */
.bento-card.card-expanded {
    transform: translateY(-8px) scale(1.05);
    z-index: 10;
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.5), 0 0 24px rgba(220, 38, 38, 0.12);
    border-color: rgba(255, 255, 255, 0.25);
}
.bento-card.card-expanded .card-excerpt {
    -webkit-line-clamp: unset;
    line-clamp: unset;
    max-height: none;
    overflow: visible;
}
.bento-card.card-expanded .card-image-wrapper img {
    transform: scale(1.08);
    transition: transform 0.4s ease;
}
.bento-card .smart-tags {
    transition: opacity 0.3s ease, transform 0.3s ease;
}
.bento-card.card-expanded .smart-tags {
    opacity: 1;
    transform: translateY(0);
}

/* Dimmed siblings */
.bento-card.card-dimmed {
    transform: scale(0.98);
    opacity: 0.85;
    filter: brightness(0.9);
}

/* Focus-within — keyboard parity */
.nce-ready .bento-card:focus-within:not(.card-expanded) {
    transform: translateY(-8px) scale(1.05);
    z-index: 10;
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.5), 0 0 24px rgba(220, 38, 38, 0.12);
    border-color: rgba(255, 255, 255, 0.25);
}
.nce-ready .bento-card:focus-within .card-excerpt {
    -webkit-line-clamp: unset;
    line-clamp: unset;
    max-height: none;
    overflow: visible;
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
    .nce-ready .bento-card,
    .bento-card.card-expanded,
    .bento-card.card-dimmed {
        transform: none !important;
        transition: none !important;
        filter: none !important;
    }
    .bento-card.card-expanded .card-excerpt,
    .nce-ready .bento-card:focus-within .card-excerpt {
        -webkit-line-clamp: unset;
        line-clamp: unset;
        max-height: none;
        overflow: visible;
    }
}

/* Mobile — disable (no hover) */
@media (hover: none) {
    .nce-ready .bento-card { will-change: auto; }
    .bento-card.card-expanded,
    .bento-card.card-dimmed {
        transform: none; opacity: 1; filter: none;
        box-shadow: none; z-index: auto;
    }
}
/**
 * Waveform Background Canvas
 * Decorative sine-wave canvas behind album tracks, lyrics, and timeline sections.
 * Positioned absolutely within its parent; content floats above via z-index.
 * Edges fade out with a vertical gradient mask.
 */

/* ── Canvas element ───────────────────────────────────────────── */
.waveform-bg-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 0;
    opacity: 0.5;
    -webkit-mask-image: linear-gradient(to bottom,
        transparent 0%, rgba(0,0,0,1) 12%, rgba(0,0,0,1) 88%, transparent 100%);
    mask-image: linear-gradient(to bottom,
        transparent 0%, rgba(0,0,0,1) 12%, rgba(0,0,0,1) 88%, transparent 100%);
}

/* ── Ensure content sits above the canvas ─────────────────────── */
.album-tracks-section > *:not(.waveform-bg-canvas),
.lyrics-results > *:not(.waveform-bg-canvas),
.about-timeline-section > *:not(.waveform-bg-canvas) {
    position: relative;
    z-index: 1;
}

/* ── Reduced motion: dimmer static frame, no animation ────────── */
@media (prefers-reduced-motion: reduce) {
    .waveform-bg-canvas {
        opacity: 0.3;
    }
}

/* ── Print: hide entirely ─────────────────────────────────────── */
@media print {
    .waveform-bg-canvas {
        display: none;
    }
}
/**
 * Cursor Spotlight
 * A radial gradient overlay that follows the mouse, giving a "flashlight"
 * illumination effect over page content.
 *
 * Variants:
 *   default   -- subtle white, 300px radius
 *   memorial  -- warm amber glow
 *   gallery   -- wider 400px radius for photo browsing
 */

.cursor-spotlight {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 9997;
    mix-blend-mode: soft-light;
    opacity: 0;
    background: radial-gradient(
        circle 300px at var(--cx, -9999px) var(--cy, -9999px),
        rgba(255, 255, 255, 0.06),
        transparent
    );
    will-change: opacity;
}

.cursor-spotlight--active {
    opacity: 1;
    transition: opacity 1s ease;
}

/* Memorial page: warm amber spotlight */
[data-page="memorial"] .cursor-spotlight {
    background: radial-gradient(
        circle 300px at var(--cx, -9999px) var(--cy, -9999px),
        rgba(255, 191, 64, 0.07),
        transparent
    );
}

/* Gallery page: wider spotlight for photo browsing */
[data-page="gallery"] .cursor-spotlight {
    background: radial-gradient(
        circle 400px at var(--cx, -9999px) var(--cy, -9999px),
        rgba(255, 255, 255, 0.06),
        transparent
    );
}

/* Respect reduced motion */
@media (prefers-reduced-motion: reduce) {
    .cursor-spotlight { display: none; }
}

/* Hide in print */
@media print {
    .cursor-spotlight { display: none; }
}
/* ============================================================
   Stagger Entrance — cinematic page content reveal animations
   ============================================================
   Entrance types: fade-up | fade-in | scale-in | slide-left | slide-right
   Each element uses --entrance-delay (set by JS) for its stagger offset.
   ============================================================ */

/* ── Base hidden state ── */
[data-entrance] {
    opacity: 0;
    will-change: opacity, transform;
}

/* ── Per-type initial transforms ── */
[data-entrance="fade-up"] {
    transform: translateY(30px);
}

[data-entrance="fade-in"] {
    transform: none;
}

[data-entrance="scale-in"] {
    transform: scale(0.92);
}

[data-entrance="slide-left"] {
    transform: translateX(-40px);
}

[data-entrance="slide-right"] {
    transform: translateX(40px);
}

/* ── Entered (revealed) state ── */
[data-entrance].entered {
    opacity: 1;
    transform: translateY(0) translateX(0) scale(1);
    transition:
        opacity 0.6s cubic-bezier(0.22, 1, 0.36, 1) var(--entrance-delay, 0ms),
        transform 0.6s cubic-bezier(0.22, 1, 0.36, 1) var(--entrance-delay, 0ms);
}

/* fade-in needs no transform transition, just opacity */
[data-entrance="fade-in"].entered {
    transform: none;
    transition: opacity 0.6s cubic-bezier(0.22, 1, 0.36, 1) var(--entrance-delay, 0ms);
}

/* ── Reduced motion — instant reveal, no animation ── */
@media (prefers-reduced-motion: reduce) {
    [data-entrance] {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
        will-change: auto;
    }
}

/* ── Escape hatch: .no-entrance on any ancestor ── */
.no-entrance [data-entrance] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    will-change: auto;
}

/* ── Print: never hide content ── */
@media print {
    [data-entrance] {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
    }
}

/* ── GPU hint: promote staggered cards during animation ── */
[data-entrance="fade-up"],
[data-entrance="scale-in"],
[data-entrance="slide-left"],
[data-entrance="slide-right"] {
    backface-visibility: hidden;
}

/* Remove will-change after entrance completes (perf) */
[data-entrance].entered {
    will-change: auto;
}
/* ==========================================================================
   Font Dynamics — Variable font animations driven by scroll & interaction
   Uses Inter variable axes: wght (100-900), opsz (14-32), ital (0-1)
   ========================================================================== */

/* --- Scroll-driven title weight ----------------------------------------- */
.font-dynamic-title {
    font-variation-settings:
        'wght' var(--dynamic-weight, 400),
        'opsz' var(--dynamic-opsz, 16);
    will-change: font-variation-settings;
    transition: font-variation-settings 0.15s ease-out;
}

/* --- Hover weight pulse on interactive elements ------------------------- */
.font-dynamic {
    --dynamic-weight: 400;
    font-variation-settings:
        'wght' var(--dynamic-weight, 400),
        'opsz' var(--dynamic-opsz, 16);
    transition: font-variation-settings 0.3s ease;
}

.font-dynamic:hover {
    --dynamic-weight: 700;
}

/* --- Character weight wave (hero band name) ----------------------------- */
.font-wave-char {
    display: inline-block;
    font-variation-settings: 'wght' var(--char-weight, 400);
    animation: weight-wave 4s ease-in-out infinite;
    animation-delay: var(--char-delay, 0s);
}

@keyframes weight-wave {
    0%   { font-variation-settings: 'wght' 300; }
    50%  { font-variation-settings: 'wght' 900; }
    100% { font-variation-settings: 'wght' 300; }
}

/* Whitespace chars should not animate or collapse */
.font-wave-char:empty,
.font-wave-char[data-is-space] {
    animation: none;
    width: 0.3em;
}

/* --- Memorial italic shift ---------------------------------------------- */
.memorial-italic-shift {
    font-variation-settings:
        'ital' var(--dynamic-ital, 0),
        'wght' var(--dynamic-weight, 400);
    transition: font-variation-settings 0.6s ease;
}

/* --- Optical size hint (applied by JS on [data-font-opsz]) -------------- */
[data-font-opsz] {
    font-variation-settings:
        'wght' var(--dynamic-weight, 400),
        'opsz' var(--dynamic-opsz, 16);
}

/* --- Reduced motion: disable all animation, use static values ----------- */
@media (prefers-reduced-motion: reduce) {
    .font-dynamic-title,
    .font-dynamic,
    .memorial-italic-shift,
    [data-font-opsz] {
        transition: none !important;
    }

    .font-wave-char {
        animation: none !important;
        font-variation-settings: 'wght' 600;
    }

    .font-dynamic-title {
        font-variation-settings: 'wght' 600, 'opsz' 24;
    }
}
/**
 * Container Query Responsive System
 * Adapts cards and content blocks to their container width.
 * Fallback block at the bottom for browsers without @container.
 * @version 1.0.0
 */

/* --- Container definitions ---------------------------------- */
.bento-grid          { container: news-grid / inline-size; }
.albums-bento-grid   { container: albums-grid / inline-size; }
.photo-grid-masonry  { container: gallery-grid / inline-size; }
.article-body-modern { container: article-body / inline-size; }
.members-grid        { container: members-grid / inline-size; }

/* --- News / Article cards ----------------------------------- */
@container news-grid (max-width: 300px) {
  .bento-card { flex-direction: column; font-size: var(--text-sm); }
  .bento-card .card-image-wrapper { aspect-ratio: 16/9; height: auto; }
  .bento-card.wide { grid-column: span 1; flex-direction: column; }
  .bento-card.wide .card-image-wrapper,
  .bento-card.wide .card-content { width: 100%; }
  .bento-card .card-excerpt { display: none; }
}
@container news-grid (min-width: 500px) {
  .bento-card.wide { flex-direction: row; align-items: stretch; }
  .bento-card.wide .card-image-wrapper { width: 45%; flex-shrink: 0; }
  .bento-card.wide .card-content { width: 55%; }
  .bento-card .card-title { font-size: var(--text-xl); }
}

/* --- Album cards -------------------------------------------- */
@container albums-grid (max-width: 300px) {
  .album-card-modern .album-card-stats { display: none; }
  .album-card-modern .album-info { padding: var(--space-xs); }
  .album-card-modern .album-info h3 {
    font-size: var(--text-sm); white-space: nowrap;
    overflow: hidden; text-overflow: ellipsis;
  }
  .album-card-modern .album-info .album-subtitle { display: none; }
}
@container albums-grid (min-width: 500px) {
  .album-card-modern .album-info h3 { font-size: var(--text-lg); }
  .album-card-modern .album-card-stats { gap: var(--space-md); }
}

/* --- Article body ------------------------------------------- */
@container article-body (min-width: 800px) {
  .typography-content { max-width: 72ch; margin-inline: auto; line-height: 1.9; font-size: var(--text-lg); }
  .article-lead { font-size: var(--text-xl); line-height: 1.7; }
}
@container article-body (max-width: 480px) {
  .typography-content { line-height: 1.6; font-size: var(--text-base); }
  .article-lead { font-size: var(--text-base); }
}

/* --- Member cards ------------------------------------------- */
@container members-grid (max-width: 300px) {
  .member-card { flex-direction: column; text-align: center; }
  .member-card .member-photo-container { width: 100%; aspect-ratio: 1; }
  .member-card .member-content { padding: var(--space-xs); }
  .member-card .member-content .member-name { font-size: var(--text-sm); }
}
@container members-grid (min-width: 500px) {
  .member-card { flex-direction: row; align-items: center; gap: var(--space-md); }
  .member-card .member-photo-container { width: 120px; flex-shrink: 0; }
  .member-card .member-content .member-name { font-size: var(--text-xl); }
  .member-card .member-content .member-role { font-size: var(--text-base); }
}

/* --- Gallery items ------------------------------------------ */
@container gallery-grid (max-width: 400px) {
  .photo-masonry-item__overlay { padding: var(--space-xs); }
  .photo-masonry-item__name { font-size: var(--text-xs); }
  .photo-masonry-item__desc { display: none; }
}
@container gallery-grid (min-width: 800px) {
  .photo-masonry-item__overlay { padding: var(--space-md); }
  .photo-masonry-item__name { font-size: var(--text-lg); }
}

/* --- Fallback: no @container support ------------------------ */
@supports not (container-type: inline-size) {
  @media (max-width: 480px) {
    .bento-card .card-excerpt { display: none; }
    .bento-card.wide { grid-column: span 1; flex-direction: column; }
    .bento-card.wide .card-image-wrapper,
    .bento-card.wide .card-content { width: 100%; }
    .album-card-modern .album-card-stats,
    .album-card-modern .album-info .album-subtitle { display: none; }
    .member-card { flex-direction: column; text-align: center; }
    .photo-masonry-item__desc { display: none; }
  }
  @media (min-width: 900px) {
    .bento-card.wide { flex-direction: row; }
    .bento-card.wide .card-image-wrapper { width: 45%; flex-shrink: 0; }
    .bento-card.wide .card-content { width: 55%; }
    .bento-card .card-title { font-size: var(--text-xl); }
    .typography-content { max-width: 72ch; margin-inline: auto; line-height: 1.9; font-size: var(--text-lg); }
    .member-card { flex-direction: row; align-items: center; gap: var(--space-md); }
    .member-card .member-photo-container { width: 120px; flex-shrink: 0; }
  }
}
/* ========================================
   CROSSFADE VISUAL INDICATOR
   Film-dissolve wipe + sliding track titles
   during crossfade transitions.
   ======================================== */

.crossfade-overlay {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    z-index: 5;
    border-radius: inherit;
}

.crossfade-wipe {
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg,
        transparent 0%, rgba(200,40,40,0.15) 35%,
        rgba(255,255,255,0.12) 50%, rgba(200,40,40,0.15) 65%,
        transparent 100%);
    mix-blend-mode: overlay;
    animation: crossfade-sweep var(--crossfade-duration, 2s) ease-in-out forwards;
    will-change: transform;
}

@keyframes crossfade-sweep {
    from { transform: translateX(-100%); }
    to   { transform: translateX(100%); }
}

/* Track text (shared) */
.crossfade-old-track,
.crossfade-new-track {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    white-space: nowrap;
    font-size: 0.95rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-shadow: 0 1px 6px rgba(0,0,0,0.7);
    color: #fff;
    will-change: transform, opacity;
}

/* Outgoing track: slides + fades left */
.crossfade-old-track {
    animation: crossfade-out var(--crossfade-duration, 2s) ease-in-out forwards;
}
@keyframes crossfade-out {
    0%   { opacity: 0.85; transform: translate(-50%,-50%) translateX(0); }
    100% { opacity: 0;    transform: translate(-50%,-50%) translateX(-50px); }
}

/* Incoming track: slides + fades in from right */
.crossfade-new-track {
    animation: crossfade-in var(--crossfade-duration, 2s) ease-in-out forwards;
}
@keyframes crossfade-in {
    0%   { opacity: 0; transform: translate(-50%,-50%) translateX(50px); }
    100% { opacity: 1; transform: translate(-50%,-50%) translateX(0); }
}

/* Light theme */
[data-theme="light"] .crossfade-old-track,
[data-theme="light"] .crossfade-new-track {
    color: #1a1a1a;
    text-shadow: 0 1px 4px rgba(255,255,255,0.6);
}
[data-theme="light"] .crossfade-wipe {
    background: linear-gradient(90deg,
        transparent 0%, rgba(180,30,30,0.1) 35%,
        rgba(0,0,0,0.06) 50%, rgba(180,30,30,0.1) 65%,
        transparent 100%);
}

/* Reduced motion: opacity-only, no slides */
@media (prefers-reduced-motion: reduce) {
    .crossfade-wipe { animation: none; display: none; }
    .crossfade-old-track { animation: none; opacity: 0; }
    .crossfade-new-track {
        animation: none;
        opacity: 1;
        transform: translate(-50%, -50%);
    }
}
/**
 * Audio-Reactive Background
 * Driven by --audio-bass, --audio-mid, --audio-energy (0-1)
 * set by audio-reactive-bg.component.js during music playback.
 * All effects are extremely subtle — atmospheric, not distracting.
 * @version 1.0.0
 */

/* Smooth interpolation when CSS vars change */
html {
  transition: background-color 0.3s ease;
}

/* Homepage hero — subtle warm/cool hue shift with bass */
.hero-section {
  filter: hue-rotate(calc(var(--audio-bass, 0) * 15deg));
  transition: filter 0.3s ease;
}

/* Album artwork — pulsing red glow with energy */
.album-artwork-large {
  box-shadow: 0 0 calc(var(--audio-energy, 0) * 30px)
    rgba(220, 38, 38, calc(var(--audio-energy, 0) * 0.3));
  transition: box-shadow 0.3s ease;
}

/* Vignette — edges darken with mid-frequency energy */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 9998;
  pointer-events: none;
  background: radial-gradient(
    ellipse at center,
    transparent 55%,
    rgba(0, 0, 0, calc(var(--audio-mid, 0) * 0.18)) 100%
  );
  transition: background 0.4s ease;
}

/* Reduced motion — force all audio vars to zero */
@media (prefers-reduced-motion: reduce) {
  html {
    --audio-bass: 0 !important;
    --audio-mid: 0 !important;
    --audio-energy: 0 !important;
  }
  .hero-section { filter: none !important; }
  .album-artwork-large { box-shadow: none !important; }
  body::after { display: none !important; }
}

/* Print — no pseudo-elements or filters */
@media print {
  body::after { display: none !important; }
  .hero-section { filter: none !important; }
  .album-artwork-large { box-shadow: none !important; }
}
/**
 * Snap Sections Component
 * Horizontal scroll-snap for era timelines and album decade groups.
 * @version 1.0.0
 */

/* ---- Container ---- */
.snap-container {
    display: flex;
    gap: 0;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    position: relative;
    outline: none;
}

/* Hide scrollbar but keep functional */
.snap-container::-webkit-scrollbar { display: none; }
.snap-container { -ms-overflow-style: none; scrollbar-width: none; }

/* ---- Section (each snap point) ---- */
.snap-section {
    scroll-snap-align: start;
    min-width: 100%;
    flex-shrink: 0;
    box-sizing: border-box;
    padding: 0 1rem;
}

/* ---- Label (current section name) ---- */
.snap-label {
    text-align: center;
    font-size: 0.85rem;
    color: var(--color-muted, rgba(255, 255, 255, 0.5));
    margin-bottom: 8px;
    min-height: 1.4em;
    letter-spacing: 0.04em;
    transition: opacity 0.3s ease;
    font-variant-numeric: tabular-nums;
}

/* ---- Dot navigation ---- */
.snap-dots {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 8px;
    padding: 16px 0;
}

.snap-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.3);
    background: transparent;
    cursor: pointer;
    padding: 0;
    transition: transform 0.25s ease, background-color 0.25s ease, border-color 0.25s ease;
}

.snap-dot:hover {
    border-color: rgba(255, 255, 255, 0.6);
}

.snap-dot:focus-visible {
    outline: 2px solid var(--color-primary, #dc2626);
    outline-offset: 2px;
}

.snap-dot.active {
    background: var(--color-primary, #dc2626);
    border-color: var(--color-primary, #dc2626);
    transform: scale(1.3);
}

/* ---- Reduced motion ---- */
@media (prefers-reduced-motion: reduce) {
    .snap-container { scroll-behavior: auto; }
    .snap-dot { transition: none; }
    .snap-label { transition: none; }
}
/**
 * Glitch Text Effect
 * Cinematic chromatic aberration + clip-path slice distortion
 * for hero headings. Layers red/cyan offset text via ::before/::after.
 * @version 1.0.0
 */

.glitch-title {
  position: relative;
  display: inline-block;
}

/* Shared pseudo-layer base */
.glitch-title::before,
.glitch-title::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  clip-path: inset(0 0 0 0);
  transition: opacity 0.05s;
}

/* Red channel — left offset */
.glitch-title::before {
  color: rgba(220, 38, 38, 0.8);
  transform: translateX(-2px);
  z-index: -1;
}

/* Cyan channel — right offset */
.glitch-title::after {
  color: rgba(0, 200, 255, 0.8);
  transform: translateX(2px);
  z-index: -1;
}

/* Active glitch state — layers visible, animated */
.glitch-title.glitching::before,
.glitch-title.glitching::after {
  opacity: 1;
}

.glitch-title.glitching::before {
  animation: glitch-shift 0.15s steps(2, jump-none) infinite,
             glitch-slice 0.15s steps(1, jump-none) infinite;
}

.glitch-title.glitching::after {
  animation: glitch-shift 0.15s steps(2, jump-none) infinite reverse,
             glitch-slice 0.12s steps(1, jump-none) infinite reverse;
}

/* Scanline overlay during glitch */
.glitch-title.glitching {
  background-image: repeating-linear-gradient(
    0deg,
    transparent 0px,
    transparent 1px,
    rgba(0, 0, 0, 0.1) 1px,
    rgba(0, 0, 0, 0.1) 2px
  );
  background-clip: text;
  -webkit-background-clip: text;
}

/* CSS-only hover fallback (JS overrides with class toggling) */
.glitch-title:hover::before,
.glitch-title:hover::after {
  opacity: 1;
}

/* Horizontal jitter keyframes */
@keyframes glitch-shift {
  0%   { transform: translateX(-3px); }
  25%  { transform: translateX(2px); }
  50%  { transform: translateX(-1px); }
  75%  { transform: translateX(3px); }
  100% { transform: translateX(0); }
}

/* Clip-path slice keyframes — horizontal strip reveals */
@keyframes glitch-slice {
  0%   { clip-path: inset(8% 0 78% 0); }
  10%  { clip-path: inset(42% 0 32% 0); }
  20%  { clip-path: inset(65% 0 15% 0); }
  30%  { clip-path: inset(15% 0 60% 0); }
  40%  { clip-path: inset(88% 0 2% 0); }
  50%  { clip-path: inset(28% 0 52% 0); }
  60%  { clip-path: inset(55% 0 20% 0); }
  70%  { clip-path: inset(3% 0 82% 0); }
  80%  { clip-path: inset(72% 0 8% 0); }
  90%  { clip-path: inset(35% 0 45% 0); }
  100% { clip-path: inset(0 0 0 0); }
}

/* Reduced motion: disable everything */
@media (prefers-reduced-motion: reduce) {
  .glitch-title::before,
  .glitch-title::after {
    display: none;
  }
  .glitch-title.glitching {
    background-image: none;
    animation: none;
  }
  .glitch-title.glitching::before,
  .glitch-title.glitching::after {
    animation: none;
    opacity: 0;
  }
}
/* Grid Density Toggle — controls + compact/comfortable overrides for listing grids */

/* ── Controls bar ── */
.grid-density-controls {
    display: flex;
    gap: 4px;
    margin-bottom: 16px;
    align-items: center;
}

.grid-density-btn {
    width: 32px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 6px;
    background: transparent;
    color: rgba(255, 255, 255, 0.6);
    cursor: pointer;
    transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
    padding: 0;
}

.grid-density-btn:hover {
    border-color: rgba(255, 255, 255, 0.35);
    color: rgba(255, 255, 255, 0.9);
}

.grid-density-btn:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

.grid-density-btn.active {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
}

.grid-density-btn svg {
    width: 16px;
    height: 16px;
    stroke: currentColor;
    pointer-events: none;
}

/* ── Smooth transitions on grids ── */
.bento-grid,
.albums-bento-grid,
.photo-grid-masonry {
    transition: gap 0.3s ease;
}

.bento-grid > *,
.albums-bento-grid > *,
.photo-grid-masonry > * {
    transition: padding 0.3s ease;
}

/* ── Compact mode ── */
.bento-grid.grid-compact {
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 8px;
}

.bento-grid.grid-compact .card-image-wrapper {
    height: 140px;
}

.bento-grid.grid-compact .card-excerpt {
    display: none;
}

.albums-bento-grid.grid-compact {
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 8px;
}

.albums-bento-grid.grid-compact .album-info {
    padding: 0.5rem;
}

.photo-grid-masonry.grid-compact {
    columns: 6 160px;
    column-gap: 6px;
}

.photo-grid-masonry.grid-compact .photo-masonry-item {
    margin-bottom: 6px;
}

/* ── Default mode (no-op, matches existing styles) ── */
/* .grid-default intentionally has no overrides */

/* ── Comfortable mode ── */
.bento-grid.grid-comfortable {
    grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
    gap: 24px;
}

.bento-grid.grid-comfortable .card-image-wrapper {
    height: 320px;
}

.bento-grid.grid-comfortable .card-excerpt {
    display: -webkit-box;
    -webkit-line-clamp: 6;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.albums-bento-grid.grid-comfortable {
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 24px;
}

.albums-bento-grid.grid-comfortable .album-info {
    padding: 1.25rem;
}

.photo-grid-masonry.grid-comfortable {
    columns: 2 400px;
    column-gap: 20px;
}

.photo-grid-masonry.grid-comfortable .photo-masonry-item {
    margin-bottom: 20px;
}

/* ── Mobile: hide controls, always use default ── */
@media (max-width: 768px) {
    .grid-density-controls {
        display: none;
    }
}

/* ── Light theme adjustments ── */
[data-theme="light"] .grid-density-btn {
    border-color: rgba(0, 0, 0, 0.15);
    color: rgba(0, 0, 0, 0.5);
}

[data-theme="light"] .grid-density-btn:hover {
    border-color: rgba(0, 0, 0, 0.35);
    color: rgba(0, 0, 0, 0.8);
}

[data-theme="light"] .grid-density-btn.active {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
}
/**
 * Playlist Queue / "Up Next" floating widget
 * Pairs with: js/components/playlist-queue.component.js
 * @version 1.0.0
 */

.playlist-queue {
    position: fixed; bottom: 80px; right: 16px; z-index: 850;
    max-width: 280px; width: 280px; overflow: hidden;
    background: rgba(17, 24, 39, 0.92);
    backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
    border-radius: 12px; border: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), inset 0 0 0 1px rgba(255, 255, 255, 0.04);
    transform: translateX(120%); opacity: 0;
    transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.4s ease;
    pointer-events: none;
}
.playlist-queue--visible { transform: translateX(0); opacity: 1; pointer-events: auto; }

/* Header */
.playlist-queue__header {
    display: flex; align-items: center; justify-content: space-between;
    padding: 10px 12px 6px;
    font-size: 0.7rem; font-weight: 600; letter-spacing: 0.08em;
    text-transform: uppercase; color: rgba(255, 255, 255, 0.45);
}
.playlist-queue__close {
    display: flex; align-items: center; justify-content: center;
    width: 20px; height: 20px; padding: 0; border: none; background: transparent;
    color: rgba(255, 255, 255, 0.35); cursor: pointer; border-radius: 4px;
    transition: color 0.2s, background 0.2s; font-size: 14px; line-height: 1;
}
.playlist-queue__close:hover { color: rgba(255, 255, 255, 0.8); background: rgba(255, 255, 255, 0.08); }

/* Track rows */
.playlist-queue__track {
    display: flex; gap: 10px; padding: 8px 12px; align-items: center;
    cursor: pointer; transition: background 0.2s; border-left: 2px solid transparent;
}
.playlist-queue__track:hover { background: rgba(255, 255, 255, 0.05); }
.playlist-queue__track--current { background: rgba(220, 38, 38, 0.1); border-left-color: var(--color-primary, #dc2626); }
.playlist-queue__track--next { opacity: 0.7; }
.playlist-queue__track--far { opacity: 0.5; }

/* Art thumbnail */
.playlist-queue__art {
    width: 36px; height: 36px; min-width: 36px;
    border-radius: 4px; object-fit: cover; background: rgba(255, 255, 255, 0.06);
}
.playlist-queue__art-placeholder {
    width: 36px; height: 36px; min-width: 36px; border-radius: 4px;
    background: rgba(255, 255, 255, 0.06); display: flex;
    align-items: center; justify-content: center; color: rgba(255, 255, 255, 0.25);
}

/* Track info */
.playlist-queue__info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.playlist-queue__title {
    font-size: 0.8rem; font-weight: 500; color: rgba(255, 255, 255, 0.9);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.playlist-queue__duration { font-size: 0.7rem; color: rgba(255, 255, 255, 0.4); font-variant-numeric: tabular-nums; }

/* Equalizer bars (now-playing indicator) */
.playlist-queue__equalizer { display: flex; align-items: flex-end; gap: 2px; width: 14px; height: 14px; min-width: 14px; }
.playlist-queue__eq-bar { width: 3px; border-radius: 1px; background: var(--color-primary, #dc2626); }
.playlist-queue__eq-bar:nth-child(1) { animation: pq-eq-1 0.45s ease-in-out infinite alternate; }
.playlist-queue__eq-bar:nth-child(2) { animation: pq-eq-2 0.55s ease-in-out infinite alternate; }
.playlist-queue__eq-bar:nth-child(3) { animation: pq-eq-3 0.40s ease-in-out infinite alternate; }
@keyframes pq-eq-1 { from { height: 25%; } to { height: 85%; } }
@keyframes pq-eq-2 { from { height: 60%; } to { height: 30%; } }
@keyframes pq-eq-3 { from { height: 35%; } to { height: 95%; } }
.playlist-queue__equalizer--paused .playlist-queue__eq-bar { animation-play-state: paused; }

/* Mobile (< 640px): full-width above player */
@media (max-width: 639px) {
    .playlist-queue {
        right: 0; left: 0; bottom: 72px; max-width: 100%; width: 100%;
        border-radius: 12px 12px 0 0; transform: translateY(120%);
    }
    .playlist-queue--visible { transform: translateY(0); }
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
    .playlist-queue { transition: none; }
    .playlist-queue--visible { transform: none; }
    .playlist-queue__eq-bar { animation: none !important; }
    .playlist-queue__eq-bar:nth-child(1) { height: 50%; }
    .playlist-queue__eq-bar:nth-child(2) { height: 80%; }
    .playlist-queue__eq-bar:nth-child(3) { height: 35%; }
}

/* Light theme variant */
[data-theme="light"] .playlist-queue,
.light-theme .playlist-queue {
    background: rgba(255, 255, 255, 0.92); border-color: rgba(0, 0, 0, 0.1);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
}
[data-theme="light"] .playlist-queue__header,
.light-theme .playlist-queue__header { color: rgba(0, 0, 0, 0.45); }
[data-theme="light"] .playlist-queue__close,
.light-theme .playlist-queue__close { color: rgba(0, 0, 0, 0.35); }
[data-theme="light"] .playlist-queue__close:hover,
.light-theme .playlist-queue__close:hover { color: rgba(0, 0, 0, 0.8); background: rgba(0, 0, 0, 0.06); }
[data-theme="light"] .playlist-queue__track:hover,
.light-theme .playlist-queue__track:hover { background: rgba(0, 0, 0, 0.04); }
[data-theme="light"] .playlist-queue__title,
.light-theme .playlist-queue__title { color: rgba(0, 0, 0, 0.85); }
[data-theme="light"] .playlist-queue__duration,
.light-theme .playlist-queue__duration { color: rgba(0, 0, 0, 0.4); }
[data-theme="light"] .playlist-queue__art-placeholder,
.light-theme .playlist-queue__art-placeholder { background: rgba(0, 0, 0, 0.06); color: rgba(0, 0, 0, 0.2); }
/**
 * Color Atmosphere — time-of-day and seasonal color shifts.
 * Driven by custom properties set in color-atmosphere.component.js:
 *   --atmosphere-hue-shift  (-12deg to +12deg)
 *   --atmosphere-saturation (0.85 to 1.15)
 *   --atmosphere-warmth     (rgba color for overlay tint)
 * Applied only when html.atmosphere-active is present.
 */

/* ── Subtle full-viewport warmth overlay ─────────────────── */

body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 9998;
    pointer-events: none;
    background: var(--atmosphere-warmth, transparent);
    mix-blend-mode: color;
    opacity: 0;
    transition: opacity 2s ease, background 2s ease;
}

html.atmosphere-active body::before {
    opacity: 1;
}

/* ── Hero sections pick up subtle hue shift ──────────────── */

.hero-section,
.articles-hero-modern,
.albums-hero-modern {
    filter: hue-rotate(var(--atmosphere-hue-shift, 0deg))
            saturate(var(--atmosphere-saturation, 1));
    transition: filter 2s ease;
}

/* ── Footer absorbs a hint of the atmosphere ─────────────── */

.site-footer {
    filter: hue-rotate(calc(var(--atmosphere-hue-shift, 0deg) * 0.5))
            saturate(var(--atmosphere-saturation, 1));
    transition: filter 2s ease;
}

/* ── Reduced motion: skip transitions, apply instantly ───── */

@media (prefers-reduced-motion: reduce) {
    body::before,
    .hero-section,
    .articles-hero-modern,
    .albums-hero-modern,
    .site-footer {
        transition: none;
    }
}

/* ── Print: no atmosphere overlay ────────────────────────── */

@media print {
    body::before {
        display: none;
    }
    .hero-section,
    .articles-hero-modern,
    .albums-hero-modern,
    .site-footer {
        filter: none;
    }
}
/**
 * Ink Reveal — Scroll-triggered ink splatter / paint reveal
 *
 * Elements are "painted" onto the page through an expanding ink-blot mask:
 * a clip-path circle grows from 0% to 150% while an SVG feTurbulence
 * displacement filter creates organic, chaotic edges that settle to clean.
 *
 * States:
 *   .ink-reveal--ready      Element is observed, waiting to enter viewport
 *   .ink-reveal--animating  Animation is in progress
 *   .ink-reveal--expanding  Clip-path is actively growing (CSS transition)
 *   .ink-reveal--filtered   SVG displacement filter is applied
 *   .ink-reveal--revealed   Final state — fully visible, no filter cost
 *   .ink-reveal--tinted     Has a colored ink overlay via --ink-tint
 */

/* ── Ready state — hidden, waiting for scroll trigger ──────────────── */
.ink-reveal--ready {
    opacity: 0;
    clip-path: circle(0% at 50% 50%);
    will-change: clip-path, opacity, filter;
}

/* ── Animating — intermediate state while JS drives the reveal ─────── */
.ink-reveal--animating {
    opacity: 1;
    clip-path: circle(var(--ink-clip, 0%) at 50% 50%);
}

/* ── Expanding — the CSS transition target for clip-path growth ────── */
.ink-reveal--expanding {
    opacity: 1;
    clip-path: circle(var(--ink-clip, 0%) at 50% 50%);
    transition: none; /* JS drives this via rAF for sync with filter */
}

/* ── Filtered — SVG displacement applied for organic ink edges ─────── */
.ink-reveal--filtered {
    filter: url(#ink-reveal-filter);
}

/* ── Revealed — final resting state, zero GPU cost ─────────────────── */
.ink-reveal--revealed {
    opacity: 1;
    clip-path: none;
    filter: none;
    will-change: auto;
}

/* ── Tinted ink overlay ────────────────────────────────────────────── */
.ink-reveal--tinted {
    position: relative;
}

.ink-reveal--tinted::after {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--ink-tint, transparent);
    mix-blend-mode: multiply;
    pointer-events: none;
    opacity: 0.15;
    border-radius: inherit;
    z-index: 1;
    transition: opacity var(--dur-slow, 600ms) ease-out;
}

.ink-reveal--revealed.ink-reveal--tinted::after {
    opacity: 0;
}

/* ── Specific target styling ───────────────────────────────────────── */

/* Hero sections get a dramatic center-origin reveal */
.articles-hero-modern.ink-reveal--animating,
.memorial-hero.ink-reveal--animating,
.album-hero.ink-reveal--animating {
    clip-path: circle(var(--ink-clip, 0%) at 50% 40%);
}

/* Headings inside data-reveal sections — slightly offset origin */
section[data-reveal] .ink-reveal--animating {
    clip-path: circle(var(--ink-clip, 0%) at 30% 50%);
}

/* ── Memorial page: amber-tinted ink for emotional weight ──────────── */
body[data-page="memorial"] .ink-reveal--tinted::after {
    background: rgba(245, 158, 11, 0.2);
}

/* ── Ink splatter edge decoration (pseudo-element paint drips) ─────── */
.ink-reveal--animating::before {
    content: '';
    position: absolute;
    inset: -4px;
    background: radial-gradient(
        ellipse 120% 120% at 50% 50%,
        transparent 40%,
        rgba(0, 0, 0, 0.03) 60%,
        transparent 80%
    );
    pointer-events: none;
    z-index: -1;
    opacity: 0.6;
    border-radius: inherit;
    transition: opacity var(--dur-base, 300ms) ease-out;
}

.ink-reveal--revealed::before {
    opacity: 0;
}

/* ── Light theme adjustments ───────────────────────────────────────── */
[data-theme="light"] .ink-reveal--animating::before,
.light-theme .ink-reveal--animating::before {
    background: radial-gradient(
        ellipse 120% 120% at 50% 50%,
        transparent 40%,
        rgba(0, 0, 0, 0.02) 60%,
        transparent 80%
    );
}

[data-theme="light"] .ink-reveal--tinted::after,
.light-theme .ink-reveal--tinted::after {
    mix-blend-mode: soft-light;
    opacity: 0.1;
}

/* ── Reduced motion — simple opacity fade, no clip-path or filter ──── */
@media (prefers-reduced-motion: reduce) {
    .ink-reveal--ready {
        clip-path: none;
        filter: none;
        opacity: 0;
        will-change: opacity;
        transition: opacity var(--dur-slow, 600ms) ease-out;
    }

    .ink-reveal--animating,
    .ink-reveal--expanding {
        clip-path: none;
        filter: none;
        transition: opacity var(--dur-slow, 600ms) ease-out;
    }

    .ink-reveal--revealed {
        opacity: 1;
        clip-path: none;
        filter: none;
        will-change: auto;
        transition: none;
    }

    /* No pseudo-element decorations */
    .ink-reveal--animating::before,
    .ink-reveal--tinted::after {
        display: none;
    }
}

/* ── Print — everything visible, no effects ────────────────────────── */
@media print {
    .ink-reveal--ready,
    .ink-reveal--animating,
    .ink-reveal--expanding,
    .ink-reveal--filtered,
    .ink-reveal--revealed {
        opacity: 1 !important;
        clip-path: none !important;
        filter: none !important;
    }

    .ink-reveal--animating::before,
    .ink-reveal--tinted::after {
        display: none !important;
    }
}
/**
 * Photo Era Morph Component
 * Historical photo comparison/morphing between two eras.
 * Canvas-based with scroll or slider control.
 *
 * Design tokens used:
 *   --space-1: 0.25rem  --space-2: 0.5rem  --space-4: 1rem  --space-8: 2rem
 *   --dur-fast: 150ms   --dur-base: 300ms  --dur-slow: 600ms
 *   --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1)
 *   --text-sm: clamp(0.8rem, 0.75rem + 0.25vw, 0.875rem)
 *
 * @version 1.0.0
 */

/* ==========================================================================
   BASE CONTAINER
   ========================================================================== */

.photo-era-morph {
    --pem-aspect: 3 / 2;
    --pem-radius: 8px;
    --pem-label-opacity: 1;
    --pem-slider-x: 50%;
    --pem-shadow-color: rgba(0, 0, 0, 0.6);
    --pem-accent: #dc2626;
    --pem-accent-glow: rgba(220, 38, 38, 0.5);
    --pem-handle-size: 48px;
    --pem-label-bg: rgba(0, 0, 0, 0.65);
    --pem-label-text: #f5f5f5;

    position: relative;
    width: 100%;
    aspect-ratio: var(--pem-aspect);
    overflow: hidden;
    border-radius: var(--pem-radius);
    background: #0a0a0a;
    isolation: isolate;
    contain: layout style paint;
    user-select: none;
    -webkit-user-select: none;
    cursor: default;
}

/* Dark theme adjustments (the site is dark-first) */
[data-theme="light"] .photo-era-morph {
    --pem-shadow-color: rgba(0, 0, 0, 0.3);
    --pem-label-bg: rgba(255, 255, 255, 0.75);
    --pem-label-text: #1a1a1a;
}


/* ==========================================================================
   LOADING STATE
   ========================================================================== */

.pem--loading {
    background:
        linear-gradient(
            135deg,
            #0a0a0a 0%,
            #1a1a2e 40%,
            #0a0a0a 60%,
            #1a1a2e 100%
        );
    background-size: 400% 400%;
}

@media (prefers-reduced-motion: no-preference) {
    .pem--loading {
        animation: pem-shimmer 2.5s ease-in-out infinite;
    }
}

@keyframes pem-shimmer {
    0%   { background-position: 0% 50%; }
    50%  { background-position: 100% 50%; }
    100% { background-position: 0% 50%; }
}

.pem--loading::after {
    content: '';
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: radial-gradient(
        circle at center,
        rgba(220, 38, 38, 0.08) 0%,
        transparent 70%
    );
    z-index: 1;
}


/* ==========================================================================
   CANVAS
   ========================================================================== */

.pem__canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    z-index: 1;
    /* Slight vignette overlay for cinematic feel */
}

.pem--loaded .pem__canvas {
    opacity: 1;
}

/* Vignette overlay — purely decorative */
.pem--loaded::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    background: radial-gradient(
        ellipse at center,
        transparent 50%,
        var(--pem-shadow-color) 100%
    );
    border-radius: inherit;
}

/* Film grain texture for vintage feel */
.pem--loaded::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 3;
    pointer-events: none;
    opacity: 0.035;
    mix-blend-mode: overlay;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
    background-size: 128px 128px;
    border-radius: inherit;
}


/* ==========================================================================
   LABELS (era dates)
   ========================================================================== */

.pem__labels {
    position: absolute;
    inset: 0;
    z-index: 5;
    pointer-events: none;
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    padding: var(--space-4, 1rem);
}

.pem__label {
    font-family: var(--font-secondary, 'Bebas Neue', sans-serif);
    font-size: clamp(1.2rem, 1rem + 1.5vw, 2.4rem);
    letter-spacing: 0.05em;
    line-height: 1;
    color: var(--pem-label-text);
    background: var(--pem-label-bg);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    padding: var(--space-1, 0.25rem) var(--space-2, 0.5rem);
    border-radius: 4px;
    opacity: var(--pem-label-opacity);
    transition: none; /* JS drives opacity via custom property */
    white-space: nowrap;
}

.pem__label--before {
    text-align: left;
}

.pem__label--after {
    text-align: right;
}

/* Subtle glow behind active label */
.pem__label--before::before,
.pem__label--after::before {
    content: '';
    position: absolute;
    inset: -4px;
    border-radius: 6px;
    opacity: 0.4;
    z-index: -1;
}

.pem__label--before::before {
    background: linear-gradient(135deg, var(--pem-accent-glow), transparent);
}

.pem__label--after::before {
    background: linear-gradient(225deg, var(--pem-accent-glow), transparent);
}


/* ==========================================================================
   SLIDER MODE
   ========================================================================== */

.pem--slider {
    cursor: col-resize;
}

.pem--slider .pem__labels {
    padding-bottom: var(--space-8, 2rem);
}

/* Vertical divider line */
.pem__slider-line {
    position: absolute;
    top: 0;
    bottom: 0;
    left: var(--pem-slider-x, 50%);
    width: 2px;
    z-index: 10;
    transform: translateX(-50%);
    pointer-events: none;
    /* Use will-change only during interaction */
}

.pem--dragging .pem__slider-line {
    will-change: left;
}

.pem__slider-line::before {
    content: '';
    position: absolute;
    inset: 0;
    width: 2px;
    background: linear-gradient(
        180deg,
        transparent 0%,
        var(--pem-accent) 10%,
        var(--pem-accent) 90%,
        transparent 100%
    );
    box-shadow: 0 0 8px var(--pem-accent-glow),
                0 0 20px rgba(220, 38, 38, 0.2);
}

/* Handle — circular grab target */
.pem__slider-handle {
    position: absolute;
    top: 50%;
    left: 50%;
    width: var(--pem-handle-size);
    height: var(--pem-handle-size);
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background: rgba(10, 10, 10, 0.85);
    border: 2px solid var(--pem-accent);
    box-shadow:
        0 0 0 4px rgba(220, 38, 38, 0.15),
        0 2px 12px var(--pem-shadow-color);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    pointer-events: auto;
    cursor: col-resize;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 11;
    touch-action: none;
    outline: none;
}

@media (prefers-reduced-motion: no-preference) {
    .pem__slider-handle {
        transition:
            box-shadow var(--dur-fast, 150ms) var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)),
            transform var(--dur-fast, 150ms) var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)),
            border-color var(--dur-fast, 150ms) ease;
    }
}

.pem__slider-handle:hover,
.pem__slider-handle:focus-visible {
    border-color: #fff;
    box-shadow:
        0 0 0 6px rgba(255, 255, 255, 0.15),
        0 0 24px var(--pem-accent-glow),
        0 4px 20px var(--pem-shadow-color);
}

.pem__slider-handle:focus-visible {
    outline: 2px solid var(--pem-accent);
    outline-offset: 4px;
}

.pem--dragging .pem__slider-handle {
    transform: translate(-50%, -50%) scale(1.12);
    box-shadow:
        0 0 0 8px rgba(220, 38, 38, 0.2),
        0 0 32px var(--pem-accent-glow),
        0 6px 24px var(--pem-shadow-color);
}

/* Grip arrows inside handle */
.pem__slider-grip {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

.pem__slider-grip::before,
.pem__slider-grip::after {
    content: '';
    display: block;
    width: 0;
    height: 0;
    border-style: solid;
}

/* Left arrow */
.pem__slider-grip::before {
    border-width: 5px 6px 5px 0;
    border-color: transparent #fff transparent transparent;
    opacity: 0.8;
}

/* Right arrow */
.pem__slider-grip::after {
    border-width: 5px 0 5px 6px;
    border-color: transparent transparent transparent #fff;
    opacity: 0.8;
}


/* ==========================================================================
   FALLBACK (reduced motion / no canvas)
   ========================================================================== */

.pem--fallback {
    aspect-ratio: auto;
}

.pem__fallback-wrap {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-2, 0.5rem);
    width: 100%;
}

.pem__fallback-side {
    position: relative;
    aspect-ratio: var(--pem-aspect);
    overflow: hidden;
    border-radius: calc(var(--pem-radius) / 2);
    background: #111;
}

.pem__fallback-side img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.pem__fallback-label {
    position: absolute;
    bottom: var(--space-2, 0.5rem);
    left: var(--space-2, 0.5rem);
    font-family: var(--font-secondary, 'Bebas Neue', sans-serif);
    font-size: clamp(0.9rem, 0.8rem + 0.8vw, 1.6rem);
    letter-spacing: 0.05em;
    line-height: 1;
    color: var(--pem-label-text);
    background: var(--pem-label-bg);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    padding: var(--space-1, 0.25rem) var(--space-2, 0.5rem);
    border-radius: 3px;
}


/* ==========================================================================
   SCROLL INDICATOR (subtle hint for scroll mode)
   ========================================================================== */

.pem:not(.pem--slider):not(.pem--fallback)::after {
    /* Reuse the film grain slot — scroll indicator sits above it.
       Since we already used ::after for grain, we add scroll hint differently. */
}

/* A small scroll-down hint icon at bottom center, fades after first interaction */
.pem--loaded:not(.pem--slider):not(.pem--fallback) .pem__labels::after {
    content: '';
    position: absolute;
    bottom: var(--space-2, 0.5rem);
    left: 50%;
    transform: translateX(-50%);
    width: 24px;
    height: 24px;
    border: 2px solid rgba(255, 255, 255, 0.4);
    border-radius: 12px;
    opacity: 0.6;
}

@media (prefers-reduced-motion: no-preference) {
    .pem--loaded:not(.pem--slider):not(.pem--fallback) .pem__labels::after {
        animation: pem-scroll-hint 2s ease-in-out infinite;
    }
}

@keyframes pem-scroll-hint {
    0%, 100% { opacity: 0.4; transform: translateX(-50%) translateY(0); }
    50%      { opacity: 0.8; transform: translateX(-50%) translateY(4px); }
}


/* ==========================================================================
   RESPONSIVE
   ========================================================================== */

@media (max-width: 768px) {
    .photo-era-morph {
        --pem-aspect: 4 / 3;
        --pem-radius: 6px;
        border-radius: var(--pem-radius);
    }

    .pem__labels {
        padding: var(--space-2, 0.5rem);
    }

    .pem__label {
        font-size: clamp(0.9rem, 0.8rem + 1vw, 1.5rem);
    }

    .pem--slider .pem__labels {
        padding-bottom: var(--space-4, 1rem);
    }

    .pem__slider-handle {
        --pem-handle-size: 40px;
    }

    /* Fallback stacks vertically on small screens */
    .pem__fallback-wrap {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 480px) {
    .photo-era-morph {
        --pem-aspect: 1 / 1;
    }

    .pem__label {
        font-size: 0.85rem;
        padding: 2px 6px;
    }
}


/* ==========================================================================
   REDUCED MOTION — ensure no animations
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
    .photo-era-morph,
    .photo-era-morph *,
    .photo-era-morph *::before,
    .photo-era-morph *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
    }

    /* Force fallback display */
    .pem__canvas {
        display: none !important;
    }

    .pem__slider-line,
    .pem__slider-handle {
        display: none !important;
    }
}


/* ==========================================================================
   PRINT
   ========================================================================== */

@media print {
    .pem__canvas,
    .pem__slider-line,
    .pem__slider-handle,
    .pem__labels::after {
        display: none !important;
    }

    .photo-era-morph {
        page-break-inside: avoid;
    }

    /* Show fallback in print */
    .pem--fallback .pem__fallback-wrap {
        gap: 4px;
    }

    .pem__fallback-side img {
        filter: grayscale(0.3);
    }
}


/* ==========================================================================
   HIGH CONTRAST
   ========================================================================== */

@media (forced-colors: active) {
    .pem__slider-handle {
        border: 3px solid ButtonText;
        background: Canvas;
    }

    .pem__label {
        background: Canvas;
        color: CanvasText;
        border: 1px solid CanvasText;
    }

    .pem__slider-line::before {
        background: ButtonText;
        box-shadow: none;
    }

    .pem__slider-grip::before {
        border-right-color: ButtonText;
    }

    .pem__slider-grip::after {
        border-left-color: ButtonText;
    }
}


/* ==========================================================================
   CONTAINER QUERIES (future-proof)
   ========================================================================== */

@supports (container-type: inline-size) {
    .photo-era-morph {
        container-type: inline-size;
        container-name: pem;
    }

    @container pem (max-width: 400px) {
        .pem__label {
            font-size: 0.85rem;
        }

        .pem__slider-handle {
            --pem-handle-size: 36px;
        }
    }

    @container pem (min-width: 800px) {
        .pem__label {
            font-size: 2.2rem;
            padding: var(--space-2, 0.5rem) var(--space-4, 1rem);
        }
    }
}
/**
 * Kinetic Headlines — Physics-based spring animation on headline characters.
 * Characters scatter/cascade/wave into position on scroll-enter,
 * with magnetic cursor repulsion on hover.
 *
 * States: --initial (hidden, scattered), --animating (spring in motion),
 *         --settled (resting, performant), --reduced (prefers-reduced-motion).
 *
 * @version 1.0.0
 */

/* ========================================================================
   Container: headline element
   ======================================================================== */

.kinetic-headline--ready {
  position: relative;
  display: inline-block;
  overflow: visible;
  cursor: default;
  /* Prevent layout shifts during character animation */
  min-height: 1em;
}

/* ========================================================================
   Individual character spans
   ======================================================================== */

.kinetic-char {
  display: inline-block;
  position: relative;
  will-change: transform, opacity;
  /* Ensure Cyrillic and all Unicode renders correctly */
  unicode-bidi: plaintext;
  /* Promote to own compositing layer during animation for GPU acceleration */
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

/* Spaces — maintain word spacing, no animation needed */
.kinetic-char--space {
  will-change: auto;
}

/* ----------------------------------------
   Initial state: characters hidden and scattered
   Inline transforms applied by JS; this class adds GPU promotion
   ---------------------------------------- */
.kinetic-char--initial {
  opacity: 0;
  pointer-events: none;
}

/* ----------------------------------------
   Animating: spring physics controlling transform via JS
   GPU-promoted for smooth sub-pixel rendering
   ---------------------------------------- */
.kinetic-char--animating {
  will-change: transform, opacity;
  contain: layout style;
  pointer-events: none;
}

/* ----------------------------------------
   Settled: animation complete, clean state for performance
   All inline transforms removed by JS; pure CSS handles appearance
   ---------------------------------------- */
.kinetic-char--settled {
  will-change: auto;
  transform: none;
  opacity: 1;
  pointer-events: auto;
  /* Smooth return from any future hover displacement */
  transition: transform var(--dur-base, 300ms) var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
}

/* Remove will-change from settled headline for memory savings */
.kinetic-headline--settled .kinetic-char {
  will-change: auto;
}

/* Subtle text shadow on settled characters for depth — rock aesthetic */
.kinetic-headline--settled .kinetic-char:not(.kinetic-char--space) {
  text-shadow:
    0 0 20px oklch(0.65 0.25 25 / 0.08),
    0 2px 4px oklch(0 0 0 / 0.3);
}

/* ========================================================================
   Hover interactions (desktop: animating class reapplied by JS)
   ======================================================================== */

@media (hover: hover) and (pointer: fine) {
  .kinetic-headline--settled {
    cursor: default;
  }

  /* While hovering, characters get subtle glow based on proximity to cursor */
  .kinetic-headline--ready:hover .kinetic-char--animating {
    text-shadow:
      0 0 12px oklch(0.7 0.3 25 / 0.2),
      0 0 30px oklch(0.6 0.2 25 / 0.1);
  }
}

/* ========================================================================
   Wave mode — additional visual treatment
   ======================================================================== */

[data-kinetic="wave"] .kinetic-char--settled {
  /* After wave settles, add a very subtle float */
  animation: kinetic-float 3s ease-in-out infinite;
  animation-delay: calc(var(--char-index, 0) * 80ms);
}

@keyframes kinetic-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-2px); }
}

/* ========================================================================
   Cascade mode — characters maintain a subtle bounce feel after settling
   ======================================================================== */

[data-kinetic="cascade"] .kinetic-char--settled {
  transform-origin: center bottom;
}

/* ========================================================================
   prefers-reduced-motion: NO spring physics — simple fade-in with stagger
   ======================================================================== */

@media (prefers-reduced-motion: reduce) {
  .kinetic-char--initial {
    opacity: 0;
    transform: none !important;
  }

  .kinetic-char--reduced {
    opacity: 1;
    transform: none;
    transition:
      opacity var(--dur-slow, 600ms) ease-out;
    /* Stagger delay set inline by JS: transitionDelay = (i * 50) + 'ms' */
  }

  /* No hover animations for reduced motion */
  .kinetic-headline--ready:hover .kinetic-char {
    transform: none;
    text-shadow: none;
  }

  /* No float animation */
  [data-kinetic="wave"] .kinetic-char--settled {
    animation: none;
  }
}

/* ========================================================================
   Splitting.js compatibility — ensure its generated spans work with us
   ======================================================================== */

.kinetic-headline--ready .char {
  display: inline-block;
}

.kinetic-headline--ready .whitespace {
  display: inline-block;
  width: 0.3em;
}

/* ========================================================================
   Dark theme enhancements (site default is dark)
   ======================================================================== */

.kinetic-headline--settled .kinetic-char:not(.kinetic-char--space) {
  text-shadow:
    0 0 20px oklch(0.65 0.25 25 / 0.1),
    0 2px 4px oklch(0 0 0 / 0.4);
}

[data-theme="light"] .kinetic-headline--settled .kinetic-char:not(.kinetic-char--space) {
  text-shadow:
    0 1px 3px oklch(0 0 0 / 0.15),
    0 0 12px oklch(0.5 0.1 25 / 0.05);
}

/* ========================================================================
   Responsive: reduce scatter range on small screens
   ======================================================================== */

@media (max-width: 768px) {
  .kinetic-headline--ready {
    /* Prevent horizontal overflow on mobile during scatter */
    overflow: hidden;
  }

  /* Wave float is too distracting on small screens */
  [data-kinetic="wave"] .kinetic-char--settled {
    animation: none;
  }
}

/* ========================================================================
   Print: completely clean state
   ======================================================================== */

@media print {
  .kinetic-char {
    transform: none !important;
    opacity: 1 !important;
    will-change: auto !important;
    text-shadow: none !important;
    animation: none !important;
    transition: none !important;
  }
}
/* ==========================================================================
   Magnetic Grid — organic breathing layout with cursor-reactive items
   Items gently repel/attract from cursor, idle-breathing when untouched.
   ========================================================================== */

/* ── Design tokens (local fallbacks) ───────────────────────────────── */
.magnetic-grid-item {
  --mag-x: 0px;
  --mag-y: 0px;
  --mag-shadow-x: 0px;
  --mag-shadow-y: 0px;
  --mag-scale: 1;
  --breathe-x: 0px;
  --breathe-y: 0px;
  --breathe-delay: 0s;
  --breathe-dur: 4s;
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
}

/* ── Grid container ────────────────────────────────────────────────── */
.magnetic-grid {
  position: relative;
}

/* ── Item transform and transitions ────────────────────────────────── */
.magnetic-grid-item {
  transform: translate(var(--mag-x, 0px), var(--mag-y, 0px)) scale(var(--mag-scale, 1));
  will-change: auto;
}

/* Spring-back transition when mouse leaves */
.magnetic-grid-item.mag-returning {
  transition:
    transform 0.6s var(--ease-out-expo),
    box-shadow 0.6s var(--ease-out-expo);
}

/* During active magnetic tracking — no transition, follow cursor directly */
.magnetic-grid-item.mag-active {
  will-change: transform;
  transition: none;
}

/* Performance: contain when items are idle and not animating.
   IMPORTANT: contain:layout is incompatible with CSS subgrid (breaks album card
   sizing on the albums page). Use style-only containment for grid items that
   participate in subgrid; layout containment is safe for non-subgrid grids. */
.magnetic-grid-item.mag-idle {
  contain: style;
}
/* Re-add layout containment only for grids that do NOT use subgrid */
.bento-grid > .magnetic-grid-item.mag-idle {
  contain: layout style;
}

/* ── Dynamic shadow that shifts opposite to translation ────────────── */
.magnetic-grid-item.mag-active,
.magnetic-grid-item.mag-returning {
  box-shadow:
    var(--mag-shadow-x, 0px) var(--mag-shadow-y, 0px) 20px -4px oklch(0 0 0 / 0.25),
    0 2px 8px oklch(0 0 0 / 0.15);
}

/* Proximity scale boost — items close to cursor get slightly larger */
.magnetic-grid-item.mag-proximate {
  --mag-scale: 1.02;
}

/* ── Idle breathing animation ──────────────────────────────────────── */
@keyframes mag-grid-breathe {
  0%, 100% {
    transform: translate(0px, 0px) scale(1);
  }
  50% {
    transform: translate(var(--breathe-x, 0px), var(--breathe-y, 0px)) scale(1);
  }
}

.magnetic-grid-item.mag-breathing {
  animation:
    mag-grid-breathe var(--breathe-dur, 4s)
    cubic-bezier(0.37, 0, 0.63, 1)
    var(--breathe-delay, 0s)
    infinite;
  will-change: transform;
}

/* Stop breathing when actively being manipulated */
.magnetic-grid-item.mag-active,
.magnetic-grid-item.mag-returning {
  animation: none;
}

/* ── Light theme adjustments ───────────────────────────────────────── */
[data-theme="light"] .magnetic-grid-item.mag-active,
[data-theme="light"] .magnetic-grid-item.mag-returning {
  box-shadow:
    var(--mag-shadow-x, 0px) var(--mag-shadow-y, 0px) 24px -6px oklch(0 0 0 / 0.12),
    0 2px 8px oklch(0 0 0 / 0.08);
}

.light-mode .magnetic-grid-item.mag-active,
.light-mode .magnetic-grid-item.mag-returning {
  box-shadow:
    var(--mag-shadow-x, 0px) var(--mag-shadow-y, 0px) 24px -6px oklch(0 0 0 / 0.12),
    0 2px 8px oklch(0 0 0 / 0.08);
}

/* ── Focus-visible: ensure keyboard users see focus ring over transforms ── */
.magnetic-grid-item:focus-visible {
  outline: 2px solid var(--color-primary, #dc2626);
  outline-offset: 4px;
  z-index: 1;
}

/* ── Reduced motion: disable ALL magnetic and breathing effects ────── */
@media (prefers-reduced-motion: reduce) {
  .magnetic-grid-item {
    transform: none !important;
    animation: none !important;
    transition: none !important;
    will-change: auto !important;
    contain: none !important;
    box-shadow: none !important;
    --mag-x: 0px !important;
    --mag-y: 0px !important;
    --mag-scale: 1 !important;
  }

  .magnetic-grid-item.mag-active,
  .magnetic-grid-item.mag-returning,
  .magnetic-grid-item.mag-breathing,
  .magnetic-grid-item.mag-proximate,
  .magnetic-grid-item.mag-idle {
    transform: none !important;
    animation: none !important;
    transition: none !important;
    box-shadow: none !important;
  }
}

/* ── Mobile: subtler effect, no breathing ──────────────────────────── */
@media (hover: none) {
  .magnetic-grid-item {
    transform: none !important;
    animation: none !important;
    will-change: auto !important;
  }
}
/**
 * Memorial Aurora Borealis — CSS
 *
 * Positions and styles the aurora canvas within memorial sections.
 * The canvas itself is drawn via JS (memorial-aurora.component.js);
 * these rules handle layout, layering, and accessibility.
 *
 * @version 1.0.0
 */

/* ── Canvas Positioning ───────────────────────────────────────── */

.memorial-aurora-canvas {
    position: absolute;
    inset: 0;
    z-index: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    /* The canvas renders soft light — no crisp edges needed */
    image-rendering: auto;
    /* Prevent layout contribution */
    display: block;
}

/* Ensure memorial containers create a stacking context for the canvas */
.memorial-hero {
    position: relative;
    z-index: 1;
    overflow: hidden;
}

[data-aurora] {
    position: relative;
    overflow: hidden;
}

/* All content inside aurora-enabled sections sits above the canvas */
.memorial-hero > *:not(.memorial-aurora-canvas),
[data-aurora] > *:not(.memorial-aurora-canvas) {
    position: relative;
    z-index: 1;
}

/* ── Theme Adaptations ────────────────────────────────────────── */

/* Light theme: canvas gets extra opacity reduction via CSS as a safety net.
   The JS also reduces layer alpha, but this catches edge cases.          */
[data-theme="light"] .memorial-aurora-canvas,
[data-color-scheme="light"] .memorial-aurora-canvas,
.light-theme .memorial-aurora-canvas,
.theme-light .memorial-aurora-canvas {
    opacity: 0.3;
}

/* Dark theme: full intensity — the aurora belongs to the night sky */
[data-theme="dark"] .memorial-aurora-canvas,
[data-color-scheme="dark"] .memorial-aurora-canvas,
.dark-theme .memorial-aurora-canvas,
.theme-dark .memorial-aurora-canvas {
    opacity: 1;
}

/* ── Reduced Motion ───────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
    .memorial-aurora-canvas {
        /* JS renders a single frozen frame.
           No CSS animation on the canvas itself. */
        will-change: auto;
    }
}

/* When motion is allowed, hint the compositor */
@media (prefers-reduced-motion: no-preference) {
    .memorial-aurora-canvas {
        will-change: contents;
    }
}

/* ── Smooth Fade-in on Load ───────────────────────────────────── */

@media (prefers-reduced-motion: no-preference) {
    .memorial-aurora-canvas {
        animation: aurora-fade-in 2.5s ease-out both;
    }
}

@keyframes aurora-fade-in {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

/* Light theme fade-in caps at 0.3 */
[data-theme="light"] .memorial-aurora-canvas,
[data-color-scheme="light"] .memorial-aurora-canvas,
.light-theme .memorial-aurora-canvas,
.theme-light .memorial-aurora-canvas {
    animation-name: aurora-fade-in-light;
}

@keyframes aurora-fade-in-light {
    from {
        opacity: 0;
    }
    to {
        opacity: 0.3;
    }
}

/* ── Print ────────────────────────────────────────────────────── */

@media print {
    .memorial-aurora-canvas {
        display: none !important;
    }
}

/* ── High Contrast Mode ───────────────────────────────────────── */

@media (forced-colors: active) {
    .memorial-aurora-canvas {
        display: none !important;
    }
}
/* =================================================================
   Ribbon Nav — Filmstrip Section Navigator
   A floating vertical ribbon on the right viewport edge showing
   section frames with type-colored indicators and a glowing
   active tracker. Expands on hover to reveal full labels.
   Mobile: hidden, replaced by a floating pill + bottom sheet.
   z-index: 900 (below modals 1000+, above content)
   ================================================================= */

/* -- Design tokens (scoped) --------------------------------------- */
.ribbon-nav,
.ribbon-nav-trigger,
.ribbon-nav-sheet {
    --ribbon-w-collapsed: 48px;
    --ribbon-w-expanded: 140px;
    --ribbon-bg: rgba(10, 10, 20, 0.6);
    --ribbon-bg-hover: rgba(10, 10, 20, 0.78);
    --ribbon-radius: 8px;
    --ribbon-accent: var(--color-accent, #ff4444);
    --ribbon-text: rgba(255, 255, 255, 0.55);
    --ribbon-text-active: rgba(255, 255, 255, 1);
    --ribbon-glow-spread: 8px;
    --ribbon-parallax: 0px;
    --dur-fast: 150ms;
    --dur-base: 300ms;
    --dur-slow: 600ms;
    --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
    --ease-out-back: cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* =================================================================
   DESKTOP RIBBON
   ================================================================= */
.ribbon-nav {
    position: fixed;
    right: 0;
    top: 50%;
    z-index: 900;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    width: var(--ribbon-w-collapsed);
    max-height: 70vh;
    padding: 10px 0;
    overflow: hidden;
    background: var(--ribbon-bg);
    backdrop-filter: blur(16px) saturate(180%);
    -webkit-backdrop-filter: blur(16px) saturate(180%);
    border-radius: var(--ribbon-radius) 0 0 var(--ribbon-radius);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-right: none;
    box-shadow:
        -4px 0 24px rgba(0, 0, 0, 0.3),
        inset 0 0 0 1px rgba(255, 255, 255, 0.03);

    /* Start hidden off-screen right */
    transform: translateY(-50%) translateX(100%);
    opacity: 0;
    pointer-events: none;
    transition:
        transform var(--dur-slow) var(--ease-out-expo),
        opacity var(--dur-base) ease,
        width var(--dur-base) var(--ease-out-expo),
        background var(--dur-fast) ease;

    /* Parallax offset from JS */
    margin-top: var(--ribbon-parallax);
}

/* Visible state: slide in from right */
.ribbon-nav--visible {
    transform: translateY(-50%) translateX(0);
    opacity: 1;
    pointer-events: auto;
}

/* Expanded (hover) state */
.ribbon-nav--expanded {
    width: var(--ribbon-w-expanded);
    background: var(--ribbon-bg-hover);
}

/* -- Track: thin continuous vertical line on the left edge -------- */
.ribbon-nav__track {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 1px;
    background: linear-gradient(
        to bottom,
        transparent 0%,
        rgba(255, 255, 255, 0.08) 15%,
        rgba(255, 255, 255, 0.08) 85%,
        transparent 100%
    );
    pointer-events: none;
}

/* -- Glow indicator: active section highlight on left edge -------- */
.ribbon-nav__glow {
    position: absolute;
    left: 0;
    top: var(--glow-top, 0);
    width: 3px;
    height: var(--glow-height, 32px);
    background: var(--ribbon-accent);
    border-radius: 0 3px 3px 0;
    box-shadow:
        0 0 var(--ribbon-glow-spread) var(--ribbon-accent),
        0 0 calc(var(--ribbon-glow-spread) * 2) rgba(255, 68, 68, 0.3);
    transition:
        top var(--dur-base) var(--ease-out-expo),
        height var(--dur-fast) ease;
    pointer-events: none;
    z-index: 2;
}

/* -- Section frame: individual section button --------------------- */
.ribbon-nav__frame {
    position: relative;
    display: flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    padding: 6px 8px 6px 10px;
    margin: 0;
    border: none;
    background: transparent;
    color: var(--ribbon-text);
    cursor: pointer;
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
    transition:
        background var(--dur-fast) ease,
        color var(--dur-fast) ease;
    -webkit-appearance: none;
    appearance: none;
    outline: none;
    font-family: inherit;
    line-height: 1.3;
}

.ribbon-nav__frame:hover {
    background: rgba(255, 255, 255, 0.06);
}

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

/* Active frame */
.ribbon-nav__frame--active {
    color: var(--ribbon-text-active);
}

.ribbon-nav__frame--active .ribbon-nav__num {
    color: var(--ribbon-accent);
    opacity: 1;
}

/* -- Section number ----------------------------------------------- */
.ribbon-nav__num {
    flex-shrink: 0;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.5px;
    opacity: 0.4;
    font-variant-numeric: tabular-nums;
    min-width: 1.4em;
    transition: opacity var(--dur-fast) ease, color var(--dur-fast) ease;
}

/* In expanded state, show numbers more prominently */
.ribbon-nav--expanded .ribbon-nav__num {
    opacity: 0.7;
}
.ribbon-nav--expanded .ribbon-nav__frame--active .ribbon-nav__num {
    opacity: 1;
}

/* -- Type color indicator ----------------------------------------- */
.ribbon-nav__indicator {
    flex-shrink: 0;
    width: 2px;
    height: 14px;
    border-radius: 1px;
    background: var(--indicator-color, var(--ribbon-accent));
    opacity: 0.5;
    transition: opacity var(--dur-fast) ease, height var(--dur-fast) ease;
}

.ribbon-nav__frame--active .ribbon-nav__indicator {
    opacity: 1;
    height: 18px;
}

/* -- Labels ------------------------------------------------------- */
.ribbon-nav__label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    transition: opacity var(--dur-fast) ease;
}

/* Short label: always visible in collapsed state */
.ribbon-nav__label--short {
    font-size: 9px;
    letter-spacing: 1px;
    text-transform: uppercase;
    opacity: 0.6;
    display: block;
}

.ribbon-nav__frame--active .ribbon-nav__label--short {
    opacity: 1;
    font-weight: 600;
}

/* Full label: hidden in collapsed, shown in expanded */
.ribbon-nav__label--full {
    font-size: 11px;
    letter-spacing: 0.3px;
    opacity: 0;
    display: none;
    max-width: 100px;
}

/* Expanded state: swap labels */
.ribbon-nav--expanded .ribbon-nav__label--short {
    display: none;
}

.ribbon-nav--expanded .ribbon-nav__label--full {
    display: block;
    opacity: 0.7;
}

.ribbon-nav--expanded .ribbon-nav__frame--active .ribbon-nav__label--full {
    opacity: 1;
    font-weight: 600;
}

/* =================================================================
   MOBILE TRIGGER BUTTON
   ================================================================= */
.ribbon-nav-trigger {
    position: fixed;
    right: 12px;
    bottom: calc(100px + env(safe-area-inset-bottom, 0px));
    z-index: 900;
    display: none; /* shown only on mobile */
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 10px 14px;
    border: none;
    border-radius: 999px;
    background: rgba(10, 10, 20, 0.75);
    backdrop-filter: blur(16px) saturate(180%);
    -webkit-backdrop-filter: blur(16px) saturate(180%);
    color: rgba(255, 255, 255, 0.85);
    cursor: pointer;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.35);
    border: 1px solid rgba(255, 255, 255, 0.08);
    font-family: inherit;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.5px;
    -webkit-appearance: none;
    appearance: none;

    /* Start hidden below */
    transform: translateY(80px);
    opacity: 0;
    pointer-events: none;
    transition:
        transform var(--dur-base, 300ms) var(--ease-out-back, cubic-bezier(0.34, 1.56, 0.64, 1)),
        opacity var(--dur-fast, 150ms) ease,
        background var(--dur-fast, 150ms) ease;
}

.ribbon-nav-trigger--visible {
    transform: translateY(0);
    opacity: 1;
    pointer-events: auto;
}

.ribbon-nav-trigger--active {
    background: var(--ribbon-accent, var(--color-accent, #ff4444));
}

.ribbon-nav-trigger:focus-visible {
    outline: 2px solid var(--ribbon-accent, var(--color-accent, #ff4444));
    outline-offset: 2px;
}

.ribbon-nav-trigger__count {
    font-variant-numeric: tabular-nums;
}

.ribbon-nav-trigger svg {
    flex-shrink: 0;
}

/* =================================================================
   MOBILE BOTTOM SHEET
   ================================================================= */

/* Overlay */
.ribbon-nav-sheet__overlay {
    position: fixed;
    inset: 0;
    z-index: 999;
    background: rgba(0, 0, 0, 0);
    pointer-events: none;
    transition: background var(--dur-base, 300ms) ease;
}

.ribbon-nav-sheet__overlay--visible {
    background: rgba(0, 0, 0, 0.5);
    pointer-events: auto;
}

/* Sheet */
.ribbon-nav-sheet {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1000;
    max-height: 65vh;
    overflow-y: auto;
    overscroll-behavior-y: contain;
    padding: 0 0 calc(16px + env(safe-area-inset-bottom, 0px)) 0;
    background: rgba(17, 20, 30, 0.92);
    backdrop-filter: blur(24px) saturate(200%);
    -webkit-backdrop-filter: blur(24px) saturate(200%);
    border-radius: 16px 16px 0 0;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: 0 -8px 40px rgba(0, 0, 0, 0.5);

    /* Start hidden below viewport */
    transform: translateY(calc(100% + 20px));
    transition: transform var(--dur-base, 300ms) var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
    will-change: transform;
}

.ribbon-nav-sheet--open {
    transform: translateY(0);
}

/* Dragging state: follow finger */
.ribbon-nav-sheet--dragging {
    transition: none;
    transform: translateY(var(--sheet-drag-y, 0));
}

/* Drag handle */
.ribbon-nav-sheet__handle {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 12px 0 4px;
    cursor: grab;
    touch-action: none;
}

.ribbon-nav-sheet__handle-bar {
    width: 36px;
    height: 4px;
    border-radius: 2px;
    background: rgba(255, 255, 255, 0.2);
}

/* Title */
.ribbon-nav-sheet__title {
    padding: 8px 20px 12px;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.4);
}

/* Item list */
.ribbon-nav-sheet__list {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 0 8px;
}

/* Individual item */
.ribbon-nav-sheet__item {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 14px 16px;
    border: none;
    border-radius: 10px;
    background: transparent;
    color: rgba(255, 255, 255, 0.7);
    cursor: pointer;
    text-align: left;
    font-family: inherit;
    font-size: 15px;
    line-height: 1.3;
    -webkit-appearance: none;
    appearance: none;
    outline: none;
    transition: background var(--dur-fast, 150ms) ease;
    -webkit-tap-highlight-color: transparent;
    min-height: 48px; /* WCAG 2.5.8 touch target */
}

.ribbon-nav-sheet__item:hover,
.ribbon-nav-sheet__item:focus-visible {
    background: rgba(255, 255, 255, 0.06);
}

.ribbon-nav-sheet__item:focus-visible {
    outline: 2px solid var(--ribbon-accent, var(--color-accent, #ff4444));
    outline-offset: -2px;
}

.ribbon-nav-sheet__item:active {
    background: rgba(255, 255, 255, 0.1);
}

/* Active item */
.ribbon-nav-sheet__item--active {
    color: var(--ribbon-text-active, rgba(255, 255, 255, 1));
    background: rgba(255, 255, 255, 0.04);
}

.ribbon-nav-sheet__item--active .ribbon-nav-sheet__item-num {
    color: var(--ribbon-accent, var(--color-accent, #ff4444));
    opacity: 1;
}

/* Item number */
.ribbon-nav-sheet__item-num {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.05);
    font-size: 11px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: rgba(255, 255, 255, 0.4);
    border-left: 2px solid var(--indicator-color, var(--ribbon-accent, var(--color-accent, #ff4444)));
    transition: color var(--dur-fast, 150ms) ease;
}

/* Item label */
.ribbon-nav-sheet__item-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
    min-width: 0;
}

/* =================================================================
   MOBILE BREAKPOINT: show trigger, hide desktop ribbon
   ================================================================= */
@media (max-width: 767px) {
    .ribbon-nav {
        display: none !important;
    }
    .ribbon-nav-trigger {
        display: flex;
    }
}

@media (min-width: 768px) {
    .ribbon-nav-trigger {
        display: none !important;
    }
    .ribbon-nav-sheet,
    .ribbon-nav-sheet__overlay {
        display: none !important;
    }
}

/* =================================================================
   LIGHT THEME
   ================================================================= */
[data-theme="light"] .ribbon-nav,
[data-theme="light"] .ribbon-nav-trigger {
    --ribbon-bg: rgba(250, 250, 255, 0.7);
    --ribbon-bg-hover: rgba(250, 250, 255, 0.88);
    --ribbon-text: rgba(0, 0, 0, 0.45);
    --ribbon-text-active: rgba(0, 0, 0, 0.9);
    border-color: rgba(0, 0, 0, 0.06);
    box-shadow: -4px 0 24px rgba(0, 0, 0, 0.08);
}

[data-theme="light"] .ribbon-nav__track {
    background: linear-gradient(
        to bottom,
        transparent 0%,
        rgba(0, 0, 0, 0.06) 15%,
        rgba(0, 0, 0, 0.06) 85%,
        transparent 100%
    );
}

[data-theme="light"] .ribbon-nav__frame:hover {
    background: rgba(0, 0, 0, 0.04);
}

[data-theme="light"] .ribbon-nav-trigger {
    background: rgba(255, 255, 255, 0.85);
    color: rgba(0, 0, 0, 0.75);
    border-color: rgba(0, 0, 0, 0.08);
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}

[data-theme="light"] .ribbon-nav-sheet {
    background: rgba(255, 255, 255, 0.94);
    border-top-color: rgba(0, 0, 0, 0.06);
    box-shadow: 0 -8px 40px rgba(0, 0, 0, 0.12);
}

[data-theme="light"] .ribbon-nav-sheet__handle-bar {
    background: rgba(0, 0, 0, 0.15);
}

[data-theme="light"] .ribbon-nav-sheet__title {
    color: rgba(0, 0, 0, 0.35);
}

[data-theme="light"] .ribbon-nav-sheet__item {
    color: rgba(0, 0, 0, 0.6);
}

[data-theme="light"] .ribbon-nav-sheet__item:hover,
[data-theme="light"] .ribbon-nav-sheet__item:focus-visible {
    background: rgba(0, 0, 0, 0.04);
}

[data-theme="light"] .ribbon-nav-sheet__item--active {
    color: rgba(0, 0, 0, 0.9);
    background: rgba(0, 0, 0, 0.03);
}

[data-theme="light"] .ribbon-nav-sheet__item-num {
    background: rgba(0, 0, 0, 0.04);
    color: rgba(0, 0, 0, 0.35);
}

[data-theme="light"] .ribbon-nav-sheet__overlay--visible {
    background: rgba(0, 0, 0, 0.25);
}

/* =================================================================
   HIGH CONTRAST
   ================================================================= */
@media (forced-colors: active) {
    .ribbon-nav,
    .ribbon-nav-trigger,
    .ribbon-nav-sheet {
        border: 2px solid CanvasText;
    }
    .ribbon-nav__glow {
        background: Highlight;
        box-shadow: none;
    }
    .ribbon-nav__frame--active {
        outline: 2px solid Highlight;
    }
    .ribbon-nav-sheet__item--active {
        outline: 2px solid Highlight;
    }
}

/* =================================================================
   REDUCED MOTION
   ================================================================= */
@media (prefers-reduced-motion: reduce) {
    .ribbon-nav {
        /* Instant show/hide, no slide-in */
        transition: opacity var(--dur-fast) ease;
        transform: translateY(-50%) translateX(0);
    }
    .ribbon-nav--visible {
        transform: translateY(-50%) translateX(0);
    }
    .ribbon-nav:not(.ribbon-nav--visible) {
        transform: translateY(-50%) translateX(0);
    }
    .ribbon-nav--expanded {
        transition: width var(--dur-fast) ease, opacity var(--dur-fast) ease;
    }
    .ribbon-nav__glow {
        transition: none;
        box-shadow: none;
    }
    .ribbon-nav__frame,
    .ribbon-nav__indicator,
    .ribbon-nav__num,
    .ribbon-nav__label {
        transition: none;
    }
    .ribbon-nav-trigger {
        transition: opacity var(--dur-fast) ease;
        transform: translateY(0);
    }
    .ribbon-nav-trigger--visible {
        transform: translateY(0);
    }
    .ribbon-nav-sheet {
        transition: none;
    }
    .ribbon-nav-sheet__overlay {
        transition: none;
    }
    .ribbon-nav-sheet__item {
        transition: none;
    }
}

/* =================================================================
   PRINT
   ================================================================= */
@media print {
    .ribbon-nav,
    .ribbon-nav-trigger,
    .ribbon-nav-sheet,
    .ribbon-nav-sheet__overlay {
        display: none !important;
    }
}

/* =================================================================
   SCROLL-DRIVEN GLOW PULSE (ambient when idle)
   Only in motion-ok mode.
   ================================================================= */
@media (prefers-reduced-motion: no-preference) {
    .ribbon-nav__glow {
        animation: ribbon-glow-pulse 3s ease-in-out infinite;
    }

    @keyframes ribbon-glow-pulse {
        0%, 100% {
            box-shadow:
                0 0 var(--ribbon-glow-spread) var(--ribbon-accent),
                0 0 calc(var(--ribbon-glow-spread) * 2) rgba(255, 68, 68, 0.3);
        }
        50% {
            box-shadow:
                0 0 calc(var(--ribbon-glow-spread) * 1.5) var(--ribbon-accent),
                0 0 calc(var(--ribbon-glow-spread) * 3) rgba(255, 68, 68, 0.2);
        }
    }

    /* Entrance slide for trigger on mobile */
    .ribbon-nav-trigger--visible {
        animation: ribbon-trigger-pop 0.5s var(--ease-out-back, cubic-bezier(0.34, 1.56, 0.64, 1)) both;
    }

    @keyframes ribbon-trigger-pop {
        from {
            transform: translateY(40px) scale(0.8);
            opacity: 0;
        }
        to {
            transform: translateY(0) scale(1);
            opacity: 1;
        }
    }

    /* Sheet slide up */
    .ribbon-nav-sheet--open {
        animation: ribbon-sheet-up 0.4s var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) both;
    }

    @keyframes ribbon-sheet-up {
        from {
            transform: translateY(100%);
        }
        to {
            transform: translateY(0);
        }
    }
}
/* ============================================================
   Elastic Overscroll Component
   Rubber-band bounce physics at scroll boundaries.
   Driven by CSS custom properties set from JS:
     --elastic-scale   (1..1.03)
     --elastic-origin   (top center | bottom center)
     --elastic-opacity  (0..0.15)
   ============================================================ */

/* ── Suppress native overscroll when component is active ── */

.elastic-overscroll-active {
  overscroll-behavior: none;
}

.elastic-overscroll-active body {
  overscroll-behavior: none;
}

/* ── Elastic transform on the page scroll target ── */

#swup.elastic-active,
main.elastic-active,
body > .elastic-active {
  transform: scaleY(var(--elastic-scale, 1));
  transform-origin: var(--elastic-origin, top center);
  will-change: transform;
}

/* ── Elastic transform on .elastic-scroll containers ── */

.elastic-scroll.elastic-active {
  transform: scaleY(var(--elastic-scale, 1));
  transform-origin: var(--elastic-origin, top center);
  will-change: transform;
}

.elastic-scroll {
  overscroll-behavior: none;
}

/* ── Gradient overlay ── */

.elastic-overlay {
  position: fixed;
  left: 0;
  right: 0;
  height: 80px;
  pointer-events: none;
  z-index: 9998;
  opacity: 0;
  transition: none;
}

/* Container-level overlays are absolute, not fixed */
.elastic-scroll .elastic-overlay {
  position: absolute;
}

.elastic-overlay--visible {
  opacity: 1;
}

/* Top edge: fading white/light gradient */
.elastic-overlay--top {
  top: 0;
  bottom: auto;
  background: linear-gradient(
    to bottom,
    rgba(255, 255, 255, var(--elastic-opacity, 0)) 0%,
    transparent 100%
  );
}

/* Bottom edge: fading dark gradient */
.elastic-overlay--bottom {
  top: auto;
  bottom: 0;
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, var(--elastic-opacity, 0)) 0%,
    transparent 100%
  );
}

/* Dark theme awareness: flip overlay colors */
[data-theme="dark"] .elastic-overlay--top,
.dark .elastic-overlay--top {
  background: linear-gradient(
    to bottom,
    rgba(255, 255, 255, calc(var(--elastic-opacity, 0) * 0.6)) 0%,
    transparent 100%
  );
}

[data-theme="dark"] .elastic-overlay--bottom,
.dark .elastic-overlay--bottom {
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, calc(var(--elastic-opacity, 0) * 1.2)) 0%,
    transparent 100%
  );
}

/* ── Reduced motion: disable all elastic transforms ── */

@media (prefers-reduced-motion: reduce) {
  #swup.elastic-active,
  main.elastic-active,
  body > .elastic-active,
  .elastic-scroll.elastic-active {
    transform: none !important;
    will-change: auto;
  }

  .elastic-overlay {
    display: none !important;
  }
}

/* ── Performance: isolate paint for elastic containers ── */

.elastic-scroll {
  isolation: isolate;
  contain: paint;
}

/* Prevent layout shift during stretch: children stay crisp */
#swup.elastic-active > *,
main.elastic-active > *,
.elastic-scroll.elastic-active > * {
  backface-visibility: hidden;
}
/* ═══════════════════════════════════════════════════════════════
   Smart Focal Crop — Component Styles
   Automatic focal-point cropping for object-fit: cover images
   ═══════════════════════════════════════════════════════════════ */

/* ── Design Tokens (fallbacks if not defined globally) ── */
:root {
  --sfc-dur-base: var(--dur-base, 300ms);
  --sfc-dur-slow: var(--dur-slow, 600ms);
  --sfc-ease-out-expo: var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
}

/* ── Analyzed Image — Apply Focal Position ── */
.smart-crop-analyzed {
  object-position: var(--focal-x, 50%) var(--focal-y, 50%);
  transition: object-position 0.5s var(--sfc-ease-out-expo);
}

/* ── Loading State — Subtle Shimmer ── */
.smart-crop-loading {
  position: relative;
}

.smart-crop-loading::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    110deg,
    transparent 30%,
    rgba(255, 255, 255, 0.06) 45%,
    rgba(255, 255, 255, 0.1) 50%,
    rgba(255, 255, 255, 0.06) 55%,
    transparent 70%
  );
  background-size: 300% 100%;
  animation: sfc-shimmer 1.8s ease-in-out infinite;
  pointer-events: none;
  z-index: 1;
  border-radius: inherit;
}

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

/*
 * Since img elements can't have ::after pseudo-elements,
 * we apply the shimmer on the parent container instead.
 * The parent wrapper gets the loading class via the component.
 */
img.smart-crop-loading {
  /* Handled via parent wrapper below or direct styling */
}

/*
 * For containers that wrap images — apply shimmer on the wrapper.
 * The component primarily targets images directly, so we rely on
 * the natural container styling. The shimmer is a progressive
 * enhancement that works when the parent provides positioning.
 */
.bento-card:has(> img.smart-crop-loading),
.album-card:has(> img.smart-crop-loading),
.member-card:has(> img.smart-crop-loading),
.gallery-item:has(> img.smart-crop-loading),
.card-image-wrapper:has(> img.smart-crop-loading) {
  position: relative;
  overflow: hidden;
}

.bento-card:has(> img.smart-crop-loading)::after,
.album-card:has(> img.smart-crop-loading)::after,
.member-card:has(> img.smart-crop-loading)::after,
.gallery-item:has(> img.smart-crop-loading)::after,
.card-image-wrapper:has(> img.smart-crop-loading)::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    110deg,
    transparent 30%,
    rgba(255, 255, 255, 0.06) 45%,
    rgba(255, 255, 255, 0.1) 50%,
    rgba(255, 255, 255, 0.06) 55%,
    transparent 70%
  );
  background-size: 300% 100%;
  animation: sfc-shimmer 1.8s ease-in-out infinite;
  pointer-events: none;
  z-index: 1;
  border-radius: inherit;
}

/* ── Debug Dot Overlay ── */
.smart-crop-debug-dot {
  position: absolute;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: rgba(255, 40, 40, 0.9);
  border: 2px solid #fff;
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.3),
    0 0 8px rgba(255, 40, 40, 0.6);
  transform: translate(-50%, -50%);
  z-index: 100;
  pointer-events: none;
  animation: sfc-debug-pulse 2s ease-in-out infinite;
}

.smart-crop-debug-dot::after {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 1px dashed rgba(255, 255, 255, 0.5);
}

@keyframes sfc-debug-pulse {
  0%, 100% {
    opacity: 0.9;
    transform: translate(-50%, -50%) scale(1);
  }
  50% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1.3);
  }
}

/* ── Light Theme Adjustments ── */
[data-theme="light"] .smart-crop-debug-dot {
  background: rgba(220, 20, 20, 0.95);
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.2),
    0 0 8px rgba(220, 20, 20, 0.5);
}

[data-theme="light"] .bento-card:has(> img.smart-crop-loading)::after,
[data-theme="light"] .album-card:has(> img.smart-crop-loading)::after,
[data-theme="light"] .member-card:has(> img.smart-crop-loading)::after,
[data-theme="light"] .gallery-item:has(> img.smart-crop-loading)::after,
[data-theme="light"] .card-image-wrapper:has(> img.smart-crop-loading)::after {
  background: linear-gradient(
    110deg,
    transparent 30%,
    rgba(0, 0, 0, 0.03) 45%,
    rgba(0, 0, 0, 0.06) 50%,
    rgba(0, 0, 0, 0.03) 55%,
    transparent 70%
  );
  background-size: 300% 100%;
}

/* ── Reduced Motion ── */
@media (prefers-reduced-motion: reduce) {
  .smart-crop-analyzed {
    /* Still apply focal position, just without transition */
    transition: none;
  }

  .smart-crop-loading::after,
  .bento-card:has(> img.smart-crop-loading)::after,
  .album-card:has(> img.smart-crop-loading)::after,
  .member-card:has(> img.smart-crop-loading)::after,
  .gallery-item:has(> img.smart-crop-loading)::after,
  .card-image-wrapper:has(> img.smart-crop-loading)::after {
    animation: none;
  }

  .smart-crop-debug-dot {
    animation: none;
  }
}

/* ── Print — Hide debug overlays ── */
@media print {
  .smart-crop-debug-dot {
    display: none !important;
  }

  .smart-crop-analyzed {
    transition: none;
  }
}
/**
 * Text Mask Component — CSS
 *
 * Fills heading text with images, gradients, or video through
 * background-clip: text. Includes CSS Houdini @property registrations
 * for smooth gradient angle and hue animation, preset palettes
 * (fire, ocean, aurora, metal), and full reduced-motion / light-theme /
 * print / forced-colors coverage.
 *
 * @version 1.0.0
 */

/* ╔═══════════════════════════════════════════════════════════════╗
   ║  CSS Houdini @property — registered custom properties        ║
   ║  Required for smooth interpolation of gradient angles/hues.  ║
   ╚═══════════════════════════════════════════════════════════════╝ */

@property --mask-angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

@property --mask-hue {
  syntax: "<number>";
  inherits: false;
  initial-value: 15;
}

@property --mask-hue-b {
  syntax: "<number>";
  inherits: false;
  initial-value: 45;
}

@property --mask-hue-c {
  syntax: "<number>";
  inherits: false;
  initial-value: 350;
}

@property --mask-lightness {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 65%;
}

@property --mask-parallax-x {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 50%;
}

@property --mask-parallax-y {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 50%;
}

/* ╔═══════════════════════════════════════════════════════════════╗
   ║  Design Tokens (scoped)                                      ║
   ╚═══════════════════════════════════════════════════════════════╝ */

:root {
  /* Durations */
  --tm-dur-rotate: 8s;
  --tm-dur-rotate-fast: 4s;
  --tm-dur-hue: 12s;
  --tm-dur-hue-fast: 6s;
  --tm-dur-fade: 600ms;

  /* Easing */
  --tm-ease: cubic-bezier(0.16, 1, 0.3, 1);

  /* Fallback solid colors per preset */
  --tm-fallback-fire: #e53e3e;
  --tm-fallback-ocean: #3182ce;
  --tm-fallback-aurora: #38a169;
  --tm-fallback-metal: #a0aec0;
  --tm-fallback-default: #dc2626;

  /* Chroma (oklch saturation) */
  --tm-chroma: 0.25;
  --tm-chroma-metal: 0.03;
}

/* ╔═══════════════════════════════════════════════════════════════╗
   ║  Base .text-mask                                              ║
   ╚═══════════════════════════════════════════════════════════════╝ */

.text-mask {
  /* Background-clip: text makes the background visible only through glyphs */
  -webkit-background-clip: text !important;
  background-clip: text !important;
  color: transparent !important;

  /* Ensure background-size covers the text bounding box */
  background-size: 200% 200%;
  background-repeat: no-repeat;

  /* Smooth transitions for hover state changes */
  transition:
    --mask-angle var(--tm-dur-fade) var(--tm-ease),
    background-position var(--tm-dur-fade) var(--tm-ease);

  /* Layout */
  position: relative;
  display: inline-block;
  line-height: 1.1;

  /* Prevent paint jank */
  will-change: --mask-angle, --mask-hue;

  /* Fallback if background-clip: text fails (set by JS via .text-mask--fallback) */
  /* color stays visible as fallback; transparent applied only when supported */
}

/* ── Fallback: browser doesn't support background-clip: text ─── */

.text-mask--fallback {
  -webkit-background-clip: border-box !important;
  background-clip: border-box !important;
  background: none !important;
  color: var(--tm-fallback-default) !important;
}

.text-mask--fallback[data-mask-preset="fire"] {
  color: var(--tm-fallback-fire) !important;
}

.text-mask--fallback[data-mask-preset="ocean"] {
  color: var(--tm-fallback-ocean) !important;
}

.text-mask--fallback[data-mask-preset="aurora"] {
  color: var(--tm-fallback-aurora) !important;
}

.text-mask--fallback[data-mask-preset="metal"] {
  color: var(--tm-fallback-metal) !important;
}

/* ╔═══════════════════════════════════════════════════════════════╗
   ║  Default Animated Gradient (conic through oklch hues)        ║
   ╚═══════════════════════════════════════════════════════════════╝ */

.text-mask--gradient {
  background-image: conic-gradient(
    from var(--mask-angle),
    oklch(var(--mask-lightness) var(--tm-chroma) var(--mask-hue)),
    oklch(var(--mask-lightness) var(--tm-chroma) var(--mask-hue-b)),
    oklch(var(--mask-lightness) var(--tm-chroma) var(--mask-hue-c)),
    oklch(var(--mask-lightness) var(--tm-chroma) var(--mask-hue))
  );
  background-size: 100% 100%;
}

/* ── Preset: Fire (reds / ambers / oranges) ──────────────────── */

.text-mask--gradient[data-mask-preset="fire"] {
  --mask-hue: 25;
  --mask-hue-b: 45;
  --mask-hue-c: 10;
  --tm-chroma: 0.28;
  --mask-lightness: 62%;
}

/* ── Preset: Ocean (blues / teals) ───────────────────────────── */

.text-mask--gradient[data-mask-preset="ocean"] {
  --mask-hue: 230;
  --mask-hue-b: 195;
  --mask-hue-c: 260;
  --tm-chroma: 0.22;
  --mask-lightness: 60%;
}

/* ── Preset: Aurora (greens / purples — matches memorial-aurora) */

.text-mask--gradient[data-mask-preset="aurora"] {
  --mask-hue: 145;
  --mask-hue-b: 285;
  --mask-hue-c: 170;
  --tm-chroma: 0.20;
  --mask-lightness: 68%;
}

/* ── Preset: Metal (silvers / grays, high lightness contrast) ── */

.text-mask--gradient[data-mask-preset="metal"] {
  --mask-hue: 250;
  --mask-hue-b: 220;
  --mask-hue-c: 0;
  --tm-chroma: var(--tm-chroma-metal);
  --mask-lightness: 80%;
}

/* ╔═══════════════════════════════════════════════════════════════╗
   ║  Gradient Rotation Animation                                  ║
   ╚═══════════════════════════════════════════════════════════════╝ */

@keyframes tm-rotate {
  to {
    --mask-angle: 360deg;
  }
}

@keyframes tm-hue-shift {
  0% {
    --mask-hue: var(--tm-hue-start, 15);
    --mask-hue-b: var(--tm-hue-mid, 45);
    --mask-hue-c: var(--tm-hue-end, 350);
  }
  33% {
    --mask-hue: var(--tm-hue-mid, 45);
    --mask-hue-b: var(--tm-hue-end, 350);
    --mask-hue-c: var(--tm-hue-start, 15);
  }
  66% {
    --mask-hue: var(--tm-hue-end, 350);
    --mask-hue-b: var(--tm-hue-start, 15);
    --mask-hue-c: var(--tm-hue-mid, 45);
  }
  100% {
    --mask-hue: var(--tm-hue-start, 15);
    --mask-hue-b: var(--tm-hue-mid, 45);
    --mask-hue-c: var(--tm-hue-end, 350);
  }
}

/* Apply animations only when motion is OK and element is in viewport */
@media (prefers-reduced-motion: no-preference) {
  .text-mask--gradient.text-mask--visible {
    animation:
      tm-rotate var(--tm-dur-rotate) linear infinite,
      tm-hue-shift var(--tm-dur-hue) ease-in-out infinite;
  }

  /* Hover: double speed */
  .text-mask--gradient.text-mask--visible:hover {
    animation-duration: var(--tm-dur-rotate-fast), var(--tm-dur-hue-fast);
  }
}

/* ╔═══════════════════════════════════════════════════════════════╗
   ║  Image Fill                                                   ║
   ╚═══════════════════════════════════════════════════════════════╝ */

.text-mask--image {
  background-size: cover;
  background-position:
    var(--mask-parallax-x, 50%)
    var(--mask-parallax-y, 50%);
  /* Smooth parallax shift */
  transition: background-position 150ms ease-out;
}

/* Hover: subtle cursor-tracking shift (set via JS --mask-hover-x/y) */
.text-mask--image:hover {
  background-position:
    calc(var(--mask-parallax-x, 50%) + var(--mask-hover-x, 0px))
    calc(var(--mask-parallax-y, 50%) + var(--mask-hover-y, 0px));
}

/* ╔═══════════════════════════════════════════════════════════════╗
   ║  Video Fill                                                   ║
   ╚═══════════════════════════════════════════════════════════════╝ */

.text-mask--video {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

/* Hidden video element positioned behind the text */
.text-mask__video {
  position: absolute;
  inset: 0;
  width: 0;
  height: 0;
  opacity: 0;
  pointer-events: none;
  /* Prevent it from contributing to layout */
  overflow: hidden;
}

/* Hidden canvas for video frame capture */
.text-mask__canvas {
  position: absolute;
  width: 0;
  height: 0;
  opacity: 0;
  pointer-events: none;
}

/* ╔═══════════════════════════════════════════════════════════════╗
   ║  Explicit gradient attribute (data-mask-gradient)            ║
   ╚═══════════════════════════════════════════════════════════════╝ */

.text-mask--custom-gradient {
  /* JS sets background-image from data-mask-gradient attribute */
  background-size: 300% 300%;
}

@keyframes tm-custom-gradient-shift {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

@media (prefers-reduced-motion: no-preference) {
  .text-mask--custom-gradient.text-mask--visible {
    animation: tm-custom-gradient-shift 6s ease-in-out infinite;
  }

  .text-mask--custom-gradient.text-mask--visible:hover {
    animation-duration: 3s;
  }
}

/* ╔═══════════════════════════════════════════════════════════════╗
   ║  Fade-in reveal                                               ║
   ╚═══════════════════════════════════════════════════════════════╝ */

@keyframes tm-reveal {
  from {
    opacity: 0;
    filter: blur(8px);
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    filter: blur(0px);
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: no-preference) {
  .text-mask--reveal {
    animation: tm-reveal 0.8s cubic-bezier(0.16, 1, 0.3, 1) both;
  }
}

/* Offscreen: pause animation, reduce GPU work */
.text-mask--offscreen {
  animation-play-state: paused !important;
  will-change: auto;
}

/* ╔═══════════════════════════════════════════════════════════════╗
   ║  Light Theme Adaptations                                      ║
   ╚═══════════════════════════════════════════════════════════════╝ */

[data-theme="light"] .text-mask,
[data-color-scheme="light"] .text-mask,
.light-theme .text-mask,
.theme-light .text-mask {
  /* Slightly thicker stroke for legibility on light backgrounds */
  -webkit-text-stroke: 0.5px rgba(0, 0, 0, 0.08);
  /* Boost saturation for contrast against light backgrounds */
  --mask-lightness: 45%;
  --tm-chroma: 0.30;
}

[data-theme="light"] .text-mask--gradient[data-mask-preset="metal"],
[data-color-scheme="light"] .text-mask--gradient[data-mask-preset="metal"],
.light-theme .text-mask--gradient[data-mask-preset="metal"],
.theme-light .text-mask--gradient[data-mask-preset="metal"] {
  --mask-lightness: 35%;
  --tm-chroma: 0.05;
}

/* ╔═══════════════════════════════════════════════════════════════╗
   ║  Reduced Motion                                               ║
   ╚═══════════════════════════════════════════════════════════════╝ */

@media (prefers-reduced-motion: reduce) {
  .text-mask {
    /* Kill all animation; show a static frozen gradient */
    animation: none !important;
    transition: none !important;
    will-change: auto;
    /* Static mid-rotation angle for visual interest without motion */
    --mask-angle: 135deg;
  }

  .text-mask--image {
    /* No parallax */
    background-position: center !important;
  }

  .text-mask--video {
    /* Show first frame only — JS handles this */
    animation: none !important;
  }
}

/* ╔═══════════════════════════════════════════════════════════════╗
   ║  Print                                                        ║
   ╚═══════════════════════════════════════════════════════════════╝ */

@media print {
  .text-mask {
    -webkit-background-clip: border-box !important;
    background-clip: border-box !important;
    background: none !important;
    color: #1a1a1a !important;
    -webkit-text-stroke: 0 !important;
  }
}

/* ╔═══════════════════════════════════════════════════════════════╗
   ║  Forced Colors (High Contrast)                                ║
   ╚═══════════════════════════════════════════════════════════════╝ */

@media (forced-colors: active) {
  .text-mask {
    -webkit-background-clip: border-box !important;
    background-clip: border-box !important;
    background: none !important;
    color: CanvasText !important;
    -webkit-text-stroke: 0 !important;
  }
}

/* ╔═══════════════════════════════════════════════════════════════╗
   ║  Responsive: tighten line-height on small screens             ║
   ╚═══════════════════════════════════════════════════════════════╝ */

@media (max-width: 640px) {
  .text-mask {
    line-height: 1.05;
    /* Ensure enough background covers wrapped lines */
    background-size: 250% 300%;
  }
}
/**
 * Anchor Tooltip Component
 * Rich contextual tooltips using CSS Anchor Positioning API with JS fallback.
 * Supports typed variants: simple, member, album, date.
 *
 * Uses Popover API for top-layer rendering (no z-index wars).
 * Respects prefers-reduced-motion for all animations.
 *
 * @version 1.0.0
 */

/* ========================================
   BASE TOOLTIP
   ======================================== */

.anchor-tooltip {
  /* Layout */
  position: fixed;
  max-width: 280px;
  padding: var(--space-2) var(--space-3);
  margin: 0;
  border: 0;
  overflow: visible;

  /* Visual */
  background: rgba(15, 15, 25, 0.95);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 8px;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow:
    0 8px 32px rgba(0, 0, 0, 0.4),
    0 2px 8px rgba(0, 0, 0, 0.2),
    inset 0 1px 0 rgba(255, 255, 255, 0.05);

  /* Typography */
  font-family: var(--font-primary, system-ui, sans-serif);
  font-size: var(--text-sm, clamp(0.8rem, 0.75rem + 0.25vw, 0.875rem));
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.92);
  text-align: left;
  word-wrap: break-word;
  overflow-wrap: break-word;

  /* Initial hidden state */
  opacity: 0;
  transform: scale(0.9);
  pointer-events: none;

  /* Transition */
  transition:
    opacity var(--dur-fast, 150ms) var(--ease-out-back, cubic-bezier(0.34, 1.56, 0.64, 1)),
    transform var(--dur-fast, 150ms) var(--ease-out-back, cubic-bezier(0.34, 1.56, 0.64, 1));
}

/* Visible state */
.anchor-tooltip[data-visible="true"] {
  opacity: 1;
  transform: scale(1);
  pointer-events: auto;
}

/* Popover overrides — when in top layer, reset browser defaults */
.anchor-tooltip[popover] {
  inset: unset;
  background: rgba(15, 15, 25, 0.95);
  color: rgba(255, 255, 255, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
}

/* No-popover fallback: z-index stacking */
.anchor-tooltip:not([popover]) {
  z-index: 10000;
}

/* ========================================
   ARROW / CARET
   ======================================== */

.anchor-tooltip__arrow {
  position: absolute;
  width: 16px;
  height: 8px;
  overflow: hidden;
  pointer-events: none;
}

.anchor-tooltip__arrow::before {
  content: '';
  position: absolute;
  width: 10px;
  height: 10px;
  background: rgba(15, 15, 25, 0.95);
  border: 1px solid rgba(255, 255, 255, 0.1);
  transform: rotate(45deg);
}

/* Arrow placement: top (tooltip above target) — arrow points down */
.anchor-tooltip[data-placement="top"] .anchor-tooltip__arrow {
  bottom: -8px;
  left: 50%;
  transform: translateX(-50%);
}

.anchor-tooltip[data-placement="top"] .anchor-tooltip__arrow::before {
  top: -5px;
  left: 3px;
  border-top: none;
  border-left: none;
}

/* Arrow placement: bottom (tooltip below target) — arrow points up */
.anchor-tooltip[data-placement="bottom"] .anchor-tooltip__arrow {
  top: -8px;
  left: 50%;
  transform: translateX(-50%);
}

.anchor-tooltip[data-placement="bottom"] .anchor-tooltip__arrow::before {
  bottom: -5px;
  left: 3px;
  border-bottom: none;
  border-right: none;
}

/* Arrow placement: left (tooltip left of target) — arrow points right */
.anchor-tooltip[data-placement="left"] .anchor-tooltip__arrow {
  right: -8px;
  top: 50%;
  transform: translateY(-50%) rotate(90deg);
}

.anchor-tooltip[data-placement="left"] .anchor-tooltip__arrow::before {
  top: -5px;
  left: 3px;
  border-top: none;
  border-left: none;
}

/* Arrow placement: right (tooltip right of target) — arrow points left */
.anchor-tooltip[data-placement="right"] .anchor-tooltip__arrow {
  left: -8px;
  top: 50%;
  transform: translateY(-50%) rotate(-90deg);
}

.anchor-tooltip[data-placement="right"] .anchor-tooltip__arrow::before {
  top: -5px;
  left: 3px;
  border-bottom: none;
  border-right: none;
}

/* ========================================
   TOOLTIP CONTENT LAYOUT
   ======================================== */

.anchor-tooltip__content {
  display: flex;
  flex-direction: column;
  gap: var(--space-1, 0.25rem);
}

.anchor-tooltip__text {
  margin: 0;
}

/* ========================================
   TYPED VARIANT: MEMBER
   Mini member card (photo + name + role)
   ======================================== */

.anchor-tooltip--member {
  border-top: 2px solid var(--accent, #dc2626);
  padding: var(--space-3);
}

.anchor-tooltip--member .anchor-tooltip__content {
  flex-direction: row;
  align-items: center;
  gap: var(--space-3, 0.75rem);
}

.anchor-tooltip__member-photo {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  border: 2px solid rgba(255, 255, 255, 0.15);
}

.anchor-tooltip__member-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.anchor-tooltip__member-name {
  font-weight: 600;
  font-size: 0.9rem;
  color: rgba(255, 255, 255, 0.95);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.anchor-tooltip__member-role {
  font-size: 0.78rem;
  color: rgba(255, 255, 255, 0.55);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ========================================
   TYPED VARIANT: ALBUM
   Mini album card (cover + title + year)
   ======================================== */

.anchor-tooltip--album {
  border-top: 2px solid var(--accent, #dc2626);
  padding: var(--space-3);
}

.anchor-tooltip--album .anchor-tooltip__content {
  flex-direction: row;
  align-items: center;
  gap: var(--space-3, 0.75rem);
}

.anchor-tooltip__album-cover {
  width: 48px;
  height: 48px;
  border-radius: 4px;
  object-fit: cover;
  flex-shrink: 0;
  border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}

.anchor-tooltip__album-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.anchor-tooltip__album-title {
  font-weight: 600;
  font-size: 0.9rem;
  color: rgba(255, 255, 255, 0.95);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.anchor-tooltip__album-year {
  font-size: 0.78rem;
  color: rgba(255, 255, 255, 0.55);
  font-variant-numeric: tabular-nums;
}

/* ========================================
   TYPED VARIANT: DATE
   Relative time + absolute date
   ======================================== */

.anchor-tooltip--date {
  text-align: center;
}

.anchor-tooltip__date-relative {
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--accent, #dc2626);
  margin-bottom: 2px;
}

.anchor-tooltip__date-absolute {
  font-size: 0.78rem;
  color: rgba(255, 255, 255, 0.55);
}

/* ========================================
   CSS ANCHOR POSITIONING (native)
   Progressive enhancement for supporting browsers.
   ======================================== */

@supports (anchor-name: --tooltip) {
  .anchor-tooltip[data-anchor-native="true"] {
    /* Remove fixed positioning — let anchor positioning handle it */
    position: fixed;
    position-anchor: var(--tooltip-anchor);
    inset: unset;

    /* Default: above the anchor, centered */
    position-area: block-start;
    position-try-fallbacks: flip-block, flip-inline;

    /* Gap from anchor */
    margin-bottom: 8px;
  }

  /* When flipped to bottom */
  .anchor-tooltip[data-anchor-native="true"][data-placement="bottom"] {
    margin-top: 8px;
    margin-bottom: 0;
  }
}

/* ========================================
   LIGHT THEME
   ======================================== */

[data-theme="light"] .anchor-tooltip,
[data-theme="light"] .anchor-tooltip[popover] {
  background: rgba(255, 255, 255, 0.95);
  color: rgba(15, 15, 25, 0.88);
  border-color: rgba(0, 0, 0, 0.1);
  box-shadow:
    0 8px 32px rgba(0, 0, 0, 0.12),
    0 2px 8px rgba(0, 0, 0, 0.08),
    inset 0 1px 0 rgba(255, 255, 255, 0.8);
}

[data-theme="light"] .anchor-tooltip__arrow::before {
  background: rgba(255, 255, 255, 0.95);
  border-color: rgba(0, 0, 0, 0.1);
}

[data-theme="light"] .anchor-tooltip__member-name,
[data-theme="light"] .anchor-tooltip__album-title {
  color: rgba(15, 15, 25, 0.92);
}

[data-theme="light"] .anchor-tooltip__member-role,
[data-theme="light"] .anchor-tooltip__album-year,
[data-theme="light"] .anchor-tooltip__date-absolute {
  color: rgba(15, 15, 25, 0.55);
}

[data-theme="light"] .anchor-tooltip__member-photo {
  border-color: rgba(0, 0, 0, 0.1);
}

[data-theme="light"] .anchor-tooltip__album-cover {
  border-color: rgba(0, 0, 0, 0.1);
}

/* ========================================
   PREFERS-REDUCED-MOTION
   Instant show/hide — no scale/fade.
   ======================================== */

@media (prefers-reduced-motion: reduce) {
  .anchor-tooltip {
    transition: none !important;
    transform: none !important;
  }

  .anchor-tooltip[data-visible="true"] {
    transform: none !important;
  }
}

/* ========================================
   FOCUS INDICATOR (keyboard trigger)
   ======================================== */

[data-tooltip]:focus-visible {
  outline: 2px solid var(--accent, #dc2626);
  outline-offset: 2px;
  border-radius: 2px;
}

/* ========================================
   RESPONSIVE
   ======================================== */

@media (max-width: 480px) {
  .anchor-tooltip {
    max-width: calc(100vw - 24px);
    font-size: 0.82rem;
  }

  .anchor-tooltip__member-photo {
    width: 32px;
    height: 32px;
  }

  .anchor-tooltip__album-cover {
    width: 40px;
    height: 40px;
  }
}

/* ========================================
   PRINT — hide all tooltips
   ======================================== */

@media print {
  .anchor-tooltip {
    display: none !important;
  }
}
/**
 * Constellation Hero Component Styles
 * Canvas overlay for interactive particle constellation backgrounds.
 * Works on .hero-section, .articles-hero-modern, [data-constellation]
 * @version 1.0.0
 */

/* ── Canvas Positioning ──────────────────────────────────────── */

.hero-section,
.articles-hero-modern,
[data-constellation] {
    position: relative;
    /* Ensure stacking context for the canvas */
}

.constellation-hero-canvas {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    display: block;
    width: 100%;
    height: 100%;

    /* Smooth canvas rendering */
    image-rendering: auto;

    /* Default: full opacity for dark theme */
    opacity: 1;
    transition: opacity var(--dur-slow, 600ms) var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
}

/* ── Allow pointer events on the parent but pass-through on canvas ── */

.hero-section:hover .constellation-hero-canvas,
.articles-hero-modern:hover .constellation-hero-canvas,
[data-constellation]:hover .constellation-hero-canvas {
    pointer-events: auto;
}

/* ── Ensure hero content stays above the canvas ─────────────── */

.hero-section > *:not(.constellation-hero-canvas),
.articles-hero-modern > *:not(.constellation-hero-canvas),
[data-constellation] > *:not(.constellation-hero-canvas) {
    position: relative;
    z-index: 1;
}

/* ── Light Theme ─────────────────────────────────────────────── */

[data-theme="light"] .constellation-hero-canvas,
[data-color-scheme="light"] .constellation-hero-canvas {
    opacity: 0.4;
}

@media (prefers-color-scheme: light) {
    :root:not([data-theme="dark"]):not([data-color-scheme="dark"]) .constellation-hero-canvas {
        opacity: 0.4;
    }
}

/* ── Reduced Motion ──────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
    .constellation-hero-canvas {
        /* Static frozen frame — no CSS animations either */
        transition: none;
    }
}

/* ── Print: hide canvas completely ───────────────────────────── */

@media print {
    .constellation-hero-canvas {
        display: none !important;
    }
}

/* ── High Contrast Mode ──────────────────────────────────────── */

@media (forced-colors: active) {
    .constellation-hero-canvas {
        display: none !important;
    }
}

/* ── Small screens: slightly reduce canvas opacity for readability ── */

@media (max-width: 480px) {
    .constellation-hero-canvas {
        opacity: 0.85;
    }

    [data-theme="light"] .constellation-hero-canvas,
    [data-color-scheme="light"] .constellation-hero-canvas {
        opacity: 0.3;
    }
}
/**
 * Sound Wave Divider Component Styles
 * Animated canvas-based audio waveform section dividers.
 * Three styles: smooth (flowing sine), bars (equalizer), dots (bouncing).
 *
 * @version 1.0.0
 */

/* ==========================================================================
   Base wrapper
   ========================================================================== */

.wave-divider {
    position: relative;
    width: 100%;
    height: 48px;
    overflow: hidden;
    pointer-events: none;
    user-select: none;
    contain: layout size;
    /* Breathing room between sections */
    margin-block: var(--space-4, 1rem);
    /* Smooth fade-in on creation */
    animation: waveDividerFadeIn var(--dur-slow, 600ms) var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) both;
}

/* Memorial variant — slightly taller with amber glow ambiance */
.wave-divider--memorial {
    height: 56px;
    margin-block: var(--space-6, 1.5rem);
}

/* Canvas element — fills the wrapper exactly */
.wave-divider__canvas {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    /* Canvas renders its own content; no additional browser paint needed */
    image-rendering: auto;
}

/* ==========================================================================
   Entrance animation
   ========================================================================== */

@keyframes waveDividerFadeIn {
    from {
        opacity: 0;
        transform: scaleX(0.6);
    }
    to {
        opacity: 1;
        transform: scaleX(1);
    }
}

/* ==========================================================================
   Reduced motion — no animation at all
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
    .wave-divider {
        animation: none;
        opacity: 0.6;
    }

    .wave-divider__canvas {
        /* Static frame rendered by JS; no CSS animation */
    }
}

/* ==========================================================================
   Light theme adjustments
   ========================================================================== */

:root.light-theme .wave-divider,
[data-theme="light"] .wave-divider {
    /* Slightly stronger presence on light backgrounds */
    opacity: 0.85;
}

:root.light-theme .wave-divider--memorial,
[data-theme="light"] .wave-divider--memorial {
    opacity: 0.9;
}

/* ==========================================================================
   Responsive sizing
   ========================================================================== */

/* Smaller on mobile to be less intrusive */
@media (max-width: 768px) {
    .wave-divider {
        height: 36px;
        margin-block: var(--space-4, 1rem);
    }

    .wave-divider--memorial {
        height: 44px;
    }
}

/* Tiny screens — even more compact */
@media (max-width: 375px) {
    .wave-divider {
        height: 28px;
    }

    .wave-divider--memorial {
        height: 36px;
    }
}

/* Wide screens — slightly taller for proportional look */
@media (min-width: 1440px) {
    .wave-divider {
        height: 56px;
    }

    .wave-divider--memorial {
        height: 64px;
    }
}

/* ==========================================================================
   Print — hidden (decorative only)
   ========================================================================== */

@media print {
    .wave-divider {
        display: none !important;
    }
}

/* ==========================================================================
   High contrast mode — show a simple rule instead
   ========================================================================== */

@media (forced-colors: active) {
    .wave-divider {
        height: 2px;
        background: CanvasText;
        overflow: visible;
    }

    .wave-divider__canvas {
        display: none;
    }
}

/* ==========================================================================
   Contextual spacing — tighter when between tightly packed elements
   ========================================================================== */

.card + .wave-divider,
.wave-divider + .card {
    margin-block: var(--space-4, 1rem);
}

article + .wave-divider,
.wave-divider + article {
    margin-block: var(--space-6, 1.5rem);
}

section + .wave-divider,
.wave-divider + section {
    margin-block: var(--space-8, 2rem);
}
/**
 * SVG Morph Sections — scroll-driven organic shape dividers.
 * Phase 87 — Extreme Creative Frontend
 */

/* ══════════════════════════════════════════════════════════
   CONTAINER
══════════════════════════════════════════════════════════ */

.svg-morph-divider {
  position: relative;
  display: block;
  width: 100%;
  overflow: hidden;
  line-height: 0;
  font-size: 0;
  pointer-events: none;
  user-select: none;
  z-index: 1;
  /* Prevent layout shifts — reserve space */
  min-height: 80px;
  margin: 0;
  padding: 0;
}

/* Custom height via attribute — fallback handled by JS (default 80px) */
.svg-morph-divider[data-morph-height] {
  min-height: auto;
}

/* Auto-inserted dividers get negative margins to overlap section edges */
.svg-morph-divider--auto {
  margin-top: calc(-1 * var(--space-4, 1rem));
  margin-bottom: calc(-1 * var(--space-4, 1rem));
  position: relative;
  z-index: 2;
}

/* ══════════════════════════════════════════════════════════
   SVG ELEMENT
══════════════════════════════════════════════════════════ */

.svg-morph-divider__svg {
  display: block;
  width: 100%;
  height: 100%;
  position: relative;
  /* GPU acceleration for parallax transforms */
  will-change: transform;
  transform: translateZ(0);
  transition: none;
}

.svg-morph-divider__path {
  /* No transition — updated via rAF for buttery smooth animation */
  transition: none;
  vector-effect: non-scaling-stroke;
}

/* ══════════════════════════════════════════════════════════
   INITIAL STATE / LOAD TRANSITION
══════════════════════════════════════════════════════════ */

.svg-morph-divider__svg {
  opacity: 0;
  animation: svgMorphFadeIn var(--dur-slow, 600ms) var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1)) forwards;
  animation-delay: var(--dur-base, 300ms);
}

@keyframes svgMorphFadeIn {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ══════════════════════════════════════════════════════════
   REDUCED MOTION
══════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .svg-morph-divider__svg {
    opacity: 1;
    animation: none;
    will-change: auto;
    transform: none !important;
  }

  .svg-morph-divider__path {
    transition: none;
  }
}

/* ══════════════════════════════════════════════════════════
   DARK/LIGHT THEME INTEGRATION
══════════════════════════════════════════════════════════ */

/* When color is not explicitly set, adapt to theme */
[data-theme="light"] .svg-morph-divider__path {
  opacity: 0.95;
}

[data-theme="dark"] .svg-morph-divider__path {
  opacity: 1;
}

/* ══════════════════════════════════════════════════════════
   RESPONSIVE
══════════════════════════════════════════════════════════ */

/* Slightly shorter on mobile for denser layouts */
@media (max-width: 768px) {
  .svg-morph-divider {
    min-height: 48px;
  }

  .svg-morph-divider--auto {
    margin-top: calc(-0.5 * var(--space-4, 1rem));
    margin-bottom: calc(-0.5 * var(--space-4, 1rem));
  }
}

@media (max-width: 480px) {
  .svg-morph-divider {
    min-height: 36px;
  }
}

/* Ultra-wide: slightly taller for proportion */
@media (min-width: 1920px) {
  .svg-morph-divider {
    min-height: 100px;
  }
}

/* ══════════════════════════════════════════════════════════
   PRINT
══════════════════════════════════════════════════════════ */

@media print {
  .svg-morph-divider {
    display: none;
  }
}
/* ============================================================
   Lazy Video Poster Component
   Cinematic YouTube facade with blur-up thumbnails, gradient
   overlay, animated play button, and ambient shimmer mode.
   Saves ~500KB+ per embed by deferring iframe load.
   ============================================================ */

/* ── Design Tokens (local fallbacks) ── */
.lazy-video {
  --_space-2: var(--space-2, 0.5rem);
  --_space-4: var(--space-4, 1rem);
  --_space-6: var(--space-6, 1.5rem);
  --_text-sm: var(--text-sm, clamp(0.8rem, 0.75rem + 0.25vw, 0.875rem));
  --_dur-fast: var(--dur-fast, 150ms);
  --_dur-base: var(--dur-base, 300ms);
  --_dur-slow: var(--dur-slow, 600ms);
  --_ease-out-expo: var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
}

/* ── Wrapper ── */
.lazy-video {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: 8px;
  background: #0a0a0a;
  contain: content;
  isolation: isolate;
}

/* ── Poster Container ── */
.lazy-video__poster {
  position: absolute;
  inset: 0;
  z-index: 2;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  transition: opacity var(--_dur-base) var(--_ease-out-expo);
}

/* Focus-visible ring for keyboard navigation */
.lazy-video__poster:focus-visible {
  outline: 3px solid #fff;
  outline-offset: -3px;
  border-radius: inherit;
}

.lazy-video__poster:focus:not(:focus-visible) {
  outline: none;
}

/* ── Thumbnails: blur-up technique ── */
.lazy-video__thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Placeholder: tiny blurred image */
.lazy-video__thumb--placeholder {
  z-index: 1;
  filter: blur(20px);
  transform: scale(1.1);
  transition: opacity var(--_dur-slow) var(--_ease-out-expo);
}

/* HD thumbnail: sits on top, invisible until loaded */
.lazy-video__thumb--hd {
  z-index: 2;
  opacity: 0;
  transition: opacity var(--_dur-slow) var(--_ease-out-expo);
}

/* Once HD loads, show it and hide placeholder */
.lazy-video--poster-loaded .lazy-video__thumb--hd {
  opacity: 1;
}

.lazy-video--poster-loaded .lazy-video__thumb--placeholder {
  opacity: 0;
}

/* ── Gradient Overlay ── */
.lazy-video__overlay {
  position: absolute;
  inset: 0;
  z-index: 3;
  background: linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0) 0%,
    rgba(0, 0, 0, 0.05) 40%,
    rgba(0, 0, 0, 0.4) 70%,
    rgba(0, 0, 0, 0.75) 100%
  );
  pointer-events: none;
  transition: background var(--_dur-base) var(--_ease-out-expo);
}

/* Darker on hover for contrast */
.lazy-video__poster:hover .lazy-video__overlay,
.lazy-video__poster:focus-visible .lazy-video__overlay {
  background: linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0.1) 0%,
    rgba(0, 0, 0, 0.15) 40%,
    rgba(0, 0, 0, 0.5) 70%,
    rgba(0, 0, 0, 0.85) 100%
  );
}

/* ── Play Button ── */
.lazy-video__play-btn {
  position: relative;
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 68px;
  height: 48px;
  pointer-events: none;
  transition: transform var(--_dur-base) var(--_ease-out-expo),
              filter var(--_dur-base) var(--_ease-out-expo);
}

.lazy-video__play-btn svg {
  display: block;
  filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.5));
}

.lazy-video__play-btn circle {
  transition: fill var(--_dur-fast) ease,
              r var(--_dur-base) var(--_ease-out-expo);
}

/* Hover: enlarge and brighten play button */
.lazy-video__poster:hover .lazy-video__play-btn,
.lazy-video__poster:focus-visible .lazy-video__play-btn {
  transform: scale(1.12);
}

.lazy-video__poster:hover .lazy-video__play-btn circle,
.lazy-video__poster:focus-visible .lazy-video__play-btn circle {
  fill: rgba(204, 0, 0, 0.9);
  stroke: rgba(255, 255, 255, 0.5);
}

/* Active: press feedback */
.lazy-video__poster:active .lazy-video__play-btn {
  transform: scale(0.96);
}

/* Pulse animation for play button */
@keyframes lvp-pulse {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.06);
  }
}

.lazy-video__play-btn {
  animation: lvp-pulse 2.5s ease-in-out infinite;
}

/* ── Info Bar (title + duration) ── */
.lazy-video__info {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 5;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--_space-2);
  padding: var(--_space-4) var(--_space-4) var(--_space-2);
  pointer-events: none;
}

.lazy-video__title {
  flex: 1 1 auto;
  color: #fff;
  font-size: var(--_text-sm);
  font-weight: 500;
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.8);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--_dur-base) var(--_ease-out-expo),
              transform var(--_dur-base) var(--_ease-out-expo);
}

/* Show title on hover */
.lazy-video__poster:hover .lazy-video__title,
.lazy-video__poster:focus-visible .lazy-video__title {
  opacity: 1;
  transform: translateY(0);
}

.lazy-video__duration {
  flex: 0 0 auto;
  padding: 2px 6px;
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  line-height: 1.4;
}

/* ── Iframe (injected on play) ── */
.lazy-video__iframe {
  position: absolute;
  inset: 0;
  z-index: 6;
  width: 100%;
  height: 100%;
  border: none;
  opacity: 0;
  animation: lvp-iframe-in var(--_dur-base) var(--_ease-out-expo) forwards;
}

@keyframes lvp-iframe-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ── Playing State ── */
.lazy-video--playing {
  background: #000;
}

/* ── Ambient Mode ── */
.lazy-video--ambient {
  pointer-events: none;
}

.lazy-video--ambient .lazy-video__iframe {
  pointer-events: none;
}

/* Shimmer placeholder for ambient mode */
.lazy-video__shimmer {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    110deg,
    #111 8%,
    #1a1a1a 18%,
    #111 33%
  );
  background-size: 200% 100%;
  animation: lvp-shimmer 1.5s ease-in-out infinite;
}

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

/* ── Reduced Motion ── */
@media (prefers-reduced-motion: reduce) {
  .lazy-video__play-btn {
    animation: none;
  }

  .lazy-video__thumb--placeholder {
    filter: blur(20px);
    transition: none;
  }

  .lazy-video__thumb--hd {
    transition: none;
  }

  .lazy-video--poster-loaded .lazy-video__thumb--hd {
    opacity: 1;
  }

  .lazy-video--poster-loaded .lazy-video__thumb--placeholder {
    opacity: 0;
  }

  .lazy-video__iframe {
    animation: none;
    opacity: 1;
  }

  .lazy-video__shimmer {
    animation: none;
    background: #1a1a1a;
  }

  .lazy-video__title {
    transition: none;
    opacity: 1;
    transform: none;
  }

  .lazy-video__overlay {
    transition: none;
  }

  .lazy-video__play-btn {
    transition: none;
  }

  .lazy-video__poster {
    transition: none;
  }
}

/* ── Responsive ── */
@media (max-width: 480px) {
  .lazy-video__play-btn svg {
    width: 54px;
    height: 38px;
  }

  .lazy-video__info {
    padding: var(--_space-2);
  }

  .lazy-video__title {
    font-size: 0.75rem;
  }
}

@media (min-width: 1200px) {
  .lazy-video__play-btn svg {
    width: 80px;
    height: 56px;
  }
}

/* ── Light Theme Variant ── */
[data-theme="light"] .lazy-video {
  background: #e0e0e0;
}

[data-theme="light"] .lazy-video__shimmer {
  background: linear-gradient(
    110deg,
    #ddd 8%,
    #eee 18%,
    #ddd 33%
  );
  background-size: 200% 100%;
}

[data-theme="light"] .lazy-video__duration {
  background: rgba(0, 0, 0, 0.7);
}

/* ── Print: hide video embeds ── */
@media print {
  .lazy-video {
    display: none;
  }
}
/**
 * Marquee Ticker — Smooth infinite-scroll horizontal ticker.
 * Pure CSS animation with duplicated content for seamless looping.
 * Gradient edge masks, pause-on-hover, multiple visual styles.
 *
 * States: --initialized (ready), --paused (hover/JS), --offscreen (GPU save).
 * Styles: default, uppercase, editorial, breaking.
 *
 * @version 1.0.0
 */

/* ========================================================================
   Keyframes
   ======================================================================== */

@keyframes ticker-scroll {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    transform: translate3d(-50%, 0, 0);
  }
}

@keyframes ticker-scroll-reverse {
  from {
    transform: translate3d(-50%, 0, 0);
  }
  to {
    transform: translate3d(0, 0, 0);
  }
}

/* ========================================================================
   Container: .marquee-ticker
   ======================================================================== */

.marquee-ticker {
  position: relative;
  overflow: hidden;
  width: 100%;
  padding-block: var(--space-sm, 0.5rem);
  background: var(--color-bg-elevated, #222228);
  border-block: 1px solid oklch(1 0 0 / 0.06);
  /* Gradient edge masks for smooth fade-in/out */
  -webkit-mask-image: linear-gradient(
    to right,
    transparent,
    black 80px,
    black calc(100% - 80px),
    transparent
  );
  mask-image: linear-gradient(
    to right,
    transparent,
    black 80px,
    black calc(100% - 80px),
    transparent
  );
  /* Contain paint for performance */
  contain: content;
  /* Prevent text selection during scroll */
  -webkit-user-select: none;
  user-select: none;
}

/* ========================================================================
   Inner track: the duplicated content wrapper that actually moves
   ======================================================================== */

.marquee-ticker__track {
  display: flex;
  align-items: center;
  width: max-content;
  gap: 0;
  will-change: transform;
  animation: ticker-scroll var(--ticker-duration, 30s) linear infinite;
}

/* Reverse direction */
.marquee-ticker--reverse .marquee-ticker__track {
  animation-name: ticker-scroll-reverse;
}

/* Speed modifiers */
.marquee-ticker--slow .marquee-ticker__track {
  --ticker-duration: 60s;
}

.marquee-ticker--fast .marquee-ticker__track {
  --ticker-duration: 15s;
}

/* ========================================================================
   Pause states
   ======================================================================== */

/* Hover pause */
.marquee-ticker:hover .marquee-ticker__track {
  animation-play-state: paused;
}

/* JS-controlled pause */
.marquee-ticker[data-ticker-paused="true"] .marquee-ticker__track {
  animation-play-state: paused;
}

/* Off-screen: pause animation to save GPU */
.marquee-ticker--offscreen .marquee-ticker__track {
  animation-play-state: paused;
}

/* ========================================================================
   Content items
   ======================================================================== */

.marquee-ticker__item {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  white-space: nowrap;
  font-size: var(--text-sm, 0.875rem);
  color: var(--color-neutral, #b0b3bc);
  line-height: 1.4;
  padding-inline: var(--space-xs, 0.25rem);
}

/* Links within items */
.marquee-ticker__item a {
  color: inherit;
  text-decoration: none;
  transition: color var(--dur-fast, 150ms) ease;
}

.marquee-ticker__item a:hover,
.marquee-ticker__item a:focus-visible {
  color: var(--color-primary-light, #ef4444);
}

/* ========================================================================
   Separators between items
   ======================================================================== */

.marquee-ticker__separator {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  padding-inline: var(--space-sm, 0.5rem);
  color: var(--color-primary, #dc2626);
  font-size: var(--text-xs, 0.75rem);
  opacity: 0.7;
}

/* ========================================================================
   Style Variant: UPPERCASE
   All-caps, wide letter-spacing, display font
   ======================================================================== */

.marquee-ticker--uppercase {
  background: var(--color-bg-surface, #2f2f35);
  border-block: 1px solid oklch(1 0 0 / 0.08);
  padding-block: var(--space-md, 0.75rem);
}

.marquee-ticker--uppercase .marquee-ticker__item {
  text-transform: uppercase;
  letter-spacing: 0.15em;
  font-family: 'Bebas Neue', 'Impact', sans-serif;
  font-size: var(--text-base, 1rem);
  color: oklch(0.9 0.01 260);
  font-weight: 400;
}

.marquee-ticker--uppercase .marquee-ticker__separator {
  font-size: var(--text-sm, 0.875rem);
  opacity: 0.5;
  color: var(--color-amber, #f59e0b);
}

/* ========================================================================
   Style Variant: EDITORIAL
   Italic serif, elegant separators
   ======================================================================== */

.marquee-ticker--editorial {
  background: oklch(0.12 0.005 260);
  border-block: 1px solid oklch(1 0 0 / 0.04);
  padding-block: var(--space-md, 0.75rem);
}

.marquee-ticker--editorial .marquee-ticker__item {
  font-family: var(--font-editorial, 'Playfair Display', Georgia, serif);
  font-style: italic;
  font-size: var(--text-base, 1rem);
  color: oklch(0.8 0.02 85);
  letter-spacing: 0.02em;
}

.marquee-ticker--editorial .marquee-ticker__separator {
  color: oklch(0.6 0.06 85);
  opacity: 0.8;
  font-style: normal;
  padding-inline: var(--space-md, 0.75rem);
}

/* ========================================================================
   Style Variant: BREAKING
   Red stripe, bold white text, urgency feel
   ======================================================================== */

.marquee-ticker--breaking {
  background: var(--color-primary, #dc2626);
  border-block: none;
  padding-block: var(--space-sm, 0.5rem) calc(var(--space-sm, 0.5rem) + 1px);
  /* Override mask: sharper edges for urgency */
  -webkit-mask-image: linear-gradient(
    to right,
    transparent,
    black 40px,
    black calc(100% - 40px),
    transparent
  );
  mask-image: linear-gradient(
    to right,
    transparent,
    black 40px,
    black calc(100% - 40px),
    transparent
  );
}

.marquee-ticker--breaking .marquee-ticker__item {
  color: #fff;
  font-weight: 700;
  font-size: var(--text-sm, 0.875rem);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.marquee-ticker--breaking .marquee-ticker__separator {
  color: oklch(1 0 0 / 0.6);
  padding-inline: var(--space-md, 0.75rem);
}

/* ========================================================================
   Stacked tickers — subtle visual separation
   ======================================================================== */

.marquee-ticker + .marquee-ticker {
  border-top: none;
  margin-top: -1px;
}

/* ========================================================================
   Light theme overrides
   ======================================================================== */

:root[data-theme="light"] .marquee-ticker,
[data-theme="light"] .marquee-ticker {
  background: oklch(0.97 0.005 260);
  border-block-color: oklch(0 0 0 / 0.08);
}

:root[data-theme="light"] .marquee-ticker__item,
[data-theme="light"] .marquee-ticker__item {
  color: oklch(0.3 0.01 260);
}

:root[data-theme="light"] .marquee-ticker--uppercase,
[data-theme="light"] .marquee-ticker--uppercase {
  background: oklch(0.95 0.005 260);
}

:root[data-theme="light"] .marquee-ticker--editorial,
[data-theme="light"] .marquee-ticker--editorial {
  background: oklch(0.98 0.005 85);
}

:root[data-theme="light"] .marquee-ticker--editorial .marquee-ticker__item,
[data-theme="light"] .marquee-ticker--editorial .marquee-ticker__item {
  color: oklch(0.35 0.03 85);
}

/* Breaking stays red in all themes */

/* ========================================================================
   Responsive: narrower fade masks on small viewports
   ======================================================================== */

@media (max-width: 640px) {
  .marquee-ticker {
    -webkit-mask-image: linear-gradient(
      to right,
      transparent,
      black 32px,
      black calc(100% - 32px),
      transparent
    );
    mask-image: linear-gradient(
      to right,
      transparent,
      black 32px,
      black calc(100% - 32px),
      transparent
    );
    padding-block: var(--space-xs, 0.25rem);
  }

  .marquee-ticker--breaking {
    -webkit-mask-image: linear-gradient(
      to right,
      transparent,
      black 20px,
      black calc(100% - 20px),
      transparent
    );
    mask-image: linear-gradient(
      to right,
      transparent,
      black 20px,
      black calc(100% - 20px),
      transparent
    );
  }
}

/* ========================================================================
   Reduced motion: no animation, show static content
   ======================================================================== */

@media (prefers-reduced-motion: reduce) {
  .marquee-ticker__track {
    animation: none !important;
    will-change: auto;
  }

  /* Show only first copy, hide duplicates */
  .marquee-ticker__copy:not(:first-child) {
    display: none;
  }

  /* Allow text to wrap and be readable */
  .marquee-ticker {
    overflow: visible;
    -webkit-mask-image: none;
    mask-image: none;
  }

  .marquee-ticker__track {
    flex-wrap: wrap;
    width: auto;
    justify-content: center;
    gap: var(--space-xs, 0.25rem);
  }

  .marquee-ticker__item {
    white-space: normal;
  }
}

/* ========================================================================
   Print: hide ticker (purely decorative)
   ======================================================================== */

@media print {
  .marquee-ticker {
    display: none;
  }
}
/**
 * Scoped Styles Component
 * CSS @scope isolation + interpolate-size height animations for expandable cards.
 * Card micro-interactions: press, lift, image zoom, clip-path underlines, focus glow.
 *
 * Relies on :root { interpolate-size: allow-keywords; } already set in base.css.
 * @version 1.0.0
 */

/* =============================================================================
   Design Tokens (local, component-scoped)
   ============================================================================= */

:root {
    --ss-dur-fast: 150ms;
    --ss-dur-base: 300ms;
    --ss-dur-slow: 600ms;
    --ss-ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
    --ss-ease-out-back: cubic-bezier(0.34, 1.56, 0.64, 1);
    --ss-clamp-lines: 3;
    --ss-card-lift: -4px;
    --ss-press-scale: 0.97;
    --ss-img-zoom: 1.05;
}


/* =============================================================================
   Part 1 — Expandable Card Content
   ============================================================================= */

/* Toggle button */
.ss-expand-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.35em;
    padding: var(--space-xs, 0.25rem) var(--space-sm, 0.5rem);
    margin-top: var(--space-xs, 0.25rem);
    border: none;
    background: transparent;
    color: var(--color-primary, #dc2626);
    font: inherit;
    font-size: var(--text-sm, 0.875rem);
    font-weight: 600;
    cursor: pointer;
    border-radius: 4px;
    transition:
        color var(--ss-dur-fast) ease,
        background var(--ss-dur-fast) ease;
    -webkit-tap-highlight-color: transparent;
}

.ss-expand-toggle:hover {
    background: oklch(0.55 0.22 25 / 0.08);
}

.ss-expand-toggle:focus-visible {
    outline: 2px solid var(--color-primary, #dc2626);
    outline-offset: 2px;
}

/* Chevron icon */
.ss-expand-chevron {
    display: inline-block;
    width: 1em;
    height: 1em;
    transition: transform var(--ss-dur-base) var(--ss-ease-out-back);
    transform: rotate(0deg);
}

.ss-expand-toggle[aria-expanded="true"] .ss-expand-chevron {
    transform: rotate(180deg);
}


/* --- Collapsed Content: interpolate-size path (modern browsers) --- */

.ss-expandable-content {
    overflow: hidden;
    transition: height var(--ss-dur-slow) var(--ss-ease-out-expo);
}

/* Collapsed state: clamp to N lines */
.ss-expandable-content[data-collapsed="true"] {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: var(--ss-clamp-lines, 3);
    line-clamp: var(--ss-clamp-lines, 3);
    /* height: auto — interpolate-size allows animating from this */
}

/* Expanded state: full height */
.ss-expandable-content[data-collapsed="false"] {
    -webkit-line-clamp: unset;
    line-clamp: unset;
    display: block;
    /* height: auto — interpolate-size allows animating to this */
}

/* Render optimisation for collapsed off-screen cards */
.ss-expandable-content[data-collapsed="true"] {
    content-visibility: auto;
    contain-intrinsic-size: auto 4.5em; /* approx 3 lines */
}

.ss-expandable-content[data-collapsed="false"] {
    content-visibility: visible;
}


/* --- Fallback path: explicit pixel height (set by JS) --- */

.ss-fallback .ss-expandable-content {
    transition: height var(--ss-dur-slow) var(--ss-ease-out-expo);
    overflow: hidden;
}

.ss-fallback .ss-expandable-content[data-collapsed="true"] {
    /* JS sets height: Npx based on clamp measurement */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: var(--ss-clamp-lines, 3);
    line-clamp: var(--ss-clamp-lines, 3);
}

.ss-fallback .ss-expandable-content[data-collapsed="false"] {
    /* JS sets height: scrollHeightpx */
    -webkit-line-clamp: unset;
    line-clamp: unset;
    display: block;
}


/* =============================================================================
   Part 2 — Card Micro-Interactions
   ============================================================================= */

/* --- a) Press Scale --- */
.ss-ready .bento-card,
.ss-ready .album-card-modern,
.ss-ready .member-card,
.ss-ready .video-card {
    transition:
        transform var(--ss-dur-fast) var(--ss-ease-out-back),
        box-shadow var(--ss-dur-base) ease;
}

.ss-card-pressing {
    transform: scale(var(--ss-press-scale, 0.97)) !important;
    transition: transform 80ms ease-in !important;
}


/* --- b) Hover Card Lift --- */
@media (hover: hover) {
    .ss-ready .bento-card:hover,
    .ss-ready .album-card-modern:hover,
    .ss-ready .member-card:hover,
    .ss-ready .video-card:hover {
        transform: translateY(var(--ss-card-lift, -4px));
        box-shadow:
            0 12px 32px oklch(0 0 0 / 0.35),
            0 4px 8px oklch(0 0 0 / 0.2);
    }
}


/* --- c) Image Hover Zoom --- */
.ss-ready .bento-card img,
.ss-ready .album-card-modern img,
.ss-ready .member-card img,
.ss-ready .video-card img {
    transition: transform var(--ss-dur-base) var(--ss-ease-out-expo);
}

.ss-ready .bento-card:hover img,
.ss-ready .album-card-modern:hover img,
.ss-ready .member-card:hover img,
.ss-ready .video-card:hover img {
    transform: scale(var(--ss-img-zoom, 1.05));
}

/* Ensure overflow clip on image wrappers */
.ss-ready .card-image-wrapper,
.ss-ready .album-cover,
.ss-ready .member-photo {
    overflow: hidden;
}


/* --- d) Clip-Path Link Underline Draw --- */
.ss-ready .bento-card a:not(.ss-expand-toggle):not(.card-hitbox),
.ss-ready .album-card-modern a:not(.ss-expand-toggle):not(.card-hitbox),
.ss-ready .member-card a:not(.ss-expand-toggle):not(.card-hitbox),
.ss-ready .video-card a:not(.ss-expand-toggle):not(.card-hitbox) {
    position: relative;
    text-decoration: none;
}

.ss-ready .bento-card a:not(.ss-expand-toggle):not(.card-hitbox)::after,
.ss-ready .album-card-modern a:not(.ss-expand-toggle):not(.card-hitbox)::after,
.ss-ready .member-card a:not(.ss-expand-toggle):not(.card-hitbox)::after,
.ss-ready .video-card a:not(.ss-expand-toggle):not(.card-hitbox)::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 1px;
    background: currentColor;
    clip-path: inset(0 100% 0 0);
    transition: clip-path var(--ss-dur-base) var(--ss-ease-out-expo);
}

.ss-ready .bento-card a:not(.ss-expand-toggle):not(.card-hitbox):hover::after,
.ss-ready .album-card-modern a:not(.ss-expand-toggle):not(.card-hitbox):hover::after,
.ss-ready .member-card a:not(.ss-expand-toggle):not(.card-hitbox):hover::after,
.ss-ready .video-card a:not(.ss-expand-toggle):not(.card-hitbox):hover::after {
    clip-path: inset(0 0 0 0);
}


/* --- e) Focus-Within Accent Glow --- */
.ss-ready .bento-card:focus-within,
.ss-ready .album-card-modern:focus-within,
.ss-ready .member-card:focus-within,
.ss-ready .video-card:focus-within {
    box-shadow:
        0 0 0 2px var(--color-primary, #dc2626),
        0 0 16px oklch(0.55 0.22 25 / 0.15);
    outline: none;
}


/* =============================================================================
   Part 3 — CSS @scope Isolation
   ============================================================================= */

/*
 * Progressive enhancement: @scope rules for component isolation.
 * Browsers without @scope ignore these blocks entirely — the fallback
 * .component-scope-{name} prefix classes are applied by JavaScript.
 */

@supports (selector(:scope)) {

    @scope (.bento-card) {
        :scope {
            position: relative;
            isolation: isolate;
        }
        .card-excerpt {
            font-size: var(--text-sm, 0.875rem);
            line-height: 1.6;
        }
        .card-meta {
            font-size: var(--text-xs, 0.75rem);
            opacity: 0.7;
        }
    }

    @scope (.album-card-modern) {
        :scope {
            position: relative;
            isolation: isolate;
        }
        .album-title {
            font-weight: 700;
        }
        .album-year {
            font-size: var(--text-xs, 0.75rem);
            opacity: 0.65;
        }
    }

    @scope (.member-card) {
        :scope {
            position: relative;
            isolation: isolate;
        }
        .member-name {
            font-weight: 700;
        }
        .member-role {
            font-size: var(--text-sm, 0.875rem);
            opacity: 0.7;
        }
    }

    @scope (.video-card) {
        :scope {
            position: relative;
            isolation: isolate;
        }
        .video-title {
            font-weight: 600;
        }
        .video-duration {
            font-size: var(--text-xs, 0.75rem);
            opacity: 0.6;
        }
    }

}

/* Fallback: class-prefix scoping for older browsers (JS adds these classes) */
.component-scope-bento .card-excerpt {
    font-size: var(--text-sm, 0.875rem);
    line-height: 1.6;
}
.component-scope-bento .card-meta {
    font-size: var(--text-xs, 0.75rem);
    opacity: 0.7;
}
.component-scope-album .album-title {
    font-weight: 700;
}
.component-scope-album .album-year {
    font-size: var(--text-xs, 0.75rem);
    opacity: 0.65;
}
.component-scope-member .member-name {
    font-weight: 700;
}
.component-scope-member .member-role {
    font-size: var(--text-sm, 0.875rem);
    opacity: 0.7;
}
.component-scope-video .video-title {
    font-weight: 600;
}
.component-scope-video .video-duration {
    font-size: var(--text-xs, 0.75rem);
    opacity: 0.6;
}


/* =============================================================================
   Light Theme Adjustments
   ============================================================================= */

[data-theme="light"] .ss-expand-toggle:hover {
    background: oklch(0.55 0.22 25 / 0.06);
}

[data-theme="light"] .ss-ready .bento-card:focus-within,
[data-theme="light"] .ss-ready .album-card-modern:focus-within,
[data-theme="light"] .ss-ready .member-card:focus-within,
[data-theme="light"] .ss-ready .video-card:focus-within {
    box-shadow:
        0 0 0 2px var(--color-primary-hover, #b91c1c),
        0 0 12px oklch(0.55 0.22 25 / 0.1);
}

@media (hover: hover) {
    [data-theme="light"] .ss-ready .bento-card:hover,
    [data-theme="light"] .ss-ready .album-card-modern:hover,
    [data-theme="light"] .ss-ready .member-card:hover,
    [data-theme="light"] .ss-ready .video-card:hover {
        box-shadow:
            0 12px 32px oklch(0 0 0 / 0.12),
            0 4px 8px oklch(0 0 0 / 0.08);
    }
}


/* =============================================================================
   Reduced Motion — disable ALL animations
   ============================================================================= */

@media (prefers-reduced-motion: reduce) {

    .ss-expand-chevron {
        transition: none !important;
    }

    .ss-expandable-content {
        transition: none !important;
    }

    .ss-ready .bento-card,
    .ss-ready .album-card-modern,
    .ss-ready .member-card,
    .ss-ready .video-card {
        transition: none !important;
    }

    .ss-card-pressing {
        transform: none !important;
        transition: none !important;
    }

    .ss-ready .bento-card:hover,
    .ss-ready .album-card-modern:hover,
    .ss-ready .member-card:hover,
    .ss-ready .video-card:hover {
        transform: none !important;
    }

    .ss-ready .bento-card img,
    .ss-ready .album-card-modern img,
    .ss-ready .member-card img,
    .ss-ready .video-card img {
        transition: none !important;
    }

    .ss-ready .bento-card:hover img,
    .ss-ready .album-card-modern:hover img,
    .ss-ready .member-card:hover img,
    .ss-ready .video-card:hover img {
        transform: none !important;
    }

    .ss-ready .bento-card a:not(.card-hitbox)::after,
    .ss-ready .album-card-modern a:not(.card-hitbox)::after,
    .ss-ready .member-card a:not(.card-hitbox)::after,
    .ss-ready .video-card a:not(.card-hitbox)::after {
        transition: none !important;
    }
}


/* =============================================================================
   Mobile — disable hover-dependent effects
   ============================================================================= */

@media (hover: none) {
    .ss-ready .bento-card,
    .ss-ready .album-card-modern,
    .ss-ready .member-card,
    .ss-ready .video-card {
        will-change: auto;
    }
}
/**
 * Heat Distortion Effect
 * SVG filter-based heat haze / mirage shimmer for hero areas.
 * GPU-accelerated via SVG filters; JS handles animation.
 */

/* ── Base target styling ──────────────────────────────────── */

.heat-distortion,
[data-heat] {
    /* Ensure the element forms a stacking context for the filter */
    isolation: isolate;
    /* Smooth transition when filter is applied/removed or intensity changes */
    transition:
        filter var(--dur-slow, 600ms) var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
}

/* Active state: element currently has the SVG filter applied */
.heat-distortion--active {
    /* filter is set inline by JS via url(#heat-distortion-{intensity}) */
    will-change: filter;
}

/* Hover: slight scale bump to complement the displacement boost */
.heat-distortion--hover {
    transition:
        filter var(--dur-base, 300ms) var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
}

/* Static fallback for prefers-reduced-motion */
.heat-distortion--static {
    /* JS applies filter: blur(0.5px) inline; this just resets transitions */
    transition: none;
    will-change: auto;
}


/* ── Rising heat lines overlay ────────────────────────────── */
/* Activated via data-heat-lines="true" */

[data-heat-lines="true"] {
    position: relative;
    overflow: hidden;
}

[data-heat-lines="true"]::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 1;
    background:
        repeating-linear-gradient(
            to right,
            transparent,
            transparent 18px,
            rgba(255, 255, 255, 0.018) 18px,
            rgba(255, 255, 255, 0.018) 19px,
            transparent 19px,
            transparent 42px,
            rgba(255, 255, 255, 0.012) 42px,
            rgba(255, 255, 255, 0.012) 43px
        );
    animation: heat-lines-rise 8s linear infinite;
    opacity: 0.6;
}

@keyframes heat-lines-rise {
    from { transform: translateY(0); }
    to   { transform: translateY(-60px); }
}


/* ── Memorial page amber tint ─────────────────────────────── */
/* The feColorMatrix in SVG handles the tint, but we add a subtle
   warm overlay for elements with heat lines on the memorial page */

[data-page="memorial"] [data-heat-lines="true"]::after {
    background:
        repeating-linear-gradient(
            to right,
            transparent,
            transparent 22px,
            rgba(255, 180, 80, 0.022) 22px,
            rgba(255, 180, 80, 0.022) 23px,
            transparent 23px,
            transparent 50px,
            rgba(255, 160, 60, 0.015) 50px,
            rgba(255, 160, 60, 0.015) 51px
        );
    animation-duration: 12s;
}


/* ── Light theme adjustments ──────────────────────────────── */

[data-theme="light"] [data-heat-lines="true"]::after,
.light-theme [data-heat-lines="true"]::after {
    background:
        repeating-linear-gradient(
            to right,
            transparent,
            transparent 20px,
            rgba(0, 0, 0, 0.012) 20px,
            rgba(0, 0, 0, 0.012) 21px,
            transparent 21px,
            transparent 45px,
            rgba(0, 0, 0, 0.008) 45px,
            rgba(0, 0, 0, 0.008) 46px
        );
    opacity: 0.4;
}


/* ── Intensity visual hints ───────────────────────────────── */
/* These don't control the SVG filter (JS does that), but provide
   complementary CSS styling for each intensity level */

[data-heat-intensity="low"] {
    /* No extra styling — the subtlest level */
}

[data-heat-intensity="high"] {
    /* Slightly warmer undertone for dramatic heat */
    background-blend-mode: overlay;
}

[data-heat-intensity="high"][data-heat-lines="true"]::after {
    opacity: 0.9;
    animation-duration: 5s;
}


/* ── prefers-reduced-motion ───────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
    .heat-distortion,
    [data-heat] {
        transition: none;
        will-change: auto;
    }

    [data-heat-lines="true"]::after {
        animation: none;
        /* Show a faint static version of the lines */
        opacity: 0.3;
    }

    .heat-distortion--active {
        will-change: auto;
    }
}


/* ── Mobile: disable on small screens for performance ─────── */

@media (max-width: 768px) {
    [data-heat-lines="true"]::after {
        /* Simpler, fewer lines on mobile */
        background:
            repeating-linear-gradient(
                to right,
                transparent,
                transparent 30px,
                rgba(255, 255, 255, 0.015) 30px,
                rgba(255, 255, 255, 0.015) 31px
            );
        animation-duration: 10s;
    }
}
/* ================================================================
   Scroll Cinema — Cinematic scroll experience
   Letterbox bars, section fades, film flicker, vignette, reel counter.
   z-index: vignette 799, bars 800, counter 801
   ================================================================ */

/* ── Custom properties ─────────────────────────────────────────── */
:root {
  --cinema-bar-height: 8vh;
  --cinema-vignette-opacity: 0.15;
  --cinema-counter-opacity: 0.3;
  --cinema-grain-opacity: 0.05;
}

/* ── Film grain noise (SVG data-URI, tiny) ─────────────────────── */
/* Used on letterbox bars for authentic film texture */

/* ── Letterbox bars ────────────────────────────────────────────── */
.cinema-bar {
  position: fixed;
  left: 0;
  right: 0;
  height: var(--cinema-bar-height);
  background: #000;
  z-index: 800;
  pointer-events: none;
  will-change: transform;
  transition: none; /* driven by JS for per-frame smoothness */
}

.cinema-bar::after {
  content: '';
  position: absolute;
  inset: 0;
  /* Film grain via repeating-conic-gradient noise trick */
  background:
    repeating-conic-gradient(
      rgba(255,255,255,0.03) 0% 25%,
      transparent 0% 50%
    ) 0 0 / 4px 4px,
    repeating-conic-gradient(
      rgba(255,255,255,0.02) 0% 25%,
      transparent 0% 50%
    ) 2px 2px / 6px 6px;
  opacity: var(--cinema-grain-opacity);
  mix-blend-mode: overlay;
}

.cinema-bar--top {
  top: 0;
  transform: translateY(calc(-1 * var(--cinema-bar-height)));
  transform-origin: top center;
}

.cinema-bar--bottom {
  bottom: 0;
  transform: translateY(var(--cinema-bar-height));
  transform-origin: bottom center;
}

/* Bars visible state — JS sets --cinema-bar-progress (0 to 1) */
.cinema-bar--top.cinema-bar--active {
  transform: translateY(calc(-1 * var(--cinema-bar-height) * (1 - var(--cinema-bar-progress, 0))));
}

.cinema-bar--bottom.cinema-bar--active {
  transform: translateY(calc(var(--cinema-bar-height) * (1 - var(--cinema-bar-progress, 0))));
}

/* ── Vignette overlay ──────────────────────────────────────────── */
.cinema-vignette {
  position: fixed;
  inset: 0;
  z-index: 799;
  pointer-events: none;
  background: radial-gradient(
    ellipse at center,
    transparent 50%,
    rgba(0, 0, 0, var(--cinema-vignette-opacity)) 100%
  );
  will-change: opacity;
  transition: opacity var(--dur-slow, 600ms) ease-out;
}

/* Intensified vignette during transitions */
.cinema-vignette--intense {
  --cinema-vignette-opacity: 0.3;
}

/* ── Section fade ──────────────────────────────────────────────── */
.cinema-section {
  opacity: var(--cinema-opacity, 1);
  will-change: opacity;
  transition: opacity 80ms linear;
}

/* ── Reel counter (timecode) ───────────────────────────────────── */
.cinema-counter {
  position: fixed;
  bottom: var(--space-4, 1rem);
  right: var(--space-4, 1rem);
  z-index: 801;
  pointer-events: none;
  font-family: 'Courier New', monospace;
  font-size: 10px;
  line-height: 1;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, var(--cinema-counter-opacity));
  user-select: none;
  opacity: 0;
  transition: opacity var(--dur-base, 300ms) ease-out;
}

.cinema-counter--visible {
  opacity: 1;
}

/* ── Fade-from-black entry overlay ─────────────────────────────── */
.cinema-entry-overlay {
  position: fixed;
  inset: 0;
  z-index: 10000;
  background: #000;
  pointer-events: none;
  opacity: 1;
  transition: opacity 1.5s ease-out;
}

.cinema-entry-overlay--faded {
  opacity: 0;
}

/* ── Film flicker (applied to body via class) ──────────────────── */
.cinema-flicker {
  /* JS oscillates --cinema-flicker-opacity between 0.97 and 1.0 */
  opacity: var(--cinema-flicker-opacity, 1);
}

/* ── Mobile adjustments ────────────────────────────────────────── */
@media (max-width: 768px) {
  :root {
    --cinema-bar-height: 4vh;
  }
}

/* ── Reduced motion ────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .cinema-bar--top,
  .cinema-bar--bottom {
    /* Keep bars static — always retracted */
    transform: translateY(0) !important;
    display: none;
  }

  .cinema-entry-overlay {
    transition: opacity 0.3s ease-out;
  }

  .cinema-section {
    opacity: 1 !important;
    transition: none;
  }

  /* Vignette is static — fine to keep */
  /* Flicker is disabled in JS — no CSS needed */
  /* Counter is static — fine to keep */
}

/* ── Print: hide everything ────────────────────────────────────── */
@media print {
  .cinema-bar,
  .cinema-vignette,
  .cinema-counter,
  .cinema-entry-overlay {
    display: none !important;
  }
}
