/*
 * Zosimo Superpowered — amendments to design's build.
 *
 * Everything in here is a deliberate departure from css/patterns.css, which is
 * kept as a byte-exact copy of design's generated file so the next port stays
 * a copy rather than a merge. If a rule belongs to design, it goes there and
 * comes from them. If we changed it, it goes here, with the reason.
 *
 * Loaded after patterns.css.
 */

/* ===== capability matrix — mark alignment ================================ */

/*
 * The three marks are inline-blocks of different heights: .dot is 10px,
 * .dot--none is a 1px dash. Inline-blocks sit their bottom edge on the
 * baseline, so the dash rendered level with the BOTTOM of the dots rather
 * than their centre, and a column of mixed marks looked misaligned.
 *
 * vertical-align:middle centres every variant on the same axis, so the dash
 * reads as the middle of the row. Applied to .dot so the half and none
 * variants inherit it — they only override size and fill.
 *
 * The value spans are .vh, which is position:absolute, so nothing else is in
 * the line box to fight with this.
 */
.dot {
	vertical-align: middle;
}

/* ===== capability matrix — responsive rebuild ============================ */

/*
 * Design's matrix is one 5-column table inside `.matrix-wrap`, which is
 * `overflow-x:auto` around a `min-width:760px` table. Below ~900px that is a
 * horizontally scrolling region with no tabindex, so a keyboard-only user
 * cannot scroll it and cannot reach four of the five columns at all. Reading
 * a row also means scrolling away from the header that says what the row is.
 *
 * compare.php now renders the same array twice: the wide table, and one small
 * table per capability. The swap below is display:none in both directions and
 * must stay that way — a visually-hidden class would leave both in the
 * accessibility tree and a screen reader would read the whole matrix twice.
 *
 * 900px is where design's own 760px minimum plus the card padding and the
 * page gutter stops fitting.
 */
.matrix-stack {
	display: none;
}

@media (max-width: 900px) {

	.matrix-wrap {
		display: none;
	}

	.matrix-stack {
		display: grid;
		gap: 14px;
		margin-top: 60px; /* design's own .matrix-wrap top gap, patterns.css:429 */
	}
}

.matrix-mini {
	inline-size: 100%;
	text-align: left;

	/*
	 * COLLAPSE, DELIBERATELY, AND THE CARD PADDING STAYS DISCARDED.
	 *
	 * Under border-collapse:collapse the spec zeroes a table element's own
	 * padding, so design's .card padding of 22px never applies here. That looks
	 * like a bug and I "fixed" it by switching to separate — which broke the
	 * page on a phone. Amy: "the lets talk button in the header is cut off and
	 * i can scroll left to right a little."
	 *
	 * Cause: this table's four headers are mono at --fs-helper and already need
	 * very nearly the full phone width. Honouring the card padding took 44px of
	 * horizontal room away from them, and a table does not wrap below its
	 * minimum content width — it overflows, which is what produced the sideways
	 * scroll and pushed the fixed header's button out of view.
	 *
	 * So the padding stays discarded on purpose. The spacing Amy actually asked
	 * for is vertical, and vertical space is bought on the CELLS below, where it
	 * costs nothing horizontally.
	 */
	border-collapse: collapse;
}

/*
 * The capability is the caption rather than a row header. At this width it is
 * the longest string in the table and the only one that must be read in full,
 * so it gets the width of the card instead of a column.
 */
.matrix-mini__caption {
	caption-side: top;
	text-align: left;
	padding-block-end: 14px;
	font-size: var(--fs-body-sm);
	line-height: 1.35;
	color: var(--ink);
}

.matrix-mini.accent .matrix-mini__caption {
	color: var(--accent);
}

.matrix-mini thead th {
	/* 14px above, matching the cells below, so the header is not flush to the
	   card's top border either. Horizontal stays 4px: see the note above. */
	padding: 14px 4px 10px;
	border-block-end: 1px solid var(--hair);
	font-family: var(--mono);
	font-size: var(--fs-helper);
	font-weight: 400;
	letter-spacing: var(--ls-label);
	text-align: center;
	text-transform: uppercase;
	color: var(--ink-muted);
}

/* Same treatment design gives the Zosimo column in the wide table. */
.matrix-mini thead th.own {
	color: var(--accent);
}

.matrix-mini td {
	/*
	 * The fix Amy asked for: the dots had 14px above them and nothing below, so
	 * they sat on the card's bottom border. Symmetric now, and block-direction
	 * only, so the four columns keep every pixel of width they had.
	 */
	padding-block: 14px;
	text-align: center;
}

/* ===== text-it-in panel — film as ground ================================= */

/*
 * 2026-09-11. The sms panel stopped being `content/split-media` and became
 * full-bleed media with the copy over it — see template-parts/panels/sms.php
 * for why, and for which of Lisa's three cuts goes where.
 *
 * Nothing here restyles patterns.css. `.panel`, `.ground`, `.body` and
 * `.legibility` all keep design's rules; this adds the copy column, the
 * posters, and the pause control, which design's build has no equivalent of.
 */

/*
 * POSTERS AS BACKGROUNDS, not as the video's `poster` attribute.
 *
 * `poster` takes ONE url and cannot follow `<source media>`, so a phone would
 * flash the wide 16:9 still before its own tall cut arrived. A background on
 * the ground can be swapped per cut, and it is the only still a reduced-motion
 * visitor ever sees, since the film itself is removed for them below.
 *
 * Breakpoints are the same aspect ratios as the <source media> queries, and
 * they have to STAY the same: a background from one cut under a film from
 * another is a visible jump on first paint.
 */
.panel--video .ground--video {
	background-position: center;
	background-repeat: no-repeat;
	background-size: cover;
	background-image: url("../images/text-it-in-desktop-poster.jpg");
}

@media (max-aspect-ratio: 7/5) {
	.panel--video .ground--video {
		background-image: url("../images/text-it-in-tablet-poster.jpg");
	}
}

@media (max-aspect-ratio: 4/5) {
	.panel--video .ground--video {
		background-image: url("../images/text-it-in-mobile-1080x2092-poster.jpg");
	}
}

/*
 * The film sits over its own poster, so it must not paint its own background
 * in the gap before the first frame decodes — a black flash over a still that
 * is already correct.
 */
.panel--video .video-panel__media {
	width: 100%;
	height: 100%;
	background: transparent;
	object-fit: cover;
}

/*
 * COPY COLUMN. The wide cut carries its subject on the right and leaves the
 * left ~40% as open gradient, so the copy takes the left half and stops well
 * short of the phone card. `.body` keeps design's max-width and gutters.
 */
.panel--video .body {
	display: grid;
	/*
	 * 5/7, not 1/1. An even split puts the copy column's right edge at the
	 * centre of the frame, and the film's phone card starts BEFORE the centre
	 * — measured at 1478px wide, the heading ran to 739 and the card began at
	 * 675. The clear gradient is roughly the left 42% of the wide cut, so the
	 * column is sized to land inside it rather than on the subject.
	 */
	grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
	align-items: center;
}

.panel--video .video-panel__copy {
	grid-column: 1;
}

/*
 * THE COPY BOX, 2026-09-12. Lisa, for ADA: the copy sits on a flat 20% black
 * container, not the derived radial blend — the .legibility div is gone from
 * sms.php. Geometry is Figma 409:13051 (wide) and 445:12289 (stacked), raw
 * values in figma-pull-log.md. The box sets the measure now, so the old ch
 * caps come off.
 */
.panel--video .video-panel__copy {
	background: rgba(0, 0, 0, 0.2);
}

/* 409:13079 / 445:12302 — the tight shadow only. --sh-heading also carries a 48px blur, which is the haze the box replaces. */
.panel--video .display {
	max-width: none;
	text-shadow: 0 1px 2px rgba(3, 6, 14, 0.7);
}

/*
 * 409:13081 / 445:12304 carry no shadow; --sh-lead's 28px blur is more of the
 * same haze.
 *
 * INK IS FULL WHITE, NOT FIGMA'S rgba(255,255,255,.9). Measured 2026-09-12 over
 * all 21 one-per-second frames of the desktop film, text band only, under the
 * 20% box: .90 reaches 4.17:1 and the theme's .94 reaches 4.39, both under the
 * 4.5 a 20px regular lead needs. #fff reaches 4.74. Amy's call; same lever
 * patterns.css already pulls for the eyebrow on video grounds.
 */
.panel--video .lead {
	max-width: none;
	text-shadow: none;
	color: #fff;
}

/* "Your changes," on the wide cut, "Your changes are" below it. */
.panel--video .hl-narrow {
	display: none;
}

