/* ============================================================
   HAUNTED ATTRACTION WEBSITES — the landing page for the
   vertical, and the live demo of the THEIRS theme.

   THE PEN SHIPS. The owner's CodePen is reproduced below VERBATIM,
   under its own banner, and the standing instruction on it is
   absolute: NOTHING IN IT MAY BE RETIMED AND NOTHING IN IT MAY
   BE RESTYLED. Every :root scene variable, every keyframe, every
   animation-range is byte-for-byte what he wrote. If you are
   about to edit anything between THE PEN BEGINS and THE PEN
   ENDS, stop and ask him.

   Everything this page adds lives AFTER the pen, in blocks each
   marked ADDED, and every one of them was written to ride the
   pen's timeline rather than to change it:

     1. THE RUNWAY. The pen states its runtime as `body
        { height: var(--runtime) }`, which is exactly right for a
        pen with nothing under the film and impossible for a page
        with eight sections under it. The height is reproduced
        EXACTLY by an empty .runway spacer, so every
        animation-range still maps to the same absolute scroll
        offset it always did. This is the ONE declaration of the
        pen's that is overridden, and the timing does not move.

        It is also what finishes the film: the pen's own scroll
        range topped out one screen short of its own runtime, so
        Scene 7 could only ever reach 20% and the screen never
        actually went black. With a page under it the document is
        taller, the burial's last frame is reachable, and it
        completes — which is the black screen the rest of this
        page is written on.

     2. THE SCRIPT. Three title cards pinned into the film on the
        pen's own scene variables. New elements, new ranges,
        nothing of the pen's touched. They are aria-hidden and
        every one of them says something the sections below say
        again in full — a line that flies past at scroll speed is
        not where content may live. The middle card opens in the
        blue sky's colours and is still on screen when the grave
        closes, so its palette crosses back to blood and black
        under the reader; that turn is the point of the set.

     3. THE PAGE. Masthead, seven sections, the collection band
        and the colophon — on THE GREY WORLD the film came out
        of, not on the black it leaves behind (2026-08-01, the owner:
        "bring that grainy and rainy scene back into play …
        it's empty, rainy and foggy"). ADDED 8 is a second,
        page-owned set of the film's own three ingredients; ADDED
        9 is the black-on-grey type that sits on them.

     4. THE RETIMES. The pen's director's board, with nine
        numbers moved on the owner's instruction and nothing else: the
        flash to blue sky lands as you pass through Frank rather
        than sixty screens later, and the grave then starts
        closing while you are still looking at the sky rather
        than a hundred and forty screens after it. All nine live
        in ONE :root OVERRIDE in ADDED 7, so the pen block itself
        is still byte-identical and there is one findable place
        to revert. Everything downstream of them — the three
        title cards, the aftermath's fade, the rain handover — is
        derived from those numbers, never tuned beside them.

     5. THE GRAVE'S SHAPE. `lower-grave` redefined whole in
        ADDED 10, again on his instruction, so the burial's hole
        holds a fixed 1 : 2.3 at every viewport instead of
        settling into the window's aspect ratio. Same technique:
        a later same-name keyframe replaces the earlier one, so
        the pen's bytes stand.

   THE no-runway TWIN IS AT THE FOOT OF THIS FILE and it is
   load-bearing twice over. The pen is 100% scroll-timeline
   driven with `fill-mode: both`, so without a resolvable
   timeline .flash-bang alone parks a full-screen white sheet
   over everything. And a reader who asked for less motion is
   owed the argument, not the ride.
   ============================================================ */


/* ---- Poster faces, for the collection band at the foot of the page.
   style.css's own subsets, declared verbatim: .poster_daylight,
   .poster_divebar and .poster_holo ask for them by name and this page
   loads no style.css. The unicode-ranges must match tools/fonts.py's
   LATIN / LATIN_EXT exactly and must not overlap.

   NOT PRELOADED, deliberately — small faces for three previews at the
   very bottom of a page whose film runs eight screens before them.
   Nothing above them waits on a font: this page's own type is the
   system stack, exactly as the pen's is. */
@font-face {
	font-family: "JetBrains Mono";
	src: url(/assets/fonts/jetbrains-mono-latin-v1.woff2) format("woff2");
	font-weight: 500;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0020-007E, U+00A0, U+00A9, U+00AE, U+00B0, U+00B7, U+2010-2027, U+2030, U+2039-203A, U+2044, U+20AC, U+2122, U+2190-2193, U+2212;
}

@font-face {
	font-family: "JetBrains Mono";
	src: url(/assets/fonts/jetbrains-mono-latinext-v1.woff2) format("woff2");
	font-weight: 500;
	font-style: normal;
	font-display: swap;
	unicode-range: U+00A1-00A8, U+00AA-00AD, U+00AF, U+00B1-00B6, U+00B8-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC;
}

@font-face {
	font-family: "Tilt Neon";
	src: url(/assets/fonts/tilt-neon-poster-v1.woff2) format("woff2");
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: "Inter";
	src: url(/assets/fonts/inter-poster-v1.woff2) format("woff2");
	font-weight: 600;
	font-style: normal;
	font-display: swap;
}


/* ============================================================
   ================  T H E   P E N   B E G I N S  =============
   The owner's CodePen, verbatim. Do not retime it and do not restyle
   it. Additions go after THE PEN ENDS.
   ============================================================ */

/* =========================================
   🎬 THE FILM STRIP TIMELINE (DIRECTOR'S BOARD)
   Adjust these variables to change when things happen.
   Think of 1vh as 1 frame of your scroll timeline.
   ========================================= */
:root {
	/* Extended runtime for the new scenes */
	--runtime: 800vh;

	/* SCENE 1: The Intro */
	--scene-1-start: 0vh;
	--scene-1-end: 50vh;

	/* SCENE 2: The Approach */
	--scene-2-start: 50vh;
	--scene-2-end: 200vh;

	/* SCENE 3: The Reveal */
	--scene-3-start: 15vh;
	--scene-3-end: 270vh;
	/* Ends right as the flash hits */

	/* SCENE 4: The Transition (Screen flashes white) */
	--scene-4-start: 260vh;
	--scene-4-peak: 290vh;
	/* Pure whiteout */
	--scene-4-end: 320vh;

	/* SCENE 5: The Blue Sky (The Scroll Pause) */
	/* No animations here, just a peaceful hold from 320vh to 450vh */

	/* SCENE 6: The Grave Descent (Walls close in) */
	--scene-6-start: 450vh;
	--scene-6-end: 700vh;

	/* SCENE 7: Buried (Fades to pitch black) */
	--scene-7-start: 680vh;
	--scene-7-end: 780vh;
}

/* Reset and Base Styles */
* {
	box-sizing: border-box;
	margin: 0;
	padding: 0;
}

body {
	color: #eaeaea;
	font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
	height: var(--runtime);
	overflow-x: hidden;
	margin: 0;
	background: #000;
}

/* Fixed Banner for Scrolljacking */
.banner {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100dvh;
	overflow: hidden;
	z-index: 1;
	background: #646464;
}

/* =========================================
   ENVIRONMENTAL EFFECTS (SCENES 1-3)
   ========================================= */
#fogCanvas {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	z-index: 2;
	background: url('assets/fog1.png') repeat-x;
	background-size: 200% 100%;
	animation: drift 50s linear infinite;
	opacity: 0.35;
	filter: grayscale(100%) contrast(1.2);
}

#rainCanvas {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	z-index: 4;
	pointer-events: none;
}

.lightning {
	position: absolute;
	inset: 0;
	background-color: #e0e5ff;
	opacity: 0;
	z-index: 5;
	pointer-events: none;
	animation: flash 12s infinite;
}

.grain {
	position: absolute;
	inset: -50%;
	width: 200%;
	height: 200%;
	z-index: 6;
	pointer-events: none;
	opacity: 0.08;
	background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
	animation: noise 1s steps(2) infinite;
}

/* =========================================
   SCENES 1 - 3: THE DOOR & FRANK
   ========================================= */
.banner-text {
	position: absolute;
	bottom: 3rem;
	left: 3rem;
	z-index: 10;
	pointer-events: auto;
	will-change: transform, opacity;
	animation: text-fade both;
	animation-timeline: scroll(root);
	animation-range: var(--scene-1-start) var(--scene-1-end);
}

/* Restored Typography and Glitch */
.banner-text h1 {
	font-size: clamp(2rem, 4vw, 4rem);
	font-weight: 300;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	margin-bottom: 0.5rem;
	color: rgba(255, 255, 255, 0.8);
	filter: blur(3px);
	animation: unstable-teleport 5s infinite;
}

.banner-text p {
	font-size: 1rem;
	font-weight: 400;
	letter-spacing: 0.25em;
	text-transform: uppercase;
	color: #5e0000;
}

.door-scene {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	perspective: 1200px;
	z-index: 3;
	pointer-events: none;
}

.pull-container {
	position: relative;
	width: clamp(200px, 20vw, 300px);
	height: clamp(400px, 40vw, 600px);
	transform-style: preserve-3d;
	will-change: transform;
	box-shadow: 0 0 50px rgba(0, 0, 0, 0.8);
	border: 8px solid #111;
	background: #000;

	animation: camera-walk cubic-bezier(0.32, 0, 0.67, 0) both;
	animation-timeline: scroll(root);
	animation-range: var(--scene-2-start) var(--scene-2-end);
}

.door-panel {
	position: absolute;
	inset: 0;
	background-color: #2a2a2c;
	transform-origin: left;
	transform-style: preserve-3d;
	z-index: 2;
	border: 1px solid #1a1a1c;
	box-shadow: inset -5px 0 15px rgba(0, 0, 0, 0.8), 5px 10px 20px rgba(0, 0, 0, 0.9);
	display: flex;
	flex-direction: column;
	padding: 10%;
	gap: 5%;
	will-change: transform;

	animation: door-open both;
	animation-timeline: scroll(root);
	animation-range: var(--scene-1-start) var(--scene-1-end);
}

