/* The only stylesheet on the site.
 *
 * Hand-written, no framework. The colours, type scale, radii and shadows come from
 * docs/visual_identity.md; the Bootstrap application that document describes is not used here,
 * because the website is plain HTML (AGENT_GUIDE section 6).
 *
 * The look since step 8.3: an Emerald hero, then sections that take turns on the house colours -
 * Porcelain, the panel grey, Graphite and a Khaki tint - so the page has rhythm without boxes
 * everywhere. Deliberately absent, because they are what a generated landing page looks like:
 * gradients, icon cards, stock pictures, emoji, and things that animate as you scroll.
 *
 * Light mode only. There is no dark-mode toggle and no prefers-color-scheme block: the
 * founder asked for a light background, and BUILD_BRIEF section 8 rules out the toggle.
 *
 * Loaded by: every page under website/, and the admin view in backend/waitlist/routes.py.
 */

/* ---------------------------------------------------------------------------
 * The typeface, served from our own origin.
 *
 * Both files are variable fonts covering the whole weight range, so there is one file per
 * character subset rather than one per weight, and font-weight below is a range.
 * website/fonts/README.md says where they came from and why they are not loaded from a CDN.
 * ------------------------------------------------------------------------ */

@font-face {
	font-family: "Hanken Grotesk";
	src: url("/fonts/hanken-grotesk-latin.woff2") format("woff2");
	font-weight: 100 900;
	font-style: normal;
	font-display: swap;
	/* Finnish lives entirely in this range, including ä, ö and å. */
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
		U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
		U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Hanken Grotesk";
	src: url("/fonts/hanken-grotesk-latin-ext.woff2") format("woff2");
	font-weight: 100 900;
	font-style: normal;
	font-display: swap;
	/* š, ž and the rest. The browser only fetches this file if the page uses one of them. */
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
		U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
		U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------------------------------------------------------------------------
 * Tokens. Every colour and size on the site is named here and nowhere else, so the palette
 * can be checked against docs/visual_identity.md in one place.
 * ------------------------------------------------------------------------ */

:root {
	/* From the identity document. */
	--emerald: #284139;
	--emerald-dark: #1e332c; /* the identity document's primary-button hover */
	--khaki: #f8d794;
	--wasabi: #809076;
	--earth: #b86830; /* warnings only, as the identity document says */
	--noir: #111a19;

	/* Neutrals. */
	--porcelain: #f3f4f1;
	--moss: #c9d2c5;
	--graphite: #232827;

	/* Semantic tokens, light mode. */
	--surface-page: var(--porcelain);
	--surface-panel: #e8eae6; /* S1 */
	--surface-raised: #f0f2ee; /* S2: inputs */
	--text-primary: var(--noir);
	--text-body: #2d3230;
	--text-muted: #5a6359;
	--border-default: var(--moss);

	/* On the dark section and the footer: the identity document's dark-mode body text. */
	--text-on-dark: #d5d9d3;

	/* Khaki mixed a third into Porcelain, for the Get Verho section. Khaki at full strength is kept
	 * for the one button that matters, so the two never compete. */
	--khaki-tint: #f5ead0;
	--khaki-hover: #f2ca7a;

	/* Radii. */
	--radius-sm: 0.375rem;
	--radius-md: 0.5rem;
	--radius-lg: 0.75rem;

	/* Elevation. Neumorphic E1 for the video, a plain float for the menu and the form card,
	 * which sit on coloured backgrounds where the white half of E1 would show as a smudge. */
	--shadow-e1: 6px 6px 12px rgba(180, 185, 175, 0.5), -6px -6px 12px rgba(255, 255, 255, 0.8);
	--shadow-float: 0 1px 2px rgba(17, 26, 25, 0.06), 0 12px 32px rgba(17, 26, 25, 0.12);

	/* Layout. --page is the one column everything on the page shares: the header, the hero's
	 * heading, the text, the video and the footer. The founder asked twice for headings and
	 * text to be the same width, so nothing is narrower than this except notes and the form.
	 *
	 * --measure is kept for secondary text only - the consent line, captions, notes - where a
	 * shorter line is easier to read. */
	--measure: 44rem;
	--page: 58rem;
	--gutter: 1.25rem;
	--header-height: 3.75rem;
}

/* ---------------------------------------------------------------------------
 * Base.
 * ------------------------------------------------------------------------ */

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

html {
	/* Anchor links land below the sticky header rather than under it. */
	scroll-padding-top: calc(var(--header-height) + 1rem);
}

/* The Get Verho button and the menu scroll to their section rather than jump, unless the visitor
 * has asked their system for less motion. */
@media (prefers-reduced-motion: no-preference) {
	html {
		scroll-behavior: smooth;
	}
}

body {
	margin: 0;
	background: var(--surface-page);
	color: var(--text-body);
	font-family: "Hanken Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
	font-size: 1rem;
	line-height: 1.55;
	/* Never let a long word or a wide element push the page sideways on a phone. */
	overflow-wrap: break-word;
}

h1,
h2,
h3 {
	color: var(--text-primary);
	font-weight: 600;
	line-height: 1.25;
	margin: 2.5rem 0 0.75rem;
}

h1 {
	font-size: 2rem;
	margin-top: 0;
}

h2 {
	font-size: 1.5rem;
}

h3 {
	font-size: 1.25rem;
}

p,
ul,
ol {
	margin: 0 0 1rem;
}

a {
	color: var(--emerald);
	text-underline-offset: 0.15em;
}

a:hover {
	color: var(--noir);
}

/* One focus style for the whole site, using the identity document's Wasabi focus ring.
 * Keyboard users need to see where they are; mouse users do not get the ring. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
summary:focus-visible,
video:focus-visible {
	outline: 2px solid var(--wasabi);
	outline-offset: 2px;
	border-radius: var(--radius-sm);
}

/* On Emerald and Graphite a Wasabi ring disappears, so it turns Khaki there. */
.hero a:focus-visible,
.section--dark a:focus-visible,
.site-footer a:focus-visible {
	outline-color: var(--khaki);
}

/* The skip link is invisible until it is focused, which is the first thing a keyboard user
 * reaches on the page. */
.skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	background: var(--emerald);
	color: var(--porcelain);
	padding: 0.5rem 1rem;
	z-index: 30;
}

