/* ==========================================================================
   Espie — brand stylesheet.

   Named block styles + section treatments. Loaded on the front end AND as the
   editor stylesheet, so the client edits against the real look.

   Every value here resolves to a theme.json preset (which is generated 1:1 from the
   DS tokens by build/gen_theme_json.py). The handful of literals below are DS values
   that have no palette slug — each is commented with its DS source line.

   Rule: no colour, size or spacing may be typed as a raw value without that citation.

   GOTCHA: WordPress kebab-cases preset slugs when it builds the CSS custom properties,
   inserting a hyphen at every digit->letter boundary. The theme.json slug `2xs` becomes
   `--wp--preset--font-size--2-xs`, `2xl` becomes `--2-xl`, and so on. Referencing the
   un-hyphenated name yields an UNDEFINED variable, which fails silently by inheriting
   whatever the parent had — it does not error. Spacing slugs (1..11) are unaffected
   because they are digits only.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Semantic context

   The DS re-points --surface-*, --text-* and --border-* under [data-theme="dark"].
   Part 7 says to mirror that rather than hardcode white text per element, so the
   same authoring model is reproduced here over theme.json presets.
   -------------------------------------------------------------------------- */
:root {
	--espie-surface-card:   var(--wp--preset--color--white);
	--espie-surface-sunken: var(--wp--preset--color--gray-100);

	--espie-text-strong: var(--wp--preset--color--ink);
	--espie-text-body:   var(--wp--preset--color--gray-800);
	--espie-text-muted:  var(--wp--preset--color--gray-600);
	--espie-text-lead:   var(--wp--preset--color--gray-700);

	--espie-border-subtle:  var(--wp--preset--color--gray-200);
	--espie-border-default: var(--wp--preset--color--gray-300);
	--espie-border-strong:  var(--wp--preset--color--gray-400);

	--espie-accent:        var(--wp--preset--color--orange);
	--espie-accent-hover:  var(--wp--preset--color--orange-hover);
	--espie-accent-active: var(--wp--preset--color--orange-press);
	--espie-chip-bg:       var(--wp--preset--color--orange-tint);

	/* DS tokens/spacing.css — radii, borders, motion. */
	--espie-radius-xs: 2px;
	--espie-radius-sm: 4px;
	--espie-radius-md: 8px;
	--espie-radius-lg: 12px;
	--espie-radius-pill: 999px;
	--espie-border-hair: 1px;
	--espie-border-thin: 1.5px;
	--espie-border-bold: 2px;
	--espie-border-accent-w: 3px;
	--espie-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
	--espie-dur-fast: 120ms;
	--espie-dur-base: 180ms;
	--espie-dur-slow: 300ms;

	/* DS tokens/typography.css — tracking. */
	--espie-tracking-wide: 0.04em;
	--espie-tracking-overline: 0.18em;

	/* DS tokens/colors.css — focus ring. */
	--espie-focus-ring: 0 0 0 3px rgba(255, 58, 2, .35);
}

/* Dark context.

   Three selectors, deliberately:
   - `.espie-dark`  — a plain class, for elements that are dark by design and already
     carry a block style (a block may hold only ONE is-style-* class, so a dark CARD
     has to be `is-style-card espie-dark`, not two block styles).
   - `.is-style-dark` — the client-facing Group toggle in the editor sidebar.
   - `[data-theme="dark"]` — the DS's own attribute, so markup lifted from the demo
     behaves identically without rewriting. */
