/*
 * Splice — main stylesheet.
 *
 * LAYOUT ARCHETYPE: "the edit bay".
 *
 * Every surface on this site borrows from the furniture of a non-linear
 * editor: monitor-bezel borders on media panels, a timecode chip in the
 * corner of every card that carries a duration, a persistent scope-green
 * accent standing in for a waveform/vectorscope reading, and a hairline
 * grid that echoes a timeline ruler rather than a generic 12-column layout.
 * None of that is arbitrary chrome — it is how an editor's own tools already
 * look, borrowed wholesale rather than invented.
 *
 * The dark base is not this catalogue's default mood — it is specific to
 * this trade: a grading/edit suite is kept near-black on purpose, because
 * a bright room desensitises the eye to the picture on the monitor. A
 * post-production studio's own site being dark is the one case in this
 * catalogue where "dark theme" is a documented professional convention,
 * not a stylistic default.
 *
 * Distinct from every prior archetype here (draft-sheet, lighting-plot,
 * programme-grid, palette-rail, waterline, bento, promenade).
 */

/* ------------------------------------------------------------------ *
 * 0. Tokens
 * ------------------------------------------------------------------ */
:root {
	--spl-ink:      #0b0c0e;
	--spl-panel:    #15171b;
	--spl-panel-2:  #1c1f24;
	--spl-paper:    #f2f5f4;
	--spl-text-soft:#9aa3a0;
	--spl-text-faint: #5b6360;
	--spl-line:     rgb( 255 255 255 / 10% );
	--spl-line-strong: rgb( 255 255 255 / 20% );

	--spl-mint:     #5cffaa;
	--spl-mint-dim: rgb( 92 255 170 / 14% );
	--spl-tally:    #ff5a36;
	--spl-tally-dim: rgb( 255 90 54 / 16% );

	--spl-ink-rgb:   11 12 14;
	--spl-panel-rgb: 21 23 27;
	--spl-mint-rgb:  92 255 170;

	/* Type. Big Shoulders Display is a condensed industrial face — the same
	   register as a broadcast lower-third or a channel ident, which is the
	   point: headings should read like on-screen graphics, not like a blog.
	   Hanken Grotesk carries body copy. JetBrains Mono is reserved for
	   anything that is a reading off an instrument: timecode, duration,
	   client/year specification, the scope readout. */
	--spl-ff-display: "Big Shoulders Display", "Arial Narrow", sans-serif;
	--spl-ff-body:    "Hanken Grotesk", system-ui, sans-serif;
	--spl-ff-mono:    "JetBrains Mono", ui-monospace, monospace;

	--spl-t-xs:  0.75rem;
	--spl-t-s:   0.875rem;
	--spl-t-m:   1.0625rem;
	--spl-t-l:   1.375rem;
	--spl-t-xl:  1.75rem;
	--spl-t-2xl: 2.5rem;
	--spl-t-3xl: 3.5rem;
	--spl-t-display: clamp( 3rem, 6vw + 1rem, 6.5rem );

	--spl-sp-1: 0.5rem;
	--spl-sp-2: 1rem;
	--spl-sp-3: 1.5rem;
	--spl-sp-4: 2rem;
	--spl-sp-5: 3rem;
	--spl-sp-6: 4rem;
	--spl-sp-7: 6rem;
	--spl-sp-8: 8rem;
	--spl-section-y: clamp( 4rem, 7vw, 9rem );

	--spl-radius: 2px;
	--spl-measure: 66ch;
	--spl-rule-w: 1px;
}

/* ------------------------------------------------------------------ *
 * 1. Reset & base
 * ------------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; color-scheme: dark; }
@media ( prefers-reduced-motion: reduce ) { html { scroll-behavior: auto; } }

body {
	margin: 0;
	overflow-x: hidden;
	background: var( --spl-ink );
	color: var( --spl-paper );
	font-family: var( --spl-ff-body );
	font-size: var( --spl-t-m );
	line-height: 1.6;
	-webkit-font-smoothing: antialiased;
}

img, svg, video, canvas { max-width: 100%; display: block; }
a { color: inherit; }
button { font: inherit; color: inherit; }

.skip-link {
	position: absolute; left: 1rem; top: -60px;
	background: var( --spl-mint ); color: var( --spl-ink );
	padding: 0.75rem 1.25rem; z-index: 1000; transition: top 160ms ease;
	font-family: var( --spl-ff-mono ); font-weight: 700;
}
.skip-link:focus { top: 1rem; }

.screen-reader-text {
	position: absolute !important; width: 1px; height: 1px; overflow: hidden;
	clip: rect( 1px, 1px, 1px, 1px ); white-space: nowrap; border: 0; padding: 0; margin: -1px;
}

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

.container { max-width: 1280px; margin-inline: auto; padding-inline: var( --spl-sp-3 ); }

/* ------------------------------------------------------------------ *
 * 2. Timeline-ruler ground
 *
 * A thin repeating tick pattern along the top of a section, standing in for
 * an NLE's timeline ruler. Cheap (one gradient, no DOM), reused everywhere a
 * section needs to feel like it sits "on the timeline" rather than floating.
 * ------------------------------------------------------------------ */
