/**
 * DOT theme — front end.
 *
 * The source design used inline styles with fixed pixel widths and a single
 * 900px breakpoint. Everything here is rebuilt on intrinsic layout (minmax,
 * auto-fit, clamp) so it degrades continuously rather than snapping at one
 * width. Colours and type come from theme.json custom properties.
 */

/* ============================================================== 1. Base */

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	/*
	 * The design set scroll-behavior on <html> globally. Respect a reduced
	 * motion preference instead of forcing smooth scroll on everyone.
	 */
	-webkit-text-size-adjust: 100%;
}

@media (prefers-reduced-motion: no-preference) {
	html {
		scroll-behavior: smooth;
	}
}

body {
	margin: 0;
	overflow-x: clip; /* Decorative oversized logos bleed past the viewport. */
}

img,
svg,
video {
	max-width: 100%;
	height: auto;
}

:where(a):focus-visible,
:where(button):focus-visible,
:where(input, select, textarea):focus-visible {
	outline: 2px solid var(--wp--preset--color--primary);
	outline-offset: 2px;
	border-radius: 2px;
}

.dot-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:focus {
	position: fixed;
	top: 8px;
	left: 8px;
	z-index: 999;
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--primary);
	padding: 12px 20px;
	border-radius: var(--wp--custom--radius--sm);
	font-weight: 600;
	box-shadow: var(--wp--preset--shadow--lift);
}

/*
 * Sticky header + in-page anchors. Without this every #jump link lands with
 * its heading hidden behind the nav bar.
 */
:target,
[id] {
	scroll-margin-top: calc(var(--dot-nav-h, 70px) + var(--dot-admin-bar, 0px) + 16px);
}

/*
 * Full-height panels land flush with the top of the viewport, with the sticky
 * header over them as the design intended. The offset above would stop a snap
 * short and expose a strip of the previous panel.
 */
.dot-panel[id] {
	scroll-margin-top: 0;
}

/* ========================================================== 2. Utilities */

.dot-container {
	max-width: var(--wp--style--global--wide-size, 1240px);
	margin-inline: auto;
	width: 100%;
}

.dot-container--narrow {
	max-width: 1100px;
}

.dot-container--text {
	max-width: 900px;
}

/*
 * Long-form copy in a 1240px section runs to ~150 characters a line, which is
 * roughly twice a comfortable measure. Cap the prose without narrowing the
 * section, so headings and full-width children still line up on the same left
 * edge as every other section.
 */
.dot-section--prose :is(p, ul, ol, blockquote) {
	max-width: 72ch;
}

.dot-eyebrow {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 500;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--wp--preset--color--primary);
	margin: 0 0 12px;
	display: block;
}

.dot-eyebrow--on-dark {
	color: #8fb3dd;
}

/* Section paddings. Fluid rather than the design's fixed 56/64/72px. */
.dot-section {
	position: relative;
	padding-block: var(--wp--preset--spacing--70);
	padding-inline: var(--wp--custom--gutter);
}

.dot-section--divided {
	border-top: 1px solid var(--wp--preset--color--border);
}

.dot-section--surface {
	background: var(--wp--preset--color--surface);
}

.dot-lede {
	font-size: var(--wp--preset--font-size--lg);
	color: var(--wp--preset--color--muted);
	line-height: 1.7;
	max-width: 68ch;
	margin: 0 0 var(--wp--preset--spacing--50);
}

/*
 * Decorative outsized logo watermark. The design positioned these with fixed
 * px offsets (right: -420px; width: 1500px), which on a phone pushed a 1500px
 * image into a 390px viewport. Sized in vmax so it scales with the screen.
 */
.dot-watermark {
	position: absolute;
	width: clamp(500px, 90vmax, 1500px);
	height: auto;
	opacity: 0.05;
	pointer-events: none;
	user-select: none;
	z-index: 0;
}

.dot-watermark--right {
	top: 50%;
	right: clamp(-420px, -28vw, -120px);
	transform: translateY(-50%);
}

.dot-watermark--top-left {
	top: clamp(-320px, -22vw, -100px);
	left: clamp(-380px, -25vw, -120px);
}

.dot-watermark--top-right {
	top: clamp(-280px, -20vw, -90px);
	right: clamp(-300px, -20vw, -90px);
}

.dot-watermark--bottom-right {
	bottom: clamp(-380px, -25vw, -120px);
	right: clamp(-320px, -22vw, -100px);
	transform: rotate(-4deg);
}

@media (max-width: 600px) {
	.dot-watermark {
		display: none; /* Pure decoration; not worth the paint cost on a phone. */
	}
}

/* ============================================================ 3. Header */

:root {
	--dot-nav-h: 70px;
	--dot-admin-bar: 0px;
}

.admin-bar {
	--dot-admin-bar: 32px;
}

@media screen and (max-width: 782px) {
	.admin-bar {
		--dot-admin-bar: 46px;
	}
}

.dot-header {
	position: sticky;
	top: var(--dot-admin-bar);
	z-index: 40;
	background: var(--wp--preset--color--base);
	border-bottom: 1px solid var(--wp--preset--color--border);
}

/*
 * Header, <main> and footer are siblings at the top level, so the editor's
 * block rhythm puts a margin at each seam. That shows as a strip of page
 * background under the nav and above the footer, and it offsets every scroll
 * snap point by the same amount. These three butt together by design.
 */
.wp-site-blocks > * {
	margin-block: 0;
}

.dot-header__inner {
	max-width: var(--wp--style--global--wide-size, 1240px);
	margin-inline: auto;
	padding: 14px var(--wp--custom--gutter);
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--40);
}

.dot-logo {
	display: flex;
	align-items: center;
	flex-shrink: 0;
	line-height: 0;
}

.dot-logo img {
	height: 40px;
	width: auto;
	display: block;
}

@media (max-width: 480px) {
	.dot-logo img {
		height: 32px;
	}
}

.dot-nav {
	display: none;
	align-items: center;
	gap: 22px;
}

.dot-nav a {
	font-size: var(--wp--preset--font-size--md);
	font-weight: 500;
	color: var(--wp--preset--color--ink);
	text-decoration: none;
	white-space: nowrap;
	transition: color var(--wp--custom--transition);
}