.espie-dark,
.is-style-dark,
[data-theme="dark"] {
	--espie-surface-card:   var(--wp--preset--color--ink);
	/* DS colors.css [data-theme="dark"] --surface-sunken — no palette slug. */
	--espie-surface-sunken: #161617;

	--espie-text-strong: var(--wp--preset--color--white);
	--espie-text-body:   var(--wp--preset--color--gray-200);
	--espie-text-muted:  var(--wp--preset--color--gray-400);
	--espie-text-lead:   var(--wp--preset--color--gray-300);

	/* DS colors.css [data-theme="dark"] border ramp. */
	--espie-border-subtle:  rgba(255, 255, 255, .08);
	--espie-border-default: rgba(255, 255, 255, .14);
	--espie-border-strong:  rgba(255, 255, 255, .24);
	--espie-chip-bg:        rgba(255, 255, 255, .07);

	color: var(--espie-text-strong);
}

.espie-dark :where(h1, h2, h3, h4, h5, h6),
.is-style-dark :where(h1, h2, h3, h4, h5, h6),
[data-theme="dark"] :where(h1, h2, h3, h4, h5, h6) {
	color: var(--espie-text-strong);
}

/* --------------------------------------------------------------------------
   2. Named block styles  (Part 5 "Named styles")
   -------------------------------------------------------------------------- */

/* Eyebrow — the brand's signature letterspaced caps.
   Tracking is .18em (DS --tracking-overline, matched by the demo). Part 5 prose says
   .2em; the DS is the canonical source per Part 5's own note. */
.is-style-eyebrow {
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 600;
	line-height: 1.2;
	letter-spacing: var(--espie-tracking-overline);
	text-transform: uppercase;
	color: var(--espie-accent);
	margin-bottom: var(--wp--preset--spacing--3);
}

/* Lead — intro paragraph. */
.is-style-lead {
	font-size: var(--wp--preset--font-size--lg);
	line-height: 1.55;
	color: var(--espie-text-lead);
}

/* Stat — the big numeral on the split-feature badge.
   Typography only: colour comes from the badge context (white on orange in the demo),
   so the same style also works as orange-on-light where Part 5 describes it. */
.is-style-stat {
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--4-xl);
	font-weight: 800;
	line-height: .9;
	letter-spacing: -0.01em;
	text-transform: uppercase;
	margin: 0;
}

/* Code / metadata — step numerals, card footers. */
.is-style-code {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--2-xs);
	font-weight: 500;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--espie-accent);
	margin: 0;
}

/* Badge — compact label chip. Mirrors DS Badge.jsx `accent` variant.

   Stays inline-flex (its natural form). A narrow element cannot be left-aligned inside
   a constrained-layout parent by margins alone — core centres it, and forcing
   `margin-inline: 0 auto` only moves it to the CONTAINER edge, not the content-width
   edge. So where the badge must line up with a headline it is wrapped in a group, and
   the group takes the content width. See espie/hero-slideshow. */
.is-style-badge {
	display: inline-flex;
	align-items: center;
	gap: var(--wp--preset--spacing--1);
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--wp--preset--font-size--2-xs);
	font-weight: 600;
	line-height: 1;
	letter-spacing: var(--espie-tracking-wide);
	text-transform: uppercase;
	padding: .36em .66em;
	border-radius: var(--espie-radius-xs);
	background: var(--espie-accent);
	color: var(--wp--preset--color--white);
	margin: 0;
}

/* Check list — the hero card's uppercase ticked list. The marker is a CSS mask of the
   Lucide `check` glyph, so no list-item needs a Custom HTML block. */
.is-style-check {
	list-style: none;
	padding-left: 0;
	margin: 0;
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--3);
}

.is-style-check li {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--3);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 600;
	letter-spacing: var(--espie-tracking-wide);
	text-transform: uppercase;
	color: var(--espie-text-body);
}

.is-style-check li::before {
	content: "";
	flex: none;
	width: 16px;
	height: 16px;
	background-color: var(--espie-accent);
	/* Lucide `check` — same path as inc/icons.php, as a mask so it inherits colour. */
	-webkit-mask: var(--espie-check-mask) center / contain no-repeat;
	mask: var(--espie-check-mask) center / contain no-repeat;
}