.frank {
	height: 100%;
	display: block;
	position: absolute;
	left: 50%;
	transform: translate3d(-50%, 0, -1000px);
	z-index: 999;
	margin: auto;

	animation: reveal-frank both;
	animation-timeline: scroll(root);
	animation-range: var(--scene-3-start) var(--scene-3-end);
}

/* Supporting Door UI Details */
.the-void {
	position: absolute;
	inset: 0;
	background: #000;
	box-shadow: inset 0 0 50px #000;
	z-index: 1;
	overflow: hidden;
}

.the-void::after {
	content: '';
	position: absolute;
	inset: 0;
	transform: scale(0.8);
	background: radial-gradient(circle, rgba(90, 0, 0, 0.4) 0%, transparent 70%);
	animation: pulse-void 4s infinite alternate ease-in-out;
}

.door-panel::before {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 999999;
	pointer-events: none;
	background: repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0, 0, 0, 0.05) 2px, rgba(0, 0, 0, 0.05) 4px);
}

.panel-inset {
	flex: 1;
	background: #252527;
	border: 2px solid #1f1f21;
	box-shadow: inset 5px 5px 10px rgba(0, 0, 0, 0.8), inset -5px -5px 10px rgba(255, 255, 255, 0.02), 2px 2px 5px rgba(0, 0, 0, 0.5);
}

.doorknob {
	position: absolute;
	right: 0;
	top: 50%;
	transform: translateY(-50%);
	width: 15px;
	height: 15px;
	border-radius: 50%;
	background: radial-gradient(circle at 30% 30%, #555, #111);
	box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.8), inset -2px -2px 5px rgba(0, 0, 0, 0.5);
}

.doorknob-plate {
	position: absolute;
	right: 0;
	top: 50%;
	transform: translateY(-50%);
	width: 20px;
	height: 60px;
	border-radius: 2px;
	background: linear-gradient(90deg, #222, #333, #222);
	box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.8);
	z-index: -1;
}

/* =========================================
   SCENE 4: THE FLASH BANG
   ========================================= */
.flash-bang {
	position: absolute;
	inset: 0;
	background: #fff;
	z-index: 9999;
	/* Top of everything */
	pointer-events: none;
	animation: flash-white both;
	animation-timeline: scroll(root);
	animation-range: var(--scene-4-start) var(--scene-4-end);
}

/* =========================================
   SCENE 5 & 6: THE SKY & THE GRAVE
   ========================================= */
.sky-scene {
	position: absolute;
	inset: 0;
	z-index: 2000;
	/* Above the rain and door, below the flash */
	overflow: hidden;

	/* Sneakily fade this in DURING the whiteout flash */
	animation: reveal-sky both;
	animation-timeline: scroll(root);
	animation-range: var(--scene-4-start) var(--scene-4-peak);
}

.sky-background {
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, #4facfe 0%, #00f2fe 100%);
}

.sun {
	position: absolute;
	top: 15%;
	left: 50%;
	width: 120px;
	height: 120px;
	background: #fff;
	border-radius: 50%;
	transform: translateX(-50%);
	box-shadow: 0 0 80px 40px rgba(255, 255, 255, 0.9),
		0 0 150px 80px rgba(255, 240, 200, 0.6);
}

/* Reusing the fog logic, but making it bright white clouds */
.clouds {
	position: absolute;
	inset: 0;
	background: url('assets/fog1.png') repeat-x;
	background-size: 200% 100%;
	/* Invert the dark smoke to make bright clouds, up the brightness */
	filter: invert(1) brightness(2.5) opacity(0.8);
	pointer-events: none;
}

.cloud-layer-1 {
	animation: drift 45s linear infinite;
}

.cloud-layer-2 {
	animation: drift 70s linear infinite reverse;
	top: 15%;
	transform: scale(1.3);
	opacity: 0.5;
}

/* The Grave Wall - 100% HTML/CSS using a shrinking div with a massive box-shadow */
.grave-opening {
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);

	/* Animation */
	animation: lower-grave both;
	animation-timeline: scroll(root);
	animation-range: var(--scene-6-start) var(--scene-6-end);
}

/* SCENE 7: Pitch Black Overlay */
.buried-blackout {
	position: absolute;
	inset: 0;
	background: #020100;
	z-index: 3000;
	/* Cover everything inside the sky scene */
	pointer-events: none;
	animation: bury-fade both;
	animation-timeline: scroll(root);
	animation-range: var(--scene-7-start) var(--scene-7-end);
}

/* =========================================
   KEYFRAMES (Animations)
   ========================================= */

/* Scene 1-3 Legacy Keyframes */
@keyframes text-fade {
	0% {
		transform: translateX(0px);
		opacity: 1;
	}

	100% {
		transform: translateX(-150px);
		opacity: 0;
	}
}

@keyframes door-open {
	0% {
		transform: rotateY(0deg);
	}

	100% {
		transform: rotateY(-110deg);
	}
}

@keyframes camera-walk {
	0% {
		transform: translateZ(0px);
	}

	50% {
		transform: translateZ(1100px) translateY(40%);
	}

	100% {
		transform: translateZ(1250px) translateY(40%);
	}
}

@keyframes reveal-frank {

	0%,
	50% {
		filter: brightness(0);
	}

	100% {
		filter: brightness(1);
	}
}

@keyframes pulse-void {
	0% {
		opacity: 0.4;
		transform: scale(0.8);
	}

	100% {
		opacity: 0.9;
		transform: scale(1.1);
	}
}

@keyframes drift {
	0% {
		background-position: 0 0;
	}

	100% {
		background-position: -200% 0;
	}
}

@keyframes flash {

	0%,
	91%,
	94%,
	96%,
	100% {
		opacity: 0;
	}

	92% {
		opacity: 0.8;
	}

	93% {
		opacity: 0.1;
	}

	95% {
		opacity: 0.6;
	}
}

/* Film Grain */
@keyframes noise {

	0%,
	100% {
		transform: translate(0, 0);
	}

	10% {
		transform: translate(-5%, -5%);
	}

	20% {
		transform: translate(-10%, 5%);
	}

	30% {
		transform: translate(5%, -10%);
	}

	40% {
		transform: translate(-5%, 15%);
	}

	50% {
		transform: translate(-10%, 5%);
	}

	60% {
		transform: translate(15%, 0);
	}

	70% {
		transform: translate(0, 15%);
	}

	80% {
		transform: translate(3%, 15%);
	}

	90% {
		transform: translate(-10%, 10%);
	}
}

/* Restored Glitch Keyframes */
@keyframes unstable-teleport {

	0%,
	40.9% {
		text-shadow: none;
	}

	41%,
	41.9% {
		text-shadow: 30px 0 0 rgba(255, 255, 255, 0.8);
	}

	42%,
	42.9% {
		text-shadow: -20px 5px 0 rgba(255, 255, 255, 0.8), 10px -5px 0 rgba(255, 255, 255, 0.8);
	}

	43%,
	43.9% {
		text-shadow: 15px 0 0 rgba(255, 255, 255, 0.8);
	}

	44%,
	44.9% {
		text-shadow: -35px -2px 0 rgba(255, 255, 255, 0.8);
	}

	45%,
	72.9% {
		text-shadow: none;
	}

	73%,
	73.9% {
		text-shadow: -40px 0 0 rgba(255, 255, 255, 0.8), 40px 0 0 rgba(255, 255, 255, 0.8);
	}

	74%,
	74.9% {
		text-shadow: 15px 10px 0 rgba(255, 255, 255, 0.8);
	}

	75%,
	75.9% {
		text-shadow: -10px -10px 0 rgba(255, 255, 255, 0.8);
	}

	76%,
	91.9% {
		text-shadow: none;
	}

	92%,
	92.9% {
		text-shadow: 50px 0 0 rgba(255, 255, 255, 0.8);
	}

	93%,
	93.9% {
		text-shadow: -25px 0 0 rgba(255, 255, 255, 0.8);
	}

	94%,
	100% {
		text-shadow: none;
	}
}

/* Scene 4: Flash */
@keyframes flash-white {
	0% {
		opacity: 0;
	}

	50% {
		opacity: 1;
	}

	/* Hits peak at --scene-4-peak */
	100% {
		opacity: 0;
	}
}

/* Scene 5: Reveal Sky under the Flash */
@keyframes reveal-sky {
	0% {
		opacity: 0;
	}

	100% {
		opacity: 1;
	}
}

/* Scene 6: The Grave Sink */
@keyframes lower-grave {
	0% {
		/* Start huge, no shadow visible */
		width: 150vw;
		height: 150vh;
		box-shadow: 0 0 0 0vmax #0a0604, inset 0 0 0px #000;
		border-radius: 0px;
	}

	5% {
		/* The shadow snaps out slightly past the screen bounds immediately */
		width: 100vw;
		height: 100vh;
		box-shadow: 0 0 0 100vmax #110905, inset 0 0 40px #000;
		border-radius: 5px;
	}

	100% {
		/* Shrinks down to a tiny hole in the distance */
		width: 12vw;
		height: 30vh;
		box-shadow: 0 0 0 100vmax #060302, inset 0 0 150px #000;
		border-radius: 20px;
		transform: translate(-50%, -65%);
		/* Shift perspective up as we go down */
	}
}

/* Scene 7: Buried Fade */
@keyframes bury-fade {
	0% {
		opacity: 0;
	}

	100% {
		opacity: 1;
	}
}

/* ============================================================
   ==================  T H E   P E N   E N D S  ===============
   Everything below is this page's, and none of it reaches back
   up into the film. Read the header note before editing.
   ============================================================ */


/* ============================================================
   ADDED 1 — THE RUNWAY

   The pen's `body { height: var(--runtime) }` is the ONE
   declaration of his this file overrides, and the override is
   the price of having a page at all: a body with a fixed height
   has nowhere to put eight sections. The runtime is handed
   straight back by .runway, an empty spacer of exactly
   var(--runtime) — the film's fixed banner plays against it and
   every animation-range in the pen resolves to the identical
   absolute scroll offset it always did.

   scroll(root) measures from the top of the document, so making
   the document TALLER cannot move a range that is written in
   absolute vh. It can only make a late one reachable, which is
   the point: at a body of exactly --runtime the scroll range tops
   out one screen short of it, so Scene 7's last 100vh of burial
   could never get past 20% and the screen never went black. It
   does now.
   ============================================================ */