.ruler {
	background-image: repeating-linear-gradient(
		to right, var( --spl-line ) 0 1px, transparent 1px 24px
	);
	background-size: 24px 100%;
	background-repeat: repeat-x;
	background-position: top;
}

/* ------------------------------------------------------------------ *
 * 3. Typography
 * ------------------------------------------------------------------ */
h1, h2, h3, h4 {
	font-family: var( --spl-ff-display ); font-weight: 700; line-height: 0.98; margin: 0;
	letter-spacing: -0.01em; text-transform: uppercase;
}
h1 { font-size: var( --spl-t-display ); }
h2 { font-size: var( --spl-t-2xl ); }
h3 { font-size: var( --spl-t-xl ); }
h4 { font-size: var( --spl-t-l ); text-transform: none; letter-spacing: 0; }
p { margin: 0 0 1em; }
.prose { max-width: var( --spl-measure ); color: var( --spl-text-soft ); }
.prose a { color: var( --spl-mint ); text-decoration: underline; text-underline-offset: 3px; }
.prose strong { color: var( --spl-paper ); }

/* Slate: this theme's section header, a numbered scene marker rather than a
   dot-and-kicker convention every other card-grid template also ships with.
   Pale oversized mono numeral + a vertical rule + kicker/heading, the way a
   clapperboard reads a scene number before the take. */
.slate { display: flex; gap: var( --spl-sp-3 ); margin-bottom: var( --spl-sp-3 ); }
.slate-num {
	font-family: var( --spl-ff-mono ); font-weight: 500; line-height: 0.85;
	font-size: clamp( 2.25rem, 4vw, 3rem ); color: var( --spl-mint ); opacity: 0.32; flex: none;
}
.slate-rule { flex: none; inline-size: 1px; background: var( --spl-line-strong ); margin-block: 0.15em; }
.slate-text { display: flex; flex-direction: column; justify-content: flex-end; gap: 0.4em; }
.slate-kicker {
	font-family: var( --spl-ff-mono ); font-size: var( --spl-t-xs ); font-weight: 500;
	letter-spacing: 0.14em; text-transform: uppercase; color: var( --spl-text-faint );
}
.slate-text h1, .slate-text h2 { margin: 0; }

.eyebrow {
	display: inline-flex; align-items: center; gap: 0.55em;
	font-family: var( --spl-ff-mono ); font-size: var( --spl-t-xs ); font-weight: 500;
	letter-spacing: 0.14em; text-transform: uppercase; color: var( --spl-mint );
	margin-bottom: var( --spl-sp-2 );
}
/* The dot is a tally light — steady, not blinking, so it reads as a status
   indicator rather than a nag. Motion is reserved for the one place it means
   something: the hero's own REC dot (see .rec-dot). */
.eyebrow::before {
	content: ''; inline-size: 7px; block-size: 7px; border-radius: 50%;
	background: var( --spl-mint ); box-shadow: 0 0 6px 1px var( --spl-mint-dim );
	flex: none;
}

.lede { font-size: var( --spl-t-l ); color: var( --spl-text-soft ); max-width: 46ch; font-family: var( --spl-ff-body ); }
.muted { color: var( --spl-text-soft ); }
.faint { color: var( --spl-text-faint ); }

/* Spec line: a client/year/role/duration readout, set the way a clip's
   metadata actually appears in an NLE bin. */
.spec { display: flex; flex-wrap: wrap; gap: 0.4em 1.4em; font-family: var( --spl-ff-mono ); font-size: var( --spl-t-xs ); }
.spec > div { display: flex; gap: 0.5em; }
.spec dt, .spec .k { color: var( --spl-text-faint ); text-transform: uppercase; letter-spacing: 0.06em; }
.spec dd, .spec .v { margin: 0; color: var( --spl-paper ); }

/* ------------------------------------------------------------------ *
 * 4. Buttons
 * ------------------------------------------------------------------ */
