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

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

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

body {
	margin: 0;
	font-family: var(--font-body);
	font-size: var(--fs-body);
	line-height: var(--lh-body);
	color: var(--ink);
	background: var(--paper);
	-webkit-font-smoothing: antialiased;
	overflow-wrap: break-word;
	/* issueslog.md #048 — only upright Karla/Space Grotesk faces are loaded
	   (design-reference.html requests no italics), so any `font-style:
	   italic` would otherwise render as a browser-slanted faux italic.
	   Weight synthesis stays allowed; style synthesis is switched off, and
	   emphasis is carried by colour/weight instead (see rich-text.css). */
	font-synthesis: weight;
}

img, picture, video, canvas, svg { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; }

/*
 * issueslog.md #038 — WebKit ignores min-height/padding/radius on a native
 * <select> unless its platform appearance is removed, so filter and
 * plan-switch selects rendered 22–25px tall in Safari/iOS. appearance:none
 * everywhere, with a chevron drawn from two currentColor gradients (no
 * image asset, no raw colour — it follows the control's text colour on
 * light and dark surfaces). Component rules set background-COLOR only, so
 * they don't reset this background-image via the shorthand.
 */
select:not([multiple]):not([size]) {
	-webkit-appearance: none;
	appearance: none;
	background-image:
		linear-gradient(45deg, transparent 50%, currentColor 50%),
		linear-gradient(135deg, currentColor 50%, transparent 50%);
	background-position:
		calc(100% - 20px) 50%,
		calc(100% - 15px) 50%;
	background-size: 5px 5px, 5px 5px;
	background-repeat: no-repeat;
	padding-right: 44px;
	min-height: 44px;
	cursor: pointer;
}
/* issueslog.md #050 — iOS Safari zooms the page on focus of any form
   control under 16px; keep every control at ≥16px on mobile. */
@media (max-width: 767px) {
	input, select, textarea { font-size: max(1rem, 1em); }
}
a { color: inherit; text-decoration: none; }
ul, ol { margin: 0; padding: 0; list-style: none; }

h1, h2, h3, h4, h5, h6 {
	margin: 0;
	font-family: var(--font-display);
	font-weight: 600;
	line-height: var(--lh-display);
	color: var(--ink);
}
.section--dark h1, .section--dark h2, .section--dark h3,
.section--dark-soft h1, .section--dark-soft h2, .section--dark-soft h3 { color: var(--paper); }

h1, .h1 { font-size: var(--fs-h1); letter-spacing: var(--tracking-h1); }
h1.h1--l2 { font-size: var(--fs-h1-l2); }
h2, .h2 { font-size: var(--fs-h2); letter-spacing: var(--tracking-h2); }
h3, .h3 { font-size: var(--fs-h3); letter-spacing: var(--tracking-h3); line-height: 1.2; }

p {
	margin: 0 0 var(--space-4);
	max-width: var(--measure);
	font-size: var(--fs-body);
	line-height: 1.7;
	color: var(--text-body-light);
}
.section--dark p, .section--dark-soft p { color: var(--text-body-dark); }

.lead {
	font-family: var(--font-body);
	font-size: var(--fs-lead);
	line-height: 1.65;
	color: var(--text-body-light);
	max-width: 58ch;
}
.section--dark .lead, .section--dark-soft .lead { color: var(--text-body-dark); }

.eyebrow {
	display: inline-block;
	font-family: var(--font-body);
	font-size: var(--fs-eyebrow);
	font-weight: 700;
	letter-spacing: var(--tracking-eyebrow);
	text-transform: uppercase;
	color: var(--accent-deep);
	margin-bottom: var(--space-3);
}
.section--dark .eyebrow, .section--dark-soft .eyebrow { color: var(--accent-light); }

.accent { color: var(--accent); }
.section--dark .accent, .section--dark-soft .accent { color: var(--accent-light); }

/*
 * Headline accent clause. ACF heading fields carry the accented word(s) as
 * <em>...</em> (editors write "We are a digital & <em>technology</em>
 * consultancy"); design-reference §02 puts the accent on the second clause,
 * once per section, in the same weight as the rest of the heading — not
 * italic. This rule is what actually makes that render correctly; without
 * it <em> just shows as plain italic text.
 */