/*
 * THE PANEL TAKES THE FILM'S SHAPE. THE FILM IS NEVER CROPPED TO THE PANEL.
 *
 * This replaces the original approach and the original approach was wrong.
 * Design's .panel is min-height:100svh and the ground is object-fit:cover, which
 * is right for footage with no fixed subject — the hero's ambient plate crops
 * anywhere and still reads. This film is the opposite: a phone card and a person
 * sit at fixed positions, and cropping either one destroys the shot.
 *
 * Measured on the live subsite 2026-09-11 at 1563x1194 (aspect 1.31): a 1920x1080
 * source in a 1548x1194 box scaled to 2125 wide to cover, cutting 288px off each
 * side and zooming 1.37x. That put the phone card half off-screen. At Amy's wider
 * window it was worse. Every viewport that is not exactly 16:9 was damaging the
 * composition, which means it was broken from the first deploy, not by a later fix.
 *
 * So the panel is given the film's aspect and stops being a full-height ground.
 * The film then fits exactly, at every width, and nothing is ever cropped.
 */
@media (min-aspect-ratio: 7/5) {

	.panel--video {
		min-height: auto;
		aspect-ratio: 16 / 9;
		container-type: inline-size;
	}

	/*
	 * THE BOX IS PLACED ON THE FILM, NOT ON THE PAGE GRID. In 409:13051 it runs
	 * from x 61 to 619 of the 1440 frame, and its right edge is the phone card's
	 * left edge. The card is baked into the film: measured on the desktop poster
	 * at 825/1920 = 42.97%, against Figma's 619/1440 = 42.99%. So the columns are
	 * percentages of the panel, and below 1440 the padding and heading scale with
	 * it (cqi), or the headline wraps before the box reaches the card.
	 */
	.panel--video .body {
		max-width: none;
		padding-inline: 0;
		grid-template-columns: 4.236% 38.75% minmax(0, 1fr);
	}

	.panel--video .video-panel__copy {
		grid-column: 2;
		/* 409:13075 inside 409:13074 — top 53, right 52, bottom 53.9, left 59 */
		padding: min(53px, 3.681cqi) min(52px, 3.611cqi) min(54px, 3.75cqi) min(59px, 4.097cqi);
	}

	/* 409:13079 — 64px */
	.panel--video .display {
		font-size: min(64px, 4.444cqi);
	}
}

/*
 * BELOW THE WIDE CUT: STACKED, NOT OVERLAID.
 *
 * Overlay needs open ground to put copy on, and only the wide cut has any. The
 * mid cut starts its phone card about 9% from the left edge and the tall cut is
 * a full composition with no empty space at all. Laid over either, the headline
 * lands on the artwork and the legibility scrim washes out the rest — on a phone
 * that made the film read as absent even though the correct cut had loaded.
 *
 * A 16:9 panel is also simply too short to hold the copy at these widths, so
 * overlay could not work here even if there were ground for it.
 *
 * Two blocks instead: copy, then the film below it at its own shape, uncropped.
 * The legibility panel goes with the overlay, having nothing left to protect.
 * The ground is re-ordered rather than re-nested — it stays a sibling of .body
 * because js/page.js finds it from the panel.
 */
@media (max-aspect-ratio: 7/5) {

	.panel--video {
		display: flex;
		flex-direction: column;
		align-items: stretch;
		justify-content: flex-start;
		min-height: 0;

		/*
		 * NOT design's panel padding, which measured 112px of empty colour above
		 * the eyebrow. That clearance is var(--hdr-h) plus 3rem and exists so copy
		 * clears the fixed bar while a panel sits centred in the viewport. A stacked
		 * panel is never centred, so it buys nothing. The anchor-jump case it
		 * protects is covered by the scroll-margin-top design puts on .panel.
		 */
		padding-block: 0;

		/* 445:12289 — the upper portion is a flat band; the box insets on it. */
		background: #c8384f;
	}

	/*
	 * 445:12289 is 768 wide: box inset 42 left/right, 27 top, 35 bottom. Below
	 * 768 the insets shrink in proportion (vw) instead of eating a phone's width.
	 * There is no phone frame — that scaling is an assumption, flagged to Lisa.
	 */
	.panel--video > .body {
		order: 1;
		padding-block: min(27px, 3.516vw) min(35px, 4.557vw);
		padding-inline: min(42px, 5.469vw);
	}

	.panel--video .body {
		grid-template-columns: minmax(0, 1fr);
	}

	/* 445:12298 inside 445:12297 — top 40, right 32, bottom 44.9, left 44 */
	.panel--video .video-panel__copy {
		padding: min(40px, 5.208vw) min(32px, 4.167vw) min(45px, 5.859vw) min(44px, 5.729vw);
	}

	/* 445:12302 — 44px at 768; floors at the theme's own 36px display minimum. */
	.panel--video .display {
		font-size: clamp(2.25rem, 5.729vw, 44px);
	}

	/* 445:12304 — lead box 518 wide */
	.panel--video .lead {
		max-width: 518px;
	}

	.panel--video .hl-wide {
		display: none;
	}

	.panel--video .hl-narrow {
		display: inline;
	}

	/* Amy 2026-09-12: the headline's line breaks are desktop-only. Lisa's tablet comp wraps it freely. */
	.panel--video .display br {
		display: none;
	}

	.panel--video > .ground {
		order: 2;
		position: static;
		height: auto;
	}

	/* The mid cut's own shape. */
	.panel--video .video-panel__media {
		height: auto;
		aspect-ratio: 16 / 9;
	}

	.panel--video > .legibility {
		display: none;
	}
}

/* The tall cut is 1080x2092 and is a different shape from the other two. */
@media (max-aspect-ratio: 4/5) {

	.panel--video .video-panel__media {
		aspect-ratio: 1080 / 2092;
	}
}

/* ===== text-it-in panel — pause control ================================== */

/*
 * WCAG 2.2.2. The film starts on its own and loops for 20.8 seconds, well past
 * the five the criterion allows without a way to stop it.
 *
 * GEOMETRY IS FIGMA-VERIFIED, COLOUR IS NOT INHERITED FROM THE SAME ATOM, and
 * the split is deliberate. Origin's pause-btn atom (553:6041, logged in
 * figma-pull-log.md 2026-09-11) gives size 40, radius 9999, stroke 2, glyph
 * stroke 2, ring 2 — all taken verbatim. Its colours are drawn for a LIGHT
 * surface: #4d4d4d stroke and glyph on a transparent fill, with #2066f3 —
 * Origin's blue, not Zosimo's pink — on hover. On dark moving footage a
 * mid-grey glyph over no fill is not reliably visible on any given frame, so
 * taking those values would have been verified and wrong.
 *
 * The four substitutions come from this theme's own :root in css/theme.css,
 * so they are not invented either. If Lisa draws a Zosimo pause atom it
 * replaces the colours; the five geometry values stand.
 *
 * This theme loads none of the parent's CSS (see functions.php), so the atom
 * could only be reproduced here, not imported.
 *
 * z-index 4 puts it above .body (3) so it stays clickable over the copy.
 */
.video-pause {
	position: absolute;
	right: max(var(--gutter), 1rem);
	bottom: max(var(--gutter), 1rem);
	z-index: 4;
	display: inline-flex;
	align-items: center;
	justify-content: center;

	/* 553:6041 — pause-btn/size, /radius, /stroke-width */
	width: 40px;
	height: 40px;
	border-radius: 9999px;
	border: 2px solid var(--card-edge);

	/* not from the atom — see the note above */
	background: var(--card-ink);
	color: var(--ink);

	padding: 0;
	cursor: pointer;
}

.video-pause:where(:hover, .is-hover) {
	border-color: var(--accent);
	color: var(--accent);
}

/* 553:6041 — pause-btn/ring-width 2. Ring COLOUR is the theme's focus accent,
   for the same reason the glyph is: the atom's #2066f3 is Origin's blue. */
.video-pause:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 3px;
}

/*
 * Two bars when playing, one triangle when paused. 553:6041 —
 * pause-btn/glyph-stroke-width 2 is the bar width; the glyph box is half the
 * 40 size, which is the atom's proportion.
 */
.video-pause__glyph {
	width: 8px;
	height: 12px;
	border-left: 2px solid currentColor;
	border-right: 2px solid currentColor;
}

.video-pause[aria-pressed="true"] .video-pause__glyph {
	width: 0;
	height: 0;
	border-left: 10px solid currentColor;
	border-right: 0;
	border-top: 6px solid transparent;
	border-bottom: 6px solid transparent;
}

/*
 * REDUCED MOTION. The film is removed rather than paused: a paused <video>
 * shows its first frame, which here is the owner mid-text with nothing
 * resolved, while the poster underneath is the payoff. Removing it shows the
 * better still and spares the download.
 *
 * The control goes with it. A pause button for something that is not moving
 * is a control that lies about the state of the page.
 */