.dot-nav a:hover,
.dot-nav a:focus-visible {
	color: var(--wp--preset--color--primary);
	text-decoration: none;
}

/*
 * The menu walker prints bare <a> elements, so WordPress's current-* classes
 * sit on the link itself — not on a wrapping <li> as core's markup would have.
 */
.dot-nav a.current-menu-item,
.dot-nav a.current-menu-ancestor,
.dot-nav a.current-menu-parent,
.dot-nav .dot-nav__link--active {
	font-weight: 700;
	color: var(--wp--preset--color--primary);
}

.dot-header__actions {
	display: flex;
	align-items: center;
	gap: 14px;
}

/*
 * Desktop-only quote button. Scoped to .dot-header so it outranks the
 * `.dot-btn { display: inline-flex }` rule that comes later in this file —
 * otherwise the button reappears on mobile and crushes the logo.
 */
.dot-header .dot-header__cta {
	display: none;
}

.dot-burger {
	display: inline-flex;
	flex-direction: column;
	justify-content: center;
	gap: 5px;
	background: none;
	border: 0;
	cursor: pointer;
	padding: 8px;
	margin-right: -8px;
}

.dot-burger span {
	width: 22px;
	height: 2px;
	background: var(--wp--preset--color--ink);
	display: block;
	transition: transform var(--wp--custom--transition), opacity var(--wp--custom--transition);
}

.dot-burger[aria-expanded="true"] span:nth-child(1) {
	transform: translateY(7px) rotate(45deg);
}

.dot-burger[aria-expanded="true"] span:nth-child(2) {
	opacity: 0;
}

.dot-burger[aria-expanded="true"] span:nth-child(3) {
	transform: translateY(-7px) rotate(-45deg);
}

.dot-mobile-nav {
	border-top: 1px solid var(--wp--preset--color--border);
	padding: 8px var(--wp--custom--gutter) 20px;
	display: flex;
	flex-direction: column;
	gap: 4px;
	max-height: calc(100dvh - var(--dot-nav-h) - var(--dot-admin-bar));
	overflow-y: auto;
}

.dot-mobile-nav[hidden] {
	display: none;
}

.dot-mobile-nav__links {
	display: flex;
	flex-direction: column;
}

.dot-mobile-nav a {
	padding: 10px 0;
	font-size: var(--wp--preset--font-size--lg);
	font-weight: 500;
	color: var(--wp--preset--color--ink);
	text-decoration: none;
}

.dot-mobile-nav a.current-menu-item,
.dot-mobile-nav a.current-menu-ancestor,
.dot-mobile-nav a.current-menu-parent,
.dot-mobile-nav .dot-nav__link--active {
	font-weight: 700;
	color: var(--wp--preset--color--primary);
}

.dot-mobile-nav .dot-btn {
	margin-top: 10px;
	text-align: center;
	justify-content: center;
}

/*
 * The design switched at 1060px. Seven top-level items at 15px need roughly
 * that much room once the logo and CTA are accounted for.
 */
@media (min-width: 1060px) {
	.dot-nav {
		display: flex;
	}

	.dot-header .dot-header__cta {
		display: inline-flex;
	}

	.dot-burger,
	.dot-mobile-nav {
		display: none !important;
	}
}

/* ============================================================ 4. Buttons */

.dot-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	font-size: var(--wp--preset--font-size--md);
	font-weight: 600;
	line-height: 1.2;
	padding: 14px 26px;
	border-radius: var(--wp--custom--radius--sm);
	border: 1px solid transparent;
	text-decoration: none;
	cursor: pointer;
	transition: background var(--wp--custom--transition), color var(--wp--custom--transition),
		border-color var(--wp--custom--transition);
}

.dot-btn:hover,
.dot-btn:focus-visible {
	text-decoration: none;
}

.dot-btn--primary {
	background: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--base);
}

.dot-btn--primary:hover,
.dot-btn--primary:focus-visible {
	background: var(--wp--preset--color--primary-dark);
	color: var(--wp--preset--color--base);
}

/*
 * White button. On a Button block the class sits on the block's wrapper div —
 * Gutenberg rejects extra classes on the link itself — so the link inside it
 * is what gets styled.
 */
.dot-btn.dot-btn--light,
.wp-block-button.dot-btn--light > .wp-block-button__link {
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--primary);
}

.dot-btn.dot-btn--light:hover,
.dot-btn.dot-btn--light:focus-visible,
.wp-block-button.dot-btn--light > .wp-block-button__link:hover,
.wp-block-button.dot-btn--light > .wp-block-button__link:focus-visible {
	background: var(--wp--preset--color--primary-tint);
	color: var(--wp--preset--color--primary-dark);
}

.dot-btn--sm {
	padding: 10px 20px;
	font-size: var(--wp--preset--font-size--base);
}

.dot-link-arrow {
	font-size: var(--wp--preset--font-size--md);
	font-weight: 600;
	text-decoration: none;
	white-space: nowrap;
}

.dot-link-arrow--on-dark {
	color: var(--wp--preset--color--on-dark-blue);
}

.dot-link-arrow--on-dark:hover,
.dot-link-arrow--on-dark:focus-visible {
	color: var(--wp--preset--color--base);
	text-decoration: none;
}

/* ============================================================== 5. Grids */

/*
 * All of these were fixed repeat(N, 1fr) with one !important override at
 * 900px. auto-fit + minmax lets them reflow at whatever width the content
 * actually needs, which matters most for the 5-up strip and the 4-up "why"
 * grid that were badly cramped between 600 and 900px.
 */

.dot-grid {
	display: grid;
	gap: var(--wp--preset--spacing--40);
}

/*
 * Core's layout styles put block-margin on every child of a group. Inside a
 * grid that fights the gap, so clear it on grid and flex containers.
 */
.dot-grid > *,
.dot-cta > *,
.dot-cta__inner > *,
.dot-pills > *,
.dot-acquisition > *,
.dot-team-grid > *,
.dot-brands > * {
	margin-block: 0;
}

/*
 * Cover blocks used as full-height panels.
 *
 * The Cover block writes min-height as an INLINE style, and its unit list has
 * no svh — only vh. An inline style outranks any selector, so !important is
 * the only way to reach it short of filtering the block's markup in PHP.
 * It matters: on a phone, 100vh is the viewport with the address bar hidden,
 * so a 100vh panel is always taller than what you can actually see.
 */