.skip-link:focus {
	left: 0;
}

/* Shown to nobody, read aloud by a screen reader: the word for a tick or a dash in the pricing
 * table (step 9.2b). */
.visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.muted {
	color: var(--text-muted);
	font-size: 0.875rem;
}

.lead {
	font-size: 1.125rem;
	color: var(--text-body);
}

/* ---------------------------------------------------------------------------
 * The wordmark: Verho, reversed out on an Emerald chip.
 * ------------------------------------------------------------------------ */

.wordmark {
	display: inline-flex;
	align-items: baseline;
	font-size: 1.25rem;
	font-weight: 600;
	letter-spacing: 0.01em;
	color: var(--text-primary);
	text-decoration: none;
}

.wordmark:hover {
	color: var(--text-primary);
}

/* The header's wordmark (step 9.2d): the logo, then Verho in dark type, no chip behind it. The
 * logo is the icon the other agent recommended in step 9.2c's third round (solid-white), copied
 * from its renders into website/icons/logo-32.png and logo-180.png, the larger for sharp
 * screens. */
.wordmark--logo {
	align-items: center;
	gap: 0.5rem;
}

.wordmark__logo {
	display: block;
	flex-shrink: 0;
}

.wordmark__chip {
	background: var(--emerald);
	color: var(--porcelain);
	border-radius: var(--radius-sm);
	padding: 0.05em 0.18em;
	margin: 0 0.03em;
}

/* ---------------------------------------------------------------------------
 * Buttons. One shape; Emerald on light backgrounds, Khaki on dark ones.
 * ------------------------------------------------------------------------ */

.button {
	display: inline-block;
	background: var(--emerald);
	color: var(--porcelain);
	border: 0;
	border-radius: var(--radius-md);
	padding: 0.6rem 1.15rem;
	font: inherit;
	font-weight: 600;
	line-height: 1.3;
	text-decoration: none;
	cursor: pointer;
	transition: background-color 0.15s ease;
}

.button:hover {
	background: var(--emerald-dark);
	color: var(--porcelain);
}

.button--light {
	background: var(--khaki);
	color: var(--noir);
}

.button--light:hover {
	background: var(--khaki-hover);
	color: var(--noir);
}

.button--large {
	padding: 0.85rem 1.5rem;
	font-size: 1.0625rem;
}

.button--small {
	padding: 0.45rem 0.85rem;
	font-size: 0.9375rem;
}

/* ---------------------------------------------------------------------------
 * The header: the wordmark, Sign in, the Get Verho button and the menu, held at the top of the
 * screen.
 * ------------------------------------------------------------------------ */

.site-header {
	position: sticky;
	top: 0;
	z-index: 20;
	background: var(--surface-page);
	border-bottom: 1px solid var(--border-default);
}

.site-header__inner {
	max-width: var(--page);
	min-height: var(--header-height);
	margin: 0 auto;
	padding: 0.5rem var(--gutter);
	display: flex;
	align-items: center;
	gap: 0.75rem;
}

/* Sign in (step 9.2b): a plain link, so that Get Verho stays the one button. It pushes itself,
 * the button and the menu to the right. */