body {
	height: auto;
}

/* THE +100vh IS THE BEAT BETWEEN THE FILM AND THE PAGE.

   var(--runtime) alone puts the page's top edge at 660vh, which means it
   starts ENTERING the viewport at 560vh — and at 560vh the burial is only
   about a fifth done, so the grave is still a lit hole onto the blue sky.
   One more screen of spacer moves the page's arrival to scroll 660vh:
   Scene 7 completes at 640vh, the screen holds PURE BLACK, and only then
   does the weather come back up under it. The owner's note for the first build
   was "cover the grave and we've got a black screen to work with"; this is
   the number that delivers it, and ADDED 8's fade is timed inside it.

   IT USED TO BE THE NO INVISIBLE WALLS RULE AS WELL, and since 2026-08-01
   it is not: #page carried an opaque black of its own and the +100 kept
   that hard edge from rising across a lit grave. #page is transparent now
   (the weather behind it is the background), so there is no edge left to
   hide — this is pacing, and only pacing.

   TIED TO --scene-7-end. If that ever moves, re-derive: the spacer must
   end at least one viewport past the frame where the blackout reaches 1. */
.runway {
	height: calc(var(--runtime) + 100vh);
	pointer-events: none;
}

/* The film is z-index 1 and fixed, the weather (ADDED 8) is z-index 2 and
   fixed, and the page rides over both at 3 with NO BACKGROUND OF ITS OWN —
   which is what lets §01 sit directly on the grain and the rain. */
#page {
	position: relative;
	z-index: 3;
}


/* ============================================================
   ADDED 2 — THE SCRIPT

   Three title cards pinned into the film, each on its own range
   inside one of the pen's scenes. NEW elements with NEW ranges:
   nothing of the pen's is retimed, and the beats they land on
   are read off his director's board rather than tuned by eye.

     L1  70–250vh   the door, and the thing behind it  (scenes 2–3)
     ---            the whiteout owns 185–235          (scene 4)
     L2 250–535vh   the blue sky, then the descent     (scenes 5–6)
     L3 560–635vh   going under                        (scene 7)

   L2 AND L3 ARE READ OFF THE BOARD AND MOVED WITH IT: both came
   up 140vh when ADDED 7's second pass pulled the back half of the
   film up. L1 did not — it sits in scenes 2–3, which neither pass
   touched.

   THEY ARE DECORATIVE AND THAT IS DELIBERATE. Each line is
   aria-hidden and each says something §01–§03 below say again
   in full. A sentence travelling past at scroll speed, over a
   thunderstorm, is a title card — it is not somewhere content
   may live, and a screen reader is owed the page, not the film.

   THE CARD IS OPAQUE ON PURPOSE, and it REPLACES the radial
   scrim the lines used to sit on. The film runs mid-grey →
   whiteout → bright sky → black underneath them, so no wash
   tuned for one backdrop survives the other three; a solid
   near-black plate with a blood edge holds its own contrast
   (white on #0b0b0c is 19:1) at every frame of the film, and
   it is also what makes the middle card's palette flip legible
   as a deliberate change rather than a lighting accident.

   L2 IS THE TURN AND IT IS ONE ELEMENT, not two. It arrives on
   the sky wearing the sky's colours and is still on screen when
   the grave starts closing at 310vh, so the palette crosses back
   to the blood edge UNDER the reader between there and ~436vh —
   the same card, lowered into the ground with them. Splitting it
   in two would cut exactly the beat it exists for.
   ============================================================ */
.script {
	position: fixed;
	inset: auto 0 0 0;
	height: 42dvh;
	z-index: 5;
	pointer-events: none;
	display: grid;
	place-items: center;
	padding: 0 var(--gutter);
}

.script_line {
	grid-area: 1 / 1;
	margin: 0;
	max-width: 30ch;
	text-align: center;
	text-wrap: balance;
	font-size: clamp(1.05rem, 2.9vw, 2.15rem);
	font-weight: 300;
	line-height: 1.3;
	letter-spacing: .12em;
	text-transform: uppercase;
	padding: .85em 1.15em;
	border: 2px solid var(--blood-edge);
	background: var(--card-dark);
	color: #fff;
	box-shadow: var(--card-dark-glow);
	opacity: 0;
}

/* the film's own last word, held on the black the burial leaves */
.script_line--last {
	letter-spacing: .2em;
}

/* L1 and L3: the palette never moves, so only the arrival does */
@keyframes script-line {
	0% {
		opacity: 0;
		translate: 0 14px;
	}

	18%,
	80% {
		opacity: 1;
		translate: 0 0;
	}

	100% {
		opacity: 0;
		translate: 0 -14px;
	}
}

/* L2: the same arrival, plus the flip. The percentages are the
   scene boundaries mapped onto its own 250→535vh range —
   21% is ~310vh (the grave starts closing, --scene-6-start) and
   65% is ~435vh (walls well in: the midpoint of the 310→560
   descent). Move the range and both stops move with it, which is
   exactly what ADDED 7 pass 2 did — they were 36% and 74% of a
   330→665vh range before the back half of the film came up. */
@keyframes script-line-turn {
	0% {
		opacity: 0;
		translate: 0 14px;
		border-color: var(--sky-edge);
		background-color: var(--card-sky);
		color: var(--sky-ink);
		box-shadow: var(--card-sky-glow);
	}

	8%,
	21% {
		opacity: 1;
		translate: 0 0;
		border-color: var(--sky-edge);
		background-color: var(--card-sky);
		color: var(--sky-ink);
		box-shadow: var(--card-sky-glow);
	}

	65%,
	93% {
		opacity: 1;
		translate: 0 0;
		border-color: var(--blood-edge);
		background-color: var(--card-dark);
		color: #fff;
		box-shadow: var(--card-dark-glow);
	}

	100% {
		opacity: 0;
		translate: 0 -14px;
		border-color: var(--blood-edge);
		background-color: var(--card-dark);
		color: #fff;
		box-shadow: var(--card-dark-glow);
	}
}


/* ============================================================
   ADDED 3 — TOKENS

   The palette is the pen's, named. #5e0000 is the sub-headline
   red he wrote and it is a SURFACE colour here, never a text
   one — on this black it measures 1.3:1. --blood-lit is the
   text-safe sibling (5.2:1) and every link and accent uses it.
   ============================================================ */
:root {
	--void: #050505;
	--void-lift: #0d0b0b;
	--void-deep: #000;

	--ink: #dcdcdc;
	/* body — 13.6:1 on --void */
	--ink-soft: #a5a5a5;
	/* secondary — 7.4:1 */
	--ink-faint: #8d8d8d;
	/* annotation — 5.4:1, the floor */

	--blood: #5e0000;
	/* the pen's red. SURFACES ONLY. */
	--blood-lit: #e0483c;
	/* text-safe red — 5.2:1 */

	/* THE TITLE CARDS (ADDED 2), both palettes, in one place because
	   the middle card animates from one to the other and a value that
	   only exists in a keyframe is a value nobody finds again.

	   --blood-edge is a LINE colour, not the pen's --blood: two pixels
	   of #5e0000 on #0b0b0c is 1.15:1 and reads as no border at all.
	   This is the same red carried up to 2:1, where the edge is
	   actually visible, and the red glow under it does the rest. It is
	   chrome on an aria-hidden card, so 2:1 is a look, not a floor —
	   the text it frames is white on near-black at 19:1.

	   The sky pair is taken off the pen's own gradient (#4facfe →
	   #00f2fe) rather than invented: a paper-white card, its edge the
	   top of that gradient, its ink the same hue run down to 11.4:1.
	   The glow is the scene's sun rather than a drop shadow. */
	--blood-edge: #8b0f14;
	--card-dark: #0b0b0c;
	--card-dark-glow: 0 0 34px rgba(139, 15, 20, .38), 0 22px 60px rgba(0, 0, 0, .8);

	--sky-edge: #2f8fd8;
	--card-sky: #f7fbff;
	--sky-ink: #0b3a5c;
	--card-sky-glow: 0 0 44px rgba(255, 255, 255, .55), 0 18px 50px rgba(4, 46, 78, .28);

	--edge: rgba(255, 255, 255, .1);
	--edge-lit: rgba(224, 72, 60, .38);

	--gutter: clamp(1.25rem, 5vw, 4rem);
	--measure: 74rem;
	--ease: cubic-bezier(.22, .61, .36, 1);
}


/* ============================================================
   ADDED 4 — TYPE AND FURNITURE

   No webfont for anything on this page's own type: the pen sets
   the system stack on <body> and it stays there, so nothing
   above the collection band waits on a font request. Headings
   take the pen's own h1 treatment — light weight, wide tracking,
   uppercase — without its blur or its glitch, neither of which
   a paragraph of copy can carry.
   ============================================================ */
#page {
	color: var(--ink);
	font-size: clamp(1rem, .96rem + .2vw, 1.075rem);
	line-height: 1.75;
	-webkit-font-smoothing: antialiased;
}

/* :not(.poster_title) IS A BUG FIX, not tidying (2026-08-01). The ported
   posters set their own title colour at (0,2,0) — `.poster_daylight
   .poster_title { color: #15181a }` — and lost to this rule's (1,0,1), so
   Daylight Study's near-black title has been rendering WHITE on pale
   paper in the collection band since the band shipped. Excluding the class
   hands all three posters their own colour back; every other declaration
   here is one .poster_title already resets for itself. */
#page h2,
#page h3:not(.poster_title) {
	font-weight: 300;
	line-height: 1.15;
	text-wrap: balance;
	color: #fff;
}

#page h2 {
	font-size: clamp(1.9rem, 1.2rem + 2.6vw, 3.4rem);
	letter-spacing: .06em;
	text-transform: uppercase;
	max-width: 22ch;
}

