/* ════════════════════════════════════════════════════════════
   WILL YOU BE MY DISCIPLE? — games page stylesheet (redesign)

   Art-first, "Cult of the Lamb"-style scene system. Builds on the
   core.css :root tokens (colours, fonts, spacing) — no new palette.
   Later phases (hero, core loop, characters, endings, devlog, CTA)
   compose the building blocks defined here. Plain CSS only; behaviour
   reuses js/site.js (reveal, tilt, yt facade, lightbox, tabs).
   ════════════════════════════════════════════════════════════ */

/* ═══ LOCAL TOKENS ═══
   Scene-system specific knobs layered on top of core.css. */
:root {
    --scene-pad-y: clamp(3rem, 6vh, 5rem);
    --scene-max: var(--container);
    --parchment: #e9dcc0;
    --parchment-2: #d9c79f;
    --parchment-ink: #2a2118;
    --parchment-ink-dim: #5c4a32;
    --seal-red: var(--crimson);
    --frame-line: rgba(217, 164, 65, 0.35); /* gilded gold hairline */
    --frame-line-strong: rgba(217, 164, 65, 0.6);
}

/* ════════════════════════════════════════════════════════════
   SCENE SYSTEM
   A scene is a full-bleed band whose backdrop is the game's own art.
   Layer order (back → front):
     .scene-bg  →  .scene-scrim  →  .scene-vignette  →  .scene-inner
   ════════════════════════════════════════════════════════════ */
.scene {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    padding: var(--scene-pad-y) 0;
    display: flex;
    align-items: center;
}
/* Hero is a full-bleed cinematic scene: the key art reads as the band, the
   title is composited over it. Tall enough to feel like a scene, with top
   padding clearing the overhanging header wordmark. */
.scene--intro {
    min-height: clamp(620px, 92vh, 900px);
    padding-top: calc(var(--nav-h) + 5.5rem);
    padding-bottom: clamp(2.5rem, 6vh, 4.5rem);
}

/* Art backdrop — set background-image inline or via a modifier class.
   Sized to cover; a slow drift can be added per-scene later. */
.scene-bg {
    position: absolute;
    inset: -22%; /* extra bleed so the stronger parallax translate never exposes an edge */
    z-index: -3;
    background-color: #0d0a08; /* banners fade to black at the edges, match it */
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    will-change: transform;
}

/* The media band is much taller than the other scenes, so `cover` zooms the
   16:9 art far more there and it reads as over-enlarged. Scale by WIDTH so the
   art shows at the same scale as the shorter scenes, then TILE downward to fill
   the extra height instead of blowing the single frame up. */
.media-v2 .scene-bg {
    background-size: 100% auto;
    background-position: center top;
    background-repeat: repeat-y;
}

/* Devlog strip — the shared .devlog-card parchment cards (css/devlog.css) sit
   inside a scene; just center the "read every dispatch" CTA below them. */
.devlog-v2-more {
    margin-top: clamp(2rem, 5vh, 3.25rem);
    text-align: center;
}
/* Match the devlog card "Read more" hover here (grow + brighten) instead of the
   shared .btn--event lift, scoped so devlog.html's "Load more" keeps its own. */
.devlog-v2-more .btn--event:hover {
    transform: scale(1.035);
    filter: drop-shadow(0 9px 15px rgba(20, 10, 4, 0.6)) brightness(1.06);
}

/* Readability scrim — dark top/bottom so overlaid text always holds.
   Mirrors the home hero's twin-gradient approach. */
.scene-scrim {
    position: absolute;
    inset: 0;
    z-index: -2;
    pointer-events: none;
    background:
        linear-gradient(180deg,
            rgba(8, 9, 13, 0.78) 0%,
            rgba(8, 9, 13, 0.30) 26%,
            rgba(8, 9, 13, 0.46) 60%,
            rgba(8, 9, 13, 0.92) 92%,
            var(--bg) 100%);
}
/* Left-weighted variant for text-on-left compositions. The 180deg layer also
   darkens the TOP strongly so a light-sky scene art (l5-outside) still holds the
   header nav and the cream title. */
.scene-scrim--left {
    background:
        linear-gradient(90deg,
            rgba(8, 9, 13, 0.92) 0%,
            rgba(8, 9, 13, 0.55) 38%,
            rgba(8, 9, 13, 0.10) 70%,
            transparent 100%),
        linear-gradient(180deg,
            rgba(8, 9, 13, 0.88) 0%,
            rgba(8, 9, 13, 0.42) 20%,
            transparent 44%,
            rgba(8, 9, 13, 0.88) 100%);
}
.scene-vignette {
    position: absolute;
    inset: 0;
    z-index: -2;
    pointer-events: none;
    box-shadow: inset 0 0 240px 70px rgba(0, 0, 0, 0.72);
}

.scene-inner {
    width: 100%;
    max-width: var(--scene-max);
    margin: 0 auto;
    padding: 0 var(--s-3);
    position: relative;
    z-index: 1;
}

/* ── Section bracket ──
   A crisp gilt ornament (native size, never upscaled) with a thin gold rule
   fading in from each side. It is NOT a solid band: negative margins pull it up
   into the scene above and down into the scene below, and its background is a
   semi-transparent dark gradient (clear at the edges, deep at the centre) so the
   two scenes fade into a dark seam with the ornament floating in it — a
   transition, not a separate strip. Sits above both scenes; clicks pass through.
   Used to bracket the showcase sections (disciples, endings): Top caps above,
   Bot (--bot) caps below, so the pair embraces the section. */
.scene-divider {
    position: relative;
    z-index: 5;
    margin: -54px 0;
    padding: 54px var(--s-3);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: clamp(0.9rem, 3vw, 2.2rem);
    pointer-events: none;
    background: linear-gradient(180deg,
        transparent 0%,
        rgba(9, 7, 8, 0.55) 30%,
        rgba(9, 7, 8, 0.94) 50%,
        rgba(9, 7, 8, 0.55) 70%,
        transparent 100%);
}
.scene-divider::before,
.scene-divider::after {
    content: '';
    height: 2px;
    width: min(26vw, 320px);
    background: linear-gradient(to right, transparent, color-mix(in srgb, var(--gold) 55%, transparent));
}
.scene-divider::after { background: linear-gradient(to left, transparent, color-mix(in srgb, var(--gold) 55%, transparent)); }
.scene-divider-orn {
    flex-shrink: 0;
    width: clamp(160px, 36vw, 260px); /* native ~246px; only ever downscaled */
    aspect-ratio: 246 / 35;
    background: url('../Assets/wybmd-assets/Seperate_Top.png') center / contain no-repeat;
    filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.6));
}
.scene-divider--bot .scene-divider-orn {
    aspect-ratio: 247 / 36;
    background-image: url('../Assets/wybmd-assets/Seperate_Bot.png');
}