.site-header__sign-in {
	margin-left: auto;
	padding: 0.45rem 0.25rem;
	color: var(--text-primary);
	font-size: 0.9375rem;
	font-weight: 600;
	text-decoration: none;
	white-space: nowrap;
}

.site-header__sign-in:hover {
	color: var(--emerald);
	text-decoration: underline;
}

/* Below 360 pixels the four do not fit on one line in Finnish; Sign in is in the menu as well. */
@media (max-width: 22.4rem) {
	.site-header__sign-in {
		display: none;
	}

	.site-header .button--small {
		margin-left: auto;
	}
}

/* The menu. A <details> element, so it opens and closes with no JavaScript at all; site.js
 * only closes it after a link is chosen, on Escape and on a click elsewhere. The panel drops
 * down under the button, over the page. */
.menu {
	position: relative;
}

.menu__button {
	list-style: none;
	display: flex;
	align-items: center;
	gap: 0.45rem;
	min-height: 2.5rem;
	padding: 0.4rem 0.7rem;
	border: 1px solid var(--border-default);
	border-radius: var(--radius-md);
	color: var(--text-primary);
	font-size: 0.9375rem;
	font-weight: 600;
	cursor: pointer;
	user-select: none;
	transition: border-color 0.15s ease;
}

/* Safari draws its own triangle unless told not to. */
.menu__button::-webkit-details-marker {
	display: none;
}

.menu__button:hover {
	border-color: var(--wasabi);
}

.menu[open] .menu__button {
	background: var(--surface-panel);
}

.menu__icon {
	display: block;
}

.menu__icon--close,
.menu[open] .menu__icon--open {
	display: none;
}

.menu[open] .menu__icon--close {
	display: block;
}

.menu__panel {
	position: absolute;
	right: 0;
	top: calc(100% + 0.6rem);
	width: min(19rem, calc(100vw - 2 * var(--gutter)));
	background: var(--surface-page);
	border: 1px solid var(--border-default);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-float);
	padding: 0.5rem;
	display: grid;
}

.menu__sections {
	display: grid;
}

.menu__panel a {
	padding: 0.7rem 0.8rem;
	border-radius: var(--radius-md);
	color: var(--text-primary);
	text-decoration: none;
	font-weight: 500;
}

.menu__panel a:hover {
	background: var(--surface-panel);
	color: var(--emerald);
}

/* The languages, each in its own name, under a rule. A visitor who lands on a page they cannot
 * read still recognises the three bars and, inside, the name of their own language. */
.menu__languages {
	display: flex;
	flex-wrap: wrap;
	gap: 0.15rem;
	margin-top: 0.35rem;
	padding-top: 0.5rem;
	border-top: 1px solid var(--border-default);
}

.menu__languages a {
	padding: 0.45rem 0.65rem;
	font-size: 0.9375rem;
}

.menu__languages a[aria-current] {
	background: var(--surface-panel);
	color: var(--emerald);
	font-weight: 600;
}

/* On a phone the icon alone says "menu"; the word stays for screen readers. */
@media (max-width: 30rem) {
	.menu__label {
		position: absolute;
		width: 1px;
		height: 1px;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
	}
}

/* ---------------------------------------------------------------------------
 * The hero: the first screen. Emerald, the heading large, one sentence, the Get Verho button.
 * ------------------------------------------------------------------------ */

.hero {
	position: relative;
	overflow: hidden;
	background: var(--emerald);
	color: var(--porcelain);
}

/* Don Maskote, the knight of our videos, as a very faint picture behind the hero: at the right
 * of the text column, facing right. The image (knight.png, made by
 * marketing/video/tools/hero.mjs) is porcelain lines with its parts filled in Emerald, so at
 * this opacity only the lines show. He is taller than the hero, which crops his feet. Carried
 * over from PR #13, where he stood behind the smaller band this replaced. */
.hero::before {
	content: "";
	position: absolute;
	top: 1.5rem;
	bottom: -40%;
	right: max(0rem, calc(50% - 29rem + 5rem));
	width: 22rem;
	background: url("/knight.png") no-repeat right top / contain;
	opacity: 0.08;
	pointer-events: none;
}

.hero__inner {
	position: relative;
	z-index: 1;
	max-width: var(--page);
	margin: 0 auto;
	padding: 5rem var(--gutter) 5.5rem;
}

.hero h1 {
	color: var(--porcelain);
	font-size: clamp(2rem, 1.1rem + 3.4vw, 3.25rem);
	line-height: 1.12;
	letter-spacing: -0.01em;
	margin: 0 0 1.25rem;
}

/* Porcelain at full strength on Emerald is the identity document's only allowed pairing; the
 * sentence is the same colour held back slightly so the heading stays dominant. */
