@charset "utf-8";

/* ============================================================================
   Dimitris Apostolou — 1st Assistant Director
   Design: "Call Sheet". The document a 1st AD lives inside — hairline rules,
   stamped labels, tabular figures, a perforated film edge — set as a website.
   No JavaScript. No third-party requests. No inline styles (CSP-safe).
   ========================================================================== */

/* --- Fonts (self-hosted, Latin subset, SIL OFL) --------------------------- */

@font-face {
	font-family: "Palanquin";
	src: url("../fonts/palanquin/palanquin-regular.woff2") format("woff2");
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}
@font-face {
	font-family: "Palanquin";
	src: url("../fonts/palanquin/palanquin-semibold.woff2") format("woff2");
	font-weight: 600;
	font-style: normal;
	font-display: swap;
}
@font-face {
	font-family: "Palanquin Dark";
	src: url("../fonts/palanquin/palanquindark-bold.woff2") format("woff2");
	font-weight: 700;
	font-style: normal;
	font-display: swap;
}

/* --- Tokens --------------------------------------------------------------- */

:root {
	color-scheme: light dark;

	--paper:      #f2efe7;
	--surface:    #fbf9f4;
	--ink:        #17150f;
	--ink-soft:   #46423a;
	--ink-muted:  #6b655a;
	--rule:       #d9d2c3;
	--rule-soft:  #e6e0d3;
	--perf:       #ded7c8;
	--accent:     #a82f1c;
	--accent-ink: #fbf9f4;
	--shadow:     0 1px 0 rgba(23, 21, 15, 0.06), 0 12px 28px -18px rgba(23, 21, 15, 0.45);
	--grain:      rgba(23, 21, 15, 0.016);

	--font-display: "Palanquin Dark", "Palanquin", "Avenir Next", sans-serif;
	--font-body: "Palanquin", "Avenir Next", "Segoe UI", sans-serif;
	--font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;

	--gutter: clamp(1.25rem, 5vw, 4rem);
	--edge: 2.25rem;
	--measure: 74rem;
}

@media (prefers-color-scheme: dark) {
	:root {
		--paper:      #100e0b;
		--surface:    #1a1713;
		--ink:        #efe9dc;
		--ink-soft:   #cbc3b3;
		--ink-muted:  #a39a8a;
		--rule:       #322d26;
		--rule-soft:  #241f1a;
		--perf:       #2b261f;
		--accent:     #e2694a;
		--accent-ink: #16120e;
		--shadow:     0 1px 0 rgba(0, 0, 0, 0.5), 0 16px 34px -20px rgba(0, 0, 0, 0.9);
		--grain:      rgba(239, 233, 220, 0.013);
	}
}

/* --- Reset ---------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html {
	overflow-x: clip;
	-webkit-text-size-adjust: 100%;
}

body {
	margin: 0;
	background-color: var(--paper);
	color: var(--ink);
	font-family: var(--font-body);
	font-size: clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
	line-height: 1.65;
	font-synthesis-weight: none;
	text-rendering: optimizeLegibility;
	-webkit-font-smoothing: antialiased;
	-webkit-tap-highlight-color: rgba(168, 47, 28, 0.14);
}

/* Paper tooth. Two crossed hairline gratings — cheap, static, no image. */
body::after {
	content: "";
	position: fixed;
	inset: 0;
	z-index: 2;
	pointer-events: none;
	background-image:
		repeating-linear-gradient(45deg, var(--grain) 0 1px, transparent 1px 5px),
		repeating-linear-gradient(-45deg, var(--grain) 0 1px, transparent 1px 7px);
}

img { max-width: 100%; height: auto; display: block; }

h1, h2, p, dl, dd, ul { margin: 0; }
ul { list-style: none; padding: 0; }

hr {
	border: 0;
	height: 1px;
	background-color: var(--rule);
	margin: 0;
}

a { color: inherit; touch-action: manipulation; }

:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 3px;
	border-radius: 2px;
}

.visuallyHidden {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.skipLink {
	position: absolute;
	left: var(--gutter);
	top: max(0.75rem, env(safe-area-inset-top));
	z-index: 10;
	transform: translateY(-260%);
	padding: 0.6rem 1rem;
	background-color: var(--accent);
	color: var(--accent-ink);
	font-family: var(--font-mono);
	font-size: 0.75rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	text-decoration: none;
	transition: transform 0.18s ease;
}
.skipLink:focus { transform: translateY(0); }

/* --- Sheet ---------------------------------------------------------------- */

.sheet {
	position: relative;
	max-width: var(--measure);
	margin-inline: auto;
	padding:
		clamp(2rem, 6vh, 4.5rem)
		max(var(--gutter), env(safe-area-inset-right))
		clamp(3rem, 8vh, 6rem)
		max(var(--gutter), env(safe-area-inset-left));
}

/* Film perforations down the left edge — desktop only, decorative. */
@media (min-width: 60rem) {
	.sheet { padding-left: calc(var(--gutter) + var(--edge)); }
	.sheet::before {
		content: "";
		position: absolute;
		left: var(--gutter);
		top: clamp(2rem, 6vh, 4.5rem);
		bottom: clamp(3rem, 8vh, 6rem);
		width: 14px;
		background-image: radial-gradient(circle at 50% 50%, var(--perf) 0 3.4px, transparent 3.6px);
		background-size: 100% 24px;
		background-repeat: repeat-y;
		opacity: 0.9;
	}
}

/* --- Masthead ------------------------------------------------------------- */

.slug {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	font-family: var(--font-mono);
	font-size: 0.6875rem;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--ink-muted);
}
.slug__mark {
	flex: none;
	width: 0.5rem;
	height: 0.5rem;
	border-radius: 50%;
	background-color: var(--accent);
	box-shadow: 0 0 0 3px rgba(168, 47, 28, 0.15);
}
.slug__text { flex: none; white-space: nowrap; }
.slug__text--end { color: var(--ink-soft); }
.slug__rule {
	flex: 1 1 auto;
	min-width: 1rem;
	height: 1px;
	background-color: var(--rule);
}

.name {
	margin-top: clamp(1.75rem, 5vh, 3.25rem);
	font-family: var(--font-display);
	font-weight: 700;
	font-size: clamp(3.1rem, 13.2vw, 9.5rem);
	line-height: 0.85;
	letter-spacing: -0.038em;
	text-wrap: balance;
	color: var(--ink);
}
.name span { display: block; }
.name span:last-child {
	color: var(--ink-soft);
	margin-left: 0.06em;
}

.role {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 0.6rem 0.85rem;
	margin-top: clamp(1.25rem, 3vh, 2rem);
}
.role__no {
	font-family: var(--font-mono);
	font-size: 0.75rem;
	font-variant-numeric: tabular-nums;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--accent-ink);
	background-color: var(--accent);
	padding: 0.3rem 0.5rem 0.25rem;
}
.role__title {
	font-family: var(--font-body);
	font-weight: 600;
	font-size: clamp(1.05rem, 0.9rem + 0.8vw, 1.5rem);
	letter-spacing: 0.02em;
	color: var(--ink);
}

.rule--heavy {
	margin-top: clamp(1.75rem, 4vh, 2.75rem);
	height: 2px;
	background-color: var(--ink);
}

/* --- Specification grid --------------------------------------------------- */

.main { display: block; }

.specs { margin-top: clamp(1.5rem, 4vh, 2.5rem); }

