/* Guest brochure. Standalone: this page never loads the tracker bundle. The
   palette and the shared wordmark/credit styles come from palette.css; what is
   here is the landing page itself.

   Rendered 25% larger than its authored px sizes, matching the tracker app's own
   scale (app/src/index.css #root) -- so every size below is an app size
   and the two pages agree on how big the wordmark, the type and the buttons are.
   Nothing here is sized in viewport units, so the zoom can go on the body itself.
   Media queries still report the UNZOOMED viewport, so the breakpoints at the
   bottom are real-viewport px, not authored px. */

body {
	zoom: 1.25;
	margin: 0;
	background: var(--bg);
	color: var(--text);
	font-family: var(--font-sans);
	font-size: 14px;
	line-height: 1.5;
}

/* Viewport units inside the zoomed body render --ui-scale times too large, exactly as
   in the app (app/src/index.css --vh100 / --vw100). Anything sized to the viewport --
   which on this page means the theater overlay -- has to go through these instead of
   raw vh / vw, or it ends up a quarter larger than the screen. The scale is written
   out rather than referenced because the zoom above is a literal too; they are one
   decision and belong in one place if that ever changes. */
:root {
	--ui-scale: 1.25;
	--vh100: calc(100vh / var(--ui-scale));
	--vw100: calc(100vw / var(--ui-scale));
}

a {
	color: var(--accent);
}

.wrap {
	width: 100%;
	max-width: 1040px;
	margin: 0 auto;
	padding: 0 22px;
}

/* ── Header ──
   The app's top bar: full-bleed black, sticky, one rule along the bottom. Opaque
   rather than translucent -- the app's header is a solid band and the blur read as
   a different surface. */

.site-header {
	position: sticky;
	top: 0;
	z-index: 50;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 14px 22px;
	background: var(--header-bg);
	/* No bottom rule: the hero below carries the same black, and the two are meant to
	   read as one band. The rule that closes the band sits at the hero's bottom edge
	   instead (see .hero). */
	/* +2px over the page's 14px, so the whole bar reads a touch larger, as in the app. */
	font-size: 16px;
}

/* ── Header brand sizes ──
   The bar's branding was reported as too small to make out, so it is set here rather
   than inherited: the wordmark a step up from the bar's own type, and the partner marks
   a step beyond that -- they are the smallest thing in the header and the first to go
   illegible, so they take the larger increase.

   BROCHURE ONLY, deliberately: these override the shared sizes in pages.css by being
   scoped to the header and loaded after it. The auth cards and the app still carry the
   old values, so the three surfaces now disagree on this until the app is done too. */

.site-header .brand-mark {
	font-size: 20px;
}

.site-header .site-sub {
	font-size: 14px;
}

.site-header .site-sub-lead,
.site-header .site-sub-amp {
	font-size: 12px;
}

/* The credit runs larger in this bar than on the auth cards, so only the sizes are set
   here -- face, weight and tracking come from pages.css. An 11px cap for 1/ST, and NYRA a
   sixth over it, which is what a condensed face needs to read the same size alongside. */
.site-header .site-sub-mark {
	font-size: 15.2px;
}

.site-header .site-sub-mark--nyra {
	font-size: 17px;
}

.site-title {
	display: flex;
	align-items: center;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 1px;
	color: var(--header-title);
}

/* The whole logo cluster is the link home, mirroring the app's brand-home button
   (there it goes to the next race; here there is only one page to go to). The
   padding gives the hover fill something to sit in and the negative margin cancels
   it out of the layout, keeping the wordmark on its 22px gutter. */
.brand-home {
	display: flex;
	align-items: baseline;
	gap: 8px;
	margin: -4px -8px;
	padding: 4px 8px;
	border-radius: 6px;
	color: inherit;
	text-decoration: none;
	transition: background 0.12s ease;
}

.brand-home:hover {
	background: var(--header-hover);
}

/* Wordmark and flag as one unit, so the narrow layout stacks the cluster as a
   two-item column instead of wrapping a three-item row. */
.brand-line {
	display: inline-flex;
	align-items: baseline;
	gap: 8px;
}

.site-actions {
	display: flex;
	align-items: center;
	gap: 14px;
	/* The bar's two halves both hold unbreakable text. Without this the buttons give up
	   width first and the branding, which overflows rather than shrinking, paints over
	   them. */
	flex-shrink: 0;
}

