/* AI Theater: the public pages (page() in src/views/layout.ts), after
   base.css. No CSS nesting: old smart TV browsers ignore a nested rule,
   with no error. */

/* ---------- Header ---------- */

.site-header {
	position: sticky;
	top: 0;
	z-index: 50;
	display: flex;
	align-items: center;
	gap: clamp(1rem, 3vw, 2.5rem);
	padding: 0.9rem var(--gutter);
	background: linear-gradient(
		to bottom,
		rgba(8, 9, 12, 0.96),
		rgba(8, 9, 12, 0.72) 70%,
		transparent
	);
	backdrop-filter: blur(10px);
}

.brand-name {
	font-size: 1.05rem;
}

.site-nav {
	display: flex;
	gap: clamp(0.75rem, 2vw, 1.5rem);
	font-size: 0.95rem;
	color: var(--text-dim);
}
.site-nav a:hover {
	color: var(--text);
}

.search {
	margin-left: auto;
}
.search input::placeholder {
	color: var(--text-dim);
}

/* ---------- Hero ---------- */

/* The slides share one grid cell, so the hero is as tall as the slide that
   shows. A slide that is not shown is `hidden` (public/hero.js). */
.hero {
	position: relative;
}
.hero-slides {
	display: grid;
}
.hero-slide {
	grid-area: 1 / 1;
	position: relative;
	min-height: clamp(380px, 56vh, 620px);
	display: flex;
	align-items: flex-end;
}
.hero-slide.is-shown {
	z-index: 1;
}
.hero-slide[hidden] {
	display: none;
}
.hero-art {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.hero-scrim {
	position: absolute;
	inset: 0;
	background:
		linear-gradient(
			to top,
			var(--bg) 2%,
			rgba(8, 9, 12, 0.35) 55%,
			rgba(8, 9, 12, 0.7)
		),
		linear-gradient(to right, rgba(8, 9, 12, 0.92) 8%, transparent 62%);
}
.hero-copy {
	position: relative;
	padding: 0 var(--gutter) clamp(2rem, 5vw, 4rem);
	max-width: min(680px, 90vw);
}
.hero-eyebrow {
	margin: 0 0 0.5rem;
	font-size: 0.75rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--accent);
}
.hero-title {
	margin: 0 0 0.6rem;
	font-size: clamp(2rem, 5vw, 3.6rem);
	line-height: 1.05;
	letter-spacing: -0.02em;
}
.hero-meta {
	margin: 0 0 0.75rem;
	color: var(--text-dim);
	font-size: 0.95rem;
}
.hero-blurb {
	margin: 0 0 1.4rem;
	color: #d6dae4;
}
.hero-actions {
	display: flex;
	gap: 0.7rem;
	flex-wrap: wrap;
}

/* The channel guide under the billboard, as a 1990s TV listing. Its window
   shows a row and a quarter. The rows scroll up under its top edge, the
   billboard's bottom border (public/hero.js). Each column keeps its width,
   and a long name is cut. */
.hero-guide {
	--guide-row: 2.75rem;
	--guide-blue: #0d1f7a;
	--guide-line: #3550d4;
	--guide-gold: #ffd84a;
	display: flex;
	gap: 0.5rem;
	align-items: stretch;
	padding: 0 var(--gutter);
}
.hero-guide[hidden] {
	display: none;
}
/* `clip`, not only `hidden`: the window is then no scroll box, so a focused
   row cannot scroll it behind the transform of public/hero.js. */
.guide-window {
	position: relative;
	flex: 1;
	min-width: 0;
	height: calc(var(--guide-row) * 1.25 + 4px);
	overflow: hidden;
	overflow: clip;
	border: 2px solid var(--guide-line);
	border-radius: 4px;
	background: var(--guide-blue);
}
/* Scan lines, for the look. */
.guide-window::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: repeating-linear-gradient(
		to bottom,
		rgba(0, 0, 0, 0.18) 0 1px,
		transparent 1px 3px
	);
}
/* A held guide looks like a VCR's pause (public/hero.js sets is-held): gray,
   with heavier scan lines, a shake as it stops and a band of static that
   rolls down. Each moves by transform alone, on the compositor. */