@media (prefers-reduced-motion: reduce) {

	.panel--video .video-panel__media,
	.panel--video .video-pause {
		display: none;
	}
}

/* ===== menu panel — search animation ===================================== */

/*
 * 2026-09-11. Lisa's rendered animation replaces the hand-built .mock--search.
 * The markup keeps design's .mock__frame around it; see the note in
 * template-parts/panels/menu.php for why that frame has to stay.
 *
 * ASPECT IS DECLARED, NOT CROPPED. Same rule the text-it-in panel had to be
 * fixed to obey: the artwork is a composed card with a search box, an answer
 * and a photo at fixed positions, so it is given its own 1196x1236 shape and
 * the box follows the artwork. Nothing here uses object-fit:cover, and nothing
 * here should.
 */
.mock--search-anim .search-anim__media {
	display: block;
	width: 100%;
	height: auto;
	/* the cropped pane's own size, so the box follows the artwork */
	aspect-ratio: 948 / 988;
	/* matches .mock__pane, which this replaces */
	border-radius: 3px;
}

/*
 * THE WHITE PLATE IS CROPPED OUT OF THE FILE, NOT HIDDEN WITH CSS.
 *
 * Amy, twice: first "it looks doubled", then "theres a white box around the
 * frame". Both were the same cause. Lisa's render is a card drawn on a white
 * page — the mint pane sits inside a white plate, and that plate is white on
 * white, so it is invisible in Figma and a hard white box on this panel's blue.
 *
 * Dropping design's frame did not help, because the box was never design's
 * frame. It was the artwork's own margin.
 *
 * Measured on a decoded frame: the pane is inset a uniform ~124px on all four
 * sides of the 1196x1236 render — left 123, right 124, bottom 124 — so the file
 * is re-encoded cropped to 948x988 at offset 123,124. The element is now the
 * pane and nothing else, which also drops it from 3.5MB to 2.8MB.
 *
 * design's .mock__frame is therefore left ALONE and does its original job:
 * it is the card, exactly as it is for every other mock on this page.
 */

/*
 * THE CARD IS CAPPED AT EVERY WIDTH, AND THE CAP IS A HEIGHT DECISION.
 *
 * Amy: "in the oriignal maockup, the video and text fell ABOVE the area where
 * the line drawing was occurring but now the video is big and covers up the
 * drawing animation. the video is taller than the mockup image from the demo
 * html file."
 *
 * Measured from her two screenshots at the same viewport: design's hand-built
 * mock was 679x520; the render at that same column width is 674x706. Lisa's
 * card is a TALLER SHAPE than the one it replaced — 948x988 against a mock that
 * was wider than tall — so at full column width it runs 186px further down,
 * straight through the produce band.
 *
 * A video cannot take width and height independently without distorting, so
 * holding the original's height means accepting the original's height as the
 * constraint and letting width follow: 520 x 948/988 = 499. Hence 500px, and
 * hence the card is narrower than the mock it replaced. That is the cost of the
 * render's aspect, not a layout preference, and it is the trade that keeps the
 * drawing visible.
 *
 * This also covers the collapsed case below, which is where it first showed up.
 *
 * Amy, on a tablet in portrait: "in the menu built to be seen section the video
 * is huge." At 900px design's .split drops to one column (patterns.css:321), so
 * the media column stops being half the grid and becomes the full content
 * width. The old hand-built mock only grew to its content; this card has a
 * declared aspect, so a full-width column makes it as tall as the column is
 * wide — on an 834pt tablet that is an 800px-tall card for a side illustration.
 *
 * 500px is not a chosen number: it is what this card measures on desktop, where
 * the two-column grid gives it about half the content width. Capping at its own
 * desktop size means the collapse stops enlarging it without shrinking it
 * anywhere it was already right. Scoped to the same 900px breakpoint that
 * causes the problem, so wide layouts are untouched.
 */
.mock--search-anim {
	max-width: 500px;
}

@media (max-width: 900px) {

	.mock--search-anim {
		margin-inline: auto;
	}
}

/*
 * The control belongs to the card, not to the panel, so it anchors to .mock —
 * which design already sets position:relative — instead of inheriting the
 * film panel's page-gutter offsets.
 */
.video-pause--inset {
	right: .75rem;
	bottom: .75rem;
}

/*
 * REDUCED MOTION, same contract as the film panel: the animation is removed so
 * its poster shows through, and the control goes with it rather than sitting
 * there offering to pause something that is not moving. The poster is the
 * first frame here, which is a complete, readable card on its own.
 */
@media (prefers-reduced-motion: reduce) {

	.mock--search-anim .search-anim__media {
		visibility: hidden;
	}

	.mock--search-anim .mock__frame {
		background-image: url("../images/search-animation-poster.jpg");
		background-size: cover;
		background-position: center;
	}

	.mock--search-anim .video-pause {
		display: none;
	}
}

/* ===== legal pages ======================================================= */

/*
 * 2026-09-11. Terms, privacy, accessibility and SMS consent, ported from
 * zosimo.io. See page.php for what deliberately did NOT come across.
 *
 * Every value below is either one of this theme's own :root tokens or a
 * spacing figure already shipped for these same four documents on the old
 * site. Nothing is invented and nothing is Figma-derived, because no Figma
 * frame for these pages exists — the old theme's footer says as much about its
 * own legal row.
 */
.legal {
	/*
	 * ONE ACCENT FOR THE WHOLE PAGE. Amy: "the sms consent page has text links
	 * in blue and in red."
	 *
	 * Both were defensible alone and wrong together. Prose links took --accent,
	 * which on a page with no panel falls back to the site default, pink. The
	 * consent form set sky on itself so its submit would match the audit form's
	 * blue, which Amy had confirmed as correct. Same page, two accents.
	 *
	 * Resolved upward rather than downward: the page runs sky, so the prose and
	 * the form agree AND the submit stays the blue she approved. Setting the
	 * form to pink instead would have fixed the links by breaking the button.
	 *
	 * Sky on --void measures about 7:1, so this does not cost contrast.
	 */
	--accent: var(--sky);
	--accent-fill: var(--sky-fill);

	/* clears the fixed header, then design's own panel rhythm below it */
	padding-block: calc(var(--hdr-h) + 3rem) 6rem;
	padding-inline: var(--gutter);
	background: var(--void);
}

/*
 * 760px is the old site's measure for these exact documents, kept rather than
 * re-chosen. --col-max is 1200 and is meant for the landing page's layouts; a
 * 1200px line of body copy is far past a comfortable reading measure.
 */
.legal__article {
	max-inline-size: 760px;
	margin-inline: auto;
}

.legal__title {
	margin: 0;
	font-size: var(--fs-display);
	line-height: var(--lh-display);
	color: var(--ink);
}

.legal__content {
	margin-block-start: 40px;
	font-size: var(--fs-body);
	line-height: var(--lh-lead);
	color: var(--ink-body);
}

/* The document supplies the top margin; the container already has padding. */
.legal__content > :first-child {
	margin-block-start: 0;
}

.legal__content h2 {
	margin: 40px 0 0;
	font-size: var(--fs-card-title);
	line-height: 1.25;
	color: var(--ink);
}

.legal__content h3 {
	margin: 28px 0 0;
	font-size: var(--fs-lead);
	line-height: 1.3;
	color: var(--ink);
}

.legal__content :is(p, ul, ol, table) {
	margin-block: 16px 0;
}

.legal__content :is(ul, ol) {
	padding-inline-start: 24px;
}

.legal__content li {
	margin-block-start: 8px;
}

/*
 * --accent, not the old site's #d1003a. That value was chosen to clear AA on a
 * #f5f6f8 ground; this ground is --void. The theme's own accent is what every
 * other link on this site uses.
 */
.legal__content a:is(:link, :visited) {
	color: var(--accent);
	text-decoration: underline;
	text-underline-offset: 2px;
}

.legal__content a:is(:hover, :focus-visible) {
	color: var(--ink);
}

.legal__content strong {
	color: var(--ink);
}

/*
 * 404 page's home button (404.php). Sits outside .legal__content so the
 * content link rule does not restyle it; 40px is the same gap .legal__content
 * uses below the title. Amy 2026-09-25: "need a space between text and button".
 */
.legal__actions {
	margin-block: 40px 0;
}

/* Legal documents contain tables; they must not force the page sideways. */
.legal__content table {
	inline-size: 100%;
	border-collapse: collapse;
}

.legal__content :is(th, td) {
	padding: 10px 12px;
	border: 1px solid var(--hair);
	text-align: left;
	vertical-align: top;
}

.legal__content th {
	color: var(--ink);
}

/* ===== SMS consent form ================================================== */

