/*
 * Chrome v2: the dock and the top row (inc/dock.php, inc/chrome.php, assets/js/nav.js).
 *
 * Structure, behaviour and geometry are the house store's, 1:1. Every colour,
 * face, size, tracking and easing is TRISTOPIC's own token (docs/style-contract.md);
 * tools/check-v2.sh rejects a raw colour here. The store prints ink on paper with
 * a lime second ink; TRISTOPIC prints paper on ink, and its accent is the second ink.
 */

:root {
	--dock-edge: 10px;     /* floating chrome sits 10px from every screen edge */
	--pill-h: 2.5rem;      /* every pill and round button */
	--dock-h: calc(var(--pill-h) + 0.4rem + 0.6875rem + max(var(--dock-edge), env(safe-area-inset-bottom, 0px)));
	--dock-ease: var(--wp--custom--ease);
	--dock-fast: var(--wp--custom--duration--fast);
	--dock-base: var(--wp--custom--duration--base);
}

/* The project card and the strips hold off the bottom by this much: now the dock. */
body.has-v2 { --tristopic-colophon-h: var(--dock-h); }

/*
 * The dock sits in one place on every page (owner, 13 Nov: "identical on all pages",
 * as the house store does it): on the bottom edge, with its legal row (© · Privacy)
 * under it, exactly where it sits over the work. The inner pages' own sticky strip
 * (clock · © · Thessaloniki, GR) is gone under v2, so there is nothing to lift the
 * dock over and © is printed once. Every page's text ends above the dock.
 */
body.has-v2 .wp-site-blocks > :is(.tristopic-footer, .wp-block-template-part:has(> .tristopic-footer)) { display: none; }
body.has-v2 .wp-site-blocks > main { padding-bottom: calc(var(--pill-h) + 2 * var(--dock-edge)); }
body.has-v2:not(.tristopic-sphere-page) .wp-site-blocks > main { padding-bottom: calc(var(--dock-h) + var(--dock-edge)); }

/* ------------------------------------------------------------ the top row */

.tristopic-bar__inner--v2 {
	grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
	align-items: center;
}
.tristopic-bar__inner--v2 .tristopic-bar__mark { justify-self: center; grid-column: 2; }
.tristopic-bar__inner--v2 > :first-child { justify-self: start; }
.tristopic-bar__inner--v2 > :last-child { justify-self: end; }

/* The view switch is the dock's left button (owner, 13 Nov, as on the house store): it
   shows the view it leads to. Off the grid the same button goes back to the grid and
   shows the view you will land in (the sphere, unless this visit picked the grid). */
.dock-view svg[data-view-icon] { display: none; }
body[data-view="index"] .dock-view:not(.dock-grid) svg[data-view-icon="sphere"],
body[data-view="sphere"] .dock-view:not(.dock-grid) svg[data-view-icon="index"],
body:not([data-view]) .dock-view:not(.dock-grid) svg[data-view-icon="index"],
html[data-last-view="index"] .dock-grid svg[data-view-icon="index"],
html:not([data-last-view="index"]) .dock-grid svg[data-view-icon="sphere"] { display: block; }

.tristopic-bar__clock {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--micro);
	letter-spacing: var(--wp--custom--tracking--wider);
	text-transform: uppercase;
	color: var(--wp--preset--color--paper-dim);
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

/* ---------------------------------------------------------------- the dock */

/*
 * One object at the bottom of every page, --dock-edge from the screen edges:
 * About · Disciplines · ☰ · Industry · Let's talk, and the legal row under it.
 * ☰ is the centre of the screen (the middle column); each side hangs from it.
 */
.dock {
	position: fixed;
	inset: auto 0 0 0;
	z-index: 70;   /* over the sphere furniture and the project card (50), with the bar (60) */
	display: grid;
	grid-template-columns: minmax(0, 1fr) var(--pill-h) minmax(0, 1fr);
	grid-template-areas: "start menu end" "legal legal legal";
	align-items: center;
	gap: 0.4rem var(--dock-edge);
	padding: 0 var(--dock-edge) max(var(--dock-edge), env(safe-area-inset-bottom, 0px));
	pointer-events: none;
	transition: translate var(--dock-base) var(--dock-ease), opacity var(--dock-fast) var(--dock-ease);
}
.dock-side { display: flex; align-items: center; gap: var(--dock-edge); min-width: 0; }
.dock-side-start { grid-area: start; justify-content: flex-end; }
.dock-side-end { grid-area: end; justify-content: flex-start; }
.dock-side > *, .dock-burger, .dock-legal { pointer-events: auto; }
.dock-burger { grid-area: menu; }
/* Hugs its pill (the measured --pick-w is the basis) and gives way only on a narrow
   screen: the pill fills it, so nav.js sees the shortfall and goes tight. */
.dock-filter { position: relative; flex: 0 1 var(--pick-w, auto); display: flex; min-width: 0; }

/* Round buttons: solid ink, a 1px line, paper drawing. */
.dock-btn {
	position: relative;
	flex: none;
	display: grid;
	place-items: center;
	width: var(--pill-h);
	height: var(--pill-h);
	padding: 0;
	border: var(--wp--custom--line);
	border-radius: 999px;
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper);
	cursor: pointer;
	text-decoration: none;
	transition: background-color var(--dock-fast) var(--dock-ease), color var(--dock-fast) var(--dock-ease), border-color var(--dock-fast) var(--dock-ease);
}
.dock-btn svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: butt; stroke-linejoin: miter; }
.dock-btn svg .is-solid { fill: currentColor; stroke: none; }
/* Touch: each button answers 5px beyond its edge (50px targets, still apart at 10px gaps). */
.dock-btn::after, .dock-pick::after { content: ""; position: absolute; inset: -5px; }
.dock-btn[aria-current] { border-color: var(--wp--preset--color--paper-faint); }