/* ════════════════════════════════════════════════════════════
   TYPOGRAPHY — editorial scale for the scenes
   ════════════════════════════════════════════════════════════ */
.kicker {
    font-family: var(--font-body);
    font-weight: 400;
    font-size: 0.78rem;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    color: var(--teal-bright);
    margin-bottom: var(--s-3);
    text-shadow: 0 2px 14px rgba(0, 0, 0, 0.8);
}
.display-xl {
    font-family: var(--font-hero);
    font-weight: 700;
    line-height: 1.0;
    font-size: clamp(2.8rem, 7.6vw, 6rem);
    color: var(--text);
    max-width: 18ch;
    letter-spacing: 0.01em;
    text-shadow: 0 4px 34px rgba(0, 0, 0, 0.7);
}
.display-lead {
    margin-top: var(--s-3);
    max-width: 56ch;
    font-size: clamp(1.05rem, 1.6vw, 1.28rem);
    line-height: 1.75;
    color: var(--text-dim);
    text-shadow: 0 2px 18px rgba(0, 0, 0, 0.85);
}

/* ════════════════════════════════════════════════════════════
   DIEGETIC UI — parchment frame + wax-seal buttons
   The in-game "event card" language, reused across scenes.
   ════════════════════════════════════════════════════════════ */
.parchment {
    position: relative;
    margin-top: var(--s-4);
    max-width: 46rem;
    padding: clamp(1.4rem, 3vw, 2.4rem);
    color: var(--parchment-ink);
    background:
        radial-gradient(120% 140% at 50% 0%, var(--parchment) 0%, var(--parchment-2) 100%);
    border: 1px solid rgba(42, 33, 24, 0.25);
    border-radius: 4px;
    box-shadow:
        0 30px 60px -28px rgba(0, 0, 0, 0.9),
        inset 0 0 60px rgba(120, 92, 48, 0.25);
}
/* Torn/aged inner edge */
.parchment::after {
    content: '';
    position: absolute;
    inset: 6px;
    border: 1px solid rgba(92, 74, 50, 0.35);
    border-radius: 3px;
    pointer-events: none;
}
.parchment-body {
    font-family: var(--font-body);
    font-size: 1.02rem;
    line-height: 1.7;
    color: var(--parchment-ink);
}
.parchment-body + .seal-row { margin-top: var(--s-3); }

.seal-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
}
.seal-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    font-family: var(--font-display);
    font-weight: 400;
    font-size: 0.95rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 0.85rem 1.6rem;
    border-radius: 3px;
    cursor: pointer;
    transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease), background-color 0.25s var(--ease);
}
.seal-btn--accept {
    color: #fff;
    background: linear-gradient(160deg, var(--seal-red), #9c2f1c);
    box-shadow: 0 10px 26px -12px rgba(214, 73, 47, 0.8);
}
.seal-btn--accept:hover {
    transform: translateY(-2px);
    box-shadow: 0 16px 34px -12px rgba(214, 73, 47, 0.9);
}
.seal-btn--decline {
    color: var(--parchment-ink);
    background: transparent;
    border: 1px solid rgba(42, 33, 24, 0.4);
}
.seal-btn--decline:hover {
    background: rgba(42, 33, 24, 0.08);
    transform: translateY(-2px);
}

/* Gilded art frame — for screenshots / event art inside dark scenes */
.art-frame {
    position: relative;
    margin-top: var(--s-4);
    border: 1px solid var(--frame-line);
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--panel);
    box-shadow: 0 30px 60px -34px rgba(0, 0, 0, 0.9);
}
.art-frame > img { width: 100%; height: auto; display: block; }

/* ════════════════════════════════════════════════════════════
   GUIDE TRANSITION — Bartholomew / Chicken Prime commentary
   A connective beat *between* scenes (normal flow, not overlapping
   content). Portrait beside a speech bubble; decorative (aria-hidden).
   Reusable across scene boundaries.
   ════════════════════════════════════════════════════════════ */
.guide-transition {
    position: relative;
    z-index: 3;
    max-width: 920px;
    margin: 0 auto;
    padding: clamp(1.5rem, 4vh, 3rem) var(--s-3);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: clamp(1rem, 3vw, 2.4rem);
    pointer-events: none;
}
.guide-transition-portrait {
    width: clamp(120px, 16vw, 190px);
    height: auto;
    aspect-ratio: 294 / 480;
    object-fit: contain;
    flex-shrink: 0;
    filter: drop-shadow(0 0 30px rgba(68, 187, 164, 0.35));
}
.guide-transition-bubble {
    max-width: 460px;
    font-family: var(--font-body);
    font-size: clamp(0.95rem, 1.4vw, 1.08rem);
    line-height: 1.6;
    color: var(--text);
    background: rgba(21, 23, 31, 0.92);
    border: 1px solid var(--line-strong);
    border-radius: 16px 16px 16px 4px;
    padding: 1rem 1.25rem;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    box-shadow: 0 18px 44px -22px rgba(0, 0, 0, 0.9);
}
@media (max-width: 560px) {
    .guide-transition { flex-direction: column; text-align: center; }
    .guide-transition-bubble { border-radius: 4px 16px 16px 16px; }
}

/* ════════════════════════════════════════════════════════════
   PLACEHOLDER CONVENTION  (.art-ph)
   Marks art that has not been delivered yet. Renders a labelled,
   dashed box so composition + contrast can be judged before the real
   image exists. The label comes from the [data-art] attribute.
   To wire a real image: drop the .art-ph class and set the background
   (for .scene-bg) or swap in an <img> (for inline/portrait).
   ════════════════════════════════════════════════════════════ */