/*
 * 2026-09-11. The form comes from the network-wide zosimo-sms-consent plugin,
 * so it appeared the moment the page was ported — but all of its CSS lived in
 * the OLD theme's stylesheet, which this theme does not load. It rendered as
 * bare browser defaults on black.
 *
 * MY FIRST ATTEMPT INVENTED A LOOK. Pill inputs, a 20px card radius, body-font
 * labels. Amy: "the form style on the home page doesnt match the sms consent
 * form. border radius off, button is blue, font is monospace" — and then, when
 * I started reading it the wrong way round, "the audit form is right. the sms
 * consent form is wrong."
 *
 * So this now MIRRORS design's own `.card` and `.field` rules from
 * patterns.css, which is what the audit form on the front page is built from.
 * The declarations are duplicated rather than shared because the plugin emits
 * its own class names and patterns.css is kept a byte-exact copy of design's
 * generated file. Every value below is either a token or is copied verbatim
 * from the rule it mirrors — nothing here was chosen by me.
 *
 *   .zosimo-consent        mirrors .card          (patterns.css:220)
 *   .zosimo-consent__field mirrors .field         (patterns.css:241)
 *   __label                mirrors .field label   (patterns.css:243)
 *   __input                mirrors .field input   (patterns.css:248)
 */
.zosimo-consent {
	display: flex;
	flex-direction: column;
	gap: 20px;
	margin-block: 32px;

	/* .card, verbatim — including no border-radius. The square corner is the
	   design; the 20px I had before is what "border radius off" meant. */
	background:
		linear-gradient(var(--card-veil), var(--card-veil)),
		linear-gradient(var(--card-ink), var(--card-ink));
	border: 1px solid var(--card-edge);
	backdrop-filter: blur(2px);
	-webkit-backdrop-filter: blur(2px);
	padding: var(--card-pad);
}

/* .field */
.zosimo-consent__field {
	display: flex;
	flex-direction: column;
	gap: 10px;
	min-width: 0;
}

/* .field label */
.zosimo-consent__label {
	font-family: var(--mono);
	font-size: var(--fs-control);
	line-height: 1.55;
	letter-spacing: var(--ls-label);
	text-transform: uppercase;
	color: rgba(255, 255, 255, .80);
}

/*
 * .field input. Double class for the same reason the old theme used one: a
 * bare element selector on inputs outranks a single class.
 */
.zosimo-consent .zosimo-consent__input {
	width: 100%;
	font-family: var(--mono);
	font-size: var(--fs-control);
	line-height: 1.74;
	letter-spacing: var(--ls-control);
	text-transform: uppercase;
	background: var(--field-fill);
	border: 1px solid var(--field-stroke);
	border-radius: var(--ctl-radius);
	color: #fff;
	padding: var(--ctl-pad-y) 14px;
	transition: border-color 180ms var(--ease), background 180ms var(--ease);
}

/* Design uses :focus, not :focus-visible, so a mouse user clicking in keeps
   the active stroke. Lisa 2026-08-29, carried across with the rule. */
.zosimo-consent .zosimo-consent__input:where(:focus, .is-active) {
	border-color: var(--field-stroke-active);
	background: rgba(255, 255, 255, .14);
	outline: none;
}

.zosimo-consent .zosimo-consent__input:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

.zosimo-consent .zosimo-consent__input::placeholder {
	color: rgba(255, 255, 255, .46);
}

@media (prefers-reduced-motion: reduce) {

	.zosimo-consent .zosimo-consent__input {
		transition: none;
	}
}

/*
 * The consent paragraph is NOT given the mono uppercase treatment. Design's
 * .field label is two or three words; this is a long legal sentence carrying
 * the actual consent, and uppercase monospace at that length is a readability
 * and comprehension problem on the one control that has to be understood.
 */
.zosimo-consent__check {
	display: flex;
	gap: 12px;
	align-items: flex-start;
	font-size: var(--fs-body-sm);
	line-height: 1.5;
	color: var(--ink-body);
}

.zosimo-consent__check input {
	flex: 0 0 auto;
	inline-size: 18px;
	block-size: 18px;
	margin-block-start: 3px;
	accent-color: var(--accent);
}

.zosimo-consent__check a:is(:link, :visited) {
	color: var(--accent);
	text-decoration: underline;
}

.zosimo-consent__fine {
	margin: 0;
	font-size: var(--fs-helper);
	line-height: 1.5;
	color: var(--ink-muted);
}

.zosimo-consent__submit {
	align-self: flex-start;
}

.zosimo-consent__error {
	margin: 0;
	padding: 12px 16px;
	border: 1px solid var(--accent);
	border-radius: var(--ctl-radius);
	background-color: color-mix(in srgb, var(--accent) 12%, transparent);
	font-size: var(--fs-body-sm);
	line-height: 1.5;
	font-weight: 700;
	color: var(--ink);
}

.zosimo-consent__done {
	margin-block: 32px;
	padding: var(--card-pad);
	background:
		linear-gradient(var(--card-veil), var(--card-veil)),
		linear-gradient(var(--card-ink), var(--card-ink));
	border: 1px solid var(--card-edge);
}

.zosimo-consent__done p {
	margin: 0;
	font-size: var(--fs-body);
	line-height: var(--lh-lead);
	color: var(--ink);
}

/*
 * THE HONEYPOT MUST BE HIDDEN. This was the real bug in Amy's screenshot, not a
 * cosmetic one: "Leave this field empty" rendered as a labelled input in the
 * middle of the form. A person who fills it in is flagged as a bot and their
 * consent submission is silently dropped.
 *
 * Out of view and out of the accessibility tree, but still submitted, so a bot
 * filling every field still gives itself away.
 */
