/* =========================================================================
   Evaria — public marketing site
   Design system read off the nine-panel style board, 2026-09-03.
   Tokens documented in docs/36-public-website/10_design-system.md
   ========================================================================= */

/* ---------- tokens ---------- */
:root {
	--bg: #0d0d0f;
	--surface: #141417;
	--raised: #1a1a1e;
	--border: rgba(255, 255, 255, 0.08);
	--border-strong: rgba(255, 255, 255, 0.14);
	--ink: #f2f2f3;
	--dim: #9b9b9f;

	--accent: #e8622c;
	--accent-ink: #0d0d0f;
	--accent-soft: rgba(232, 98, 44, 0.14);

	/* Content-category colours — a SEPARATE layer from --accent.
	   Accent means "you can act on this". These mean "this is a kind of thing".
	   See 10_design-system.md §1. */
	--cat-food: #3ecf8e;
	--cat-loos: #7e8b9a;
	--cat-wellbeing: #5b8cff;
	--cat-stages: #e8622c;
	--cat-info: #f2c94c;
	--cat-films: #f2704a;
	--cat-polls: #3ecf8e;
	--cat-scoreboards: #9b7ede;
	--cat-hunts: #e8622c;
	--cat-news: #5b8cff;

	--wrap: 1160px;
	--pad: 44px;
	--radius: 14px;
	--radius-sm: 12px;

	--font: "Plus Jakarta Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

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

html {
	scroll-behavior: smooth;
	-webkit-text-size-adjust: 100%;
}

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}
}

body {
	margin: 0;
	background: var(--bg);
	color: var(--ink);
	font-family: var(--font);
	font-size: 16px;
	line-height: 1.6;
	-webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
	margin: 0;
	letter-spacing: -0.025em;
	line-height: 1.1;
	text-wrap: pretty;
	font-weight: 700;
}

p {
	margin: 0;
}

img,
svg {
	max-width: 100%;
	display: block;
}

/* `height: auto` is NOT optional here.
   Every <img> carries width/height attributes so the browser can reserve space
   and avoid layout shift. Without this rule, any image we then size with
   `width: 100%` keeps its ATTRIBUTE height and stretches: the schedule
   screenshot rendered 633x875 against a natural 1400x875 - a 2.2x vertical
   stretch - and the three guest phones the same way. Caught by an automated
   aspect-ratio check, not by eye; it is subtle enough to look "fine" in a
   screenshot. The .hero-bg / .cta-bg rules set height explicitly and win on
   specificity, so full-bleed covers are unaffected. */
img {
	height: auto;
}

a {
	color: var(--accent);
	text-decoration: none;
}

a:hover {
	color: #fff;
}

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

/* Skip link — first thing in the tab order, invisible until focused. */
.skip {
	position: absolute;
	left: -9999px;
	top: 0;
	background: var(--accent);
	color: var(--accent-ink);
	padding: 12px 20px;
	border-radius: 0 0 8px 0;
	font-weight: 600;
	z-index: 100;
}

.skip:focus {
	left: 0;
}

/* ---------- layout ---------- */
.wrap {
	max-width: var(--wrap);
	margin: 0 auto;
	padding: 0 var(--pad);
}

/* `padding-block`, not `padding: 104px 0`. Every `.sec` is also a `.wrap`,
   and the shorthand zeroed the wrap's side padding - at phone width the text
   of every section ran to the screen edge with no gutter, while the header
   above it kept its 28px. Found 2026-11-04 writing privacy.html. */
.sec {
	padding-block: 104px;
}

.band {
	background: var(--surface);
	border-top: 1px solid var(--border);
	border-bottom: 1px solid var(--border);
}

.split {
	display: grid;
	grid-template-columns: 0.85fr 1.15fr;
	gap: 56px;
	align-items: center;
}

.split--narrow-right {
	grid-template-columns: 1.15fr 0.85fr;
}

.stack {
	display: flex;
	flex-direction: column;
	gap: 22px;
}