.btn {
	display: inline-flex; align-items: center; justify-content: center; gap: 0.5em;
	font-family: var( --spl-ff-mono ); font-size: var( --spl-t-xs ); letter-spacing: 0.08em;
	text-transform: uppercase; text-decoration: none; white-space: nowrap;
	padding: 1em 1.7em; border-radius: var( --spl-radius ); border: 1px solid transparent;
	cursor: pointer; transition: transform 160ms cubic-bezier( .2,.8,.3,1 ), background 160ms, border-color 160ms, color 160ms;
}
.btn:hover { transform: translateY( -2px ); }
.btn:active { transform: translateY( 0 ); }
.btn--mint { background: var( --spl-mint ); color: var( --spl-ink ); font-weight: 700; }
.btn--mint:hover { background: #7fffbc; }
.btn--tally { background: var( --spl-tally ); color: #fff; font-weight: 700; }
.btn--ghost { background: transparent; border-color: var( --spl-line-strong ); color: var( --spl-paper ); }
.btn--ghost:hover { border-color: var( --spl-mint ); color: var( --spl-mint ); }
.btn[disabled] { opacity: 0.5; cursor: default; transform: none; }

/* ------------------------------------------------------------------ *
 * 5. Header / nav
 * ------------------------------------------------------------------ */
.site-header {
	position: sticky; top: 0; z-index: 60;
	background: rgb( var( --spl-ink-rgb ) / 0.86 );
	-webkit-backdrop-filter: blur( 10px ); backdrop-filter: blur( 10px );
}
.site-header-row {
	display: flex; align-items: center; justify-content: space-between;
	padding-block: var( --spl-sp-2 ); padding-inline: var( --spl-sp-3 );
}

/* The page timeline: scroll position read out as a running programme clock
   rather than a plain progress bar. The whole page is treated as one 8-minute
   reel; the fraction driving the fill/head/timecode is the same
   scrollY/maxScroll figure a bare progress bar would use, just read the way
   an editor reads a timeline instead. Lives inside the sticky header so it
   never needs to guess the header's own height. */
.page-tl {
	display: flex; align-items: center; gap: var( --spl-sp-3 );
	height: 30px; padding-inline: var( --spl-sp-3 );
	border-top: 1px solid var( --spl-line ); border-bottom: 1px solid var( --spl-line );
}
.page-tl-track {
	position: relative; flex: 1; height: 100%;
	background-image: repeating-linear-gradient( to right, var( --spl-line ) 0 1px, transparent 1px 40px );
}
.page-tl-fill { position: absolute; inset-block: 0; left: 0; width: 0%; background: var( --spl-mint-dim ); border-right: 1px solid var( --spl-mint ); }
.page-tl-head { position: absolute; top: 0; bottom: 0; left: 0%; width: 2px; background: var( --spl-mint ); box-shadow: 0 0 6px 1px var( --spl-mint-dim ); }
.page-tl-tc { flex: none; font-family: var( --spl-ff-mono ); font-size: 0.7rem; letter-spacing: 0.04em; color: var( --spl-text-soft ); }
@media ( max-width: 640px ) { .page-tl-track { background-size: 20px 100%; } }
.brand { display: flex; align-items: center; gap: 0.65em; text-decoration: none; min-inline-size: 0; }
.brand-mark { inline-size: 26px; block-size: 26px; flex: none; color: var( --spl-mint ); }
.brand-name {
	font-family: var( --spl-ff-display ); font-size: 1.35rem; letter-spacing: 0.01em; text-transform: uppercase;
	white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
@media ( max-width: 480px ) { .brand-name { font-size: 1.1rem; max-inline-size: 46vw; } }

.nav { display: flex; align-items: center; gap: var( --spl-sp-4 ); }
.nav ul, .nav .nav-list { display: flex; align-items: center; gap: var( --spl-sp-3 ); list-style: none; margin: 0; padding: 0; }
.nav a { text-decoration: none; font-family: var( --spl-ff-mono ); font-size: var( --spl-t-xs ); text-transform: uppercase; letter-spacing: 0.08em; color: var( --spl-text-soft ); }
.nav a:hover, .nav a[aria-current="page"] { color: var( --spl-mint ); }

.menu-toggle { display: none; background: none; border: 1px solid var( --spl-line-strong ); border-radius: var( --spl-radius ); padding: 0.5em 0.7em; }
.menu-toggle span, .menu-toggle::before, .menu-toggle::after { content: ''; display: block; inline-size: 20px; block-size: 1px; background: currentColor; margin: 5px 0; }

@media ( max-width: 900px ) {
	.menu-toggle { display: block; }
	/* height, not `bottom: 0` — backdrop-filter on .site-header establishes a
	   containing block for fixed descendants exactly like `filter` does, so a
	   bottom-anchored panel would resolve against the header's own box and
	   collapse to a sliver. This exact bug has shipped before in this
	   catalogue; viewport units sidestep it entirely. */
	.nav {
		position: fixed; inset-inline: 0; top: 88px;
		height: calc( 100vh - 88px ); height: calc( 100dvh - 88px );
		background: var( --spl-ink ); flex-direction: column; align-items: flex-start;
		padding: var( --spl-sp-4 ); transform: translateX( -100% );
		transition: transform 260ms ease; overflow-y: auto;
	}
	.nav.is-open { transform: translateX( 0 ); }
	.nav ul, .nav .nav-list { flex-direction: column; align-items: flex-start; gap: var( --spl-sp-3 ); width: 100%; }
	.nav a { font-size: var( --spl-t-l ); font-family: var( --spl-ff-display ); text-transform: uppercase; letter-spacing: 0; }
	html, body { overflow-x: hidden; }
}

/* ------------------------------------------------------------------ *
 * 6. Sections
 * ------------------------------------------------------------------ */
.section { padding-block: var( --spl-section-y ); position: relative; }
.section--panel { background: var( --spl-panel ); }
.section--tight { padding-block: var( --spl-sp-6 ); }
.section-head { max-width: 62ch; margin-bottom: var( --spl-sp-5 ); }
.section-head--split { display: flex; align-items: flex-end; justify-content: space-between; gap: var( --spl-sp-4 ); flex-wrap: wrap; max-width: none; }

/* ------------------------------------------------------------------ *
 * 7. Hero — the reel
 * ------------------------------------------------------------------ */
.hero { position: relative; overflow: hidden; padding-block: var( --spl-sp-7 ) var( --spl-sp-6 ); }
.hero h1 { max-width: 16ch; }
.hero .lede { margin-block: var( --spl-sp-3 ) var( --spl-sp-4 ); }
.hero-cta { display: flex; gap: var( --spl-sp-2 ); flex-wrap: wrap; }

/* The hero bench: a viewer (main cut) beside an inspector rail, the two-pane
   layout every NLE actually uses — not a hero image with a paragraph next to
   it. The inspector is real project metadata, not filler copy. */
.hero-bench { display: grid; grid-template-columns: 1fr 260px; gap: var( --spl-sp-6 ); align-items: start; }
@media ( max-width: 980px ) {
	/* The inspector stays AFTER the headline/CTA/video here, not before —
	   metadata is a supporting panel, not the thing a mobile visitor should
	   have to scroll past to reach the actual pitch. */
	.hero-bench { grid-template-columns: 1fr; gap: var( --spl-sp-5 ); }
	.hero-inspector { position: static; }
}

.hero-inspector {
	position: sticky; top: calc( 88px + var( --spl-sp-3 ) );
	background: var( --spl-panel ); border: 1px solid var( --spl-line ); padding: var( --spl-sp-3 );
}
.insp-head {
	display: flex; align-items: center; gap: 0.6em;
	font-family: var( --spl-ff-mono ); font-size: var( --spl-t-xs ); text-transform: uppercase; letter-spacing: 0.12em;
	color: var( --spl-text-faint ); padding-bottom: var( --spl-sp-2 ); border-bottom: 1px solid var( --spl-line );
	margin-bottom: var( --spl-sp-2 );
}
.insp-dot { inline-size: 6px; block-size: 6px; border-radius: 50%; background: var( --spl-mint ); flex: none; }
.insp-fields { margin: 0; display: flex; flex-direction: column; gap: 0.65em; }
.insp-fields > div { display: flex; justify-content: space-between; gap: 1em; font-family: var( --spl-ff-mono ); font-size: var( --spl-t-xs ); }
.insp-fields dt { margin: 0; color: var( --spl-text-faint ); text-transform: uppercase; letter-spacing: 0.04em; }
.insp-fields dd { margin: 0; color: var( --spl-paper ); font-weight: 500; }
.insp-bin { margin-top: var( --spl-sp-3 ); padding-top: var( --spl-sp-3 ); border-top: 1px solid var( --spl-line ); }
.insp-bin-label {
	display: block; font-family: var( --spl-ff-mono ); font-size: 0.65rem; text-transform: uppercase;
	letter-spacing: 0.08em; color: var( --spl-text-faint ); margin-bottom: 0.7em;
}
.insp-bin ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5em; }
.insp-bin li { display: flex; flex-direction: column; padding-block: 0.4em; border-bottom: 1px dashed var( --spl-line ); }
.insp-bin li:last-child { border-bottom: 0; }
.insp-bin a { text-decoration: none; font-size: var( --spl-t-xs ); color: var( --spl-paper ); }
.insp-bin a:hover { color: var( --spl-mint ); }
.insp-bin .insp-bin-disc { font-family: var( --spl-ff-mono ); font-size: 0.65rem; color: var( --spl-text-faint ); text-transform: uppercase; letter-spacing: 0.05em; margin-top: 0.2em; }

/* The monitor: a fixed-aspect frame so there is never layout shift whether
   or not the video has mounted, bordered like an actual broadcast monitor
   bezel rather than a bare <video> tag floating on the page. */
.monitor {
	position: relative; aspect-ratio: 16 / 9; inline-size: 100%;
	background: #000; border: 1px solid var( --spl-line-strong );
	overflow: hidden; margin-top: var( --spl-sp-5 );
}
.monitor video, .monitor img.monitor-poster {
	position: absolute; inset: 0; inline-size: 100%; block-size: 100%; object-fit: cover;
}
.monitor img.monitor-poster { transition: opacity 500ms ease; }
.monitor.is-playing img.monitor-poster { opacity: 0; pointer-events: none; }

/* Corner chrome that reads as camera/monitor HUD: REC indicator top-left,
   timecode readout bottom-left, resolution/format tag top-right. All CSS —
   nothing here is baked into the video, so it stays sharp at any size and
   costs zero bitrate. */
.monitor-hud {
	position: absolute; inset: 0; pointer-events: none;
	font-family: var( --spl-ff-mono ); font-size: var( --spl-t-xs ); letter-spacing: 0.06em;
	color: rgb( 255 255 255 / 0.86 ); text-shadow: 0 1px 3px rgb( 0 0 0 / 0.6 );
}
.monitor-hud .rec {
	position: absolute; top: 14px; left: 16px; display: flex; align-items: center; gap: 0.5em;
	text-transform: uppercase;
}
.rec-dot {
	inline-size: 8px; block-size: 8px; border-radius: 50%; background: var( --spl-tally );
	animation: spl-rec-blink 1.1s steps( 1 ) infinite;
}
@keyframes spl-rec-blink { 50% { opacity: 0.25; } }
.monitor-hud .format-tag {
	position: absolute; top: 14px; right: 16px;
}
.monitor-hud .timecode {
	position: absolute; bottom: 14px; left: 16px;
	background: rgb( 0 0 0 / 0.5 ); padding: 0.2em 0.5em; border-radius: 1px;
}
@media ( prefers-reduced-motion: reduce ) { .rec-dot { animation: none; } }

/* ------------------------------------------------------------------ *
 * 8. The scrub timeline — the signature interaction
 *
 * A real editing-timeline control: the range input's value drives the hero
 * video's currentTime directly (assets/js/fx.js), and the ruler + waveform
 * beneath it are drawn from the same clock. Styled to look like an NLE
 * timeline strip, not a generic HTML5 seek bar.
 * ------------------------------------------------------------------ */
.scrub {
	margin-top: var( --spl-sp-3 ); background: var( --spl-panel );
	border: 1px solid var( --spl-line ); padding: var( --spl-sp-2 ) var( --spl-sp-3 );
}
.scrub-row { display: flex; align-items: center; gap: var( --spl-sp-2 ); }
.scrub-tc {
	font-family: var( --spl-ff-mono ); font-size: var( --spl-t-s ); color: var( --spl-mint );
	min-inline-size: 8.5ch; flex: none;
}
.scrub-play {
	flex: none; inline-size: 34px; block-size: 34px; border-radius: 50%;
	border: 1px solid var( --spl-line-strong ); background: transparent; color: var( --spl-paper );
	display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.scrub-play:hover { border-color: var( --spl-mint ); color: var( --spl-mint ); }
.scrub-track { position: relative; flex: 1; height: 34px; }
.scrub-wave {
	position: absolute; inset: 0; width: 100%; height: 100%;
	opacity: 0.55;
}
.scrub-range {
	position: absolute; inset: 0; width: 100%; height: 100%;
	-webkit-appearance: none; appearance: none; background: transparent; cursor: pointer; margin: 0;
}
.scrub-range::-webkit-slider-runnable-track { height: 34px; background: transparent; }
.scrub-range::-moz-range-track { height: 34px; background: transparent; }
.scrub-range::-webkit-slider-thumb {
	-webkit-appearance: none; appearance: none;
	inline-size: 2px; block-size: 34px; border-radius: 0;
	background: var( --spl-paper ); box-shadow: 0 0 0 3px rgb( 242 245 244 / 0.15 );
	margin-top: 0; cursor: grab;
}
.scrub-range::-moz-range-thumb {
	inline-size: 2px; block-size: 34px; border-radius: 0; border: 0;
	background: var( --spl-paper ); box-shadow: 0 0 0 3px rgb( 242 245 244 / 0.15 ); cursor: grab;
}
.scrub-range:active::-webkit-slider-thumb { cursor: grabbing; }
.scrub-hint { margin-top: 0.5em; font-family: var( --spl-ff-mono ); font-size: 0.7rem; color: var( --spl-text-faint ); letter-spacing: 0.04em; }

/* ------------------------------------------------------------------ *
 * 9. The scope — live vectorscope/waveform reading the playing video
 * ------------------------------------------------------------------ */
.scope-panel {
	display: grid; grid-template-columns: repeat( 2, 1fr ); gap: var( --spl-sp-3 );
}
.scope-box {
	background: #000; border: 1px solid var( --spl-line ); aspect-ratio: 1 / 1;
	position: relative; overflow: hidden;
}
.scope-box canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.scope-box .scope-label {
	position: absolute; top: 8px; left: 10px; font-family: var( --spl-ff-mono );
	font-size: 0.65rem; letter-spacing: 0.1em; text-transform: uppercase; color: var( --spl-mint ); opacity: 0.8;
}
@media ( max-width: 640px ) { .scope-panel { grid-template-columns: 1fr; } }

/* ------------------------------------------------------------------ *
 * 10. Reel cards
 * ------------------------------------------------------------------ */
.reel-grid { display: grid; grid-template-columns: repeat( auto-fit, minmax( 300px, 1fr ) ); gap: var( --spl-sp-4 ); }
.reel-card { background: var( --spl-panel ); border: 1px solid var( --spl-line ); display: flex; flex-direction: column; }
.reel-card a { text-decoration: none; }

/* Every still is dressed as a physical filmstrip frame: perforated top and
   bottom edges (a repeating punched-hole gradient, no image asset needed),
   the way a clip actually looks in an editor's bin rather than a generic
   rounded thumbnail. */
.reel-still {
	position: relative; aspect-ratio: 16 / 10; overflow: hidden; background: #000;
	--sprocket: radial-gradient( circle at 10px 5px, var( --spl-ink ) 4px, transparent 4.6px ) repeat-x;
}
.reel-still::before, .reel-still::after {
	content: ''; position: absolute; inset-inline: 0; block-size: 10px; z-index: 2;
	background: var( --sprocket ); background-size: 20px 10px;
}
.reel-still::before { top: 0; }
.reel-still::after { bottom: 0; }
.reel-still img { inline-size: 100%; block-size: 100%; object-fit: cover; transition: transform 500ms cubic-bezier( .2,.8,.2,1 ); }
.reel-card:hover .reel-still img, .bin-card:hover .reel-still img { transform: scale( 1.045 ); }
/* Timecode chip in the corner of every still — the archetype's signature
   card marking, doing the same job a clip's duration badge does in a bin.
   Inset past the sprocket band above so the two never overlap. */
.reel-still .tc-chip {
	position: absolute; bottom: 16px; right: 8px;
	background: rgb( 0 0 0 / 0.72 ); color: var( --spl-mint );
	font-family: var( --spl-ff-mono ); font-size: 0.7rem; letter-spacing: 0.04em;
	padding: 0.25em 0.55em; border: 1px solid rgb( 92 255 170 / 0.3 );
}
.reel-still .disc-chip {
	position: absolute; top: 16px; left: 8px;
	background: rgb( 0 0 0 / 0.6 ); color: var( --spl-paper );
	font-family: var( --spl-ff-mono ); font-size: 0.65rem; letter-spacing: 0.06em; text-transform: uppercase;
	padding: 0.25em 0.55em;
}
.reel-body { padding: var( --spl-sp-3 ); display: flex; flex-direction: column; gap: var( --spl-sp-1 ); }
.reel-body h3 { font-size: var( --spl-t-l ); }
.reel-client { font-family: var( --spl-ff-mono ); font-size: var( --spl-t-xs ); color: var( --spl-mint ); text-transform: uppercase; letter-spacing: 0.06em; }

/* ------------------------------------------------------------------ *
 * 10b. The bin — a horizontal, snap-scrolling filmstrip
 *
 * Editors browse a bin by scrubbing sideways through clip thumbnails, not by
 * reading a vertical card list — so the homepage's reel teaser scrolls
 * horizontally instead of wrapping into another responsive grid. The full
 * "/work/" archive stays a filterable grid (pagination needs that), but
 * shares the same perforated-still styling above.
 * ------------------------------------------------------------------ */
.bin {
	position: relative; margin-inline: calc( var( --spl-sp-3 ) * -1 ); padding-inline: var( --spl-sp-3 );
	overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x proximity;
	scrollbar-width: thin; scrollbar-color: var( --spl-mint-dim ) transparent;
	-webkit-mask-image: linear-gradient( to right, transparent 0, black var( --spl-sp-3 ), black calc( 100% - var( --spl-sp-3 ) ), transparent 100% );
	mask-image: linear-gradient( to right, transparent 0, black var( --spl-sp-3 ), black calc( 100% - var( --spl-sp-3 ) ), transparent 100% );
}
.bin-track { display: flex; gap: var( --spl-sp-4 ); padding-block: 0.25rem 1.25rem; }
.bin-card {
	flex: 0 0 300px; scroll-snap-align: start;
	background: var( --spl-panel ); border: 1px solid var( --spl-line ); display: flex; flex-direction: column;
}
.bin-card a { text-decoration: none; }
.bin-hint {
	display: flex; align-items: center; gap: 0.5em; margin-top: -0.5rem;
	font-family: var( --spl-ff-mono ); font-size: 0.7rem; letter-spacing: 0.04em; color: var( --spl-text-faint );
}
.bin-hint svg { inline-size: 26px; block-size: 8px; flex: none; opacity: 0.7; }

/* ------------------------------------------------------------------ *
 * 11. Discipline filter pills (archive)
 * ------------------------------------------------------------------ */
.filter-row { display: flex; flex-wrap: wrap; gap: 0.6em; margin-bottom: var( --spl-sp-4 ); }
.filter-pill {
	font-family: var( --spl-ff-mono ); font-size: var( --spl-t-xs ); text-transform: uppercase; letter-spacing: 0.06em;
	padding: 0.5em 1em; border: 1px solid var( --spl-line-strong ); border-radius: 999px;
	text-decoration: none; color: var( --spl-text-soft );
}
.filter-pill:hover { border-color: var( --spl-mint ); color: var( --spl-mint ); }
.filter-pill[aria-current="page"], .filter-pill.is-active {
	background: var( --spl-mint ); border-color: var( --spl-mint ); color: var( --spl-ink ); font-weight: 700;
}

/* ------------------------------------------------------------------ *
 * 12. Services
 * ------------------------------------------------------------------ */
.service-grid { display: grid; grid-template-columns: repeat( auto-fit, minmax( 240px, 1fr ) ); gap: var( --spl-sp-4 ); }
.service-card { padding: var( --spl-sp-3 ); border-top: 2px solid var( --spl-mint ); background: var( --spl-panel ); }
.service-card h3 { font-size: var( --spl-t-l ); margin-bottom: 0.4em; }

.quote-grid { display: grid; grid-template-columns: repeat( auto-fit, minmax( 280px, 1fr ) ); gap: var( --spl-sp-4 ); }
.quote { padding: var( --spl-sp-4 ); background: var( --spl-panel ); border: 1px solid var( --spl-line ); }
.quote p { font-family: var( --spl-ff-display ); font-size: var( --spl-t-l ); line-height: 1.25; text-transform: none; }
.quote .who { font-family: var( --spl-ff-mono ); font-size: var( --spl-t-xs ); color: var( --spl-text-faint ); margin-top: 0.8em; }

/* ------------------------------------------------------------------ *
 * 13. CTA band
 * ------------------------------------------------------------------ */
.cta-band { background: var( --spl-panel-2 ); padding-block: var( --spl-sp-7 ); border-top: 1px solid var( --spl-line ); border-bottom: 1px solid var( --spl-line ); }
.cta-band h2 { max-width: 22ch; }
.cta-band .lede { color: var( --spl-text-soft ); }

/* ------------------------------------------------------------------ *
 * 14. Forms
 * ------------------------------------------------------------------ */
.field { display: flex; flex-direction: column; gap: 0.4em; margin-bottom: var( --spl-sp-3 ); }
.field label { font-family: var( --spl-ff-mono ); font-size: var( --spl-t-xs ); text-transform: uppercase; letter-spacing: 0.06em; color: var( --spl-text-soft ); }
.field input, .field select, .field textarea {
	font: inherit; background: var( --spl-panel ); color: var( --spl-paper );
	border: 1px solid var( --spl-line-strong ); border-radius: var( --spl-radius ); padding: 0.8em 0.9em;
}
.field input:focus, .field textarea:focus, .field select:focus { border-color: var( --spl-mint ); outline: none; }
.field--hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: var( --spl-sp-3 ); }
@media ( max-width: 640px ) { .form-row { grid-template-columns: 1fr; } }
.form-note { font-size: var( --spl-t-s ); margin-top: var( --spl-sp-2 ); font-family: var( --spl-ff-mono ); }
.form-note.is-ok { color: var( --spl-mint ); }
.form-note.is-error { color: var( --spl-tally ); }

/* ------------------------------------------------------------------ *
 * 15. Two-column split
 * ------------------------------------------------------------------ */
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: var( --spl-sp-6 ); align-items: start; }
@media ( max-width: 860px ) { .two-col { grid-template-columns: 1fr; gap: var( --spl-sp-4 ); } }

/* ------------------------------------------------------------------ *
 * 16. Journal
 * ------------------------------------------------------------------ */
.post-grid { display: grid; grid-template-columns: repeat( auto-fit, minmax( 260px, 1fr ) ); gap: var( --spl-sp-4 ); }
.post-card { background: var( --spl-panel ); border: 1px solid var( --spl-line ); padding: var( --spl-sp-3 ); }
.post-card h3 { font-size: var( --spl-t-l ); margin-bottom: 0.3em; text-transform: none; }
.post-card a { text-decoration: none; }
.post-meta { display: flex; gap: 0.9em; flex-wrap: wrap; font-family: var( --spl-ff-mono ); font-size: var( --spl-t-xs ); color: var( --spl-text-faint ); }

/* ------------------------------------------------------------------ *
 * 17. Footer
 * ------------------------------------------------------------------ */
.site-foot { border-top: 1px solid var( --spl-line ); padding-block: var( --spl-sp-6 ) var( --spl-sp-4 ); background: var( --spl-panel ); }
.foot-grid { display: grid; grid-template-columns: 2fr repeat( 3, 1fr ); gap: var( --spl-sp-4 ); }
@media ( max-width: 780px ) { .foot-grid { grid-template-columns: 1fr 1fr; } }
.foot-col h4 { font-family: var( --spl-ff-mono ); font-size: var( --spl-t-xs ); text-transform: uppercase; letter-spacing: 0.08em; color: var( --spl-text-faint ); margin-bottom: var( --spl-sp-2 ); }
.foot-col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5em; }
.foot-col a { text-decoration: none; color: var( --spl-text-soft ); }
.foot-col a:hover { color: var( --spl-mint ); }
.foot-bottom { margin-top: var( --spl-sp-5 ); padding-top: var( --spl-sp-3 ); border-top: 1px solid var( --spl-line ); display: flex; justify-content: space-between; flex-wrap: wrap; gap: var( --spl-sp-2 ); color: var( --spl-text-faint ); font-family: var( --spl-ff-mono ); font-size: var( --spl-t-xs ); }