#page h3 {
	font-size: clamp(1.1rem, 1rem + .5vw, 1.35rem);
	letter-spacing: .05em;
	text-transform: uppercase;
	margin-bottom: .55rem;
}

#page p {
	max-width: 68ch;
}

#page p+p {
	margin-top: 1.05rem;
}

#page a {
	color: var(--blood-lit);
	text-underline-offset: .22em;
	text-decoration-thickness: 1px;
}

#page a:hover {
	color: #fff;
}

:focus-visible {
	outline: 2px solid var(--blood-lit);
	outline-offset: 3px;
}

/* the section index — the pen's small red caps, moved to a colour that
   can carry text on black */
.anno {
	font-size: .72rem;
	letter-spacing: .28em;
	text-transform: uppercase;
	color: var(--ink-faint);
	max-width: none;
}

.anno--lit {
	color: var(--blood-lit);
}

.lede {
	font-size: clamp(1.1rem, 1rem + .55vw, 1.45rem);
	line-height: 1.55;
	color: #fff;
	font-weight: 300;
	max-width: 40ch;
}

.skip {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 200;
	background: var(--void-deep);
	color: #fff;
	padding: .75rem 1.25rem;
	border: 1px solid var(--edge-lit);
}

.skip:focus {
	left: 1rem;
	top: 1rem;
}

/* --- sections ------------------------------------------------------- */
.band {
	position: relative;
	padding: clamp(4.5rem, 12vh, 9rem) var(--gutter);
	border-top: 1px solid var(--edge);
}

.band--lift {
	background: var(--void-lift);
}

.band_inner {
	width: min(100%, var(--measure));
	margin-inline: auto;
}

.band h2 {
	margin: .7rem 0 1.4rem;
}

.split {
	display: grid;
	grid-template-columns: 1.15fr .85fr;
	gap: clamp(2rem, 5vw, 4.5rem);
	align-items: start;
}

.split--even {
	grid-template-columns: 1fr 1fr;
}

@media (max-width: 900px) {

	.split,
	.split--even {
		grid-template-columns: 1fr;
	}
}

.notes {
	display: grid;
	gap: clamp(1rem, 2.5vh, 1.5rem);
}

.cards {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: clamp(1rem, 2.5vw, 2rem);
}

@media (max-width: 900px) {
	.cards {
		grid-template-columns: 1fr;
	}
}

/* THE PLATE — the door's own material. The pen builds its door out of a
   flat dark face, an inset shadow top-left and a lifted shadow below;
   a plate is that panel at another size, which is why nothing here
   needs a colour to read as an object. */
.plate {
	padding: clamp(1.35rem, 3vw, 2rem);
	background: #17151599;
	border: 1px solid var(--edge);
	box-shadow: inset 5px 5px 12px rgba(0, 0, 0, .8), 2px 6px 18px rgba(0, 0, 0, .55);
}

.plate .anno {
	margin-bottom: .5rem;
}

.plate p {
	color: var(--ink-soft);
	font-size: .96rem;
}

.plate--lit {
	border-color: var(--edge-lit);
	box-shadow: inset 5px 5px 12px rgba(0, 0, 0, .8), 2px 6px 18px rgba(0, 0, 0, .55), 0 0 0 1px rgba(94, 0, 0, .5);
}

/* --- the spec list, on the door's inset panels ---------------------- */
.specs {
	list-style: none;
	margin: 1.6rem 0 0;
	border-top: 1px solid var(--edge);
}

.specs li {
	display: grid;
	grid-template-columns: 15rem 1fr;
	gap: .5rem 1.5rem;
	padding: .85rem 0;
	border-bottom: 1px solid var(--edge);
}

@media (max-width: 620px) {
	.specs li {
		grid-template-columns: 1fr;
	}
}

.spec_k {
	font-size: .74rem;
	letter-spacing: .2em;
	text-transform: uppercase;
	color: var(--blood-lit);
	padding-top: .28em;
}

.spec_v {
	color: var(--ink-soft);
	font-size: .96rem;
}

/* --- questions ------------------------------------------------------ */
.qas {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: clamp(1.5rem, 4vw, 3rem);
	margin-top: 1rem;
}

@media (max-width: 900px) {
	.qas {
		grid-template-columns: 1fr;
	}
}

.qa p {
	color: var(--ink-soft);
	font-size: .98rem;
}

/* --- the titleblock, the pen's bottom-left caption promoted to a rule
   across the foot of a section ---------------------------------------- */
.titleblock {
	display: flex;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: .5rem 1.5rem;
	margin-top: clamp(2rem, 5vh, 3.25rem);
	padding-top: .9rem;
	border-top: 1px solid var(--edge);
}

/* --- buttons: the door panel, pressable ----------------------------- */
/* Written at #page specificity on purpose: `#page a` is (1,0,1) and would
   otherwise paint every button in link red. */
#page .mybutton {
	display: inline-block;
	padding: .85rem 1.6rem;
	font-size: .78rem;
	letter-spacing: .22em;
	text-transform: uppercase;
	text-decoration: none;
	font-family: inherit;
	color: var(--ink);
	background: #1c1a1a;
	border: 1px solid var(--edge);
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, .05), 0 6px 16px rgba(0, 0, 0, .6);
	cursor: pointer;
	transition: color .25s var(--ease), border-color .25s var(--ease), translate .25s var(--ease);
}

#page .mybutton:hover {
	color: #fff;
	border-color: var(--edge-lit);
	translate: 0 -2px;
}

#page .mybutton--primary {
	background: linear-gradient(180deg, #3a0505, var(--blood));
	border-color: #7a1a1a;
	color: #fff;
}

.actions {
	display: flex;
	flex-wrap: wrap;
	gap: .75rem;
	margin-top: 2rem;
}

/* --- contact form --------------------------------------------------- */
.contact_form {
	display: grid;
	gap: 1rem;
	align-content: start;
}

.field {
	display: grid;
	gap: .4rem;
}

.field label {
	font-size: .72rem;
	letter-spacing: .2em;
	text-transform: uppercase;
	color: var(--ink-faint);
}

.field input,
.field textarea {
	font: inherit;
	font-size: 1rem;
	color: var(--ink);
	background: #100e0e;
	border: 1px solid var(--edge);
	padding: .7rem .85rem;
	box-shadow: inset 3px 3px 8px rgba(0, 0, 0, .8);
	width: 100%;
}

.field textarea {
	resize: vertical;
}

.field input:focus,
.field textarea:focus {
	border-color: var(--edge-lit);
	outline: none;
	box-shadow: inset 3px 3px 8px rgba(0, 0, 0, .8), 0 0 0 2px rgba(224, 72, 60, .35);
}

/* the honeypot: off-screen, never display:none — a bot fills what it can
   parse, and a real reader never reaches it (tabindex -1, aria-hidden) */
.hp_field {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.form_status {
	font-size: .9rem;
	min-height: 1.4em;
	color: var(--ink-soft);
}

.form_status.ok {
	color: #6fdc8c;
}

.form_status.err {
	color: var(--blood-lit);
}

/* --- the PS close, the last thing read ------------------------------ */
.ps_note {
	margin-top: clamp(2.5rem, 6vh, 4rem);
	padding: clamp(1.35rem, 3vw, 2rem);
	border: 1px solid var(--edge-lit);
	background: linear-gradient(180deg, rgba(94, 0, 0, .18), rgba(0, 0, 0, 0));
}

.ps_note p+p {
	margin-top: .6rem;
}

.ps_note .anno {
	color: var(--blood-lit);
}


/* ============================================================
   ADDED 5 — THE MASTHEAD / INDEX PANEL

   The site's seven real pages, and the same arrangement every
   theme page uses: a plain row above 900px, and below it one
   panel opened by the toggle, because seven links wrapping to
   three lines makes a fixed masthead a third of a phone screen.

   CRAWL PARITY: nothing is display:none and no link is dropped.
   The closed panel is a transformed, visibility:hidden sheet
   holding the same seven real <a href>, made `inert` by the
   script at the foot of the page. This page is deliberately not
   in DECK_CHAIN and nothing in the site nav points at it, so
   there is no aria-current link here.

   THE SCRIM IS THE ONLY REASON IT IS LEGIBLE over the storm:
   the film behind it runs from mid-grey to blue sky to black, so
   the bar cannot rely on any one backdrop.
   ============================================================ */
.masthead {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 60;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding: .9rem var(--gutter);
	background: linear-gradient(180deg, rgba(0, 0, 0, .82), rgba(0, 0, 0, 0));
}

.wordmark {
	font-size: .78rem;
	letter-spacing: .24em;
	text-transform: uppercase;
	text-decoration: none;
	color: rgba(255, 255, 255, .92);
	text-shadow: 0 1px 8px rgba(0, 0, 0, .9);
}

.wordmark:hover {
	color: #fff;
}

/* the toggle is three claw marks — uneven on purpose.

   IT SITS ABOVE THE OPEN PANEL, and that is not decoration: the panel
   is a fixed sheet dropped from `inset: 0 0 auto 0` and it is a later
   positioned sibling, so at equal z-index it PAINTS OVER the button
   that opened it. The only way out of the menu was Escape. Lifting the
   two masthead children one layer puts the control back on top of its
   own sheet, where a thumb can reach it. */
.nav_toggle,
.wordmark {
	position: relative;
	z-index: 2;
}

.nav_toggle {
	display: none;
	background: none;
	border: 1px solid var(--edge);
	padding: .55rem .7rem;
	cursor: pointer;
	line-height: 0;
}

.nav_rules {
	display: grid;
	gap: 4px;
	width: 22px;
}

.nav_rule {
	height: 1px;
	background: rgba(255, 255, 255, .85);
	box-shadow: 0 0 6px rgba(224, 72, 60, .6);
	transition: translate .3s var(--ease), rotate .3s var(--ease),
		opacity .2s var(--ease), width .3s var(--ease);
}

.nav_rule--1 {
	width: 100%;
}

.nav_rule--2 {
	width: 72%;
	justify-self: end;
}

.nav_rule--3 {
	width: 88%;
}

#index_panel .index_eyebrow,
#index_panel .index_block {
	display: none;
}