/* ---------- type ---------- */
.h-xl {
	font-size: clamp(34px, 5vw, 52px);
}
.h-lg {
	font-size: clamp(30px, 4vw, 40px);
}
.h-md {
	font-size: clamp(26px, 3.2vw, 38px);
}

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

.lede {
	font-size: 16.5px;
	color: var(--dim);
	line-height: 1.65;
	max-width: 52ch;
}

.eyebrow {
	font-size: 12.5px;
	font-weight: 700;
	letter-spacing: 0.09em;
	text-transform: uppercase;
	color: var(--accent);
}

.fine {
	font-size: 12.5px;
	color: var(--dim);
}

/* ---------- buttons & links ---------- */
.btn,
.btn-ghost {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	font-family: inherit;
	font-size: 15px;
	border-radius: 999px;
	padding: 13px 26px;
	transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
	white-space: nowrap;
	/* 44px minimum hit target — this site is read on phones in fields. */
	min-height: 44px;
}

.btn {
	background: var(--accent);
	color: var(--accent-ink);
	font-weight: 700;
	border: 1px solid var(--accent);
}

.btn:hover {
	background: #f2743f;
	border-color: #f2743f;
	color: var(--accent-ink);
}

.btn-ghost {
	border: 1px solid var(--border-strong);
	color: var(--ink);
	font-weight: 600;
	background: transparent;
}

.btn-ghost:hover {
	border-color: var(--ink);
	color: var(--ink);
}

.btn-sm {
	padding: 10px 20px;
	font-size: 14px;
}

.link-arrow {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	font-size: 15px;
	font-weight: 600;
	min-height: 44px;
}

.link-arrow svg {
	transition: transform 0.15s ease;
}

.link-arrow:hover svg {
	transform: translateX(3px);
}

.btn-row {
	display: flex;
	gap: 12px;
	flex-wrap: wrap;
}

/* ---------- icons ---------- */
.icon {
	width: 24px;
	height: 24px;
	flex-shrink: 0;
	stroke: currentColor;
	fill: none;
}

.icon-sm {
	width: 18px;
	height: 18px;
}

/* ---------- header ---------- */
.site-header {
	position: sticky;
	top: 0;
	z-index: 40;
	background: rgba(13, 13, 15, 0.84);
	backdrop-filter: blur(16px);
	-webkit-backdrop-filter: blur(16px);
	border-bottom: 1px solid var(--border);
}

.nav {
	display: flex;
	align-items: center;
	justify-content: space-between;
	height: 72px;
	gap: 20px;
}

.brand {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	color: var(--ink);
	font-size: 19px;
	font-weight: 700;
	letter-spacing: -0.02em;
	/* 44px minimum hit target — the logo is a link home and was 30px tall. */
	min-height: 44px;
}

.brand:hover {
	color: var(--ink);
}

.nav-links {
	display: flex;
	gap: 28px;
	align-items: center;
	font-size: 14px;
	font-weight: 600;
}

.nav-links a {
	color: var(--dim);
	padding: 6px 0;
}

.nav-links a:hover,
.nav-links a[aria-current="page"] {
	color: var(--ink);
}

.nav-links a[aria-current="page"] {
	color: var(--accent);
}

.nav-toggle {
	display: none;
	background: transparent;
	border: 1px solid var(--border-strong);
	border-radius: 10px;
	width: 44px;
	height: 44px;
	align-items: center;
	justify-content: center;
	color: var(--ink);
	cursor: pointer;
}

/* ---------- hero ---------- */
.hero {
	position: relative;
	overflow: hidden;
	border-bottom: 1px solid var(--border);
	isolation: isolate;
}

.hero-bg {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0.4;
	z-index: -2;
}

.hero-veil {
	position: absolute;
	inset: 0;
	z-index: -1;
	background: linear-gradient(
		100deg,
		var(--bg) 32%,
		rgba(13, 13, 15, 0.74) 60%,
		rgba(13, 13, 15, 0.48)
	);
}

.hero-inner {
	padding: 104px 0 88px;
	max-width: 640px;
}