/* The burger: two 2px bars that cross into an × while the menu is open. */
.burger { position: relative; width: 16px; height: 10px; }
.burger i { position: absolute; left: 0; width: 16px; height: 2px; background: currentColor; transition: transform var(--dock-base) var(--dock-ease), top var(--dock-base) var(--dock-ease); }
.burger i:first-child { top: 0; }
.burger i:last-child { top: 8px; }
body.menu-open .burger i:first-child { top: 4px; transform: rotate(45deg); }
body.menu-open .burger i:last-child { top: 4px; transform: rotate(-45deg); }
body.menu-open .dock-burger { background: var(--wp--preset--color--paper); color: var(--wp--preset--color--ink); border-color: var(--wp--preset--color--paper); }

/*
 * Disciplines and Industry: two pills of one width, mirrored about ☰, as wide as
 * the widest name either list can show, never changing with what is chosen
 * (nav.js sets --pick-w from the words themselves). Each opens its list upward,
 * centred over its own pill. One list at a time.
 */
.dock-pick {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	width: 100%;
	min-width: 0;
	height: var(--pill-h);
	padding: 0 0.9rem;
	border: var(--wp--custom--line);
	border-radius: 999px;
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper);
	cursor: pointer;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--micro);
	letter-spacing: var(--wp--custom--tracking--wide);
	text-transform: uppercase;
	line-height: 1;
	transition: background-color var(--dock-fast) var(--dock-ease), color var(--dock-fast) var(--dock-ease), border-color var(--dock-fast) var(--dock-ease);
}
.dock-pick > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dock-caret { flex: none; width: 10px; height: 10px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: butt; stroke-linejoin: miter; transition: rotate var(--dock-base) var(--dock-ease); }
.dock-pick[aria-expanded="true"] .dock-caret { rotate: 180deg; }
.dock-pick:is(.is-active, [aria-expanded="true"]) { background: var(--wp--preset--color--paper); color: var(--wp--preset--color--ink); border-color: var(--wp--preset--color--paper); }
/* Tight (nav.js, when the screen gives the pills less than their words; or any
   320px screen before the script runs): tighter letters and no caret, words whole. */
.dock.is-tight .dock-pick { padding: 0 0.5rem; letter-spacing: 0.04em; }
.dock.is-tight .dock-caret { display: none; }
@media (max-width: 359px) {
	.dock-pick { padding: 0 0.35rem; font-size: 0.5625rem; letter-spacing: 0.02em; }   /* a size down, so "Disciplines" stays whole beside ☰ */
	.dock-caret { display: none; }
}

.dock-menu-list {
	position: absolute;
	bottom: calc(100% + var(--dock-edge));
	left: 50%;
	translate: -50% 0;
	z-index: 1;
	display: grid;
	min-width: 100%;
	width: max-content;
	max-width: min(16rem, calc(100vw - 2 * var(--dock-edge)));
	max-height: min(60vh, 22rem);
	overflow: auto;
	overscroll-behavior: contain;
	scrollbar-width: none;
	border: var(--wp--custom--line);
	border-radius: 14px;
	background: var(--wp--preset--color--ink-raised);
	animation: dock-pick-in var(--dock-base) var(--dock-ease) both;
}
.dock-menu-list::-webkit-scrollbar { display: none; }
.dock-menu-list[hidden] { display: none; }
@keyframes dock-pick-in { from { opacity: 0; translate: -50% 8px; } }
.dock-item {
	display: flex;
	align-items: center;
	height: var(--pill-h);
	padding: 0 0.9rem;
	color: var(--wp--preset--color--paper);
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--micro);
	letter-spacing: var(--wp--custom--tracking--wide);
	text-transform: uppercase;
	text-decoration: none;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	transition: background-color var(--dock-fast) var(--dock-ease), color var(--dock-fast) var(--dock-ease);
}
.dock-item + .dock-item { border-top: var(--wp--custom--line); }
.dock-item[aria-current], .dock-item[aria-pressed="true"] { background: var(--wp--preset--color--paper); color: var(--wp--preset--color--ink); }
/* In place (grid pages) the rows are buttons: name left, how many projects it leaves right. */
button.dock-item { width: 100%; gap: 1.25rem; justify-content: space-between; border: 0; border-radius: 0; background: none; cursor: pointer; text-align: left; }
button.dock-item + .dock-item { border-top: var(--wp--custom--line); }
button.dock-item[aria-pressed="true"] { background: var(--wp--preset--color--paper); }
.dock-item-name { overflow: hidden; text-overflow: ellipsis; }
.dock-item-count { flex: none; font-variant-numeric: tabular-nums; color: var(--wp--preset--color--paper-faint); }
.dock-item[aria-pressed="true"] .dock-item-count { color: inherit; }
/* A choice that would leave no work, given the other pill: there, but not pressable. */
.dock-item:disabled { cursor: default; color: var(--wp--preset--color--paper-faint); }
.dock-item:disabled .dock-item-count { color: var(--wp--preset--color--ink-line); }

/* The second ink: hover fills with the accent, the drawing in ink (pointer devices only). */
@media (hover: hover) and (pointer: fine) {
	:is(.dock-btn, .dock-pick:not([aria-expanded="true"]), .dock-item:not([aria-current], [aria-pressed="true"], :disabled)):hover {
		background: var(--wp--preset--color--accent);
		color: var(--wp--preset--color--ink);
		border-color: var(--wp--preset--color--accent);
	}
}
/* Keyboard focus: the site's own rule (accent), on the shape you would press. */
:is(.dock-btn, .dock-pick, .dock-item):focus-visible { outline: none; color: var(--wp--preset--color--accent); border-color: var(--wp--preset--color--accent); }
:is(.dock-pick.is-active, .dock-pick[aria-expanded="true"], .dock-item[aria-current], .dock-item[aria-pressed="true"]):focus-visible { color: var(--wp--preset--color--ink); box-shadow: inset 0 0 0 2px var(--wp--preset--color--accent); }

