/*
 * Selective motion for photographic stills.
 *
 * These moves are intentionally slow and small: the image should feel alive,
 * never advertise an effect. Apply one class only to an authored story beat;
 * dialogue, evidence UI, terminals and real video plates remain locked.
 */
.cinematic-still {
    backface-visibility: hidden;
    transform-origin: 50% 50%;
    will-change: transform;
}

/* Series default: a photographic plate should never feel like a frozen
 * slideshow. Unauthored stills receive a nearly invisible "breathing" move;
 * authored shots below retain their deliberate push, pull, or lateral drift.
 * The direct-child rule avoids moving diagrams, terminals, and screenshots. */
.slide.active > img.backdrop:not(.cinematic-still),
.slide.active > img.gil-office-backdrop:not(.cinematic-still),
.slide.active .cinematic-still:not(.camera-push):not(.camera-pull):not(.camera-drift-left):not(.camera-drift-right):not(.camera-lock) {
    animation: camera-breathe 24s cubic-bezier(.2,.65,.2,1) both;
    backface-visibility: hidden;
    transform-origin: 50% 50%;
    will-change: transform;
}

/* Change the axis gently from shot to shot. This is editorial variation, not
 * an attention-grabbing transition. */
.slide:nth-child(4n + 2).active > img.backdrop:not(.cinematic-still),
.slide:nth-child(4n + 2).active > img.gil-office-backdrop:not(.cinematic-still) {
    animation-name: camera-auto-left;
}

.slide:nth-child(4n + 3).active > img.backdrop:not(.cinematic-still),
.slide:nth-child(4n + 3).active > img.gil-office-backdrop:not(.cinematic-still) {
    animation-name: camera-auto-right;
}

.slide:nth-child(4n).active > img.backdrop:not(.cinematic-still),
.slide:nth-child(4n).active > img.gil-office-backdrop:not(.cinematic-still) {
    animation-name: camera-auto-pull;
}

/* Episodes 6–7 replace several legacy plates through CSS so the original img
 * is deliberately hidden. Recreate those plates as moving layers; otherwise
 * they would be the only photographic scenes frozen in the final MP4. */
.slide.active:has(> img[src="images/backdrops/ep6-canary-sam-investigates-v1.png"])::before,
.slide.active:has(> img[src="images/backdrops/ep6-canary-witnesses-v1.png"])::before,
.slide.active:has(> img[src="images/backdrops/ep6-canary-shutdown-v1.png"])::before,
.slide.active:has(> img[src="images/backdrops/episode7/ep7-signed-control-v1.png"])::before,
.slide.active:has(> img[src="images/backdrops/episode7/ep7-service-reveal-v1.png"])::before {
    content: "";
    position: absolute;
    z-index: 0;
    inset: -2%;
    background-position: center;
    background-size: cover;
    transform: var(--camera-auto-transform, none);
    animation: camera-breathe 24s cubic-bezier(.2,.65,.2,1) both;
    backface-visibility: hidden;
    will-change: transform;
}

.slide.active:has(> img[src="images/backdrops/ep6-canary-sam-investigates-v1.png"])::before {
    background-image: linear-gradient(90deg,rgba(5,9,12,.12),rgba(5,9,12,.32)), url("images/backdrops/revision-2026-08/ep6-sam-night-v3.png");
}
.slide.active:has(> img[src="images/backdrops/ep6-canary-witnesses-v1.png"])::before {
    background-image: linear-gradient(90deg,rgba(5,9,12,.08),rgba(5,9,12,.24)), url("images/backdrops/revision-2026-08/ep6-bank-witnesses-v4.png");
}
.slide.active:has(> img[src="images/backdrops/ep6-canary-shutdown-v1.png"])::before,
.slide.active:has(> img[src="images/backdrops/episode7/ep7-signed-control-v1.png"])::before,
.slide.active:has(> img[src="images/backdrops/episode7/ep7-service-reveal-v1.png"])::before {
    background-image: linear-gradient(90deg,rgba(5,9,12,.1),rgba(5,9,12,.3)), url("images/backdrops/revision-2026-08/ep7-signed-control-v3.png");
}

.slide.active .cinematic-still.camera-push {
    animation: camera-push 18s cubic-bezier(.2,.65,.2,1) both;
}

.slide.active .cinematic-still.camera-pull {
    animation: camera-pull 20s cubic-bezier(.2,.65,.2,1) both;
}

.slide.active .cinematic-still.camera-drift-left {
    animation: camera-drift-left 22s cubic-bezier(.2,.65,.2,1) both;
}

.slide.active .cinematic-still.camera-drift-right {
    animation: camera-drift-right 22s cubic-bezier(.2,.65,.2,1) both;
}

@keyframes camera-push {
    from { transform: scale(1.005) translate3d(0, 0, 0); }
    to { transform: scale(1.045) translate3d(-.35%, -.2%, 0); }
}

@keyframes camera-pull {
    from { transform: scale(1.055) translate3d(-.25%, -.15%, 0); }
    to { transform: scale(1.012) translate3d(0, 0, 0); }
}

@keyframes camera-drift-left {
    from { transform: scale(1.035) translate3d(.65%, 0, 0); }
    to { transform: scale(1.045) translate3d(-.65%, -.15%, 0); }
}

@keyframes camera-drift-right {
    from { transform: scale(1.04) translate3d(-.65%, -.15%, 0); }
    to { transform: scale(1.035) translate3d(.65%, 0, 0); }
}

@keyframes camera-breathe {
    from { transform: scale(1.012) translate3d(0, 0, 0); }
    to { transform: scale(1.035) translate3d(-.18%, -.12%, 0); }
}

@keyframes camera-auto-left {
    from { transform: scale(1.025) translate3d(.38%, 0, 0); }
    to { transform: scale(1.04) translate3d(-.42%, -.1%, 0); }
}

@keyframes camera-auto-right {
    from { transform: scale(1.035) translate3d(-.38%, -.1%, 0); }
    to { transform: scale(1.025) translate3d(.42%, 0, 0); }
}

@keyframes camera-auto-pull {
    from { transform: scale(1.042) translate3d(-.12%, -.08%, 0); }
    to { transform: scale(1.016) translate3d(0, 0, 0); }
}

@media (prefers-reduced-motion: reduce) {
    .slide.active :is(.cinematic-still, .backdrop, .gil-office-backdrop) { animation: none !important; }
}