.dot-panel.wp-block-cover {
	min-height: calc(100svh - var(--dot-admin-bar)) !important;
}

/*
 * Cover blocks used as panels or heroes: hold their content to the same
 * 1240px column every other section uses, so the left edge lines up down the
 * whole page.
 */
.dot-panel.wp-block-cover > .wp-block-cover__inner-container,
.dot-hero.wp-block-cover > .wp-block-cover__inner-container {
	position: relative;
	z-index: 1;
	max-width: var(--wp--style--global--wide-size, 1240px);
	margin-inline: auto;
	width: 100%;
}

/*
 * Core's constrained layout caps every unaligned child at contentSize (760px).
 * The panels are built on a 1240px grid, so their covers use the flow layout
 * instead — this undoes the cap for anything that still arrives constrained,
 * e.g. a section the client adds later from the inserter.
 */
.dot-panel.wp-block-cover > .wp-block-cover__inner-container > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
	max-width: none;
}

/*
 * Core sets `color: #fff` on every Cover block. That is right for the dark
 * panels and wrong for the one built on a light scrim, where it renders the
 * heading white-on-white. Put the ink palette back for those.
 */
.dot-panel--light,
.dot-panel--light :is(h1, h2, h3, h4, h5, h6) {
	color: var(--wp--preset--color--ink);
}

.dot-panel--light .dot-lede,
.dot-panel--light p:not([class*="has-"]) {
	color: var(--wp--preset--color--muted);
}

.dot-panel--light .dot-card--blue,
.dot-panel--light .dot-card--blue :is(h1, h2, h3, h4, h5, h6) {
	color: var(--wp--preset--color--base);
}

.dot-panel--light .dot-card--blue .dot-card__text {
	color: var(--wp--preset--color--on-dark-blue);
}

/* Parallax on a cover's background image. */
.dot-panel--hero .wp-block-cover__image-background {
	transform: translate3d(0, var(--dot-parallax, 0px), 0);
	will-change: transform;
	/* The design overscanned the image so the shift never exposes an edge. */
	height: 116%;
	top: -8%;
	object-fit: cover;
	/*
	 * The source applied brightness(0.5) to the photo *in addition* to the
	 * gradient scrim. Cover blocks only do the scrim, so without this the
	 * hero body copy sits on a photo that is far too bright to read.
	 */
	filter: brightness(0.5);
}

@media (prefers-reduced-motion: reduce) {
	.dot-panel--hero .wp-block-cover__image-background {
		transform: none;
		height: 100%;
		top: 0;
	}
}

.dot-grid--3 {
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
}

.dot-grid--4 {
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr));
	gap: var(--wp--preset--spacing--50);
}

.dot-grid--5 {
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 170px), 1fr));
	gap: 14px;
}

.dot-grid--split {
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
	gap: var(--wp--preset--spacing--60);
	align-items: center;
}

.dot-grid--split-top {
	align-items: start;
}

/*
 * The source reversed some split rows by putting the image first in source
 * order. That reads backwards on a phone, where the heading should come
 * first. Source order stays text-first; this flips it visually on wide
 * screens only.
 */
@media (min-width: 900px) {
	.dot-grid--reverse > :first-child {
		order: 2;
	}
}

/* ============================================================== 6. Cards */

.dot-card {
	background: var(--wp--preset--color--surface-card);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	padding: clamp(20px, 5vw, 28px);
	display: block;
	text-decoration: none;
	color: inherit;
	transition: border-color var(--wp--custom--transition), box-shadow var(--wp--custom--transition),
		transform var(--wp--custom--transition);
}

a.dot-card:hover,
a.dot-card:focus-visible {
	border-color: var(--wp--preset--color--primary);
	box-shadow: var(--wp--preset--shadow--card);
	text-decoration: none;
}

@media (prefers-reduced-motion: no-preference) {
	a.dot-card:hover,
	a.dot-card:focus-visible {
		transform: translateY(-2px);
	}
}

.dot-card__title {
	font-size: var(--wp--preset--font-size--subhead-sm);
	color: var(--wp--preset--color--ink);
	margin: 0 0 10px;
	font-weight: 600;
}

.dot-card__text {
	font-size: var(--wp--preset--font-size--base);
	color: var(--wp--preset--color--muted);
	line-height: 1.6;
	margin: 0;
}

.dot-card--white {
	background: var(--wp--preset--color--base);
}

.dot-card--tile {
	text-align: center;
	padding: 18px 10px;
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 500;
	color: var(--wp--preset--color--ink);
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 64px;
}

.dot-card--blue {
	background: var(--wp--preset--color--primary);
	border-color: transparent;
}

.dot-card--blue .dot-card__title {
	color: var(--wp--preset--color--base);
}

.dot-card--blue .dot-card__text {
	color: var(--wp--preset--color--on-dark-blue);
}

.dot-card--bare {
	background: none;
	border: 0;
	padding: 0;
}

.dot-card--bare .dot-card__title {
	font-size: var(--wp--preset--font-size--lg);
	color: var(--wp--preset--color--base);
	margin-bottom: 8px;
}

.dot-card--bare .dot-card__text {
	color: var(--wp--preset--color--on-dark);
}

/* ============================================================ 7. CTA band */

.dot-cta {
	background: var(--wp--preset--color--primary);
	border-radius: var(--wp--custom--radius--xl);
	padding: clamp(28px, 4vw, 48px);
	display: flex;
	justify-content: space-between;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--40);
}

.dot-cta__title {
	font-size: var(--wp--preset--font-size--section);
	color: var(--wp--preset--color--base);
	margin: 0 0 8px;
	font-weight: 700;
}

.dot-cta__text {
	font-size: var(--wp--preset--font-size--md);
	color: var(--wp--preset--color--on-dark-blue);
	margin: 0;
	max-width: 60ch;
}

.dot-cta--flat {
	border-radius: 0;
	padding: var(--wp--preset--spacing--60) var(--wp--custom--gutter);
	justify-content: center;
}

.dot-cta--flat .dot-cta__inner {
	max-width: var(--wp--style--global--wide-size, 1240px);
	width: 100%;
	margin-inline: auto;
	display: flex;
	justify-content: space-between;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--40);
}