/* Glyph masks live in the generated espie-icon-masks.css (build/gen_icons.py),
   enqueued ahead of this file. */
/* --------------------------------------------------------------------------
   3. Cards  (mirrors DS components/core/Card.jsx)
   -------------------------------------------------------------------------- */
.is-style-card,
.is-style-card-interactive,
.is-style-card-featured {
	position: relative;
	background: var(--espie-surface-card);
	border: var(--espie-border-hair) solid var(--espie-border-subtle);
	border-radius: var(--espie-radius-lg);
	box-shadow: var(--wp--preset--shadow--sm);
	color: var(--espie-text-body);
	transition:
		box-shadow var(--espie-dur-base) var(--espie-ease-out),
		transform var(--espie-dur-base) var(--espie-ease-out),
		border-color var(--espie-dur-base) var(--espie-ease-out);
}

.is-style-card-interactive:hover,
.is-style-card-interactive:focus-within {
	box-shadow: var(--wp--preset--shadow--lg);
	transform: translateY(-3px);
	border-color: var(--espie-border-default);
}

/* Featured card — 2px orange border, raised, and the badge sits astride the top edge.
   Positioning lives here rather than inline on the block (Part 1 rule 2). */
.is-style-card-featured {
	border: var(--espie-border-bold) solid var(--espie-accent);
	box-shadow: var(--wp--preset--shadow--lg);
	overflow: visible;
}

.is-style-card-featured > .is-style-badge {
	position: absolute;
	top: -11px;
	left: 50%;
	transform: translateX(-50%);
	z-index: 1;
}

/* Card footer rule — the mono caption under a hairline. */
.espie-card__meta {
	margin-top: auto;
	padding-top: var(--wp--preset--spacing--4);
	border-top: var(--espie-border-hair) solid var(--espie-border-subtle);
}

/* --------------------------------------------------------------------------
   4. Icon chips  (rendered by espie_icon_chip() in inc/icons.php)
   -------------------------------------------------------------------------- */
.espie-icon {
	display: block;
	flex: none;
}

.espie-chip {
	display: grid;
	place-items: center;
	flex: none;
	width: var(--espie-chip-size, 46px);
	height: var(--espie-chip-size, 46px);
	border-radius: var(--espie-radius-md);
	color: var(--espie-accent);
}

.espie-chip--soft  { background: var(--wp--preset--color--orange-tint); }
.espie-chip--ink   { background: var(--wp--preset--color--ink); }
.espie-chip--glass { background: var(--espie-chip-bg); }
.espie-chip--plain { background: none; }

/* Outlined chip used beside the split-feature and contact rows. */
.espie-chip--outline {
	background: var(--espie-surface-card);
	border: var(--espie-border-hair) solid var(--espie-border-subtle);
}

/* --------------------------------------------------------------------------
   5. Buttons  (mirrors DS components/core/Button.jsx)

   theme.json already styles the default (solid orange primary). These are the
   two other variants plus the dark-context handling.
   -------------------------------------------------------------------------- */
.wp-block-button__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--wp--preset--spacing--2);
	border: var(--espie-border-thin) solid transparent;
	white-space: nowrap;
	transition:
		background var(--espie-dur-fast) var(--espie-ease-out),
		color var(--espie-dur-fast) var(--espie-ease-out),
		transform var(--espie-dur-fast) var(--espie-ease-out),
		box-shadow var(--espie-dur-fast) var(--espie-ease-out),
		border-color var(--espie-dur-fast) var(--espie-ease-out);
}

.wp-block-button__link:active { transform: translateY(1px); }

.wp-block-button__link:focus-visible {
	outline: none;
	box-shadow: var(--espie-focus-ring);
}

/* Secondary — ink fill. */
.wp-block-button.is-style-secondary .wp-block-button__link {
	background-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--white);
	box-shadow: none;
}

.wp-block-button.is-style-secondary .wp-block-button__link:hover {
	background-color: var(--wp--preset--color--gray-800);
	box-shadow: none;
}