.art-ph {
    background-color: #14161e;
    background-image:
        repeating-linear-gradient(45deg,
            rgba(116, 227, 203, 0.06) 0 12px,
            transparent 12px 24px);
    border: 1px dashed rgba(116, 227, 203, 0.35);
    display: flex;
    align-items: center;
    justify-content: center;
}
.art-ph::after {
    content: 'ART — ' attr(data-art);
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 0.72rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: rgba(116, 227, 203, 0.65);
    text-align: center;
    padding: 0.6rem 1rem;
    pointer-events: none;
}
/* The scene-bg placeholder must keep filling its layer */
.scene-bg.art-ph { inset: 0; }
.art-ph--inline {
    display: block;
    width: 100%;
    aspect-ratio: 3 / 2;
    position: relative;
}
.art-ph--inline::after {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}
.art-ph--portrait {
    border-radius: 8px;
    position: relative;
}
.art-ph--portrait::after {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* ════════════════════════════════════════════════════════════
   SCENE HEAD + secondary display sizes (shared by Phase 2+ scenes)
   ════════════════════════════════════════════════════════════ */
.scene-head {
    max-width: 680px;
    margin-bottom: var(--s-5);
}
.scene-head--center {
    text-align: center;
    margin-left: auto;
    margin-right: auto;
}
.display-lg {
    font-family: var(--font-display);
    font-weight: 700;
    line-height: 1.08;
    font-size: clamp(2rem, 4.6vw, 3.3rem);
    color: var(--text);
    letter-spacing: 0.01em;
    text-shadow: 0 4px 30px rgba(0, 0, 0, 0.7);
}
.scene-head .kicker + .display-lg { margin-top: 0; }

/* ════════════════════════════════════════════════════════════
   PHASE 2 — HERO
   Full-bleed art scene; a left-aligned text block sits over the art.
   ════════════════════════════════════════════════════════════ */
.hero-v2-inner {
    max-width: 680px;
}
.hero-v2-tagline {
    margin-top: var(--s-3);
    font-family: var(--font-display);
    font-weight: 400; /* Aladin ships a single weight; 600 forced faux-bold (thick/blurry) */
    font-size: clamp(1.1rem, 2vw, 1.5rem);
    line-height: 1.3;
    color: var(--teal-bright);
    text-shadow: 0 2px 18px rgba(0, 0, 0, 0.85);
}
/* Concise genre descriptor under the tagline (DD-style), so the standalone
   About band is no longer needed. */
.hero-v2-genre {
    margin-top: var(--s-2);
    font-family: var(--font-body);
    font-size: clamp(0.95rem, 1.4vw, 1.12rem);
    letter-spacing: 0.02em;
    color: var(--muted);
    text-shadow: 0 2px 14px rgba(0, 0, 0, 0.85);
}
.hero-v2-actions {
    margin-top: var(--s-4);
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
}
.hero-v2-platform {
    margin-top: var(--s-3);
    font-family: var(--font-body);
    font-size: 0.92rem;
    letter-spacing: 0.02em;
    color: var(--muted);
    text-shadow: 0 2px 12px rgba(0, 0, 0, 0.85);
}

/* ── Scroll cue ──
   Quiet "enter the temple" invitation that replaces the hero's store CTA.
   Sits at the bottom of the intro scene; the dot bobs to hint the scroll. */
.scroll-cue {
    position: absolute;
    left: 50%;
    bottom: clamp(1.4rem, 4vh, 2.6rem);
    transform: translateX(-50%);
    z-index: 2;
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    color: var(--teal-bright);
    text-decoration: none;
}
.scroll-cue-text {
    font-family: var(--font-body);
    font-weight: 400;
    font-size: 0.72rem;
    letter-spacing: 0.24em;
    text-transform: uppercase;
    text-shadow: 0 2px 12px rgba(0, 0, 0, 0.85);
}
.scroll-cue-dot {
    width: 26px;
    height: 42px;
    border: 2px solid rgba(116, 227, 203, 0.55);
    border-radius: 999px;
    position: relative;
}
.scroll-cue-dot::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 8px;
    width: 4px;
    height: 8px;
    margin-left: -2px;
    border-radius: 999px;
    background: var(--teal-bright);
    animation: scrollCueBob 1.6s var(--ease) infinite;
}
@keyframes scrollCueBob {
    0%, 100% { transform: translateY(0); opacity: 0.4; }
    50% { transform: translateY(12px); opacity: 1; }
}
.scroll-cue:hover .scroll-cue-dot { border-color: var(--frame-line-strong); }
.scroll-cue:focus-visible { outline: 2px solid var(--teal); outline-offset: 4px; border-radius: 6px; }

/* The diegetic parchment seal button (.wishlist-seal, incl. -texts/-label/-name
   and hover flourishes) is defined in core.css so it is available site-wide
   (games wishlist strip + 404 return button). */

/* ════════════════════════════════════════════════════════════
   MEDIA BAND — trailer (gilded YouTube facade) leading the gallery
   ════════════════════════════════════════════════════════════ */
.media-v2-trailer { margin-bottom: clamp(3.5rem, 8vh, 6.5rem); }
.trailer-v2-frame {
    position: relative;
    max-width: 960px;
    margin: 0 auto;
    aspect-ratio: 16 / 9;
    cursor: pointer;
}
.trailer-v2-frame .trailer-v2-poster {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.trailer-v2-frame iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}
.trailer-v2-play {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 84px;
    height: 84px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    color: #fff;
    background: rgba(214, 73, 47, 0.92);
    box-shadow: 0 16px 40px -12px rgba(0, 0, 0, 0.8);
    transition: transform 0.3s var(--ease), background-color 0.3s var(--ease);
}
.trailer-v2-play svg { width: 34px; height: 34px; margin-left: 4px; }
.trailer-v2-frame:hover .trailer-v2-play,
.trailer-v2-frame:focus-visible .trailer-v2-play {
    transform: translate(-50%, -50%) scale(1.08);
    background: var(--crimson);
}

/* ════════════════════════════════════════════════════════════
   PHASE 3 — THE BLESSINGS (in-game HUD: filling gauges)
   ════════════════════════════════════════════════════════════ */
/* No panel box: the three sigils stand directly on the scene art. */
.blessings-hud {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(1.5rem, 4vw, 3.5rem);
    padding: 0;
}
.blessing {
    text-align: center;
    padding: var(--s-2);
}
.blessing-sigil {
    position: relative;
    display: inline-flex;
    width: clamp(104px, 12vw, 148px);
    height: clamp(104px, 12vw, 148px);
    align-items: center;
    justify-content: center;
    margin-bottom: var(--s-3);
    /* Static glow, tinted to the icon (--force). Stays constant, not animated. */
    filter:
        drop-shadow(0 6px 16px rgba(0, 0, 0, 0.7))
        drop-shadow(0 0 26px color-mix(in srgb, var(--force) 55%, transparent));
}
.blessing-sigil img { position: relative; z-index: 1; width: 100%; height: 100%; object-fit: contain; }
/* Hover aura — the game's per-resource background effect, behind the sigil.
   The per-resource image is set below via :nth-child (relative url() in a
   custom property resolves against this stylesheet's folder, which broke the
   path — so the images live here directly). */
.blessing-sigil::before {
    content: '';
    position: absolute;
    inset: -24%;
    z-index: 0;
    background-position: center;
    background-size: contain;
    background-repeat: no-repeat;
    opacity: 0;
    transform: scale(0.6);
    transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
    pointer-events: none;
}
/* Hover particles — the game's per-resource particle sheet, over the sigil,
   slowly rotating left (counter-clockwise) while hovered. */
