/*
 * Kloomiyin 2026 — extras.css
 *
 * Everything that theme.json cannot express. Loaded on the front end and,
 * via add_editor_style(), inside the block editor.
 *
 * Colour reference (theme.json owns the oklch strings; hex fallbacks here are
 * for eyeballing only — do not paste them into block attributes):
 *   base       oklch(0.98 0.008 150)   ~ #f5faf6
 *   surface    #ffffff
 *   ink        oklch(0.24 0.02 162)    ~ #17221c
 *   ink-soft   oklch(0.34 0.02 162)    ~ #2f3b35
 *   muted      oklch(0.50 0.015 162)   ~ #5c6661
 *   border     oklch(0.91 0.012 155)   ~ #dbe4de
 *   green      oklch(0.66 0.15 152)    ~ #36ac62
 *   green-soft oklch(0.95 0.04 152)    ~ #dcf7e2
 *   green-tint oklch(0.96 0.018 152)   ~ #e9f6ec
 *   dark       oklch(0.235 0.045 162)  ~ #052517
 *   darker     oklch(0.20 0.04 162)    ~ #021c10
 *   on-dark    oklch(0.97 0.012 150)   ~ #f0f8f1
 *
 * Surface treatment (radii, shadows, hero glow/grid, section washes) matches
 * the design source and routes through the SURFACE TOKENS in section 0. Paste
 * the FLAT VARIANT block that follows them to switch the whole theme to flat
 * surfaces — 6px radii, no shadows, no textures — without touching anything
 * else. Buttons never carry a shadow in either variant.
 */

/* ---------------------------------------------------------------------------
 * 0. Local tokens
 * ------------------------------------------------------------------------ */

:root {
	/* Hairline: the border preset softened against the page. */
	--kmy-hairline: color-mix(in oklab, var(--wp--preset--color--border, oklch(0.91 0.012 155)) 88%, transparent);
	/* Hairline that reads on the dark/darker panels. ~ #44584d */
	--kmy-hairline-dark: oklch(0.44 0.03 162 / 0.55);
	/* Button/CTA hover fill. ~ #56bd78 */
	--kmy-green-hover: oklch(0.72 0.14 152);
	/* Link green used for inline "read more" affordances. ~ #05773b */
	--kmy-green-link: oklch(0.50 0.13 152);
	/* Nav pill hover wash. ~ #e1f0e4 */
	--kmy-nav-hover: oklch(0.94 0.022 150);
	/* Link green on hover — one step darker than --kmy-green-link. ~ #04642f */
	--kmy-green-link-hover: oklch(0.44 0.13 152);

	/* -- SURFACE TOKENS -------------------------------------------------------
	 * Every radius, shadow and background texture in the theme resolves through
	 * one of these. Values are lifted verbatim from the design source
	 * (bundle-page.html). To go flat, paste the FLAT VARIANT block below.
	 * ---------------------------------------------------------------------- */

	/* Radii. */
	--kmy-radius-card: 26px;
	--kmy-radius-btn: 999px;
	--kmy-radius-window: 26px;
	--kmy-radius-panel: 36px;
	--kmy-radius-pill: 999px;

	/* Layered card shadow. ink @ 4% + ink @ 5%. */
	--kmy-shadow-card: 0 1px 2px oklch(0.24 0.02 162 / 0.04), 0 16px 40px oklch(0.24 0.02 162 / 0.05);
	/* Shallower variant for list rows. */
	--kmy-shadow-row: 0 1px 2px oklch(0.24 0.02 162 / 0.04), 0 10px 28px oklch(0.24 0.02 162 / 0.04);
	/* Deepest variant, for the contact form panel. */
	--kmy-shadow-raised: 0 1px 2px oklch(0.24 0.02 162 / 0.04), 0 20px 48px oklch(0.24 0.02 162 / 0.06);

	/* Hero: two green glows. Glow colour ~ #46b86e. */
	--kmy-hero-glow:
		radial-gradient(ellipse 1000px 520px at 50% 6%, oklch(0.70 0.15 152 / 0.13), transparent 68%),
		radial-gradient(ellipse 700px 400px at 92% 108%, oklch(0.70 0.15 152 / 0.09), transparent 70%);

	/* Hero: faint 120px engineering grid. Line colour ~ #dce9de. */
	--kmy-hero-grid:
		repeating-linear-gradient(to right, oklch(0.92 0.02 150 / 0.035) 0 1px, transparent 1px 120px),
		repeating-linear-gradient(to bottom, oklch(0.92 0.02 150 / 0.028) 0 1px, transparent 1px 120px);

	/* Card face wash. ~ #fcfefc -> ~ #eff9f0 */
	--kmy-card-wash: linear-gradient(180deg, oklch(0.995 0.004 150), oklch(0.972 0.016 150));
	/* Light section wash. ~ #f1faf2 -> ~ #e4f6e8 */
	--kmy-section-wash: linear-gradient(180deg, oklch(0.975 0.014 150), oklch(0.955 0.026 152));
	/* Card face wash on the dark panels. ~ #113022 -> ~ #0a291c */
	--kmy-card-wash-dark: linear-gradient(180deg, oklch(0.28 0.045 162), oklch(0.255 0.045 162));
	/* Card hairline, a touch warmer than the border preset. ~ #d9e5dd */
	--kmy-card-border: oklch(0.91 0.016 155);
}

/* =============================================================================
 * FLAT VARIANT — one paste to switch the whole theme to flat surfaces.
 * Uncomment this block (it must stay after the :root above) and every card,
 * window, panel, button and hero drops its radius, shadow and texture. No other
 * edits needed anywhere in the theme.
 *
:root {
	--kmy-radius-card: 6px;
	--kmy-radius-btn: 6px;
	--kmy-radius-window: 6px;
	--kmy-radius-panel: 6px;
	--kmy-radius-pill: 6px;

	--kmy-shadow-card: none;
	--kmy-shadow-row: none;
	--kmy-shadow-raised: none;

	--kmy-hero-glow: none;
	--kmy-hero-grid: none;

	--kmy-card-wash: none;
	--kmy-section-wash: none;
	--kmy-card-wash-dark: none;
	--kmy-card-border: var(--wp--preset--color--border, oklch(0.91 0.012 155));
}
 * ========================================================================== */

/* ---------------------------------------------------------------------------
 * 1. Typography guards
 * theme.json emits element styles as `:root :where(h1)` (specificity 0,1,0),
 * so these `:root h1` selectors (0,1,1) win without !important.
 * ------------------------------------------------------------------------ */

:root h1,
:root h2,
:root h3,
:root h4,
:root h5,
:root h6,
:root .wp-block-post-title {
	font-optical-sizing: auto;
}

:root h1,
:root h2,
:root .wp-block-post-title {
	text-wrap: balance;
}