/* ── Buttons ──
   Two idioms, both lifted from the app's header: a neutral-outlined link in the
   shape of its "Welcome, Guest" menu handle, and an accent-outlined one in the
   shape of its Tour button, which is the optional "start here" action there and
   the sign-up action here. */

.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	padding: 6px 14px;
	border: 1px solid var(--border);
	border-radius: 6px;
	background: transparent;
	color: var(--text);
	font: inherit;
	font-size: 13px;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	text-decoration: none;
	white-space: nowrap;
	cursor: pointer;
	transition: background 0.12s, border-color 0.12s;
}

.btn:hover {
	background: var(--hover);
	text-decoration: underline;
}

.site-header .btn {
	color: var(--header-title);
}

.site-header .btn:hover {
	background: var(--header-hover);
}

.btn-accent {
	border-color: var(--accent);
	color: var(--accent);
}

.site-header .btn-accent {
	color: var(--accent);
}

.btn-accent:hover,
.site-header .btn-accent:hover {
	background: color-mix(in srgb, var(--accent) 12%, transparent);
}

/* Filled accent, matching the app's selected control (button.active): the page's
   one loudest action. */
.btn-primary {
	background: var(--accent);
	border-color: var(--accent);
	color: var(--accent-ink);
	font-weight: 600;
}