.blessing-sigil::after {
    content: '';
    position: absolute;
    inset: -32%;
    z-index: 2;
    background-position: center;
    background-size: contain;
    background-repeat: no-repeat;
    opacity: 0;
    transition: opacity 0.4s var(--ease);
    pointer-events: none;
}
/* Per-resource effect art (order: secrecy, morality, faith). */
.blessings-hud .blessing:nth-child(1) .blessing-sigil::before { background-image: url('../Assets/wybmd-assets/Secrecy_Background_Effect_High.png'); }
.blessings-hud .blessing:nth-child(1) .blessing-sigil::after  { background-image: url('../Assets/wybmd-assets/Secrecy_Particle.png'); }
.blessings-hud .blessing:nth-child(2) .blessing-sigil::before { background-image: url('../Assets/wybmd-assets/Morality_Background_Effect_High.png'); }
.blessings-hud .blessing:nth-child(2) .blessing-sigil::after  { background-image: url('../Assets/wybmd-assets/Morality_Particle.png'); }
.blessings-hud .blessing:nth-child(3) .blessing-sigil::before { background-image: url('../Assets/wybmd-assets/Faith_Background_Effect_High.png'); }
.blessings-hud .blessing:nth-child(3) .blessing-sigil::after  { background-image: url('../Assets/wybmd-assets/Faith_Particle.png'); }
.blessing:hover .blessing-sigil::before,
.blessing:focus-within .blessing-sigil::before { opacity: 1; transform: scale(1); }
.blessing:hover .blessing-sigil::after,
.blessing:focus-within .blessing-sigil::after {
    opacity: 1;
    animation: blessing-particle-spin 14s linear infinite;
}
@keyframes blessing-particle-spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(-360deg); }
}
.blessing-name {
    font-family: var(--font-caps);
    font-weight: 700;
    font-size: 1.35rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text);
    margin-bottom: var(--s-2);
    text-shadow: 0 2px 18px rgba(0, 0, 0, 0.9);
}
.blessing-desc {
    margin-top: var(--s-3);
    font-size: 0.95rem;
    line-height: 1.6;
    color: var(--text-dim);
    max-width: 28ch;
    margin-left: auto;
    margin-right: auto;
    text-shadow: 0 2px 14px rgba(0, 0, 0, 0.9);
}

/* ════════════════════════════════════════════════════════════
   THE DISCIPLES — in-game encounter (one disciple at a time)
   Layered stage recreating the game's encounter view:
     bg (hall) → character → table (foreground) → bubble / name / sigil nav.
   Coordinates are % of the 16:9 stage and text/controls use cqw units, so
   the whole composition scales together at any width.
   ════════════════════════════════════════════════════════════ */
/* The section is the stage: full-bleed, no band padding. */
.disciples-v2 {
    padding: 0;
    display: block;
    overflow: hidden;
}
.encounter { margin: 0; display: block; width: 100%; }
.encounter-stage {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    container-type: inline-size;   /* UI (heading/bubble/nav) sizes in cqw of the stage */
    isolation: isolate;
    user-select: none;
}
/* The rigid scene. Always 16/9; on desktop it fills the stage exactly, on tall
   phone stages it is sized to cover (height-driven) and cropped L/R so every
   plane inside keeps its relative scale/position. Its own container context
   makes the scene's cqw units track the diorama, not the stage. */
.encounter-diorama {
    position: absolute;
    inset: 0;
    z-index: 0;
    isolation: isolate;            /* self-contained stacking context for the planes */
    container-type: inline-size;
    background: #120d09;
}
/* Plane 0 — forest seen through the windows (parallax-drifted). */
.encounter-bg {
    position: absolute;
    inset: -6%;                    /* bleed so the parallax translate never exposes an edge */
    z-index: 0;
    background: #120d09 url('../Assets/images/locations/l9-forest-background.webp') center / cover no-repeat;
    will-change: transform;
}
/* Plane 1 — iron windows + stone wall (transparent glass + floor). */
.encounter-wall {
    position: absolute;
    inset: 0;
    z-index: 1;
    background: url('../Assets/images/locations/l9-forest-wall-back.webp') center / cover no-repeat;
}
/* Planes 2-3 — the throne chairs framing the table (back pair smaller/higher,
   front pair larger/lower for depth). Positioned in % of the diorama. */
.enc-chair {
    position: absolute;
    width: auto;
    pointer-events: none;
    filter: drop-shadow(0 10px 16px rgba(0, 0, 0, 0.5));
}
/* Each chair sits in its own dark alcove baked into the wall art
   (`l9-forest-wall-back`): the front pair fills the OUTER alcoves at the very
   edges, the back pair the INNER alcoves (smaller + raised for depth) so the back
   chair reads beside the front one, not hidden behind it. Values matched to the
   wall's shadow slots + referans.png. */
.enc-chair-lb, .enc-chair-rb { z-index: 2; height: 46%; bottom: 7%; }
.enc-chair-lf, .enc-chair-rf { z-index: 3; height: 55%; bottom: 0; }
.enc-chair-lb { left: 12%; }
.enc-chair-rb { right: 12%; }
.enc-chair-lf { left: 0; }
.enc-chair-rf { right: 0; }
.encounter-chars { will-change: transform; }
/* Veil — darkens the top-left behind the heading (and a touch of the top) so
   the overlaid text stays legible, without dimming the centred character. */
.encounter-veil {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background:
        linear-gradient(102deg, rgba(6, 5, 4, 0.94) 0%, rgba(6, 5, 4, 0.68) 22%, rgba(6, 5, 4, 0.2) 40%, transparent 50%),
        linear-gradient(180deg, rgba(6, 5, 4, 0.55) 0%, transparent 24%);
}
/* Heading overlaid top-left, like in-game UI over the scene. */
.encounter-head {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 4;
    max-width: 40%;
    margin: 0;
    padding: clamp(1.4rem, 4cqw, 4.5rem) clamp(1.4rem, 4cqw, 4.5rem) 0;
    pointer-events: none;
}
.encounter-head .display-lead { max-width: none; }
/* Characters — fixed centre for all, standing behind the table. */
.encounter-chars { position: absolute; inset: 0; z-index: 4; }
.enc-char {
    position: absolute;
    left: 50%;
    bottom: 5%;
    height: 72%;
    width: auto;
    transform: translateX(-50%) scale(0.99);
    transform-origin: bottom center;
    opacity: 0;
    pointer-events: none;
    filter: drop-shadow(0 16px 22px rgba(0, 0, 0, 0.6));
    transition: opacity 0.45s var(--ease), transform 0.45s var(--ease);
}
.enc-char.is-active { opacity: 1; transform: translateX(-50%) scale(1); }
/* Per-character scale. The cut-outs are each tight-cropped onto a uniform
   480px canvas, and some are full-body (goblin, demon, circus) while others
   are half-body (Arnold, Bonwa, courier), so one shared height made them all
   read at the wrong scale (half-body faces looked huge). These per-character
   heights restore believable relative stature. Values are % of the diorama;
   tune to taste. bottom:5% still anchors them behind the table. */