/* ---------- trust badges ---------- */
.badges {
	display: flex;
	gap: 34px;
	flex-wrap: wrap;
	margin-top: 34px;
	padding-top: 30px;
	border-top: 1px solid var(--border);
}

.badge {
	display: flex;
	align-items: flex-start;
	gap: 11px;
	max-width: 215px;
}

.badge-ring {
	width: 28px;
	height: 28px;
	border-radius: 50%;
	border: 1px solid var(--accent);
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--accent);
	flex-shrink: 0;
}

.badge-ring .icon {
	width: 14px;
	height: 14px;
}

.badge-t {
	font-size: 13.5px;
	font-weight: 700;
	line-height: 1.35;
}

.badge-s {
	font-size: 12.5px;
	color: var(--dim);
	line-height: 1.45;
}

/* ---------- checklists ---------- */
.checks {
	display: flex;
	flex-direction: column;
	gap: 13px;
	list-style: none;
	margin: 0;
	padding: 0;
}

.checks li {
	display: flex;
	align-items: flex-start;
	gap: 11px;
	font-size: 15px;
	line-height: 1.5;
}

.checks .icon {
	color: var(--accent);
	margin-top: 1px;
}

/* ---------- map cards ---------- */
.map-stack {
	position: relative;
	min-height: 440px;
}

.map-card {
	position: absolute;
	border-radius: var(--radius);
	overflow: hidden;
	border: 1px solid var(--border);
	box-shadow: 0 34px 70px -26px rgba(0, 0, 0, 0.85);
}

.map-card img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.map-card--1 {
	left: 0;
	top: 30px;
	width: 46%;
	height: 340px;
	transform: rotate(-7deg);
}

.map-card--2 {
	left: 27%;
	top: 8px;
	width: 46%;
	height: 366px;
	transform: rotate(-1.5deg);
}

.map-card--3 {
	left: 54%;
	top: 38px;
	width: 46%;
	height: 352px;
	transform: rotate(4.5deg);
	box-shadow: 0 40px 80px -26px rgba(232, 98, 44, 0.32);
}

.map-caption {
	position: absolute;
	bottom: -34px;
	left: 0;
	right: 0;
	text-align: center;
	font-size: 12.5px;
	color: var(--dim);
}

/* ---------- app window frame ---------- */
.window {
	border-radius: var(--radius);
	overflow: hidden;
	background: var(--raised);
	border: 1px solid var(--border);
	box-shadow: 0 40px 90px -34px rgba(0, 0, 0, 0.9);
}

.window-bar {
	height: 38px;
	background: #1f1f24;
	display: flex;
	align-items: center;
	gap: 7px;
	padding: 0 14px;
	border-bottom: 1px solid var(--border);
}

.window-bar span {
	width: 9px;
	height: 9px;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.16);
}

.window img {
	width: 100%;
}

/* ---------- category tiles ---------- */
.cat-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 14px;
}

.cat {
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	padding: 22px;
	display: flex;
	flex-direction: column;
	gap: 9px;
}

.cat .icon {
	width: 24px;
	height: 24px;
}

.cat-t {
	font-size: 15.5px;
	font-weight: 700;
}

.cat-s {
	font-size: 13px;
	color: var(--dim);
	line-height: 1.5;
}

/* ---------- feature columns ---------- */
.feat-grid {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 28px;
	margin-top: 52px;
}