.btn-primary:hover {
	background: color-mix(in srgb, var(--accent) 88%, #fff);
	border-color: color-mix(in srgb, var(--accent) 88%, #fff);
	color: var(--accent-ink);
	text-decoration: none;
}

/* Roomier than the header's buttons: these carry the hero and sit on their own. */
.hero-ctas .btn {
	padding: 9px 18px;
	font-size: 14px;
}

/* ── Hero ──
   Two columns: the pitch on the left, the live preview on the right. The board is
   the page's real argument, so it sits beside the slogan instead of under it, and the
   copy goes left-aligned to sit against it rather than floating centred beside a
   panel. Both collapse to one column when the board runs out of room (see the
   breakpoints at the bottom). */

.hero {
	/* The header's black, continued: bar and hero are one unbroken band, and the only
	   rule is the one that closes it against the page below. It is also the base colour
	   the photograph and its scrim sit on, and what shows through wherever they don't. */
	position: relative;
	background: var(--header-bg);
	border-bottom: 1px solid var(--border);
	padding: 56px 0 64px;
	/* The photo layer is inset past the edges so its blur doesn't feather into view. */
	overflow: hidden;
}

/* The photograph. Zoomed well past cover and positioned onto the pack, so what reads is
   horses and silks rather than the water and grass above them -- and blurred, because
   this is a texture behind the page's type, not a picture the page is about. */
.hero::before {
	content: "";
	position: absolute;
	/* Negative inset: the blur's soft edge falls outside the section instead of showing
	   as a pale border along it. */
	inset: -16px;
	background-image: url("../images/brochure/splash.jpg");
	background-repeat: no-repeat;
	background-size: 150% auto;
	background-position: 62% 68%;
	filter: blur(2px) saturate(0.9);
}

/* Scrim, in two gradients over the photo:
     - top to bottom, opaque black for the first stretch, so the band still meets the
       header seamlessly and the photo begins below it rather than at it;
     - left to right, opaque black across the left half -- the copy column reads on flat
       black, as it did before there was a photograph -- easing to a heavy wash on the
       right, where the board sits. The wash is what keeps the board legible; the photo
       is meant to be sensed behind it, not looked at. */
.hero::after {
	content: "";
	position: absolute;
	inset: 0;
	background:
		linear-gradient(to bottom, var(--header-bg) 0, rgba(0, 0, 0, 0) 42%),
		linear-gradient(
			to right,
			var(--header-bg) 0,
			var(--header-bg) 46%,
			rgba(0, 0, 0, 0.72) 72%,
			rgba(0, 0, 0, 0.66) 100%
		);
}

/* Above both layers. */
.hero > .wrap {
	position: relative;
	z-index: 1;
}

.hero-grid {
	display: grid;
	/* The board needs the wider share: it carries a five-column table, and its rows
	   are what a visitor is here to look at. */
	grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
	gap: 44px;
	align-items: center;
}

/* Kicker over the headline: the site's beta standing, said where the page is read
   first. An eyebrow rather than a banner, so the bar and the hero stay the one
   unbroken black band they are drawn as. */
.hero-eyebrow {
	display: flex;
	align-items: center;
	gap: 7px;
	margin: 0 0 12px;
	color: var(--accent);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.14em;
	line-height: 1.2;
	text-transform: uppercase;
}

/* The word itself, boxed off the line so it lands before the phrase is read. */
.hero-eyebrow-tag {
	padding: 2px 7px;
	background: color-mix(in srgb, var(--accent) 16%, transparent);
	border: 1px solid color-mix(in srgb, var(--accent) 42%, transparent);
	border-radius: 999px;
}

.hero-eyebrow-sep {
	opacity: 0.5;
}

/* The page's headline, and its only h1 -- the whole left column, now that the
   wordmark and credit live in the header alone. Set as two block lines rather than one
   wrapped line, so the break lands on "on demand" at every width instead of wherever
   the column happens to run out. */
.hero-slogan {
	margin: 0;
	font-size: 30px;
	font-weight: 700;
	letter-spacing: 0.2px;
	line-height: 1.2;
}

.hero-slogan-line {
	display: block;
}

/* The turn of the phrase, in the accent -- the same amber that marks live state
   everywhere in the app. */
.hero-slogan-turn {
	color: var(--accent);
}

.hero-ctas {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 12px;
	margin-top: 26px;
}

/* ── Live preview widget ──
   The live board, unboxed: no panel, no rules, no chrome -- the race, its runners and
   their silks sit straight on the page. Enough of the app's board survives (the accent
   race number, the status pill, the saddle cloths, tabular figures) that it reads as
   the same product, without a card competing with the hero beside it.

   Its height is RESERVED, not measured. The widget occupies the same space in every
   state -- loading, live, finished, or a race whose odds haven't opened -- so the hero
   never jumps when the first payload lands, when the field is short, or when the next
   race rolls over. The fixed min-height, the capped runner list and the flex column
   below are all in service of that; anything added here has to preserve it. */

.preview {
	display: flex;
	flex-direction: column;
	/* Head + six rows + the "more" indicator + the footnote, at the sizes set below.
	   Revisit it if any of those change -- the row cap itself is MAX_RUNNERS in
	   js/preview.js. */
	min-height: 400px;
}

/* Race identity on the left, live state on the right. Deliberately NOT wrapping: a
   long track name ellipsizes rather than pushing the row onto a second line and
   taking the widget's height with it. */
.preview-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	padding: 0 0 12px;
}

.preview-title {
	display: flex;
	align-items: baseline;
	gap: 10px;
	min-width: 0;
}

.preview-track {
	font-size: 18px;
	font-weight: 700;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Race number in the accent, as the app's status band and mini bar both render it. */
.preview-race {
	color: var(--accent);
	font-size: 18px;
	font-weight: 700;
	white-space: nowrap;
}

.preview-state {
	display: flex;
	align-items: center;
	gap: 12px;
	margin-left: auto;
}

/* MTP countdown, in the accent the app gives its status-band headline. */
.preview-mtp {
	flex-shrink: 0;
	color: var(--accent);
	font-size: 16px;
	font-weight: 700;
	letter-spacing: 0.5px;
	white-space: nowrap;
	font-variant-numeric: tabular-nums;
}

/* Live/finished indicator: the app's status pill -- a capsule outlined and inked in
   one colour, with a matching dot. The one outline the widget keeps, because the pill
   IS its outline; without it there is no live indicator left. */
.preview-pill {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	flex-shrink: 0;
	padding: 4px 12px;
	border: 1px solid var(--pill-color, var(--text-dim));
	border-radius: 999px;
	color: var(--pill-color, var(--text-dim));
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.6px;
	white-space: nowrap;
}

.preview-pill--live {
	--pill-color: var(--green);
}

.preview-dot {
	width: 8px;
	height: 8px;
	border-radius: 999px;
	background: var(--pill-color, var(--text-dim));
}

/* Takes the slack when the field is short, so the footnote stays pinned to the bottom
   of the reserved space instead of riding up under the last runner. */
.preview-rows {
	flex: 1;
	margin: 0;
	padding: 0;
	list-style: none;
}

/* 26px silk + 12px of padding top and bottom = a 50px row. The reserved height above
   counts on that, so a change here is a change there. */
.preview-row {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 12px 0;
	font-size: 14px;
}

.preview-row.scratched {
	opacity: 0.4;
	text-decoration: line-through;
}

/* Saddle-cloth swatch with the program number inside it. Colour, ink and the ring a
   near-black silk needs all arrive inline from the payload (see js/preview.js),
   exactly as the app's Silk component sets them. */
.preview-silk {
	flex-shrink: 0;
	width: 26px;
	height: 26px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: 5px;
	font-size: 12px;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
}

.preview-name {
	flex: 1;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-weight: 600;
}

.preview-odds {
	flex-shrink: 0;
	width: 70px;
	text-align: right;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
}

/* Shown when the field is longer than the cap: says only THAT there are more runners,
   never which or how many. Indented to the runner names, so it reads as the list
   trailing off rather than as a row of its own. */
.preview-more {
	padding: 6px 0;
	padding-left: 38px;
	color: var(--text-dim);
	font-size: 18px;
	line-height: 1;
	letter-spacing: 2px;
}

/* Loading, and the states with no runners to show. Fills the reserved space so those
   states are the same height as a full board. */
.preview-message {
	flex: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	text-align: center;
	color: var(--text-dim);
	font-size: 13px;
}

/* Carries the next race in line, or the day's own message (racing finished), or
   nothing. Rendered in every case, and holding one line's height either way, so the
   widget's reserved height is the same whichever applies. */
.preview-foot {
	margin-top: auto;
	padding: 12px 0 0;
	min-height: 18px;
	color: var(--text-dim);
	font-size: 12px;
}

/* Next-up signpost: quiet by design. It says what is coming, not what is happening --
   so no accent, no pill, nothing that competes with the live race above it. */
.preview-next {
	display: inline-flex;
	align-items: baseline;
	gap: 7px;
	min-width: 0;
}

.preview-next-arrow {
	flex-shrink: 0;
}

.preview-next-label {
	flex-shrink: 0;
	font-size: 10px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.6px;
}

/* The one part at full ink: the race itself is what a reader is meant to take from
   this line. Ellipsized rather than wrapped -- a second line here would cost the
   widget its fixed height. */
.preview-next-race {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	color: var(--text);
	font-weight: 600;
}

.preview-next-mtp {
	flex-shrink: 0;
	font-variant-numeric: tabular-nums;
}
/* ── Features ──
   Says what the site is, and lists what it does beside it. Same 5:6 split and gutter as
   the hero above, so the page keeps one spine: the words on the left, the substance on
   the right. No cards -- panels around a six-word bullet were chrome around nothing. */

.features {
	padding: 56px 0 64px;
}

.features-grid {
	display: grid;
	grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
	gap: 44px;
	align-items: start;
}

.section-title {
	margin: 0 0 12px;
	font-size: 24px;
	font-weight: 700;
	letter-spacing: 0.5px;
}

/* The section's real content now, rather than a caption under the heading -- so it is
   set as prose: reading size, measured line length, full paragraph spacing. */
.section-lede {
	margin: 0;
	max-width: 52ch;
	color: var(--text-dim);
	font-size: 15px;
}

/* A caveat under the paragraph rather than part of it: same voice, a step quieter. */
.section-note {
	margin: 14px 0 0;
	max-width: 52ch;
	color: var(--text-dim);
	font-size: 13px;
}

/* A glossed term -- the words carry a definition on hover. Lifted out of the dim body
   text by mixing a little accent into full-strength ink, which reads as "there is more
   here" without turning into a link, plus a dotted underline saying the same thing more
   plainly. `cursor: help` is the third signal. */
.gloss {
	position: relative;
	color: color-mix(in srgb, var(--accent) 26%, var(--text));
	text-decoration: underline dotted color-mix(in srgb, var(--accent) 45%, transparent);
	text-underline-offset: 3px;
	cursor: help;
}

.gloss:hover,
.gloss:focus-visible {
	color: color-mix(in srgb, var(--accent) 55%, var(--text));
	outline: none;
}

/* The definition itself, in the idiom of the app's chart tooltip: a small panel above
   the term, on one line. Focusable as well as hoverable, so it isn't pointer-only --
   which is also what makes it reachable on a touch screen, where hover never happens. */
.gloss::after {
	content: attr(data-gloss);
	position: absolute;
	left: 0;
	bottom: calc(100% + 8px);
	z-index: 2;
	display: none;
	padding: 6px 9px;
	border: 1px solid var(--border);
	border-radius: 8px;
	background: var(--panel-2);
	box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45);
	color: var(--text);
	font-size: 12px;
	font-weight: 500;
	white-space: nowrap;
	/* The term is underlined; its tooltip shouldn't inherit that. */
	text-decoration: none;
	cursor: default;
}

.gloss:hover::after,
.gloss:focus-visible::after {
	display: block;
}

/* Two columns of three, so six short items read as one block beside the paragraph
   rather than as a long thin list running past it. */
.feature-list {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 12px 24px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.feature-list li {
	display: flex;
	align-items: baseline;
	gap: 10px;
	font-size: 15px;
	font-weight: 600;
}

/* An accent dot rather than a disc: the same amber that marks live state in the app,
   and small enough to read as punctuation. Nudged onto the text's baseline by hand --
   there is nothing inside it to align one with. */
.feature-list li::before {
	content: "";
	flex-shrink: 0;
	width: 5px;
	height: 5px;
	border-radius: 999px;
	background: var(--accent);
	transform: translateY(-3px);
}

/* ── Gallery ──
   A grid of real screens. Each one is a button, not a link: it opens the theater view
   below rather than navigating anywhere, and a button is what that is. */

.gallery {
	padding: 0 0 72px;
}

/* The shared lede rule carries no bottom margin -- beside a paragraph in the features
   section it needs none, above a grid it does. */
.gallery .section-lede {
	margin-bottom: 26px;
}

/* Four to a row, stated rather than fitted: auto-fill would give a different count at
   every width, and the point of a mosaic is that the count is deliberate. One gutter
   value on both axes, so the space between swatches is the same everywhere. */
.gallery-grid {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 12px;
	margin: 0;
	padding: 0;
	list-style: none;
}

/* A square swatch, whatever shape the screen inside it is: ten shots of three different
   aspect ratios read as one grid only if the tiles themselves are identical. The screen
   fills the square like a background, and everything else -- vignette, caption -- is
   layered over it. Hence position: relative, which is also what the hover z-index needs
   to act on. */
.gallery-item {
	position: relative;
	display: block;
	width: 100%;
	aspect-ratio: 1;
	padding: 0;
	/* Flat: square corners and no resting frame. The screen runs to all four edges and
	   the gutter is what separates one swatch from the next -- a border and a radius
	   would draw a card around something that isn't one. */
	border: 0;
	border-radius: 0;
	background: var(--bg);
	color: inherit;
	font: inherit;
	text-align: left;
	overflow: hidden;
	cursor: pointer;
	/* Lifted on hover, so the transform has somewhere to come from. */
	transition: transform 0.16s ease, box-shadow 0.16s ease;
}

/* Bubbles out: up, slightly larger, and over its neighbours. With no border to tint,
   the accent edge is the first of two shadows -- a hairline ring drawn outside the
   swatch -- and the second is the drop that separates it from the grid. */
.gallery-item:hover,
.gallery-item:focus-visible {
	z-index: 1;
	transform: translateY(-4px) scale(1.03);
	box-shadow:
		0 0 0 1px color-mix(in srgb, var(--accent) 70%, transparent),
		0 14px 30px rgba(0, 0, 0, 0.55);
	outline: none;
}

/* The screen as the square's background: covering it edge to edge, cropped rather than
   letterboxed. Anchored to the top, because a UI screenshot's first rows are the part
   that identifies it, and centred horizontally so a wide capture keeps its middle
   instead of one arbitrary edge. The whole screen is one click away in the theater. */
.gallery-item img {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: top center;
}

/* Vignette. Two jobs in one layer: it settles the screenshot into the tile instead of
   letting it butt against four hard edges, and its foot is what the caption is legible
   against. Softer on hover, so the shot lifts and clears as it bubbles out.
   pointer-events: none, or the layer would eat the button's clicks. */
.gallery-item::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background:
		radial-gradient(125% 115% at 50% 38%, rgba(0, 0, 0, 0) 44%, rgba(0, 0, 0, 0.62) 100%),
		linear-gradient(to top, rgba(0, 0, 0, 0.88) 0, rgba(0, 0, 0, 0) 40%);
	transition: opacity 0.16s ease;
}

.gallery-item:hover::after,
.gallery-item:focus-visible::after {
	opacity: 0.72;
}

/* Over the image, on the vignette's dark foot -- no bar, no rule. z-index puts it above
   the vignette layer, which would otherwise be painted on top of it. */
.gallery-caption {
	position: absolute;
	z-index: 1;
	right: 0;
	bottom: 0;
	left: 0;
	padding: 10px 12px;
	color: var(--text);
	font-size: 12px;
	font-weight: 600;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	/* The shot behind it can be anything, so the type carries its own contrast. */
	text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9);
}