/* =============================================================== 8. Hero */

.dot-hero {
	position: relative;
	display: flex;
	align-items: center;
	overflow: hidden;
	isolation: isolate;
	padding-inline: var(--wp--custom--gutter);
	padding-block: var(--wp--preset--spacing--80);
	min-height: clamp(320px, 42vw, 440px);
}

.dot-hero__media {
	position: absolute;
	inset: 0;
	z-index: -2;
}

.dot-hero__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	filter: brightness(0.5);
}

.dot-hero__scrim {
	position: absolute;
	inset: 0;
	z-index: -1;
	pointer-events: none;
	background: var(--wp--preset--gradient--hero-scrim);
}

/* The flat scrim the four centred page heroes sit on. */
.dot-hero__scrim--flat {
	background: rgba(13, 22, 38, 0.78);
}

.dot-hero__inner {
	position: relative;
	max-width: var(--wp--style--global--wide-size, 1240px);
	margin-inline: auto;
	width: 100%;
}

.dot-hero__panel {
	max-width: 800px;
	color: var(--wp--preset--color--base);
}

.dot-hero__panel--boxed {
	background: var(--wp--preset--color--navy-deep);
	border-radius: var(--wp--custom--radius--lg);
	padding: clamp(24px, 3.5vw, 40px);
}

.dot-hero__title {
	font-size: var(--wp--preset--font-size--title);
	color: var(--wp--preset--color--base);
	margin: 0 0 14px;
	font-weight: 700;
	line-height: 1.12;
	text-wrap: pretty;
}

.dot-hero__text {
	font-size: var(--wp--preset--font-size--lg);
	line-height: 1.7;
	color: #dbe3ee;
	margin: 0 0 var(--wp--preset--spacing--40);
	max-width: 58ch;
	text-wrap: pretty;
}

/*
 * Links inside a dark hero panel. The global link colour is the brand blue,
 * which on the navy panel is nearly unreadable — go white and underline on
 * hover so the affordance survives.
 */
.dot-hero__panel a:not(.dot-btn):not(.dot-pill) {
	color: var(--wp--preset--color--base);
	font-weight: 600;
	text-decoration: none;
}

.dot-hero__panel a:not(.dot-btn):not(.dot-pill):hover,
.dot-hero__panel a:not(.dot-btn):not(.dot-pill):focus-visible {
	color: var(--wp--preset--color--base);
	text-decoration: underline;
}

.dot-hero--page {
	background: var(--wp--preset--color--navy-deep);
}

/*
 * The centred page hero: About, Industries, Locations and Contact.
 *
 * An 820px column centred in the viewport with centred text, rather than the
 * left-aligned 1240px treatment Services uses. Getting this wrong is the most
 * visible way a page can stop looking like the design.
 */
.dot-hero--centered .dot-hero__inner {
	max-width: 820px;
}

.dot-hero--centered .dot-hero__panel {
	max-width: none;
	text-align: center;
}

.dot-hero--centered .dot-hero__text {
	max-width: 60ch;
	margin-inline: auto;
}

/* Services keeps the panel to the left of a full 1240px container. */
.dot-hero--left .dot-hero__panel {
	max-width: 800px;
}

/* Jump-link pill row on the Services hero. */
.dot-pills {
	display: flex;
	gap: 10px;
	flex-wrap: wrap;
}

.dot-pill {
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border-strong);
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 600;
	padding: 8px 16px;
	border-radius: 20px;
	white-space: nowrap;
	text-decoration: none;
	transition: background var(--wp--custom--transition), border-color var(--wp--custom--transition);
}

.dot-pill:hover,
.dot-pill:focus-visible {
	background: var(--wp--preset--color--primary-tint);
	border-color: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--primary-dark);
	text-decoration: none;
}

/*
 * Below 700px the eight pills wrapped to five rows and pushed the CTA off
 * screen. A single scrollable row reads better and keeps the hero compact.
 */
@media (max-width: 700px) {
	.dot-pills {
		flex-wrap: nowrap;
		overflow-x: auto;
		scrollbar-width: none;
		padding-bottom: 4px;
		margin-inline: calc(var(--wp--custom--gutter) * -1);
		padding-inline: var(--wp--custom--gutter);
		scroll-snap-type: x proximity;
	}

	.dot-pills::-webkit-scrollbar {
		display: none;
	}

	.dot-pill {
		scroll-snap-align: start;
	}
}

/* ====================================================== 9. Home sections */

/*
 * The homepage is a stack of full-viewport scroll-snapping panels.
 *
 * Snapping is desktop-only and opt-in: on a phone, mandatory y-snap fights
 * the address bar collapsing and can strand content in panels taller than
 * the viewport. It is also disabled whenever the panel content is taller
 * than the screen, and for anyone who prefers reduced motion.
 */
/*
 * Snapping is `mandatory`, as the design had it. `proximity` is advisory and
 * browsers routinely ignore it on an ordinary wheel scroll, which makes the
 * effect look broken — and without the snap the reveal animation plays off
 * screen and is never seen.
 *
 * The media query is the whole safety mechanism: snap only where there is room
 * for a full-height panel, and never against a reduced-motion preference. On
 * anything smaller the page scrolls normally.
 */
@media (min-width: 901px) and (min-height: 640px) and (prefers-reduced-motion: no-preference) {
	/*
	 * Scoped to pages that actually have panels. Snapping turns itself off if
	 * the client ever removes them, and ordinary pages are never affected.
	 */
	html:has(.dot-panel) {
		scroll-snap-type: y mandatory;
	}

	.dot-panel {
		scroll-snap-align: start;
	}

	/*
	 * The footer needs a snap point of its own, or it is unreachable: the last
	 * panel's snap point is the nearest one to the end of the document, so a
	 * mandatory snap pulls straight back to it and the footer never shows.
	 *
	 * `end` rather than `start` — the footer is a few hundred pixels tall, so
	 * aligning its *top* to the viewport top asks the page to scroll further
	 * than it can. Aligning its bottom to the viewport bottom is exactly the
	 * end of the document, which is always reachable.
	 */
	.dot-footer {
		scroll-snap-align: end;
	}

	/*
	 * The header is sticky but still in flow, so the first panel starts one
	 * header-height down. Without this it becomes the nearest snap point at
	 * load and the browser scrolls the header out of view before the visitor
	 * has touched anything. JS publishes --dot-header-h; the fallback covers
	 * the moment before it runs.
	 */
	.dot-content > .dot-panel:first-child {
		scroll-margin-top: var(--dot-header-h, 70px);
	}
}