/* ---------------------------------------------------------- the legal row */

.dock-legal { grid-area: legal; justify-self: center; min-width: 0; max-width: 100%; }
.dock-links {
	display: flex;
	align-items: center;
	gap: 1.1rem;
	overflow-x: auto;
	scrollbar-width: none;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.5625rem;
	letter-spacing: var(--wp--custom--tracking--wider);
	text-transform: uppercase;
	line-height: 1;
	padding: 6px 5px 11px;
	margin: -6px -5px -11px;   /* room for a focus ring and the tap areas, no shift */
}
.dock-links::-webkit-scrollbar { display: none; }
.dock-links > * { flex: none; color: var(--wp--preset--color--paper-dim); }
@supports (text-box: trim-both cap alphabetic) {
	.dock-links > * { text-box: trim-both cap alphabetic; }   /* the letters themselves sit 10px from the screen edge */
}
.dock-links a { text-decoration: none; padding-block: 6px 11px; margin-block: -6px -11px; transition: color var(--dock-fast) var(--dock-ease); }
.dock-links a:hover { color: var(--wp--preset--color--accent); }
.dock-links a[aria-current] { color: var(--wp--preset--color--paper); text-decoration: underline; text-underline-offset: 0.35em; }

/* ------------------------------------------------------ the full-screen menu */

/*
 * The house store's menu, 1:1 in structure (inc/menu.php, nav.js), on TRISTOPIC's
 * ink. Under the dock (70), over the page and the bar; the wordmark is lifted
 * above it while it is open, and the dock comes back down to the edge with its
 * legal row, so the open menu is the same on every page.
 */
.menu {
	--menu-shell: clamp(1rem, 3.2vw, 2.5rem);
	--menu-top: calc(2.25rem + var(--menu-shell));   /* under the wordmark */
	position: fixed;
	inset: 0;
	z-index: 65;
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper);
}
.menu[hidden] { display: none; }
.menu-panel {
	height: 100%;
	overflow: auto;
	display: grid;
	grid-template-rows: 1fr auto;
	grid-template-columns: minmax(0, 1fr);   /* never wider than the screen */
	padding: var(--menu-top) var(--menu-shell) calc(var(--dock-h) + 1.5rem);   /* the bottom clears the dock */
	outline: none;
	overscroll-behavior: contain;
	animation: menu-fade-in 0.35s var(--dock-ease) both;
}
.menu.is-closing .menu-panel { animation: menu-fade-out 0.25s var(--dock-ease) forwards; }
@keyframes menu-fade-in { from { opacity: 0; } }
@keyframes menu-fade-out { to { opacity: 0; } }
.menu-main { align-self: center; display: grid; }   /* the disciplines and the service row, centred together */
.menu-list { display: grid; justify-items: stretch; margin: 0; padding: 0; list-style: none; text-align: center; }
.menu-list li { border-top: var(--wp--custom--line); animation: menu-in 0.6s var(--dock-ease) both; animation-delay: calc(var(--i) * 45ms + 60ms); }
.menu-list li:last-child { border-bottom: var(--wp--custom--line); }
@keyframes menu-in { from { opacity: 0; transform: translateY(14px); } }

/* One size drives the menu, and rows follow it: the word is as large as the screen's
   height allows for the number of disciplines (--rows, from inc/menu.php) with the
   service row, the accounts, the newsletter and the dock still in view; never more
   than 9.6% of the width or 80px, never under 18px. A row is 1.36 words + 19px
   (number, gap); the rest takes 400px. svh: the height with the browser's bars showing. */
.menu { --menu-size: clamp(1.125rem, min(9.6vw, calc((100vh - 400px - 19px * var(--rows, 5)) / (1.36 * var(--rows, 5)))), 5rem); }
@supports (height: 100svh) {
	.menu { --menu-size: clamp(1.125rem, min(9.6vw, calc((100svh - 400px - 19px * var(--rows, 5)) / (1.36 * var(--rows, 5)))), 5rem); }
}

/* Centred: the number above its word, both on the centre line. */
.menu-link { display: grid; justify-items: center; gap: 0.5rem; padding: calc(var(--menu-size) * 0.18) 0; color: var(--wp--preset--color--paper); text-decoration: none; }
.menu-num {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--micro);
	letter-spacing: var(--wp--custom--tracking--wider);
	color: var(--wp--preset--color--paper-faint);
	line-height: 1;
}
/* TRISTOPIC's title cut: 700 at 124%, display tracking. */
.menu-word {
	font-size: var(--menu-size);
	font-weight: 700;
	font-stretch: 124%;
	line-height: 1;
	letter-spacing: -0.035em;
	text-underline-offset: 0.12em;
	text-decoration-thickness: max(1px, 0.04em);
	transition: transform var(--dock-base) var(--dock-ease), color var(--dock-fast) var(--dock-ease);
}
/* The one being shown is underlined: the site's own "you are here". */
.menu-link[aria-current] .menu-word { text-decoration-line: underline; }
@media (hover: hover) and (pointer: fine) {
	.menu-link:hover .menu-word { transform: scale(1.03); color: var(--wp--preset--color--accent); }
}
.menu-link:focus-visible { outline: none; }
.menu-link:focus-visible .menu-word { color: var(--wp--preset--color--accent); }

/* Under the disciplines: the service pages, small, centred, in the bar's register. */
.menu-more {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 0.15rem 1.6rem;
	margin: 0;
	padding: clamp(1rem, 2.5vh, 1.75rem) 0 0;
	list-style: none;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--micro);
	letter-spacing: var(--wp--custom--tracking--wider);
	text-transform: uppercase;
	animation: menu-in 0.6s var(--dock-ease) both;
	animation-delay: calc(var(--i) * 45ms + 60ms);
}
.menu-more a { display: inline-block; padding-block: 0.6rem; color: var(--wp--preset--color--paper-dim); text-decoration: none; text-underline-offset: 0.35em; text-decoration-thickness: 1px; transition: color var(--dock-fast) var(--dock-ease); }
.menu-more a[aria-current] { color: var(--wp--preset--color--paper); text-decoration-line: underline; }
@media (hover: hover) and (pointer: fine) { .menu-more a:hover { color: var(--wp--preset--color--accent); } }