.feat {
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.feat .icon {
	width: 30px;
	height: 30px;
}

.feat-t {
	font-size: 16.5px;
	font-weight: 700;
}

/* ---------- phones ---------- */
.phones {
	display: flex;
	gap: 20px;
	justify-content: center;
	align-items: flex-start;
}

.phone {
	border-radius: 32px;
	padding: 8px;
	background: var(--raised);
	border: 1px solid var(--border-strong);
	box-shadow: 0 34px 70px -30px rgba(0, 0, 0, 0.9);
	flex: 1 1 0;
	max-width: 200px;
	margin-top: 48px;
}

.phone-screen {
	border-radius: 24px;
	overflow: hidden;
	background: var(--bg);
}

/* The middle phone leads: real event branding + the whole feature menu in
   one frame. See 12_screenshot-templates.md. */
.phone--lead {
	max-width: 228px;
	margin-top: 0;
	border-radius: 36px;
	padding: 9px;
	border-color: rgba(255, 255, 255, 0.2);
	box-shadow: 0 44px 90px -28px rgba(232, 98, 44, 0.36);
}

.phone--lead .phone-screen {
	border-radius: 27px;
}

/* ---------- process steps ---------- */
.steps {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 24px;
	margin-top: 52px;
	align-items: start;
}

.step {
	display: flex;
	flex-direction: column;
	gap: 13px;
}

.step-icon {
	width: 54px;
	height: 54px;
	border-radius: var(--radius);
	background: var(--surface);
	border: 1px solid var(--border);
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--accent);
}

.step-n {
	font-size: 12px;
	font-weight: 800;
	color: var(--accent);
	letter-spacing: 0.04em;
}

.step-t {
	font-size: 17.5px;
	font-weight: 700;
}

/* ---------- pricing ---------- */
.tiers {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 20px;
	align-items: start;
}

.tier {
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	padding: 32px;
	display: flex;
	flex-direction: column;
	gap: 20px;
}

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

/* Four bands - a free tier and three sized by attendance. Two-up before it
   collapses to one, because four columns at tablet width leaves each card
   about 160px for a price. */
.tiers--4 {
	grid-template-columns: repeat(4, minmax(0, 1fr));
}

.tiers--4 .tier {
	padding: 28px 24px;
}

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

.tier-cap {
	font-size: 14px;
	font-weight: 700;
	color: var(--ink);
	margin-top: -8px;
}

.tier-more {
	margin-top: 28px;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	padding: 28px 32px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	flex-wrap: wrap;
}

.tier-more p {
	color: var(--dim);
	font-size: 15px;
	max-width: 62ch;
}

.price-notes {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 28px;
	margin-top: 44px;
}

.price-notes h3 {
	font-size: 16px;
	margin-bottom: 8px;
}

.price-notes p {
	color: var(--dim);
	font-size: 14.5px;
	line-height: 1.65;
}

@media (max-width: 960px) {
	.price-notes {
		grid-template-columns: 1fr;
	}
}

.tier-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
}

.tier-name {
	font-size: 19px;
	font-weight: 700;
}

.tier-for {
	font-size: 13px;
	color: var(--dim);
	margin-top: 5px;
}

.tier-price {
	display: flex;
	align-items: baseline;
	gap: 7px;
	font-size: 32px;
	font-weight: 800;
	letter-spacing: -0.02em;
}

.tier-per {
	font-size: 13px;
	font-weight: 500;
	color: var(--dim);
}

.pill {
	background: var(--accent);
	color: var(--accent-ink);
	font-size: 11.5px;
	font-weight: 800;
	padding: 5px 11px;
	border-radius: 999px;
	white-space: nowrap;
}

.tier-list {
	display: flex;
	flex-direction: column;
	gap: 13px;
	border-top: 1px solid var(--border);
	padding-top: 22px;
	list-style: none;
	margin: 0;
}

.tier-list li {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	font-size: 14px;
	color: var(--dim);
	line-height: 1.5;
}

.tier-list .icon {
	width: 16px;
	height: 16px;
	color: var(--accent);
	margin-top: 3px;
}

/* Placeholder values still to be set by the owner — visibly marked, never
   quietly invented. See 08_launch-checklist-and-open-questions.md. */
.tbd {
	color: var(--accent);
	font-variant-numeric: tabular-nums;
}

/* ---------- CTA ---------- */
.cta {
	position: relative;
	overflow: hidden;
	border-top: 1px solid var(--border);
	isolation: isolate;
}

.cta-bg {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0.28;
	z-index: -2;
}

.cta-veil {
	position: absolute;
	inset: 0;
	z-index: -1;
	background: linear-gradient(180deg, rgba(13, 13, 15, 0.9), rgba(13, 13, 15, 0.97));
}