/* Outline — core's own style, restyled to DS spec.

   Core ships `is-style-outline` with its own `padding: .667em 1.333em` and a 2px border,
   which override theme.json's elements.button values. At the theme's 14px button text
   that computes to 9.3px/18.6px and a 35px-tall control — noticeably smaller than every
   other button on the page. Restate padding and border width so the outline variant
   matches the primary exactly. */
.wp-block-button.is-style-outline > .wp-block-button__link,
.wp-block-button .wp-block-button__link.is-style-outline {
	padding: 18px var(--wp--preset--spacing--6);
	border-width: var(--espie-border-thin);
	border-style: solid;
}

.wp-block-button.is-style-outline .wp-block-button__link {
	background-color: transparent;
	color: var(--espie-text-strong);
	border-color: var(--espie-border-strong);
	box-shadow: none;
}

.wp-block-button.is-style-outline .wp-block-button__link:hover {
	background-color: transparent;
	border-color: var(--espie-accent);
	color: var(--espie-accent);
	box-shadow: none;
}

/* The secondary action on a hero photo or an accent band gets a real fill rather than a
   transparent outline. A hairline button sitting next to a solid one reads as unfinished,
   and over photography a transparent fill leaves the label competing with whatever is
   behind it. `is-style-outline` stays a true outline in light contexts — only these two
   dark/accent surfaces take a fill. Part 5's "one orange action per view" still holds:
   the filled secondary is ink or white, never a second orange. */

/* Hero — ink fill against the orange primary, with a light edge so it separates from
   the darker parts of the photograph. */
.espie-hero .wp-block-button.is-style-outline .wp-block-button__link {
	background-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--white);
	border-color: rgba(255, 255, 255, .45);
}

.espie-hero .wp-block-button.is-style-outline .wp-block-button__link:hover {
	background-color: var(--wp--preset--color--white);
	border-color: var(--wp--preset--color--white);
	color: var(--espie-accent);
}

/* Accent band — white fill, orange label. The primary there is already ink, so this
   gives two solid buttons that still read as primary and secondary. */
.espie-band--accent .wp-block-button.is-style-outline .wp-block-button__link {
	background-color: var(--wp--preset--color--white);
	color: var(--espie-accent);
	border-color: var(--wp--preset--color--white);
}

.espie-band--accent .wp-block-button.is-style-outline .wp-block-button__link:hover {
	background-color: var(--wp--preset--color--ink);
	border-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--white);
}

/* --------------------------------------------------------------------------
   6. Section treatments
   -------------------------------------------------------------------------- */

/* The 5px orange left edge on dark page headers and the hero.
   A plain class, deliberately NOT a registered block style: these sections already
   carry `is-style-dark`, and WordPress lets a block hold only one selected style —
   registering both would make choosing one silently drop the other. The edge is
   intrinsic to these sections, not something the client should toggle. */
.espie-hero,
.espie-page-header {
	position: relative;
}

.espie-hero::before,
.espie-page-header::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0;
	bottom: 0;
	width: 5px;
	background: var(--espie-accent);
	pointer-events: none;
	z-index: 2;
}

/* Numbered process step — rule on top, orange on the first. */
.is-style-step {
	border-top: var(--espie-border-accent-w) solid var(--espie-border-subtle);
	padding-top: var(--wp--preset--spacing--5);
}

.is-style-step.espie-step--current {
	border-top-color: var(--espie-accent);
}

/* Full-width accent band (CTA). */
.espie-band--accent {
	background: var(--espie-accent);
	color: var(--wp--preset--color--white);
}

.espie-band--accent :where(h1, h2, h3, p) {
	color: var(--wp--preset--color--white);
}

.espie-band--accent .is-style-lead {
	color: rgba(255, 255, 255, .92);
}