/* The accounts and the newsletter: under everything, centred; they enter last. */
.menu-letter { align-self: start; display: grid; justify-items: center; gap: 0.9rem; padding: clamp(1rem, 2.5vh, 2rem) 0 0; animation: menu-in 0.6s var(--dock-ease) both; animation-delay: calc(var(--i) * 45ms + 60ms); }
.menu-socials { display: flex; flex-wrap: wrap; justify-content: center; gap: 0 1.4rem; margin: 0; padding: 0; list-style: none; font-family: var(--wp--preset--font-family--mono); font-size: var(--wp--preset--font-size--micro); letter-spacing: var(--wp--custom--tracking--wider); text-transform: uppercase; }
.menu-socials a { display: inline-block; padding-block: 0.6rem; color: var(--wp--preset--color--paper-dim); text-decoration: none; transition: color var(--dock-fast) var(--dock-ease); }
@media (hover: hover) and (pointer: fine) { .menu-socials a:hover { color: var(--wp--preset--color--accent); } }
.menu-letter-box { display: grid; justify-items: center; gap: 0.7rem; }
.menu-letter-label { margin: 0; font-family: var(--wp--preset--font-family--mono); font-size: var(--wp--preset--font-size--micro); letter-spacing: var(--wp--custom--tracking--wider); text-transform: uppercase; color: var(--wp--preset--color--paper-faint); line-height: 1; }
.menu-letter-btn {
	display: inline-flex;
	align-items: center;
	height: var(--pill-h);
	padding: 0 1.25rem;
	border: var(--wp--custom--line);
	border-radius: 999px;
	color: var(--wp--preset--color--paper);
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--micro);
	letter-spacing: var(--wp--custom--tracking--wide);
	text-transform: uppercase;
	text-decoration: none;
	transition: background-color var(--dock-fast) var(--dock-ease), color var(--dock-fast) var(--dock-ease), border-color var(--dock-fast) var(--dock-ease);
}
@media (hover: hover) and (pointer: fine) {
	.menu-letter-btn:hover { background: var(--wp--preset--color--accent); color: var(--wp--preset--color--ink); border-color: var(--wp--preset--color--accent); }
}

/* While it is open: the wordmark stays on top (fixed, no ground), the grid's own
   furniture steps back. */
body.menu-open .tristopic-bar { position: fixed; inset: 0 0 auto; z-index: 66; background: none; backdrop-filter: none; -webkit-backdrop-filter: none; border-bottom-color: transparent; }
body.menu-open .tristopic-bar__clock { visibility: hidden; }

/* The page under the menu stays exactly where it is (iPhone and iPad drag a page
   that is only overflow:hidden): nav.js pins it at its own scroll offset. */
body.is-locked { position: fixed; left: 0; right: 0; width: 100%; overflow: hidden; padding-right: var(--sbw, 0px); }
html:has(> body.is-locked) { overscroll-behavior: none; }

/*
 * Phones: the same places with a hierarchy, one column. Work opens to the
 * disciplines; About and Let's talk are big rows; the work index and Privacy
 * small ones. Tablets and computers keep the big words and the row under them:
 * there the fold dissolves (display: contents) and the phone's rows are not shown.
 */
