/*
 * HandiSoft Solution: the editorial look.
 *
 * A near-black hero with a moving dot field, serif headlines with one italic
 * phrase, pill buttons, numbered service rows, and the company name set as
 * text in place of the logo. On every page: see hs_is_editorial() in
 * functions.php.
 *
 * Loaded after main.css. Every rule is scoped to the .theme-editorial body
 * class. Section 1 gives the main.css tokens new values, which carries most of
 * the change; the sections after it cover what tokens cannot.
 *
 * 1. Tokens     2. Type        3. Buttons and links   4. Header
 * 5. Hero       6. Facts       7. Services            8. Dark band
 * 9. Clients    10. Closing call to action and footer
 * 11. Inner pages (service pages, About, Our Work, case studies, Contact,
 *     long-form pages)                                 12. Motion
 */

/* 0. Fonts: Instrument Serif for headlines and Source Sans Pro for text,
   self-hosted like the others (assets/fonts/README.md). */

@font-face {
	font-family: "Source Sans Pro";
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("../fonts/source-sans-pro-latin-400-normal.woff2") format("woff2");
}

@font-face {
	font-family: "Source Sans Pro";
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url("../fonts/source-sans-pro-latin-600-normal.woff2") format("woff2");
}

@font-face {
	font-family: "Instrument Serif";
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("../fonts/instrument-serif-latin-400-normal.woff2") format("woff2");
}

@font-face {
	font-family: "Instrument Serif";
	font-style: italic;
	font-weight: 400;
	font-display: swap;
	src: url("../fonts/instrument-serif-latin-400-italic.woff2") format("woff2");
}

/* 1. Tokens --------------------------------------------------------------- */

.theme-editorial {
	/* "Navy" becomes ink: the dark bands and the headings on light. */
	--color-navy: #0B1017;
	--color-navy-pressed: #1C242E;
	--color-navy-raised: #141A22;
	--color-navy-line: #27313C;

	/* A white page. */
	--color-ink: #1B2026;
	--color-muted: #56616D;
	--color-border: #E2E5E9;
	--color-bg: #FFFFFF;
	--color-on-navy-muted: #A3AEBA;

	/* New in this file. Paper is the off-white of buttons on dark bands. */
	--color-paper: #F4F2ED;
	--color-rule: #CDD2D8;
	--color-wash: #F4F6F8;
	--color-soft: #7C848D;
	--color-on-navy-soft: #75808C;

	--font-heading: "Instrument Serif", "Iowan Old Style", Georgia, "Times New Roman", serif;
	--font-body: "Source Sans Pro", Roboto, sans-serif;
	/* Source Sans Pro runs smaller than Inter at the same size. */
	--text-body: 1.125rem;
	--text-lead: 1.25rem;
	--text-small: 0.9375rem;
	--text-eyebrow: 0.8125rem;
	--text-h1: clamp(2.625rem, 1.2rem + 6.2vw, 5.75rem);
	--text-h2: clamp(2.25rem, 1.4rem + 3.6vw, 4rem);
	--text-h3: 1.75rem;
	--leading-h1: 1;
	--leading-h2: 1.04;
	--leading-h3: 1.15;
	--tracking-heading: -0.015em;

	/* Slow, soft easing for everything that enters or reacts. */
	--ease-soft: cubic-bezier(0.16, 1, 0.3, 1);
	--motion-reveal: 900ms;
}

@media (min-width: 48rem) {
	.theme-editorial {
		--text-body: 1.1875rem;
		--text-lead: 1.375rem;
		--text-small: 1rem;
	}
}

/* The Scroll link and the menu's in-page links glide. Switched off with
   reduced motion by the rule in main.css. */
html:has(.theme-editorial) {
	scroll-behavior: smooth;
}

/* 2. Type ----------------------------------------------------------------- */

/* The serif has one weight. Asking for bold would make the browser fake it. */
.theme-editorial h1,
.theme-editorial h2,
.theme-editorial h3,
.theme-editorial .h3 {
	font-weight: 400;
	letter-spacing: var(--tracking-heading);
}

.theme-editorial h1 em,
.theme-editorial h2 em {
	font-style: italic;
}

.theme-editorial .heading-soft {
	color: var(--color-soft);
}

.theme-editorial .section > .container > h2:not(.eyebrow) {
	max-width: 14em;
	margin-bottom: var(--space-7);
}

/* 3. Buttons and links ---------------------------------------------------- */

.theme-editorial .button {
	padding-inline: 1.75rem;
	border-radius: var(--radius-pill);
	font-size: 1.0625rem;
	font-weight: 600;
	transition: background-color 400ms var(--ease-soft), border-color 400ms var(--ease-soft), color 400ms var(--ease-soft), transform 400ms var(--ease-soft);
}

.theme-editorial .site-header__cta,
.theme-editorial .cookie-notice .button {
	font-size: 0.9375rem;
}

/* The main button on a dark band carries an arrow that moves on hover. */
.theme-editorial .on-navy .button--primary::after {
	content: "\2192";
	content: "\2192" / "";
	margin-left: 0.6em;
	transition: transform 400ms var(--ease-soft);
}

.theme-editorial .on-navy .button--primary:hover::after {
	transform: translateX(5px);
}

.theme-editorial .button--primary {
	background: var(--color-navy);
}

.theme-editorial .button--primary:hover {
	background: var(--color-teal);
}

.theme-editorial .button--primary:active {
	background: var(--color-teal-active);
}

.theme-editorial .on-navy .button--primary,
.theme-editorial .on-navy .button--primary:active {
	background: var(--color-paper);
	color: var(--color-navy);
}

.theme-editorial .on-navy .button--primary:hover {
	background: var(--color-mint);
	color: var(--color-navy);
}

.theme-editorial .on-navy .button--secondary {
	border-color: rgba(255, 255, 255, 0.45);
}

.theme-editorial .on-navy .button--secondary:hover {
	border-color: var(--color-paper);
	background: var(--color-paper);
}

.theme-editorial .text-link {
	text-decoration: none;
}

.theme-editorial .text-link::after {
	content: "\2192";
	content: "\2192" / "";
	margin-left: 0.5em;
	transition: transform var(--motion-base) var(--ease-out);
}

.theme-editorial .text-link:hover::after {
	transform: translateX(4px);
}

/* 4. Header --------------------------------------------------------------- */

.theme-editorial .site-header {
	background: rgba(255, 255, 255, 0.9);
	-webkit-backdrop-filter: blur(12px);
	backdrop-filter: blur(12px);
}

.js .theme-editorial.has-hero .site-header.is-over-hero {
	border-bottom-color: transparent;
	background: transparent;
	-webkit-backdrop-filter: none;
	backdrop-filter: none;
}

.theme-editorial .site-logo {
	transition: color var(--motion-base) var(--ease-out);
}

.js .theme-editorial .is-over-hero .site-logo {
	color: var(--color-surface);
}

.site-logo__wordmark {
	font-size: 1.3125rem;
	font-weight: 400;
	line-height: 1;
	letter-spacing: -0.01em;
	white-space: nowrap;
}

.theme-editorial .site-nav__link {
	font-weight: 400;
}

@media (min-width: 64rem) {
	.theme-editorial .site-nav__link {
		font-size: 1.0625rem;
	}
}