.index_list {
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	gap: .25rem 1.5rem;
	margin: 0;
}

.index_list a {
	font-size: .72rem;
	letter-spacing: .18em;
	text-transform: uppercase;
	text-decoration: none;
	color: rgba(255, 255, 255, .78);
	text-shadow: 0 1px 8px rgba(0, 0, 0, .9);
}

.index_list a:hover {
	color: #fff;
}

@media (max-width: 900px) {
	.nav_toggle {
		display: block;
	}

	#index_panel {
		position: fixed;
		inset: 0 0 auto 0;
		padding: 4.5rem var(--gutter) 2rem;
		background: rgba(6, 4, 4, .97);
		border-bottom: 1px solid var(--edge-lit);
		box-shadow: 0 24px 60px rgba(0, 0, 0, .9);
		translate: 0 -100%;
		visibility: hidden;
		transition: translate .35s var(--ease), visibility .35s;
	}

	html.nav-open #index_panel {
		translate: 0 0;
		visibility: visible;
	}

	/* THE CLAW MARKS BECOME A CROSS while the menu is open. The button
	   was always a toggle; nothing on screen ever said so, which is half
	   of why the menu felt one-way. Rows are 1px on a 4px gap, so the
	   outer two are exactly 5px off centre — that is where the 5px
	   comes from, and it moves if the gap does. */
	html.nav-open .nav_rule--1 {
		width: 100%;
		translate: 0 5px;
		rotate: 45deg;
	}

	html.nav-open .nav_rule--2 {
		opacity: 0;
	}

	html.nav-open .nav_rule--3 {
		width: 100%;
		translate: 0 -5px;
		rotate: -45deg;
	}

	/* TAP ANYWHERE ELSE TO CLOSE. The panel is only as tall as its own
	   links, so everything under it is the film and the page — and the
	   page is `inert` while the menu is open, which means a tap down
	   there reaches no listener of its own. This pseudo is that missing
	   surface: it belongs to the panel, so its clicks target the panel
	   and the handler at the foot of the page already sees them. It also
	   dims what it covers, so it reads as a closed door rather than a
	   dead one. `position: absolute` (not fixed) is what anchors it to
	   the panel's bottom edge instead of the viewport's. */
	html.nav-open #index_panel::after {
		content: "";
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		height: 100vh;
		height: 100lvh;
		background: rgba(3, 2, 2, .72);
	}

	#index_panel .index_eyebrow,
	#index_panel .index_block {
		display: block;
	}

	#index_panel .index_block {
		display: flex;
		justify-content: space-between;
		gap: 1rem;
		margin-top: 1.5rem;
		padding-top: .9rem;
		border-top: 1px solid var(--edge);
	}

	.index_list {
		display: grid;
		gap: .1rem;
		margin-top: 1rem;
	}

	.index_list a {
		display: block;
		padding: .6rem 0;
		font-size: .82rem;
		border-bottom: 1px solid var(--edge);
	}

	html.nav-open body {
		overflow: hidden;
	}
}


/* ============================================================
   ADDED 6 — THE COLLECTION BAND  (.alsolike)

   "Like this theme? You might also like:", written to TRAVEL —
   nothing here is named for this page and nothing is an id.

   THE CARDS ARE HOME'S POSTERS, PORTED VERBATIM from
   css/style.css — .slide_poster, .poster_bg, .poster_title,
   .poster_sub and each theme's own block, copied unchanged.
   NOT ported: the 3-D hover pops and the fan poses, both of
   which need the fan's preserve-3d rig. Anything that changes in
   style.css's POSTERS block changes here.
   ============================================================ */
.alsolike {
	position: relative;
	padding: clamp(3.5rem, 9vh, 7rem) var(--gutter);
	background: var(--void-lift);
	border-top: 1px solid var(--edge);
}

.alsolike::after {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 1px;
	background: linear-gradient(90deg, var(--blood-lit), rgba(224, 72, 60, 0));
	transform-origin: 0 50%;
}

.alsolike_inner {
	width: min(100%, var(--measure));
	margin-inline: auto;
}

.alsolike h2 {
	margin: .6rem 0 1rem;
	max-width: 20ch;
}

.alsolike_lead {
	margin-bottom: clamp(2rem, 5vh, 3.25rem);
	max-width: 62ch;
	color: var(--ink-soft);
}

.alsolike_grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: clamp(1.25rem, 2.5vw, 2.25rem);
}

@media (max-width: 860px) {
	.alsolike_grid {
		grid-template-columns: 1fr;
	}
}

.alsolike_more {
	margin-top: clamp(1.75rem, 4vh, 2.75rem);
}

/* --- one card = one poster ------------------------------------------ */
/* NO CARD CHROME: the poster is the object. `container-type` is what
   gives the poster its em scale, exactly as the home fan's column does —
   with no padding, 100cqw IS the poster's width. */
.tt_card {
	display: block;
	text-decoration: none;
	container-type: inline-size;
	transition: translate .3s var(--ease);
}

/* The lift is on `translate`, NOT on `transform`: the arrival animation
   below owns `transform` and its fill state keeps applying after it
   settles, so a hover written as a transform would silently do nothing. */
@media (hover: hover) and (pointer: fine) {
	.tt_card:hover {
		translate: 0 -4px;
	}

	.tt_card:hover .tt_art {
		box-shadow: 0 26px 40px rgba(0, 0, 0, .8), 0 0 0 1px var(--edge-lit);
	}
}

.tt_art {
	position: relative;
	overflow: hidden;
	aspect-ratio: 700 / 450;
	border-radius: 18px;
	--u: calc(100cqw / 700);
	/* posters size themselves in em, off this */
	font-size: calc(16 * var(--u));
	box-shadow: 0 18px 34px rgba(0, 0, 0, .7), 0 0 0 1px var(--edge);
	transition: box-shadow .3s ease;
}

/* THE GLINT — one pass of light across the poster as it lands. Scrubbed
   by the motion layer, so it happens once, on arrival, at the reader's
   own speed; parked off-frame here so a browser with no scroll timelines
   never sees it. */
.tt_art::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 3;
	pointer-events: none;
	background: linear-gradient(104deg, transparent 38%, rgb(255 255 255 / .35) 50%, transparent 62%);
	transform: translateX(-140%);
}

.tt_note {
	margin-top: .9rem;
	font-size: .92rem;
	color: var(--ink-soft);
	max-width: none;
}

.tt_card .titleblock {
	margin-top: .9rem;
}

/* =========================== POSTERS ====================================
   Ported from css/style.css. Everything is em-based so it rides .tt_art's
   --u-derived font-size. */
.slide_poster {
	position: relative;
	width: 100%;
	height: 100%;
	border-radius: inherit;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: .4em;
	text-align: center;
	transform-style: preserve-3d;
}

/* Decor layer: carries the poster's background art. */
.poster_bg {
	position: absolute;
	inset: 0;
	overflow: hidden;
	border-radius: inherit;
	transform: translateZ(0);
}

/* Every poster element rests 2px off the card face — never coplanar with
   the opaque .poster_bg at Z 0, so preserve-3d's depth sort never has a
   tie to resolve. Give any NEW poster element the same rest lift.

   The resets are this page's tax, not home's: home has no element rules
   on h3/p at all, so a poster title there renders in the poster's own
   face. Here #page h3 carries uppercase, wide tracking and a light
   weight, all of which would leak in and quietly restyle three other
   studios' work. */
.poster_title {
	margin: 0;
	position: relative;
	font-size: 3.4em;
	line-height: 1.05;
	letter-spacing: 2px;
	font-weight: 700;
	font-variation-settings: normal;
	text-transform: none;
	text-shadow: none;
	text-wrap: wrap;
	transform: translateZ(2px);
}

.poster_kicker {
	margin: 0 0 .4em;
	position: relative;
	max-width: none;
	font-size: .8em;
	letter-spacing: .28em;
	text-transform: uppercase;
	font-family: 'Courier New', monospace;
	transform: translateZ(2px);
}

.poster_sub {
	margin: 0;
	position: relative;
	max-width: none;
	font-size: 1.3em;
	line-height: 1.2;
	transform: translateZ(2px);
}

/* ---- Daylight Study: the architecture sheet — pale paper with a warm
   band of daylight falling across it and an ink border a hair inside the
   card edge. ---- */