@media (min-width: 600px) {
	.menu-work, .menu-work > .menu-fold-panel, .menu-work .menu-fold-inner { display: contents; }
	.menu-fold-btn, .menu-phone { display: none; }
}
@media (max-width: 599px) {
	.menu { --menu-size: 1.25rem; }
	.menu-panel { padding-bottom: calc(var(--dock-h) + 0.75rem); scroll-padding: var(--menu-top) 0 calc(var(--dock-h) + 0.75rem); }
	.menu-main { align-self: start; display: block; }   /* top-aligned: a row that opens pushes down, nothing jumps */
	/* What scrolls fades out under the wordmark and above the dock; only over the panel's padding. */
	.menu::before, .menu::after { content: ""; position: absolute; left: 0; right: 0; z-index: 1; pointer-events: none; }
	.menu::before { top: 0; height: var(--menu-top); background: linear-gradient(var(--wp--preset--color--ink) calc(100% - var(--menu-shell)), transparent); }
	.menu::after { bottom: 0; height: calc(var(--dock-h) + 0.75rem); background: linear-gradient(transparent, var(--wp--preset--color--ink) 0.75rem); }
	.menu-more { display: none; }
	.menu-letter { padding-top: 1.5rem; }

	.menu-rows { margin: 0; padding: 0; list-style: none; }
	.menu-row { display: flex; align-items: center; gap: 0.5rem; width: 100%; min-height: 2.75rem; padding: 0; border: 0; border-top: var(--wp--custom--line); background: none; color: var(--wp--preset--color--paper); text-align: left; text-decoration: none; cursor: pointer; font: inherit; }
	.menu-row.is-big { min-height: 3.25rem; }
	.menu-rows-small > li:last-child > .menu-row { border-bottom: var(--wp--custom--line); }
	:is(.menu-work > .menu-fold-btn, .menu-rows > li) { animation: menu-in 0.6s var(--dock-ease) both; animation-delay: calc(var(--i) * 45ms + 60ms); }
	/* Phones: the title cut comes in to 108%, as on the project cards (thin wide letters on black go fragile). */
	.menu-row-word { font-size: clamp(1.375rem, 6.4vw, 1.75rem); font-weight: 700; font-stretch: 108%; line-height: 1; letter-spacing: -0.02em; text-underline-offset: 0.14em; text-decoration-thickness: 1px; }
	.menu-row-count { align-self: flex-start; margin-top: 0.95rem; font-family: var(--wp--preset--font-family--mono); font-size: var(--wp--preset--font-size--micro); letter-spacing: var(--wp--custom--tracking--wider); color: var(--wp--preset--color--paper-faint); line-height: 1; }   /* on the word's cap line, like a footnote */
	.menu-row-label { font-family: var(--wp--preset--font-family--mono); font-size: var(--wp--preset--font-size--micro); letter-spacing: var(--wp--custom--tracking--wider); text-transform: uppercase; color: var(--wp--preset--color--paper-dim); line-height: 1; }
	.menu-row[aria-current] :is(.menu-row-word, .menu-row-label) { text-decoration-line: underline; color: var(--wp--preset--color--paper); }
	.menu-arrow { flex: none; width: 16px; height: 16px; margin-left: auto; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: butt; stroke-linejoin: miter; }

	/* + turns into −: the upright bar lies down. */
	.menu-fold-mark { position: relative; flex: none; width: 14px; height: 14px; margin-left: auto; }
	.menu-fold-mark::before, .menu-fold-mark::after { content: ""; position: absolute; left: 0; top: 50%; width: 100%; height: 1.5px; margin-top: -0.75px; background: currentColor; transition: transform 0.4s var(--dock-ease); }
	.menu-fold-mark::after { transform: rotate(90deg); }
	.menu-fold.is-open > .menu-fold-btn .menu-fold-mark::after { transform: rotate(0deg); }

	.menu-fold-panel { display: grid; grid-template-rows: 0fr; visibility: hidden; transition: grid-template-rows 0.42s var(--dock-ease), visibility 0s linear 0.42s; }
	.menu-fold.is-open > .menu-fold-panel { grid-template-rows: 1fr; visibility: visible; transition: grid-template-rows 0.42s var(--dock-ease), visibility 0s; }
	.menu-fold-inner { min-height: 0; overflow: hidden; }
	.menu-fold.is-open .menu-list > li { animation: menu-fold-in 0.45s var(--dock-ease) both; animation-delay: calc(var(--i) * 28ms + 50ms); }

	/* The disciplines: number · name. */
	.menu-list { display: block; padding: 0.125rem 0 0.625rem; text-align: left; }
	.menu-list li, .menu-list li:last-child { border: 0; animation: none; }
	.menu-link { grid-template-columns: 2.25rem minmax(0, 1fr); align-items: center; justify-items: start; gap: 0; min-height: 2.625rem; padding: 0; }
	.menu-word { font-stretch: 108%; letter-spacing: -0.02em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
}
@keyframes menu-fold-in { from { opacity: 0; transform: translateY(-6px); } }

@media (prefers-reduced-motion: reduce) {
	.menu, .menu * { transition: none !important; animation: none !important; }
}

/* --------------------------------------------------------- the project card */

/*
 * The house store's pop-up, 1:1 in structure (nav.js builds it around chrome.js's
 * card): the work left, the words right, ONE spacing value (--card-pad: stage to
 * card edge = words to card edge = stage to words), the × outside the card at
 * --dock-edge from the screen's corner. TRISTOPIC's own scrim, card ground, radius,
 * type and motion stay as they are (sphere.css, main.css).
 */
.tristopic-overlay.is-card {
	z-index: 68;   /* over the top row (60), as the store's pop-up covers its logo; under the dock (70) */
	padding: calc(var(--pill-h) + 2 * var(--dock-edge)) clamp(0.5rem, 2.5vw, 2rem) calc(var(--dock-h) + var(--dock-edge));
	grid-template-rows: minmax(0, 1fr);
}
.is-card .tristopic-overlay__panel {
	width: min(1180px, 100%);
	padding: 0;
}
.is-card .tristopic-case {
	--card-pad: clamp(1rem, 2.2vw, 1.75rem);
	padding: var(--card-pad);
	gap: var(--card-pad);
}
.is-card .tristopic-case__cover { display: none; }   /* the stage shows it */

/* The close: a round button like the dock's, fixed to the screen's corner. */
.is-card .card-close {
	position: fixed;
	top: var(--dock-edge);
	right: var(--dock-edge);
	z-index: 3;
	display: grid;
	place-items: center;
	width: var(--pill-h);
	height: var(--pill-h);
	padding: 0;
	border: var(--wp--custom--line);
	border-radius: 999px;
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper);
	opacity: 0;
	transition: opacity var(--dock-base) var(--dock-ease), background-color var(--dock-fast) var(--dock-ease), color var(--dock-fast) var(--dock-ease), border-color var(--dock-fast) var(--dock-ease);
}
.is-card.is-open .card-close { opacity: 1; }
.is-card .card-close::after { content: ""; position: absolute; inset: -5px; }
.card-close-x { position: relative; width: 16px; height: 16px; }
.card-close-x i { position: absolute; left: 0; top: 7px; width: 16px; height: 2px; background: currentColor; }
.card-close-x i:first-child { transform: rotate(45deg); }
.card-close-x i:last-child { transform: rotate(-45deg); }
@media (hover: hover) and (pointer: fine) {
	.is-card .card-close:hover { background: var(--wp--preset--color--accent); color: var(--wp--preset--color--ink); border-color: var(--wp--preset--color--accent); }
}
.is-card .card-close:focus-visible { outline: none; color: var(--wp--preset--color--accent); border-color: var(--wp--preset--color--accent); }

/* The work: the stage (each picture whole, on the card's ink), its counter in the
   bottom-right corner, and five thumbnail slots under it, edge to edge. */