.dot-panel {
	position: relative;
	display: flex;
	align-items: center;
	overflow: hidden;
	isolation: isolate;
	padding-block: var(--wp--preset--spacing--70);
	padding-inline: var(--wp--custom--gutter);
	/*
	 * Full-bleed panels butt directly against one another. The editor's block
	 * rhythm would otherwise put a margin between them, which shows as a white
	 * strip across each seam and offsets every snap point by that much.
	 */
	margin-block: 0;
	/*
	 * svh, not vh: on mobile browsers vh is the *largest* viewport height, so
	 * a 100vh panel is taller than the visible area whenever the address bar
	 * is showing. Also leaves room for the admin bar when logged in.
	 */
	min-height: calc(100svh - var(--dot-admin-bar));
}

.dot-panel--stack {
	flex-direction: column;
	justify-content: center;
	gap: var(--wp--preset--spacing--60);
}

.dot-panel__head {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	margin-bottom: var(--wp--preset--spacing--50);
	flex-wrap: wrap;
	gap: 12px;
}

.dot-panel__title {
	font-size: var(--wp--preset--font-size--section-lg);
	margin: 0;
	font-weight: 700;
}

/* ------------------------------------------------- reveal animations */

/*
 * The source fired these off a rounded scroll-position index, which misfires
 * on short viewports and on any resize. IntersectionObserver fires once when
 * the panel actually enters view.
 */
@keyframes dot-paper-feed {
	0% {
		clip-path: inset(0 0 100% 0);
		transform: translateY(90px) scale(0.98);
	}
	70% {
		clip-path: inset(0 0 0 0);
	}
	100% {
		clip-path: inset(0 0 0 0);
		transform: none;
	}
}

@keyframes dot-roller-sweep {
	0% {
		opacity: 0;
		transform: translateY(-16px) scaleX(0.7);
	}
	25% {
		opacity: 1;
		transform: translateY(0) scaleX(1);
	}
	55% {
		opacity: 0.6;
	}
	100% {
		opacity: 0;
	}
}

/*
 * Content is only ever hidden once JS has added .is-armed to it, which it
 * does one element at a time as it hands each to the observer. If the script
 * fails to load, throws, or the browser has no IntersectionObserver, nothing
 * is armed and everything simply renders. There is no state in which the
 * copy is invisible and nothing is coming to reveal it.
 */
.dot-reveal.is-armed {
	clip-path: inset(0 0 100% 0);
}

.dot-reveal.is-armed.is-visible {
	animation: dot-paper-feed 1.5s cubic-bezier(0.2, 0.7, 0.3, 1) forwards;
}

/*
 * The roller sweep: a light bar that crosses the top edge of the panel just
 * before the content feeds in, like a print head passing over paper.
 *
 * It is a pseudo-element on the panel rather than a div in the pattern, so it
 * spans the full panel width and sits on its top edge. As markup inside the
 * Cover block it was positioned against the 1240px inner container instead —
 * inset by the panel's padding and stopping short of both edges, which read as
 * a stray white line rather than a sweep.
 */
.dot-panel:has(.dot-reveal)::before {
	content: "";
	position: absolute;
	top: 0;
	inset-inline: 0;
	height: 4px;
	opacity: 0;
	z-index: 2;
	transform-origin: center;
	pointer-events: none;
	background: linear-gradient(90deg, transparent, var(--dot-roller-color, #fff) 50%, transparent);
	box-shadow: 0 0 16px 2px var(--dot-roller-glow, rgba(255, 255, 255, 0.6));
}

/* On the light panel the bar is brand blue, as the design had it. */
.dot-panel--light {
	--dot-roller-color: var(--wp--preset--color--primary);
	--dot-roller-glow: rgba(29, 78, 137, 0.4);
}

.dot-panel.is-visible::before {
	animation: dot-roller-sweep 1s ease-out forwards;
}

/* No JS: the roller never animates, so don't leave an invisible strip. */
html:not(.dot-js) .dot-panel::before {
	display: none;
}

@media (prefers-reduced-motion: reduce) {
	.dot-reveal,
	.dot-reveal.is-armed,
	.dot-reveal.is-armed.is-visible {
		clip-path: none;
		animation: none;
		transform: none;
	}

	.dot-panel::before {
		display: none;
	}
}

/* ------------------------------------------------------- dot navigator */

.dot-dots {
	position: fixed;
	right: 22px;
	top: 50%;
	transform: translateY(-50%);
	z-index: 30;
	display: none;
	flex-direction: column;
	gap: 14px;
}

.dot-dots a {
	display: block;
	width: 9px;
	height: 9px;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.35);
	border: 1px solid rgba(255, 255, 255, 0.6);
	transition: all var(--wp--custom--transition);
}

.dot-dots a:hover {
	background: rgba(255, 255, 255, 0.7);
}

.dot-dots a.is-active {
	background: #fff;
	transform: scale(1.3);
}

/*
 * The design had this pinned at the right edge at every width, where on a
 * phone it sits on top of the body copy. Desktop only.
 */
@media (min-width: 1100px) {
	.dot-dots {
		display: flex;
	}
}

/* ============================================================ 10. Footer */

.dot-footer {
	background: var(--wp--preset--color--navy-footer);
	color: #c9d0dc;
}

.dot-footer__grid {
	max-width: var(--wp--style--global--wide-size, 1240px);
	margin-inline: auto;
	padding: var(--wp--preset--spacing--60) var(--wp--custom--gutter) var(--wp--preset--spacing--50);
	display: grid;
	grid-template-columns: 1.4fr repeat(3, 1fr);
	gap: var(--wp--preset--spacing--50);
}

@media (max-width: 900px) {
	.dot-footer__grid {
		grid-template-columns: 1fr 1fr;
	}

	.dot-footer__brand {
		grid-column: 1 / -1;
	}
}

@media (max-width: 520px) {
	.dot-footer__grid {
		grid-template-columns: 1fr;
	}
}

.dot-footer__logo {
	height: 34px;
	width: auto;
	display: block;
	margin-bottom: 16px;
}

.dot-footer__blurb {
	font-size: var(--wp--preset--font-size--base);
	line-height: 1.6;
	color: #8b96a8;
	max-width: 40ch;
	margin: 0 0 16px;
}

.dot-footer__partners {
	font-size: var(--wp--preset--font-size--sm);
	color: #6b7688;
	margin: 0;
}

.dot-footer__heading {
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 600;
	color: var(--wp--preset--color--base);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	margin: 0 0 14px;
}

.dot-footer__list {
	display: flex;
	flex-direction: column;
	gap: 10px;
	list-style: none;
	margin: 0;
	padding: 0;
}

.dot-footer a {
	color: #c9d0dc;
	text-decoration: none;
	font-size: var(--wp--preset--font-size--base);
	transition: color var(--wp--custom--transition);
}

.dot-footer a:hover,
.dot-footer a:focus-visible {
	color: var(--wp--preset--color--base);
	text-decoration: none;
}

.dot-footer__offices {
	display: flex;
	flex-direction: column;
	gap: 4px;
	font-size: var(--wp--preset--font-size--base);
	margin-bottom: 14px;
}

.dot-footer__social {
	display: flex;
	gap: 14px;
}

.dot-footer__social a {
	color: #8b96a8;
	font-size: var(--wp--preset--font-size--sm);
}

.dot-footer__bar {
	border-top: 1px solid #232f42;
	max-width: var(--wp--style--global--wide-size, 1240px);
	margin-inline: auto;
	padding: 20px var(--wp--custom--gutter);
	display: flex;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 8px;
	font-size: var(--wp--preset--font-size--sm);
	color: #6b7688;
}

/* =========================================================== 11. Products */

.dot-breadcrumb {
	background: var(--wp--preset--color--surface);
	border-bottom: 1px solid var(--wp--preset--color--border);
	padding: 14px var(--wp--custom--gutter);
	font-size: var(--wp--preset--font-size--sm);
	color: var(--wp--preset--color--muted);
}

.dot-breadcrumb__inner {
	max-width: var(--wp--style--global--wide-size, 1240px);
	margin-inline: auto;
}

.dot-breadcrumb a {
	font-weight: 600;
	text-decoration: none;
}

.dot-breadcrumb .sep {
	color: #9aa3b0;
	margin-inline: 4px;
}

/*
 * The design's product card was `grid-template-columns: 380px 1fr`, which
 * overflows any viewport under ~420px. minmax with a percentage cap keeps
 * the image column proportional and lets it collapse cleanly.
 */
.dot-product-card {
	display: grid;
	grid-template-columns: 31% minmax(0, 1fr);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--lg);
	overflow: hidden;
	background: var(--wp--preset--color--base);
	text-decoration: none;
	color: inherit;
	transition: border-color var(--wp--custom--transition), box-shadow var(--wp--custom--transition);
}