.hero__lead {
	font-size: clamp(1.125rem, 1rem + 0.5vw, 1.3125rem);
	line-height: 1.5;
	color: #dfe3dd;
	margin: 0 0 2.25rem;
}

.hero__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 1rem 1.75rem;
	margin: 0;
}

.hero__link {
	color: var(--porcelain);
	font-weight: 600;
	text-decoration: none;
	border-bottom: 1px solid rgba(243, 244, 241, 0.45);
	padding-bottom: 0.1rem;
}

.hero__link:hover {
	color: var(--khaki);
	border-bottom-color: var(--khaki);
}

.hero__note {
	margin: 1.75rem 0 0;
	font-size: 0.9375rem;
	color: var(--moss);
}

/* ---------------------------------------------------------------------------
 * Sections. Each one spans the screen with its own background and holds its content in the
 * one shared column.
 * ------------------------------------------------------------------------ */

.section {
	padding: 4.5rem 0;
}

.section__inner {
	max-width: var(--page);
	margin: 0 auto;
	padding: 0 var(--gutter);
}

.section h2 {
	margin-top: 0;
	margin-bottom: 1.25rem;
	font-size: clamp(1.5rem, 1.2rem + 1vw, 1.9375rem);
	letter-spacing: -0.005em;
}

.section p:last-child {
	margin-bottom: 0;
}

.section--panel {
	background: var(--surface-panel);
}

.section--dark {
	background: var(--graphite);
	color: var(--text-on-dark);
}

.section--dark h2 {
	color: var(--porcelain);
}

.section--dark a {
	color: var(--khaki);
}

/* The link to the privacy policy, last in the section (step 9.2b). */
.more {
	margin-top: 1.5rem;
	font-weight: 600;
}

/* The line under the data protection text: the flag of Europe, small, and where our server
 * is (step 8.3c). A hairline keeps the flag's edge from dissolving into the dark. */
.eu-mark {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	margin-top: 2rem;
	padding-top: 1.5rem;
	border-top: 1px solid rgba(213, 217, 211, 0.15);
	font-size: 0.9375rem;
	color: var(--moss);
}

.eu-mark img {
	flex: none;
	border-radius: 2px;
	box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.12);
}

.section--khaki {
	background: var(--khaki-tint);
}

/* A sentence the page wants read first: the Finnish-language point in "what it is". */
.callout {
	margin: 1.5rem 0 0;
	padding: 0.2rem 0 0.2rem 1.25rem;
	border-left: 4px solid var(--khaki);
	font-size: 1.125rem;
	color: var(--text-primary);
}

/* ---------------------------------------------------------------------------
 * How it works: the demo, then the five steps under it.
 * ------------------------------------------------------------------------ */

/* The steps are numbered with Emerald discs rather than the browser's own numbers, so they
 * read as a sequence at a glance. A list on a phone, a row of five on a wide screen. */
.steps {
	list-style: none;
	counter-reset: step;
	margin: 2.5rem 0 0;
	padding: 0;
	display: grid;
	gap: 0.85rem;
}

.steps li {
	counter-increment: step;
	position: relative;
	padding-left: 2.75rem;
	min-height: 2rem;
}

.steps li::before {
	content: counter(step);
	position: absolute;
	left: 0;
	top: -0.1rem;
	width: 2rem;
	height: 2rem;
	border-radius: 50%;
	background: var(--emerald);
	color: var(--porcelain);
	display: grid;
	place-items: center;
	font-size: 0.9375rem;
	font-weight: 600;
}

@media (min-width: 56rem) {
	.steps {
		grid-template-columns: repeat(5, 1fr);
		gap: 1.5rem;
		font-size: 0.9375rem;
	}

	.steps li {
		padding: 2.9rem 0 0;
	}

	.steps li::before {
		top: 0;
	}
}

/* The demo reads as part of the page rather than as a video set into it (step 8.3b): no frame,
 * no shadow, no controls, and the video's own background is the page's Porcelain - #f3f3f1 in
 * the video and #f3f4f1 here, one step apart in green, which no eye can tell. It reaches into
 * the gutters on both sides, so the chat window inside it lines up with the text above instead
 * of sitting inset from it. site.js plays and pauses it. */
.demo {
	margin: 2rem calc(-1 * var(--gutter)) 0;
}

/* The poster is this background, from the two variables page.html sets on the element, rather
 * than a poster attribute, which cannot change with the screen: so each screen downloads only
 * its own. "contain" letterboxes it in the page's own colour, which is invisible. */
.demo video {
	display: block;
	width: 100%;
	height: auto;
	background: var(--porcelain) var(--poster) center / contain no-repeat;
}

/* A phone gets the tall video (the <source media> in page.html uses the same 40rem), so the box
 * takes its shape. It stops at four fifths of the screen's height so the whole of it can be
 * seen at once; the video letterboxes into the page's colour, which again does not show. */