.card-media { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.card-stage {
	position: relative;
	aspect-ratio: 1;
	border-radius: 1rem;
	overflow: hidden;
	background: var(--wp--preset--color--ink);
	touch-action: pan-y;
	outline: none;
}
.card-media.has-many .card-stage { cursor: pointer; }
.card-media.has-none .card-stage { display: none; }
.card-stage:focus-visible { box-shadow: inset 0 0 0 2px var(--wp--preset--color--accent); }
.card-img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: contain;
	opacity: 0;
	transition: opacity 0.45s var(--dock-ease);
}
.card-img.is-on { opacity: 1; }
.card-count {
	position: absolute;
	z-index: 2;
	right: 0.9rem;
	bottom: 0.9rem;
	padding: 0.35rem 0.55rem;
	border-radius: 999px;
	background: rgb(from var(--wp--preset--color--ink) r g b / 0.72);
	color: var(--wp--preset--color--paper);
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--micro);
	letter-spacing: var(--wp--custom--tracking--wide);
	font-variant-numeric: tabular-nums;
	line-height: 1;
	pointer-events: none;
}
.card-count:empty { display: none; }
.card-thumbs {
	--thumb-gap: 0.625rem;
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: calc((100% - 4 * var(--thumb-gap)) / 5);   /* exactly five slots: the first on the stage's left edge, the fifth on its right */
	gap: var(--thumb-gap);
	margin-top: var(--thumb-gap);
	overflow-x: auto;
	scrollbar-width: none;
}
.card-thumbs::-webkit-scrollbar { display: none; }
.card-thumbs:empty { display: none; }
.card-thumb {
	aspect-ratio: 1;
	padding: 0;
	border: 1px solid transparent;
	border-radius: 0.5rem;
	background: var(--wp--preset--color--ink);
	overflow: hidden;
	cursor: pointer;
	transition: border-color var(--dock-fast) var(--dock-ease);
}
.card-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.card-thumb[aria-pressed="true"] { border-color: var(--wp--preset--color--paper); }
@media (hover: hover) and (pointer: fine) { .card-thumb:not([aria-pressed="true"]):hover { border-color: var(--wp--preset--color--accent); } }
.card-thumb:focus-visible { outline: none; border-color: var(--wp--preset--color--accent); }

/* The words. The facts become rows, the label left and the value on the right edge. */
.card-info { display: flex; flex-direction: column; gap: 1.25rem; min-width: 0; min-height: 0; }
.is-card .tristopic-case__head { display: block; }
.is-card .tristopic-case__spec { display: grid; grid-template-columns: minmax(0, 1fr); justify-content: stretch; gap: 0; padding: 0; border-bottom: 0; }   /* the flex rule's space-between would shrink the grid's track */
.is-card .tristopic-case__spec > div { display: grid; grid-template-columns: minmax(5.5rem, 32%) minmax(0, 1fr); align-items: baseline; gap: 1rem; padding-block: 0.8rem; border-bottom: var(--wp--custom--line); text-align: left; }
.is-card .tristopic-case__spec > div[hidden] { display: none; }
.is-card .tristopic-case__spec dd { margin: 0; text-align: right; }
/* The case study's text only: its pictures are on the stage. */
.is-card .tristopic-case__body :is(figure, .wp-block-gallery, .wp-block-image, .wp-block-video, .wp-block-embed, .wp-block-cover) { display: none; }
.is-card .tristopic-case__actions { margin: 0; }

/*
 * The card never changes size from 700px up: its height is fixed, the stage fills
 * the work's column, and the words' area takes what the facts leave, scrolling
 * inside (no bar) with soft fades where there is more. The text is always shown
 * there, so the [+] that hides it on a phone has no job and steps away.
 */
@media (min-width: 700px) {
	.is-card .tristopic-overlay__panel { height: min(100%, 52rem); overflow: clip; }   /* clip, not hidden: no scroll container, so nothing (a script, a focus jump) can shift the card; only the words' area scrolls */
	.is-card .tristopic-case { height: 100%; grid-template-columns: minmax(0, 1.12fr) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); }
	.card-stage { aspect-ratio: auto; flex: 1 1 0; min-height: 0; }
	.is-card .tristopic-case__toggle { display: none; }
	.is-card .tristopic-case__more {
		display: block;
		flex: 1 1 0;
		min-height: 5rem;
		overflow-y: auto;
		overscroll-behavior: contain;
		scrollbar-width: none;
		--fade-top: 0px;
		--fade-foot: 0px;
		-webkit-mask: linear-gradient(transparent, black var(--fade-top), black calc(100% - var(--fade-foot)), transparent);
		mask: linear-gradient(transparent, black var(--fade-top), black calc(100% - var(--fade-foot)), transparent);
	}
	.is-card .tristopic-case__more::-webkit-scrollbar { display: none; }
	.is-card .tristopic-case__more.has-less { --fade-top: 1.5rem; }
	.is-card .tristopic-case__more.has-more { --fade-foot: 3rem; }
	.is-card .tristopic-case__lead { font-size: var(--wp--preset--font-size--body); }
	.is-card .tristopic-case__title { font-size: clamp(2rem, 3.4vw, 3.5rem); }
}

/* Phones: one column that scrolls inside the card, between the close and the dock,
   so nothing in it ever runs under the dock's buttons. */
@media (max-width: 699px) {
	.tristopic-overlay.is-card { padding: calc(var(--pill-h) + 2 * var(--dock-edge)) var(--dock-edge) calc(var(--dock-h) + var(--dock-edge)); }
	.is-card .tristopic-overlay__panel { max-height: 100%; border-radius: 1rem; }
	.is-card .tristopic-case { grid-template-columns: minmax(0, 1fr); }
}

/* ------------------------------------------------------- the inner pages */

/*
 * The house store's page system (owner, 11 Nov: option A), in TRISTOPIC's own type:
 * every inner page is ONE centred column with ONE header. The title is the About
 * page's cut (.tristopic-frame__title: 700 at 116%, 108% on phones; by height on
 * large screens), centred, the same distance under the bar on every page. Policies
 * read from the column's left edge; statements (About, Let's talk, 404) are centred.
 * The archives keep their wide grid under the centred title. The project page and
 * the grid pages are not inner pages here.
 *
 *   page.html     main.tristopic-page        (Privacy and the default pages)
 *   404.html      body.error404 main
 *   index.html    body.archive main          (the /field/ and /industry/ archives)
 *   page-frame    main.tristopic-frame       (About, Let's talk)
 */