.poster_daylight .poster_bg {
	background:
		linear-gradient(118deg, rgba(240, 215, 164, .58) 0 20%, rgba(240, 215, 164, 0) 62%),
		linear-gradient(168deg, #eceded 0%, #dfe1dd 100%);
}

/* the sheet edge. ::after because .poster_bg::before is unused and this is
   the layer that clips — the border must not ride the type's Z pops */
.poster_daylight .poster_bg::after {
	content: "";
	position: absolute;
	inset: .65em;
	border: 1px solid rgba(21, 24, 26, .28);
}

.poster_daylight .poster_kicker {
	font-family: "JetBrains Mono", ui-monospace, monospace;
	color: #676c6e;
}

.poster_daylight .poster_title {
	font-family: "JetBrains Mono", ui-monospace, monospace;
	font-size: 2.3em;
	letter-spacing: .01em;
	text-transform: uppercase;
	color: #15181a;
}

.poster_daylight .poster_sub {
	color: #676c6e;
}

/* ---- Dive Bar: brick, warm lamp glow, neon sign ---- */
.poster_divebar .poster_bg {
	background:
		radial-gradient(ellipse 60% 45% at 50% 15%, rgba(255, 130, 60, .18), transparent 70%),
		repeating-linear-gradient(0deg, transparent 0 1.75em, rgba(0, 0, 0, .5) 1.75em 1.95em),
		repeating-linear-gradient(90deg, transparent 0 3.6em, rgba(0, 0, 0, .3) 3.6em 3.8em),
		#1a120e;
}

.poster_divebar .poster_title {
	font-family: "Tilt Neon", sans-serif;
	font-weight: 100;
	text-transform: uppercase;
	color: #fff;
	text-shadow:
		0 0 .06em #fff,
		0 0 .25em #ff6a3d,
		0 0 .6em #ff3d2e,
		0 0 1.2em #ff3d2e;
}

.poster_divebar .poster_sub {
	color: #d8b49a;
}

/* ---- Holotype: cold hologram — perspective floor + a wireframe icon
   blinking above the title, same cyan-on-navy palette as the real theme ---- */
.poster_holo .poster_bg {
	background:
		repeating-linear-gradient(0deg, transparent 0 1.9em, rgba(77, 227, 255, .08) 1.9em 2em),
		radial-gradient(120% 80% at 50% 0%, #0a1220 0%, #05080f 60%);
}

.poster_holo .poster_glyph {
	position: relative;
	width: 2.4em;
	height: 2.4em;
	color: #4de3ff;
	filter: drop-shadow(0 0 .3em rgba(77, 227, 255, .55));
	transform: translateZ(2px);
	transition: transform .35s ease;
}

.poster_holo .poster_glyph svg {
	width: 100%;
	height: 100%;
}

.poster_holo .poster_title {
	font-family: "Inter", sans-serif;
	color: #d9e6f2;
	text-shadow: 0 0 .5em rgba(77, 227, 255, .5);
}

.poster_holo .poster_sub {
	color: #93a7bd;
}


/* ============================================================
   THE COLOPHON — it continues the band's surface rather than
   starting a new one, so the two read as one lit stretch at the
   foot of the page. TRAVELS WITH THE BAND: a page that takes
   .alsolike takes this pairing, or the annotation vanishes into
   whatever the page's last background happened to be.
   ============================================================ */
.colophon {
	position: relative;
	/* 3, with #page — above the fixed weather at 2. It sat at 2 and only
	   painted on top by DOM order, which is not a thing to rely on. */
	z-index: 3;
	padding: 2.5rem var(--gutter) 3.5rem;
	background: var(--void-lift);
	display: flex;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 1rem;
}

.colophon a {
	color: var(--ink-soft);
}

.colophon a:hover {
	color: #fff;
}


/* ============================================================
   ADDED 7 — THE RETIMES

   THE PEN'S DIRECTOR'S BOARD, OVERRIDDEN IN ONE PLACE. Two
   passes, both the owner's, both 2026-08-01, and they are kept in a
   single :root block on purpose — a board split across two
   override sites is a board nobody can read.

   ---- PASS 1: THE FLASH ----
   Make the flash to blue sky land "right as you pass through
   Frank".

   At the pen's own numbers it does not. `camera-walk` runs
   50→200vh on cubic-bezier(.32,0,.67,0) — both control points at
   y=0, so it is an extreme ease-in that holds and then lunges —
   and .door-scene's perspective is 1200px. The container passes
   the camera plane the frame its translateZ crosses 1200, which
   that curve puts at ≈190vh. The whiteout did not start until
   260vh, so there were seventy screens-worth of scroll where
   nothing moved and you stood looking at him.

   It is written as a :root OVERRIDE rather than an edit inside
   the pen, so THE PEN BLOCK IS STILL BYTE-IDENTICAL and this is
   the one place to revert.

     --scene-4-start  260 → 185vh  the white starts as the
                                   doorway swallows the camera
     --scene-4-peak   290 → 210vh  kept at the MIDPOINT of
                                   start/end, which is where
                                   flash-white's own 50% lands
                                   and is the relationship the
                                   pen's three numbers had
     --scene-4-end    320 → 235vh
     --scene-3-end    270 → 190vh  Frank has to be FULLY LIT
                                   before the white takes him,
                                   and reveal-frank holds
                                   brightness(0) for the first
                                   HALF of its own range. Left at
                                   270 he is 41% lit when the
                                   flash begins — a silhouette,
                                   not a reveal. At 190 he
                                   brightens across exactly the
                                   stretch the camera spends held
                                   at 12x zoom in the doorway.

   ---- PASS 2: THE SKY HOLD ----
   The owner, on the first pass live: "there's much too much scrolling
   happening while you're just looking at the sky before the
   'lowering into a grave' animation starts."

   PASS 1 CAUSED IT AND LEFT IT. Moving the whiteout up 85vh
   without moving the grave stretched the hold from the pen's own
   130vh (320→450) to 215vh (235→450) — and a hold is the one
   thing on this timeline that gets LONGER when everything before
   it gets tighter. The note left here said to pull scenes 6 and
   7 up by the same 85vh; that only restores the pen's 130, and
   his word was "much".

   THE HOLD IS 75vh NOW — the sky is fully in at --scene-4-peak
   (210vh), the white has cleared by 235, the middle title card
   is fully arrived by ~268, and the walls start closing at 310.
   Scenes 6 and 7 keep their own lengths exactly; the whole back
   half of the film is pulled up 140vh as one piece, so nothing
   inside it is retimed relative to anything else.

     --scene-6-start  450 → 310vh  ─┐ the back half, moved as
     --scene-6-end    700 → 560vh   │ one block: 6 is still
     --scene-7-start  680 → 540vh   │ 250vh long, 7 is still
     --scene-7-end    780 → 640vh  ─┘ 100vh and still overlaps
                                     6 by 20vh
     --runtime        800 → 660vh  IT HAS TO MOVE WITH THEM, or
                                   the 20vh of pure black after
                                   the burial becomes 160vh and
                                   the complaint moves rather
                                   than clears. The film ends at
                                   640 and the page's first pixel
                                   arrives at scroll --runtime;
                                   the gap between those two IS
                                   the beat, and it is unchanged.

   FOUR THINGS DOWNSTREAM ARE DERIVED FROM THESE AND ALL FOUR
   MOVED IN THE SAME PASS. They are listed here because nothing
   in their own blocks names a scene variable:
     ADDED 8   .aftermath's fade, 786→806 becomes 646→666 (it
               sits in the black beat: 6vh after the burial
               completes, ending 6vh after the page arrives)
     the rain  buriedAt in index.html, innerHeight × 7.8 → × 6.4
               — it is --scene-7-end and nothing else
     ADDED 2   both lower title cards, and the middle one's flip
               stops with them; the derivation is at the keyframe
     .runway   nothing to do, it is written off --runtime
   ============================================================ */
:root {
	/* pass 1 — the flash */
	--scene-3-end: 190vh;
	--scene-4-start: 185vh;
	--scene-4-peak: 210vh;
	--scene-4-end: 235vh;

	/* pass 2 — the back half, pulled up 140vh as one block */
	--scene-6-start: 310vh;
	--scene-6-end: 560vh;
	--scene-7-start: 540vh;
	--scene-7-end: 640vh;
	--runtime: 660vh;
}


/* ============================================================
   ADDED 8 — THE AFTERMATH

   The weather, after the film. The owner, 2026-08-01: "bring that
   grainy and rainy scene back into play … it's empty, rainy and
   foggy."

   IT IS A SECOND, PAGE-OWNED SET OF THE SAME THREE INGREDIENTS,
   not the pen's moved. The film's fog, rain and grain live
   inside .banner at z-index 1 and are covered by
   .buried-blackout from --scene-7-end (640vh) on; none of that
   may be touched.
   This is a fixed sheet at z-index 2 — above the film, below the
   page — carrying the pen's own fog plate at the pen's own
   opacity, the pen's own grain at the pen's own opacity, and a
   second rain canvas driven by the pen's own rainfield.

   IT IS ALSO THE PAGE'S BACKGROUND. #page used to paint opaque
   black; it paints nothing now, which is what lets §01 sit
   directly on the rain the way the owner asked, and what makes
   .band--lift's veil read as a section break rather than a
   colour change.

   WHAT THE READER ACTUALLY SEES IS NOT #646464. fog1.png is a
   near-WHITE plate (that is why the film's storm is a pale grey
   and not a black one): at .35 over the pen's banner colour it
   lands around #9a9a9a, which is where ADDED 9's ink is
   measured. Change either the sheet or the fog opacity and every
   contrast figure in ADDED 9 moves with it.

   BASE STATE IS VISIBLE, ON PURPOSE. A browser with no scroll
   timelines parks the whole film on its last keyframe (a black
   rectangle) and gets the collapsed runway at the foot of this
   file, so the grey world is exactly what it should be looking
   at. Only where scroll(root) resolves does this start hidden
   and fade up — inside the pure-black beat the .runway's +100vh
   buys, so nothing crosses anything.
   ============================================================ */
.aftermath {
	position: fixed;
	inset: 0;
	z-index: 2;
	overflow: hidden;
	pointer-events: none;
	background: var(--sheet);
}

/* The test string is view(), not scroll(root), so that it is the EXACT
   inverse of the runway collapse at the foot of this file. Split the two
   tests and a browser that supported one and not the other would get an
   uncollapsed runway under a sheet that never fades — the grey world
   painted over the whole film from scroll 0. */
@supports (animation-timeline: view()) {
	.aftermath {
		opacity: 0;
		animation: aftermath-in both linear;
		animation-timeline: scroll(root);
		/* inside the black beat: the burial completes at --scene-7-end
		   (640vh) and the page's first pixel arrives at --runtime
		   (660vh). Both moved in ADDED 7 pass 2; these are derived. */
		animation-range: 646vh 666vh;
	}

	@keyframes aftermath-in {
		0% {
			opacity: 0;
		}

		100% {
			opacity: 1;
		}
	}
}

/* the pen's #fogCanvas, at the pen's opacity and filter, on a slower
   drift — the film is walking somewhere and the page is standing still */
.aftermath_fog {
	position: absolute;
	inset: 0;
	background: url('assets/fog1.png') repeat-x;
	background-size: 200% 100%;
	animation: drift 72s linear infinite;
	opacity: .35;
	filter: grayscale(100%) contrast(1.2);
}

/* the pen's own rainfield, second canvas. Half strength: the film's rain
   is the subject, this one is behind six thousand words. */
#pageRain {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	opacity: .5;
}

/* the pen's .grain, verbatim including the noise plate */
.aftermath_grain {
	position: absolute;
	inset: -50%;
	width: 200%;
	height: 200%;
	opacity: .08;
	background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
	animation: noise 1s steps(2) infinite;
}

/* NO LIGHTNING DOWN HERE, and that is a decision. The film's .lightning
   fires a 0.8-opacity full-screen white every 12s; behind the film it is
   the storm, behind six thousand words of body copy it is a strobe over
   the thing you are trying to read. */

/* The looping ambience is time-based, not scroll-based, so the
   html.no-runway twin at the foot of the file cannot be the only guard —
   a reader whose OS asks for less motion but who has JS off never gets
   stamped. Same reasoning the film's own loops deserve and do not yet
   have; this is the half that is in scope. */
@media (prefers-reduced-motion: reduce) {

	.aftermath_fog,
	.aftermath_grain {
		animation: none;
	}
}


/* ============================================================
   ADDED 9 — THE GREY WORLD

   The owner, 2026-08-01: "overall adjust the theme to be more like
   the intro … black text on this grey background works well.
   Our theme is hopelessness and emptiness."

   So §01–§07 are BLACK ON THE STORM. Everything here is scoped
   `#page .band` and reaches nothing else: the collection band,
   the colophon and the masthead are still the dark surfaces they
   were built as, and so are the CARDS INSIDE these sections —
   The owner's "keep the cards as-is for now".

   THE NUMBERS, all against the ~#9a9a9a the sheet-plus-fog
   actually composites to (ADDED 8):

     --sheet-ink       #0a0a0a   7.0:1  ·  5.5:1 on a lifted band
     --sheet-ink-soft  #1f1f1f   5.9:1  ·  4.6:1
     --blood (#5e0000) 5.1:1 on the base sheet — the pen's own
                       deep red is finally a TEXT-CAPABLE colour
                       here, which is why it is the underline
                       under every link and the hover state.
     white             2.8:1 — WHICH IS WHY .anno--lit IS BLACK.
                       The owner called white "passable" off the
                       banner h1, and at display size over a
                       moving storm it is; at .72rem uppercase it
                       is not. The glitch keeps the banner's
                       signature either way: unstable-teleport
                       only animates text-shadow, so black type
                       throwing white ghosts is the same effect
                       read the other way round.

   --blood-lit (#e0483c) is the OPPOSITE of text-capable here —
   1.15:1 on the sheet. It stays exactly where it was earned, on
   the dark plates. Do not let it back onto the grey.
   ============================================================ */
:root {
	/* the pen's own banner colour. The visible grey is this plus the fog. */
	--sheet: #646464;
	--sheet-ink: #0a0a0a;
	--sheet-ink-soft: #1f1f1f;
	--sheet-rule: rgba(0, 0, 0, .26);
	/* the section break: a bank of thicker weather, not a new colour */
	--sheet-veil: rgba(6, 5, 5, .16);
}

#page .band {
	color: var(--sheet-ink);
	border-top-color: var(--sheet-rule);
}