.dot-product-card:hover,
.dot-product-card:focus-visible {
	border-color: var(--wp--preset--color--primary);
	box-shadow: var(--wp--preset--shadow--card);
	text-decoration: none;
}

@media (max-width: 860px) {
	.dot-product-card {
		grid-template-columns: 1fr;
	}
}

.dot-product-card__media {
	background: var(--wp--preset--color--surface);
	padding: clamp(20px, 5vw, 32px);
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 260px;
}

.dot-product-card__media--white {
	background: var(--wp--preset--color--base);
	border-right: 1px solid #f0f2f5;
}

@media (max-width: 860px) {
	.dot-product-card__media--white {
		border-right: 0;
		border-bottom: 1px solid #f0f2f5;
	}
}

.dot-product-card__media img {
	max-width: 100%;
	max-height: 220px;
	width: auto;
	object-fit: contain;
	/*
	 * multiply knocks out the white studio background on supplier photos.
	 * Only safe because the panel behind it is white or near-white.
	 */
	mix-blend-mode: multiply;
}

.dot-product-card__body {
	padding: clamp(24px, 3vw, 32px) clamp(24px, 3.2vw, 36px);
	display: flex;
	flex-direction: column;
	justify-content: center;
}

.dot-product-card__title {
	font-size: var(--wp--preset--font-size--subhead);
	color: var(--wp--preset--color--ink);
	margin: 0 0 10px;
	font-weight: 700;
}

.dot-product-card__text {
	font-size: var(--wp--preset--font-size--md);
	color: var(--wp--preset--color--muted);
	line-height: 1.7;
	margin: 0 0 20px;
	max-width: 62ch;
}

.dot-highlights {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--40);
	margin-bottom: 22px;
}

.dot-highlights__label {
	font-size: var(--wp--preset--font-size--xs);
	color: #8a929e;
	margin-bottom: 4px;
}

.dot-highlights__value {
	font-size: var(--wp--preset--font-size--base);
	font-weight: 600;
	color: var(--wp--preset--color--ink);
}

.dot-product-card__foot {
	display: flex;
	gap: 16px;
	align-items: center;
	flex-wrap: wrap;
}

.dot-product-card__note {
	font-size: var(--wp--preset--font-size--sm);
	color: var(--wp--preset--color--muted);
}

/* --------------------------------------------------- single product */

.dot-product-hero {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 360px), 1fr));
	gap: var(--wp--preset--spacing--60);
	align-items: start;
	max-width: var(--wp--style--global--wide-size, 1240px);
	margin-inline: auto;
}

.dot-product-figure {
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--lg);
	padding: clamp(20px, 3vw, 36px);
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: clamp(260px, 32vw, 380px);
	margin: 0;
}

.dot-product-figure--white {
	background: var(--wp--preset--color--base);
}

.dot-product-figure img {
	max-width: 100%;
	max-height: 400px;
	width: auto;
	object-fit: contain;
	mix-blend-mode: multiply;
}

.dot-product-gallery {
	display: flex;
	gap: 10px;
	flex-wrap: wrap;
	margin-top: 14px;
}

.dot-product-gallery button {
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--sm);
	background: var(--wp--preset--color--base);
	padding: 4px;
	width: 74px;
	height: 74px;
	cursor: pointer;
	transition: border-color var(--wp--custom--transition);
}