:root {
	--page-top: clamp(0.75rem, 2.2vw, 2rem);   /* bar to title, every inner page */
	--page-measure: 40rem;                      /* the one column */
}

/* Short pages: the colophon on the screen's bottom edge, so the dock stands there too.
   (The framed pages hold the screen with their own grid from 1100 x 768.) */
body.has-v2:not(.tristopic-sphere-page):not(.tristopic-framed) .wp-site-blocks { min-height: 100svh; display: flex; flex-direction: column; }
body.has-v2:not(.tristopic-sphere-page):not(.tristopic-framed) .wp-site-blocks > main { flex: 1 0 auto; }
body.has-v2.tristopic-framed:not(.tristopic-sphere-page) .wp-site-blocks { min-height: 100svh; }

/* One distance under the bar. (404 and the archives set theirs inline, hence !important.) */
body.has-v2 :is(main.tristopic-page, main.tristopic-frame),
body.has-v2.error404 .wp-site-blocks > main,
body.has-v2.archive:not(.tristopic-sphere-page) .wp-site-blocks > main { padding-top: var(--page-top) !important; }

/* One title: the About cut, centred. */
body.has-v2 :is(main.tristopic-page > h1, main.tristopic-frame .tristopic-frame__title),
body.has-v2.error404 .wp-site-blocks > main > h1,
body.has-v2.archive:not(.tristopic-sphere-page) .wp-site-blocks > main > h1 {
	max-width: var(--page-measure);
	margin: 0 auto !important;
	text-align: center;
	font-size: clamp(2.5rem, 7vw, 5.5rem);
	line-height: 0.94;
	letter-spacing: -0.035em;
	font-weight: 700;
	font-stretch: 116%;
	text-wrap: balance;
}
@media (max-width: 599px) {
	body.has-v2 :is(main.tristopic-page > h1, main.tristopic-frame .tristopic-frame__title),
	body.has-v2.error404 .wp-site-blocks > main > h1,
	body.has-v2.archive:not(.tristopic-sphere-page) .wp-site-blocks > main > h1 { font-stretch: 108%; letter-spacing: -0.02em; }
}
@media (min-width: 1100px) and (min-height: 768px) {
	body.has-v2 :is(main.tristopic-page > h1, main.tristopic-frame .tristopic-frame__title),
	body.has-v2.error404 .wp-site-blocks > main > h1,
	body.has-v2.archive:not(.tristopic-sphere-page) .wp-site-blocks > main > h1 { font-size: clamp(2.25rem, 5.5vh, 3.5rem); }
}

/* The header's line under the title (About's standing line) centred with it, at every size. */
body.has-v2 main.tristopic-frame .tristopic-frame__masthead { text-align: center; }
body.has-v2 main.tristopic-frame .tristopic-frame__meta { max-width: none; margin-inline: auto; }

/* One column. Policies read from its left edge; their first line (the date) is centred
   under the title, like the header it belongs to. */
body.has-v2 main.tristopic-page > .wp-block-spacer { height: var(--wp--preset--spacing--30) !important; }
body.has-v2 main.tristopic-page > .wp-block-post-content { max-width: var(--page-measure); margin-inline: auto !important; }
body.has-v2 main.tristopic-page > .wp-block-post-content > * { max-width: none; margin-inline: 0; }
body.has-v2 main.tristopic-page > .wp-block-post-content > p:first-child { text-align: center; }
/* Statements centre their text: the 404 line, and the framed pages below 1100px (above it they already do). */
body.has-v2.error404 .wp-site-blocks > main > p { max-width: var(--page-measure); margin-inline: auto !important; text-align: center; }
body.has-v2 main.tristopic-frame { text-align: center; }
/* The archives: a centred title, the grid as wide as before. */
body.has-v2.archive:not(.tristopic-sphere-page) .wp-site-blocks > main > .wp-block-spacer { height: var(--wp--preset--spacing--30) !important; }

@media (prefers-reduced-motion: reduce) {
	.dock, .dock *, .is-card .card-img, .is-card .card-close { transition: none !important; animation: none !important; }
}

/* Filtered out of the hidden HTML work list too (screen readers, no-WebGL). */
.tristopic-index__item[hidden] { display: none; }

/*
 * Touch screens (final check, 11 Nov). Small words keep their look, but get a tap
 * area of at least 24px, drawn by an invisible ::after (as the view toggle already
 * does). Text fields never go under 16px, or iOS zooms the page when one is tapped.
 */
@media (pointer: coarse) {
	body.has-v2 :is(.tristopic-bar__mark, .tristopic-case__back a, .tristopic-slider__step, .wp-block-post-terms a) { position: relative; }
	body.has-v2 :is(.tristopic-case__back a, .tristopic-slider__step, .wp-block-post-terms a)::after { content: ""; position: absolute; inset: -6px -8px; }
	body.has-v2 .tristopic-bar__mark::after { content: ""; position: absolute; inset: -12px -16px; }
	body.has-v2 :is(input:not([type="checkbox"], [type="radio"], [type="file"], [type="hidden"]), textarea, select) { font-size: max(16px, 1em); }
}

/*
 * Audit quick wins (11 Nov).
 *
 * The grid page: the top row (wordmark, clock) sat straight on the artwork and was
 * hard to read. A soft ink fade under it, between the grid and the chrome (z 55: over the canvas, under the bar 60,
 * the menu 65, the card 68 and the dock 70). No hit area: the grid still drags.
 */
body.has-v2.tristopic-sphere-page .wp-block-tristopic-work-sphere::before {
	content: "";
	position: fixed;
	left: 0;
	right: 0;
	z-index: 55;
	pointer-events: none;
}
body.has-v2.tristopic-sphere-page .wp-block-tristopic-work-sphere::before {
	top: 0;
	height: 3.5rem;
	background: linear-gradient(to bottom, color-mix(in srgb, var(--wp--preset--color--ink) 88%, transparent), transparent);
}