/* ── Theater ──
   Built by js/gallery.js on the first open. Fixed to the viewport rather than scrolled
   with the page, and the page itself is locked while it's up. */

.theater {
	position: fixed;
	inset: 0;
	z-index: 100;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 32px;
	background: rgba(0, 0, 0, 0.88);
	-webkit-backdrop-filter: blur(3px);
	backdrop-filter: blur(3px);
}

.theater[hidden] {
	display: none;
}

/* Locks the page behind the overlay. */
body.theater-open {
	overflow: hidden;
}

.theater-frame {
	display: flex;
	flex-direction: column;
	max-width: min(1180px, calc(var(--vw100) * 0.92));
	max-height: calc(var(--vh100) * 0.88);
	min-width: 0;
}

.theater-image {
	display: block;
	max-width: 100%;
	/* Leaves the caption bar its own room inside the frame's height. */
	max-height: calc(var(--vh100) * 0.88 - 46px);
	width: auto;
	height: auto;
	object-fit: contain;
	border: 1px solid var(--border);
	background: var(--bg);
}

.theater-bar {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 16px;
	padding: 12px 2px 0;
	font-size: 13px;
}

.theater-caption {
	font-weight: 600;
}

.theater-count {
	flex-shrink: 0;
	color: var(--text-dim);
	font-size: 12px;
	font-variant-numeric: tabular-nums;
}