.dot-product-gallery button:hover,
.dot-product-gallery button[aria-current="true"] {
	border-color: var(--wp--preset--color--primary);
}

.dot-product-gallery img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	mix-blend-mode: multiply;
	display: block;
}

.dot-glance {
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--lg);
	padding: 24px;
	margin-bottom: var(--wp--preset--spacing--40);
}

.dot-glance__title {
	font-size: var(--wp--preset--font-size--base);
	color: var(--wp--preset--color--ink);
	margin: 0 0 14px;
	font-weight: 700;
}

.dot-glance__list {
	display: flex;
	flex-direction: column;
	gap: 10px;
	margin: 0;
}

.dot-glance__row {
	display: flex;
	justify-content: space-between;
	gap: 16px;
	font-size: var(--wp--preset--font-size--base);
}

.dot-glance__row dt {
	color: var(--wp--preset--color--muted);
	flex-shrink: 0;
}

.dot-glance__row dd {
	color: var(--wp--preset--color--ink);
	font-weight: 600;
	text-align: right;
	margin: 0;
}

/* Spec table — needs its own scroll container on narrow screens. */
.dot-specs-wrap {
	overflow-x: auto;
}

.dot-specs {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--wp--preset--font-size--base);
}

.dot-specs th,
.dot-specs td {
	padding: 14px 0;
	text-align: left;
	vertical-align: top;
	border-top: 1px solid var(--wp--preset--color--border);
}

.dot-specs tr:last-child td,
.dot-specs tr:last-child th {
	border-bottom: 1px solid var(--wp--preset--color--border);
}

.dot-specs th {
	color: var(--wp--preset--color--muted);
	font-weight: 400;
	width: 40%;
	padding-right: 20px;
}

.dot-specs td {
	color: var(--wp--preset--color--ink);
}

@media (max-width: 520px) {
	.dot-specs th {
		width: 45%;
	}
}

.dot-specs__note {
	font-size: var(--wp--preset--font-size--sm);
	color: #8a929e;
	line-height: 1.7;
	margin: 18px 0 0;
}

/* Acquisition option cards. */
.dot-acquisition {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
	gap: var(--wp--preset--spacing--40);
}

/* ============================================================ 12. Team */

.dot-team-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr));
	gap: var(--wp--preset--spacing--40);
}

.dot-team-card {
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	padding: 24px;
	text-align: center;
}

.dot-team-card__photo {
	width: 72px;
	height: 72px;
	border-radius: 50%;
	object-fit: cover;
	display: block;
	margin: 0 auto 14px;
	background: var(--wp--preset--color--surface);
}

.dot-team-card__photo--placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--lg);
	color: var(--wp--preset--color--muted-light);
	border: 1px dashed var(--wp--preset--color--border-strong);
}

.dot-team-card__name {
	font-size: var(--wp--preset--font-size--md);
	font-weight: 600;
	color: var(--wp--preset--color--ink);
}

.dot-team-card__role {
	font-size: var(--wp--preset--font-size--sm);
	color: var(--wp--preset--color--muted-light);
	margin-top: 4px;
}

.dot-team-card__bio {
	font-size: var(--wp--preset--font-size--sm);
	color: var(--wp--preset--color--muted);
	line-height: 1.6;
	margin: 12px 0 0;
}

.dot-team-card__contact {
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin-top: 14px;
	padding-top: 14px;
	border-top: 1px solid var(--wp--preset--color--border);
	font-size: var(--wp--preset--font-size--sm);
}

.dot-team-card__contact a {
	text-decoration: none;
	word-break: break-word;
}

/* =========================================================== 13. Answer box */

.dot-answer {
	background: var(--wp--preset--color--surface);
	border-radius: var(--wp--custom--radius--md);
	padding: clamp(20px, 5vw, 28px);
	border: 1px solid var(--wp--preset--color--border);
	align-self: start;
}

.dot-answer--white {
	background: var(--wp--preset--color--base);
}

.dot-answer__text {
	font-size: var(--wp--preset--font-size--base);
	color: var(--wp--preset--color--ink);
	line-height: 1.7;
	margin: 0;
}

/* ====================================================== 14. Testimonials */

.dot-quote {
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	padding: 24px;
	margin: 0;
}

.dot-quote--placeholder {
	border-style: dashed;
	border-color: var(--wp--preset--color--border-strong);
}

.dot-quote__text {
	font-size: var(--wp--preset--font-size--base);
	color: var(--wp--preset--color--muted);
	line-height: 1.6;
	margin: 0 0 14px;
	font-style: italic;
}

.dot-quote__cite {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--xs);
	color: var(--wp--preset--color--muted-light);
	font-style: normal;
}

/* ============================================================= 15. Forms */

.dot-form-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
	gap: var(--wp--preset--spacing--60);
	max-width: 1100px;
	margin-inline: auto;
	align-items: start;
}

/*
 * Fluent Forms ships its own stylesheet. These rules pull it onto the
 * theme's tokens rather than restyling every element from scratch.
 */
.dot-form .fluentform .ff-el-input--label label,
.dot-form .ff-el-input--label label {
	font-size: var(--wp--preset--font-size--base);
	font-weight: 600;
	color: var(--wp--preset--color--ink);
	margin-bottom: 6px;
}

.dot-form .fluentform input[type="text"],
.dot-form .fluentform input[type="email"],
.dot-form .fluentform input[type="tel"],
.dot-form .fluentform input[type="number"],
.dot-form .fluentform select,
.dot-form .fluentform textarea,
.dot-field-input {
	width: 100%;
	padding: 12px 14px;
	border: 1px solid var(--wp--preset--color--border-strong);
	border-radius: var(--wp--custom--radius--sm);
	font-size: var(--wp--preset--font-size--base);
	font-family: var(--wp--preset--font-family--sans);
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--ink);
	line-height: 1.5;
	box-shadow: none;
	transition: border-color var(--wp--custom--transition), box-shadow var(--wp--custom--transition);
}

.dot-form .fluentform input:focus,
.dot-form .fluentform select:focus,
.dot-form .fluentform textarea:focus {
	border-color: var(--wp--preset--color--primary);
	box-shadow: 0 0 0 3px rgba(29, 78, 137, 0.12);
	outline: none;
}

.dot-form .fluentform textarea {
	resize: vertical;
	min-height: 110px;
}