@media (max-width: 40rem) {
	.demo video {
		aspect-ratio: 9 / 16;
		max-height: 80vh;
		max-height: 80svh;
		background-image: var(--poster-tall);
	}
}

.demo figcaption {
	margin-top: 0.25rem;
	padding: 0 var(--gutter);
	color: var(--text-muted);
	font-size: 0.8125rem;
}

/* Where Verho works: one sentence under the steps (step 9.2b; until then a framed row of names
 * with "Works now" and "Coming soon" labels, from step 8.3c). */
.services {
	margin-top: 2.5rem;
	font-size: 1.125rem;
}

/* Pricing (step 9.2b): Light and Pro compared in one table inside a thin frame, the plans' names
 * large at the top of their columns, a row per feature, then the price and the button. A tick
 * in Emerald where a plan has a feature, a muted dash where it does not. On a phone the feature
 * column takes what the two plan columns leave. */
.compare-frame {
	margin-top: 2rem;
	border: 1px solid var(--border-default);
	border-radius: var(--radius-lg);
	background: var(--surface-page);
	overflow: hidden;
}

/* Fixed columns, so a long word wraps inside its own column rather than widening the table:
 * the features take 40%, each plan 30%. Finnish words may hyphenate, and the page's lang
 * tells the browser which language's rules to use. */
.compare {
	width: 100%;
	border-collapse: collapse;
	table-layout: fixed;
	hyphens: auto;
	overflow-wrap: break-word;
}

.compare col.compare__features {
	width: 40%;
}

.compare th,
.compare td {
	padding: 0.85rem 1rem;
	text-align: left;
	vertical-align: top;
}

.compare tbody tr,
.compare tfoot tr:first-child {
	border-top: 1px solid var(--border-default);
}

.compare thead th {
	padding-top: 1.5rem;
	padding-bottom: 1.25rem;
}

.compare__name {
	display: block;
	font-size: 1.75rem;
	font-weight: 600;
	line-height: 1.2;
	letter-spacing: -0.01em;
	color: var(--text-primary);
}

.compare__for {
	display: block;
	margin-top: 0.35rem;
	font-size: 0.9375rem;
	font-weight: 400;
	color: var(--text-muted);
}

/* A feature's name. */
.compare tbody th {
	font-weight: 400;
}

.compare__yes {
	color: var(--emerald);
}

.compare__yes svg {
	display: block;
	margin-top: 0.2rem;
}

.compare__no {
	color: var(--text-muted);
}

.compare__price th {
	font-weight: 600;
}

.compare__price td {
	font-size: 1.375rem;
	font-weight: 600;
	line-height: 1.25;
	color: var(--text-primary);
}

.compare__unit {
	display: block;
	margin-top: 0.2rem;
	font-size: 0.875rem;
	font-weight: 400;
	color: var(--text-muted);
}

.compare__action td {
	padding-top: 0.25rem;
	padding-bottom: 1.5rem;
}

/* "Coming soon", where Light has its button: a plain line, muted, at the button's height. */
.compare__soon {
	display: inline-block;
	padding: 0.6rem 0;
	font-weight: 600;
	color: var(--text-muted);
}

/* On a phone three columns leave a Finnish word no room, so each row becomes two: the feature's
 * name across the whole width, and under it Light's and Pro's marks under their names. The
 * empty corner cells go, and so does the price row's heading, which the prices make plain. */
@media (max-width: 40rem) {
	.compare,
	.compare thead,
	.compare tbody,
	.compare tfoot {
		display: block;
	}

	.compare tr {
		display: grid;
		grid-template-columns: 1fr 1fr;
	}

	.compare th,
	.compare td {
		padding-left: 0.85rem;
		padding-right: 0.85rem;
	}

	.compare thead td,
	.compare__price th,
	.compare__action td:first-child {
		display: none;
	}

	.compare tbody th {
		grid-column: 1 / -1;
		padding-bottom: 0.25rem;
	}

	.compare tbody td {
		padding-top: 0.25rem;
	}

	.compare__name {
		font-size: 1.375rem;
	}

	.compare__for {
		font-size: 0.875rem;
	}

	.compare__price td {
		font-size: 1.25rem;
	}
}

/* Enterprise: a line under the table, not a third column, because it is priced by agreement and
 * has no feature the table could tick. */
.enterprise {
	margin-top: 2rem;
}

.enterprise__name {
	margin: 0 0 0.35rem;
	font-size: 1.375rem;
}

.enterprise p {
	margin: 0 0 0.35rem;
}

.enterprise .missing {
	display: inline-block;
	padding: 0.1rem 0.5rem;
	margin: 0 0.5rem 0 0;
}