.guide-window {
	transition: filter 0.3s;
}
.hero-guide.is-held .guide-window {
	filter: grayscale(0.9) brightness(0.8);
}
.hero-guide.is-held .guide-window::after {
	background: repeating-linear-gradient(
		to bottom,
		rgba(0, 0, 0, 0.4) 0 1px,
		transparent 1px 3px
	);
}
.guide-window::before {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	z-index: 1;
	height: 45%;
	pointer-events: none;
	visibility: hidden;
	background:
		repeating-linear-gradient(
			to bottom,
			rgba(255, 255, 255, 0.45) 0 1px,
			transparent 1px 3px
		),
		linear-gradient(
			to bottom,
			transparent,
			rgba(255, 255, 255, 0.22),
			transparent
		);
	-webkit-mask-image: linear-gradient(
		to bottom,
		transparent,
		#000 35% 65%,
		transparent
	);
	mask-image: linear-gradient(
		to bottom,
		transparent,
		#000 35% 65%,
		transparent
	);
}
.hero-guide.is-held .guide-window::before {
	visibility: visible;
	animation: guide-static 2.8s linear infinite;
}
.hero-guide.is-held .guide-list {
	animation: guide-shake 0.3s steps(1);
}
@keyframes guide-static {
	0% {
		transform: translateY(-100%);
	}
	60%,
	100% {
		transform: translateY(225%);
	}
}
@keyframes guide-shake {
	0% {
		translate: 4px 0;
	}
	25% {
		translate: -3px 1px;
	}
	50% {
		translate: 2px 0;
	}
	75% {
		translate: -1px 0;
	}
	100% {
		translate: 0;
	}
}
.guide-list {
	margin: 0;
	padding: 0;
	list-style: none;
	will-change: transform;
}
.guide-row button {
	display: grid;
	grid-template-columns: 4.5rem minmax(0, 1fr) 8.25rem 7.5rem 5rem;
	width: 100%;
	height: var(--guide-row);
	padding: 0;
	border: 0;
	border-bottom: 1px solid var(--guide-line);
	background: none;
	color: #fff;
	cursor: pointer;
	font:
		700 1rem/var(--guide-row) ui-monospace,
		"Cascadia Mono",
		Consolas,
		"Courier New",
		monospace;
	letter-spacing: 0.04em;
	text-align: left;
	text-transform: uppercase;
}
.guide-row button:hover {
	background: #1a32a8;
}
/* Inside the row, since the window clips anything outside it. */
.guide-row button:focus-visible {
	outline-color: var(--guide-gold);
	outline-offset: -3px;
}
.guide-row button > span {
	padding: 0 0.75rem;
	border-right: 1px solid var(--guide-line);
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}
.guide-row button > span:last-child {
	border-right: 0;
	text-align: center;
}
/* A doodle in place of a length or a rating (DOODLES in src/views/hero.ts). */
.guide-row button > span.is-icon {
	text-align: center;
	font-size: 1.25em;
}
.guide-channel {
	color: var(--guide-gold);
}
.guide-arrows {
	display: grid;
	grid-template-rows: 1fr 1fr;
	gap: 3px;
}
/* ▲ and ▼, in the guide's colors. */
.guide-key {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.75rem;
	padding: 0;
	border: 2px solid var(--guide-line);
	border-radius: 4px;
	background: var(--guide-blue);
	color: var(--guide-gold);
	font-size: 0.8rem;
	line-height: 1;
	cursor: pointer;
}
.guide-key:hover {
	background: #1a32a8;
}
/* The pause key, as a VCR's button: wide, silver and raised, with a black
   glyph. It sinks when pressed. */
.guide-pause {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	align-self: center;
	width: 4.5rem;
	height: 2.25rem;
	padding: 0;
	border: 1px solid #5d626b;
	border-radius: 3px;
	color: #15171a;
	cursor: pointer;
	background: linear-gradient(
		to bottom,
		#f5f6f8,
		#d3d6db 48%,
		#b7bbc2 52%,
		#dfe2e6
	);
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.9),
		inset 0 -2px 0 rgba(0, 0, 0, 0.2),
		0 2px 0 #2a2d33;
}
.guide-pause:hover {
	filter: brightness(1.06);
}
.guide-pause:active {
	transform: translateY(2px);
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.7),
		inset 0 -1px 0 rgba(0, 0, 0, 0.2);
}
.guide-pause svg {
	width: 14px;
	height: 16px;
}
.guide-pause .glyph-play,
.guide-pause.is-stopped .glyph-pause {
	display: none;
}
.guide-pause.is-stopped .glyph-play {
	display: block;
}
/* A phone: the type as a short code, no length, and the pause key centered
   under the guide, so the names get the room. */
@media (max-width: 720px) {
	.hero-guide {
		--guide-row: 2.4rem;
		display: grid;
		grid-template-columns: minmax(0, 1fr) auto;
		gap: 0.35rem;
	}
	.guide-row button {
		grid-template-columns: 2.1rem minmax(0, 1fr) 2.8rem 2.8rem;
		font-size: 0.75rem;
		letter-spacing: 0;
	}
	.guide-row button > span {
		padding: 0 0.25rem;
	}
	.guide-type {
		font-size: 0;
	}
	.guide-type::after {
		content: attr(data-short);
		font-size: 0.75rem;
	}
	.guide-length {
		display: none;
	}
	.guide-key {
		width: 2.25rem;
	}
	.guide-pause {
		grid-column: 1 / -1;
		justify-self: center;
		height: 2rem;
	}
}


/* ---------- Rows ---------- */

.rows {
	padding: clamp(1.5rem, 4vw, 2.5rem) 0 4rem;
	display: flex;
	flex-direction: column;
	gap: var(--row-gap);
}
.row {
	position: relative;
}

.row-heading {
	display: flex;
	align-items: baseline;
	gap: 0.75rem;
	padding: 0 var(--gutter) 0.7rem;
}
.row-heading h2 {
	margin: 0;
	font-size: clamp(1.05rem, 2vw, 1.4rem);
	letter-spacing: -0.01em;
}
.row-more {
	font-size: 0.82rem;
	color: var(--text-dim);
	opacity: 0;
	transition: opacity 0.15s;
}
a.row-heading:hover .row-more {
	opacity: 1;
}
.row-description {
	margin: -0.4rem 0 0.6rem;
	padding: 0 var(--gutter);
	color: var(--text-dim);
	font-size: 0.88rem;
}