/* Full-body cut-outs: feet at bottom:5% (base), legs hidden behind the table. */
.enc-char[src*="CircusManager"] { height: 70%; }  /* full body, stout adult - reference */
.enc-char[src*="GoblinAhmet"]   { height: 60%; }  /* full body, short goblin */
.enc-char[src*="DemonBoy"]      { height: 50%; }  /* full body, small child - shortest */
/* Half-body cut-outs (cropped at waist/hip, no legs): raised so the crop line
   tucks just behind the table's back rim instead of sinking below it. Tuned
   against the centred table rim (Table.webp fills the diorama's bottom ~34%). */
.enc-char[src*="Bonwa"]         { height: 64%; bottom: 20%; }  /* 3/4 body + tall hat */
.enc-char[src*="Corrier"]       { height: 54%; bottom: 27%; }  /* half body (head to hip) */
.enc-char[src*="ArnoldVon"]     { height: 50%; bottom: 24%; }  /* half body (head to waist) */
/* Table foreground — occludes the character's legs so they read as standing.
   It is the ONLY table in the scene now (the backdrop no longer bakes one in),
   and it lives in the rigid diorama, so it can never decouple from the backdrop.
   width:100% of the diorama; max-width:none keeps it free of the global
   img{max-width:100%} reset regardless. */
.encounter-table {
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    max-width: none;
    z-index: 5;
    pointer-events: none;
}
/* Speech bubble — the game's own bubble.png + bubblearrow.png. */
.encounter-bubble {
    position: absolute;
    top: 14%;
    right: 13%;
    z-index: 4;
    width: max-content;
    max-width: 27%;
    font-family: var(--font-body);
    font-size: clamp(0.82rem, 1.9cqw, 1.22rem);
    line-height: 1.4;
    color: #3c3120;
    text-align: center;
    background: url('../Assets/wybmd-assets/bubble.png') center / 100% 100% no-repeat;
    padding: 2.6cqw 3cqw;
    filter: drop-shadow(0 10px 20px rgba(0, 0, 0, 0.5));
}
.encounter-bubble::after {
    content: '';
    position: absolute;
    left: 14%;
    bottom: -1.7cqw;
    width: 2.6cqw;
    height: 2.8cqw;
    background: url('../Assets/wybmd-assets/bubblearrow.png') center / contain no-repeat;
}
.enc-quote { margin: 0; }
/* Name plate — sits on the table. */
/* Name plate = the game's paper scroll (5-frame unroll). The frames cross-swap
   under JS; the name shows only when the scroll is fully open. */
.enc-nameplate {
    position: absolute;
    bottom: 6%;
    left: 50%;
    transform: translateX(-50%);
    z-index: 4;
    width: clamp(170px, 24cqw, 330px);
    aspect-ratio: 439 / 210;
    display: grid;
    place-items: center;
}
.enc-scroll { position: absolute; inset: 0; }
.enc-frame {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    opacity: 0;
    filter: drop-shadow(0 6px 12px rgba(0, 0, 0, 0.5));
}
.enc-frame.is-shown { opacity: 1; }
.enc-name {
    position: relative;
    z-index: 1;
    max-width: 72%;
    text-align: center;
    font-family: var(--font-caps);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    line-height: 1.08;
    font-size: clamp(0.6rem, 1.5cqw, 0.95rem);
    color: #3a2f1e;
    opacity: 0;
    transition: opacity 0.15s var(--ease);
}
.enc-nameplate.is-open .enc-name { opacity: 1; }
/* Sigil nav buttons */
.enc-nav {
    position: absolute;
    top: 57%;
    transform: translateY(-50%);
    z-index: 5;
    width: clamp(64px, 10.5cqw, 120px);
    aspect-ratio: 1;
    background: none;
    border: 0;
    cursor: pointer;
    transition: transform 0.2s var(--ease);
}
/* Hover glow behind the sigil (game's Sigil_Background_Effect). */
.enc-nav::before {
    content: '';
    position: absolute;
    inset: -14%;
    background: url('../Assets/wybmd-assets/Sigil_Background_Effect.png') center / contain no-repeat;
    opacity: 0;
    transform: scale(0.55);
    transition: opacity 0.25s var(--ease), transform 0.25s var(--ease);
    pointer-events: none;
}
/* The sigil disc itself (drawn above the glow). */
.enc-nav::after {
    content: '';
    position: absolute;
    inset: 0;
    background: center / contain no-repeat;
    filter: drop-shadow(0 6px 12px rgba(0, 0, 0, 0.7));
}
.enc-prev { left: 8%; }
.enc-next { right: 8%; }
.enc-prev::after { background-image: url('../Assets/wybmd-assets/Sigil_Left_Button.png'); }
.enc-next::after { background-image: url('../Assets/wybmd-assets/Sigil_Right_Button.png'); }
.enc-nav:hover { transform: translateY(-50%) scale(1.08); }
.enc-nav:hover::before { opacity: 1; transform: scale(1); }
.enc-nav:focus-visible { outline: 2px solid var(--teal); outline-offset: 3px; border-radius: 6px; }
/* Dots */
.enc-dots {
    position: absolute;
    bottom: 2.5%;
    left: 50%;
    transform: translateX(-50%);
    z-index: 5;
    display: flex;
    gap: 0.9cqw;
}
.enc-dot {
    width: clamp(6px, 1cqw, 10px);
    aspect-ratio: 1;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.32);
    border: 1px solid rgba(0, 0, 0, 0.5);
    padding: 0;
    cursor: pointer;
    transition: background 0.2s var(--ease), transform 0.2s var(--ease);
}
.enc-dot.is-active { background: var(--gold); transform: scale(1.25); }

/* Narrow-desktop / tablet: on a short 16/9 stage the heading wraps taller and
   the sigil nav (top-left) starts to collide with the title. Drop the intro
   line so the heading stays in the top band, clear of the nav. */
@media (max-width: 900px) {
    .encounter-head { max-width: 52%; }
    .encounter-head .display-lead { display: none; }
}
/* Phones: a 16/9 stage is too short to read the standing character, so make the
   stage taller and let the rigid diorama COVER it (height-driven, cropped left
   and right). The whole scene keeps its scale/lock; only the outer chairs fall
   outside the frame. UI is pinned to the stage so nothing gets cropped. */
@media (max-width: 640px) {
    .encounter-stage { aspect-ratio: 4 / 5; }
    .encounter-diorama {
        inset: auto;
        top: 50%;
        left: 50%;
        height: 100%;
        width: auto;
        aspect-ratio: 16 / 9;
        transform: translate(-50%, -50%);
    }
    .encounter-head { max-width: 100%; padding: clamp(1rem, 4cqw, 2rem) clamp(1rem, 4cqw, 2rem) 0; }
    .encounter-head .display-lg { font-size: clamp(1.35rem, 6.4cqw, 2rem); line-height: 1.05; }
    .encounter-bubble { max-width: 60%; top: 25%; right: 5%; font-size: clamp(0.72rem, 3cqw, 1rem); }
    .enc-nav { top: 60%; width: clamp(42px, 12cqw, 58px); }
    .enc-prev { left: 3%; }
    .enc-next { right: 3%; }
    .enc-nameplate { bottom: 8%; font-size: clamp(0.66rem, 3cqw, 0.95rem); }
    .enc-dots { bottom: 3%; }
}
@media (prefers-reduced-motion: reduce) {
    .enc-char { transition: opacity 0.2s linear; }
}