.theme-editorial .site-header__cta {
	background: var(--color-navy);
}

.theme-editorial .site-header__cta:hover {
	background: var(--color-teal);
}

.js .theme-editorial .is-over-hero .site-header__cta {
	background: var(--color-paper);
	color: var(--color-navy);
}

.js .theme-editorial .is-over-hero .site-header__cta:hover {
	background: var(--color-mint);
	color: var(--color-navy);
}

@media (max-width: 22.5rem) {
	.theme-editorial .site-header__cta {
		padding-inline: var(--space-3);
	}
}

@media (min-width: 48rem) {
	.site-logo__wordmark {
		font-size: 1.625rem;
	}
}

/* 5. Hero ----------------------------------------------------------------- */

/* Every hero, back to front: ink, two slow drifting lights, the dot field, the
   words. The lights are the whole background when the dot field is not drawn. */
.theme-editorial .hero {
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	min-height: min(74svh, 46rem);
	background: var(--color-navy);
	isolation: isolate;
	view-timeline: --hero block;
}

/* Home fills the first screen: the words sit in the middle, the place line at
   the foot. */
.theme-editorial .hero--home {
	justify-content: flex-start;
	min-height: 100vh;
	min-height: 100svh;
	padding-bottom: var(--space-4);
}

.theme-editorial .hero::before,
.theme-editorial .hero::after {
	content: "";
	position: absolute;
	z-index: -1;
	border-radius: 50%;
	filter: blur(90px);
	pointer-events: none;
}

/* Mint, low on the right, where the dot field is densest. */
.theme-editorial .hero::before {
	top: auto;
	right: -12%;
	bottom: -28%;
	width: 62%;
	height: 70%;
	background: radial-gradient(closest-side, rgba(94, 234, 212, 0.3), rgba(15, 118, 110, 0.14) 55%, transparent);
}

/* A cooler light behind the headline, top left. */
.theme-editorial .hero::after {
	top: -22%;
	left: -14%;
	width: 55%;
	height: 62%;
	background: radial-gradient(closest-side, rgba(96, 130, 255, 0.16), transparent);
}

/* The mask keeps the dots clear of the words: they gather low on a phone and
   to the right on a wide screen. */