/* ------------------------------------------------------------------ *
 * 18. Breadcrumbs, pagination, comments
 * ------------------------------------------------------------------ */
.crumbs { font-family: var( --spl-ff-mono ); font-size: var( --spl-t-xs ); color: var( --spl-text-faint ); margin-bottom: var( --spl-sp-3 ); }
.crumbs ol, .crumbs__list { list-style: none; display: flex; gap: 0.5em; margin: 0; padding: 0; flex-wrap: wrap; }
.crumbs li + li::before { content: '/'; margin-right: 0.5em; }
.crumbs a { color: var( --spl-text-soft ); text-decoration: none; }
.crumbs a:hover { color: var( --spl-mint ); }

.pagination { display: flex; gap: 0.5em; margin-top: var( --spl-sp-5 ); }
.pagination .page-numbers { display: inline-flex; align-items: center; justify-content: center; min-inline-size: 2.4em; min-block-size: 2.4em; border: 1px solid var( --spl-line-strong ); text-decoration: none; font-family: var( --spl-ff-mono ); font-size: var( --spl-t-xs ); color: var( --spl-paper ); }
.pagination .page-numbers.current { background: var( --spl-mint ); color: var( --spl-ink ); border-color: var( --spl-mint ); }
.pagination a.page-numbers:hover { border-color: var( --spl-mint ); color: var( --spl-mint ); }