.cta-inner {
	padding: 104px 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: 24px;
}

.cta-inner .lede {
	max-width: 46ch;
}

.cta .badges {
	justify-content: center;
	border-top: 0;
	padding-top: 0;
}

/* ---------- footer ---------- */
.site-footer {
	border-top: 1px solid var(--border);
}

.footer-inner {
	padding: 44px 0;
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 20px;
}

.footer-links {
	display: flex;
	gap: 26px;
	font-size: 13.5px;
	flex-wrap: wrap;
}

.footer-links a {
	color: var(--dim);
}

.footer-links a:hover {
	color: var(--ink);
}

/* ---------- prose (privacy page) ---------- */
.prose {
	max-width: 68ch;
}

.prose h2 {
	font-size: 22px;
	margin: 40px 0 12px;
}

.prose p,
.prose li {
	color: var(--dim);
	font-size: 15.5px;
	line-height: 1.7;
}

.prose p + p {
	margin-top: 14px;
}

.prose ul {
	padding-left: 20px;
	margin: 12px 0;
}

.prose li + li {
	margin-top: 8px;
}

.notice {
	background: var(--accent-soft);
	border: 1px solid var(--accent);
	border-radius: var(--radius-sm);
	padding: 20px 24px;
	margin-bottom: 32px;
}

.notice p {
	color: var(--ink);
	font-size: 15px;
}

.notice p + p {
	margin-top: 10px;
}

/* The policy's sub-sections and its "what, where, how long" tables. A table
   is the honest shape for a storage inventory: a reader checks one row, not
   a paragraph. It scrolls inside its own box at phone width rather than
   pushing the page sideways. */
.prose h3 {
	font-size: 17px;
	margin: 28px 0 10px;
}

.prose strong {
	color: var(--ink);
}

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

.prose-meta {
	color: var(--dim);
	font-size: 14px;
	margin-bottom: 28px;
}

.table-scroll {
	overflow-x: auto;
	margin: 16px 0 8px;
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
}

.prose table {
	width: 100%;
	border-collapse: collapse;
	font-size: 14px;
	line-height: 1.55;
}

.prose th,
.prose td {
	text-align: left;
	vertical-align: top;
	padding: 11px 14px;
	border-bottom: 1px solid var(--border);
	color: var(--dim);
}

.prose th {
	color: var(--ink);
	font-weight: 700;
	background: var(--surface);
}

.prose tr:last-child td {
	border-bottom: 0;
}

.prose td:first-child {
	color: var(--ink);
	min-width: 140px;
}

.toc {
	columns: 2;
	column-gap: 32px;
}

@media (max-width: 720px) {
	.toc {
		columns: 1;
	}
}

/* ---------- the live demo (/demo.html) ----------
   The frame is a CSS build of docs/36 §12's `frame-phone.svg`: 430x884 case,
   52px outer radius, a 20px bezel and a 34px screen radius, with the same
   3px inner edge. Same numbers, because the same drawing appears as a static
   image elsewhere on this site and the two should not disagree.

   THE SCREEN IS AN ASPECT RATIO, NOT A FIXED 390x844. The app inside is a
   phone app and lays itself out for whatever width it is given, so a narrow
   viewport gets a smaller phone rather than a scaled-down one - no blurred
   text, and the app's own breakpoints stay honest. It also keeps the frame
   below 769px, which is where userV9 draws its OWN desktop phone frame
   (`P88`); two nested phone frames would be the joke this page cannot make. */
/* `padding-block`, NOT the `padding` shorthand: this element is also a
   `.wrap`, and a shorthand here resets its horizontal gutter to zero. Measured
   at 375px, where the phone frame ran edge to edge with no page margin. */
.demo-sec {
	padding-top: 44px;
	padding-bottom: 100px;
}

.demo-layout {
	display: grid;
	grid-template-columns: 430px minmax(0, 1fr);
	gap: 56px;
	align-items: start;
}