/* ════════════════════════════════════════════════════════════
   PHASE 4 — OVER 100 ENDINGS (oversized focal number + fate list)
   ════════════════════════════════════════════════════════════ */
.endings-v2-layout {
    display: grid;
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    gap: clamp(2rem, 5vw, 4.5rem);
    align-items: start;
}
.endings-v2-focal { position: relative; }
.endings-v2-num {
    display: block;
    font-family: var(--font-display);
    font-weight: 700;
    line-height: 0.9;
    font-size: clamp(6rem, 16vw, 12rem);
    color: transparent;
    -webkit-text-stroke: 2px rgba(217, 164, 65, 0.55);
    text-stroke: 2px rgba(217, 164, 65, 0.55);
    margin-bottom: var(--s-2);
    text-shadow: 0 0 60px rgba(217, 164, 65, 0.12);
}
.endings-v2-plus {
    color: var(--gold);
    -webkit-text-stroke: 0;
    text-stroke: 0;
}
.fates {
    display: flex;
    flex-direction: column;
    gap: 0;
    counter-reset: fate;
}
.fate {
    display: flex;
    align-items: baseline;
    gap: var(--s-3);
    padding: var(--s-3) 0;
    border-top: 1px solid var(--frame-line);
    cursor: default;
    transition: transform 0.4s var(--ease);
}
.fate:last-of-type { border-bottom: 1px solid var(--frame-line); }
.fate-idx {
    flex: 0 0 auto;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.1rem;
    color: var(--gold);
    letter-spacing: 0.05em;
    min-width: 2.2rem;
}
.fate-name {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.5rem;
    color: var(--text);
    margin-bottom: 0.3rem;
}
.fate-body p {
    color: var(--text-dim);
    font-size: 0.98rem;
    line-height: 1.65;
    max-width: 46ch;
}
.fate:hover { transform: translateX(6px); }
.fate:hover .fate-name { color: var(--teal-bright); }
.fates-foot {
    margin-top: var(--s-4);
    grid-column: 1 / -1;
    font-family: var(--font-display);
    font-style: italic;
    font-size: 1.1rem;
    color: var(--muted);
    text-align: center;
}
.fates-foot strong { color: var(--teal-bright); font-style: normal; }

/* ════════════════════════════════════════════════════════════
   PHASE 4 — GALLERY (feature + tidy mosaic) + LIGHTBOX
   A deterministic, gap-free mosaic for the all-landscape (16:9) shots:
     row 1-2 : feature (2×2)  +  two wide tiles (2-col) stacked beside it
     row 3   : four single tiles
   12 cells across a 4-col grid → no orphaned empty cells.
   ════════════════════════════════════════════════════════════ */
.gallery-v2-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--s-3);
    margin-top: clamp(2.5rem, 6vh, 4.5rem);
}
.gallery-item {
    position: relative;
    overflow: hidden;
    border-radius: var(--radius);
    border: 1px solid var(--frame-line);
    background: var(--panel);
    cursor: zoom-in;
    aspect-ratio: 16 / 9;
}
.gallery-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: filter 0.2s var(--ease);
}
/* Wide tiles span two columns; the feature also spans two rows. The feature
   drops its own aspect-ratio so its height is dictated by the two rows it
   covers (≈ matching the wide tiles beside it). */
.gallery-item.g-wide { grid-column: span 2; }
.gallery-item.g-feature {
    grid-column: span 2;
    grid-row: span 2;
    aspect-ratio: auto;
}
/* Hover matches the devlog viewer images (.devlog-zoom): a gentle brightness
   lift, no scale, so both galleries feel identical. */
.gallery-item:hover img { filter: brightness(1.06); }

.chronicle-stats {
    margin-top: var(--s-4);
    text-align: center;
    font-family: var(--font-display);
    font-style: italic;
    font-size: 1rem;
    color: var(--muted);
}
.chronicle-stats strong { color: var(--teal-bright); font-style: normal; font-weight: 700; }

/* ════════════════════════════════════════════════════════════
   AGE RATINGS — official badges beneath the wishlist strip, Darkest-Dungeon
   style. No plates: each badge carries its own background (ESRB white box,
   PEGI orange, USK green), so they read cleanly on the dark strip.
   ════════════════════════════════════════════════════════════ */
.age-ratings {
    margin-top: var(--s-3);
    padding: 0 var(--s-3);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: clamp(1rem, 2vw, 1.6rem);
}
.rating-esrb {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}
.age-ratings img {
    height: 76px;
    width: auto;
    display: block;
    flex-shrink: 0;
}
/* One descriptor per line (fed via <br> in the i18n string) so the ESRB block
   stays narrow and the badges don't drift far apart. */
.rating-desc {
    font-size: 0.8rem;
    line-height: 1.45;
    color: var(--muted);
    text-align: left;
    white-space: normal;
}

/* ════════════════════════════════════════════════════════════
   WISHLIST STRIP — slim single-line store call (replaces the CTA scene)
   ════════════════════════════════════════════════════════════ */
.wishlist-strip {
    border-top: 1px solid var(--frame-line);
    background: linear-gradient(180deg, rgba(12, 13, 18, 0.6), var(--bg));
    padding: clamp(1.5rem, 3vh, 2rem) 0;
}
/* Stacked: prompt on top, wishlist buttons under it, ratings below (added
   separately after .wishlist-strip-inner). */
.wishlist-strip-inner {
    max-width: var(--scene-max);
    margin: 0 auto;
    padding: 0 var(--s-3);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--s-3);
    text-align: center;
}
.wishlist-strip-text {
    font-family: var(--font-display);
    font-size: clamp(1rem, 1.8vw, 1.25rem);
    color: var(--text);
    letter-spacing: 0.01em;
}
.wishlist-strip-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--s-2);
}
/* Strip seals share the exact hero seal size (single style, kept consistent). */
/* Tighten the congregation block on this page: less vertical padding so its
   contents read as centered, not floating in a tall band. The wishlist strip
   already separates it, so drop the footer's big top margin too. */
body[data-page="games"] .site-footer { margin-top: 0; }
body[data-page="games"] .footer-cta { padding: clamp(1.8rem, 4vh, 2.6rem) 0; }

