/* ============================================================
   Herinneringen in Beeld — presentatie-speler
   Rustgevend, sereen, professioneel. Bewegende achtergrond +
   zachte Ken Burns op foto's + crossfades.
   ============================================================ */

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }

.player-body {
    background: #05080b;
    overflow: hidden;
    font-family: 'Inter', system-ui, sans-serif;
    color: #fff;
    -webkit-font-smoothing: antialiased;
}

.stage {
    position: fixed;
    inset: 0;
    overflow: hidden;
    background: var(--bg);
    font-family: var(--font);
    cursor: default;
}

/* ── Achtergrondlagen ───────────────────────────────────── */
.bg-layer { position: absolute; inset: -5%; z-index: 0; }
.bg-layer video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* GPU-versnelling voor de bewegende achtergrondlagen (vloeiender). */
.bg-layer::before, .bg-layer::after {
    will-change: transform; backface-visibility: hidden; transform: translateZ(0);
}

/* Foto-achtergrond: scherpe basisfoto met zachte, GPU-vloeiende zoom,
   plus een lichte glinster-laag over het water. Alleen transform/opacity
   (geen SVG-filters of blend-modes → geen per-frame CPU-berekening). */
.bg-photo { position: absolute; inset: 0; }
.photo-base {
    position: absolute; inset: -3%;
    background-size: cover; background-position: center;
    backface-visibility: hidden;
}
/* Zachte, langzame zoom (alleen voor scherpe foto-achtergronden). */
.photo-anim {
    will-change: transform;
    animation: kenburns-bg 44s ease-in-out infinite alternate;
}
@keyframes kenburns-bg {
    from { transform: scale(1.0)  translate3d(0, 0, 0); }
    to   { transform: scale(1.07) translate3d(-1%, -0.8%, 0); }
}
/* Portret zacht in de achtergrond verwerkt: statische blur + scale,
   geen transform-animatie (blur + beweging = haperingen). */
.photo-portrait {
    filter: blur(14px) brightness(0.78) saturate(0.95);
    transform: scale(1.1);
}
/* Zonneglinstering op het water: twee kruisende lichtbanen die zacht
   heen en weer drijven. Alleen transform → vloeiend, en met 'alternate'
   geen zichtbare sprong bij het herhalen. */
.photo-water { position: absolute; inset: -3%; overflow: hidden; }
.photo-water::before, .photo-water::after {
    content: ""; position: absolute; inset: -8%;
    will-change: transform; backface-visibility: hidden;
}
.photo-water::before {
    background: repeating-linear-gradient(72deg,
        rgba(255,255,255,0) 0 60px,
        rgba(255,255,255,0.06) 85px,
        rgba(255,255,255,0) 115px);
    animation: water-glints 7s ease-in-out infinite alternate;
}
.photo-water::after {
    background: repeating-linear-gradient(-64deg,
        rgba(255,255,255,0) 0 90px,
        rgba(210,238,250,0.05) 120px,
        rgba(255,255,255,0) 160px);
    animation: water-glints2 10s ease-in-out infinite alternate;
}
@keyframes water-glints  {
    from { transform: translate3d(-6%, -3%, 0); }
    to   { transform: translate3d(6%, 3%, 0); }
}
@keyframes water-glints2 {
    from { transform: translate3d(5%, 2%, 0); }
    to   { transform: translate3d(-5%, -2%, 0); }
}
.bg-tint {
    position: absolute; inset: 0; z-index: 3;
    background: var(--overlay);
    pointer-events: none;
}

/* ── Procedurele achtergronden (alleen transform/opacity → vloeiend) ── */
/* Effen kleur: de klant kiest de kleur (--bg); subtiele lichtval voor diepte. */
.bg--plain { background:
    radial-gradient(120% 90% at 50% -10%, rgba(255,255,255,0.10) 0%, rgba(255,255,255,0) 45%, rgba(0,0,0,0.22) 100%),
    var(--bg); }