/* Nav and close: quiet circles on the backdrop, brightening on hover. Sized for a
   thumb as much as a pointer. */
.theater-nav,
.theater-close {
	position: absolute;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 1px solid var(--border);
	border-radius: 999px;
	background: color-mix(in srgb, var(--panel) 85%, transparent);
	color: var(--text-dim);
	font: inherit;
	line-height: 1;
	cursor: pointer;
	transition: color 0.12s, border-color 0.12s, background 0.12s;
}

.theater-nav:hover,
.theater-close:hover,
.theater-nav:focus-visible,
.theater-close:focus-visible {
	background: var(--panel);
	border-color: var(--accent);
	color: var(--accent);
	outline: none;
}

.theater-nav {
	top: 50%;
	margin-top: -22px;
	font-size: 26px;
	/* The glyphs sit high in their box; nudged back onto the button's centre. */
	padding-bottom: 4px;
}

.theater-nav--prev {
	left: 20px;
}

.theater-nav--next {
	right: 20px;
}

.theater-close {
	top: 20px;
	right: 20px;
	font-size: 24px;
	padding-bottom: 3px;
}

/* Four to a row needs the width; below it, three, then two. */
@media (max-width: 1000px) {
	.gallery-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

@media (max-width: 700px) {
	.gallery-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* Narrow: the arrows move off the picture's sides, where there is no longer room for
   them, and sit under it as a pair. */
@media (max-width: 700px) {
	.theater {
		padding: 16px;
	}

	.theater-frame {
		max-width: 100%;
	}

	.theater-image {
		max-height: calc(var(--vh100) * 0.88 - 110px);
	}

	.theater-nav {
		top: auto;
		bottom: 20px;
		margin-top: 0;
	}

	.theater-nav--prev {
		left: calc(50% - 54px);
	}

	.theater-nav--next {
		right: calc(50% - 54px);
	}
}
/* ── Footer ──
   A black bar closing the page, the way the header and hero open it, with everything
   on one line. Small, tracked-out caps: this is the fine print, and it should read as
   fine print rather than as another section. */

.site-footer {
	padding: 18px 0;
	background: var(--header-bg);
	border-top: 1px solid var(--border);
	color: var(--text-dim);
	font-size: 11px;
	text-transform: uppercase;
	letter-spacing: 0.06em;
}

/* Wraps rather than overflows on a narrow screen; the row gap is what keeps the
   wrapped lines apart, and the column gap doubles as the space around the divider. */
.footer-line {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-wrap: wrap;
	gap: 6px 14px;
}

.footer-sep {
	opacity: 0.45;
}

/* The partners' names, lifted the same way a glossed term is: a little accent mixed
   into full-strength ink, which reads as "this is a name" without turning the line
   into a row of links. */
.footer-brand {
	color: color-mix(in srgb, var(--accent) 26%, var(--text));
	text-decoration: none;
}

.footer-brand:hover {
	color: color-mix(in srgb, var(--accent) 55%, var(--text));
	text-decoration: underline;
}


/* Breakpoints are in REAL viewport px (media queries don't see the body zoom), so
   they fire earlier in authored px than the numbers suggest -- 1180 real px is about
   944 authored, which is where the board's own columns start to crowd. */
@media (max-width: 1180px) {
	/* One column: copy first, board under it. Centred here, because a single narrow
	   column reads better centred than ragged against nothing. */
	.hero-grid {
		grid-template-columns: minmax(0, 1fr);
		gap: 36px;
		justify-items: center;
	}

	.hero-copy {
		text-align: center;
		max-width: 620px;
	}

	/* Flex rows, so the column's text-align above doesn't reach them. */
	.hero-eyebrow,
	.hero-ctas {
		justify-content: center;
	}

	/* The board keeps the column's full width; it has a table to fit. */
	.hero-grid .preview {
		width: 100%;
	}
}

@media (max-width: 900px) {
	.features-grid {
		grid-template-columns: minmax(0, 1fr);
		gap: 28px;
	}
}

@media (max-width: 560px) {
	.feature-list {
		grid-template-columns: minmax(0, 1fr);
		gap: 16px;
	}
}

@media (max-width: 760px) {
	.hero {
		padding: 44px 0 48px;
	}

	.features {
		padding: 40px 0 48px;
	}

	.hero-eyebrow {
		margin-bottom: 10px;
		font-size: 10px;
	}

	.hero-slogan {
		font-size: 26px;
	}

	/* Stack the cluster as a two-item column, as the app's header does when it runs
	   out of room. */
	.brand-home {
		flex-direction: column;
		align-items: flex-start;
		gap: 3px;
	}

	/* The branding was sized for a bar with a page's width to spread across. Stacked
	   into a phone's header beside a button, at the same size, it fills the bar and
	   reads as crammed rather than confident -- so it comes down a step here, and
	   another at the next breakpoint. */
	.site-header {
		gap: 12px;
		padding: 12px 16px;
	}

	.site-header .brand-mark {
		font-size: 18px;
	}

	.site-header .site-sub {
		gap: 4px;
		font-size: 12px;
	}

	.site-header .site-sub-lead,
	.site-header .site-sub-amp {
		font-size: 10px;
	}

	.site-header .site-sub-mark {
		font-size: 13.8px;
	}

	.site-header .site-sub-mark--nyra {
		font-size: 15.4px;
	}
}

/* Only one action fits beside the branding now, and Sign In is the one that matters:
   someone who already has an account and can't get to it is stuck, while someone who
   wants one can reach Register from the hero's Create Free Account -- which is the
   whole point of that button. (This used to be the other way round.) */
@media (max-width: 540px) {
	.site-header .btn-accent {
		display: none;
	}

	.site-header .brand-mark {
		font-size: 16px;
	}

	.site-header .site-sub {
		font-size: 11px;
	}

	.site-header .site-sub-lead,
	.site-header .site-sub-amp {
		font-size: 9px;
	}

	.site-header .site-sub-mark {
		font-size: 11px;
	}

	.site-header .site-sub-mark--nyra {
		font-size: 12.3px;
	}
}

/* Below this the credit line has nowhere left to go: it either wraps or squeezes the
   wordmark, and of the two the wordmark is the one that has to survive. The partners
   are still named in the footer. */
@media (max-width: 400px) {
	.site-header .site-sub {
		display: none;
	}
}