/* The upload hint says what the form takes; it was drawn in the hairline colour
   (1.4:1). paper-faint is the theme's quietest text colour that still reads (4.6:1). */
body.has-v2 .tristopic-commission__hint { color: var(--wp--preset--color--paper-faint); }

/* Phones: the footer stands 10px off the glass on every template. The pages had it
   (the theme's own 599px rule for has-global-padding); project and archive pages
   print the footer without that class, so their colophon touched the edge. */
@media (max-width: 599px) {
	body.has-v2 .tristopic-footer:not(.has-global-padding) { padding-inline: 0.625rem; }
}

/* Framed pages (About, Let's talk) below the frame's own screen-holding grid (from
   1100 x 768): like every other short page, the page fills the screen so the pinned
   footer line sits on the bottom edge instead of floating above an empty strip (up to
   300px on a tablet). The frame grows; its rows stay packed at the top. */
@media (max-width: 1099px), (max-height: 767px) {
	body.has-v2.tristopic-framed:not(.tristopic-sphere-page) .wp-site-blocks { display: flex; flex-direction: column; }
	body.has-v2.tristopic-framed:not(.tristopic-sphere-page) .wp-site-blocks > main { flex: 1 0 auto; align-content: start; }
}

/* About and Let's talk, polish (owner, 12-13 Nov: "polish as much as you can", then
   "more compact"). Below the frame's own screen-holding grid, the page had the
   desktop's 64px between title and body on a tablet and a flat 32px between every
   block; it now steps with the screen, the same way the framed grid already does
   above 1100 x 768. */
@media (max-width: 1099px), (max-height: 767px) {
	body.has-v2 main.tristopic-frame {
		--frame-step: clamp(0.85rem, 2.2vw, 1.25rem);
		gap: clamp(1rem, 3vw, 1.75rem);
	}
	body.has-v2 main.tristopic-frame .tristopic-frame__body .entry-content > * + * { margin-top: var(--frame-step); }
}

/* Compact: a new section (a run-in label, or a label on its own line before a list)
   gets half a step more than the lines inside one; the way on gets the same. */
body.has-v2 main.tristopic-frame .entry-content > :is(.tristopic-eyebrow, .has-runin, .tristopic-cta) { margin-top: calc(var(--frame-step) * 1.5); }
body.has-v2 main.tristopic-frame .entry-content > .tristopic-eyebrow + * { margin-top: calc(var(--frame-step) * 0.4); }

/* Tighter leading: the lead is display-sized and does not need body leading. */
body.has-v2 main.tristopic-frame .entry-content > .has-lead-font-size { line-height: 1.3; }
body.has-v2 main.tristopic-frame .entry-content > p:not(.has-lead-font-size):not(.tristopic-band) { line-height: 1.5; }

/* Centred lines kept short enough for the eye to find the next one: the lead at about
   50 characters, body copy at about 65. */
body.has-v2 main.tristopic-frame .entry-content > .has-lead-font-size { max-width: 44ch; margin-inline: auto; }
body.has-v2 main.tristopic-frame .entry-content > p:not(.tristopic-band):not(.has-lead-font-size):not(.tristopic-cta) { max-width: 54ch; margin-inline: auto; }

/* Line breaks that read: short centred lines balanced, prose never ending on one word. */
body.has-v2 main.tristopic-frame :is(.tristopic-frame__title, .tristopic-frame__meta, .tristopic-eyebrow, .has-small-font-size) { text-wrap: balance; }
body.has-v2 main.tristopic-frame .entry-content > p:not(.tristopic-band) { text-wrap: pretty; }

/* Let's talk: the band's lower hairline already opens the sheet; a second rule 8px under
   it read as a printing fault. */
body.has-v2 .tristopic-commission__process + .tristopic-commission__form .tristopic-commission__sheet { border-top: 0; }

/* The two bands sit at the same height, so the hairlines hold still when the dock moves
   between About and Let's talk. WordPress zeroes a page's first block margin; the form's
   band is one level down and kept its own 13px. */
body.has-v2 .tristopic-commission > .tristopic-commission__process:first-child { margin-top: 0; }

/* The service picker's arrow: a thin chevron like the dock's, not the browser's solid
   triangle (Chrome's customisable select; other browsers already draw the CSS caret). */
@supports (appearance: base-select) {
	body.has-v2 .tristopic-field__control select::picker-icon {
		content: "";
		width: 0.42rem;
		height: 0.42rem;
		margin-right: 0.4rem;
		border-right: 1.5px solid currentColor;
		border-bottom: 1.5px solid currentColor;
		transform: translateY(-30%) rotate(45deg);
	}
	body.has-v2 .tristopic-field__control select:open::picker-icon { transform: translateY(20%) rotate(225deg); }
}

/* The "sent" and "something was missing" notes sit on the form's own column, the same
   40rem as the sheet under them, instead of hanging off the page's left edge. */
body.has-v2 .tristopic-commission__notice {
	box-sizing: border-box;
	width: 100%;
	max-width: 40rem;
	margin-inline: auto;
	text-align: left;
	text-wrap: pretty;
}

/* No underlines on link texts (owner, 13 Nov): the wordmark, the legal row, the menu.
   The page you are on keeps its brighter colour; long-form text keeps its underlines,
   so a link inside a sentence can still be told from the words around it. */
body.has-v2 .tristopic-bar a:is(:hover, [aria-current]),
body.has-v2 .dock-links a[aria-current],
body.has-v2 .menu-link[aria-current] .menu-word,
body.has-v2 .menu-more a[aria-current],
body.has-v2 .menu-row[aria-current] :is(.menu-row-word, .menu-row-label) { text-decoration-line: none; }