.zosimo-consent__hp {
	position: absolute;
	inline-size: 1px;
	block-size: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* ===== closing panel — tablet spacing ==================================== */

/*
 * 2026-09-12. Amy, on her tablet in both orientations: "a bunch of dead space"
 * below the portfolio. Measured in tablet-sized frames of the live page: 154px
 * at 768x1024, 1024x768 and 1180x820, 237px at 820x1180, all of it the closing
 * panel's own top. Design's .panel reserves --hdr-h + 3rem (128px) so copy
 * clears the fixed header while a panel sits centred, and min-height 100svh
 * centres short content in a tall screen. Read by scrolling, neither buys
 * anything; the anchor jump to #cta is still covered by .panel's
 * scroll-margin-top. Same reasoning as the text-it-in panel above.
 *
 * 3rem is the portfolio panel's own padding (.showcase), so nothing new is
 * invented. Measured with the rule in place: 74px at all four sizes.
 *
 * TOUCH DEVICES, NOT A WIDTH. A 1180px tablet and a 1180px laptop window are
 * the same width, and desktop was to stay as it is. This also reaches phones,
 * which stack the same way.
 */
@media (hover: none) and (pointer: coarse) {

	.panel.closing {
		padding-top: 3rem;
		min-height: auto;
	}
}

/* ===== About page ======================================================== */

/*
 * 2026-09-14. page-about.php, from Figma 402:10497; raw values are in
 * figma-pull-log.md under the same date. Built from design's own blocks —
 * .panel, .ground, .eyebrow, .display, .lead, .card — so what follows is layout
 * plus the few type sizes those blocks do not have.
 *
 * WHERE EACH VALUE COMES FROM. Plain px figures are Figma's, read at the 1440
 * frame. Every clamp() floor and vw rate is NOT: the frame is desktop-only, so
 * how a figure shrinks is my reading, flagged to Amy, to be replaced if Lisa
 * draws narrower frames.
 */

/*
 * A WIDER COLUMN THAN THE LANDING PAGE. 402:10497 runs an 80px gutter and a
 * 1280 column — the intro box, the pillar row and the step row all start at
 * x 80 — where the front page runs design's 120 + 1200. So these panels get
 * their own gutter. The intro box's right edge is at 1355, not 1360; read as a
 * 5px drawing slip and built symmetric.
 */
.about {
	--about-gutter: clamp(1.25rem, 1.5rem + 3.9vw, 5rem);   /* 80 at 1440 */
}

.about .panel > .body {
	max-width: calc(1280px + 2 * var(--about-gutter));
	padding-inline: var(--about-gutter);
}

/* Figma's line breaks. Design's text-wrap:balance re-breaks these headlines away from the comp. */
.about .display {
	text-wrap: wrap;
}

/* The FAQ (465:13279) and closing (402:11474) frames go back to design's own 120 + 1200 column. */
.about .about-faq > .body,
.about .about-closing > .body {
	max-width: calc(var(--col-max) + 2 * var(--gutter));
	padding-inline: var(--gutter);
}

/* ----- intro, 461:12492 --------------------------------------------------- */

/* The box top is at 139: the 80px header plus 59. "Here's our story" ends 57 above the section's bottom. */
.about-intro {
	padding-block: calc(var(--hdr-h) + clamp(1.5rem, 4.1vw, 59px)) clamp(2rem, 3.96vw, 57px);
}

.about-intro__stage {
	position: relative;
}

/* 461:12544 */
.about-intro__box {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	background: rgba(0, 0, 0, 0.3);
}

/*
 * 461:12545 — 43 down, 44 in, 570 wide, so 26 on the right of a 640 column.
 * The 125 below is Figma's empty spacer 461:12550 (117.8) plus its 7px gap,
 * which is what makes the box 341 tall.
 *
 * THE 26 IS LOAD-BEARING. It was 44 at first, which left the heading 552px, and
 * "Human experience." measures 557px in Geist at 64 (Figma's SF Pro is
 * narrower) — so it wrapped to three lines and the box grew to 414. Measured on
 * the live draft 2026-09-14.
 */
.about-intro__copy {
	padding: 43px 26px 125px 44px;
}

/*
 * THE HEADING STAYS FULL SIZE; THE BOX STACKS INSTEAD. "Human experience." is
 * 557px in Geist at 64, and a two-column copy column is that wide only near
 * 1440. Measured in iframes 2026-09-14: four lines at 920-1200. Scaling the
 * heading to the column kept two lines but made it smaller than the section
 * headings below (40px against 63 at 1000). Amy chose (b): stack the box below
 * 1200 so the heading keeps design's display size and may wrap. See the
 * max-width 1200 block below.
 */

/* 461:12545 gap 7, not design's 20 */
.about-intro .display {
	margin-top: 7px;
	max-width: none;
}

/*
 * 461:12551 — 103 right of the centre line, 440 wide, top 83 below the box top
 * (its centre is at y 292 and it is 140 tall). 20px on 1.75, not design's 1.6.
 */
.about-intro__lead {
	align-self: start;
	max-width: calc(440px + 103px);
	margin-top: 0;
	padding: 83px 0 0 103px;
	line-height: 1.75;
}

/*
 * 461:12556 — 2px, white at 40%. From the box's top edge down to 14px above
 * "Here's our story": 139 to 536 at 1440, the text starting at 550. Anchored to
 * the stage's bottom, so it follows the text whatever the box's height. 36 is
 * that 14 plus the link's own 21.7 line.
 */
.about-intro__line {
	position: absolute;
	z-index: 1;
	top: 0;
	bottom: 36px;
	left: 50%;
	width: 2px;
	margin-left: -1px;
	overflow: hidden;
	background: rgba(255, 255, 255, 0.4);
	pointer-events: none;
}

/*
 * THE INVITATION. Amy 2026-09-14: the line "should gently animate to invite the
 * use to click the scroll down link or just scroll". A soft light runs down the
 * line toward the link, rests, and runs again. Same idea as design's own scroll
 * cue on the hero (patterns.css .scroll-cue), drawn on this line rather than as
 * a new mark, on design's --ease. The duration and the rest are mine — 3.2s at
 * first, halved to 1.6s on Amy's instruction 2026-09-14 ("speed up 2x").
 *
 * IT LOOPS WHILE THE VISITOR IS ACTIVE. WCAG 2.2.2: motion that starts by
 * itself and lasts past five seconds alongside other content needs a way to
 * pause it. A plain infinite loop fails that; three runs and a stop passed it
 * but Amy: "the hero animation only goes twice - not ok", and a pause button
 * is "inappropriate here". So:
 *
 *   - on arrival it runs 3 times (4.8s) — the only self-starting motion;
 *   - js/about.js adds .is-awake on any pointer move, scroll, key or touch
 *     while the intro is on screen, which loops it;
 *   - ~2.5s after the last activity it drops .is-awake at the end of a run,
 *     so the light finishes rather than cutting out, and rests.
 *
 * Nothing moves under reduced motion; the line itself stays.
 */
.about-intro__line::after {
	content: "";
	position: absolute;
	inset: 0 0 auto;
	height: 28%;
	background: linear-gradient(to bottom, rgba(255, 255, 255, 0), #fff 70%, rgba(255, 255, 255, 0));
	opacity: 0;
	transform: translateY(-100%);
}

@media (prefers-reduced-motion: no-preference) {

	.about-intro__line::after {
		animation: about-line 1.6s var(--ease) 3;
	}

	/* Visitor active: keep looping. Changing only the count carries the running animation on without a restart. */
	.about-intro.is-awake .about-intro__line::after {
		animation-iteration-count: infinite;
	}
}

/* 357% of a 28% light is the line's full length. */
@keyframes about-line {
	0%        { opacity: 0; transform: translateY(-100%); }
	15%       { opacity: 1; }
	70%       { opacity: 1; transform: translateY(357%); }
	80%, 100% { opacity: 0; transform: translateY(357%); }
}

/* 461:12557 — 70 below the box, centred on the line */
.about-intro__cue {
	display: block;
	width: max-content;
	margin: 70px auto 0;
	border-bottom: 1px solid transparent;
	font-family: var(--mono);
	font-size: var(--fs-control);
	line-height: 1.55;
	letter-spacing: var(--ls-eyebrow);
	text-transform: uppercase;
	/*
	 * Figma's .78 is the eyebrow ink, and patterns.css already takes the eyebrow
	 * to full white on gradient grounds because .78 misses 4.5:1 there. Same
	 * lever, same reason.
	 */
	color: #fff;
	text-decoration: none;
	transition: border-color 0.2s;
}

.about-intro__cue:hover,
.about-intro__cue:focus-visible {
	border-bottom-color: currentColor;
}

/* 1200, not design's 900 — Amy 2026-09-14, option (b) above. */
@media (max-width: 1200px) {

	.about-intro__box {
		grid-template-columns: minmax(0, 1fr);
	}

	.about-intro__copy {
		padding: 32px 24px 0;
	}

	.about-intro__lead {
		max-width: none;
		padding: 20px 24px 32px;
	}

	/* Stacked, a full-height line would cut through the copy. It keeps only its run below the box: 70 of gap less the 14 above the text. */
	.about-intro__line {
		top: auto;
		height: 56px;
	}
}

/* ----- What were we thinking?, 461:12322 ---------------------------------- */

/* Lisa's second pass: 101 above (was 108); 151 below is unchanged. */
.about-thinking {
	padding-block: clamp(3.5rem, 7.01vw, 101px) clamp(3.5rem, 10.49vw, 151px);
}

/* 461:12327 is 1309 wide in the second pass; design's 34ch cap would break it early */
.about-thinking .display {
	max-width: 1309px;
}

/* 461:12348 — 71 below the headline (286.4 to 357), four across, 23 apart */
.about-pillars {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 23px;
	margin: 71px 0 0;
	padding: 0;
	list-style: none;
}

/* Design's .card is 461:12329's fill and edge exactly; only the padding differs. */
.about-pillar {
	padding: 24px 20px 32px;
}

.about-pillar__title,
.about-agent__name,
.about-founder__name {
	font-family: var(--mono);
	font-size: var(--fs-control);
	line-height: 1.55;
	letter-spacing: var(--ls-label);   /* 1.68px at 14 */
	text-transform: uppercase;
}

.about-pillar__title {
	color: var(--mint);   /* #67d2a0 */
}

/* The small body copy in the pillars, agents and founders: 14px on 1.6, white .9 at 60% opacity. */
.about-pillar__text,
.about-agent__text,
.about-founder__bio {
	font-size: var(--fs-body-sm);
	line-height: 1.6;
	color: var(--ink-body);
	opacity: 0.6;
}

.about-pillar__text {
	margin-top: 14px;
}

/* 461:12713 — 88 below the cards; four 211 columns on a 270 pitch */
.about-agents {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 211px));
	gap: 48px 59px;
	justify-content: center;
	margin: 88px 0 0;
	padding: 0;
	list-style: none;
}

/* The text starts 83 below the tallest icon's top (721 to 804): 1 + 54 + 28 for the square icons, 57 + 26 for Rita's cloud. */
.about-agent__icon {
	margin: 1px 0 28px;
}

.about-agent__icon--rita {
	margin: 0 0 26px;
}

.about-agent__name {
	color: var(--agent);
}

.about-agent__text {
	margin-top: 6px;
}

/*
 * THE EYES. js/about.js sets --ex, --ey and --er (a glance) and --eb (a blink).
 * fill-box puts each pivot at the middle of the pair, so a turn swivels the two
 * eyes together and a blink squashes them together.
 *
 * The glance is quick and the ease decelerates hard, like an eye landing on
 * something: movement that arrives and stops is what gets noticed, where the
 * first version's slow 600ms drift did not (Amy 2026-09-14).
 */