.hero__field {
	position: absolute;
	inset: 0;
	z-index: -1;
	width: 100%;
	height: 100%;
	max-width: none;
	opacity: 0;
	pointer-events: none;
	transition: opacity 1800ms var(--ease-out);
	-webkit-mask-image: linear-gradient(to bottom, transparent 35%, #000 95%);
	mask-image: linear-gradient(to bottom, transparent 35%, #000 95%);
}

.hero__field.is-live {
	opacity: 0.6;
}

.hero__inner {
	margin-block: auto;
	padding-block: var(--space-6);
}

.theme-editorial .hero--home .eyebrow {
	margin-bottom: var(--space-5);
}

.theme-editorial .hero--home h1 {
	max-width: 13em;
	margin-bottom: var(--space-5);
}

/* Each word sits in a window and rises into it. The window is wider than the
   word so the italic's overhang and the descenders are not cut off. */
.word {
	display: inline-block;
	clip-path: inset(-0.12em -0.3em -0.24em -0.12em);
}

.word > span {
	display: inline-block;
}

.theme-editorial .hero .lead {
	max-width: 36rem;
}

.theme-editorial .hero h1 {
	max-width: 13em;
}

.theme-editorial .hero .eyebrow {
	margin-bottom: var(--space-5);
}

/* The trail back, small and quiet above the headline. */
.theme-editorial .hero .breadcrumb {
	margin-bottom: var(--space-6);
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: var(--tracking-eyebrow);
	text-transform: uppercase;
}

.theme-editorial .hero .breadcrumb a {
	text-decoration: none;
}

.theme-editorial .hero .breadcrumb a:hover {
	color: var(--color-mint);
}

.theme-editorial .hero .breadcrumb [aria-current] {
	color: var(--color-surface);
}

.hero__foot {
	display: flex;
	align-items: center;
	min-height: 2.75rem;
	color: var(--color-on-navy-muted);
	font-size: 0.8125rem;
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: var(--tracking-eyebrow);
	text-transform: uppercase;
}

.hero__foot p {
	margin: 0;
}

/* Centred, so it never sits under the floating WhatsApp button. */
.hero__scroll {
	display: none;
}

@media (min-width: 48rem) {
	.hero__field {
		-webkit-mask-image: linear-gradient(100deg, transparent 14%, #000 66%);
		mask-image: linear-gradient(100deg, transparent 14%, #000 66%);
	}

	.hero__field.is-live {
		opacity: 1;
	}

	.theme-editorial .hero--home {
		padding-bottom: var(--space-5);
	}

	.theme-editorial .hero:not(.hero--home) {
		padding-bottom: var(--space-8);
	}

	.hero__scroll {
		position: absolute;
		left: 50%;
		display: inline-flex;
		align-items: center;
		gap: var(--space-3);
		min-height: 2.75rem;
		color: inherit;
		text-decoration: none;
		transform: translateX(-50%);
		transition: color 400ms var(--ease-soft);
	}

	.hero__scroll:hover {
		color: var(--color-mint);
	}

	.hero__scroll::after {
		content: "";
		width: 1px;
		height: 1.75rem;
		background: currentColor;
		transform-origin: top;
		animation: scroll-hint 2400ms var(--ease-in-out) infinite;
	}
}

/* 6. Facts ---------------------------------------------------------------- */

/* Four facts in one box, split into cells. On a pointer device the cell under
   the pointer turns to ink. The GMT+8 clock shows the time there. */
.theme-editorial .facts-band {
	padding-block: var(--space-7) 0;
}

.facts-row {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	margin: 0;
	padding: 0;
	overflow: hidden;
	border: 1px solid var(--color-border);
	border-radius: 24px;
	background: var(--color-surface);
	box-shadow: 0 40px 70px -50px rgba(11, 16, 23, 0.35);
	list-style: none;
}

/* Each cell takes its colours from these five, so a cell can change sides. */
.facts-row li {
	--cell: var(--color-surface);
	--cell-text: var(--color-muted);
	--cell-figure: var(--color-navy);
	--cell-tile: var(--color-teal-tint);
	--cell-icon: var(--color-teal);
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	padding: var(--space-5) var(--space-4);
	background-color: var(--cell);
	color: var(--cell-text);
	font-size: var(--text-small);
	line-height: 1.5;
}

/* White, ink, white, ink. */
.facts-row li:nth-child(even) {
	--cell: var(--color-navy);
	--cell-text: var(--color-on-navy-muted);
	--cell-figure: var(--color-surface);
	--cell-tile: rgba(94, 234, 212, 0.14);
	--cell-icon: var(--color-mint);
}

.facts-row li:nth-child(even) {
	border-left: 1px solid var(--color-border);
}

.facts-row li:nth-child(n+3) {
	border-top: 1px solid var(--color-border);
}

.facts-row .icon {
	width: 3rem;
	height: 3rem;
	margin-bottom: var(--space-5);
	padding: 0.75rem;
	border-radius: 14px;
	background-color: var(--cell-tile);
	color: var(--cell-icon);
}

.facts-row__figure {
	color: var(--cell-figure);
	font-family: var(--font-heading);
	font-size: clamp(2rem, 1.2rem + 2.6vw, 3.375rem);
	font-weight: 400;
	line-height: 1;
	letter-spacing: var(--tracking-heading);
}

@media (min-width: 48rem) {
	.facts-row li {
		padding: var(--space-6);
	}
}

@media (min-width: 64rem) {
	.theme-editorial .facts-band {
		padding-top: var(--space-8);
	}

	.facts-row {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}

	.facts-row li {
		padding: var(--space-6) var(--space-5) var(--space-7);
		container-type: inline-size;
	}

	/* Sized from the cell, so the longest figure still fits on one line. */
	.facts-row__figure {
		font-size: clamp(1.75rem, 17cqi, 3.5rem);
	}

	.facts-row li:nth-child(n) {
		border-top: 0;
	}

	.facts-row li + li {
		border-left: 1px solid var(--color-border);
	}
}

/* 7. Services -------------------------------------------------------------- */

/* The five services as large rows: icon, name, what it is and what it costs,
   and a round arrow. The whole row is the link. On a pointer device the row
   under the pointer fills with ink from the bottom.

   A row takes its colours from the six properties below, so the filled state
   only has to change those. Its two backgrounds are the ink fill (first) and
   the rule along its top (second). */
.theme-editorial .service-grid {
	display: block;
}

.theme-editorial .service-grid > .hairline {
	--row-title: var(--color-navy);
	--row-text: var(--color-muted);
	--row-tile: var(--color-teal-tint);
	--row-icon: var(--color-teal);
	--row-edge: var(--color-rule);
	--row-arrow: var(--color-navy);
	position: relative;
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	padding: var(--space-6) var(--space-4);
	border-radius: 20px;
	background:
		linear-gradient(var(--color-navy), var(--color-navy)) 50% 100% / 100% 0 no-repeat,
		linear-gradient(var(--color-rule), var(--color-rule)) 0 0 / 100% 1px no-repeat;
}

.theme-editorial .service-grid .icon {
	width: 3.25rem;
	height: 3.25rem;
	margin-bottom: var(--space-5);
	padding: 0.8rem;
	border-radius: 16px;
	background-color: var(--row-tile);
	color: var(--row-icon);
}

.theme-editorial .service-grid :is(h3, .h3) {
	margin-bottom: var(--space-3);
	color: var(--row-title);
	font-size: clamp(2rem, 1.3rem + 2.6vw, 3.25rem);
	line-height: 1.02;
}

.theme-editorial .service-grid p {
	max-width: 34rem;
	margin-bottom: var(--space-4);
	color: var(--row-text);
}

/* The price, as a small outlined label. */
.theme-editorial .service-grid .price {
	justify-self: start;
	padding: 0.3rem 0.9rem;
	border: 1px solid var(--row-edge);
	/* A pill on one line, and still tidy when a long price wraps to two. */
	border-radius: 1rem;
	color: var(--row-title);
	font-size: var(--text-small);
	font-weight: 400;
}

.theme-editorial .service-grid .text-link {
	justify-self: start;
	color: var(--row-arrow);
}

/* The link covers its row. */
.theme-editorial .service-grid .text-link::before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
}

.theme-editorial .service-grid > .hairline:has(.text-link:focus-visible) {
	outline: var(--focus-ring);
	outline-offset: var(--focus-offset);
}

.theme-editorial .service-grid .text-link:focus-visible {
	outline: none;
}

@media (min-width: 64rem) {
	.theme-editorial .service-grid > .hairline {
		grid-template-columns: 3.25rem minmax(0, 5fr) minmax(0, 6fr) 3.75rem;
		column-gap: var(--space-6);
		align-items: center;
		padding: var(--space-7) var(--space-6);
	}

	.theme-editorial .service-grid .icon {
		grid-area: 1 / 1 / span 2;
		margin-bottom: 0;
	}

	.theme-editorial .service-grid :is(h3, .h3) {
		grid-area: 1 / 2 / span 2;
		margin-bottom: 0;
	}

	.theme-editorial .service-grid p {
		grid-column: 3;
		margin-bottom: var(--space-3);
	}

	.theme-editorial .service-grid .price {
		margin-bottom: 0;
	}

	/* The words "Learn more" stay for screen readers; the eye gets the arrow. */
	.theme-editorial .service-grid .text-link {
		grid-area: 1 / 4 / span 2;
		justify-content: center;
		justify-self: end;
		width: 3.75rem;
		height: 3.75rem;
		border: 1px solid var(--row-edge);
		border-radius: 50%;
		font-size: 0;
	}

	.theme-editorial .service-grid .text-link::after {
		margin: 0;
		font-size: 1.375rem;
	}
}

/* 8. Dark band ("Why companies choose us") -------------------------------- */

.section--ink {
	background: var(--color-navy-raised);
	color: var(--color-on-navy-muted);
}

.section--ink h2,
.section--ink h3 {
	color: var(--color-surface);
}

.theme-editorial .section--ink .heading-soft {
	color: var(--color-on-navy-soft);
}

.section--ink .hairline {
	--line: var(--color-navy-line);
}

.section--ink .icon {
	color: var(--color-mint);
}

.section--ink .hairline p {
	max-width: 34rem;
}

@media (min-width: 64rem) {
	.section--ink .grid--2 {
		gap: var(--space-8) var(--space-9);
	}
}

/* Featured work, when case studies are published, sits one step lighter than
   the hero. */
.theme-editorial .showcase {
	background: var(--color-navy-raised);
}

.theme-editorial .showcase .card > .shot {
	background: var(--color-navy-pressed);
}

/* 8A. Completed work (Home) -------------------------------------------------
 *
 * A dark band. Above: the heading and the projects as a row of names. Below:
 * the chosen project, its words on the left and three overlapping screenshots
 * on the right, each with a small label.
 *
 * The names are labels of radio buttons. :has() shows the spread that belongs
 * to the ticked one. Where :has() is not supported the names are hidden and
 * every spread is shown, one under another.
 */
.work-show {
	background: var(--color-navy-raised);
	color: var(--color-on-navy-muted);
	overflow: hidden;
}

.work-show h2,
.work-show h3 {
	color: var(--color-surface);
}

.work-show__head p {
	max-width: 34rem;
	font-size: var(--text-lead);
	line-height: 1.55;
}

.theme-editorial .work-show .heading-soft {
	color: var(--color-on-navy-soft);
}

.work-show__tabs {
	display: none;
	min-width: 0;
	margin: var(--space-7) 0 0;
	padding: 0;
	border: 0;
	border-bottom: 1px solid var(--color-navy-line);
}

.work-show__radio {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
}

.work-show__tabs label {
	flex: none;
	margin-bottom: -1px;
	padding: var(--space-3) 0 var(--space-4);
	border-bottom: 2px solid transparent;
	color: var(--color-on-navy-soft);
	font-family: var(--font-heading);
	font-size: clamp(1.375rem, 1.1rem + 1vw, 1.875rem);
	line-height: 1.1;
	letter-spacing: var(--tracking-heading);
	white-space: nowrap;
	cursor: pointer;
	transition: color 400ms var(--ease-soft), border-color 400ms var(--ease-soft);
}

.work-show__tabs label:hover {
	color: var(--color-surface);
}

.work-show__radio:checked + label {
	border-bottom-color: var(--color-mint);
	color: var(--color-surface);
}

.work-show__radio:focus-visible + label {
	outline: 3px solid var(--color-mint);
	outline-offset: 4px;
}

.work-spread {
	display: grid;
	gap: var(--space-6);
	margin-top: var(--space-7);
}

.work-spread h3 {
	margin-bottom: var(--space-2);
	font-size: clamp(2.25rem, 1.5rem + 3vw, 3.75rem);
	line-height: 1;
}

.work-spread__meta {
	margin-bottom: var(--space-5);
	color: var(--color-mint);
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: var(--tracking-eyebrow);
	text-transform: uppercase;
}

.work-spread__text > p:not([class]) {
	max-width: 30rem;
	font-size: var(--text-lead);
	line-height: 1.5;
}

.theme-editorial .work-show .tag {
	border-color: var(--color-navy-line);
	color: var(--color-on-navy-muted);
}

.work-spread__links {
	display: flex;
	flex-wrap: wrap;
	gap: 0 var(--space-6);
	margin: var(--space-5) 0 0;
}

/* Three screenshots, overlapping: the card image, one more page, and a phone. */
.work-spread__shots {
	position: relative;
	aspect-ratio: 16 / 11.4;
}

.work-shot {
	position: absolute;
	margin: 0;
	overflow: hidden;
	border: 1px solid rgba(255, 255, 255, 0.1);
	border-radius: 12px;
	background: var(--color-navy-pressed);
	box-shadow: 0 40px 80px -30px rgba(0, 0, 0, 0.75);
}

.work-shot img,
.work-shot .shot__placeholder {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: top;
}

.work-shot--main {
	top: 11%;
	left: 0;
	width: 72%;
	aspect-ratio: 16 / 10;
}

.work-shot--side {
	top: 0;
	right: 0;
	z-index: 1;
	width: 42%;
	aspect-ratio: 16 / 10;
}

.work-shot--phone {
	right: 7%;
	bottom: 0;
	z-index: 2;
	width: 19%;
	aspect-ratio: 780 / 1560;
	border-radius: 16px;
}

/* A project with one picture only: it takes the whole space. */
.work-shot--main:only-child {
	top: 0;
	width: 100%;
	height: 100%;
	aspect-ratio: auto;
	background: var(--color-surface);
}

.work-shot figcaption:not(.screen-reader-text) {
	position: absolute;
	bottom: 0.75rem;
	left: 0.75rem;
	max-width: calc(100% - 1.5rem);
	padding: 0.4rem 0.7rem;
	background: rgba(11, 16, 23, 0.86);
	color: var(--color-surface);
	font-size: 0.6875rem;
	font-weight: 600;
	line-height: 1.2;
	letter-spacing: var(--tracking-eyebrow);
	text-transform: uppercase;
}

/* On a phone the second picture is too small to carry a label over it. */
@media (max-width: 47.98rem) {
	.work-shot--side figcaption:not(.screen-reader-text) {
		width: 1px;
		height: 1px;
		padding: 0;
		overflow: hidden;
		clip-path: inset(50%);
	}
}

.work-show__all {
	margin-top: var(--space-7);
}

@supports selector(:has(a)) {
	.work-show__tabs {
		display: flex;
		gap: var(--space-6);
		overflow-x: auto;
		scrollbar-width: none;
	}

	.work-spread {
		display: none;
	}

	.work-show:has(#work-show-1:checked) .work-spread:nth-of-type(1),
	.work-show:has(#work-show-2:checked) .work-spread:nth-of-type(2),
	.work-show:has(#work-show-3:checked) .work-spread:nth-of-type(3),
	.work-show:has(#work-show-4:checked) .work-spread:nth-of-type(4) {
		display: grid;
	}
}

@media (min-width: 64rem) {
	.work-show__tabs {
		gap: var(--space-7);
	}

	.work-spread {
		grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
		gap: var(--space-8);
		align-items: center;
		margin-top: var(--space-8);
	}

	.work-shot figcaption:not(.screen-reader-text) {
		bottom: 1rem;
		left: 1rem;
		font-size: 0.75rem;
	}
}

/* 9. Clients -------------------------------------------------------------- */

/* The client names as one line that moves slowly from right to left and never
   ends, and stops under the pointer. The two sets of names are the same
   width, so moving the pair by one set (and one gap) lands exactly where it
   started. */
.clients-band {
	padding-block: var(--section-padding);
	overflow: hidden;
	border-top: 1px solid var(--color-border);
}

.clients-band h2 {
	margin-bottom: var(--space-7);
	text-align: center;
}

.marquee {
	--marquee-gap: clamp(3rem, 7vw, 6rem);
	display: flex;
	gap: var(--marquee-gap);
	overflow: hidden;
	-webkit-mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent);
	mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent);
}

.marquee__group {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: space-around;
	gap: var(--marquee-gap);
	min-width: 100%;
	margin: 0;
	padding: 0;
	list-style: none;
}

.marquee__group li {
	color: var(--color-soft);
	font-family: var(--font-heading);
	font-size: clamp(2rem, 1.6rem + 1.8vw, 2.75rem);
	line-height: 1.2;
	letter-spacing: var(--tracking-heading);
	white-space: nowrap;
	transition: color 500ms var(--ease-soft);
}

.marquee__group li:hover {
	color: var(--color-navy);
}

/* 10. Closing call to action and footer ----------------------------------- */

/* Full width and joined to the footer, in place of the inset panel. */
.theme-editorial .closing-cta {
	padding: 0;
	background: var(--color-navy);
}

.theme-editorial .closing-cta__panel {
	max-width: none;
	padding: 5rem var(--page-margin);
	border-radius: 0;
	background: radial-gradient(70% 90% at 50% 110%, rgba(94, 234, 212, 0.1), transparent 70%);
}

.theme-editorial .closing-cta h2 {
	font-size: clamp(2.5rem, 1.3rem + 5vw, 5rem);
	line-height: 1;
}

.theme-editorial .closing-cta p {
	max-width: 34rem;
}

.theme-editorial .site-footer {
	border-top: 1px solid var(--color-navy-line);
}

.site-footer__wordmark {
	margin-bottom: var(--space-4);
	color: var(--color-surface);
	font-family: var(--font-heading);
	font-size: 2rem;
	line-height: 1;
	letter-spacing: -0.01em;
}

@media (min-width: 48rem) {
	.theme-editorial .closing-cta__panel {
		padding-block: 8rem;
	}
}

/* The cookie notice: on a wide screen a slim dark bar along the foot, so it
   does not cover the hero buttons at the bottom left. */
.theme-editorial .cookie-notice {
	border-color: var(--color-navy-line);
	background: var(--color-navy-raised);
	color: var(--color-on-navy-muted);
}

.theme-editorial .cookie-notice a {
	color: var(--color-mint);
}

.theme-editorial .cookie-notice .button--secondary {
	border-color: rgba(255, 255, 255, 0.45);
	color: var(--color-surface);
}

.theme-editorial .cookie-notice .button--secondary:hover {
	border-color: var(--color-paper);
	background: var(--color-paper);
	color: var(--color-navy);
}

.theme-editorial .cookie-notice :focus-visible {
	outline-color: var(--color-mint);
}

@media (min-width: 64rem) {
	.theme-editorial .cookie-notice {
		right: 6.5rem;
		left: var(--space-5);
		display: flex;
		align-items: center;
		gap: var(--space-5);
		width: auto;
		max-width: 52rem;
		padding: var(--space-3) var(--space-3) var(--space-3) var(--space-5);
		border-radius: var(--radius-pill);
	}

	.theme-editorial .cookie-notice[hidden] {
		display: none;
	}

	.theme-editorial .cookie-notice p {
		margin: 0;
	}

	.theme-editorial .cookie-notice__buttons {
		flex: none;
	}

	.theme-editorial .cookie-notice .button {
		min-height: 2.75rem;
		padding-inline: var(--space-5);
		font-size: 0.875rem;
	}
}

/* 11. Inner pages ----------------------------------------------------------- */

/* Alternate bands are a pale wash, with no rules above and below. */
.theme-editorial .section--alt {
	border-block: 0;
	background: var(--color-wash);
}

/* A heading with its text beside it on a wide screen: the short text sections
   of a service page, the questions, and the story on About. */
@media (min-width: 64rem) {
	.theme-editorial .reading:not(.prose) {
		display: grid;
		grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
		column-gap: var(--space-8);
		max-width: none;
	}

	.theme-editorial .reading:not(.prose) > h2 {
		grid-column: 1;
		grid-row: 1 / span 12;
	}

	.theme-editorial .reading:not(.prose) > :not(h2) {
		grid-column: 2;
	}

	/* In a hero there is nothing to set beside the heading. */
	.theme-editorial .hero .reading {
		display: block;
		margin-inline: 0;
	}
}

.theme-editorial .reading:not(.prose) > p {
	font-size: var(--text-lead);
	line-height: 1.6;
}

/* 11.1 Service pages */

/* The starting prices, as a pane of glass on the hero. */
.theme-editorial .hero .price-panel {
	overflow: visible;
	border: 1px solid rgba(255, 255, 255, 0.14);
	border-radius: 24px;
	background: rgba(255, 255, 255, 0.06);
	-webkit-backdrop-filter: blur(18px);
	backdrop-filter: blur(18px);
	box-shadow: 0 50px 90px -50px rgba(0, 0, 0, 0.7);
	color: var(--color-on-navy-muted);
}

.theme-editorial .hero .price-panel .card__body {
	gap: var(--space-5);
	padding: var(--space-6);
}

.theme-editorial .hero .price-panel .eyebrow {
	margin: 0;
	color: var(--color-mint);
}

.theme-editorial .hero .price-list {
	gap: 0;
}

.theme-editorial .hero .price-list > div {
	flex-direction: column;
	gap: var(--space-1);
	padding-block: var(--space-4);
	border-top: 1px solid rgba(255, 255, 255, 0.14);
}

.theme-editorial .hero .price-list > div:last-child {
	border-bottom: 1px solid rgba(255, 255, 255, 0.14);
}

.theme-editorial .hero .price-list .price {
	color: var(--color-surface);
	font-size: 1.75rem;
	font-weight: 400;
	line-height: 1.15;
	letter-spacing: -0.02em;
}

.theme-editorial .hero .price-panel .small {
	color: var(--color-on-navy-muted);
}

.theme-editorial .hero .price-panel a:not(.button) {
	color: var(--color-mint);
}

.theme-editorial .hero .price-panel .button--primary {
	background: var(--color-paper);
	color: var(--color-navy);
}

.theme-editorial .hero .price-panel .button--primary:hover {
	background: var(--color-mint);
}

.theme-editorial .hero .price-panel :focus-visible {
	outline-color: var(--color-mint);
}

/* "What we build": four cards joined into one box. The gap between them is
   the box's own colour showing through, which draws the dividing lines. */
.theme-editorial .grid:has(> .card--plain) {
	gap: 1px;
	overflow: hidden;
	border: 1px solid var(--color-border);
	border-radius: 24px;
	background: var(--color-border);
	box-shadow: 0 40px 70px -50px rgba(11, 16, 23, 0.35);
}

.theme-editorial .card--plain {
	--cell: var(--color-surface);
	--cell-text: var(--color-muted);
	--cell-title: var(--color-navy);
	--cell-tile: var(--color-teal-tint);
	--cell-icon: var(--color-teal);
	border: 0;
	border-radius: 0;
	background-color: var(--cell);
	box-shadow: none;
}

.theme-editorial .card--plain .card__body {
	gap: var(--space-3);
	padding: var(--space-6) var(--space-5) var(--space-7);
}

.theme-editorial .card--plain .icon {
	margin-bottom: var(--space-5);
	border-radius: 14px;
	background-color: var(--cell-tile);
	color: var(--cell-icon);
}

.theme-editorial .card--plain .h4 {
	margin: 0;
	color: var(--cell-title);
	font-family: var(--font-heading);
	font-size: 1.75rem;
	font-weight: 400;
	line-height: 1.1;
	letter-spacing: var(--tracking-heading);
}

.theme-editorial .card--plain .small {
	color: var(--cell-text);
}

/* "What every site includes": the list as ruled rows with a tick. */
.theme-editorial .checklist {
	margin: 0;
}

.theme-editorial .checklist li {
	margin: 0;
	padding: var(--space-4) 0 var(--space-4) 3rem;
	border-top: 1px solid var(--color-rule);
	font-size: var(--text-lead);
	line-height: 1.4;
}

.theme-editorial .checklist li:last-child {
	border-bottom: 1px solid var(--color-rule);
}

.theme-editorial .checklist li::before {
	top: 50%;
	width: 1.75rem;
	height: 1.75rem;
	background-size: 1.25rem;
	background-position: center;
	background-repeat: no-repeat;
	transform: translateY(-50%);
}

/* "How a project runs" is a sequence, so it keeps its numbers, on a dark band. */
.theme-editorial .section:has(> .container > .steps) {
	border: 0;
	background: var(--color-navy-raised);
	color: var(--color-on-navy-muted);
}

.theme-editorial .section:has(> .container > .steps) h2 {
	color: var(--color-surface);
}

.theme-editorial .steps {
	gap: var(--space-7) var(--space-6);
}

.theme-editorial .steps li {
	padding-top: var(--space-5);
	border-top-color: var(--color-navy-line);
}

/* Set in the text font: the serif's "1" reads as a lower-case L. */
.theme-editorial .steps li::before {
	margin-bottom: var(--space-5);
	color: var(--color-mint);
	font-family: var(--font-body);
	font-size: 0.9375rem;
	font-weight: 600;
	letter-spacing: 0.1em;
}

.theme-editorial .steps .h4 {
	margin-bottom: var(--space-3);
	color: var(--color-surface);
	font-family: var(--font-heading);
	font-size: 2rem;
	font-weight: 400;
	line-height: 1.05;
	letter-spacing: var(--tracking-heading);
}

.theme-editorial .steps .small {
	color: var(--color-on-navy-muted);
	font-size: var(--text-body);
}

.theme-editorial .section:has(> .container > .steps) :focus-visible {
	outline-color: var(--color-mint);
}

/* Questions. */
.theme-editorial .faq details {
	border-color: var(--color-rule);
}

.theme-editorial .faq summary {
	padding-block: var(--space-5);
	font-size: clamp(1.5rem, 1.2rem + 1vw, 1.875rem);
	font-weight: 400;
	line-height: 1.15;
	letter-spacing: var(--tracking-heading);
	transition: color 400ms var(--ease-soft);
}

.theme-editorial .faq summary:hover {
	color: var(--color-teal);
}

/* The plus, in a ring. */
.theme-editorial .faq summary::after {
	display: grid;
	place-items: center;
	width: 2.75rem;
	height: 2.75rem;
	border: 1px solid var(--color-rule);
	border-radius: 50%;
	color: var(--color-navy);
	font-family: var(--font-body);
	font-size: 1.5rem;
}

.theme-editorial .faq details[open] summary::after {
	border-color: var(--color-navy);
	background: var(--color-navy);
	color: var(--color-surface);
}

.theme-editorial .faq details p {
	max-width: 40rem;
	color: var(--color-muted);
}

/* 11.2 Cards: case studies on Our Work and on the service pages */

.theme-editorial .card:not(.card--plain) {
	border-radius: 20px;
}

/* Screenshots sit on the wash, a step darker where the band is the wash. */
.theme-editorial .shot {
	border-radius: 20px;
	background: var(--color-wash);
}

.theme-editorial .section--alt .shot {
	background: #E7EBEF;
}

.theme-editorial .card__title {
	font-size: 2rem;
	line-height: 1.05;
}

.theme-editorial .tag {
	border: 1px solid var(--color-border);
	background: none;
	color: var(--color-muted);
	font-size: 0.8125rem;
	font-weight: 400;
}

/* "Have a project in mind?", the last card on Our Work. */
.theme-editorial .card--cta {
	gap: var(--space-4);
	padding: var(--space-6);
	border: 0;
	background: var(--color-navy);
	color: var(--color-on-navy-muted);
}

.theme-editorial .card--cta .card__title {
	color: var(--color-surface);
}

.theme-editorial .card--cta .button--primary {
	background: var(--color-paper);
	color: var(--color-navy);
}

.theme-editorial .card--cta .button--primary:hover {
	background: var(--color-mint);
}

.theme-editorial .card--cta :focus-visible {
	outline-color: var(--color-mint);
}

/* 11.3 Case study */

/* The facts, as a pane of glass on the hero like the price panel. */
.theme-editorial .hero .facts {
	padding: var(--space-3) var(--space-5);
	border: 1px solid rgba(255, 255, 255, 0.14);
	border-radius: 24px;
	background: rgba(255, 255, 255, 0.06);
	-webkit-backdrop-filter: blur(18px);
	backdrop-filter: blur(18px);
	box-shadow: 0 50px 90px -50px rgba(0, 0, 0, 0.7);
	color: var(--color-surface);
}

.theme-editorial .hero .facts__row {
	padding-block: var(--space-3);
}

.theme-editorial .hero .facts__row + .facts__row {
	border-top-color: rgba(255, 255, 255, 0.14);
}

.theme-editorial .hero .facts dt {
	color: var(--color-on-navy-muted);
}

.theme-editorial .hero .facts dd {
	font-weight: 400;
}

.theme-editorial .hero .shot {
	margin-top: var(--space-7);
	border-radius: 20px;
}

.theme-editorial .hero .shot__frame {
	border-radius: 20px;
}

.theme-editorial .prose h2 {
	margin-top: var(--space-7);
	font-size: clamp(2rem, 1.5rem + 2vw, 3rem);
}

.theme-editorial .prose > h2:first-child {
	margin-top: 0;
}

.theme-editorial .prose .h3 {
	font-size: 2rem;
}

.theme-editorial .result-grid li {
	padding: var(--space-5);
	border-radius: 20px;
	font-weight: 400;
}

.theme-editorial .testimonial blockquote {
	font-weight: 400;
	font-style: italic;
	line-height: 1.15;
}

/* The way on to the next project: one large row that fills with ink. */
.theme-editorial .next-project {
	padding: var(--space-6);
	border-radius: 24px;
	background:
		linear-gradient(var(--color-navy), var(--color-navy)) 50% 100% / 100% 0 no-repeat,
		var(--color-surface);
	box-shadow: none;
}

.theme-editorial .next-project__title {
	font-size: clamp(2rem, 1.4rem + 2.6vw, 3.25rem);
	line-height: 1.02;
}

.theme-editorial .next-project svg {
	width: 3.75rem;
	height: 3.75rem;
	padding: 1rem;
	border: 1px solid var(--color-rule);
	border-radius: 50%;
	color: var(--color-navy);
}

/* 11.4 About */

.theme-editorial .person h2 {
	margin-bottom: var(--space-2);
	font-size: clamp(2.5rem, 1.6rem + 4vw, 4.5rem);
	line-height: 1;
}

.theme-editorial .person .muted {
	margin-bottom: var(--space-5);
}

.theme-editorial .person .muted + p {
	max-width: 40rem;
	margin-bottom: 0;
	font-size: var(--text-lead);
	line-height: 1.6;
}

@media (min-width: 64rem) {
	.theme-editorial .person {
		display: grid;
		grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
		column-gap: var(--space-8);
		align-items: end;
	}

	.theme-editorial .person > * {
		grid-column: 1;
	}

	.theme-editorial .person .muted {
		margin-bottom: 0;
	}

	.theme-editorial .person .muted + p {
		grid-column: 2;
		grid-row: 1 / span 3;
		font-size: 1.5rem;
		line-height: 1.5;
	}
}

.theme-editorial .about-photo {
	border-radius: 24px;
}

/* Company details, and the contact details on Contact. */
.theme-editorial .facts {
	border-radius: 24px;
	box-shadow: none;
	font-size: var(--text-body);
}

.theme-editorial .facts__row {
	padding-block: var(--space-3);
}

@media (min-width: 48rem) {
	.theme-editorial .facts:not(.facts--bare) .facts__row {
		grid-template-columns: 9.5rem 1fr;
	}
}

.theme-editorial .facts dd {
	font-weight: 400;
}

/* 11.5 Contact */

.theme-editorial .contact {
	padding-top: var(--space-8);
}

.theme-editorial .contact .breadcrumb {
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: var(--tracking-eyebrow);
	text-transform: uppercase;
}

.theme-editorial .contact .breadcrumb a {
	text-decoration: none;
}

.theme-editorial .contact h1 {
	margin-top: var(--space-5);
}

.theme-editorial .contact__layout {
	margin-top: var(--space-7);
}

.theme-editorial .chat-card {
	padding: var(--space-4) var(--space-5);
	border-radius: 20px;
	background: var(--color-wash);
	border-color: transparent;
	box-shadow: none;
}

.theme-editorial .chat-card .h4 {
	font-family: var(--font-heading);
	font-size: 1.625rem;
	font-weight: 400;
	line-height: 1.1;
}

.theme-editorial .field label {
	font-size: var(--text-small);
}

.theme-editorial .field input:not([type="checkbox"]),
.theme-editorial .field select,
.theme-editorial .field textarea {
	min-height: 3.5rem;
	border-width: 1px;
	border-radius: 14px;
	font-size: 1.0625rem;
	transition: border-color 300ms var(--ease-soft), box-shadow 300ms var(--ease-soft);
}

.theme-editorial .field input:not([type="checkbox"]):focus,
.theme-editorial .field select:focus,
.theme-editorial .field textarea:focus {
	border-color: var(--color-navy);
	box-shadow: 0 0 0 4px rgba(15, 118, 110, 0.14);
}

.theme-editorial .field--consent input {
	accent-color: var(--color-navy);
}

/* The details beside the form: an ink card that stays in view. */
.theme-editorial .contact__panel {
	border: 0;
	border-radius: 24px;
	background:
		radial-gradient(90% 70% at 100% 100%, rgba(94, 234, 212, 0.16), transparent 70%),
		var(--color-navy);
	box-shadow: none;
	color: var(--color-on-navy-muted);
}

.theme-editorial .contact__panel .card__body {
	padding: var(--space-6);
}

.theme-editorial .contact__panel .h4 {
	color: var(--color-surface);
	font-family: var(--font-heading);
	font-size: 2rem;
	font-weight: 400;
	line-height: 1.05;
}

.theme-editorial .contact__panel .facts {
	border-radius: 0;
	background: none;
	color: var(--color-surface);
}

.theme-editorial .contact__panel .facts__row + .facts__row {
	border-top-color: var(--color-navy-line);
}

.theme-editorial .contact__panel .facts dt,
.theme-editorial .contact__panel .small {
	color: var(--color-on-navy-muted);
}

.theme-editorial .contact__panel a {
	color: var(--color-mint);
}

.theme-editorial .contact__panel :focus-visible {
	outline-color: var(--color-mint);
}

.theme-editorial .notice {
	border-radius: 14px;
}

/* 11.6 Long-form pages: Privacy Policy, Terms of Use */

.theme-editorial .prose table {
	font-size: var(--text-small);
}

/* 12. Motion --------------------------------------------------------------
 *
 * Minimal and slow: one long ease (--ease-soft) for everything.
 *
 * The first screen: the headline's words rise into place one after another,
 * the two lights drift, and as the hero scrolls away its words lift and fade
 * while the dot field lags behind. The headline is clipped, never transparent,
 * so it still counts as painted at once.
 *
 * Everything below: each heading, row, card and footer column rises in as it
 * arrives, and each rule above a row draws itself from the left. They are
 * hidden only once the script that will show them is running (.fx-ready and
 * data-reveal are set by editorial.js), so without it nothing is missing.
 *
 * The reduced-motion rule in main.css switches all of it off.
 */

@keyframes word-rise   { from { transform: translateY(135%) rotate(5deg); } }
@keyframes scroll-hint { 0% { transform: scaleY(0); } 45% { transform: scaleY(1); } 100% { transform: scaleY(1); opacity: 0; } }
@keyframes light-drift { to { transform: translate3d(-9%, -7%, 0) scale(1.12); } }
@keyframes hero-leave  { to { transform: translateY(-5rem); opacity: 0; } }
@keyframes field-lag   { to { transform: translateY(14%) scale(1.06); } }

.word > span {
	transform-origin: 0 100%;
	animation: word-rise 1100ms var(--ease-soft) both;
	animation-delay: calc(120ms + var(--word, 0) * 60ms);
}

.theme-editorial .hero .eyebrow,
.theme-editorial .hero .breadcrumb {
	animation: hero-rise var(--motion-enter) var(--ease-out) both;
}

.theme-editorial .hero .lead {
	animation: hero-rise 900ms var(--ease-soft) 650ms both;
}

/* What sits beside or under the words on an inner page: the price panel, the
   facts of a case study, its screenshot, the live-site button. */
.theme-editorial .hero .price-panel,
.theme-editorial .hero .facts,
.theme-editorial .hero .shot,
.theme-editorial .hero .lead + p {
	animation: hero-rise 1100ms var(--ease-soft) 800ms both;
}

.theme-editorial .hero--home .hero__buttons .button {
	animation: hero-rise 900ms var(--ease-soft) 800ms both;
}

.theme-editorial .hero--home .hero__buttons .button + .button {
	animation-delay: 890ms;
}

.theme-editorial .hero__foot {
	animation: hero-rise 900ms var(--ease-soft) 1200ms both;
}

.theme-editorial .hero::before {
	animation: light-drift 16s var(--ease-in-out) infinite alternate;
}

.theme-editorial .hero::after {
	animation: light-drift 22s var(--ease-in-out) infinite alternate-reverse;
}

/* Tied to the scroll position, where the browser supports it. */
@supports (animation-timeline: view()) {
	.theme-editorial .hero > .container:not(.hero__foot) {
		animation: hero-leave linear both;
		animation-timeline: --hero;
		animation-range: exit 5% exit 75%;
	}

	.hero__field {
		animation: field-lag linear both;
		animation-timeline: --hero;
		animation-range: exit 0% exit 100%;
	}
}

/* Rules above rows are drawn as a background, so they can grow. */
.theme-editorial .hairline {
	border-top: 0;
	background: linear-gradient(var(--line, var(--color-rule)), var(--line, var(--color-rule))) 0 0 / 100% 1px no-repeat;
}

/* Facts: each icon is drawn as its box arrives, the figures count up
   (editorial.js), and the cell under the pointer turns to ink. */
.facts-row li,
.facts-row .icon,
.facts-row__figure {
	transition: background-color 600ms var(--ease-soft), color 600ms var(--ease-soft), transform 600ms var(--ease-soft);
}

.facts-row .icon * {
	stroke-dasharray: 90;
	transition: stroke-dashoffset 1800ms var(--ease-soft) 300ms;
}

.fx-ready .theme-editorial .facts-row [data-reveal]:not(.is-in) .icon * {
	stroke-dashoffset: 90;
}

.facts-row .clock-hand {
	transition: transform 1200ms var(--ease-soft);
}

/* The cell under the pointer changes sides: white turns to ink, ink to white. */
@media (hover: hover) {
	.facts-row li:nth-child(odd):hover {
		--cell: var(--color-navy);
		--cell-text: var(--color-on-navy-muted);
		--cell-figure: var(--color-surface);
		--cell-tile: rgba(94, 234, 212, 0.14);
		--cell-icon: var(--color-mint);
	}

	.facts-row li:nth-child(even):hover {
		--cell: var(--color-surface);
		--cell-text: var(--color-muted);
		--cell-figure: var(--color-navy);
		--cell-tile: var(--color-teal-tint);
		--cell-icon: var(--color-teal);
	}

	.facts-row li:hover .icon {
		transform: translateY(-4px) rotate(-6deg);
	}
}

/* Services: each icon is drawn as its row arrives. Under the pointer the row
   fills with ink from the bottom, its colours change sides, and the arrow
   turns to point up and out. */
.theme-editorial .service-grid > .hairline {
	transition: background-size 700ms var(--ease-soft), opacity var(--motion-reveal) var(--ease-soft), transform var(--motion-reveal) var(--ease-soft);
}

.theme-editorial .service-grid :is(h3, .h3),
.theme-editorial .service-grid p,
.theme-editorial .service-grid .icon,
.theme-editorial .service-grid .text-link {
	transition: color 500ms var(--ease-soft), background-color 500ms var(--ease-soft), border-color 500ms var(--ease-soft), transform 700ms var(--ease-soft);
}

.theme-editorial .service-grid .text-link::after {
	transition: transform 700ms var(--ease-soft);
}

.theme-editorial .service-grid .icon * {
	stroke-dasharray: 90;
	transition: stroke-dashoffset 1800ms var(--ease-soft) 250ms;
}

.fx-ready .theme-editorial .service-grid [data-reveal]:not(.is-in) .icon * {
	stroke-dashoffset: 90;
}

.fx-ready .theme-editorial .service-grid > .hairline[data-reveal]:not(.is-in) {
	background-size: 100% 0, 0 1px;
}

@media (hover: hover) {
	.theme-editorial .service-grid > .hairline:hover {
		--row-title: var(--color-surface);
		--row-text: var(--color-on-navy-muted);
		--row-tile: rgba(94, 234, 212, 0.14);
		--row-icon: var(--color-mint);
		--row-edge: rgba(255, 255, 255, 0.28);
		--row-arrow: var(--color-navy);
		background-size: 100% 100%, 100% 1px;
	}

	.theme-editorial .service-grid > .hairline:hover :is(h3, .h3) {
		transform: translateX(10px);
	}

	.theme-editorial .service-grid > .hairline:hover .icon {
		transform: rotate(-6deg) scale(1.06);
	}

	.theme-editorial .service-grid > .hairline:hover .text-link {
		border-color: var(--color-mint);
		background-color: var(--color-mint);
	}

	.theme-editorial .service-grid > .hairline:hover .text-link::after {
		transform: rotate(-45deg);
	}
}

/* Below the wide layout the link is the words "Learn more", not a round
   button, so on a filled row it turns white rather than sitting on mint. */
@media (hover: hover) and (max-width: 63.98rem) {
	.theme-editorial .service-grid > .hairline:hover {
		--row-arrow: var(--color-surface);
	}

	.theme-editorial .service-grid > .hairline:hover .text-link {
		background-color: transparent;
	}
}

/* Joined feature cards: the one under the pointer turns to ink. */
.theme-editorial .card--plain,
.theme-editorial .card--plain .h4,
.theme-editorial .card--plain .small,
.theme-editorial .card--plain .icon {
	transition: background-color 600ms var(--ease-soft), color 600ms var(--ease-soft), transform 600ms var(--ease-soft), opacity var(--motion-reveal) var(--ease-soft);
}

.theme-editorial .card--plain .icon * {
	stroke-dasharray: 90;
	transition: stroke-dashoffset 1800ms var(--ease-soft) 250ms;
}

.fx-ready .theme-editorial .card--plain[data-reveal]:not(.is-in) .icon * {
	stroke-dashoffset: 90;
}

@media (hover: hover) {
	.theme-editorial .card--plain:hover {
		--cell: var(--color-navy);
		--cell-text: var(--color-on-navy-muted);
		--cell-title: var(--color-surface);
		--cell-tile: rgba(94, 234, 212, 0.14);
		--cell-icon: var(--color-mint);
	}

	.theme-editorial .card--plain:hover .icon {
		transform: translateY(-4px) rotate(-6deg);
	}

	/* The way on to the next project fills from the bottom, like a service row. */
	.theme-editorial .next-project:hover {
		background-size: 100% 100%, auto;
		transform: none;
	}

	.theme-editorial .next-project:hover .next-project__title a,
	.theme-editorial .next-project:hover .eyebrow {
		color: var(--color-surface);
	}

	.theme-editorial .next-project:hover .card__meta {
		color: var(--color-on-navy-muted);
	}

	.theme-editorial .next-project:hover svg {
		border-color: var(--color-mint);
		background: var(--color-mint);
		transform: rotate(-45deg);
	}
}

.theme-editorial .next-project {
	transition: background-size 700ms var(--ease-soft), opacity var(--motion-reveal) var(--ease-soft), transform var(--motion-reveal) var(--ease-soft);
}

.theme-editorial .next-project svg,
.theme-editorial .next-project__title a,
.theme-editorial .next-project .eyebrow,
.theme-editorial .next-project .card__meta {
	transition: color 500ms var(--ease-soft), background-color 500ms var(--ease-soft), border-color 500ms var(--ease-soft), transform 700ms var(--ease-soft);
}

/* Completed work: when a project is chosen its words rise in and its three
   screenshots arrive one after another. A screenshot under the pointer lifts. */
@keyframes shot-in  { from { transform: translateY(2.5rem) scale(0.96); opacity: 0; } }

.work-spread__text {
	animation: hero-rise 800ms var(--ease-soft) both;
}

.work-shot {
	animation: shot-in 1000ms var(--ease-soft) both;
	transition: transform 600ms var(--ease-soft), box-shadow 600ms var(--ease-soft);
}

.work-shot--side {
	animation-delay: 140ms;
}

.work-shot--phone {
	animation-delay: 280ms;
}

.work-shot img {
	transition: transform 1200ms var(--ease-soft);
}

@media (hover: hover) {
	.work-shot:hover {
		z-index: 3;
		transform: translateY(-8px);
	}

	.work-shot:hover img {
		transform: scale(1.03);
	}
}

/* Cards that lead somewhere lift a little. */
.theme-editorial .card {
	transition: transform 600ms var(--ease-soft), box-shadow 600ms var(--ease-soft), border-color 600ms var(--ease-soft);
}

.theme-editorial .card:has(.card__link):hover {
	transform: translateY(-6px);
}

.theme-editorial .hairline .icon {
	transition: transform 600ms var(--ease-soft);
}

.theme-editorial .section--ink .hairline:hover .icon {
	transform: translateY(-4px);
}

@keyframes marquee { to { transform: translateX(calc(-100% - var(--marquee-gap))); } }

.marquee__group {
	animation: marquee 38s linear infinite;
}

.marquee:hover .marquee__group {
	animation-play-state: paused;
}

/* Reveal on scroll. The attribute is taken off again once an element has
   arrived, so its own hover transitions take over. */
.theme-editorial [data-reveal] {
	transition: opacity var(--motion-reveal) var(--ease-soft), transform var(--motion-reveal) var(--ease-soft), background-size 1400ms var(--ease-soft), background-color 600ms var(--ease-soft), color 600ms var(--ease-soft);
	transition-delay: calc(var(--reveal-order, 0) * 90ms);
}

.fx-ready .theme-editorial [data-reveal]:not(.is-in) {
	opacity: 0;
	transform: translateY(2rem);
	background-size: 0 1px;
}

@media (prefers-reduced-motion: reduce) {
	.fx-ready .theme-editorial [data-reveal]:not(.is-in) {
		opacity: 1;
		transform: none;
		background-size: 100% 1px;
	}

	.fx-ready .theme-editorial .facts-row [data-reveal]:not(.is-in) .icon * {
		stroke-dashoffset: 0;
	}

	/* The names sit still, once, and wrap to fit. */
	.marquee {
		-webkit-mask-image: none;
		mask-image: none;
	}

	.marquee__group {
		flex: 1;
		flex-wrap: wrap;
		justify-content: flex-start;
		min-width: 0;
		padding-inline: var(--page-margin);
	}

	.marquee__group[aria-hidden] {
		display: none;
	}

	.fx-ready .theme-editorial .service-grid [data-reveal]:not(.is-in) .icon *,
	.fx-ready .theme-editorial .card--plain[data-reveal]:not(.is-in) .icon * {
		stroke-dashoffset: 0;
	}

	.fx-ready .theme-editorial .service-grid > .hairline[data-reveal]:not(.is-in) {
		background-size: 100% 0, 100% 1px;
	}
}