/* Short accent rule used beside section headers. */
.espie-rule {
	width: 64px;
	height: 4px;
	background: var(--espie-accent);
	border: 0;
	margin: 0;
}

/* --------------------------------------------------------------------------
   7. Hero slideshow  (Part 7 "Hero slideshow — agreed build spec")

   Slides are stacked core/cover blocks. The script only toggles .is-active and
   builds the dots; all presentation is here.
   -------------------------------------------------------------------------- */
.espie-hero {
	position: relative;
	display: flex;
	align-items: center;
	min-height: 620px;
	overflow: hidden;
	background: var(--wp--preset--color--ink);
}

.espie-hero__slides {
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
}

.espie-hero__slide {
	position: absolute;
	inset: 0;
	opacity: 0;
	transition: opacity 1.1s var(--espie-ease-out);
}

/* Slide 1 carries .is-active in the saved markup, so with no JS the hero still
   shows a photo (Part 7: "Degrade with no JS"). */
.espie-hero__slide.is-active {
	opacity: 1;
}

/* Ken Burns rides on the image only, never the overlay or the copy. */
.espie-hero__slide .wp-block-cover__image-background {
	animation: espieHeroZoom 20s ease-in-out infinite alternate;
}

@keyframes espieHeroZoom {
	from { transform: scale(1.001); }
	to   { transform: scale(1.08); }
}

.espie-hero__content {
	position: relative;
	z-index: 2;
	width: 100%;
}

/* Copy widths from the demo (h1 760, lead 540). Not cosmetic: Part 5 requires the hero
   copy to sit over the dark left third of the photo, and full-width text runs out into
   the bright side of the scrim where white type stops being readable. */
.espie-hero__content h1 {
	max-width: 760px;
	text-wrap: balance;
}

.espie-hero__content .is-style-lead {
	max-width: 540px;
}

/* ---- Leading-edge pin -------------------------------------------------------------
   Core's constrained layout centres ANY child narrower than the content width:

     .is-layout-constrained > :where(...) { margin-left: auto !important; ... }

   The !important means plain margins lose, so a narrow element cannot be left-aligned
   without matching it. This has caught three separate things now — the icon chip, and
   both hero copy widths — so every case lives in this one list instead of the override
   being scattered around and rediscovered each time.

   Where the markup allows it, the better fix is a flow-layout wrapper (see
   .espie-hero__copy below) — flow children lay out from the leading edge naturally and
   need no override. The chip cannot use that: it sits directly inside card groups whose
   constrained layout is doing useful work for the text around it. */
.espie-chip {
	margin-inline-start: 0 !important;
	margin-inline-end: auto !important;
}

/* The hero copy avoids that override entirely: .espie-hero__copy is a FLOW-layout group
   sitting inside the constrained one, so it takes the 1200px content width and centres,
   and its own children then lay out from its leading edge with ordinary margins. That is
   the general escape hatch — put a flow group inside the constrained one — and it is
   preferable to fighting the !important wherever the markup allows a wrapper. */
.espie-hero__copy {
	width: 100%;
}

.espie-hero__dots {
	position: absolute;
	right: var(--wp--preset--spacing--6);
	bottom: var(--wp--preset--spacing--5);
	display: flex;
	gap: var(--wp--preset--spacing--2);
	z-index: 3;
}

.espie-hero__dot {
	height: 5px;
	width: 11px;
	padding: 0;
	border: none;
	border-radius: var(--espie-radius-pill);
	background: rgba(255, 255, 255, .45);
	cursor: pointer;
	transition: width var(--espie-dur-slow) var(--espie-ease-out),
		background var(--espie-dur-slow) var(--espie-ease-out);
}

.espie-hero__dot[aria-current="true"] {
	width: 30px;
	background: var(--espie-accent);
}

.espie-hero__dot:focus-visible {
	outline: none;
	box-shadow: var(--espie-focus-ring);
}