.about-agent__eyes {
	transform-box: fill-box;
	transform-origin: center;
	transform: translate(calc(var(--ex, 0) * 1px), calc(var(--ey, 0) * 1px)) rotate(calc(var(--er, 0) * 1deg));
	transition: transform 260ms cubic-bezier(0.3, 0.7, 0.2, 1);
}

.about-agent__lids {
	transform-box: fill-box;
	transform-origin: center;
	transform: scaleY(var(--eb, 1));
	transition: transform 70ms ease-in-out;
}

@media (prefers-reduced-motion: reduce) {

	.about-agent__eyes,
	.about-agent__lids {
		transform: none;
		transition: none;
	}
}

/* 1000 and 560 are the breakpoints design uses for its own four-across chips (patterns.css .chips). */
@media (max-width: 1000px) {

	.about-pillars {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.about-agents {
		grid-template-columns: repeat(2, minmax(0, 211px));
	}
}

@media (max-width: 560px) {

	.about-pillars {
		grid-template-columns: minmax(0, 1fr);
	}

	.about-agents {
		grid-template-columns: minmax(0, 1fr);
		justify-content: stretch;
	}
}

/* ----- How it Works, 461:12558 -------------------------------------------- */

/*
 * 73 above the title at 1440. 278 below the button, which is the room the
 * drawing takes (the frame is 1014 tall; the button ends at 736). The drawing
 * bleeds off both sides, so the panel clips it rather than the page scrolling.
 */
.about-steps {
	overflow: hidden;
	padding-block: clamp(3rem, 5.07vw, 73px) clamp(8rem, 19.31vw, 278px);
}

/* 461:12584 — centred, with only the tight shadow */
.about-steps__title {
	max-width: none;
	margin: 0;
	text-align: center;
	text-shadow: 0 1px 2px rgba(3, 6, 14, 0.7);
}

/* 461:12600 — 64 below the title, three across, 39 apart */
.about-steps__list {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 39px;
	margin: 64px 0 0;
	padding: 0;
	list-style: none;
}

/* 461:12597 */
.about-step {
	padding: 25px 25px 35px;
	background: rgba(0, 0, 0, 0.3);
}

/* 461:12592 — the eyebrow's type, in white */
.about-step__label {
	font-family: var(--mono);
	font-size: var(--fs-control);
	line-height: 1.55;
	letter-spacing: var(--ls-eyebrow);
	text-transform: uppercase;
	color: #fff;
}

/* 461:12603 — 38px on 1.13, 23 below the label. Design has no 38px size; the 28px floor is mine. */
.about-step__title {
	margin-top: 23px;
	font-size: clamp(1.75rem, 1.1rem + 1.9vw, 2.375rem);
	line-height: 1.13;
	color: var(--ink);
	text-shadow: var(--sh-heading);
}

/* 461:12605 — 18px on 1.75, 16 below the title */
.about-step__text {
	margin-top: 16px;
	font-size: 1.125rem;
	line-height: 1.75;
	color: var(--ink-lead);
	text-shadow: var(--sh-lead);
}

/* 461:12702 — 82 below the boxes; the step-title size, centred, tight shadow only */
.about-steps__chat {
	margin-top: 82px;
	font-size: clamp(1.75rem, 1.1rem + 1.9vw, 2.375rem);
	line-height: 1.13;
	text-align: center;
	color: var(--ink);
	text-shadow: 0 1px 2px rgba(3, 6, 14, 0.7);
}

/* 461:12707 — 31 below the chat line. Its rgba(251,67,103,.5) fill is design's .btn--primary on pink. */
.about-steps__actions {
	display: flex;
	justify-content: center;
	margin-top: 31px;
}

/*
 * 465:13074 — Figma places it at left -19.38%, right -13.42%, bottom 2.32% of
 * the frame. Sized by width (1912/1440 = 132.79%) with its own aspect, so it
 * never stretches; bottom in vw for the same reason (23.5 of 1440).
 * z-index 1: above the ground, under the copy (.body is 3).
 */
.about-steps__drawing {
	position: absolute;
	z-index: 1;
	left: -19.38%;
	bottom: 1.63vw;
	width: 132.79%;
	max-width: none;
	height: auto;
	pointer-events: none;
}

/*
 * THE DRAW-IN (Amy 2026-09-14). js/about.js adds .is-drawn once, when the
 * drawing is a third on screen. The pen runs 4.8s — under WCAG 2.2.2's five
 * seconds for self-starting motion — and the line then stays. pathLength="1"
 * on the path makes one dash exactly the path's length at any size.
 *
 * Hidden only where scripting is on, the same fail-safe design uses for .b:
 * with no script the art is simply there.
 */
@media (scripting: enabled) {

	.about-steps__drawing path {
		stroke-dasharray: 1;
		stroke-dashoffset: 1;
	}
}

.about-steps__drawing.is-drawn path {
	stroke-dashoffset: 0;
	transition: stroke-dashoffset 4.8s cubic-bezier(0.37, 0, 0.63, 1);
}

@media (prefers-reduced-motion: reduce) {

	.about-steps__drawing path,
	.about-steps__drawing.is-drawn path {
		stroke-dashoffset: 0;
		transition: none;
	}
}

/*
 * NARROW: THE DRAWING GOES BELOW THE BUTTON. At 1440 the figure's head sits
 * left of the centred button, so the frame can let the drawing rise behind the
 * chat line. The drawing scales with the viewport and the button does not, so
 * as the page narrows the head slides under the button — measured on the live
 * draft at 659px, the lines ran behind "Book a 15 min consultation". Below 1000
 * the bottom padding becomes the drawing's own height (1912x419 at 132.79vw =
 * 29.14vw) plus its 1.63vw offset plus a 24px gap, so it sits wholly beneath.
 * Not a Figma value; the frame has no narrow layout.
 */
@media (max-width: 1000px) {

	.about-steps {
		padding-bottom: calc(30.77vw + 24px);
	}
}

@media (max-width: 900px) {

	.about-steps__list {
		grid-template-columns: minmax(0, 1fr);
		gap: 20px;
	}
}

/* ----- FAQ, 465:13279 ----------------------------------------------------- */

.about-faq {
	padding-block: clamp(3.5rem, 5.97vw, 86px) clamp(3.5rem, 8.54vw, 123px);
}

/* 465:13282 — no eyebrow above it, so no top margin; 887 wide */
.about-faq__title {
	max-width: 887px;
	margin-top: 0;
}

/* 465:13284 — 48 below the title */
.about-faq__list {
	margin-top: 48px;
	background: rgba(3, 4, 7, 0.48);
	backdrop-filter: blur(1px);
	-webkit-backdrop-filter: blur(1px);
}

/* 465:13285 — rows after the first drop their top border, so edges never double */
.about-faq__item {
	padding: 20px 32px;
	border: 1px solid rgba(255, 255, 255, 0.1);
	background: rgba(255, 255, 255, 0.08);
}

.about-faq__item + .about-faq__item {
	border-top: 0;
}

/* 465:13286 — question and icon share a row, 16 below */
.about-faq__item summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	padding-bottom: 16px;
	cursor: pointer;
	list-style: none;
}

.about-faq__item summary::-webkit-details-marker {
	display: none;
}

/* 465:13287 — 24px on 1.1. The 20px floor is mine. */
.about-faq__q {
	margin: 0;
	font-size: clamp(1.25rem, 1.1rem + 0.5vw, 1.5rem);
	line-height: 1.1;
	color: var(--ink);
}

/*
 * 465:13289 / 465:13336 — two 1px mint strokes in a 20 box, at y 9.5 and x 9.92.
 * The vertical one goes when the row is open, which is Figma's minus sign.
 */
.about-faq__icon {
	position: relative;
	flex: 0 0 20px;
	width: 20px;
	height: 20px;
}

.about-faq__icon::before,
.about-faq__icon::after {
	content: "";
	position: absolute;
	background: var(--mint);
}

.about-faq__icon::before {
	top: 9px;
	left: 0;
	width: 20px;
	height: 1px;
}

.about-faq__icon::after {
	top: 0;
	left: 9.42px;
	width: 1px;
	height: 20px;
}

.about-faq__item[open] .about-faq__icon::after {
	display: none;
}

/* js/about.js keeps `open` until the slide-shut finishes; the icon turns back to plus as it starts. */
.about-faq__item[data-state="closing"] .about-faq__icon::after {
	display: block;
}

/* 465:13288 — 18px on 1.5, #a8b4c8, 60 clear of the icon column. Paragraphs sit flush (mb-0). */
.about-faq__a {
	padding-right: 60px;
	font-size: 1.125rem;
	line-height: 1.5;
	color: #a8b4c8;
}

@media (max-width: 700px) {

	.about-faq__item {
		padding: 16px 20px;
	}

	.about-faq__a {
		padding-right: 0;
	}
}