.comments { margin-top: var( --spl-sp-6 ); }
.comment-list { list-style: none; margin: 0; padding: 0; }
.comment-body { padding-block: var( --spl-sp-3 ); border-bottom: 1px solid var( --spl-line ); }
.comment-meta { font-family: var( --spl-ff-mono ); font-size: var( --spl-t-xs ); color: var( --spl-text-faint ); }
.comment-respond { margin-top: var( --spl-sp-4 ); }
.reply a { font-family: var( --spl-ff-mono ); font-size: var( --spl-t-xs ); color: var( --spl-mint ); text-decoration: none; }

/* ------------------------------------------------------------------ *
 * 19. Reveal-on-scroll
 *
 * threshold:0 + a scroll/resize sweep fallback, not a fractional threshold —
 * a fractional IO threshold can be skipped entirely by an instant jump
 * (anchor link, restored scroll position, a video resizing the element after
 * observe starts) and the element then never reveals. Learned the hard way
 * in an earlier theme in this catalogue; not repeating it here.
 * ------------------------------------------------------------------ */
[data-reveal] { opacity: 0; transition: opacity 640ms ease, transform 640ms cubic-bezier( .2,.8,.2,1 ); }
[data-reveal="up"] { transform: translate3d( 0, 1.4rem, 0 ); }
[data-reveal="left"] { transform: translate3d( -1.3rem, 0, 0 ); }
[data-reveal="right"] { transform: translate3d( 1.3rem, 0, 0 ); }
[data-reveal].is-in { opacity: 1; transform: none; }
@media ( prefers-reduced-motion: reduce ) {
	[data-reveal] { opacity: 1; transform: none; transition: none; }
}
.no-js [data-reveal] { opacity: 1 !important; transform: none !important; }

/* ------------------------------------------------------------------ *
 * 20. Section transition overlay (video-clip wipe)
 * ------------------------------------------------------------------ */
.transition-fx {
	position: fixed; inset: 0; z-index: 200; pointer-events: none;
	opacity: 0; mix-blend-mode: screen;
}
.transition-fx video { width: 100%; height: 100%; object-fit: cover; }
.transition-fx.is-active { opacity: 1; }

/* ------------------------------------------------------------------ *
 * 21. 404 / search
 * ------------------------------------------------------------------ */
.error-404 { text-align: center; padding-block: var( --spl-sp-8 ); }
.search-form { display: flex; gap: 0.5em; max-inline-size: 480px; }
.search-form input[type="search"] { flex: 1; }

@media ( max-width: 640px ) {
	.section { padding-block: var( --spl-sp-5 ); }
	.hero { padding-block: var( --spl-sp-5 ) var( --spl-sp-4 ); }
}