.row-track {
	display: flex;
	gap: 0.75rem;
	padding: 0.25rem var(--gutter) 1rem;
	overflow-x: auto;
	scroll-snap-type: x proximity;
	/* Without this the snap point sits at the track's content edge, so a row that
     overflows starts scrolled by the gutter and its cards sit flush against the
     viewport while the heading above keeps its margin. */
	scroll-padding-inline: var(--gutter);
	scrollbar-width: thin;
	scrollbar-color: var(--line) transparent;
}
.row-track::-webkit-scrollbar {
	height: 6px;
}
.row-track::-webkit-scrollbar-thumb {
	background: var(--line);
	border-radius: 99px;
}

/* ---------- Cards ---------- */

.card {
	flex: 0 0 var(--card-width);
	scroll-snap-align: start;
	transition: transform 0.18s ease;
}
.card:hover,
.card:focus-visible {
	transform: scale(1.04);
	z-index: 2;
}

.card-art {
	position: relative;
	aspect-ratio: 16 / 9;
	border-radius: var(--radius);
	overflow: hidden;
	background: var(--bg-raised);
	border: 1px solid var(--line);
}
.card-art img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.card-art-empty {
	width: 100%;
	height: 100%;
	background: linear-gradient(135deg, #1b1e27, #0d0f14);
}

.card-duration,
.card-source {
	position: absolute;
	bottom: 0.45rem;
	padding: 0.15rem 0.4rem;
	border-radius: 4px;
	background: rgba(0, 0, 0, 0.78);
	font-size: 0.7rem;
	font-weight: 600;
	letter-spacing: 0.02em;
}
.card-duration {
	right: 0.45rem;
}
.card-series {
	color: var(--accent);
}
.card-source {
	left: 0.45rem;
	color: var(--text-dim);
}

.card-body {
	padding: 0.55rem 0.15rem 0;
}
.card-title {
	margin: 0;
	font-size: 0.92rem;
	font-weight: 600;
	line-height: 1.3;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
.card-meta {
	margin: 0.2rem 0 0;
	color: var(--text-dim);
	font-size: 0.78rem;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* ---------- Grid and generic pages ---------- */

.grid {
	display: grid;
	gap: 1.25rem 0.9rem;
	grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
}
.grid .card {
	flex: initial;
}

.page {
	padding: clamp(1.5rem, 4vw, 3rem) var(--gutter) 5rem;
	max-width: 1500px;
	margin: 0 auto;
}
.page h1 {
	margin: 0 0 0.5rem;
	font-size: clamp(1.6rem, 4vw, 2.5rem);
	letter-spacing: -0.02em;
}
.lede {
	margin: 0 0 1.25rem;
	color: var(--text-dim);
	max-width: 60ch;
}
.count {
	margin: 0 0 1.25rem;
	color: var(--text-dim);
	font-size: 0.88rem;
}
.empty {
	color: var(--text-dim);
}
.empty-state {
	padding: 6rem var(--gutter);
	text-align: center;
}

.prose {
	max-width: 70ch;
}
.prose h2 {
	margin: 2rem 0 0.6rem;
	font-size: 1.2rem;
}
.prose p,
.prose li {
	color: #d6dae4;
}
.prose ul {
	padding-left: 1.2rem;
}
.prose li {
	margin-bottom: 0.4rem;
}
.prose a {
	color: var(--accent);
	text-decoration: underline;
	text-underline-offset: 2px;
}
.prose code {
	background: var(--bg-raised);
	padding: 0.1rem 0.35rem;
	border-radius: 4px;
	font-size: 0.88em;
}

.chip-list {
	list-style: none;
	margin: 0 0 1.5rem;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}
.chip {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.45rem 0.9rem;
	border: 1px solid var(--line);
	border-radius: 999px;
	background: var(--bg-raised);
	font-size: 0.9rem;
}
.chip:hover {
	background: var(--bg-hover);
}
.chip span {
	color: var(--text-dim);
	font-size: 0.78rem;
}
.browse-group h2 {
	font-size: 1.05rem;
	margin: 0 0 0.6rem;
}


.creator-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 0.5rem;
	grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}
.creator-list a {
	display: flex;
	justify-content: space-between;
	gap: 1rem;
	align-items: center;
	padding: 0.8rem 1rem;
	border: 1px solid var(--line);
	border-radius: 8px;
	background: var(--bg-raised);
}
.creator-list a:hover {
	background: var(--bg-hover);
}
.creator-count {
	color: var(--text-dim);
	font-size: 0.82rem;
}
.creator-header {
	display: flex;
	align-items: center;
	gap: 1rem;
	flex-wrap: wrap;
	margin-bottom: 1rem;
}

/* ---------- Details: everything about one film ---------- */

/* The film's stills fill the hero, one after another (public/backdrop.js),
   with the copy over them. Only images sit under the copy, never a player:
   YouTube's embed rules forbid any element in front of a player. */
/* The backdrop clips its drifting stills. The hero itself does not clip, so
   the playlist menu can open over the page below it. */
.details-hero {
	position: relative;
	isolation: isolate;
	display: flex;
	align-items: flex-end;
	min-height: clamp(440px, 72vh, 760px);
	padding: clamp(5rem, 14vh, 9rem) var(--gutter) clamp(1.75rem, 4vw, 3rem);
}
.backdrop {
	position: absolute;
	inset: 0;
	z-index: -2;
	overflow: hidden;
	background: linear-gradient(135deg, #1b1e27, #0d0f14);
}
.backdrop-frame {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0;
	transition: opacity 1.4s ease;
	/* A slow drift on every still, so a fade never meets a jump in scale. */
	animation: backdrop-drift 24s ease-in-out infinite alternate;
}
.backdrop-frame.is-shown {
	opacity: 1;
}
@keyframes backdrop-drift {
	from {
		transform: scale(1);
	}
	to {
		transform: scale(1.08) translateX(-1.5%);
	}
}
.backdrop-scrim {
	position: absolute;
	inset: 0;
	z-index: -1;
	background:
		linear-gradient(
			to top,
			var(--bg) 2%,
			rgba(8, 9, 12, 0.35) 55%,
			rgba(8, 9, 12, 0.55)
		),
		linear-gradient(
			to right,
			rgba(8, 9, 12, 0.92) 10%,
			rgba(8, 9, 12, 0.5) 45%,
			transparent 75%
		);
}

.details-copy {
	min-width: 0;
	max-width: min(680px, 100%);
}
.details-title {
	margin: 0 0 0.5rem;
	font-size: clamp(1.6rem, 3.4vw, 2.6rem);
	line-height: 1.08;
	letter-spacing: -0.02em;
}
.details-meta {
	margin: 0 0 0.35rem;
	color: var(--text-dim);
	font-size: 0.92rem;
}
.details-creator {
	margin: 0 0 1rem;
	font-size: 0.95rem;
}
.details-creator a {
	border-bottom: 1px solid var(--line);
}
.details-creator a:hover {
	border-bottom-color: var(--accent);
}
.details-guide {
	margin: -0.5rem 0 1rem;
	font-size: 0.9rem;
	color: #d6dae4;
	max-width: 56ch;
}
.details-guide-also {
	display: block;
	color: var(--text-dim);
	font-size: 0.85rem;
}
.details-blurb {
	margin: 0 0 1.5rem;
	color: #d6dae4;
	max-width: 56ch;
}
.details-actions {
	display: flex;
	gap: 0.7rem;
	flex-wrap: wrap;
}

.details-body {
	max-width: 1500px;
	margin: 0 auto;
	padding: 0 var(--gutter) 2rem;
}

/* The title page: one centered column, and the hero's copy lined up with
   it. The hero still bleeds to the edges. 100% here is the page's width. */
.details-film {
	max-width: calc(var(--film-column) + 2 * var(--gutter));
	padding-top: clamp(1.25rem, 3vw, 2rem);
}
.details-film-hero {
	padding-left: max(var(--gutter), calc((100% - var(--film-column)) / 2));
	padding-right: max(var(--gutter), calc((100% - var(--film-column)) / 2));
}
.details-film .description,
.details-film .source-note,
.details-film .curator-note {
	max-width: none;
}

/* The film's preview. Nothing sits over the player and nothing crops it,
   not even rounded corners: YouTube's embed rules. */
.film-preview {
	margin: 0 0 2.5rem;
}
.film-preview h2 {
	margin: 0 0 0.25rem;
	font-size: clamp(1.05rem, 2vw, 1.4rem);
}
.film-preview-note {
	margin: 0 0 0.9rem;
	color: var(--text-dim);
	font-size: 0.9rem;
}
.film-preview-note a {
	color: var(--text);
	text-decoration: underline;
	text-decoration-color: var(--line);
	text-underline-offset: 2px;
}
.film-preview-note a:hover {
	text-decoration-color: var(--accent);
}
.details-player {
	aspect-ratio: 16 / 9;
	background: #000;
}
.details-player iframe {
	width: 100%;
	height: 100%;
	border: 0;
	display: block;
}

/* The public pages take part in cross-document view transitions: a card
   grows into the page it opens (public/transitions.js), and the rest of the
   page crossfades. Both pages must opt in. Only the public pages load this
   file, so the admin does not. A visitor who asks for reduced motion gets
   plain page loads. */
@media (prefers-reduced-motion: no-preference) {
	@view-transition {
		navigation: auto;
	}
}

/* The card-to-details transition (public/transitions.js, and the opt-in
   above). The hero's backdrop is the "poster" that a card's image grows
   into. The scrim, the copy and the site header have names of their own, so
   they stay painted above the growing poster: a named element draws above
   the rest of the page until the transition ends. */
.details-hero .backdrop {
	view-transition-name: poster;
}
.details-hero .backdrop-scrim {
	view-transition-name: poster-scrim;
}
.details-hero .details-copy {
	view-transition-name: poster-copy;
}
.site-header {
	view-transition-name: site-header;
}
::view-transition-group(poster) {
	animation-duration: 0.45s;
	animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1);
}
/* A card is 16:9 and the hero is wider. Crop each picture to the box as it grows, instead of stretching it. */
::view-transition-old(poster),
::view-transition-new(poster) {
	height: 100%;
	object-fit: cover;
}
::view-transition-image-pair(poster) {
	overflow: clip;
}
/* On Back, the hero's copy and scrim leave fast, so the old title does not ride on the shrinking poster. */
::view-transition-old(poster-copy),
::view-transition-old(poster-scrim) {
	animation-duration: 0.12s;
}

/* An episode's series and its neighbours, above the title on the details and watch pages. */
.episode-nav {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem;
	margin: 0 0 0.6rem;
	font-size: 0.9rem;
}
.episode-series {
	font-weight: 600;
	color: var(--accent);
}
.episode-place {
	color: var(--text-dim);
	font-size: 0.8rem;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}
.series-season {
	margin: 2rem 0;
}
.series-season h2 {
	font-size: clamp(1.05rem, 2vw, 1.4rem);
	margin: 0 0 0.9rem;
}
/* The wrapper, not the row: .rows is a flex column, and auto margins on a flex
   item shrink it to its content width instead of centring it at full width. */
.details .rows {
	max-width: 1500px;
	margin: 0 auto;
}
/* The title page's shelf keeps to its column. */
.details-film + .rows {
	max-width: calc(var(--film-column) + 2 * var(--gutter));
}

/* The content guide's tiers, explained on the About page. The badges are in base.css. */
.guide-tiers {
	display: grid;
	grid-template-columns: max-content 1fr;
	gap: 0.5rem 1rem;
	margin: 1rem 0;
}
.guide-tiers dt {
	font-weight: 600;
}
.guide-tiers dd {
	margin: 0;
	color: var(--text-dim);
}
@media (max-width: 520px) {
	.guide-tiers {
		grid-template-columns: 1fr;
		gap: 0.2rem;
	}
	.guide-tiers dd {
		margin-bottom: 0.6rem;
	}
}

/* ---------- Watch: the film, filling the viewport ---------- */

body.watching {
	background: #000;
}

/* The bar sits above the player, never over it: YouTube's embed rules
   forbid any element in front of a player (Required Minimum Functionality,
   "Overlays and frames"). The screen keeps the bar's height as padding, so
   the bar can turn fixed once the film is scrolled away with no jump. */
.watch {
	--watch-bar-h: 3.75rem;
}
.watch-screen {
	position: relative;
	display: flex;
	flex-direction: column;
	padding-top: var(--watch-bar-h);
	/* svh, not vh: on a phone vh counts the space under the browser's own
     toolbars, so the film would run off the bottom of the screen. The few
     rems taken off leave the top of the details showing, which is the hint
     that there is more below. */
	height: 100vh;
	height: calc(100svh - 3.5rem);
	min-height: 55vh;
}

.watch-bar {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	z-index: 60;
	height: var(--watch-bar-h);
	display: flex;
	align-items: center;
	gap: clamp(0.75rem, 2vw, 1.5rem);
	padding: 0 var(--gutter);
	background: #000;
	border-bottom: 1px solid transparent;
}

/* Scrolled past the film, the bar stays at the top of the details. It turns
   fixed only once no part of the player is in view (public/watch.js). */
.watch-bar.is-detached {
	position: fixed;
	background: rgba(8, 9, 12, 0.94);
	border-bottom-color: var(--line);
	backdrop-filter: blur(10px);
	animation: watch-bar-in 0.2s ease;
}
.watch-bar.is-detached .watch-bar-creator {
	color: var(--text-dim);
}
@keyframes watch-bar-in {
	from {
		opacity: 0;
		transform: translateY(-100%);
	}
}

.watch-back {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	flex: none;
	padding: 0.5rem 0.95rem 0.5rem 0.7rem;
	border: 1px solid rgba(255, 255, 255, 0.16);
	border-radius: 999px;
	background: rgba(20, 22, 28, 0.72);
	font-size: 0.92rem;
	font-weight: 600;
	transition:
		background 0.15s,
		border-color 0.15s;
}
.watch-back:hover {
	background: rgba(44, 48, 60, 0.92);
	border-color: rgba(255, 255, 255, 0.3);
	color: #fff;
}

.watch-bar-text {
	min-width: 0;
}
.watch-bar-title {
	margin: 0;
	font-size: 1rem;
	font-weight: 600;
	line-height: 1.25;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.watch-bar-creator {
	display: block;
	font-size: 0.82rem;
	color: #cdd3e0;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
a.watch-bar-creator:hover {
	color: var(--text);
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* Playing a playlist: its name and place, Previous and Next, at the bar's
   right end (playlistPlayNav in src/views/pages.ts). */
.watch-playlist {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	flex: none;
	margin-left: auto;
	font-size: 0.85rem;
}
.watch-playlist-place {
	color: #cdd3e0;
	white-space: nowrap;
}
.watch-playlist-place a:hover {
	color: var(--text);
	text-decoration: underline;
	text-underline-offset: 2px;
}
@media (max-width: 640px) {
	.watch-playlist-name {
		display: none;
	}
}

/* Up next: the playing playlist, under the player (upNext in src/views/pages.ts). */
.up-next {
	margin: 0 0 2.5rem;
	scroll-margin-top: calc(var(--watch-bar-h) + 1rem);
}
.up-next h2 {
	margin: 0 0 0.75rem;
	font-size: clamp(1.05rem, 2vw, 1.3rem);
}
.up-next h2 a {
	color: var(--accent);
}
.up-next-list {
	list-style: none;
	margin: 0 0 0.75rem;
	padding: 0;
	display: grid;
	gap: 0.35rem;
	max-height: 26rem;
	overflow-y: auto;
}
.up-next-list li {
	border-radius: var(--radius);
}
.up-next-list .playlist-item-film {
	padding: 0.4rem;
	border-radius: var(--radius);
}
.up-next-list .playlist-item-film:hover {
	background: var(--bg-hover);
}
.up-next-list li[aria-current="true"] {
	background: var(--bg-raised);
	outline: 1px solid var(--line);
}
.up-next-place {
	flex: none;
	width: 1.8rem;
	text-align: right;
	color: var(--text-dim);
	font-size: 0.85rem;
	font-variant-numeric: tabular-nums;
}
.up-next-now {
	display: block;
	color: var(--accent);
	font-size: 0.75rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.04em;
}
.watch-playlist-place a[href="#up-next"] {
	text-decoration: underline;
	text-underline-offset: 2px;
}

.watch-stage {
	position: relative;
	flex: 1;
	min-height: 0;
	width: 100%;
	background: #000;
}
.watch-stage iframe {
	width: 100%;
	height: 100%;
	border: 0;
	display: block;
}

.watch-cue {
	display: block;
	width: fit-content;
	margin: 0.9rem auto 0;
	padding: 0.4rem 1rem;
	border: 1px solid var(--line);
	border-radius: 999px;
	background: var(--bg-raised);
	color: var(--text-dim);
	font-size: 0.82rem;
}
.watch-cue:hover {
	background: var(--bg-hover);
	color: var(--text);
}

.watch-details {
	max-width: 1240px;
	margin: 0 auto;
	padding: clamp(1.5rem, 4vw, 2.5rem) var(--gutter) 0;
	/* The overlay bar is fixed, so an anchor jump has to stop short of it. */
	scroll-margin-top: 4.5rem;
}
.watch-details h1 {
	margin: 0 0 0.35rem;
	font-size: clamp(1.4rem, 3.5vw, 2.2rem);
	letter-spacing: -0.02em;
}
.watch-meta {
	margin: 0 0 1.25rem;
	color: var(--text-dim);
	font-size: 0.92rem;
}
.watch-more {
	margin: 0 0 2.5rem;
	font-size: 0.9rem;
}
.watch-more a {
	color: var(--accent);
	text-decoration: underline;
	text-underline-offset: 2px;
}
.watch .rows {
	max-width: 1240px;
	margin: 0 auto;
}

/* The outward links every page that plays a film carries. */
.host-links {
	display: flex;
	gap: 0.6rem;
	flex-wrap: wrap;
	margin-bottom: 1.25rem;
}

.source-note {
	margin: 0 0 1.5rem;
	padding: 0.75rem 1rem;
	border-left: 3px solid var(--line);
	border-radius: 0 6px 6px 0;
	background: var(--bg-raised);
	color: var(--text-dim);
	font-size: 0.86rem;
	max-width: 70ch;
}

.tag-list {
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	gap: 0.45rem;
	padding: 0;
	margin: 0 0 1.5rem;
}
.tag-list a {
	display: inline-block;
	padding: 0.3rem 0.7rem;
	border: 1px solid var(--line);
	border-radius: 999px;
	background: var(--bg-raised);
	font-size: 0.8rem;
	color: var(--text-dim);
}
.tag-list a:hover {
	color: var(--text);
	background: var(--bg-hover);
}

.curator-note {
	margin: 0 0 1.5rem;
	padding: 1rem 1.25rem;
	border-left: 3px solid var(--accent);
	border-radius: 0 6px 6px 0;
	background: var(--bg-raised);
	max-width: 70ch;
}
.curator-note p {
	margin: 0 0 0.4rem;
}
.curator-note cite {
	color: var(--text-dim);
	font-size: 0.78rem;
	font-style: normal;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.description {
	max-width: 70ch;
	color: #c8cdd9;
	font-size: 0.94rem;
	margin-bottom: 2rem;
}
.description p {
	margin: 0 0 0.8rem;
}
.description-head {
	margin: 0 0 0.5rem;
	color: var(--text-dim);
	font-size: 0.78rem;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

/* The film's questions (src/views/faq.ts), each a native toggle. */
.faq {
	margin: 0 0 2.5rem;
	font-size: 0.94rem;
}
.faq h2 {
	margin: 0 0 0.6rem;
	font-size: clamp(1.05rem, 2vw, 1.4rem);
}
.faq-item {
	border-top: 1px solid var(--line);
	scroll-margin-top: 5rem;
}
.faq-item:last-child {
	border-bottom: 1px solid var(--line);
}
.faq summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding: 0.85rem 0;
	cursor: pointer;
	list-style: none;
}
.faq summary::-webkit-details-marker {
	display: none;
}
.faq summary::after {
	content: "";
	flex: none;
	width: 0.5rem;
	height: 0.5rem;
	margin-right: 0.3rem;
	border-right: 2px solid var(--text-dim);
	border-bottom: 2px solid var(--text-dim);
	transform: translateY(-25%) rotate(45deg);
	transition: transform 0.15s;
}
.faq-item[open] summary::after {
	transform: translateY(25%) rotate(-135deg);
}
.faq summary:hover h3 {
	color: #fff;
}
.faq h3 {
	margin: 0;
	font-size: 0.98rem;
	font-weight: 600;
}
.faq p {
	margin: 0 0 1rem;
	color: #c8cdd9;
}
.faq a {
	color: var(--text);
	text-decoration: underline;
	text-decoration-color: var(--line);
	text-underline-offset: 2px;
}
.faq a:hover {
	text-decoration-color: var(--accent);
}

.report {
	max-width: 50ch;
	margin-bottom: 2.5rem;
}
.report summary {
	cursor: pointer;
	color: var(--text-dim);
	font-size: 0.88rem;
}
.report form {
	display: grid;
	gap: 0.4rem;
	margin-top: 0.8rem;
}
.report label {
	font-size: 0.82rem;
	color: var(--text-dim);
}


/* ---------- Viewer: My List, thumbs and the /my pages (src/views/viewer.ts) ---------- */

.viewer-controls {
	display: flex;
	gap: 0.7rem;
	flex-wrap: wrap;
}
.viewer-controls form {
	display: flex;
	gap: 0.5rem;
}
.viewer-controls[aria-busy="true"] {
	opacity: 0.6;
	pointer-events: none;
}
.button-icon {
	padding-left: 0.85rem;
	padding-right: 0.85rem;
}
.button-icon .glyph {
	margin-right: 0;
}
.button[aria-pressed="true"] {
	border-color: var(--text);
	background: var(--bg-hover);
}
.button-icon[aria-pressed="true"] .glyph path {
	fill: currentColor;
}
.thumb-down .glyph {
	transform: rotate(180deg);
}
.watch-details .viewer-controls {
	margin: 0 0 1.25rem;
}

.my-intro {
	color: var(--text-dim);
	max-width: 60ch;
}
.my-controls {
	margin: 0 0 1.5rem;
}
.my-controls input[type="text"],
.my-section .inline-form input[type="text"] {
	flex: 0 1 22rem;
	width: auto;
}
.my-section {
	margin-top: 3rem;
}
.viewer-notice {
	flex-basis: 100%;
	margin: 0;
	color: #ffb4b4;
	font-size: 0.9rem;
}

/* Add to playlist. The panel opens over the page, under the controls and
   lined up with their left edge, so it stays on screen on a phone. */
.viewer-controls {
	position: relative;
}
.playlist-menu > summary {
	list-style: none;
}
.playlist-menu > summary::-webkit-details-marker {
	display: none;
}
.playlist-menu[open] > summary {
	border-color: var(--text);
}
.playlist-menu-panel {
	position: absolute;
	z-index: 5;
	top: calc(100% + 0.5rem);
	left: 0;
	display: grid;
	gap: 0.15rem;
	padding: 0.4rem;
	box-shadow: 0 12px 32px rgb(0 0 0 / 0.5);
	width: min(20rem, calc(100vw - 2 * var(--gutter)));
	max-height: 18rem;
	overflow-y: auto;
	border: 1px solid var(--line);
	border-radius: var(--radius);
	background: var(--bg-raised);
}
.playlist-choice {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	width: 100%;
	padding: 0.5rem 0.6rem;
	border: 0;
	border-radius: 6px;
	background: none;
	color: var(--text);
	font: inherit;
	font-size: 0.92rem;
	text-align: left;
	cursor: pointer;
}
.playlist-choice:hover {
	background: var(--bg-hover);
}
.playlist-choice .glyph {
	flex: none;
}
.playlist-choice span {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.playlist-new {
	display: flex;
	gap: 0.4rem;
	padding: 0.4rem 0.2rem 0.2rem;
	border-top: 1px solid var(--line);
	margin-top: 0.2rem;
}
.playlist-new input[type="text"] {
	flex: 1;
	min-width: 0;
	padding-block: 0.35rem;
}

/* One playlist: a numbered column of films, each with Up, Down and Remove. */
.playlist-items {
	list-style: none;
	margin: 1.5rem 0 0;
	padding: 0;
	display: grid;
	gap: 0.6rem;
	max-width: var(--film-column);
}
.playlist-item {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	flex-wrap: wrap;
	padding: 0.5rem;
	border: 1px solid var(--line);
	border-radius: var(--radius);
	background: var(--bg-raised);
}
.playlist-item-film {
	display: flex;
	align-items: center;
	gap: 0.9rem;
	min-width: 0;
	flex: 1 1 16rem;
}
.playlist-item-film img,
.playlist-item-art {
	flex: none;
	width: 128px;
	height: 72px;
	border-radius: 6px;
	object-fit: cover;
	background: var(--bg-hover);
}
.playlist-item-film strong {
	display: block;
	line-height: 1.3;
}
.playlist-item .button-row form {
	display: flex;
	gap: 0.4rem;
}
.share-link {
	max-width: 36rem;
}

/* ---------- Footer ---------- */

.site-footer {
	border-top: 1px solid var(--line);
	padding: 2rem var(--gutter) 3rem;
	color: var(--text-dim);
	font-size: 0.85rem;
}
.footer-note {
	margin: 0 0 0.8rem;
	max-width: 70ch;
}
.footer-nav {
	display: flex;
	gap: 1.25rem;
	flex-wrap: wrap;
}
.footer-nav a:hover {
	color: var(--text);
}
.footer-link {
	background: none;
	border: 0;
	padding: 0;
	font: inherit;
	color: inherit;
	cursor: pointer;
}
.footer-link:hover {
	color: var(--text);
}

/* The consent banner and Cookie settings (public/consent.js), in the site's
   colors. `html #cc-main` outranks CookieConsent's own `#cc-main`. */
html #cc-main {
	--cc-font-family: var(--font);
	--cc-bg: var(--bg-raised);
	--cc-primary-color: var(--text);
	--cc-secondary-color: var(--text-dim);
	--cc-link-color: var(--text);
	--cc-btn-primary-bg: var(--accent);
	--cc-btn-primary-color: var(--accent-ink);
	--cc-btn-primary-border-color: var(--accent);
	--cc-btn-primary-hover-bg: #ff6b6b;
	--cc-btn-primary-hover-color: var(--accent-ink);
	--cc-btn-primary-hover-border-color: #ff6b6b;
	--cc-btn-secondary-bg: var(--bg-hover);
	--cc-btn-secondary-color: var(--text);
	--cc-btn-secondary-border-color: var(--line);
	--cc-btn-secondary-hover-bg: var(--line);
	--cc-btn-secondary-hover-color: var(--text);
	--cc-btn-secondary-hover-border-color: var(--line);
	--cc-separator-border-color: var(--line);
	--cc-toggle-on-bg: var(--accent);
	--cc-toggle-off-bg: var(--line);
	--cc-toggle-on-knob-bg: var(--accent-ink);
	--cc-toggle-off-knob-bg: var(--text-dim);
	--cc-toggle-enabled-icon-color: var(--accent);
	--cc-toggle-disabled-icon-color: var(--bg-raised);
	--cc-toggle-readonly-bg: var(--bg-hover);
	--cc-toggle-readonly-knob-bg: var(--text-dim);
	--cc-toggle-readonly-knob-icon-color: var(--bg-raised);
	--cc-section-category-border: var(--line);
	--cc-cookie-category-block-bg: var(--bg);
	--cc-cookie-category-block-border: var(--line);
	--cc-cookie-category-block-hover-bg: var(--bg-hover);
	--cc-cookie-category-block-hover-border: var(--line);
	--cc-cookie-category-expanded-block-bg: var(--bg);
	--cc-cookie-category-expanded-block-hover-bg: var(--bg-hover);
	--cc-overlay-bg: rgba(0, 0, 0, 0.7);
	--cc-footer-bg: var(--bg);
	--cc-footer-color: var(--text-dim);
	--cc-footer-border-color: var(--line);
}

@media (max-width: 720px) {
	/* The nav is not hidden here. Hiding it with no replacement made /browse and
     /creators unreachable on a phone. It wraps to its own line instead. */
	.site-header {
		flex-wrap: wrap;
		row-gap: 0.6rem;
	}
	.site-nav {
		order: 3;
		width: 100%;
		justify-content: space-between;
		font-size: 0.9rem;
	}
	.search {
		margin-left: auto;
	}
	.search input {
		width: clamp(140px, 42vw, 220px);
	}
	.hero {
		min-height: 340px;
	}
}

@media (max-width: 900px) {
	/* The copy is taller than the still is wide here. Leave the top of the still clear above it. */
	.details-hero {
		min-height: 0;
		padding-top: clamp(10rem, 48vw, 18rem);
	}
}

/* A phone held sideways. The screen is short, so the player takes all of
   it, and Back moves to a margin of its own beside the player. The bar shows
   the title for a few seconds, then tucks away once and stays away
   (public/watch.js, which repeats this media query). A bar that came back
   on every tap would resize the film each time. */
@media (orientation: landscape) and (max-height: 540px) {
	.watch {
		--watch-rail: calc(3.5rem + env(safe-area-inset-left));
		padding-left: var(--watch-rail);
	}
	.watch-screen {
		height: 100vh;
		height: 100svh;
		min-height: 0;
		transition: padding-top 0.6s ease;
	}
	.watch-bar {
		padding-left: 0;
		overflow: hidden;
		transition: height 0.6s ease;
	}
	.watch-bar.is-detached {
		position: absolute;
		background: #000;
		border-bottom-color: transparent;
		backdrop-filter: none;
		animation: none;
	}
	.watch-back {
		position: fixed;
		z-index: 61;
		top: 0.55rem;
		left: calc(0.4rem + env(safe-area-inset-left));
		padding: 0.6rem;
		visibility: visible;
	}
	.watch-back span {
		position: absolute;
		width: 1px;
		height: 1px;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
	}
	.watch-bar-text {
		transition: opacity 0.3s ease;
	}
	.watch-screen.is-tucked {
		padding-top: 0;
	}
	/* No border either: a 1px box left at the top would paint over the player. */
	.watch-screen.is-tucked .watch-bar {
		height: 0;
		border-bottom-width: 0;
		visibility: hidden;
		transition:
			height 0.6s ease,
			visibility 0s 0.6s;
	}
	.watch-screen.is-tucked .watch-bar-text {
		opacity: 0;
		visibility: hidden;
	}
}

@media (prefers-reduced-motion: reduce) {
	.card {
		transition: none;
	}
	.backdrop-frame {
		animation: none;
	}
	/* A held guide is gray with scan lines, with no shake and no static. */
	.guide-window {
		transition: none;
	}
	.hero-guide.is-held .guide-list {
		animation: none;
	}
	.hero-guide.is-held .guide-window::before {
		visibility: hidden;
		animation: none;
	}

	.faq summary::after {
		transition: none;
	}
	.watch-screen,
	.watch-bar,
	.watch-bar-text {
		transition: none;
	}
	.watch-bar.is-detached {
		animation: none;
	}
}