/* ----- closing, 402:11474 ------------------------------------------------- */

/* 101 above the eyebrow; 168 below the chips (574.25 to 742) */
.about-closing {
	padding-block: clamp(3.5rem, 7.01vw, 101px) clamp(3.5rem, 11.65vw, 168px);
}

/* 402:11475 is 587 wide and 402:11480 is 558, with 55 between (707 to 762) */
.about-closing .body {
	display: grid;
	grid-template-columns: minmax(0, 587fr) minmax(0, 558fr);
	column-gap: 55px;
	align-items: start;
}

/* 402:11479 — tight shadow only; the 587 column sets the measure */
.about-closing .display {
	max-width: none;
	text-shadow: 0 1px 2px rgba(3, 6, 14, 0.7);
}

/* 402:11480 — design's .card; its top is 41 below the eyebrow's (101 to 142), 28 in */
.about-closing__card {
	margin-top: 41px;
	padding: 28px;
}

/* 402:11482 — centred, 26 below it plus the 10 gap */
.about-closing__card .card__title {
	margin-bottom: 36px;
	text-align: center;
}

/* 402:11484 — full width; its rgba(0,161,255,.5) fill is design's .btn--primary on sky */
.about-closing__card .btn {
	width: 100%;
}

/* 402:11486 — 75 below the heading block (358.4 to 433), four across, 27 apart */
.about-closing__chips {
	grid-column: 1 / -1;
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 27px;
	margin: 75px 0 0;
	padding: 0;
	list-style: none;
}

/* 402:11487 — 141 tall, text centred both ways; 20px mono on 1.42. The 16px floor is mine. */
.about-closing__chip {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 141px;
	padding: 27px 28px 28px;
	border: 1px solid rgba(255, 255, 255, 0.2);
	background: rgba(255, 255, 255, 0.2);
	box-shadow: 0 8px 30px rgba(37, 37, 45, 0.08);
	font-family: var(--mono);
	font-size: clamp(1rem, 0.85rem + 0.5vw, 1.25rem);
	line-height: 1.42;
	text-align: center;
	color: #fff;
	text-shadow: 0 1px 2px rgba(3, 6, 14, 0.7);
}

/* 1000 and 560, as design's own chips */
@media (max-width: 1000px) {

	.about-closing .body {
		grid-template-columns: minmax(0, 1fr);
	}

	.about-closing__card {
		margin-top: 2rem;
	}

	.about-closing__chips {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		margin-top: 2.5rem;
	}
}

@media (max-width: 560px) {

	.about-closing__chips {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* ----- contact, 461:12800 — the closing section with an email form ---------- */

/*
 * The frame's copy starts 180 from the top of the page, which includes the
 * 80px header, so 100 below it; the chips end 99 above the footer (980 to 1079).
 */
.about-closing--contact {
	padding-block: calc(var(--hdr-h) + clamp(3.5rem, 6.94vw, 100px)) clamp(3.5rem, 6.88vw, 99px);
}

/* 461:12953 — 100 below the card (739 to 839). Here the card, not the heading, is the taller item. */
.about-closing--contact .about-closing__chips {
	margin-top: 100px;
}

/* Stacked, the same 2.5rem as About's closing — measured 100px at 390 before this, because the rule above outranked it. */
@media (max-width: 1000px) {

	.about-closing--contact .about-closing__chips {
		margin-top: 2.5rem;
	}
}

/* 461:13027 — 21px on 1.2, centred, heading shadow; 37 above plus the card's 10 gap */
.about-closing__or {
	margin-top: 47px;
	font-size: 1.3125rem;
	line-height: 1.2;
	text-align: center;
	color: var(--ink);
	text-shadow: var(--sh-heading);
}

/* 462:13044 — fields 20 apart, the label 10 above its field; the whole block 10 below the line above */
.about-contact-form {
	display: flex;
	flex-direction: column;
	gap: 20px;
	margin-top: 10px;
}

.about-contact-form__field {
	display: flex;
	flex-direction: column;
	gap: 10px;
}

/* 462:13047 — design's own .field label: mono 14, 1.68 tracking, uppercase, white .8 */
.about-contact-form label {
	font-family: var(--mono);
	font-size: var(--fs-control);
	line-height: 1.55;
	letter-spacing: var(--ls-label);
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.8);
}

/*
 * 462:13049 / 462:13055 — design's .field input box (fill .1, stroke .3,
 * radius 3, 10/14 padding), but the frame sets the text in Geist 16 sentence
 * case, not the audit form's mono capitals.
 */
.about-contact-form :is(input:not([type="radio"]), textarea) {
	width: 100%;
	padding: 10px 14px;
	border: 1px solid var(--field-stroke);
	border-radius: var(--ctl-radius);
	background: var(--field-fill);
	font-family: var(--sans);
	font-size: 1rem;
	line-height: 1.52;
	letter-spacing: 0.02em;
	color: #fff;
	transition: border-color 180ms var(--ease), background 180ms var(--ease);
}

/* The frame's placeholder is 40% white; design's form uses .46, kept for one placeholder ink across the site. */
.about-contact-form :is(input:not([type="radio"]), textarea)::placeholder {
	color: rgba(255, 255, 255, 0.46);
}

/* 462:13049 shows the active stroke, .65 — design's --field-stroke-active */
.about-contact-form :is(input:not([type="radio"]), textarea):focus {
	border-color: var(--field-stroke-active);
	background: rgba(255, 255, 255, 0.14);
	outline: none;
}

.about-contact-form :is(input:not([type="radio"]), textarea):focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

/* 461:13023 — 24 below the last field plus the card's 10 gap: 34, less the form's own 20 */
.about-contact-form .btn {
	margin-top: 14px;
}

/*
 * PHONE AND CONTACT PREFERENCE (Amy 2026-09-14). Not in the frame, so these
 * reuse the form's own label and field styles rather than inventing any. The
 * choice is a fieldset so the question is announced with its options.
 */
.about-contact-form__optional {
	letter-spacing: normal;
	text-transform: none;
	color: rgba(255, 255, 255, 0.6);
}

.about-contact-form__choice {
	margin: 0;
	padding: 0;
	border: 0;
	min-width: 0;
}

/* The legend is the same type as the field labels. */
.about-contact-form__choice legend {
	margin-bottom: 10px;
	padding: 0;
	font-family: var(--mono);
	font-size: var(--fs-control);
	line-height: 1.55;
	letter-spacing: var(--ls-label);
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.8);
}

.about-contact-form__options {
	display: flex;
	flex-wrap: wrap;
	gap: 10px 28px;
}

.about-contact-form__options label {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	cursor: pointer;
	color: var(--ink);
}

.about-contact-form__options input {
	inline-size: 18px;
	block-size: 18px;
	margin: 0;
	accent-color: var(--accent);
}

/*
 * THE COMMENTS BOX IS TALLER THAN THE FRAME'S ONE-LINE FIELD — Amy 2026-09-14,
 * "taller". Four lines of the field's own type plus its padding; the visitor can
 * pull it taller, never narrower.
 */
.about-contact-form textarea {
	display: block;
	min-height: calc(4 * 1.52em + 20px);
	resize: vertical;
}

/* The #contact-form jump after a submission clears the fixed header. */
.about-contact-form,
.about-contact-form__done {
	scroll-margin-top: calc(var(--hdr-h) + 24px);
}

/* The zosimo-contact plugin's honeypot — out of view, still submitted. Same rule as the consent form's. */
.zosimo-contact__hp {
	position: absolute;
	inline-size: 1px;
	block-size: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* Result messages mirror the consent form's (.zosimo-consent__done / __error above). */
.about-contact-form__done {
	margin: 10px 0 0;
	padding: var(--card-pad);
	border: 1px solid var(--card-edge);
	font-size: var(--fs-body);
	line-height: var(--lh-lead);
	text-align: center;
	color: var(--ink);
}

.about-contact-form__error {
	margin: 0;
	padding: 12px 16px;
	border: 1px solid var(--accent);
	border-radius: var(--ctl-radius);
	background-color: color-mix(in srgb, var(--accent) 12%, transparent);
	font-size: var(--fs-body-sm);
	line-height: 1.5;
	font-weight: 700;
	color: var(--ink);
}

/* Only if the plugin is inactive: the address instead of a form that submits into nothing. */
.about-contact-form__fallback {
	margin-top: 10px;
	text-align: center;
}

.about-contact-form__fallback a {
	color: var(--ink);
}

@media (prefers-reduced-motion: reduce) {

	.about-contact-form :is(input:not([type="radio"]), textarea) {
		transition: none;
	}
}

/* ----- Founders, 461:12608 ------------------------------------------------ */

.about-founders {
	padding-block: clamp(3.5rem, 7.08vw, 102px);
}

/* 461:12797 is 723 wide, which is what breaks it after "digital" */
.about-founders__title {
	max-width: 723px;
}

/*
 * 461:12632 / 461:12635 — two 458 columns, 82 apart, 54 below the headline.
 * Centred. Figma's pair sits 20px left of centre (x 201 to 1199); read as a
 * drawing slip, like the agents row, which is 11px left.
 */
.about-founders__list {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 458px));
	gap: 64px 82px;
	justify-content: center;
	margin-top: 54px;
}