/* Frequently asked questions (step 9.2c): the questions in one thin frame like the pricing
 * table, a hairline between them. The browser's own triangle gives way to a plus that becomes a
 * minus when the answer is open. */
.faq {
	margin-top: 2rem;
	border: 1px solid var(--border-default);
	border-radius: var(--radius-lg);
	background: var(--surface-page);
}

.faq__item + .faq__item {
	border-top: 1px solid var(--border-default);
}

.faq__item summary {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	padding: 1.1rem 1.5rem;
	list-style: none;
	font-weight: 600;
	color: var(--text-primary);
	cursor: pointer;
}

/* Safari draws its own triangle unless told not to. */
.faq__item summary::-webkit-details-marker {
	display: none;
}

.faq__item summary::after {
	content: "+";
	flex-shrink: 0;
	font-size: 1.375rem;
	font-weight: 400;
	line-height: 1;
	color: var(--emerald);
}

.faq__item[open] summary::after {
	content: "\2212";
}

.faq__item summary:hover {
	color: var(--emerald);
}

.faq__answer {
	padding: 0 1.5rem 1.25rem;
	max-width: var(--measure);
}

.faq__answer p {
	margin: 0 0 0.75rem;
}

.faq__answer p:last-child {
	margin-bottom: 0;
}

@media (max-width: 40rem) {
	.faq__item summary {
		padding: 1rem 1.1rem;
	}

	.faq__answer {
		padding: 0 1.1rem 1.1rem;
	}
}

/* The founder's address under the team, a line of its own. */
.contact {
	margin-top: 1.25rem;
	font-weight: 600;
}

/* ---------------------------------------------------------------------------
 * Get Verho (step 9.2b): the store's button and the sign-in's, side by side, one above the other
 * on a narrow phone.
 * ------------------------------------------------------------------------ */

.start__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem 1rem;
	margin-top: 1.75rem;
}

/* ---------------------------------------------------------------------------
 * Forms: the sign-in page's and the account page's (until step 9.2b also the waitlist's).
 * ------------------------------------------------------------------------ */

.form__row {
	margin: 0 0 1rem;
}

.form label {
	display: block;
	margin-bottom: 0.3rem;
	font-weight: 600;
	font-size: 0.9375rem;
}

.form input[type="email"],
.form input[type="text"] {
	display: block;
	width: 100%;
	padding: 0.6rem 0.75rem;
	border: 1px solid var(--border-default);
	border-radius: var(--radius-md);
	background: var(--surface-raised);
	font: inherit;
	color: var(--text-body);
}

.form input:focus {
	border-color: var(--wasabi);
	outline: 0;
	box-shadow: 0 0 0 3px rgba(128, 144, 118, 0.4);
}

/* The consent line is a sentence with a box in it, not a label above a field, so it reads as
 * something you agree to rather than as another thing to fill in. */
.form__consent label {
	display: flex;
	gap: 0.55rem;
	align-items: flex-start;
	font-weight: 400;
	font-size: 0.9375rem;
	max-width: var(--measure);
}

.form__consent input {
	margin-top: 0.3rem;
	flex-shrink: 0;
	accent-color: var(--emerald);
}

.form .button {
	width: 100%;
}

/* ---------------------------------------------------------------------------
 * A page of plain text, such as the privacy notice.
 * ------------------------------------------------------------------------ */

.page {
	max-width: var(--page);
	margin: 0 auto;
	padding: 3.5rem var(--gutter) 5rem;
}

.page h1 {
	font-size: clamp(2rem, 1.4rem + 2vw, 2.5rem);
	margin-bottom: 1.25rem;
}

/* ---------------------------------------------------------------------------
 * Signing in and the account (step 9.4). Plain pages in the same column as the privacy notice:
 * the sign-in choices one above the other, the same width, so neither looks preferred.
 * ------------------------------------------------------------------------ */

.sign-in__choices {
	display: grid;
	gap: 0.75rem;
	max-width: 24rem;
	margin: 2rem 0 1.5rem;
}

.sign-in__choice {
	text-align: center;
}

/* "or", between the two buttons and the email form (step 9.4b): a word between two hairlines. */
.sign-in__or {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	max-width: 24rem;
	margin: 0 0 1.25rem;
	color: var(--text-muted);
	font-size: 0.875rem;
}

.sign-in__or::before,
.sign-in__or::after {
	content: "";
	flex: 1;
	border-top: 1px solid var(--border-default);
}

/* The address, the code and the link's button: the same width as the buttons above. */
.sign-in__form {
	max-width: 24rem;
	margin-bottom: 1.5rem;
}