/* Film-template: donkere basis onder de videoloop (en als er geen is gekozen). */
.bg--movie { background:
    radial-gradient(120% 90% at 50% -10%, #16303d 0%, #0e1c26 55%, #081218 100%); }

.bg--water { background:
    radial-gradient(120% 90% at 50% -10%, #143a47 0%, #0b1f29 55%, #07151c 100%); }
.bg--water::before {
    content: ""; position: absolute; inset: -20%;
    background:
        radial-gradient(40% 30% at 30% 35%, rgba(159,214,224,0.30), transparent 70%),
        radial-gradient(45% 35% at 70% 60%, rgba(120,190,205,0.24), transparent 70%),
        radial-gradient(30% 25% at 50% 80%, rgba(200,240,245,0.20), transparent 70%);
    animation: drift 26s ease-in-out infinite alternate;
}

.bg--garden { background:
    radial-gradient(120% 100% at 50% 0%, #2a4421 0%, #16280f 60%, #0c1a08 100%); }
.bg--garden::before {
    content: ""; position: absolute; inset: -12%;
    background:
        radial-gradient(50% 40% at 25% 20%, rgba(220,240,180,0.32), transparent 70%),
        radial-gradient(45% 40% at 80% 70%, rgba(150,200,120,0.24), transparent 70%);
    animation: drift 32s ease-in-out infinite alternate;
}

.bg--trees { background:
    radial-gradient(120% 100% at 50% 0%, #3a2c14 0%, #221808 60%, #140d04 100%); }
.bg--trees::before {
    content: ""; position: absolute; inset: -14%;
    background:
        radial-gradient(35% 30% at 30% 25%, rgba(255,220,150,0.36), transparent 70%),
        radial-gradient(40% 35% at 68% 55%, rgba(230,180,110,0.26), transparent 70%),
        radial-gradient(25% 22% at 50% 85%, rgba(255,235,190,0.20), transparent 70%);
    transform-origin: 50% 0%;
    animation: sway 16s ease-in-out infinite alternate;
}

.bg--blossom { background:
    radial-gradient(120% 100% at 50% 0%, #4a2438 0%, #2a1622 60%, #1a0e15 100%); }
.bg--blossom::before {
    content: ""; position: absolute; inset: -12%;
    background:
        radial-gradient(45% 40% at 30% 30%, rgba(255,200,220,0.30), transparent 70%),
        radial-gradient(40% 35% at 75% 65%, rgba(255,170,200,0.22), transparent 70%);
    animation: drift 30s ease-in-out infinite alternate;
}

@keyframes drift {
    0%   { transform: translate3d(0,0,0) scale(1.02); }
    100% { transform: translate3d(-3%, 2%, 0) scale(1.08); }
}
@keyframes sway {
    0%   { transform: rotate(-1.1deg) translate3d(-1%,0,0); }
    100% { transform: rotate(1.1deg)  translate3d(1%,0,0); }
}

/* Zwevende deeltjes (motes / bloesem), door JS toegevoegd */
.particle {
    position: absolute; top: -8%; z-index: 2;
    border-radius: 50%;
    pointer-events: none;
    will-change: transform, opacity;
}
.particle.mote {
    background: radial-gradient(circle, rgba(255,255,235,0.9), rgba(255,255,210,0) 70%);
    animation: rise linear infinite;
}
.particle.petal {
    background: radial-gradient(circle at 35% 30%, #ffd7e6, #f6a8c6 60%, #e98bb0 100%);
    border-radius: 60% 0 60% 60%;
    animation: fall linear infinite;
}
@keyframes rise {
    0%   { transform: translateY(110vh) translateX(0) scale(0.8); opacity: 0; }
    10%  { opacity: 0.9; }
    90%  { opacity: 0.7; }
    100% { transform: translateY(-12vh) translateX(40px) scale(1); opacity: 0; }
}
@keyframes fall {
    0%   { transform: translateY(-12vh) translateX(0) rotate(0deg); opacity: 0; }
    12%  { opacity: 0.95; }
    100% { transform: translateY(112vh) translateX(120px) rotate(420deg); opacity: 0; }
}

/* ── Dia's ──────────────────────────────────────────────── */
.slides { position: absolute; inset: 0; z-index: 5; }
.slide {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    opacity: 0; clip-path: inset(0 0 0 0);
    transition: opacity var(--trans-dur, 1.1s) ease-in-out;
    pointer-events: none;
    /* Niet-actieve dia's volledig overslaan bij het tekenen; GPU-lagen
       (will-change) alleen voor de dia's die daadwerkelijk bewegen —
       anders krijgt élke dia een schermvullende laag en hapert het. */
    visibility: hidden;
}
.slide.is-active, .slide.is-leaving {
    visibility: visible;
    will-change: opacity, clip-path;
}
.slide.is-active { opacity: 1; z-index: 5; }

/* ── Overgangen per dia (data-trans, per foto instelbaar) ──
   Openbaren/splitsen: het nieuwe beeld komt via een bewegend masker binnen. */
.slide[data-trans="reveal-ltr"]  { clip-path: inset(0 100% 0 0); }
.slide[data-trans="reveal-rtl"]  { clip-path: inset(0 0 0 100%); }
.slide[data-trans="split-h-out"] { clip-path: inset(0 50% 0 50%); }
.slide[data-trans="split-v-out"] { clip-path: inset(50% 0 50% 0); }
.slide[data-trans="reveal-ltr"], .slide[data-trans="reveal-rtl"],
.slide[data-trans="split-h-out"], .slide[data-trans="split-v-out"] {
    opacity: 1; visibility: hidden; transition: none;
}
.slide[data-trans="reveal-ltr"].is-active, .slide[data-trans="reveal-rtl"].is-active,
.slide[data-trans="split-h-out"].is-active, .slide[data-trans="split-v-out"].is-active {
    clip-path: inset(0 0 0 0); visibility: visible;
    transition: clip-path var(--trans-dur, 1.1s) ease-in-out;
}
/* Van buiten naar binnen / verschijnen: de nieuwe dia staat er meteen (geen
   eigen animatie); de oude klapt dicht (leave-split-*) of vervaagt er bovenop
   weg (leave-fade). */
.slide[data-trans="split-h-in"].is-active,
.slide[data-trans="split-v-in"].is-active,
.slide[data-trans="appear"].is-active { transition: none; }

/* De vertrekkende dia vervaagt rustig onder de nieuwe uit (geen harde knip
   aan het eind); bij 'van buiten naar binnen' klapt hij er bovenop dicht.
   player.js ruimt de klassen na afloop op. */
.slide.is-leaving {
    opacity: 0; visibility: visible; clip-path: inset(0 0 0 0);
    transition: opacity var(--trans-dur, 1.1s) ease-in-out;
    z-index: 4;
}
.slide.is-leaving.leave-top { z-index: 6; opacity: 1; transition: none; }
.slide.is-leaving.leave-split-h {
    clip-path: inset(0 50% 0 50%);
    transition: clip-path var(--trans-dur, 1.1s) ease-in-out;
}
.slide.is-leaving.leave-split-v {
    clip-path: inset(50% 0 50% 0);
    transition: clip-path var(--trans-dur, 1.1s) ease-in-out;
}
/* Verschijnen: de oude dia vervaagt bovenop de (al zichtbare) nieuwe weg. */
.slide.is-leaving.leave-fade {
    opacity: 0;
    transition: opacity var(--trans-dur, 1.1s) ease-in-out;
}

/* Titeldia */
.slide-title { flex-direction: column; text-align: center; padding: 6vh 8vw; }
.slide-title::before {
    content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
    background: radial-gradient(ellipse 58% 46% at 50% 48%,
        rgba(4,16,22,0.62) 0%, rgba(4,16,22,0.30) 46%, transparent 72%);
}
.slide-title > * { position: relative; z-index: 1; }
.slide-title .eyebrow {
    letter-spacing: 0.35em; text-transform: uppercase;
    font-family: 'Inter', sans-serif; font-weight: 300;
    font-size: clamp(11px, 1.1vw, 14px); color: var(--accent);
    opacity: 0;
}
.slide-title h1 {
    font-weight: 500; line-height: 1.05; margin: 2.2vh 0 1.4vh;
    font-size: clamp(34px, 5.6vw, 84px); color: var(--text);
    text-shadow: 0 2px 24px rgba(0,0,0,0.55), 0 1px 6px rgba(0,0,0,0.4);
    opacity: 0;
}
.slide-title .dates {
    font-size: clamp(15px, 1.8vw, 24px); color: var(--text);
    font-style: italic;
    opacity: 0;
}
.slide-title .hobbies {
    margin-top: 3vh; font-family: 'Inter', sans-serif; font-weight: 300;
    letter-spacing: 0.12em; font-size: clamp(12px, 1.2vw, 16px);
    color: var(--text); opacity: 0;
}
.slide-title .hobbies span { opacity: 0.7; }
.slide-title .divider {
    width: 0; height: 1px; margin: 2.4vh auto 0;
    background: linear-gradient(90deg, transparent, var(--accent), transparent);
}
/* Teksten animeren pas wanneer de dia actief wordt (dus niet al bij het laden
   van de pagina) én nadat de dia-overgang klaar is (+ --trans-dur). Anders
   staat de tekst van de volgende dia al onder de vorige foto. */
.slide-title.is-active .eyebrow { animation: rise-in calc(2s   * var(--anim-scale, 1)) ease calc(var(--trans-dur, 1.1s) + 0.3s * var(--anim-scale, 1)) forwards; }
.slide-title.is-active h1       { animation: rise-in calc(2.2s * var(--anim-scale, 1)) ease calc(var(--trans-dur, 1.1s) + 0.6s * var(--anim-scale, 1)) forwards; }
.slide-title.is-active .dates   { animation: rise-in calc(2.2s * var(--anim-scale, 1)) ease calc(var(--trans-dur, 1.1s) + 1s   * var(--anim-scale, 1)) forwards; --to: 0.85; }
.slide-title.is-active .hobbies { animation: rise-in calc(2.2s * var(--anim-scale, 1)) ease calc(var(--trans-dur, 1.1s) + 1.4s * var(--anim-scale, 1)) forwards; }
.slide-title.is-active .divider { animation: grow-line calc(2.4s * var(--anim-scale, 1)) ease calc(var(--trans-dur, 1.1s) + 1.2s * var(--anim-scale, 1)) forwards; }
@keyframes rise-in { from { opacity: 0; transform: translateY(18px); } to { opacity: var(--to,1); transform: none; } }
@keyframes grow-line { to { width: min(280px, 40vw); } }

/* Fotodia — ingelijste foto met Ken Burns, bewegende achtergrond eromheen */
.slide-photo { flex-direction: column; padding: 7vh 7vw 9vh; }
.frame {
    position: relative;
    /* Fotogrootte: schaal de hele lijst (werkt ook omhoog, bij kleine foto's). */
    transform: scale(var(--photo-scale, 1));
    transform-origin: center center;
    border-radius: 4px; overflow: hidden;
    box-shadow: 0 30px 80px rgba(0,0,0,0.55), 0 0 0 1px rgba(255,255,255,0.06);
}
.frame::after { /* zachte binnen-vignet */
    content: ""; position: absolute; inset: 0; pointer-events: none;
    box-shadow: inset 0 0 90px rgba(0,0,0,0.35);
}
/* Handmatige focus: blurt de omgeving en belicht een ovaal om de persoon.
   De belichting fade't in: eerst zie je de normale foto, dan langzaam belicht. */
.frame .spot-blur, .frame .spotlight { opacity: 0; }
.slide.is-active .frame .spot-blur,
.slide.is-active .frame .spotlight {
    animation: focus-in var(--focus-dur, 2600ms) ease var(--focus-delay, 750ms) forwards;
}
@keyframes focus-in { from { opacity: 0; } to { opacity: 1; } }
.frame .spot-blur {
    position: absolute; inset: 0; z-index: 2; pointer-events: none;
    -webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px);
    -webkit-mask: radial-gradient(var(--rx, 30%) var(--ry, 36%) at var(--sx, 50%) var(--sy, 50%),
        rgba(0,0,0,0) 0, rgba(0,0,0,0) 66%, rgba(0,0,0,1) 100%);
            mask: radial-gradient(var(--rx, 30%) var(--ry, 36%) at var(--sx, 50%) var(--sy, 50%),
        rgba(0,0,0,0) 0, rgba(0,0,0,0) 66%, rgba(0,0,0,1) 100%);
}
.frame .spotlight {
    position: absolute; inset: 0; z-index: 3; pointer-events: none;
    background: radial-gradient(var(--rx, 30%) var(--ry, 36%) at var(--sx, 50%) var(--sy, 50%),
        rgba(255,255,255,0.10) 0%, rgba(0,0,0,0) 55%, rgba(0,0,0,0.40) 92%, rgba(0,0,0,0.66) 100%);
}
/* Rand om de foto's (instelbaar per presentatie) */
.stage[data-photo-border="white"] .frame {
    border: 10px solid #fff;
    box-shadow: 0 30px 80px rgba(0,0,0,0.55);
}
.stage[data-photo-border="white-thin"] .frame {
    border: 3px solid #fff;
    box-shadow: 0 30px 80px rgba(0,0,0,0.55);
}
.stage[data-photo-border="dark"] .frame {
    border: 3px solid rgba(12,16,20,0.9);
    box-shadow: 0 30px 80px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.08);
}
/* Fotolijstje: witte passe-partout met een dunne houten buitenrand. */
.stage[data-photo-border="frame"] .frame {
    border: 14px solid #f7f4ee;
    border-radius: 2px;
    box-shadow:
        0 0 0 3px #6b5b47,                 /* smalle lijst eromheen */
        inset 0 0 0 1px rgba(0,0,0,0.15),   /* schaduwlijn passe-partout */
        0 30px 80px rgba(0,0,0,0.6);
}
/* Schilderijlijst: gouden, gebeeldhouwd ogende lijst. */
.stage[data-photo-border="ornate"] .frame {
    border: 18px solid #caa34a;
    border-image: linear-gradient(135deg, #6e5416 0%, #e8cd7e 22%, #b8891f 50%, #f3e2a6 74%, #7a5d18 100%) 1;
    box-shadow:
        0 0 0 2px #4d3a12,                  /* donkere buitenrand */
        inset 0 0 0 2px rgba(0,0,0,0.35),    /* diepte binnenin */
        0 30px 80px rgba(0,0,0,0.65);
}
/* Vloeiende rand: de foto loopt aan alle zijden transparant uit in de
   achtergrond (--photo-fade, per foto instelbaar, 0–50%). Kader, schaduw en
   binnen-vignet gaan uit — die hebben een harde rechthoekige rand die dan
   zou opvallen. (Staat ná de kaderstijlen zodat dit wint bij combinatie.) */
.stage .frame.frame-fade {
    border: 0; border-radius: 0; overflow: visible; box-shadow: none;
}
.stage .frame.frame-fade::after { display: none; }
.stage .frame.frame-fade img {
    -webkit-mask-image:
        linear-gradient(to right,  transparent, #000 var(--photo-fade, 10%), #000 calc(100% - var(--photo-fade, 10%)), transparent),
        linear-gradient(to bottom, transparent, #000 var(--photo-fade, 10%), #000 calc(100% - var(--photo-fade, 10%)), transparent);
    -webkit-mask-composite: source-in;
    mask-image:
        linear-gradient(to right,  transparent, #000 var(--photo-fade, 10%), #000 calc(100% - var(--photo-fade, 10%)), transparent),
        linear-gradient(to bottom, transparent, #000 var(--photo-fade, 10%), #000 calc(100% - var(--photo-fade, 10%)), transparent);
    mask-composite: intersect;
}
.frame img {
    display: block;
    /* Elke foto even groot in beeld: vul de vaste hoogte, of bij heel brede
       foto's de volle breedte. De verhouding (--ar) zet player.js per foto,
       zodat opeenvolgende foto's dezelfde hoogte óf breedte delen. */
    height: min(70vh, calc(76vw / var(--ar, 1.5)));
    width: auto;
    backface-visibility: hidden;
}
/* Alleen de zichtbare foto krijgt een eigen GPU-laag voor de Ken Burns-beweging. */
.slide.is-active .frame img, .slide.is-leaving .frame img { will-change: transform; }
.slide.is-active .frame img { animation: var(--kb, kb1) calc(14s * var(--anim-scale, 1)) ease-out forwards; }
/* Alle varianten starten in ruststand (scale 1, geen verschuiving), zodat de
   foto tijdens de overgang niet verspringt op het moment dat de dia actief wordt. */
@keyframes kb1 { from { transform: scale(1.0) translate(0,0); } to { transform: scale(1.09) translate(-2%, -1.5%); } }
@keyframes kb2 { from { transform: scale(1.0) translate(0,0); } to { transform: scale(1.08) translate(2%, 1%); } }
@keyframes kb3 { from { transform: scale(1.0) translate(0,0); } to { transform: scale(1.10) translate(-1.5%, 1.5%); } }
@keyframes kb4 { from { transform: scale(1.0) translate(0,0); } to { transform: scale(1.07) translate(1%, -1%); } }

.caption {
    margin-top: 2.6vh; font-family: 'Inter', sans-serif; font-weight: 300;
    letter-spacing: 0.06em; font-size: clamp(13px, 1.4vw, 18px);
    color: var(--text); opacity: 0;
    text-shadow: 0 1px 16px rgba(0,0,0,0.5);
}
/* Bijschrift pas opkomen als de dia actief is en de overgang klaar is. */
.slide.is-active .caption {
    animation: rise-in calc(1.8s * var(--anim-scale, 1)) ease calc(var(--trans-dur, 1.1s) + 0.8s * var(--anim-scale, 1)) forwards;
}

/* ── Fotostapel: kaarten op elkaar, bovenste vouwt telkens weg ── */
.slide-stack { display: flex; align-items: center; justify-content: center; padding: 6vh 6vw; }
/* Geen perspective op de stapel zelf: dat maakt van élke kaart een eigen
   3D-laag die bij elke videoframe opnieuw samengesteld moet worden. Het
   perspectief zit in de fold-away-animatie (perspective() per kaart). */
.slide-stack .stack { display: grid; place-items: center; }
.stack-card {
    grid-area: 1 / 1;                        /* alle kaarten in dezelfde cel = op elkaar */
    transform: rotate(var(--rot, 0deg));     /* speelse, schuine hoek per kaart */
}
/* Geen permanent will-change: de browser promoot de kaart vanzelf zodra de
   vouw-animatie start; anders houdt élke kaart een grote GPU-laag vast. */
.stack-fold { transform-origin: 50% 0%; }
/* De bovenste (en volgende) kaarten vouwen één voor één weg; de laatste blijft. */
.slide-stack.is-active .stack-card:not(:last-child) .stack-fold {
    animation: fold-away calc(0.9s * var(--anim-scale, 1)) ease forwards;
    animation-delay: calc(var(--step, 5000ms) * (var(--i) + 1));
}
.stage.is-paused .stack-fold { animation-play-state: paused; }
/* Buiten de actieve dia: verberg de niet-laatste kaarten meteen, zodat de
   stapel bij het weggaan niet terugklapt naar de begin-pile (geen flits). */
.slide-stack:not(.is-active) .stack-card:not(:last-child) { opacity: 0; }
/* Geen Ken Burns binnen een stapel — de fold is de beweging. */
.slide-stack.is-active .frame img { animation: none; }
.stack-cap {
    position: absolute; left: 0; right: 0; bottom: 0; z-index: 4;
    padding: 12px 14px; font-family: 'Inter', sans-serif; font-weight: 300;
    font-size: clamp(12px, 1.3vw, 16px); color: #fff; text-align: center;
    background: linear-gradient(transparent, rgba(0,0,0,0.62));
}
@keyframes fold-away {
    from { transform: perspective(1900px) rotateX(0deg) translateY(0); opacity: 1; visibility: visible; }
    /* visibility: weggevouwen kaarten doen daarna niet meer mee met het
       samenstellen van het beeld (scheelt veel op zwakkere GPU's). */
    to   { transform: perspective(1900px) rotateX(-108deg) translateY(-7%); opacity: 0; visibility: hidden; }
}

/* Slotdia */
.slide-closing { flex-direction: column; text-align: center; }
.slide-closing .dove { font-size: clamp(34px, 4vw, 56px); opacity: 0; }
.slide-closing p {
    font-size: clamp(20px, 2.6vw, 38px); font-style: italic; line-height: 1.4;
    color: var(--text); margin: 2.4vh 0 0; opacity: 0;
}
.slide-closing.is-active .dove { animation: rise-in calc(2.4s * var(--anim-scale, 1)) ease var(--trans-dur, 1.1s) forwards; }
.slide-closing.is-active p { animation: rise-in calc(2.4s * var(--anim-scale, 1)) ease calc(var(--trans-dur, 1.1s) + 0.6s * var(--anim-scale, 1)) forwards; }
.slide-closing strong { font-style: normal; font-weight: 500; color: var(--accent); }

/* Vlak vóór de diawissel (is-ending, gezet door player.js) vervagen alle
   teksten alvast — eerder dan de foto. Staat ná de is-active-regels zodat
   dit wint zolang de dia nog actief is. */
@keyframes text-out { from { opacity: 1; } to { opacity: 0; } }
.slide.is-ending .caption,
.slide.is-ending .stack-cap,
.slide.is-ending .eyebrow,
.slide.is-ending h1,
.slide.is-ending .dates,
.slide.is-ending .hobbies,
.slide.is-ending .divider,
.slide.is-ending .dove,
.slide.is-ending p {
    animation: text-out 0.6s ease forwards;
}
/* De sierlijn houdt zijn volle breedte terwijl hij vervaagt (geen terugkrimp). */
.slide.is-ending .divider { width: min(280px, 40vw); }

/* ── Bediening ──────────────────────────────────────────── */
.controls {
    position: absolute; bottom: 28px; left: 50%; transform: translateX(-50%);
    z-index: 20; display: flex; align-items: center; gap: 14px;
    /* visibility: verborgen bediening kost anders nog steeds backdrop-blur. */
    opacity: 0; visibility: hidden;
    transition: opacity 0.4s ease, visibility 0s linear 0.4s;
}
.controls.show, .controls:hover {
    opacity: 1; visibility: visible;
    transition: opacity 0.4s ease;
}
/* Verberg de muiscursor als er niets beweegt. */
.stage.idle { cursor: none; }
.ctrl {
    width: 42px; height: 42px; border-radius: 50%;
    border: 1px solid rgba(255,255,255,0.18);
    background: rgba(10,14,18,0.4); backdrop-filter: blur(8px);
    color: #fff; font-size: 18px; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    transition: background 0.25s, transform 0.25s;
}
.ctrl:hover { background: rgba(255,255,255,0.16); transform: scale(1.06); }
.ctrl-play { font-size: 13px; }

.progress {
    position: absolute; top: -14px; left: 0;
    height: 2px; width: 0; background: var(--accent);
    border-radius: 2px; transition: width 0.2s linear;
}
.controls { width: min(640px, 80vw); justify-content: center; }
.progress { width: 100%; background: rgba(255,255,255,0.12); }
.progress > i {
    /* Via transform (GPU) i.p.v. width: geen layout/paint per frame. */
    display: block; height: 100%; width: 100%; background: var(--accent);
    transform: scaleX(0); transform-origin: 0 50%;
}

/* ── Demo-elementen ─────────────────────────────────────── */
.demo-badge {
    position: absolute; top: 18px; left: 50%; transform: translateX(-50%); z-index: 20;
    background: rgba(255,255,255,0.12); backdrop-filter: blur(6px);
    border: 1px solid rgba(255,255,255,0.2);
    color: #fff; font-family: 'Inter', sans-serif; font-size: 11px;
    letter-spacing: 0.2em; text-transform: uppercase;
    padding: 6px 12px; border-radius: 20px;
}
.template-switcher {
    position: absolute; top: 16px; right: 18px; z-index: 20;
    display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
    font-family: 'Inter', sans-serif; font-size: 12px;
    background: rgba(10,14,18,0.4); backdrop-filter: blur(8px);
    border: 1px solid rgba(255,255,255,0.14);
    padding: 8px 12px; border-radius: 24px; max-width: 60vw;
}
.template-switcher span { opacity: 0.6; margin-right: 4px; }
.template-switcher a {
    color: rgba(255,255,255,0.75); text-decoration: none;
    padding: 4px 10px; border-radius: 16px; transition: background 0.2s, color 0.2s;
}
.template-switcher a:hover { background: rgba(255,255,255,0.1); color: #fff; }
.template-switcher a.is-active { background: var(--accent); color: #102027; font-weight: 500; }

.player-back {
    position: absolute; top: 18px; left: 18px; z-index: 20;
    background: rgba(10,14,18,0.4); backdrop-filter: blur(8px);
    border: 1px solid rgba(255,255,255,0.18); color: #fff;
    text-decoration: none; font-family: 'Inter', sans-serif; font-size: 13px;
    padding: 8px 14px; border-radius: 22px; transition: background 0.2s, opacity 0.4s ease;
}
.player-back:hover { background: rgba(255,255,255,0.16); }
/* Vervaag de terug-link mee als de muis stilstaat. */
.stage.idle .player-back { opacity: 0; pointer-events: none; }

.svg-defs { position: absolute; width: 0; height: 0; }

@media (prefers-reduced-motion: reduce) {
    .bg-layer::before, .bg-layer::after, .particle, .bg-photo { animation: none !important; }
    .slide.is-active .frame img { animation: none !important; transform: scale(1.03); }
    /* Tekst direct tonen i.p.v. infaden. */
    .slide-title .eyebrow, .slide-title h1, .slide-title .dates,
    .slide-title .hobbies, .caption, .slide-closing .dove, .slide-closing p {
        animation: none !important; opacity: 1 !important; transform: none !important;
    }
    .slide-title .divider { animation: none !important; width: min(280px, 40vw); }
}

/* ── Informatie-icoontje met korte uitleg (demo-pagina) ── */
.info-tip {
    position: relative; display: inline-flex; align-items: center; justify-content: center;
    width: 15px; height: 15px; margin-left: 4px; flex: none; vertical-align: 1px;
    border-radius: 50%; background: rgba(255,255,255,0.28); color: #fff;
    font-family: Georgia, serif; font-size: 10.5px; font-style: italic; font-weight: 700;
    line-height: 1; cursor: help; user-select: none; opacity: 1;
}
.info-tip:hover, .info-tip:focus { background: rgba(255,255,255,0.5); outline: none; }
.info-tip::after {
    content: attr(data-tip);
    position: absolute; left: 50%; bottom: calc(100% + 9px); transform: translateX(-50%);
    width: max-content; max-width: 280px;
    background: rgba(16,32,39,0.96); color: #fff;
    font-family: 'Inter', system-ui, sans-serif; font-style: normal; font-weight: 400;
    font-size: 12.5px; line-height: 1.5; text-align: left;
    padding: 8px 12px; border-radius: 8px;
    box-shadow: 0 10px 26px rgba(0,0,0,0.4);
    opacity: 0; visibility: hidden; transition: opacity 0.15s; pointer-events: none; z-index: 120;
}
.info-tip:hover::after, .info-tip:focus::after { opacity: 1; visibility: visible; }