.demo-phone {
	position: relative;
	width: 430px;
	max-width: 100%;
	padding: 20px;
	border-radius: 52px;
	background: var(--raised);
	border: 1px solid var(--border-strong);
	box-shadow: 0 50px 100px -34px rgba(0, 0, 0, 0.95);
}

/* The side buttons from the template - volume pair left, wake right. */
.demo-phone::before,
.demo-phone::after {
	content: "";
	position: absolute;
	width: 3px;
	border-radius: 2px;
	background: rgba(255, 255, 255, 0.16);
}

.demo-phone::before {
	left: -2px;
	top: 22%;
	height: 118px;
}

.demo-phone::after {
	right: -2px;
	top: 26%;
	height: 86px;
}

.demo-screen {
	position: relative;
	aspect-ratio: 390 / 844;
	border-radius: 34px;
	overflow: hidden;
	background: var(--bg);
	box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.9);
}

.demo-screen > picture {
	display: block;
	position: absolute;
	inset: 0;
}

/* `cover`, and `height` beats the global `img { height: auto }` by
   specificity: the poster is a 520x1048 capture and the slot is 390x844, so
   something has to give and it should not be the aspect ratio. */
.demo-screen img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: top center;
}

/* Dimmed until it is live, so the button on top of it reads as a control
   rather than as part of the screenshot. */
.demo-screen:not(.is-live)::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background: linear-gradient(180deg, rgba(13, 13, 15, 0.5), rgba(13, 13, 15, 0.78));
}

.demo-screen > iframe {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
	display: none;
	/* The app paints its own background over this the moment it boots; the
	   colour is here so the cut from poster to app is not through white. */
	background: var(--bg);
}

.demo-screen.is-live > iframe {
	display: block;
}

.demo-play {
	position: absolute;
	z-index: 2;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
	box-shadow: 0 20px 44px -14px rgba(0, 0, 0, 0.9);
	cursor: pointer;
}

.demo-play[disabled] {
	opacity: 0.6;
	cursor: progress;
}

/* The same trap as `.demo-tour[hidden]` below, twice more: `display` on an
   element that something toggles has to say what hidden means, or the
   browser's own `[hidden] { display: none }` loses. Measured with the app
   already running in the frame and "Open the app" still sitting on top of it. */
.demo-play[hidden],
.demo-screen > picture[hidden] {
	display: none;
}

.demo-side {
	padding-top: 8px;
}

.demo-consent {
	max-width: 460px;
	padding: 26px 28px;
	border: 1px solid var(--border-strong);
	border-radius: var(--radius);
	background: var(--raised);
	color: var(--ink);
}

.demo-consent::backdrop {
	background: rgba(0, 0, 0, 0.66);
}

.demo-consent h2 {
	font-size: 19px;
	margin: 0 0 12px;
}

.demo-consent p {
	font-size: 14px;
	line-height: 1.6;
	margin: 0 0 12px;
	color: var(--dim);
}

.demo-consent ul {
	margin: 0 0 16px;
	padding-left: 18px;
	font-size: 14px;
	line-height: 1.6;
	color: var(--dim);
}

.demo-consent li {
	margin-bottom: 7px;
}

.demo-consent strong {
	color: var(--ink);
	font-weight: 600;
}

.demo-consent-actions {
	display: flex;
	gap: 10px;
	justify-content: flex-end;
	margin-top: 18px;
}

.demo-installed {
	display: flex;
	align-items: center;
	gap: 10px;
	flex-wrap: wrap;
	font-size: 13px;
	color: var(--dim);
	margin: 0;
}

.demo-installed[hidden] {
	display: none;
}

.demo-erase {
	font-family: inherit;
	font-size: 13px;
	font-weight: 600;
	color: var(--ink);
	background: none;
	border: 1px solid var(--border-strong);
	border-radius: 999px;
	padding: 5px 12px;
	cursor: pointer;
}

.demo-os {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
}

.demo-os-label {
	font-size: 13px;
	color: var(--dim);
	margin-right: 2px;
}