:root p,
:root li {
	text-wrap: pretty;
}

/* Phones: the display clamp bottoms out at 56px, which is too heavy under
 * ~780px. Re-clamp against the viewport instead.
 *
 * WordPress prints font-size preset CLASSES with !important
 * (".has-display-font-size{font-size:var(…) !important}"), so the class-based
 * selectors below have to match that to win. The bare element selectors do
 * not need it — theme.json element styles carry no !important. */
@media (max-width: 781px) {
	:root h1,
	:root .wp-block-post-title {
		font-size: clamp(32px, 8.6vw, 56px);
		line-height: 1.06;
		letter-spacing: -0.015em;
	}

	:root .has-display-font-size {
		font-size: clamp(32px, 8.6vw, 56px) !important;
		line-height: 1.06;
	}

	:root h2 {
		font-size: clamp(26px, 6.6vw, 40px);
		line-height: 1.12;
	}

	:root .has-xx-large-font-size {
		font-size: clamp(26px, 6.6vw, 40px) !important;
	}

	:root h3 {
		font-size: clamp(21px, 5vw, 26px);
	}

	/* x-large (34px) is used on paragraphs as well as headings, so this is
	 * deliberately element-agnostic — the old h2/h3-qualified version never
	 * matched anything the content actually shipped. */
	:root .has-x-large-font-size {
		font-size: clamp(21px, 5vw, 30px) !important;
	}
}

@media (max-width: 480px) {
	:root h1,
	:root .wp-block-post-title {
		font-size: clamp(30px, 9.4vw, 42px);
	}

	:root .has-display-font-size {
		font-size: clamp(30px, 9.4vw, 42px) !important;
	}
}

/* Hero pill: the design highlights one word in an h1 with a green lozenge
 * (bundle-page.html, the services hero — "get <more> out of Salesforce").
 * A <mark> is the editable, semantic way to say that in a heading block, so
 * this overrides the browser's yellow default. */
:root h1 mark,
:root .wp-block-post-title mark {
	display: inline-block;
	padding: 4px 20px;
	border-radius: var(--kmy-radius-pill, 999px);
	line-height: 1.1;
	background-color: var(--wp--preset--color--green, oklch(0.66 0.15 152)); /* ~ #36ac62 */
	color: var(--wp--preset--color--darker, oklch(0.20 0.04 162)); /* ~ #021c10 */
}

/* Buttons: pill by default, flat by token. theme.json sets the same var, this
 * is the belt-and-braces pass for buttons rendered outside a block context. */
:root .wp-element-button,
:root .wp-block-button__link {
	box-shadow: none;
	border-radius: var(--kmy-radius-btn, 999px);
	text-decoration: none;
}

/* ---------------------------------------------------------------------------
 * 2. kmy-grain — feTurbulence noise overlay for dark panels
 * ------------------------------------------------------------------------ */

.kmy-grain {
	position: relative;
	isolation: isolate;
	/* Rounded dark panels clip their own grain. */
	overflow: hidden;
}

.kmy-grain::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	background-image: url("data:image/svg+xml,%3Csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20width=%27140%27%20height=%27140%27%3E%3Cfilter%20id=%27g%27%3E%3CfeTurbulence%20type=%27fractalNoise%27%20baseFrequency=%270.9%27%20numOctaves=%274%27%20stitchTiles=%27stitch%27/%3E%3C/filter%3E%3Crect%20width=%27140%27%20height=%27140%27%20filter=%27url%28%23g%29%27/%3E%3C/svg%3E");
	background-repeat: repeat;
	background-size: 140px 140px;
	opacity: 0.07;
}

/* Keep real content above the noise layer. */
.kmy-grain > * {
	position: relative;
	z-index: 1;
}

/* ---------------------------------------------------------------------------
 * 3. kmy-hand-underline — hand-drawn green stroke under a word
 *
 * Content supplies ONLY the span: <span class="kmy-hand-underline">word</span>.
 * The stroke is a background-image data-URI, so there is no pseudo-element
 * carrying text and nothing for the editor to strip on re-save.
 *
 * The path is lifted verbatim from the design source's hero underline
 * (bundle-page.html: viewBox "0 0 160 16", preserveAspectRatio="none",
 * stroke-width 4.5, round caps). Green is inlined as #36ac62 — the hex
 * fallback for oklch(0.66 0.15 152) — because a data-URI cannot resolve a
 * CSS custom property.
 * ------------------------------------------------------------------------ */