#page .band--lift {
	background: var(--sheet-veil);
}

#page .band :is(h2, h3),
#page .band .lede,
#page .band .anno--lit,
#page .band .spec_k {
	color: var(--sheet-ink);
}

#page .band .anno,
#page .band .qa p,
#page .band .spec_v,
#page .band .field label,
#page .band .form_status {
	color: var(--sheet-ink-soft);
}

/* :not(.mybutton) is load-bearing — a .mybutton is an <a> inside .band, and
   this selector would otherwise beat #page .mybutton and paint black type
   onto a near-black button. The link colour is the ink and the CUE is the
   blood underline, so nothing on the sheet depends on hue to be found. */
#page .band a:not(.mybutton) {
	color: var(--sheet-ink);
	text-decoration-color: var(--blood);
	text-decoration-thickness: 1px;
}

#page .band a:not(.mybutton):hover {
	color: var(--blood);
}

#page .band .specs,
#page .band .specs li,
#page .band .titleblock {
	border-color: var(--sheet-rule);
}

#page .band :focus-visible {
	outline-color: var(--sheet-ink);
}

/* --- the cards keep the dark they were built for --------------------- */
/* KEPT AS-IS ON THE OWNER'S WORD, and there is one open number in it: .plate is
   #17151599, i.e. 60% opaque, so over the grey it composites to about
   #4b4b4b instead of the near-black it used to. Its body copy
   (--ink-soft) is ~3.5:1 there against 7.7:1 before. One character fixes
   it — raise the plate's alpha to dd — but that is a look, so it is
   The owner's call and not made here. */
#page .band .plate :is(h2, h3) {
	color: #fff;
}

#page .band .plate .anno {
	color: var(--ink-faint);
}

#page .band .plate a {
	color: var(--blood-lit);
}

#page .band .plate a:hover {
	color: #fff;
}

#page .band .plate :focus-visible {
	outline-color: var(--blood-lit);
}

/* THE GLITCH — the banner h1's, lifted to a class so anything can wear it.
   unstable-teleport is the PEN'S keyframe, referenced and not copied; it
   animates text-shadow only, so it carries no blur and no layout cost and
   a paragraph-scale element can take it. Live on all seven .anno--lit
   section eyebrows (2026-08-01, the owner). */
.glitch {
	animation: unstable-teleport 5s infinite;
}

@media (prefers-reduced-motion: reduce) {
	.glitch {
		animation: none;
	}
}


/* ============================================================
   ============  T H E   M O T I O N   L A Y E R  =============
   ============================================================

   EVERYTHING scroll-driven ON THIS PAGE'S OWN CONTENT is inside
   this one block. The film above is not — the pen owns its own
   timeline and is never touched from here.

   The guard is doubled on purpose: @supports so a browser
   without scroll timelines simply gets the settled page, and
   prefers-reduced-motion so a reader who asked for stillness
   gets it from the OS without needing the site's own stamp. The
   site's stamp (html.no-runway) is handled after the block.

   THE PAGE'S MOTION BUDGET IS SPENT ON THE FILM, and nothing in
   here is allowed to compete with it. Every entry below is a
   fade plus a ≤22px translate on a view() timeline — no pin, no
   scrub of anything the reader is trying to read, no depth.
   Eight screens of storm has earned the reader a page that
   mostly sits still.
   ============================================================ */
@supports (animation-timeline: view()) {
	@media (prefers-reduced-motion: no-preference) {

		/* ---- THE SCRIPT. Three cards, three ranges, all read off the
		   pen's own scene variables. See ADDED 2. ---- */
		.script_line {
			animation-name: script-line;
			animation-timing-function: ease-in-out;
			animation-fill-mode: both;
			animation-timeline: scroll(root);
		}

		/* the door and what is behind it */
		.script_line:nth-child(1) {
			animation-range: 70vh 250vh;
		}

		/* THE TURN — it opens on the sky and closes in the ground, so it
		   is the only card that outlives a scene boundary. Its length is
		   what the palette flip is timed against; see ADDED 2.
		   DERIVED FROM THE BOARD, NOT TUNED: it opens where L1 finishes
		   (250vh, so the two never share the cell — they are stacked in
		   one grid area) and clears 5vh before the blackout starts
		   (--scene-7-start 540). */
		.script_line--sky {
			animation-name: script-line-turn;
			animation-range: 250vh 535vh;
		}

		/* the last word, on the black the burial leaves — it starts on
		   --scene-6-end and clears 5vh before --scene-7-end, as it always
		   has; both moved in ADDED 7 pass 2 */
		.script_line--last {
			animation-range: 560vh 635vh;
		}

		/* The layer itself goes inert in the gap between the last card
		   leaving (635vh) and the page arriving at --runtime (660vh). It
		   sits at z-index 5 — above the film AND above #page — so a fixed
		   sheet left live over the copy would eat every click in the lower
		   42dvh of the screen for the rest of the document. `visibility`
		   is discrete, so this is a hard off, not a fade. DERIVED: it came
		   up 140vh with the board in ADDED 7 pass 2. */
		.script {
			animation: script-out both linear;
			animation-timeline: scroll(root);
			animation-range: 635vh 650vh;
		}

		@keyframes script-out {
			0% {
				visibility: visible;
			}

			99.9% {
				visibility: visible;
			}

			100% {
				visibility: hidden;
			}
		}

		/* ---- BAND ARRIVALS. One per element, each on its own view()
		   timeline, so every one is relative to itself and none needs a
		   page offset.

		   ONE ANIMATION PER ELEMENT, and it is the rule that shapes this
		   whole list. Nested view() arrivals COMPOUND their opacities —
		   a .plate inside an animating column fades to .25 at the point
		   both are half done, which reads as a fault rather than a
		   flourish. So a container animates OR its children do, never
		   both: the two-column sections hand it down to the columns, and
		   the card grids hand it down to the cards.

		   THE SITE'S SPLIT-KIT GRAMMAR, at a whisper (2026-08-01, the owner:
		   "incorporate our more subtle scroll animations in the real body
		   content"). Copy comes in laterally, the objects beside it come
		   from the other side a beat later — home's feature-split motion,
		   without the depth and without the pin, because none of these
		   sections is pinned and this page has already spent eight screens
		   of the reader's attention. opacity and translate only: the two
		   a compositor moves without re-rastering. ---- */
		.band_inner>*:not(.split):not(.cards):not(.qas),
		.alsolike_inner>* {
			animation: page-arrive both linear;
			animation-timeline: view();
			animation-range: entry 12% entry 62%;
		}

		/* the copy column, and whatever sits opposite it */
		.split>*:first-child {
			animation: copy-arrive both linear;
			animation-timeline: view();
			animation-range: entry 12% entry 62%;
		}

		.split>*:not(:first-child):not(.notes),
		.notes>*,
		.cards>*,
		.qas>* {
			animation: aside-arrive both linear;
			animation-timeline: view();
			animation-range: entry 16% entry 68%;
		}

		/* A ROW NEEDS A STAGGER AND A COLUMN DOES NOT. Stacked plates
		   (.notes, .qas on one column) are already staggered by the only
		   thing that matters — their own position down the page. Cards
		   sitting side by side share a top edge, so their timelines are
		   identical and they land as one block; these offsets are the
		   difference. */
		.cards>*:nth-child(2),
		.qas>*:nth-child(even) {
			animation-range: entry 22% entry 74%;
		}

		.cards>*:nth-child(3) {
			animation-range: entry 28% entry 80%;
		}

		/* THE EYEBROWS WEAR TWO ANIMATIONS AND HAVE TO SAY SO IN ONE PLACE.
		   Every .anno--lit is a direct child of .band_inner, so the blanket
		   rule above already claims the `animation` shorthand on it — and a
		   shorthand resets animation-name, so .glitch (0,1,0) losing to
		   (0,4,0) meant the glitch silently never ran. Listed together here
		   instead, each with its own timeline: the arrival is scrubbed, the
		   glitch is on the clock. #page carries this over the blanket rule;
		   raising the class count alone cannot beat four of them. */
		#page .band .glitch {
			animation: page-arrive both linear, unstable-teleport 5s infinite;
			animation-timeline: view(), auto;
			animation-range: entry 12% entry 62%, normal;
		}

		@keyframes page-arrive {
			0% {
				opacity: 0;
				translate: 0 22px;
			}

			100% {
				opacity: 1;
				translate: 0 0;
			}
		}

		@keyframes copy-arrive {
			0% {
				opacity: 0;
				translate: -22px 0;
			}

			100% {
				opacity: 1;
				translate: 0 0;
			}
		}

		@keyframes aside-arrive {
			0% {
				opacity: 0;
				translate: 22px 0;
			}

			100% {
				opacity: 1;
				translate: 0 0;
			}
		}

		/* ---- THE GLINT across each poster, once, on arrival ---- */
		.tt_art::after {
			animation: poster-glint both linear;
			animation-timeline: view();
			animation-range: entry 25% cover 45%;
		}

		@keyframes poster-glint {

			0%,
			25% {
				transform: translateX(-140%);
			}

			100% {
				transform: translateX(140%);
			}
		}

		/* ---- THE DATUM struck across the top of the band ---- */
		.alsolike::after {
			animation: datum-draw both linear;
			animation-timeline: view();
			animation-range: entry 0% entry 70%;
		}

		@keyframes datum-draw {
			0% {
				scale: 0 1;
			}

			100% {
				scale: 1 1;
			}
		}
	}
}