.specs__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 0;
}
@media (min-width: 48rem) {
	.specs__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.spec {
	min-width: 0;
	padding: 1.35rem 0;
	border-top: 1px solid var(--rule-soft);
}
.spec:first-child { border-top: 0; }
@media (min-width: 48rem) {
	.spec {
		border-top: 0;
		padding: 0.35rem 1.75rem 0.35rem 0;
		border-left: 1px solid var(--rule);
		padding-left: 1.75rem;
	}
	.spec:first-child { border-left: 0; padding-left: 0; }
}

.spec__label {
	font-family: var(--font-mono);
	font-size: 0.625rem;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: var(--ink-muted);
}
.spec__value {
	margin-top: 0.55rem;
	font-size: 1rem;
	line-height: 1.5;
	color: var(--ink-soft);
	overflow-wrap: break-word;
	text-wrap: pretty;
}

/* Stat form: the figure leads, the category captions it. Flipped in CSS so the
   <dt>/<dd> pairing stays semantically correct in the source. */
.spec--count {
	display: flex;
	flex-direction: column-reverse;
	justify-content: flex-end;
}
.spec--count .spec__label {
	margin-top: 0.6rem;
	text-wrap: balance;
}
.spec--count .spec__value { margin-top: 0; }
.count {
	font-family: var(--font-display);
	font-weight: 700;
	font-size: clamp(2.6rem, 6vw, 3.6rem);
	line-height: 1;
	letter-spacing: -0.03em;
	font-variant-numeric: tabular-nums;
	color: var(--ink);
}
.count__plus {
	color: var(--accent);
	font-size: 0.5em;
	vertical-align: super;
	letter-spacing: 0;
}
/* --- Content blocks ------------------------------------------------------- */

.block {
	display: grid;
	grid-template-columns: 1fr;
	gap: 0.9rem;
	padding-top: clamp(2.5rem, 6vh, 4rem);
	margin-top: clamp(2.5rem, 6vh, 4rem);
	border-top: 1px solid var(--rule);
}
@media (min-width: 48rem) {
	.block {
		grid-template-columns: minmax(0, 14rem) minmax(0, 1fr);
		gap: 2rem;
	}
}

.blockTitle {
	font-family: var(--font-mono);
	font-size: 0.6875rem;
	font-weight: 400;
	letter-spacing: 0.24em;
	text-transform: uppercase;
	color: var(--ink-muted);
	padding-top: 0.35rem;
	scroll-margin-top: 2rem;
}
.block__body { min-width: 0; }

.lede {
	max-width: 34ch;
	font-size: clamp(1.15rem, 1rem + 0.7vw, 1.5rem);
	line-height: 1.35;
	letter-spacing: -0.012em;
	text-wrap: pretty;
	color: var(--ink);
}

.actions { margin-top: 1.5rem; }

.button {
	display: inline-flex;
	align-items: center;
	gap: 0.65rem;
	padding: 0.8rem 1.15rem;
	background-color: var(--ink);
	color: var(--paper);
	font-family: var(--font-body);
	font-weight: 600;
	font-size: 0.9375rem;
	letter-spacing: 0.01em;
	text-decoration: none;
	transition: background-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
}
.button__arrow {
	display: inline-block;
	transition: transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.button:hover {
	background-color: var(--accent);
	color: var(--accent-ink);
}
.button:hover .button__arrow { transform: translateX(0.28rem); }
.button:active { transform: translateY(1px); }

.mono {
	font-family: var(--font-mono);
	font-size: 0.8125rem;
	letter-spacing: 0.01em;
	overflow-wrap: anywhere;
}
.mono--muted { color: var(--ink-muted); }
.mono a {
	color: var(--ink-soft);
	text-decoration: underline;
	text-decoration-color: var(--rule);
	text-decoration-thickness: 1px;
	text-underline-offset: 0.22em;
	transition: color 0.2s ease, text-decoration-color 0.2s ease;
}
.mono a:hover {
	color: var(--accent);
	text-decoration-color: var(--accent);
}

/* --- Filmography cards ---------------------------------------------------- */

.cards {
	display: grid;
	grid-template-columns: 1fr;
	gap: 1rem;
}
@media (min-width: 34rem) {
	.cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.card { min-width: 0; }

.card__link {
	display: flex;
	flex-direction: column;
	gap: 1.15rem;
	height: 100%;
	padding: 1.15rem;
	background-color: var(--surface);
	border: 1px solid var(--rule);
	text-decoration: none;
	transition: border-color 0.22s ease, box-shadow 0.22s ease, transform 0.22s ease;
}
.card__link:hover {
	border-color: var(--ink);
	box-shadow: var(--shadow);
	transform: translateY(-2px);
}

.card__figure {
	display: flex;
	align-items: center;
	justify-content: center;
	height: 5.25rem;
	overflow: hidden;
}
.card__figure img {
	max-height: 100%;
	width: auto;
	object-fit: contain;
}
.card__figure--imdb img { max-height: 2.75rem; }
.card__figure--crew img { max-height: 4.25rem; }

/* The Crew United mark shipped as black-on-opaque-white; its white plate has
   been converted to transparency, so the card needs no blend mode to hide it
   (blend modes are the kind of thing that goes wrong on one engine and not
   another). Dark mode just inverts the RGB — alpha survives, so the artwork
   turns white and the background stays clear. */
@media (prefers-color-scheme: dark) {
	.card__figure--crew img { filter: invert(1); }
}

.card__meta {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 0.75rem;
	padding-top: 0.9rem;
	border-top: 1px solid var(--rule-soft);
	min-width: 0;
}
.card__name {
	font-family: var(--font-body);
	font-weight: 600;
	font-size: 0.9375rem;
	color: var(--ink);
	white-space: nowrap;
}
.card__hint {
	display: inline-flex;
	align-items: baseline;
	gap: 0.4rem;
	min-width: 0;
	font-family: var(--font-mono);
	font-size: 0.6875rem;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	font-variant-numeric: tabular-nums;
	color: var(--ink-muted);
	overflow: hidden;
	text-overflow: ellipsis;
}
.card__arrow {
	display: inline-block;
	transition: transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.card__link:hover .card__hint { color: var(--accent); }
.card__link:hover .card__arrow { transform: translateX(0.28rem); }

/* --- Colophon ------------------------------------------------------------- */

.colophon {
	margin-top: clamp(3rem, 8vh, 5rem);
	padding-bottom: env(safe-area-inset-bottom);
}
.colophon .rule { margin-bottom: 1.15rem; }
.colophon p { max-width: 52ch; line-height: 1.75; }

/* --- Mirrors -------------------------------------------------------------- */

/* The same sheet, served over Tor and I2P. Addresses are printed in full
   because neither can be guessed, retyped from memory, or found by search. */

/* The colophon borrows the block grid so its label sits in the same column as
   Contact and Filmography, and the mirror tiles line up with the credit cards. */
.colophon__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 0.9rem;
}
@media (min-width: 48rem) {
	.colophon__grid {
		grid-template-columns: minmax(0, 14rem) minmax(0, 1fr);
		gap: 2rem;
	}
}
.colophon__body { min-width: 0; }
.colophon .blockTitle { padding-top: 0.1rem; }

/* One per row, not two up. Side by side, the column is ~190px and every
   address wraps — the onion inevitably, the eepsite just barely, orphaning a
   "p/" on its own line. Full width, each address sits on one unbroken line,
   which is what an address you are meant to copy should do. */
.mirrors {
	display: grid;
	grid-template-columns: 1fr;
	gap: 0.6rem;
	margin-top: 1rem;
}

.mirror { min-width: 0; }

.mirror__link {
	display: flex;
	align-items: flex-start;
	gap: 0.9rem;
	height: 100%;
	min-width: 0;
	padding: 0.85rem 0.95rem;
	background-color: var(--surface);
	border: 1px solid var(--rule-soft);
	text-decoration: none;
	transition: border-color 0.22s ease, box-shadow 0.22s ease, transform 0.22s ease;
}
.mirror__link:hover {
	border-color: var(--ink);
	box-shadow: var(--shadow);
	transform: translateY(-2px);
}

/* Both marks are stamped on a fixed paper chip rather than sitting loose on
   the sheet, so neither needs a dark-mode filter. That matters here: the Tor
   onion is full-colour artwork on transparency and the I2P mark is a colour
   wordmark on an opaque white plate — inverting either wrecks it, and the
   invert trick used on the Crew United logo only works because that mark is
   monochrome. On the dark theme the chip reads as a stamp, which is on-brief. */
.mirror__chip {
	flex: none;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 2.4rem;
	height: 2.4rem;
	background-color: #fbf9f4;
	border: 1px solid var(--rule-soft);
}

.mirrorIcon {
	width: auto;
	object-fit: contain;
}
.mirrorIcon--tor { max-height: 1.5rem; }
.mirrorIcon--i2p { max-height: 1.35rem; }

.mirror__meta {
	display: flex;
	flex-direction: column;
	gap: 0.2rem;
	min-width: 0;
	padding-top: 0.1rem;
}
.mirror__net {
	font-family: var(--font-body);
	font-weight: 600;
	font-size: 0.9375rem;
	line-height: 1.25;
	color: var(--ink);
}
.mirror__addr,
.mirror__alt {
	font-family: var(--font-mono);
	font-size: 0.6875rem;
	line-height: 1.45;
	/* No tracking. Mono is evenly spaced already, and 0.01em across a 70-char
	   onion URL costs ~8px — enough to push the trailing slash onto a line of
	   its own, which is the ugliest possible break for an address. */
	letter-spacing: 0;
	overflow-wrap: anywhere;
	transition: color 0.2s ease;
}
.mirror__addr { color: var(--ink-soft); }

/* The scheme is printed, not implied. A bare `host.onion` pasted into Tor
   Browser gets https:// guessed for it by HTTPS-Only Mode and fails, because
   the onion service speaks plain HTTP — so the visible string has to be the
   whole URL, byte-identical to the href. It is set quieter than the address
   it prefixes; copying still yields the full text, spans do not affect it. */
.mirror__scheme { color: var(--ink-muted); }

/* The b32 is the address that always resolves; the .i2p name needs an
   addressbook subscription. Subordinate, but it still has to be readable, so
   it steps down in size rather than fading — an opacity ramp here fell under
   4.5:1 on the light theme. */
.mirror__alt {
	font-size: 0.625rem;
	color: var(--ink-muted);
}
.mirror__link:hover .mirror__addr { color: var(--accent); }

.colophon__note { margin-top: 1.35rem; }

/* --- Page load: the sheet is struck, then filled in ------------------------ */

@keyframes rise {
	from { opacity: 0; transform: translateY(0.85rem); }
	to   { opacity: 1; transform: none; }
}
@keyframes strike {
	from { transform: scaleX(0); }
	to   { transform: scaleX(1); }
}

.slug,
.name span,
.role,
.specs,
.block,
.colophon {
	animation: rise 0.72s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

.slug            { animation-delay: 0.02s; }
.name span:first-child { animation-delay: 0.10s; }
.name span:last-child  { animation-delay: 0.17s; }
.role            { animation-delay: 0.26s; }
.specs           { animation-delay: 0.40s; }
.block--contact  { animation-delay: 0.48s; }
.block--credits  { animation-delay: 0.56s; }
.colophon        { animation-delay: 0.64s; }

.rule--heavy,
.slug__rule {
	transform-origin: left center;
	animation: strike 0.85s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.slug__rule   { animation-delay: 0.12s; }
.rule--heavy  { animation-delay: 0.34s; }

@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after {
		animation-duration: 0.001ms !important;
		animation-delay: 0ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
	}
	.card__link:hover,
	.mirror__link:hover { transform: none; }
	.button:hover .button__arrow,
	.card__link:hover .card__arrow { transform: none; }
}