/* Part 7: reduced motion kills auto-advance AND Ken Burns; dots stay functional. */
@media (prefers-reduced-motion: reduce) {
	.espie-hero__slide {
		transition-duration: 1ms;
	}

	.espie-hero__slide .wp-block-cover__image-background {
		animation: none;
	}
}

/* --------------------------------------------------------------------------
   8. Split feature — image with the stat badge sitting inside it.

   Part 2 ❌ bans badges hanging OFF a photo's edge; this one sits INSIDE the
   image, which is the sanctioned core/cover treatment.
   -------------------------------------------------------------------------- */
.espie-stat-badge {
	background: var(--espie-accent);
	color: var(--wp--preset--color--white);
	padding: var(--wp--preset--spacing--5) var(--wp--preset--spacing--6);
}

.espie-stat-badge :where(p, h1, h2, h3, h4, h5, h6) {
	color: var(--wp--preset--color--white);
	margin: 0;
}

.espie-stat-badge .is-style-eyebrow {
	color: var(--wp--preset--color--white);
	margin-top: 4px;
	margin-bottom: 0;
	font-size: var(--wp--preset--font-size--2-xs);
}

/* --------------------------------------------------------------------------
   9. Header / footer
   -------------------------------------------------------------------------- */

/* Root-level blockGap put 24px between the header, main and footer, which rendered as
   a pale band above the hero and below the CTA band — the page background showing
   through between two dark sections. Sections carry their own vertical padding, so the
   site-level children should butt together. Scoped to direct children of .wp-site-blocks
   so blockGap inside page content is untouched. */
.wp-site-blocks > * {
	margin-block-start: 0;
	margin-block-end: 0;
}
.espie-header {
	position: sticky;
	top: 0;
	z-index: 50;
	background: var(--wp--preset--color--ink);
	border-bottom: var(--espie-border-hair) solid var(--espie-border-subtle);
}

.espie-header .wp-block-navigation {
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 600;
	letter-spacing: var(--espie-tracking-wide);
	text-transform: uppercase;
}

.espie-header .wp-block-navigation a:where(:not(.wp-element-button)) {
	color: rgba(255, 255, 255, .82);
	text-decoration: none;
}

.espie-header .wp-block-navigation a:where(:not(.wp-element-button)):hover,
.espie-header .wp-block-navigation .current-menu-item > a {
	color: var(--espie-accent);
}

.espie-header__phone {
	display: inline-flex;
	align-items: center;
	gap: var(--wp--preset--spacing--2);
	color: var(--wp--preset--color--white);
	font-weight: 600;
	font-size: var(--wp--preset--font-size--md);
	letter-spacing: var(--espie-tracking-wide);
	white-space: nowrap;
	text-decoration: none;
}

.espie-header__phone:hover { color: var(--espie-accent); }
.espie-header__phone .espie-icon { color: var(--espie-accent); }

.espie-footer {
	background: var(--wp--preset--color--ink-deep);
	color: var(--wp--preset--color--white);
}

.espie-footer a:where(:not(.wp-element-button)) {
	color: var(--wp--preset--color--gray-300);
	text-decoration: none;
}

.espie-footer a:where(:not(.wp-element-button)):hover { color: var(--espie-accent); }

.espie-footer__label {
	font-size: var(--wp--preset--font-size--2-xs);
	letter-spacing: var(--espie-tracking-overline);
	text-transform: uppercase;
	color: var(--wp--preset--color--gray-600);
	margin-bottom: var(--wp--preset--spacing--4);
}

/* The divisions list reads as plain lines in the design, not a bulleted list. */
.espie-footer__divisions {
	list-style: none;
	padding-left: 0;
	margin: 0;
}

/* Division logos on the ecosystem cards are sized by HEIGHT, not width: the three
   marks have different aspect ratios, so a common width would render them at
   visibly different optical sizes. */