/* Lightbox (self-contained copy for the games page) */
/* Unified lightbox — shared visual language with the devlog viewer
   (css/devlog.css .devlog-lb*): same overlay, image, sigil nav and counter.
   Keep the two blocks in sync when either changes. */
.lightbox {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 4vmin;
    background: rgba(6, 6, 9, 0.93);
}
.lightbox.open { display: flex; }
.lightbox-img {
    max-width: 92vw;
    max-height: 88vh;
    border-radius: var(--radius);
    border: 1px solid var(--line-strong);
    box-shadow: 0 30px 80px -30px #000;
}
.lightbox-close {
    position: absolute;
    top: 16px; right: 22px;
    width: 44px; height: 44px;
    display: grid;
    place-items: center;
    background: none;
    border: none;
    color: var(--text);
    cursor: pointer;
    opacity: 0.8;
    transition: opacity 0.2s var(--ease);
}
.lightbox-close:hover { opacity: 1; }
.lightbox-close svg { width: 26px; height: 26px; }
/* Sigil prev/next. z-index sits ABOVE the image so the left sigil is never
   painted under the image when it widens on narrow screens. */
.lightbox-nav {
    position: absolute;
    top: 50%;
    z-index: 2;
    transform: translateY(-50%);
    width: 64px; height: 64px;
    background: center / contain no-repeat;
    border: none;
    cursor: pointer;
    transition: transform 0.25s var(--ease), filter 0.25s var(--ease);
}
.lightbox-nav:hover { transform: translateY(-50%) scale(1.08); filter: brightness(1.12); }
.lightbox-nav.prev { left: 3vmin; background-image: url('../Assets/wybmd-assets/Sigil_Left_Button.png'); }
.lightbox-nav.next { right: 3vmin; background-image: url('../Assets/wybmd-assets/Sigil_Right_Button.png'); }
.lightbox-nav[hidden] { display: none; }
.lightbox-count {
    position: absolute;
    bottom: 20px; left: 50%;
    transform: translateX(-50%);
    font-family: var(--font-caps);
    letter-spacing: 0.1em;
    font-size: 0.85rem;
    color: var(--text-dim);
}
@media (prefers-reduced-motion: reduce) { .lightbox-nav { transition: none; } }
@media (max-width: 600px) {
    .lightbox-nav { width: 48px; height: 48px; }
    .lightbox-nav.prev { left: 2vmin; }
    .lightbox-nav.next { right: 2vmin; }
}

/* ════════════════════════════════════════════════════════════
   PHASE 5 — DEVLOG MODULE (cards rendered by js/devlog.js)
   Card markup/classes are produced by the engine; we style them here in
   the v2 language. Only the latest 4 are shown on this page (CSS cap);
   the full archive lives on devlog.html.
   ════════════════════════════════════════════════════════════ */
.devlog-v2-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--s-3);
}
/* Cap to the latest few on the games page; archive holds the rest */
.devlog-v2-grid .devlog-card:nth-child(n+5) { display: none; }

.devlog-card {
    position: relative;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border-radius: var(--radius-lg);
    border: 1px solid var(--frame-line);
    background: var(--panel);
    transition: transform 0.4s var(--ease), border-color 0.3s var(--ease), box-shadow 0.4s var(--ease);
}
/* Card styling now lives in css/devlog.css (loaded after this file on both
   games.html and devlog.html). The rules below are legacy and mostly overridden;
   hover motion is intentionally not defined so the panels sit still. */
/* First post spans the full row as a feature */
.devlog-card.is-feature {
    grid-column: 1 / -1;
    flex-direction: row;
}
.devlog-card-anchor {
    position: absolute;
    inset: 0;
    z-index: 2;
}
.devlog-card-media {
    position: relative;
    overflow: hidden;
    aspect-ratio: 16 / 9;
    background: var(--bg-2);
}
.devlog-card.is-feature .devlog-card-media {
    flex: 0 0 48%;
    aspect-ratio: auto;
}
.devlog-card-body {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: var(--s-3);
}
.devlog-card.is-feature .devlog-card-body { justify-content: center; padding: var(--s-4); }
.devlog-card-date {
    font-family: var(--font-body);
    font-size: 0.74rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--teal);
}
.devlog-card-title {
    font-family: var(--font-display);
    font-weight: 400;
    font-size: 1.2rem;
    line-height: 1.25;
    color: var(--text);
}
.devlog-card.is-feature .devlog-card-title { font-size: clamp(1.4rem, 2.4vw, 2rem); }
.devlog-card-excerpt {
    font-size: 0.92rem;
    line-height: 1.6;
    color: var(--text-dim);
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.devlog-card-link {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    margin-top: auto;
    font-family: var(--font-display);
    font-weight: 400;
    font-size: 0.85rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--teal-bright);
    transition: gap 0.3s var(--ease);
}
.devlog-card-link svg { width: 16px; height: 16px; }

/* Loading / empty state + spinner (engine injects these) */
.devlog-state {
    grid-column: 1 / -1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s-2);
    padding: var(--s-6) 0;
    color: var(--muted);
}
.devlog-spinner {
    width: 34px;
    height: 34px;
    border: 3px solid var(--line-strong);
    border-top-color: var(--teal);
    border-radius: 50%;
    animation: dvSpin 0.8s linear infinite;
}
@keyframes dvSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .devlog-spinner { animation: none; } }

.devlog-v2-foot { margin-top: var(--s-4); text-align: center; }
.devlog-v2-all {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    font-family: var(--font-display);
    font-weight: 400;
    font-size: 0.92rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--teal-bright);
    padding: 0.7rem 1.4rem;
    border: 1px solid var(--frame-line-strong);
    border-radius: var(--radius);
    transition: background-color 0.3s var(--ease), gap 0.3s var(--ease);
}
.devlog-v2-all:hover { background: rgba(68, 187, 164, 0.1); gap: 0.85rem; }
.devlog-v2-all svg { width: 18px; height: 18px; }

/* ════════════════════════════════════════════════════════════
   PHASE 5 — CTA ENCOUNTER (Accept / Decline seals)
   Reuses the parchment look; wired to js/site.js initCtaEncounter.
   ════════════════════════════════════════════════════════════ */