/*
 * The portraits are different sizes, 328 and 352, with their centres level, so
 * each is centred in a 352 band. The name starts 26 below the band.
 */
.about-founder__portrait {
	display: flex;
	align-items: center;
	min-height: 352px;
	margin-bottom: 26px;
}

.about-founder__portrait img {
	height: auto;
}

.about-founder__name {
	color: var(--founder);
}

.about-founder__bio {
	margin-top: 6px;
}

/* 461:12634 — an empty line between the two paragraphs */
.about-founder__bio p + p {
	margin-top: 1.6em;
}

@media (max-width: 900px) {

	.about-founders__list {
		grid-template-columns: minmax(0, 458px);
	}

	.about-founder__portrait {
		min-height: 0;
	}
}

/* ===== How it works, 663:8973 — replaces the pricing panel =============== */

/*
 * Lisa's Figma, file bJOQV9jBrChY424AD4UNF7, node 663:8973, desktop 1440 only.
 * Every number below is from that pull (Origin figma-pull-log.md, 2026-10-02)
 * unless its comment says "no frame". Smaller sizes have no frames: Koda
 * 2026-10-02 said Build stacks them and Lisa reviews before live, so every
 * breakpoint value in this section is Build's, waiting on her look.
 *
 * Reuses the page's own blocks: .eyebrow, .display + em (mint via
 * data-accent), .card for the band and tiles (same veil, ink, edge and blur
 * as Figma), .btn--primary for the closer (mint at 50%, as drawn).
 */
.how.panel{ padding-block:164px 112px }
.how > .body{ display:flex; flex-direction:column; gap:72px }

/* theme.css resets h1-h3 only; the benefit and tile titles here are h4. */
.how h4{ margin:0; font-weight:400 }
.how-head{ display:flex; flex-direction:column; gap:20px }
.how .display{ margin-top:0; max-width:none; line-height:1.18 }
.how-head__sub{ font-size:var(--fs-lead); line-height:1.5; color:var(--ink-eyebrow) }

/* --- the "every site includes" band --- */
.how-band{ display:flex; flex-direction:column; align-items:center; gap:32px; padding:36px 24px 40px }
.how-band__title,
.how-tile__label{
  font-family:var(--mono); font-size:var(--fs-control); line-height:1.55;
  letter-spacing:var(--ls-eyebrow); text-transform:uppercase; color:var(--mint);
}
.how-band__title{ text-align:center }
.how-benefits{
  list-style:none; margin:0; padding:0; width:100%;
  display:grid; grid-template-columns:repeat(5, minmax(0,1fr)); gap:24px;
}
.how-benefit{ display:flex; flex-direction:column; align-items:center; gap:12px; text-align:center }
.how-benefit__badge{
  display:flex; align-items:center; justify-content:center;
  width:56px; height:56px; border-radius:28px; margin-bottom:4px; /* the 1 x 4 spacer */
  background:rgba(103,210,160,.10); border:1px solid rgba(103,210,160,.40);
}
.how-benefit__title{ font-size:17px; line-height:1.3; font-weight:500; color:var(--ink) }
.how-benefit__body{ font-size:var(--fs-body-sm); line-height:1.6; color:var(--ink-eyebrow) }

/* --- the three layers --- */
.how-layer{
  display:flex; align-items:flex-start; gap:48px; padding-block:44px;
  border-top:1px solid rgba(255,255,255,.12);
}
.how-layer:last-child{ border-bottom:1px solid rgba(255,255,255,.12) }
.how-layer__label{ flex:0 0 264px; display:flex; flex-direction:column; gap:14px }
.how-layer__num{ font-size:56px; line-height:56px; font-weight:300; color:var(--mint) }
.how-layer__name{
  font-family:var(--mono); font-size:var(--fs-control); line-height:1.55;
  letter-spacing:var(--ls-eyebrow); text-transform:uppercase; color:var(--ink);
}
.how-layer__line{ font-size:var(--fs-body); line-height:1.6; color:var(--ink-eyebrow) }

.how-tiles{ flex:1 1 0; min-width:0; display:flex; gap:12px; align-items:stretch }
.how-tile{ flex:1 1 0; min-width:0; display:flex; flex-direction:column; gap:14px; padding:22px 22px 24px }

.how-tile__art{
  position:relative; height:96px; overflow:hidden; border-radius:2px;
  border:1px solid rgba(188,214,255,.20);
  display:flex; align-items:center; justify-content:center;
}
.how-tile__art::before{ content:""; position:absolute; inset:-1px; opacity:.22 }
.how-tile__art--build::before{ background:linear-gradient(-25.334deg, rgb(54,153,107) 8.06%, rgb(64,181,127) 88.875%) }
.how-tile__art--host::before{ background:linear-gradient(139.557deg, rgb(0,161,255) 0%, rgb(88,122,218) 100%) }
.how-tile__art--boost::before{ background:linear-gradient(to right, #f78614, #d97400) }
.how-art{ position:relative; flex:none }
.how-art__piece{ position:absolute; max-width:none }
.how-art__piece--half{ opacity:.5 }
.how-art__piece--faint{ opacity:.4 }
.how-art__text{ font-size:20px; line-height:1.2; color:var(--ink); white-space:nowrap; transform:translateX(-50%) }

.how-tile__head{ display:flex; flex-direction:column; gap:10px }
.how-tile__title{ font-size:24px; line-height:1.2; color:var(--ink) }
.how-tile__intro{ font-size:var(--fs-body-sm); line-height:1.6; color:var(--ink-body) }

/* The divider is the list's top border: 14px either side inside the tile's
   gap, 10px on Basic Hosting, whose list sits inside the header (Figma 663:9105). */
.how-tile__bullets{
  list-style:none; margin:0; padding:14px 0 0;
  border-top:1px solid var(--hair);
  display:flex; flex-direction:column; gap:8px;
}
.how-tile--tight .how-tile__bullets{ padding-top:10px }
.how-tile__bullets li{
  position:relative; padding-left:22px; /* 8px dot + 14px gap */
  font-size:var(--fs-list); line-height:20px; font-weight:500;
  letter-spacing:-.01em; color:var(--ink-list);
}
.how-tile__bullets li::before{
  content:""; position:absolute; left:0; top:0; width:8px; height:14px;
  background:url("../images/how-it-works/dot.svg") no-repeat;
}

.how-or{ flex:0 0 32px; display:flex; align-items:center; justify-content:center }
.how-or span{
  display:flex; align-items:center; justify-content:center;
  width:32px; height:32px; border-radius:16px;
  background:#030407; border:1px solid rgba(188,214,255,.40);
  font-family:var(--mono); font-size:12px; line-height:16px; text-transform:uppercase;
  color:var(--ink-nav);
}

/* --- closer --- */
.how-closer{ display:flex; flex-direction:column; align-items:center; gap:28px; padding-top:8px; text-align:center }
.how-closer__title{ font-size:40px; line-height:1.2; color:var(--ink) }
.how-closer__btn{ padding:12px 28px; letter-spacing:2px; filter:drop-shadow(0 0 12px rgba(102,209,161,.25)) }

/* --- smaller screens: no frames (see top of section) --- */

/* Below 1280 the 264px label column leaves the three tiles under ~200px each
   (at Amy's 120% scaling a 1440 laptop is 1200 wide), so the label goes above. */
@media (max-width:1279px){
  .how-layer{ flex-direction:column; gap:28px }
  .how-layer__label{ flex:none }
  .how-benefits{ grid-template-columns:repeat(3, minmax(0,1fr)); row-gap:32px }
}
@media (max-width:900px){
  .how.panel{ padding-block:calc(var(--hdr-h) + 3rem) 4rem }
  .how > .body{ gap:56px }
  .how-tiles{ flex-direction:column; gap:12px }
  .how-tile{ flex:none }
  .how-or{ flex:none; height:32px }
  .how-benefits{ grid-template-columns:repeat(2, minmax(0,1fr)) }
  .how-closer__title{ font-size:clamp(1.75rem, 1.2rem + 2.4vw, 2.5rem) }
}
@media (max-width:560px){
  .how-benefits{ grid-template-columns:1fr }
  .how-closer__btn{ white-space:normal }
}