h1 em, h2 em, h3 em, .h1 em, .h2 em, .h3 em {
	font-style: normal;
	color: var(--accent);
}
.section--dark h1 em, .section--dark h2 em, .section--dark h3 em,
.section--dark-soft h1 em, .section--dark-soft h2 em, .section--dark-soft h3 em {
	color: var(--accent-light);
}
/*
 * --accent on --paper measures 3.52:1 — enough for "large text" (≥24px, or
 * ≥18.66px at bold weight) but h3's clamped minimum (21px at font-weight
 * 600) sits in the ambiguous zone between the two large-text definitions.
 * h1/h2 are unambiguously large at every viewport, so only h3 needs the
 * safer, always-≥4.5:1 --accent-deep. (Dark sections already use
 * --accent-light at 8.59:1, no ambiguity there.)
 */
h3 em, .h3 em { color: var(--accent-deep); }

.sr-only {
	position: absolute;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.skip-link {
	position: absolute;
	top: -100px;
	left: var(--space-4);
	background: var(--ink);
	color: var(--paper);
	padding: var(--space-3) var(--space-5);
	z-index: 1000;
	border-radius: var(--radius-sm);
	transition: top var(--dur-fast) var(--ease-out);
}
.skip-link:focus { top: var(--space-4); }

:focus-visible {
	outline: 2px solid var(--accent-deep);
	outline-offset: 3px;
}
.section--dark :focus-visible, .section--dark-soft :focus-visible { outline-color: var(--accent-light); }
/*
 * Chrome that renders on a dark (near-`--ink`) background without carrying
 * a `.section--dark`/`.section--dark-soft` class: the sticky dark header,
 * the mega-menu's dark featured panel, and the full-screen mobile nav.
 * --accent-deep against --ink measures 3.57:1 — just over the 3:1 UI/focus
 * minimum, so not a hard failure, but --accent-light (8.59:1 against
 * --ink) is unambiguous and matches the same swap already applied inside
 * dark sections.
 */
.site-header:not(.site-header--light) :focus-visible,
.mega-menu__featured :focus-visible,
.mobile-nav :focus-visible { outline-color: var(--accent-light); }

.container {
	max-width: var(--container-max);
	margin-inline: auto;
	padding-inline: var(--margin-desktop);
}

@media (max-width: 1023px) { .container { padding-inline: var(--margin-tablet); } }
@media (max-width: 767px) { .container { padding-inline: var(--margin-mobile); } }

.grid-12 {
	display: grid;
	grid-template-columns: repeat(12, 1fr);
	gap: var(--gutter);
}
@media (max-width: 1023px) { .grid-12 { grid-template-columns: repeat(8, 1fr); } }
@media (max-width: 767px) { .grid-12 { grid-template-columns: repeat(4, 1fr); } }

.section {
	padding-block: var(--section-pad-light);
	background: var(--paper);
	color: var(--ink);
}
.section--soft { background: var(--paper-soft); }
.section--dark { background: var(--ink); color: var(--paper); padding-block: var(--section-pad-dark); }
.section--dark-soft { background: var(--ink-soft); color: var(--paper); padding-block: var(--section-pad-dark); }

/*
 * Accessibility fix — a11y audit (§15). --text-body-light and --muted-light
 * are only AA-compliant against --paper/--paper-soft; several components
 * across components.css/l1-modules.css/modules-l2.css/rich-text.css/
 * single-templates.css set `color: var(--text-body-light)` or
 * `var(--muted-light)` directly on spans/divs (not just <p>/.muted, which
 * already had light/dark handling) with no dark-section equivalent, so
 * those elements went unreadable (as low as 2.65:1) whenever an editor sets
 * a module's theme control to dark. Redefining the two tokens on any dark
 * section makes every such usage resolve to the already-compliant dark
 * pairing automatically, with no per-component edits required now or for
 * components added later.
 */
.section--dark, .section--dark-soft {
	--text-body-light: var(--text-body-dark);
	--muted-light: var(--muted-dark);
}

.section--compact { padding-block: calc(var(--section-pad-light) * 0.6); }
.section--dark.section--compact, .section--dark-soft.section--compact { padding-block: calc(var(--section-pad-dark) * 0.6); }
.section--spacious { padding-block: calc(var(--section-pad-light) * 1.3); }
.section--dark.section--spacious, .section--dark-soft.section--spacious { padding-block: calc(var(--section-pad-dark) * 1.3); }

.section-head {
	max-width: 640px;
	margin-bottom: var(--space-8);
}
.section-head--split {
	display: flex;
	justify-content: space-between;
	align-items: flex-end;
	gap: var(--space-6);
	max-width: none;
}
@media (max-width: 767px) {
	.section-head { margin-bottom: var(--space-6); }
	.section-head--split { flex-direction: column; align-items: flex-start; }
}

.muted { color: var(--muted-light); }
.section--dark .muted, .section--dark-soft .muted { color: var(--muted-dark); }

.btn {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	font-family: var(--font-body);
	font-size: var(--fs-eyebrow);
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	padding: 18px 30px;
	border-radius: var(--radius-pill);
	border: 1px solid transparent;
	cursor: pointer;
	transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
	min-height: 48px;
}
.btn:hover { transform: translateY(-1px); }
.btn--sm { padding: 15px 24px; }
.btn--lg { padding: 20px 34px; }

/* issueslog.md #012 — every .btn variant needs a defined disabled state before the native form submit buttons use it. */
.btn:disabled, .btn[aria-disabled="true"] {
	opacity: 0.5;
	cursor: not-allowed;
	transform: none;
	pointer-events: none;
}
.btn:disabled:hover, .btn[aria-disabled="true"]:hover { transform: none; }

/* "Small / tertiary" pill from design-reference §05 — paper-tint fill, used for standalone secondary actions like "All case stories" */
.btn--pill-tertiary { background: var(--paper-soft); color: var(--ink); border-color: transparent; }
.btn--pill-tertiary:hover { background: var(--line-light); }
.section--dark .btn--pill-tertiary, .section--dark-soft .btn--pill-tertiary { background: var(--ink-soft); color: var(--paper); }
.section--dark .btn--pill-tertiary:hover, .section--dark-soft .btn--pill-tertiary:hover { background: var(--line-dark); }

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

.btn--secondary { border: 1px solid var(--ink); background: transparent; color: var(--ink); padding: 17px 30px; }
.section--dark .btn--secondary, .section--dark-soft .btn--secondary { color: var(--paper); border-color: rgba(255,255,255,0.5); }
.btn--secondary:hover { background: var(--ink); color: var(--paper); }
.section--dark .btn--secondary:hover, .section--dark-soft .btn--secondary:hover { background: var(--paper); color: var(--ink); border-color: var(--paper); }

.btn--tertiary {
	background: none;
	border: none;
	padding: 0;
	/* issueslog.md #041 — text links were 33px tall. 44px tap box, with the
	   label kept sitting on its accent rule (flex-end) so the visual is
	   unchanged; the extra height is added above the text, not between the
	   text and its underline. */
	min-height: 44px;
	align-items: flex-end;
	color: inherit;
	font-weight: 600;
	text-transform: none;
	letter-spacing: normal;
	font-size: var(--fs-body-sm);
	border-bottom: 2px solid var(--accent);
	border-radius: 0;
	padding-bottom: 4px;
}
.section--dark .btn--tertiary, .section--dark-soft .btn--tertiary { border-bottom-color: var(--accent-light); }
.btn--tertiary .arrow { transition: transform var(--dur-fast) var(--ease-out); }
.btn--tertiary:hover .arrow { transform: translateX(4px); }

@media (max-width: 767px) {
	.btn { width: 100%; justify-content: center; }
	/* issueslog.md #034 — inside an inline control row (e.g. the 404 search
	   field + button) the button must stay content-width, or the
	   flex: 1 / min-width: 0 input collapses to ~34px beside it. */
	.inline-field .btn { width: auto; flex-shrink: 0; }
}

.card-grid { display: grid; gap: var(--card-gap); }
.card-grid--2 { grid-template-columns: repeat(2, 1fr); }
.card-grid--3 { grid-template-columns: repeat(3, 1fr); }
.card-grid--4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1023px) {
	.card-grid--3, .card-grid--4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 767px) {
	.card-grid--2, .card-grid--3, .card-grid--4 { grid-template-columns: 1fr; }
}

.placeholder-media {
	position: relative;
	width: 100%;
	background: var(--paper-soft);
	overflow: hidden;
}
.section--dark .placeholder-media, .section--dark-soft .placeholder-media { background: var(--ink-soft); }
.placeholder-media::after {
	content: "";
	position: absolute; inset: 0;
	background: linear-gradient(135deg, transparent 40%, rgba(238,76,124,0.1) 100%);
}
.placeholder-media--16-9 { aspect-ratio: 16 / 9; }
.placeholder-media--4-3 { aspect-ratio: 4 / 3; }
.placeholder-media--3-4 { aspect-ratio: 3 / 4; }
.placeholder-media--1-1 { aspect-ratio: 1 / 1; }
.placeholder-media--16-10 { aspect-ratio: 16 / 10; }
.placeholder-media img { width: 100%; height: 100%; object-fit: cover; }
/* The pink wash is for the empty placeholder only, never over a real image. */
.placeholder-media:has(img:not([src*="placeholder.svg"]))::after { display: none; }

[data-reveal] {
	opacity: 0;
	transform: translateY(16px);
	transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
}
[data-reveal].is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
	[data-reveal] { opacity: 1; transform: none; }
}