/* How the extension's sign-in went (step 9.5): a calm line, shown only while it matters. */
.extension-status {
	max-width: 32rem;
	padding: 0.85rem 1rem;
	border-radius: var(--radius-md);
	background: var(--khaki-tint);
	color: var(--text-primary);
	font-weight: 600;
}

/* Empty until site.js puts the sentence for a failed sign-in in it. */
.sign-in__error:not(:empty) {
	color: var(--earth);
	font-weight: 600;
}

.account__facts {
	display: grid;
	grid-template-columns: max-content 1fr;
	gap: 0.5rem 1.5rem;
	margin: 0 0 1.5rem;
}

.account__facts dt {
	color: var(--text-muted);
}

.account__facts dd {
	margin: 0;
	color: var(--text-primary);
	font-weight: 600;
}

/* ---------------------------------------------------------------------------
 * The account page's firm, seats and account-wide actions (step 9.6). Sections one under the
 * other in the page's column, each with a hairline above it; forms as narrow as the sign-in's.
 * ------------------------------------------------------------------------ */

.account__section {
	margin-top: 2.25rem;
	padding-top: 1.75rem;
	border-top: 1px solid var(--border-default);
}

.account__section h2 {
	font-size: 1.375rem;
	margin: 0 0 0.75rem;
}

.account__section h3 {
	font-size: 1.0625rem;
	margin: 1.75rem 0 0.5rem;
}

.account__form {
	max-width: 24rem;
}

/* What happened after a button or a form: the same calm line as the extension's, and the
 * warning colour as a rule down its side when something was refused. */
.account__notice {
	max-width: 32rem;
	padding: 0.85rem 1rem;
	border-radius: var(--radius-md);
	background: var(--khaki-tint);
	color: var(--text-primary);
	font-weight: 600;
}

.account__notice--error {
	border-left: 4px solid var(--earth);
}

.account__more summary {
	cursor: pointer;
	font-weight: 600;
	margin: 0.5rem 0 1rem;
}

.account__buttons {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	margin-bottom: 0.75rem;
}

.account__buttons form {
	margin: 0;
}

/* A button that is not the page's main action: an outline in the house green. */
.button--quiet {
	background: transparent;
	color: var(--emerald);
	box-shadow: inset 0 0 0 1px var(--emerald);
}

.button--quiet:hover {
	background: var(--surface-panel);
	color: var(--emerald-dark);
}

/* Deleting the account: dark text inside the warning colour's outline, which the identity keeps
 * for warnings. Earth as a fill would be too faint behind either light or dark text. */
.button--warning {
	background: transparent;
	color: var(--text-primary);
	box-shadow: inset 0 0 0 2px var(--earth);
}

.button--warning:hover {
	background: var(--khaki-tint);
	color: var(--text-primary);
}

/* An invitation waiting to be accepted (step 9.6b): a framed box at the top, so it is the first
 * thing a person who opened the link sees. */
.account__invite {
	max-width: 32rem;
	margin: 0 0 2rem;
	padding: 1.25rem 1.25rem 0.5rem;
	border-radius: var(--radius-lg);
	background: var(--surface-panel);
	box-shadow: inset 0 0 0 1px var(--border-default);
}

.account__invite h2 {
	font-size: 1.25rem;
	margin: 0 0 0.5rem;
}

.account__invite .button[hidden] {
	display: none;
}

/* The invitation link, shown once: the address in a field the width of the column, and Copy. */
.account__link {
	max-width: 32rem;
	margin-bottom: 1.5rem;
}

.account__link label {
	display: block;
	margin-bottom: 0.4rem;
	font-size: 0.9375rem;
}

.account__copy {
	display: flex;
	gap: 0.5rem;
}

.account__copy input {
	flex: 1;
	min-width: 0;
	padding: 0.45rem 0.65rem;
	border: 1px solid var(--border-default);
	border-radius: var(--radius-md);
	background: var(--surface-raised);
	font: inherit;
	font-size: 0.875rem;
	color: var(--text-body);
}

#invite-sent {
	font-weight: 600;
}

/* An admin's list of seats: who, their role, and the buttons, wrapping on a narrow screen. */
.seats {
	list-style: none;
	margin: 0 0 1.5rem;
	padding: 0;
	max-width: var(--measure);
}

.seats__seat {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem 1rem;
	padding: 0.85rem 0;
	border-bottom: 1px solid var(--border-default);
}

.seats__who {
	flex: 1 1 14rem;
	min-width: 0;
	overflow-wrap: anywhere;
}

.seats__name {
	font-weight: 600;
	color: var(--text-primary);
}

.seats__you,
.seats__email {
	color: var(--text-muted);
}

.seats__email {
	display: block;
	font-size: 0.9375rem;
}

.seats__role {
	flex: 0 0 auto;
	color: var(--text-muted);
}

.seats__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}