.kmy-hand-underline {
	display: inline-block;
	white-space: nowrap;
	padding-bottom: 0.1em;
	background-image: url("data:image/svg+xml,%3Csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20viewBox=%270%200%20160%2016%27%20preserveAspectRatio=%27none%27%3E%3Cpath%20d=%27M4%2011.5%20C%2033%204.5,%2072%2014.5,%20118%206.5%20C%20133%203.8,%20145%206.4,%20156%209.6%27%20fill=%27none%27%20stroke=%27%2336ac62%27%20stroke-width=%274.5%27%20stroke-linecap=%27round%27/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: 0 100%;
	background-size: 100% 0.19em;
}

/* ---------------------------------------------------------------------------
 * 4. kmy-window — product window panel (surface, 6px, hairline, no shadow)
 * ------------------------------------------------------------------------ */

.kmy-window {
	background-color: var(--wp--preset--color--surface, #ffffff);
	background-image: var(--kmy-card-wash);
	color: var(--wp--preset--color--ink, oklch(0.24 0.02 162)); /* ~ #17221c */
	border: 1px solid var(--kmy-card-border);
	border-radius: var(--kmy-radius-window, 14px);
	box-shadow: var(--kmy-shadow-card);
	overflow: hidden;
}

.kmy-window > * {
	max-width: none;
}

/* Card — the design's 26px content card. Same surface treatment as a window,
 * one step rounder. */
.kmy-card {
	background-color: var(--wp--preset--color--surface, #ffffff);
	background-image: var(--kmy-card-wash);
	color: var(--wp--preset--color--ink, oklch(0.24 0.02 162)); /* ~ #17221c */
	border: 1px solid var(--kmy-card-border); /* ~ #d9e5dd */
	border-radius: var(--kmy-radius-card, 26px);
	box-shadow: var(--kmy-shadow-card);
}

/* Shallower shadow for full-width list rows (the products list). */
.kmy-card.is-row,
.kmy-window.is-row {
	box-shadow: var(--kmy-shadow-row);
}

/* Deepest shadow for the contact form panel. */
.kmy-card.is-raised,
.kmy-window.is-raised {
	box-shadow: var(--kmy-shadow-raised);
}

/* A card sitting on a dark panel flips its face and hairline. */
.has-dark-background-color .kmy-card,
.has-darker-background-color .kmy-card,
.kmy-hero .kmy-card,
.kmy-grain .kmy-card {
	background-color: oklch(0.28 0.045 162); /* ~ #113022 */
	background-image: var(--kmy-card-wash-dark);
	color: var(--wp--preset--color--on-dark, oklch(0.97 0.012 150)); /* ~ #f0f8f1 */
	border-color: oklch(0.34 0.035 162); /* ~ #2a3d33 */
	box-shadow: none;
}

/* A window sitting on a dark panel keeps a lighter hairline. */
.has-dark-background-color .kmy-window,
.has-darker-background-color .kmy-window,
.kmy-grain .kmy-window {
	border-color: color-mix(in oklab, #ffffff 16%, transparent);
}

/* NOTE: .kmy-window-chrome (the macOS-style dots bar) and .kmy-overlap-down
 * (the negative-margin pull) were removed — neither appears in the design
 * source and no pattern applies them. The CONTRACT.md class list still names
 * them; treat that entry as stale. */

/* ---------------------------------------------------------------------------
 * 5. kmy-ledger — ruled ledger list, 380px / 1fr at desktop
 * Direct children are the rows.
 * ------------------------------------------------------------------------ */

.kmy-ledger {
	display: block;
}

/* `:root` prefix (0,1,1) so the grid beats core's `.wp-block-columns{display:flex}`
 * — the ledger rows are columns blocks. */
:root .kmy-ledger > * {
	display: grid;
	grid-template-columns: 380px minmax(0, 1fr);
	gap: 24px 48px;
	align-items: start;
	margin: 0;
	padding: 28px 0;
	border-top: 1px solid var(--kmy-hairline);
}

/* The block editor injects appenders/margins between inner blocks; neutralise. */
.kmy-ledger > * + * {
	margin-top: 0;
}

.kmy-ledger > * > * {
	margin-block: 0;
	max-width: none;
}

.kmy-ledger > :last-child {
	border-bottom: 1px solid var(--kmy-hairline);
}

/* Ledger on a dark panel. */
.has-dark-background-color .kmy-ledger > *,
.has-darker-background-color .kmy-ledger > *,
.kmy-grain .kmy-ledger > * {
	border-color: var(--kmy-hairline-dark); /* ~ #44584d */
}

@media (max-width: 781px) {
	:root .kmy-ledger > * {
		grid-template-columns: minmax(0, 1fr);
		gap: 8px;
		padding: 22px 0;
	}
}

/* ---------------------------------------------------------------------------
 * 6. kmy-tick — small green check circle
 * Content supplies the inline SVG inside the element.
 * ------------------------------------------------------------------------ */

.kmy-tick {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 22px;
	height: 22px;
	flex: 0 0 22px;
	border-radius: 999px;
	background-color: var(--wp--preset--color--green-soft, oklch(0.95 0.04 152)); /* ~ #dcf7e2 */
	color: var(--kmy-green-link); /* ~ #05773b */
	line-height: 0;
	vertical-align: middle;
}

.kmy-tick svg {
	display: block;
	width: 13px;
	height: 13px;
	overflow: visible;
}

.kmy-tick svg path {
	fill: none;
	stroke: currentColor;
	stroke-width: 2.2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.has-dark-background-color .kmy-tick,
.has-darker-background-color .kmy-tick,
.kmy-grain .kmy-tick {
	background-color: color-mix(in oklab, var(--wp--preset--color--green, oklch(0.66 0.15 152)) 22%, transparent);
	color: var(--wp--preset--color--green, oklch(0.66 0.15 152)); /* ~ #36ac62 */
}

/* ---------------------------------------------------------------------------
 * 7. kmy-btn-ghost-dark — secondary button on a dark panel
 * The class may land on the .wp-block-button wrapper (block className) or on
 * the link itself, so both are covered.
 * ------------------------------------------------------------------------ */

.kmy-btn-ghost-dark .wp-element-button,
.kmy-btn-ghost-dark .wp-block-button__link,
.wp-element-button.kmy-btn-ghost-dark,
.wp-block-button__link.kmy-btn-ghost-dark {
	background-color: transparent;
	background-image: none;
	color: var(--wp--preset--color--on-dark, oklch(0.97 0.012 150)); /* ~ #f0f8f1 */
	border: 1px solid var(--kmy-hairline-dark); /* ~ #44584d */
	border-radius: var(--kmy-radius-btn, 999px);
	box-shadow: none;
}

.kmy-btn-ghost-dark .wp-element-button:hover,
.kmy-btn-ghost-dark .wp-element-button:focus,
.kmy-btn-ghost-dark .wp-block-button__link:hover,
.kmy-btn-ghost-dark .wp-block-button__link:focus,
.wp-element-button.kmy-btn-ghost-dark:hover,
.wp-element-button.kmy-btn-ghost-dark:focus,
.wp-block-button__link.kmy-btn-ghost-dark:hover,
.wp-block-button__link.kmy-btn-ghost-dark:focus {
	background-color: color-mix(in oklab, var(--wp--preset--color--green, oklch(0.66 0.15 152)) 14%, transparent);
	border-color: var(--wp--preset--color--green, oklch(0.66 0.15 152)); /* ~ #36ac62 */
	color: var(--wp--preset--color--on-dark, oklch(0.97 0.012 150));
}

/* ---------------------------------------------------------------------------
 * 8. Header / footer chrome (owned by parts/header.html + parts/footer.html)
 * ------------------------------------------------------------------------ */

.kmy-header {
	border-bottom: 1px solid var(--wp--preset--color--border, oklch(0.91 0.012 155)); /* ~ #dbe4de */
}

/* The brand lockup is a flex group: the SVG mark in a core/html block (artwork,
 * not copy) next to a real core/site-title so the client can rename the site.
 * The group's own flex layout supplies display/gap; these are the belt-and-
 * braces values plus what layout CSS cannot say. */
.kmy-brand {
	display: flex;
	align-items: center;
	gap: 10px;
	line-height: 1;
}

.kmy-brand svg {
	display: block;
	flex: 0 0 auto;
}

/* The mark's link is aria-hidden and untabbable — the site title next to it is
 * the announced, focusable "home" link, so the two are not read out twice. */
.kmy-brand-mark {
	display: block;
	flex: 0 0 auto;
	line-height: 0;
}

.kmy-brand-word {
	margin: 0;
	font-family: var(--wp--preset--font-family--display, "Bricolage Grotesque", system-ui, sans-serif);
	font-weight: 600;
	font-size: 22px;
	line-height: 1.2;
	letter-spacing: 0;
	color: var(--wp--preset--color--ink, oklch(0.24 0.02 162)); /* ~ #17221c */
}

/* core/site-title renders its own <a>; theme.json colours it ink, but the
 * footer's generic link tone would otherwise grey it out. */
.kmy-brand-word a {
	color: inherit;
	text-decoration: none;
}

.kmy-footer .kmy-brand-word,
.kmy-footer .kmy-brand-word a,
.kmy-footer .kmy-brand-word a:hover,
.kmy-footer .kmy-brand-word a:focus {
	color: var(--wp--preset--color--on-dark, oklch(0.97 0.012 150)); /* ~ #f0f8f1 */
}

/* Nav items per the design source: 40px pills, 18px side padding, 16.5px/500,
 * hover wash oklch(0.94 0.022 150). Radius follows the pill token. */
.kmy-nav .wp-block-navigation-item__content {
	display: inline-flex;
	align-items: center;
	height: 40px;
	padding: 0 18px;
	border-radius: var(--kmy-radius-pill, 999px);
	font-size: 16.5px;
	font-weight: 500;
	line-height: 1;
	transition: background-color 120ms ease, color 120ms ease;
}

.kmy-nav .wp-block-navigation-item__content:hover,
.kmy-nav .wp-block-navigation-item__content:focus {
	background-color: var(--kmy-nav-hover); /* ~ #e1f0e4 */
	color: var(--wp--preset--color--ink, oklch(0.24 0.02 162));
}

.kmy-nav .wp-block-navigation-item.current-menu-item .wp-block-navigation-item__content {
	background-color: var(--wp--preset--color--green-soft, oklch(0.95 0.04 152)); /* ~ #dcf7e2 */
}

/* Mobile nav overlay: keep it on the ink panel, not white-on-white. */
.kmy-nav .wp-block-navigation__responsive-container.is-menu-open {
	background-color: var(--wp--preset--color--base, oklch(0.98 0.008 150)); /* ~ #f5faf6 */
	color: var(--wp--preset--color--ink, oklch(0.24 0.02 162));
	padding: 24px;
}

.kmy-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
	display: block;
	height: auto;
	padding: 8px 0;
	border-radius: 0;
	background-color: transparent;
}

/* Footer link tone: soft on dark, green on hover. */
.kmy-footer a:where(:not(.wp-element-button)) {
	color: oklch(0.82 0.02 150); /* ~ #bbc8bd */
	text-decoration: none;
}

.kmy-footer a:where(:not(.wp-element-button)):hover,
.kmy-footer a:where(:not(.wp-element-button)):focus {
	color: var(--wp--preset--color--green, oklch(0.66 0.15 152)); /* ~ #36ac62 */
}

.kmy-footer-rule {
	border-top: 1px solid oklch(0.30 0.03 162); /* ~ #203329 */
}

.kmy-footer-rule p {
	margin: 0;
	color: oklch(0.70 0.02 150); /* ~ #96a298 */
}

/* Column labels in the footer stay plain case. Scoped through .kmy-footer so it
 * outranks the `:root h3` phone clamp above. */
.kmy-footer .kmy-footer-label,
.kmy-footer-label {
	font-family: var(--wp--preset--font-family--body, "Hanken Grotesk", system-ui, sans-serif);
	font-size: 17px;
	font-weight: 600;
	line-height: 1.6;
	letter-spacing: 0;
	text-transform: none;
	color: var(--wp--preset--color--on-dark, oklch(0.97 0.012 150)); /* ~ #f0f8f1 */
}

/* ---------------------------------------------------------------------------
 * 9. Small shared helpers used by the page patterns
 * ------------------------------------------------------------------------ */

/* Eyebrow label above a section heading. */
.kmy-eyebrow {
	font-size: 16px;
	font-weight: 600;
	letter-spacing: 0;
	color: oklch(0.48 0.08 152); /* ~ #386b47 */
}

.has-dark-background-color .kmy-eyebrow,
.has-darker-background-color .kmy-eyebrow,
.kmy-grain .kmy-eyebrow {
	color: oklch(0.72 0.13 152); /* ~ #5ebc7b */
}

/* Full-bleed dark panel that still respects the content width inside. */
.kmy-panel {
	border-radius: var(--kmy-radius-panel, 36px);
	overflow: hidden;
}

@media (max-width: 781px) {
	.kmy-panel {
		border-radius: min(var(--kmy-radius-panel, 36px), 18px);
	}

	.kmy-card,
	.kmy-window {
		border-radius: min(var(--kmy-radius-card, 26px), 18px);
	}
}

/* ---------------------------------------------------------------------------
 * 10. kmy-hero / kmy-wash — section surface textures
 *
 * .kmy-hero  lays the two green glows and the 120px grid over the dark colour
 *            the block itself sets (backgroundColor "dark" or "darker"). All
 *            three layers are background-images, so they sit behind content
 *            with no stacking-context tricks. Combine with .kmy-grain for the
 *            feTurbulence noise on top.
 * .kmy-wash  the light section's vertical gradient.
 *
 * Both degrade to a flat colour on their own when the FLAT VARIANT is pasted in
 * (background-image resolves to `none, none`, which is valid).
 * ------------------------------------------------------------------------ */

.kmy-hero {
	background-color: var(--wp--preset--color--dark, oklch(0.235 0.045 162)); /* ~ #052517 */
	background-image: var(--kmy-hero-glow), var(--kmy-hero-grid);
	background-repeat: no-repeat, no-repeat, repeat, repeat;
	background-attachment: scroll;
}

/* Honour whichever dark preset the block actually declared. */
.kmy-hero.has-darker-background-color {
	background-color: var(--wp--preset--color--darker, oklch(0.20 0.04 162)); /* ~ #021c10 */
}

.kmy-hero.has-dark-background-color {
	background-color: var(--wp--preset--color--dark, oklch(0.235 0.045 162)); /* ~ #052517 */
}

/* Grid only, no glow — for the dark bands that are not the page hero. */
.kmy-hero.is-grid-only {
	background-image: var(--kmy-hero-grid);
	background-repeat: repeat, repeat;
}

.kmy-wash {
	background-image: var(--kmy-section-wash);
}

/* .kmy-grain sits above .kmy-hero's background layers but below content, so the
 * two classes compose on the same element without further plumbing. */

/* ---------------------------------------------------------------------------
 * 11. Inline links
 *
 * theme.json's `link` element paints every link ink-coloured with no underline,
 * which is right for nav/footer but leaves body-copy links invisible. Blocks
 * that carry real inline links opt in with .kmy-link on the block.
 *
 * theme.json emits `:root :where(a:where(:not(.wp-element-button)))`
 * (specificity 0,1,0), so `:root .kmy-link a:where(…)` (0,2,0) wins.
 * ------------------------------------------------------------------------ */

:root .kmy-link a:where(:not(.wp-element-button)) {
	color: var(--kmy-green-link); /* ~ #05773b */
	font-weight: 600;
}

:root .kmy-link a:where(:not(.wp-element-button)):hover,
:root .kmy-link a:where(:not(.wp-element-button)):focus {
	color: var(--kmy-green-link-hover); /* ~ #04642f */
	text-decoration: underline;
}

/* Eyebrows are sometimes a link (a section that jumps somewhere). The label
 * colour is the point, so the link inherits it rather than turning ink. */
:root .kmy-eyebrow a:where(:not(.wp-element-button)) {
	color: inherit;
}

:root .kmy-eyebrow a:where(:not(.wp-element-button)):hover,
:root .kmy-eyebrow a:where(:not(.wp-element-button)):focus {
	color: var(--wp--preset--color--green, oklch(0.66 0.15 152)); /* ~ #36ac62 */
}

/* ---------------------------------------------------------------------------
 * 12. Outline buttons (core's is-style-outline)
 *
 * The design's secondary button on a light surface: 1px hairline, ink label,
 * green border + green-ink label on hover. (bundle-page.html, "Request a demo".)
 * The dark-panel variant is .kmy-btn-ghost-dark in section 7.
 * ------------------------------------------------------------------------ */

.is-style-outline > .wp-block-button__link,
.wp-block-button__link.is-style-outline {
	border-width: 1px;
	border-style: solid;
	border-color: oklch(0.86 0.03 155); /* ~ #cfdcd4 */
	background-color: transparent;
	background-image: none;
	color: oklch(0.28 0.02 162); /* ~ #1e2b24 */
}

.is-style-outline > .wp-block-button__link:hover,
.is-style-outline > .wp-block-button__link:focus,
.wp-block-button__link.is-style-outline:hover,
.wp-block-button__link.is-style-outline:focus {
	border-color: var(--wp--preset--color--green, oklch(0.66 0.15 152)); /* ~ #36ac62 */
	color: oklch(0.34 0.10 152); /* ~ #1c633a */
	background-color: transparent;
}

/* ---------------------------------------------------------------------------
 * 13. Content component classes
 *
 * These land on plain core blocks (list / paragraph) via block className, so
 * the copy stays editable and nothing here depends on markup the editor could
 * strip. Values are lifted from the design source.
 * ------------------------------------------------------------------------ */

/* --- .kmy-checklist — a core/list of ticked points ------------------------ */
/* Design: `grid-template-columns: 22px minmax(0,1fr); gap: 12px; align-items:
 * start`. The check rides in the ::before so wrapped lines hang against the
 * text column instead of tucking under the mark. Green is inlined as #dcf7e2 /
 * #05773b — a data-URI cannot resolve a custom property. */
:root .kmy-checklist {
	list-style: none;
	padding-left: 0 !important;
	margin-left: 0;
	display: grid;
	gap: 12px;
}

:root .kmy-checklist > li {
	display: grid;
	grid-template-columns: 22px minmax(0, 1fr);
	gap: 12px;
	align-items: start;
	margin: 0;
	line-height: 1.6;
}

:root .kmy-checklist > li::before {
	content: "";
	display: block;
	width: 22px;
	height: 22px;
	margin-top: 2px;
	background-image: url("data:image/svg+xml,%3Csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20viewBox=%270%200%2018%2018%27%3E%3Ccircle%20cx=%279%27%20cy=%279%27%20r=%279%27%20fill=%27%23dcf7e2%27/%3E%3Cpath%20d=%27M3.6%209.6%20L7.3%2013.2%20L14.3%205.2%27%20fill=%27none%27%20stroke=%27%2305773b%27%20stroke-width=%272.2%27%20stroke-linecap=%27round%27%20stroke-linejoin=%27round%27/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-size: 22px 22px;
}

/* On a dark panel the tint disc would go muddy — swap in the translucent
 * green disc with the bright check, matching .kmy-tick's dark variant. */
.has-dark-background-color .kmy-checklist > li::before,
.has-darker-background-color .kmy-checklist > li::before,
.kmy-grain .kmy-checklist > li::before {
	background-image: url("data:image/svg+xml,%3Csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20viewBox=%270%200%2018%2018%27%3E%3Ccircle%20cx=%279%27%20cy=%279%27%20r=%279%27%20fill=%27%2336ac62%27%20fill-opacity=%270.22%27/%3E%3Cpath%20d=%27M3.6%209.6%20L7.3%2013.2%20L14.3%205.2%27%20fill=%27none%27%20stroke=%27%2336ac62%27%20stroke-width=%272.2%27%20stroke-linecap=%27round%27%20stroke-linejoin=%27round%27/%3E%3C/svg%3E");
}

/* --- .kmy-step — the numbered process badge ------------------------------ */
/* Lifted from the inline styles the home-process pattern used to carry. It is
 * a core/paragraph now, i.e. a block-level box, so `display:flex` replaces the
 * design's `inline-flex` — same circle, no stray line-box leading. */
:root .kmy-step {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 46px;
	height: 46px;
	flex: 0 0 46px;
	border-radius: var(--kmy-radius-pill, 999px);
	background-color: var(--wp--preset--color--dark, oklch(0.235 0.045 162)); /* ~ #052517 */
	color: var(--wp--preset--color--green-soft, oklch(0.95 0.04 152)); /* ~ #dcf7e2 */
	font-family: var(--wp--preset--font-family--display, "Bricolage Grotesque", system-ui, sans-serif);
	font-weight: 600;
	font-size: 20px;
	line-height: 1;
	font-variant-numeric: tabular-nums;
}

/* On a dark panel the ink disc disappears — invert to the green tint. */
.has-dark-background-color .kmy-step,
.has-darker-background-color .kmy-step,
.kmy-grain .kmy-step {
	background-color: color-mix(in oklab, var(--wp--preset--color--green, oklch(0.66 0.15 152)) 22%, transparent);
	color: var(--wp--preset--color--on-dark, oklch(0.97 0.012 150)); /* ~ #f0f8f1 */
}

/* --- .kmy-chips — a core/list rendered as tag pills ----------------------- */
/* Design: 30px tall, 13px side padding, 14px/500, green tint disc.
 * `padding-left` needs !important: theme.json gives core/list a 1.2em left
 * padding, which WP prints on `.wp-block-list` at equal specificity. */
:root .kmy-chips {
	list-style: none;
	padding-left: 0 !important;
	margin-left: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

:root .kmy-chips > li {
	display: inline-flex;
	align-items: center;
	height: 30px;
	padding: 0 13px;
	margin: 0;
	border-radius: var(--kmy-radius-pill, 999px);
	background-color: oklch(0.93 0.05 152); /* ~ #d3f4dc */
	color: oklch(0.34 0.08 152); /* ~ #1d6339 */
	font-size: 14px;
	font-weight: 500;
	line-height: 1;
	white-space: nowrap;
}

.has-dark-background-color .kmy-chips > li,
.has-darker-background-color .kmy-chips > li,
.kmy-grain .kmy-chips > li {
	background-color: color-mix(in oklab, var(--wp--preset--color--green, oklch(0.66 0.15 152)) 18%, transparent);
	color: var(--wp--preset--color--on-dark, oklch(0.97 0.012 150)); /* ~ #f0f8f1 */
}

/* --- .kmy-badge — the design's muted "Coming Soon" pill ------------------- */
/* 48px tall, 28px side padding, 16.5px/600, hairline border. A core/paragraph,
 * so `inline-flex` would leave line-box leading; use flex + fit-content. */
:root .kmy-badge {
	display: flex;
	width: fit-content;
	align-items: center;
	height: 48px;
	padding: 0 28px;
	border-radius: var(--kmy-radius-pill, 999px);
	background-color: oklch(0.94 0.012 150); /* ~ #eaf0eb */
	border: 1px solid oklch(0.90 0.014 155); /* ~ #d7e2da */
	color: oklch(0.48 0.02 162); /* ~ #58635d */
	font-size: 16.5px;
	font-weight: 600;
	line-height: 1;
}

.has-dark-background-color .kmy-badge,
.has-darker-background-color .kmy-badge,
.kmy-grain .kmy-badge {
	background-color: color-mix(in oklab, #ffffff 8%, transparent);
	border-color: var(--kmy-hairline-dark); /* ~ #44584d */
	color: oklch(0.82 0.02 150); /* ~ #bbc8bd */
}

/* ---------------------------------------------------------------------------
 * 14. Focus ring
 *
 * theme.json paints :focus link/button colours but cannot emit an outline, and
 * the pill radius makes the UA default ring hard to see on green. One visible
 * ring for every interactive thing, keyboard users only.
 * ------------------------------------------------------------------------ */

:root :is(a, button, .wp-element-button, input, select, textarea):focus-visible {
	outline: 2px solid var(--wp--preset--color--green, oklch(0.66 0.15 152)); /* ~ #36ac62 */
	outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
 * 15. Separators on dark panels
 * theme.json's core/separator border-color is the light `border` preset, which
 * vanishes on the ink panels.
 * ------------------------------------------------------------------------ */

.has-dark-background-color .wp-block-separator,
.has-darker-background-color .wp-block-separator,
.kmy-grain .wp-block-separator {
	border-color: var(--kmy-hairline-dark, oklch(0.34 0.03 162)); /* ~ #44584d */
}

/* Reduced motion: nothing here animates much, but be explicit. */
@media (prefers-reduced-motion: reduce) {
	.kmy-nav .wp-block-navigation-item__content {
		transition: none;
	}
}

/* ---------------------------------------------------------------------------
 * 16. Images supplied by the client (product marks, founder portraits)
 * ------------------------------------------------------------------------ */

:root .kmy-product-mark {
	margin: 0;
	width: 72px;
	height: 72px;
	flex: 0 0 72px;
}

:root .kmy-product-mark img {
	display: block;
	width: 72px;
	height: 72px;
	object-fit: cover;
	border-radius: 18px;
	border: 1px solid var(--kmy-card-border, oklch(0.91 0.016 155));
	background: var(--wp--preset--color--surface, #ffffff);
}

:root .kmy-portrait {
	margin: 0 0 20px;
	width: 96px;
	height: 96px;
	flex: 0 0 96px;
	overflow: hidden;
	border-radius: 50%;
	border: 1px solid var(--kmy-card-border, oklch(0.91 0.016 155));
	background: var(--wp--preset--color--green-tint, #e9f6ec);
}

:root .kmy-portrait img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center top;
}

/* Product rows: keep the action buttons on one line beside the badge. */
:root .kmy-card.is-row .wp-block-button__link {
	white-space: nowrap;
	padding-left: 24px;
	padding-right: 24px;
}

:root .kmy-badge {
	white-space: nowrap;
}

/* ---------------------------------------------------------------------------
 * 17. Product rows — containment of the three-column row and its action group
 *
 * The action column has a fixed 300px flex-basis, but "Request a demo" (177px)
 * + the 16px group gap + the "Coming Soon" pill (157px) measure ~350px. The
 * group is a core flex group with flexWrap "nowrap", so once .kmy-badge got
 * `white-space: nowrap` the pill had nowhere to go and hung past the card's
 * right padding edge at every unstacked width (and pushed the whole document
 * wider than the viewport on phones).
 *
 * Rules below, in order:
 *   a) no column may be forced wider than the space the row gives it;
 *   b) the 72px product mark is the one thing that must not be squeezed;
 *   c) the action group and the buttons block WRAP instead of overflowing, so a
 *      group that does not fit becomes button-on-top / badge-below;
 *   d) unstacked, the action group hugs the card's right padding edge;
 *      stacked on phones it left-aligns under the text (core's own default);
 *   e) from 1000px up the action column sizes to its content, so the button and
 *      the badge sit on one line. Between 782px and 1000px it keeps the 300px
 *      basis and may shrink below it, and the group wraps to two lines.
 * ------------------------------------------------------------------------ */

:root .kmy-card.is-row > .wp-block-column {
	min-width: 0;
}

:root .kmy-card.is-row > .wp-block-column:first-child {
	flex-shrink: 0;
}

:root .kmy-card.is-row .wp-block-group.is-nowrap,
:root .kmy-card.is-row .wp-block-buttons {
	flex-wrap: wrap;
}

:root .kmy-card.is-row > .wp-block-column:last-child > .wp-block-group,
:root .kmy-card.is-row > .wp-block-column:last-child > .wp-block-buttons {
	max-width: 100%;
	justify-content: flex-start;
}

@media (min-width: 782px) {
	:root .kmy-card.is-row > .wp-block-column:last-child > .wp-block-group,
	:root .kmy-card.is-row > .wp-block-column:last-child > .wp-block-buttons {
		justify-content: flex-end;
	}
}

@media (min-width: 1000px) {
	/* `!important` because the 300px basis is an INLINE style that core writes
	 * from the column's `width` attribute — the same reason core's own mobile
	 * stacking rule is `flex-basis: 100% !important`.
	 *
	 * `max-content`, NOT `auto`: `flex-basis: auto` defers to the column's
	 * `width`, which core resolves to the full row here, so the action column
	 * ate the whole card and squeezed the copy column to zero. `max-content`
	 * asks for exactly the group's natural width (~350px). flex-shrink stays 1,
	 * so the column still gives the width back if the row runs out. */
	:root .kmy-card.is-row > .wp-block-column:last-child {
		flex-basis: max-content !important;
		max-width: 100%;
	}
}

/* ---------------------------------------------------------------------------
 * 18. Mobile
 *
 * One place for every phone/tablet adjustment. 781px is the breakpoint core
 * uses to stack columns, so everything here lines up with that.
 *
 * 18.0 is not a media query: it removes the strip of page background that sat
 * between the header and the first full-bleed section (and between the last
 * section and the footer) at EVERY width.
 *
 * 18.1 is the main lever. Nearly every padding, blockGap and column gap in the
 * page markup is written as `var(--wp--preset--spacing--NN)`, so re-pointing
 * those custom properties inside a media query re-spaces the whole site at once
 * — no `!important`, no per-section overrides, and the block markup (which
 * lives in the WordPress database and cannot be edited from the theme) is left
 * untouched. extras.css is enqueued after global-styles, so a plain `:root`
 * here wins on source order.
 * ------------------------------------------------------------------------ */

/* --- 18.0 Root block gap ------------------------------------------------- */
/* theme.json's root `blockGap` (spacing 40 = 24px) is emitted by core as
 * `:where(.wp-site-blocks) > * { margin-block-start: … }`. At root level the
 * only children are the header part, <main> and the footer part, so all that
 * gap ever did was show 24px of page background between the header and the
 * hero, and again above the footer. The sections carry their own padding.
 * `:where()` scores zero, so `.wp-site-blocks > *` (0,1,0) is enough. */
.wp-site-blocks > * {
	margin-block-start: 0;
}

@media (max-width: 781px) {
	/* --- 18.1 Spacing scale ---------------------------------------------- */
	/* Tablet/stacked step. Desktop values in brackets. */
	:root {
		--wp--preset--spacing--30: 14px; /* 16px */
		--wp--preset--spacing--40: 20px; /* 24px */
		--wp--preset--spacing--50: 28px; /* 40px */
		--wp--preset--spacing--60: 36px; /* 64px */
		--wp--preset--spacing--70: 56px; /* 96px */
		--wp--preset--spacing--80: 72px; /* 140px */
	}

	/* --- 18.2 Typography -------------------------------------------------- */
	/* Section 1 already re-clamps h1/h2/h3 under 781px; these bring the
	 * preset-class sizes (which WP prints with !important) into the same
	 * range and tighten the heading leading. */
	:root .has-large-font-size {
		font-size: 18.5px !important;
		line-height: 1.45;
	}

	:root h2.has-large-font-size,
	:root h3.has-large-font-size,
	:root h4.has-large-font-size {
		line-height: 1.25;
	}

	:root .has-medium-font-size {
		font-size: 16px !important;
	}

	:root .entry-content p,
	:root .entry-content li {
		font-size: 16px;
		line-height: 1.55;
	}

	:root .kmy-eyebrow {
		font-size: 14px;
	}

	/* --- 18.3 Cards, windows and panels ----------------------------------- */
	/* The 18.1 scale already takes the padding these carry as inline styles
	 * from 40px to 28px; on a phone (18.10) it goes to 20px. Only the radius
	 * and the internal rhythm need saying here. */
	:root .kmy-card,
	:root .kmy-window,
	:root .kmy-panel {
		border-radius: 16px;
	}

	/* --- 18.4 Equal-height process cards ---------------------------------- */
	/* The two-up grids themselves are in 18.11. Here the process columns are
	 * made flex containers so their green panel fills the grid track — two
	 * side-by-side steps of different copy length end up the same height. */
	:root .wp-block-columns:has(> .wp-block-column > .kmy-panel > .kmy-step) > .wp-block-column {
		display: flex;
	}

	:root .wp-block-columns:has(> .wp-block-column > .kmy-panel > .kmy-step) > .wp-block-column > .kmy-panel {
		flex: 1 1 auto;
	}

	/* --- 18.5 Numbered process steps -------------------------------------- */
	/* Badge, title and copy stack vertically at desktop. On a phone the badge
	 * moves up beside the title and shrinks, which removes a whole 46px row
	 * plus its gap from every step. */
	:root .kmy-panel:has(> .kmy-step) {
		display: grid;
		grid-template-columns: 34px minmax(0, 1fr);
		column-gap: 12px;
		row-gap: 6px;
		align-items: center;
	}

	:root .kmy-panel:has(> .kmy-step) > * {
		margin-block-start: 0;
		grid-column: 1 / -1;
	}

	:root .kmy-panel > .kmy-step {
		grid-column: 1;
		grid-row: 1;
		width: 34px;
		height: 34px;
		flex: 0 0 34px;
		font-size: 16px;
	}

	:root .kmy-panel:has(> .kmy-step) > .kmy-step + * {
		grid-column: 2;
		grid-row: 1;
	}

	/* --- 18.6 Buttons ----------------------------------------------------- */
	/* Hero and CTA-panel buttons go full-width and stack, so both actions are
	 * the same easy target instead of two pills of different widths. That is a
	 * phone move, so it lives in 18.10 — at 600–781px there is room for the two
	 * pills side by side and a stretched button just looks stranded.
	 *
	 * Comfortable tap target everywhere. */
	:root .wp-block-button__link,
	:root .wp-element-button {
		min-height: 46px;
		display: inline-flex;
		align-items: center;
		justify-content: center;
	}

	/* --- 18.7 Product rows ------------------------------------------------ */
	/* The three-column row becomes a two-row grid: mark + title on line one,
	 * description across the full width beneath, actions full-width below that.
	 * `display: contents` on the copy column lets its heading and paragraph
	 * become grid items of the row itself, which is what puts the title next to
	 * the mark without touching the markup. */
	:root .kmy-card.is-row {
		display: grid;
		grid-template-columns: 48px minmax(0, 1fr);
		column-gap: 12px;
		row-gap: 12px;
		align-items: center;
	}

	:root .kmy-card.is-row > .wp-block-column {
		flex-basis: auto !important;
		margin: 0;
		min-width: 0;
	}

	:root .kmy-card.is-row > .wp-block-column:first-child {
		grid-column: 1;
		grid-row: 1;
	}

	:root .kmy-card.is-row > .wp-block-column:nth-child(2) {
		display: contents;
	}

	:root .kmy-card.is-row > .wp-block-column:nth-child(2) > :first-child {
		grid-column: 2;
		grid-row: 1;
		margin: 0;
		align-self: center;
	}

	:root .kmy-card.is-row > .wp-block-column:nth-child(2) > :first-child ~ * {
		grid-column: 1 / -1;
		margin: 0;
	}

	:root .kmy-card.is-row > .wp-block-column:last-child {
		grid-column: 1 / -1;
	}

	:root .kmy-product-mark {
		width: 48px;
		height: 48px;
		flex: 0 0 48px;
	}

	/* core/image writes the 72px size as an INLINE style on the <img>, so this
	 * is the one place a width needs !important — without it the 72px mark
	 * overflows its 48px figure and lands on top of the description. */
	:root .kmy-product-mark img {
		width: 48px !important;
		height: 48px !important;
		border-radius: 12px;
	}

	/* Actions: one full-width column, so the Coming Soon pill can never hang
	 * outside the card the way it did when the group was nowrap. */
	:root .kmy-card.is-row .wp-block-group.is-nowrap,
	:root .kmy-card.is-row .wp-block-buttons {
		display: flex;
		flex-direction: column;
		align-items: stretch;
		width: 100%;
		gap: 8px;
	}

	:root .kmy-card.is-row .wp-block-button {
		width: 100%;
	}

	:root .kmy-card.is-row .wp-block-button__link {
		display: flex;
		width: 100%;
		text-align: center;
		white-space: normal;
	}

	/* box-sizing is NOT border-box by default on the front end (core sets it on
	 * .wp-block-button__link but not on a paragraph), so a full-width badge
	 * would add its 16px side padding on top of the 100% and hang off the card.
	 */
	:root .kmy-card.is-row .kmy-badge {
		box-sizing: border-box;
		width: 100%;
		height: 44px;
		justify-content: center;
		padding: 0 16px;
	}

	/* --- 18.8 Images ------------------------------------------------------ */
	:root .kmy-portrait {
		width: 64px;
		height: 64px;
		flex: 0 0 64px;
		margin-bottom: 12px;
	}

	:root .wp-block-image img {
		max-width: 100%;
		height: auto;
	}

	/* --- 18.9 Header, footer, contact ------------------------------------- */
	:root .kmy-brand-word {
		font-size: 19px;
	}

	:root .kmy-header .wp-element-button {
		font-size: 15px;
		padding: 10px 18px;
	}

	/* core/navigation is set to overlayMenu "mobile", which core reads as
	 * "below 600px". Between 600px and 781px the five inline items plus the CTA
	 * are wider than the header, so the flex group wraps the brand, the nav and
	 * the button onto three separate rows. Extend the hamburger up to the
	 * stacking breakpoint instead. Core's rules live in a `min-width: 600px`
	 * query at (0,2,0); the .kmy-nav prefix takes these to (0,3,0). The close
	 * button is only hidden by core while the overlay is CLOSED, so it still
	 * appears once the menu opens. */
	:root .kmy-nav .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) {
		display: none;
	}

	:root .kmy-nav .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: flex;
	}

	:root .kmy-footer .kmy-brand-word {
		font-size: 20px;
	}

	:root .kmy-footer-label {
		font-size: 16px;
	}

	/* Contact: the form is the reason the page exists, so it comes first and
	 * the address / what-to-expect column follows it. */
	:root .wp-block-columns > .wp-block-column:has(.kmy-lead-form) {
		order: -1;
	}

	:root .kmy-lead-form {
		gap: 18px;
	}

	:root .kmy-lead-form__submit {
		align-self: stretch;
		width: 100%;
		height: 52px;
	}
}

/* --- 18.10 Phone ---------------------------------------------------------- */
/* One step tighter than the tablet scale above. 44px of vertical section
 * padding and 20px of horizontal is the target from the design review. */
@media (max-width: 600px) {
	:root {
		--wp--preset--spacing--30: 12px;
		--wp--preset--spacing--40: 16px;
		--wp--preset--spacing--50: 20px;
		--wp--preset--spacing--60: 28px;
		--wp--preset--spacing--70: 44px;
		--wp--preset--spacing--80: 56px;
	}

	:root .kmy-badge {
		height: 40px;
		padding: 0 18px;
		font-size: 15px;
	}

	/* Hero and CTA-panel buttons: full-width and stacked, so both actions are
	 * the same easy target instead of two pills of different widths. */
	:root .kmy-hero > .wp-block-buttons,
	:root .kmy-panel .wp-block-buttons {
		flex-direction: column;
		align-items: stretch;
		gap: 10px;
	}

	:root .kmy-hero > .wp-block-buttons > .wp-block-button,
	:root .kmy-panel .wp-block-buttons > .wp-block-button {
		width: 100%;
	}

	:root .kmy-hero > .wp-block-buttons .wp-block-button__link,
	:root .kmy-panel .wp-block-buttons .wp-block-button__link {
		display: flex;
		width: 100%;
		text-align: center;
	}
}

/* --- 18.11 Two-up card grids (400px – 781px) ------------------------------ */
/* Kept in its own query so the selectors read in one place. Every match is a
 * core/columns block whose columns hold short cards; the grid replaces core's
 * one-per-row mobile stack, and a lone third or fifth card spans both tracks
 * rather than sitting half-width next to nothing. */
@media (min-width: 400px) and (max-width: 781px) {
	:root .wp-block-columns:has(> .wp-block-column > .kmy-panel > .kmy-step),
	:root .wp-block-columns:has(> .wp-block-column > .kmy-window):not(:has(.kmy-link)):not(:has(.kmy-chips)):not(:has(.kmy-checklist)):not(:has(.kmy-lead-form)),
	:root .wp-block-columns:has(> .wp-block-column > .kmy-card):not(:has(.kmy-portrait)):not(:has(.is-raised)):not(:has(.kmy-lead-form)) {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: var(--wp--preset--spacing--40);
		align-items: stretch;
	}

	:root .wp-block-columns:has(> .wp-block-column > .kmy-panel > .kmy-step) > .wp-block-column,
	:root .wp-block-columns:has(> .wp-block-column > .kmy-window):not(:has(.kmy-link)):not(:has(.kmy-chips)):not(:has(.kmy-checklist)):not(:has(.kmy-lead-form)) > .wp-block-column,
	:root .wp-block-columns:has(> .wp-block-column > .kmy-card):not(:has(.kmy-portrait)):not(:has(.is-raised)):not(:has(.kmy-lead-form)) > .wp-block-column {
		flex-basis: auto !important;
		margin: 0;
		min-width: 0;
	}

	/* An odd card at the end of the set spans the full row. */
	:root .wp-block-columns:has(> .wp-block-column > .kmy-panel > .kmy-step) > .wp-block-column:last-child:nth-child(odd),
	:root .wp-block-columns:has(> .wp-block-column > .kmy-window):not(:has(.kmy-link)):not(:has(.kmy-chips)):not(:has(.kmy-checklist)):not(:has(.kmy-lead-form)) > .wp-block-column:last-child:nth-child(odd),
	:root .wp-block-columns:has(> .wp-block-column > .kmy-card):not(:has(.kmy-portrait)):not(:has(.is-raised)):not(:has(.kmy-lead-form)) > .wp-block-column:last-child:nth-child(odd) {
		grid-column: 1 / -1;
	}
}