/* ============================================================
   ==============  T H E   n o - r u n w a y   T W I N  =======

   The site's own stamp, set pre-paint in js/deck-prepaint.js for
   reduced motion AND for a stored 'standard' / 'deck' choice.
   The experience selector is not on this page, but a choice made
   anywhere else on the site still stamps the flag here.

   IT DOES MORE WORK HERE THAN ON ANY OTHER PAGE, because the
   thing it collapses is not a runway — it is a film. Read all
   four parts before editing one:

   1. THE FILM IS NOT SAFE AT REST. Every scene animation is
      `fill-mode: both` on a scroll timeline; with no timeline
      resolving, each element parks at its own base state, and
      .flash-bang's base state is a full-screen opaque white
      sheet at z-index 9999. .sky-scene and .buried-blackout are
      the same story. So the three overlays are explicitly
      switched off AND zeroed — killing the animation alone
      makes the page white.

   2. THE RUNWAY COLLAPSES TO ONE SCREEN, not to nothing. The
      pen's h1 lives inside the fixed banner, so hiding the
      banner would take the page's own <h1> with it. One screen
      of the title card — the door shut, the rain still — is the
      right answer: it is the poster for a film this reader has
      told us they do not want played at them.

   3. THE LOOPING AMBIENCE STOPS TOO. Fog drift, the lightning
      cycle, the film grain and the void's pulse are all plain
      time-based `infinite` animations — nothing to do with
      scroll, and every one of them is exactly what a reduced-
      motion reader asked to be spared. The rain canvas is JS and
      is handled at the foot of the page, not here.

   4. THE SCRIPT GOES, and nothing is lost with it. Every line
      of it is aria-hidden and every line is said again in full
      in §01–§03. That is why it was allowed to be decorative.

   5. THE WEATHER STAYS, STILL (2026-08-01). #page has no
      background of its own any more, so .aftermath IS the page's
      background — switching it off would leave the copy sitting
      on the parked film. Its fade is killed and it is pinned
      OPEN; only the drift and the flicker inside it stop. The
      second rain canvas is JS and returns early on
      tbwReducedMotion(), like the film's.
   ============================================================ */
html.no-runway .runway {
	height: 100svh;
}

html.no-runway .aftermath {
	animation: none;
	opacity: 1;
}

html.no-runway .aftermath_fog,
html.no-runway .aftermath_grain {
	animation: none;
}

/* THE SAME COLLAPSE, FOR A BROWSER WITH NO SCROLL TIMELINES (Firefox
   today). It gets no stamp, so the twin above never fires — and every
   scene animation resolves as a 0s time animation parked on its own last
   keyframe, which means .buried-blackout is opaque from the first frame
   and the film is a black rectangle. Nine screens of runway under a black
   rectangle is not a film, it is a fault. One screen of it, and then the
   grey world (which is already visible here — .aftermath only starts
   hidden inside the @supports block in ADDED 8). */
@supports not (animation-timeline: view()) {
	.runway {
		height: 100svh;
	}
}

html.no-runway .script {
	display: none;
}

/* the three overlays: off AND zeroed, in the same rule */
html.no-runway .flash-bang,
html.no-runway .sky-scene,
html.no-runway .buried-blackout {
	animation: none;
	opacity: 0;
}

/* the scrubbed scenes, parked at their opening frame */
html.no-runway .banner-text,
html.no-runway .banner-text h1,
html.no-runway .pull-container,
html.no-runway .door-panel,
html.no-runway .frank,
html.no-runway .grave-opening {
	animation: none;
}

/* the looping ambience */
html.no-runway #fogCanvas,
html.no-runway .lightning,
html.no-runway .grain,
html.no-runway .the-void::after,
html.no-runway .clouds {
	animation: none;
}

/* the pen's h1 is blurred 3px at rest — legible as a mark inside a
   moving storm, and not legible as the only heading on a still page */
html.no-runway .banner-text h1 {
	filter: none;
}


/* ============================================================
   ADDED 10 — THE GRAVE KEEPS ITS SHAPE

   The owner, 2026-08-01: the burial's hole "is entirely based on the
   viewport, so sometimes it's square, sometimes it becomes very
   thin". It was: the pen sizes the opening 12vw wide by 30vh
   tall, which is two unrelated axes, so the shape it settles
   into is whatever the window's aspect ratio happens to be —
   230x324 on a 1920x1080 desktop (1 : 1.4, near square), 47x253
   on a 390x844 phone (1 : 5.4, a letter slot). Neither is a
   grave, and the reader holds on that shape for the whole of the
   blackout's fade.

   THE RATIO IS LOCKED, NOT APPROACHED (the owner, on the first pass
   live: "it looks like the shape of the grave ADJUSTS to be the
   correct aspect ratio rather than ALWAYS being the correct
   aspect ratio — otherwise we lose the 'this is a grave' almost
   immediately"). The first pass fixed only the last frame and
   added a midpoint, so the hole spent the first half of the sink
   morphing out of the window's shape and into a grave. It has to
   BE one from the frame the walls appear.

   IT LOCKS BECAUSE EVERY FRAME IS ONE UNIT. Both dimensions are
   vh at all three stops and every stop is height / 2.3 — a
   3ft x 7ft plot — so linear interpolation between them preserves
   the ratio exactly: lerp(h0,h1) / 2.3 IS lerp(w0,w1) when
   w = h / 2.3 at both ends. No midpoint frame is needed and the
   one the first pass added is gone; there is nothing left to
   drift between.

   WRITTEN AS A WHOLE-KEYFRAME OVERRIDE, NOT AN EDIT, on ADDED 7's
   precedent — a later @keyframes of the same name replaces the
   earlier one entirely, so THE PEN BLOCK IS STILL BYTE-IDENTICAL
   and this is the one place to revert. Every value below that is
   not a width or a height is restated exactly as he wrote it, and
   the three stops are still his three stops.

   THE HEIGHTS, AND WHY 5% IS THE ONE THAT MOVED:
      0%  150vh, his. Invisible — the shadow spread is 0 here, and
          the element paints no background of its own, so only the
          spread ever draws anything.
      5%  100vh → 105vh. THIS IS THE FRAME THAT CARRIES THE FIX.
          His 100vw x 100vh is the whole screen, which is a
          rectangle with no shape of its own; a grave that starts
          as the viewport can only become a grave later. At 105vh
          tall the ends sit just off screen and the side walls are
          on it from the first frame of the sink — on 1920x1080 a
          493px slot of sky between 713px of wall, on 390x844 a
          385px slot in a 390px window. Both read as a hole in the
          ground immediately, which is the whole ask.
    100%  30vh, his, untouched.

   THE WIDTHS ARE NOT CHOICES. 65.22 / 45.65 / 13.04vh are those
   three heights divided by 2.3. Change the ratio and all three
   are recomputed together, or the lock is gone.
   ============================================================ */
@keyframes lower-grave {
	0% {
		/* Start huge, no shadow visible */
		width: 65.22vh;
		height: 150vh;
		box-shadow: 0 0 0 0vmax #0a0604, inset 0 0 0px #000;
		border-radius: 0px;
	}

	5% {
		/* The shadow snaps out slightly past the screen bounds immediately */
		width: 45.65vh;
		height: 105vh;
		box-shadow: 0 0 0 100vmax #110905, inset 0 0 40px #000;
		border-radius: 5px;
	}

	100% {
		/* Shrinks down to a tiny hole in the distance */
		width: 13.04vh;
		height: 30vh;
		box-shadow: 0 0 0 100vmax #060302, inset 0 0 150px #000;
		border-radius: 20px;
		transform: translate(-50%, -65%);
		/* Shift perspective up as we go down */
	}
}