.dot-form .fluentform .ff-btn-submit,
.dot-form .fluentform button[type="submit"] {
	background: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--base);
	border: 0;
	font-size: var(--wp--preset--font-size--md);
	font-weight: 600;
	font-family: var(--wp--preset--font-family--sans);
	padding: 14px 26px;
	border-radius: var(--wp--custom--radius--sm);
	cursor: pointer;
	transition: background var(--wp--custom--transition);
}

.dot-form .fluentform .ff-btn-submit:hover,
.dot-form .fluentform button[type="submit"]:hover {
	background: var(--wp--preset--color--primary-dark);
}

.dot-form .fluentform .ff-message-success,
.dot-form .ff_submit_success {
	background: var(--wp--preset--color--primary-tint);
	border: 1px solid var(--wp--preset--color--border-strong);
	border-radius: var(--wp--custom--radius--md);
	padding: 24px;
	font-size: var(--wp--preset--font-size--base);
	color: var(--wp--preset--color--ink);
}

.dot-form .fluentform .ff-el-is-error .text-danger,
.dot-form .fluentform .error {
	font-size: var(--wp--preset--font-size--sm);
	color: #b32d2e;
}

/* Fallback form, used if Fluent Forms is not active. */
.dot-fallback-form {
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.dot-fallback-form__row {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
	gap: 16px;
}

.dot-form-aside {
	display: flex;
	flex-direction: column;
	gap: 20px;
}

.dot-form-aside__card {
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	padding: clamp(20px, 5vw, 26px);
}

.dot-form-aside__product {
	display: flex;
	gap: 16px;
	align-items: center;
}

.dot-form-aside__thumb {
	width: 84px;
	height: 84px;
	background: var(--wp--preset--color--surface);
	border-radius: var(--wp--custom--radius--md);
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	padding: 4px;
}

.dot-form-aside__thumb img {
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
	mix-blend-mode: multiply;
}

.dot-form-aside__name {
	font-size: var(--wp--preset--font-size--md);
	font-weight: 700;
	color: var(--wp--preset--color--ink);
	margin-bottom: 4px;
}

.dot-form-aside__sub {
	font-size: var(--wp--preset--font-size--sm);
	color: var(--wp--preset--color--muted);
}

.dot-form-aside__heading {
	font-size: var(--wp--preset--font-size--md);
	font-weight: 600;
	margin: 0 0 10px;
}

.dot-form-aside__text {
	font-size: var(--wp--preset--font-size--base);
	color: var(--wp--preset--color--muted);
	line-height: 1.7;
	margin: 0;
}

.dot-form-aside__text a {
	font-weight: 600;
}

/* ======================================================= 16. Block editor */

/*
 * Page content is authored in Gutenberg. These give the core blocks the
 * design's rhythm without the editor needing to set anything.
 */
.dot-content > * {
	margin-block: var(--wp--preset--spacing--40);
}

/* …except full-bleed panels and sections, which set their own spacing. */
.dot-content > .dot-panel,
.dot-content > .dot-section {
	margin-block: 0;
}

.dot-content > :first-child {
	margin-block-start: 0;
}

.dot-content > :last-child {
	margin-block-end: 0;
}

.dot-content > h2 {
	margin-block-start: var(--wp--preset--spacing--60);
}

.dot-content > h3 {
	margin-block-start: var(--wp--preset--spacing--50);
}

/*
 * Page content is wrapped in .dot-content, so a bare `.dot-content p` rule
 * outranks every single-class component rule inside it (.dot-card__text,
 * .dot-hero__text, .dot-eyebrow …) and repaints them all muted. These are
 * scoped to elements that carry no dot- class of their own, so they style
 * the editor's plain prose and nothing else.
 */
.dot-content :where(ul, ol):not([class*="dot-"]) {
	padding-left: 20px;
	color: var(--wp--preset--color--muted);
}

.dot-content :where(li) {
	margin-block: 0.35em;
}

.dot-content :where(li) strong {
	color: var(--wp--preset--color--ink);
}

.dot-content :where(p):not([class*="dot-"]):not([class*="has-"]) {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--md);
}

.dot-content table {
	width: 100%;
	border-collapse: collapse;
}

/* ============================================================== 17. Misc */

.dot-notice {
	background: #fff8e5;
	border: 1px solid #f0c33c;
	border-radius: var(--wp--custom--radius--md);
	padding: 20px 24px;
	font-size: var(--wp--preset--font-size--base);
	color: #674e00;
}

.dot-notice code {
	font-family: var(--wp--preset--font-family--mono);
	background: rgba(0, 0, 0, 0.06);
	padding: 1px 5px;
	border-radius: 3px;
}

.dot-empty {
	border: 1px dashed var(--wp--preset--color--border-strong);
	border-radius: var(--wp--custom--radius--md);
	padding: clamp(20px, 5vw, 32px);
	text-align: center;
	color: var(--wp--preset--color--muted-light);
	font-size: var(--wp--preset--font-size--md);
}

.dot-pagination {
	display: flex;
	gap: 8px;
	justify-content: center;
	margin-top: var(--wp--preset--spacing--60);
	flex-wrap: wrap;
}

.dot-pagination .page-numbers {
	padding: 8px 14px;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--sm);
	text-decoration: none;
	font-size: var(--wp--preset--font-size--base);
}

.dot-pagination .page-numbers.current {
	background: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--base);
	border-color: var(--wp--preset--color--primary);
}

/* Brand partner tiles. */
.dot-brands {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
	gap: var(--wp--preset--spacing--40);
	text-align: center;
}

.dot-brand-tile {
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	padding: clamp(20px, 5vw, 28px);
}

.dot-brand-tile__name {
	font-size: var(--wp--preset--font-size--xl);
	font-weight: 700;
	color: var(--wp--preset--color--ink);
}

.dot-brand-tile__note {
	font-size: var(--wp--preset--font-size--sm);
	color: var(--wp--preset--color--muted-light);
	margin-top: 6px;
}

/* Location cards. */
.dot-location-card {
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--lg);
	overflow: hidden;
	display: flex;
	flex-direction: column;
}

.dot-location-card__media img {
	width: 100%;
	height: 160px;
	object-fit: cover;
	display: block;
}

.dot-location-card__body {
	padding: 24px;
}