.demo-os-btn {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-family: inherit;
	font-size: 13.5px;
	font-weight: 600;
	color: var(--ink);
	background: var(--surface);
	border: 1px solid var(--border-strong);
	border-radius: 999px;
	padding: 6px 13px 6px 11px;
	cursor: pointer;
}

/* `aria-pressed` IS the state, rather than a class kept in step with it.
   There is one source of truth for which platform is showing, and a screen
   reader and a sighted visitor are reading the same one. */
.demo-os-btn[aria-pressed="true"] {
	color: var(--accent);
	border-color: var(--accent);
}

.demo-os-btn[disabled] {
	opacity: 0.5;
	cursor: progress;
}

/* A developer-only line, and it should look like one: this is the note that
   says the local server is not proxying the API. `display` has to say what
   hidden means here for the same reason it does three rules above. */
.demo-devnote {
	font-size: 13px;
	line-height: 1.5;
	color: var(--accent);
	border-left: 2px solid var(--accent);
	padding-left: 10px;
	margin: 0;
}

.demo-devnote[hidden] {
	display: none;
}

.demo-tour {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

/* `display: flex` beats the browser's own `[hidden] { display: none }`, which
   is a two-line bug that renders a dead tour beside a phone that has not been
   opened yet. Same trap as `.demo-status:empty` below - a display rule on an
   element something toggles has to say what hidden means. */
.demo-tour[hidden] {
	display: none;
}

.demo-btn {
	font-family: inherit;
	font-size: 14.5px;
	font-weight: 600;
	color: var(--ink);
	background: var(--surface);
	border: 1px solid var(--border-strong);
	border-radius: 999px;
	padding: 11px 20px;
	min-height: 44px;
	cursor: pointer;
	transition: border-color 0.15s ease, color 0.15s ease, background-color 0.15s ease;
}

.demo-btn:hover:not([disabled]) {
	border-color: var(--ink);
}

.demo-btn[disabled] {
	opacity: 0.55;
	cursor: progress;
}

/* Which stop the frame is showing. The app has its own idea of where it is;
   this only says which button put it there. */
.demo-btn.is-on {
	border-color: var(--accent);
	background: var(--accent-soft);
	color: var(--accent);
}

.demo-btn--back {
	background: transparent;
	color: var(--dim);
	font-weight: 500;
}

.demo-status {
	font-size: 14px;
	color: var(--dim);
	display: flex;
	align-items: center;
	gap: 10px;
	min-height: 22px;
}

.demo-status:empty {
	display: none;
}

/* A dot, not a spinner, and never on its own - `CLAUDE.md`: a spinner with no
   text is a black frame in the middle of a scene. Every message this sits
   beside says which step is running. */
.demo-status.is-busy::before {
	content: "";
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: var(--accent);
	flex-shrink: 0;
	animation: demo-pulse 1.1s ease-in-out infinite;
}

@keyframes demo-pulse {
	0%,
	100% {
		opacity: 0.25;
		transform: scale(0.8);
	}
	50% {
		opacity: 1;
		transform: scale(1);
	}
}

.demo-checks {
	margin-top: 4px;
}

/* =========================================================================
   RESPONSIVE
   The board is a desktop composition. Everything below is the phone/tablet
   behaviour it doesn't specify. 430px is the target this project cares about
   most — a real phone, held in a field.
   ========================================================================= */

@media (max-width: 960px) {
	:root {
		--pad: 28px;
	}

	.sec {
		padding-block: 72px;
	}

	.split,
	.split--narrow-right {
		grid-template-columns: 1fr;
		gap: 40px;
	}

	/* Text always leads on small screens, whatever the DOM order is. */
	.split > .stack {
		order: -1;
	}

	.nav-links {
		display: none;
	}

	.nav-links.is-open {
		display: flex;
		position: absolute;
		top: 72px;
		left: 0;
		right: 0;
		flex-direction: column;
		gap: 0;
		background: var(--bg);
		border-bottom: 1px solid var(--border);
		padding: 8px var(--pad) 20px;
	}

	.nav-links.is-open a {
		padding: 14px 0;
		border-bottom: 1px solid var(--border);
		font-size: 16px;
	}

	.nav-toggle {
		display: inline-flex;
	}

	.nav .btn {
		display: none;
	}

	.feat-grid,
	.steps {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 32px 24px;
	}

	.tiers {
		grid-template-columns: 1fr;
	}

	.hero-inner {
		padding: 72px 0 64px;
	}

	.hero-veil {
		background: linear-gradient(170deg, rgba(13, 13, 15, 0.82), rgba(13, 13, 15, 0.95));
	}
}

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

	/* The rotated overlap needs width it doesn't have on a phone.
	   Below 720 the three map cards become an honest horizontal scroller —
	   still the same three real renders, still in order. */
	.map-stack {
		display: flex;
		gap: 14px;
		overflow-x: auto;
		min-height: 0;
		padding-bottom: 12px;
		scroll-snap-type: x mandatory;
		-webkit-overflow-scrolling: touch;
	}

	.map-card {
		position: static;
		transform: none;
		width: 72%;
		height: 300px;
		flex: 0 0 auto;
		scroll-snap-align: center;
		box-shadow: none;
	}

	.map-caption {
		position: static;
		margin-top: 10px;
		text-align: left;
	}

	.phones {
		gap: 12px;
	}

	.phone {
		margin-top: 0;
		border-radius: 22px;
		padding: 5px;
	}

	.phone-screen {
		border-radius: 17px;
	}

	.phone--lead {
		border-radius: 24px;
		padding: 6px;
	}

	.phone--lead .phone-screen {
		border-radius: 18px;
	}

	.badges {
		gap: 20px;
	}
}