.espie-card__logo {
	margin: 0 0 var(--wp--preset--spacing--5);
	display: flex;
	align-items: center;
	min-height: 46px;
}

.espie-card__logo img {
	height: 38px;
	width: auto;
	max-width: 100%;
}

.espie-footer__legal {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--xs);
	color: var(--wp--preset--color--gray-600);
	border-top: var(--espie-border-hair) solid var(--espie-border-subtle);
}

/* --------------------------------------------------------------------------
   10. Responsive

   Part 5 keeps the hero's left third dark and uncluttered; on narrow screens the
   scrim can't do that, so the copy gets its own backdrop from the Cover overlay.
   -------------------------------------------------------------------------- */
@media (max-width: 781px) {
	.espie-hero {
		min-height: 520px;
	}

	.espie-hero__dots {
		right: 50%;
		transform: translateX(50%);
	}

	.espie-stat-badge {
		padding: var(--wp--preset--spacing--4) var(--wp--preset--spacing--5);
	}
}

/* --------------------------------------------------------------------------
   11. Gravity Forms  (Part 1 rule 4 — a plugin supplying a widget, not the foundation)

   GF 3.x renders with its "Orbital" theme framework, which exposes a documented CSS
   custom-property API. Styling through those properties rather than overriding GF's
   selectors means no specificity war, no !important, and it survives plugin updates.
   Variable names below were read off the rendered form, not guessed.

   Selector note: GF declares these across three stacked layers (foundation, framework,
   orbital), all enqueued AFTER the theme's stylesheet, and the orbital layer redeclares
   several at (0,3,0) — measured, not assumed: with three classes the SIZE vars landed
   but the COLOUR vars did not, because orbital redeclares the colours at matching
   specificity and loads last. Four classes (0,4,0) wins both. GF applies the properties
   themselves at (0,13,0) via internal --gf-local-* vars, so overriding properties
   directly does not work; the API variables are the only supported route.

   Target: the DS Input/Select components (components/forms/*.jsx).
   -------------------------------------------------------------------------- */
.gform_wrapper.gform-theme.gform-theme--framework.gform-theme--orbital {
	/* Controls — DS .eg-input */
	--gf-ctrl-bg-color: var(--wp--preset--color--white);
	--gf-ctrl-bg-color-focus: var(--wp--preset--color--white);
	--gf-ctrl-bg-color-hover: var(--wp--preset--color--white);
	--gf-ctrl-color: var(--wp--preset--color--ink);
	--gf-ctrl-color-focus: var(--wp--preset--color--ink);
	--gf-ctrl-color-hover: var(--wp--preset--color--ink);
	--gf-ctrl-border-color: var(--wp--preset--color--gray-300);
	--gf-ctrl-border-color-hover: var(--wp--preset--color--gray-400);
	--gf-ctrl-border-color-focus: var(--espie-accent);
	--gf-ctrl-border-color-error: var(--espie-danger);
	--gf-ctrl-border-width: var(--espie-border-thin);
	--gf-ctrl-radius: var(--espie-radius-sm);
	--gf-ctrl-size-md: 42px;
	--gf-ctrl-size-lg: 42px;
	--gf-ctrl-font-size: var(--wp--preset--font-size--sm);
	--gf-ctrl-padding-x: var(--wp--preset--spacing--3);
	--gf-ctrl-accent-color: var(--espie-accent);

	/* Labels — DS .eg-field__label */
	--gf-ctrl-label-color-primary: var(--espie-text-muted);
	--gf-ctrl-label-color-secondary: var(--espie-text-muted);
	--gf-ctrl-label-color-tertiary: var(--espie-text-muted);
	--gf-ctrl-label-color-quaternary: var(--espie-text-muted);
	--gf-ctrl-label-font-size-primary: var(--wp--preset--font-size--2-xs);
	--gf-ctrl-label-font-weight-primary: 600;
	--gf-ctrl-label-color-req: var(--espie-accent);

	/* Submit — DS .eg-btn--primary at size lg */
	--gf-ctrl-btn-bg-color-primary: var(--espie-accent);
	--gf-ctrl-btn-bg-color-hover-primary: var(--espie-accent-hover);
	--gf-ctrl-btn-bg-color-focus-primary: var(--espie-accent-hover);
	--gf-ctrl-btn-color-primary: var(--wp--preset--color--white);
	--gf-ctrl-btn-radius: var(--espie-radius-sm);
	--gf-ctrl-btn-size-md: 52px;
	--gf-ctrl-btn-size-lg: 52px;
	--gf-ctrl-btn-font-size: var(--wp--preset--font-size--sm);
	--gf-ctrl-btn-font-weight: 600;
	--gf-ctrl-btn-padding-x: var(--wp--preset--spacing--6);

	/* Rhythm — the demo spaces fields on the 4px scale */
	--gf-ctrl-btn-text-transform: uppercase;
	--gf-ctrl-btn-letter-spacing: var(--espie-tracking-wide);
	--gf-ctrl-btn-font-family: var(--wp--preset--font-family--sans);
	--gf-ctrl-font-family: var(--wp--preset--font-family--sans);
	--gf-ctrl-label-font-family-primary: var(--wp--preset--font-family--sans);
	--gf-ctrl-label-letter-spacing-primary: var(--espie-tracking-wide);

	--gf-field-gap-y: var(--wp--preset--spacing--4);
	--gf-field-gap-x: var(--wp--preset--spacing--4);
	--gf-form-gap-y: var(--wp--preset--spacing--5);
}