.cta-v2 { text-align: center; }
.cta-v2-inner { display: flex; flex-direction: column; align-items: center; }
.cta-card {
    max-width: 640px;
    text-align: center;
}
.cta-card-art {
    width: 100%;
    height: auto;
    border-radius: 3px;
    margin-bottom: var(--s-3);
    box-shadow: 0 16px 36px -18px rgba(0, 0, 0, 0.7);
}
.cta-card-title {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(1.6rem, 3.4vw, 2.4rem);
    color: var(--parchment-ink);
    margin-bottom: var(--s-2);
}
.cta-card-text {
    color: var(--parchment-ink-dim);
    font-size: 1rem;
    line-height: 1.7;
    max-width: 46ch;
    margin: 0 auto var(--s-3);
}
.cta-choices {
    display: flex;
    justify-content: center;
    gap: var(--s-2);
}
.cta-choice {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-family: var(--font-display);
    font-weight: 400;
    font-size: 0.98rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 0.85rem 1.9rem;
    border-radius: 3px;
    cursor: pointer;
    transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease), background-color 0.25s var(--ease);
}
.cta-choice--accept {
    color: #fff;
    background: linear-gradient(160deg, var(--seal-red), #9c2f1c);
    box-shadow: 0 10px 26px -12px rgba(214, 73, 47, 0.8);
}
.cta-choice--accept:hover { transform: translateY(-2px); box-shadow: 0 16px 34px -12px rgba(214, 73, 47, 0.95); }
.cta-choice--decline {
    color: var(--parchment-ink);
    background: transparent;
    border: 1px solid rgba(42, 33, 24, 0.4);
}
.cta-choice--decline:hover { background: rgba(42, 33, 24, 0.08); transform: translateY(-2px); }

/* Decline shakes the card (site.js adds .shake) */
.cta-card.shake { animation: ctaShake 0.5s var(--ease); }
@keyframes ctaShake {
    10%, 90% { transform: translateX(-2px); }
    20%, 80% { transform: translateX(4px); }
    30%, 50%, 70% { transform: translateX(-7px); }
    40%, 60% { transform: translateX(7px); }
}
/* From the 2nd refusal the Accept seal nudges forward (site.js adds .nudge) */
.cta-choice--accept.nudge { animation: ctaNudge 0.6s var(--ease); }
@keyframes ctaNudge {
    0%, 100% { transform: translateY(0); }
    30% { transform: translateY(-6px) scale(1.05); }
}
@media (prefers-reduced-motion: reduce) {
    .cta-card.shake, .cta-choice--accept.nudge { animation: none; }
}

/* Bartholomew materialises after the first refusal (site.js toggles hidden + .bart-in) */
.cta-bart {
    display: flex;
    align-items: center;
    gap: var(--s-2);
    margin-top: var(--s-4);
    max-width: 520px;
    opacity: 0;
    transform: translateY(12px);
    transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
}
.cta-bart.bart-in { opacity: 1; transform: none; }
.cta-bart-bubble {
    font-size: 0.95rem;
    line-height: 1.55;
    color: var(--text);
    background: rgba(21, 23, 31, 0.92);
    border: 1px solid var(--line-strong);
    border-radius: 14px 14px 4px 14px;
    padding: 0.85rem 1.1rem;
}
.cta-bart-ghost { width: clamp(90px, 12vw, 130px); height: auto; }

.cta-stores-hint {
    margin-top: var(--s-4);
    font-size: 0.92rem;
    color: var(--muted);
}
.cta-stores {
    margin-top: var(--s-2);
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--s-2);
}

/* ════════════════════════════════════════════════════════════
   RESPONSIVE — scaffolding-level; per-scene tuning lands in Phase 7
   ════════════════════════════════════════════════════════════ */
@media (max-width: 900px) {
    .display-xl { max-width: none; }
    .blessings-hud { grid-template-columns: 1fr; }
    .dv2--a, .dv2--b, .dv2--c, .dv2--d, .dv2--e, .dv2--locked { top: 0; }
    .endings-v2-layout { grid-template-columns: 1fr; }
    .devlog-v2-grid { grid-template-columns: 1fr; }
    .devlog-card.is-feature { flex-direction: column; }
    .devlog-card.is-feature .devlog-card-media { flex-basis: auto; aspect-ratio: 16 / 9; }
    .cta-bart { flex-direction: column; text-align: center; }
}
@media (max-width: 600px) {
    .scene--intro { padding-top: calc(var(--nav-h) + 2rem); }
    .display-xl { font-size: clamp(2.1rem, 11vw, 3.2rem); }
    .parchment { padding: 1.3rem; }
    .trailer-v2-play { width: 64px; height: 64px; }
    .trailer-v2-play svg { width: 26px; height: 26px; }
    .gallery-v2-grid { grid-template-columns: repeat(2, 1fr); }
    .gallery-item.g-wide { grid-column: span 2; }
    /* Feature drops the 2-row span on phones (no neighbour defines its height)
       and falls back to a full-width 16:9 hero tile. */
    .gallery-item.g-feature { grid-column: span 2; grid-row: auto; aspect-ratio: 16 / 9; }
    .endings-v2-num { font-size: clamp(5rem, 28vw, 8rem); }
    .fate { gap: var(--s-2); }
    .fate-idx { min-width: 1.6rem; font-size: 0.95rem; }
    .cta-choices { flex-direction: column; align-items: stretch; }
    .cta-choice { justify-content: center; }
}

/* ════════════════════════════════════════════════════════════
   PHASE 7 — POLISH: tablet, focus, reduced-motion, performance
   ════════════════════════════════════════════════════════════ */

/* ─── Tablet / mid widths ─── */
@media (max-width: 1100px) and (min-width: 901px) {
    .endings-v2-layout { gap: 2.5rem; }
    .dv2 { width: clamp(140px, 20vw, 200px); }
}
/* Small phones — keep disciples legible side by side */
@media (max-width: 480px) {
    .disciples-row { gap: 0.5rem; }
    .dv2 { width: clamp(92px, 30vw, 150px); }
    .dv2--b { width: clamp(104px, 33vw, 180px); }
    .scene { padding: clamp(3rem, 8vh, 5rem) 0; }
}

/* ─── Focus-visible for non-native interactive elements ─── */
.trailer-v2-frame:focus-visible,
.gallery-item:focus-visible,
.cta-choice:focus-visible,
.seal-btn:focus-visible {
    outline: 2px solid var(--teal);
    outline-offset: 3px;
    border-radius: 4px;
}
/* Keyboard users can surface a disciple's quote */
.dv2:focus-visible { outline: 2px solid var(--teal); outline-offset: 4px; border-radius: 8px; }

/* ─── Performance: skip layout/paint for off-screen scenes ───
   Each scene reserves ~viewport height so scrollbar length stays stable. */
.scene:not(.scene--intro) {
    content-visibility: auto;
    contain-intrinsic-size: auto 720px;
}

/* ─── Reduced motion: still functional, just still ─── */
@media (prefers-reduced-motion: reduce) {
    .scroll-cue-dot::after { animation: none; }
    .blessing-sigil::after { animation: none; }
    .gallery-item img,
    .devlog-card-media img { transition: none; }
    .gallery-item:hover img,
    .devlog-card:hover .devlog-card-media img { transform: none; }
    .fate,
    .gallery-item,
    .devlog-card,
    .wishlist-seal { transition: none; }
    .cta-bart { transition: opacity 0.3s linear; transform: none; }
}