.seats__actions [hidden],
.seats__you[hidden] {
	display: none;
}

/* ---------------------------------------------------------------------------
 * The language page at an address that names no language, such as / (step 9.2). Its script
 * sends the visitor on before it is drawn, so this is what a visitor without script sees: the
 * wordmark and every language, in the middle of the screen.
 * ------------------------------------------------------------------------ */

.language-page {
	min-height: 100vh;
	min-height: 100svh;
	display: grid;
	place-content: center;
	justify-items: center;
	gap: 1.75rem;
	padding: 2rem var(--gutter);
	text-align: center;
}

.language-page__wordmark {
	margin: 0;
	font-size: 2.25rem;
}

.language-page__links {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 0.75rem;
}

.language-page__links a {
	padding: 0.6rem 1.15rem;
	border: 1px solid var(--border-default);
	border-radius: var(--radius-md);
	color: var(--text-primary);
	font-weight: 600;
	text-decoration: none;
}

.language-page__links a:hover {
	border-color: var(--wasabi);
	color: var(--emerald);
}

.language-page__company {
	margin: 0;
	color: var(--text-muted);
	font-size: 0.875rem;
}

/* ---------------------------------------------------------------------------
 * The footer: dark, the wordmark, the privacy link, the company and its business ID.
 * ------------------------------------------------------------------------ */

.site-footer {
	background: var(--noir);
	color: var(--moss);
}

.site-footer__inner {
	max-width: var(--page);
	margin: 0 auto;
	padding: 2.5rem var(--gutter) 3rem;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.75rem 1.75rem;
	font-size: 0.9375rem;
}

.site-footer .wordmark,
.site-footer .wordmark:hover {
	color: var(--porcelain);
}

.site-footer a {
	color: var(--porcelain);
}

.site-footer a:hover {
	color: var(--khaki);
}

.site-footer__company {
	margin-left: auto;
	font-size: 0.875rem;
}

/* On a phone the line wraps under the wordmark; at the right edge alone it looks misplaced. */
@media (max-width: 40rem) {
	.site-footer__company {
		flex-basis: 100%;
		margin-left: 0;
	}
}

/* Every language again, on a line of its own: where people look for it on a site they cannot
 * read, and a plain link for search engines to follow. */
.site-footer__languages {
	flex-basis: 100%;
	display: flex;
	flex-wrap: wrap;
	gap: 0.25rem 1.25rem;
	padding-top: 1rem;
	border-top: 1px solid var(--graphite);
	font-size: 0.875rem;
}

.site-footer__languages a {
	color: var(--moss);
	text-decoration: none;
}

.site-footer__languages a[aria-current] {
	color: var(--porcelain);
	text-decoration: underline;
}

/* ---------------------------------------------------------------------------
 * Content the founder has not written yet.
 *
 * Deliberately loud. A placeholder that looks like text is a placeholder that ships, and
 * step 8.7 fails the build while any of these remain.
 * ------------------------------------------------------------------------ */

.missing {
	display: block;
	background: repeating-linear-gradient(
		45deg,
		rgba(184, 104, 48, 0.08),
		rgba(184, 104, 48, 0.08) 10px,
		transparent 10px,
		transparent 20px
	);
	border: 1px dashed var(--earth);
	border-radius: var(--radius-md);
	color: var(--earth);
	padding: 0.75rem 1rem;
	margin: 0 0 1rem;
	font-size: 0.9375rem;
	max-width: var(--measure);
}

/* ---------------------------------------------------------------------------
 * The waitlist admin view at /waitlist/admin.
 *
 * Rendered by backend/waitlist/routes.py, which links this same stylesheet so the page looks
 * like the rest of the site without a second stylesheet to keep in step.
 * ------------------------------------------------------------------------ */

.admin main {
	max-width: var(--page);
	margin: 0 auto;
	padding: 2rem var(--gutter) 4rem;
}

.admin__count {
	font-weight: 600;
}

.admin__note {
	color: var(--text-muted);
	font-size: 0.875rem;
	max-width: var(--measure);
}

.admin__empty {
	color: var(--text-muted);
}

.admin__table {
	width: 100%;
	border-collapse: collapse;
	margin-top: 1.5rem;
	font-size: 0.9375rem;
}

.admin__table th,
.admin__table td {
	text-align: left;
	padding: 0.5rem 0.75rem 0.5rem 0;
	border-bottom: 1px solid var(--border-default);
	vertical-align: top;
}

.admin__table th {
	font-size: 0.8125rem;
	color: var(--text-muted);
	text-transform: uppercase;
	letter-spacing: 0.03em;
}

/* Every row says this until there is an email provider to confirm with. It is meant to be
 * noticeable: the gap should be visible every time the list is opened. */
.admin__pending {
	color: var(--earth);
}