/* DS danger token — status colours are derived in the DS, not in the brand sheet, so
   this is the one literal here that has no palette slug (tokens/colors.css --danger-500). */
:root { --espie-danger: #D32F0F; }

/* Type: GF inherits the page font, but labels need the brand's letterspaced caps. */
.gform_wrapper.gform-theme--framework .gform-field-label {
	font-family: var(--wp--preset--font-family--sans);
	letter-spacing: var(--espie-tracking-wide);
	text-transform: uppercase;
}

.gform_wrapper.gform-theme--framework .gform_button {
	font-family: var(--wp--preset--font-family--sans);
	letter-spacing: var(--espie-tracking-wide);
	text-transform: uppercase;
	width: 100%;
}

.gform_wrapper.gform-theme--framework .gform_button:focus-visible {
	outline: none;
	box-shadow: var(--espie-focus-ring);
}

/* Focus ring on inputs — DS uses a 3px orange ring alongside the border change. */
.gform_wrapper.gform-theme--framework :where(input, select, textarea):focus {
	box-shadow: var(--espie-focus-ring);
}

/* The textarea is a fixed 42px control by default; the demo gives it room to breathe. */
.gform_wrapper.gform-theme--framework textarea {
	min-height: 96px;
	padding-top: var(--wp--preset--spacing--3);
	padding-bottom: var(--wp--preset--spacing--3);
	line-height: 1.55;
	resize: vertical;
}

/* Confirmation — mirrors the demo's "Request received" panel. */
.espie-form-success {
	text-align: center;
	padding: var(--wp--preset--spacing--7) var(--wp--preset--spacing--3);
}

.espie-form-success h2 {
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--2-xl);
	font-weight: 800;
	text-transform: uppercase;
	color: var(--espie-text-strong);
	margin: 0 0 var(--wp--preset--spacing--2);
}

.espie-form-success p {
	color: var(--espie-text-muted);
	max-width: 340px;
	margin: 0 auto;
}

.espie-form-success::before {
	content: "";
	display: block;
	width: 66px;
	height: 66px;
	margin: 0 auto var(--wp--preset--spacing--5);
	border-radius: 50%;
	background:
		var(--espie-check-icon-accent) center / 32px 32px no-repeat,
		var(--wp--preset--color--orange-tint);
}