@media (max-width: 480px) {
	.feat-grid,
	.steps,
	.cat-grid {
		grid-template-columns: 1fr;
	}

	.btn-row .btn,
	.btn-row .btn-ghost {
		width: 100%;
	}

	.badge {
		max-width: none;
	}
}

/* ---------- the live demo, small screens ----------
   Read on a phone, the demo IS a phone, so the frame stops being furniture and
   just gets out of the way: no fake case worth 40px of a 390px screen, and the
   tour below the app rather than beside it. */
@media (max-width: 960px) {
	.demo-layout {
		grid-template-columns: minmax(0, 1fr);
		gap: 36px;
		justify-items: center;
	}

	.demo-side {
		width: 100%;
		max-width: 560px;
	}

	.demo-sec {
		padding-top: 32px;
		padding-bottom: 76px;
	}
}

/* THE FRAME COMES OFF ON A PHONE, AND THAT IS THE SAME RULE `P88` FOLLOWS.
   The guest app draws its OWN 390x844 phone above 768px and goes full-bleed
   below it, for the reason a frame inside a frame is not a picture of a phone,
   it is a joke about one. This is that rule applied to the frame around it.

   It is also arithmetic. At 375px the page gutter and the bezel took 56px, so
   the app rendered at 319 - narrower than any phone made - and clipped its own
   splash title to "DAY OF THE DEA". Full-bleed hands it the whole 375, which
   is a real device width and what the app is designed for. Measured at the
   mobile preset, which is where almost everybody will read this page.

   The negative margins cancel `.wrap`'s gutter exactly rather than using
   `100vw`, which overshoots by the width of a scrollbar wherever there is one. */
@media (max-width: 520px) {
	.demo-phone {
		padding: 0;
		border: 0;
		border-radius: 0;
		box-shadow: none;
		/* `justify-self`, or the negative margins below do nothing: the grid
		   above sets `justify-items: center`, which sizes this to its content
		   and then centres it — so the margins only move the centring and the
		   app stays 319px wide. Stretch first, then pull out to the edges. */
		justify-self: stretch;
		width: auto;
		max-width: none;
		margin-left: calc(-1 * var(--pad));
		margin-right: calc(-1 * var(--pad));
	}

	.demo-screen {
		border-radius: 0;
		box-shadow: none;
	}

	.demo-phone::before,
	.demo-phone::after {
		display: none;
	}

	.demo-btn {
		flex: 1 1 100%;
	}
}
