/**
 * GrowthRefactor supplemental styles.
 *
 * SCOPE RULE: theme.json is the design system. Only add rules here that
 * theme.json genuinely cannot express (gradient text clipping, pseudo-elements,
 * :has(), state classes, marker styling). Everything else belongs in theme.json.
 *
 * AUTHORING RULE: mobile-first. Base rules target phones with no media query.
 * Enhance upward with `min-width` only. Never write a `max-width` query here.
 * This is a deliberate break from the old desktop-first sites/main/css/style.css.
 */

/* ---------------------------------------------------------------------------
 * 1. Gradient text (background-clip cannot be expressed in theme.json)
 * ------------------------------------------------------------------------ */

.is-style-gradient-text,
.gr-gradient-text {
	background: var(--wp--preset--gradient--sunrise);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	-webkit-text-fill-color: transparent;
	/* Keeps descenders from being clipped by the text box. */
	padding-bottom: 0.06em;
}

/* An <em> inside a heading is the brand's emphasis device, not italics. */
.gr-hero h1 em,
.gr-emphasis em {
	font-style: normal;
	background: var(--wp--preset--gradient--sunrise);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	-webkit-text-fill-color: transparent;
}

/* Forced-colors users get no gradient, so restore a real color. */
@media (forced-colors: active) {
	.is-style-gradient-text,
	.gr-gradient-text,
	.gr-hero h1 em,
	.gr-emphasis em {
		background: none;
		color: CanvasText;
		-webkit-text-fill-color: CanvasText;
	}
}

/* ---------------------------------------------------------------------------
 * 2. Buttons
 *
 * Contrast maths behind these choices:
 *   #FF5A5F on #FFFFFF = 3.05:1  -> fails AA for text
 *   #C6353B on #FFFFFF = 5.29:1  -> passes AA  (theme.json default button)
 *   #3A2E2E on sunrise = 4.27:1 to 5.40:1 -> gradient buttons use cocoa text
 * ------------------------------------------------------------------------ */

.wp-block-button.is-style-sunrise > .wp-block-button__link {
	background: var(--wp--preset--gradient--sunrise);
	color: var(--wp--preset--color--cocoa);
	border: 0;
}

.wp-block-button.is-style-sunrise > .wp-block-button__link:hover,
.wp-block-button.is-style-sunrise > .wp-block-button__link:focus-visible {
	filter: saturate(1.15) brightness(0.97);
	color: var(--wp--preset--color--cocoa);
}

/* Ghost buttons are token-driven so the DEFAULT is readable on a light page
   and dark bands opt in. The old version hardcoded white-on-transparent, which
   rendered a literally invisible button (1:1 contrast) the one time the style
   was used outside a cocoa band — in the proof section, of all places. */
.wp-block-button.is-style-ghost > .wp-block-button__link {
	background: transparent;
	color: var(--gr-ghost-fg, var(--wp--preset--color--cocoa));
	border: 1px solid var(--gr-ghost-edge, rgba(58, 46, 46, 0.45));
}

.wp-block-button.is-style-ghost > .wp-block-button__link:hover,
.wp-block-button.is-style-ghost > .wp-block-button__link:focus-visible {
	background: var(--gr-ghost-wash, rgba(58, 46, 46, 0.06));
	border-color: var(--gr-ghost-fg, var(--wp--preset--color--cocoa));
	color: var(--gr-ghost-fg, var(--wp--preset--color--cocoa));
}

.has-cocoa-background-color,
.gr-hero,
.gr-cta,
.gr-footer {
	--gr-ghost-fg: var(--wp--preset--color--white);
	--gr-ghost-edge: rgba(255, 255, 255, 0.5);
	--gr-ghost-wash: rgba(255, 255, 255, 0.1);
}

.wp-block-button__link {
	transition: transform 0.15s ease, background-color 0.15s ease, filter 0.15s ease;
}

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

/* A visible focus ring everywhere, token-driven for contrast: coral-ink is
   5.3:1 on white but only 2.5:1 on cocoa, so the dark bands switch the ring
   to amber (7.9:1 on cocoa) — and light cards INSIDE a dark band (the audit
   form lives in the closing cocoa section) switch it straight back. */
:root {
	--gr-focus-ring: var(--wp--preset--color--coral-ink);
}

.gr-hero,
.gr-cta,
.gr-footer,
.has-cocoa-background-color,
.gr-nav.is-open {
	--gr-focus-ring: var(--wp--preset--color--amber);
}

.is-style-card,
.gr-form-thanks {
	--gr-focus-ring: var(--wp--preset--color--coral-ink);
}

:where(a, button, .wp-block-button__link, summary, input, textarea, select):focus-visible {
	outline: 3px solid var(--gr-focus-ring);
	outline-offset: 2px;
	border-radius: 3px;
}

/* Buttons stack full-width on phones, sit inline from small tablets up. */
.gr-hero .wp-block-buttons > .wp-block-button {
	width: 100%;
}

.gr-hero .wp-block-buttons > .wp-block-button > .wp-block-button__link {
	display: block;
	text-align: center;
}

@media (min-width: 480px) {
	.gr-hero .wp-block-buttons > .wp-block-button {
		width: auto;
	}

	.gr-hero .wp-block-buttons > .wp-block-button > .wp-block-button__link {
		display: inline-block;
	}
}

/* ---------------------------------------------------------------------------
 * 3. Eyebrow label ("// marketing automation Automation Studio")
 * ------------------------------------------------------------------------ */

.is-style-eyebrow {
	font-family: var(--wp--preset--font-family--jetbrains-mono);
	font-size: var(--wp--preset--font-size--eyebrow);
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--coral-ink);
	margin-bottom: 0.75rem;
}

.gr-hero .is-style-eyebrow {
	color: var(--wp--preset--color--amber);
}

/* ---------------------------------------------------------------------------
 * 3b. Measure wrapper
 *
 * WordPress constrained layout forces `margin-left/right: auto !important` onto
 * every child, so a nested constrained group with a narrower contentSize gets
 * CENTERED, not left-aligned. That reads as broken next to a full-width card
 * grid. So text blocks use a `layout:default` group with this class instead,
 * which caps the measure while keeping everything flush left.
 * ------------------------------------------------------------------------ */

/* Section headers: everything runs the full content width. The prose was
   briefly capped at 46rem for line-length comfort, but the client weighed the
   trade and chose to use the space — the empty right column read worse to
   them than longer lines. Line-height 1.6 on the intros does the remaining
   readability work. */
.gr-measure > * {
	max-width: none;
	margin-left: 0;
	margin-right: 0;
}

.gr-measure-wide > * {
	max-width: 52rem;
	margin-left: 0;
	margin-right: 0;
}

/* ---------------------------------------------------------------------------
 * 4. Hero (cocoa field + radial sunrise glows)
 * ------------------------------------------------------------------------ */

.gr-hero {
	position: relative;
	isolation: isolate;
	overflow: hidden;
}

.gr-hero::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background:
		radial-gradient(60% 55% at 15% 10%, rgba(255, 90, 95, 0.22) 0%, transparent 60%),
		radial-gradient(50% 50% at 88% 85%, rgba(255, 134, 39, 0.16) 0%, transparent 60%);
	pointer-events: none;
}

.gr-hero :where(h1, h2, p) {
	color: var(--wp--preset--color--white);
}

/* Hero content sits in a `layout:default` group (.gr-hero-inner) rather than
   directly in the constrained wrapper. Direct children of a constrained layout
   get `margin-left/right: auto !important`, which silently centres anything
   given a max-width. Nesting one level escapes that entirely. */

.gr-hero .gr-hero-sub {
	color: rgba(255, 255, 255, 0.82);
	max-width: 62ch;
	margin-top: var(--wp--preset--spacing--50);
}

.gr-hero h1 {
	max-width: 24ch;
	margin-top: var(--wp--preset--spacing--30);
}

/* ---------------------------------------------------------------------------
 * 5. Stat bar (gradient numerals + rule)
 * ------------------------------------------------------------------------ */

.gr-stat-bar {
	border-top: 1px solid rgba(255, 255, 255, 0.14);
	padding-top: var(--wp--preset--spacing--50);
}

/* WordPress grid layout emits repeat(auto-fill, ...), which keeps empty trailing
   tracks. In a wide container that renders three stats bunched into the left of
   a five-column grid with dead space beside them. auto-fit collapses the empty
   tracks so the stats spread across the full width whatever the count. The
   doubled class is only there to outrank WP's generated .wp-container-* rule
   without resorting to !important. */
.wp-block-group.gr-stat-bar {
	grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
}

/* Four proof cards stacked in a half-width column ran 636px tall against 348px
   of argument beside them, leaving a 288px void next to the text. Two per row
   brings the evidence roughly level with the claim it supports, so the pair
   reads as one thought rather than a short column beside a long one. Below
   900px the column is too narrow to split, so the cards stay stacked. */
@media (min-width: 900px) {
	.gr-spec.is-2col {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: var(--wp--preset--spacing--30);
		align-items: start;
	}

	/* The group's blockGap emits margin-block-start on every child but the
	   first. Harmless while these were stacked; once they are grid items that
	   margin pushes each card down inside its own cell, so the second card in
	   row one sat 16px below the first and the second row gapped twice. */
	.gr-spec.is-2col > * {
		margin-top: 0;
	}
}

/* Five audience cards across a 1120px row left each one 208px wide and 280px
   tall, so every card was a narrow column of wrapped text. Three per row match
   the card width used by the pillars and the proof bar, and the last card
   stretches over the two free tracks so the second row has no ragged hole.
   Measured: the 20rem tracks first fit two across between 703px and 706px. Below
   that the grid is a single column, where spanning two would force an implicit
   second track and push the row wider than the container. If the track width or
   the block gap changes, re-check this number. */
@media (min-width: 706px) {
	.gr-audience .gr-audience-wide {
		grid-column: span 2;
	}
}

.gr-stat-value {
	font-family: var(--wp--preset--font-family--space-grotesk);
	font-weight: 700;
	line-height: 1.05;
	background: var(--wp--preset--gradient--sunrise);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	-webkit-text-fill-color: transparent;
}

.gr-stat-label {
	font-size: var(--wp--preset--font-size--small);
	color: rgba(255, 255, 255, 0.62);
	margin-top: 0.25rem;
}

/* On a light section the stat labels need the normal body colour. */
.gr-stat-bar.is-on-light {
	border-top-color: rgba(58, 46, 46, 0.12);
}

/* Standalone proof band under the hero: the band supplies its own rule, so the
   stat bar drops its top border and padding. */
.gr-proof .gr-stat-bar {
	border-top: 0;
	padding-top: 0;
}

.gr-proof .gr-stat-value {
	line-height: 1.1;
}

.gr-stat-bar.is-on-light .gr-stat-label {
	color: var(--wp--preset--color--taupe-ink);
}

/* ---------------------------------------------------------------------------
 * 6. Cards
 * ------------------------------------------------------------------------ */

.wp-block-group.is-style-card {
	background: var(--wp--preset--color--white);
	border-radius: var(--wp--custom--radius--base);
	box-shadow: var(--wp--preset--shadow--card);
	padding: var(--wp--preset--spacing--60);
	height: 100%;
	transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.wp-block-group.is-style-card:hover {
	transform: translateY(-2px);
	box-shadow: var(--wp--preset--shadow--pop);
}

/* Cards are flex columns so a trailing arrow-link can pin to the base: three
   pillar cards previously ended their CTAs on three different baselines, one
   per body length. The accent bar is clipped by the card's own radius. */
.wp-block-group.is-style-card {
	display: flex;
	flex-direction: column;
	overflow: hidden;
}

.wp-block-group.is-style-card > .gr-link-arrow {
	margin-top: auto;
	padding-top: var(--wp--preset--spacing--40);
}

/* The audit form is a card by style but not by behaviour: without this it
   inherited the hover lift, so all five inputs jumped 2px whenever the
   pointer approached the form. */
.wp-block-group.is-style-card.gr-close-form:hover {
	transform: none;
	box-shadow: var(--wp--preset--shadow--card);
}

.wp-block-group.is-style-card-accent {
	background: var(--wp--preset--color--mist);
	border-radius: var(--wp--custom--radius--base);
	border-left: 4px solid var(--wp--preset--color--coral);
	padding: var(--wp--preset--spacing--60);
	height: 100%;
	/* Mist-on-mist: in the pain, outcomes and audience sections these cards
	   sit on a mist band, where their own mist fill gave 1:1 card contrast and
	   fourteen "cards" read as floating text. A hairline and a soft shadow
	   make the card an object again on either background. */
	border-top: 1px solid rgba(58, 46, 46, 0.08);
	border-right: 1px solid rgba(58, 46, 46, 0.08);
	border-bottom: 1px solid rgba(58, 46, 46, 0.08);
	box-shadow: 0 1px 2px rgba(58, 46, 46, 0.04);
	overflow: hidden;
	/* Same hover language as the plain cards, so the two card families move
	   as one system: a small lift, a deeper shadow, and the coral edge
	   sharpening to its ink shade. Transform and shadow only, and the global
	   reduced-motion rule flattens it for users who ask for that. */
	transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.22s ease, border-color 0.22s ease;
}

.wp-block-group.is-style-card-accent:hover {
	transform: translateY(-2px);
	box-shadow: var(--wp--preset--shadow--pop);
	border-left-color: var(--wp--preset--color--coral-ink);
}

.has-mist-background-color .wp-block-group.is-style-card-accent {
	background: var(--wp--preset--color--white);
}

/* Mono index numeral on service cards ("01."). */
.gr-card-num {
	font-family: var(--wp--preset--font-family--jetbrains-mono);
	font-size: var(--wp--preset--font-size--eyebrow);
	font-weight: 500;
	color: var(--wp--preset--color--taupe-ink);
	letter-spacing: 0.06em;
}

/* Rounded coral-tinted icon tile. */
.gr-icon-tile {
	width: 44px;
	height: 44px;
	display: grid;
	place-items: center;
	border-radius: var(--wp--custom--radius--sm);
	background: rgba(255, 90, 95, 0.12);
	color: var(--wp--preset--color--coral-ink);
	margin-bottom: var(--wp--preset--spacing--40);
}

.gr-icon-tile svg {
	width: 22px;
	height: 22px;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* ---------------------------------------------------------------------------
 * 7. Process steps (gradient numeral circles, cocoa text for AA)
 * ------------------------------------------------------------------------ */

.gr-step-num {
	width: 52px;
	height: 52px;
	display: grid;
	place-items: center;
	border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--preset--gradient--sunrise);
	color: var(--wp--preset--color--cocoa);
	font-family: var(--wp--preset--font-family--space-grotesk);
	font-weight: 700;
	font-size: 1.2rem;
	flex: none;
}

/* The circle used to sit alone on its own row with a card-width of dead space
   beside it. The heading now shares that row, vertically centred on the circle,
   and the body spans the full width beneath the pair. Applies to card steps and
   to plain (un-boxed) step groups alike, e.g. the "From Scope to Shipped" steps
   on the custom-software page. Scoped by :has(> .gr-step-num) so the pillar
   cards (mono "01." labels) keep their own stacked layout. */
.wp-block-group:has(> .gr-step-num) {
	display: grid;
	grid-template-columns: auto 1fr;
	column-gap: var(--wp--preset--spacing--40);
	row-gap: var(--wp--preset--spacing--40);
	align-content: start;
	align-items: center;
}

.wp-block-group:has(> .gr-step-num) > * {
	margin-top: 0;
	margin-bottom: 0;
}

.wp-block-group:has(> .gr-step-num) > h3 {
	grid-column: 2;
}

.wp-block-group:has(> .gr-step-num) > p:not(.gr-step-num) {
	grid-column: 1 / -1;
	align-self: start;
}

/* A four-step process reads cleanly as 1 / 2x2 / 4-across. WordPress' grid
   layout (minimumColumnWidth) auto-fills columns, which at some widths fits
   only three and orphans the fourth step on a row of its own. Fixed column
   counts at explicit breakpoints keep the rows balanced on every screen. The
   two-class selector outranks WP's generated .wp-container-* grid rule, so this
   wins regardless of stylesheet order; the block keeps minimumColumnWidth as a
   no-CSS fallback. */
.wp-block-group.gr-steps-4up {
	grid-template-columns: 1fr;
}

@media (min-width: 600px) {
	.wp-block-group.gr-steps-4up {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 960px) {
	.wp-block-group.gr-steps-4up {
		grid-template-columns: repeat(4, 1fr);
	}
}

/* ---------------------------------------------------------------------------
 * 8. Link with animated arrow
 * ------------------------------------------------------------------------ */

.gr-link-arrow a,
a.gr-link-arrow {
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
	font-weight: 600;
	font-family: var(--wp--preset--font-family--space-grotesk);
	text-decoration: none;
	/* These are the only links into the three money pages; at their natural
	   26px they were among the smallest tap targets on the site. */
	min-height: 44px;
}

.gr-link-arrow a::after,
a.gr-link-arrow::after {
	content: "\2192";
	transition: transform 0.18s ease;
}

.gr-link-arrow a:hover::after,
a.gr-link-arrow:hover::after {
	transform: translateX(4px);
}

/* ---------------------------------------------------------------------------
 * 9. FAQ accordion (native <details>, zero JS)
 * ------------------------------------------------------------------------ */

/* The list keeps the same content measure as every other section, so its left
   edge lines up with the headings above it, then splits into two columns on
   desktop so each answer holds a readable 65-75 character line. Single column
   on mobile. The width itself comes from the parent constrained layout, so
   there is deliberately no max-width override here. */
@media (min-width: 860px) {
	.gr-faq-list {
		display: grid;
		grid-template-columns: 1fr 1fr;
		column-gap: clamp(2.5rem, 5vw, 4.5rem);
		align-items: start;
	}
}

.gr-faq .wp-block-details {
	border-bottom: 1px solid rgba(58, 46, 46, 0.12);
	padding: var(--wp--preset--spacing--40) 0;
}

.gr-faq .wp-block-details summary {
	position: relative;
	cursor: pointer;
	list-style: none;
	padding-right: 2.25rem;
	font-family: var(--wp--preset--font-family--space-grotesk);
	font-weight: 600;
	color: var(--wp--preset--color--cocoa);
	line-height: 1.4;
	/* The row was 22px tall, well under the 44px touch minimum, on a control
	   that is tapped eleven times over on the densest section of the page.
	   Padding rather than height so multi-line questions still grow. */
	min-height: 44px;
	display: flex;
	align-items: center;
	padding-top: 0.6rem;
	padding-bottom: 0.6rem;
}

.gr-faq .wp-block-details summary::-webkit-details-marker {
	display: none;
}

.gr-faq .wp-block-details summary::after {
	content: "+";
	position: absolute;
	right: 0;
	top: 50%;
	transform: translateY(-50%);
	font-family: var(--wp--preset--font-family--jetbrains-mono);
	font-size: 1.35rem;
	line-height: 1;
	color: var(--wp--preset--color--coral-ink);
}

.gr-faq .wp-block-details[open] summary::after {
	content: "\2212";
}

.gr-faq .wp-block-details > :not(summary) {
	margin-top: var(--wp--preset--spacing--30);
	max-width: 68ch;
}

/* ---------------------------------------------------------------------------
 * 10. Comparison table (scrolls on phones instead of breaking the layout)
 * ------------------------------------------------------------------------ */

.gr-table-scroll {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}

/* Both homepage tables scroll inside themselves rather than widening the page.
   Without this a phone gets a horizontal scrollbar on the whole document. */
.wp-block-table.gr-compare,
.wp-block-table.gr-cost-table {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
	margin: 0;
}

.wp-block-table.gr-compare table,
.wp-block-table.gr-cost-table table {
	border-collapse: collapse;
	width: 100%;
}

.wp-block-table.gr-compare table {
	min-width: 44rem;
}

.wp-block-table.gr-compare :where(th, td),
.wp-block-table.gr-cost-table :where(th, td) {
	border: 1px solid rgba(58, 46, 46, 0.12);
	padding: 0.85rem 1rem;
	text-align: left;
	vertical-align: top;
}

.wp-block-table.gr-compare thead th,
.wp-block-table.gr-cost-table thead th {
	background: var(--wp--preset--color--cocoa);
	color: var(--wp--preset--color--white);
	font-family: var(--wp--preset--font-family--space-grotesk);
	/* 700, not 600: with the static faces, 600 resolved up to the 700 file, so
	   this is what the headers have always rendered at. The variable face would
	   otherwise thin them out in the two tables under the most scrutiny. */
	font-weight: 700;
	vertical-align: bottom;
}

/* The shared is-style-compare rules mark column two as "ours". This table leads
   with the question a buyer should ask, so the emphasis sits one column across. */
.wp-block-table.gr-compare tbody td:nth-child(3) {
	background: rgba(255, 90, 95, 0.07);
	font-weight: 500;
}

.wp-block-table.gr-compare thead th:nth-child(3) {
	background: var(--wp--preset--color--coral-ink);
}

.wp-block-table.gr-compare tbody td:nth-child(2) {
	color: var(--wp--preset--color--taupe-ink);
}

/* On phones the 44rem table put the "Ours" column 118px past the right edge
   with no scroll affordance — a reader saw eight rows of criticism of other
   agencies and none of our answers. Below 782px each row becomes a labelled
   card: question on top, both answers beneath it, nothing hidden. Dropping
   native table semantics on mobile is the accepted cost of this pattern. */
@media (max-width: 781px) {
	.wp-block-table.gr-compare table,
	.wp-block-table.gr-compare tbody,
	.wp-block-table.gr-compare tbody tr,
	.wp-block-table.gr-compare tbody td {
		display: block;
		width: 100%;
	}

	.wp-block-table.gr-compare table {
		min-width: 0;
	}

	.wp-block-table.gr-compare thead {
		display: none;
	}

	.wp-block-table.gr-compare tbody tr {
		border: 1px solid rgba(58, 46, 46, 0.12);
		border-radius: var(--wp--custom--radius--base);
		margin-bottom: var(--wp--preset--spacing--40);
		overflow: hidden;
	}

	.wp-block-table.gr-compare tbody td {
		border: 0;
	}

	.wp-block-table.gr-compare tbody td:first-child {
		background: var(--wp--preset--color--cocoa);
		color: var(--wp--preset--color--white);
		font-family: var(--wp--preset--font-family--space-grotesk);
		font-weight: 700;
	}

	.wp-block-table.gr-compare tbody td[data-label]::before {
		content: attr(data-label);
		display: block;
		font-family: var(--wp--preset--font-family--jetbrains-mono);
		font-size: 0.7rem;
		letter-spacing: 0.05em;
		text-transform: uppercase;
		color: var(--wp--preset--color--taupe-ink);
		margin-bottom: 0.25rem;
	}

	.wp-block-table.gr-compare tbody td[data-label="Ours"]::before {
		color: var(--wp--preset--color--coral-ink);
	}
}

/* Mobile reading order in the cost section.
   The desktop layout puts the closing line and the CTA in the left column so it
   matches the height of the two cards opposite. Stacked on a phone that means
   the reader met the big number, then the ask, and only afterwards the two cards
   that argue the number back down — which is the whole reason the section reads
   as honest rather than as a scare. `display: contents` drops the column boxes
   out of the layout so the six children can be ordered individually: table,
   both cards, then the conclusion and the ask. No markup or copy changes. */
@media (max-width: 781px) {
	.gr-cost-columns {
		display: flex;
		flex-direction: column;
		gap: var(--wp--preset--spacing--50);
	}

	.gr-cost-columns > .wp-block-column {
		display: contents;
	}

	.gr-cost-columns .gr-cost-table {
		order: 1;
	}

	.gr-cost-columns .is-style-card-accent {
		order: 2;
		margin-top: 0;
	}

	.gr-cost-columns > .wp-block-column > p {
		order: 3;
		margin-top: 0;
	}

	.gr-cost-columns .wp-block-buttons {
		order: 4;
		margin-top: 0;
	}
}

/* The cost table is doing arithmetic, so the figures are set in the mono face
   with tabular figures — and right-aligned, because tabular numerals only
   line up digit-for-digit when the digits share an edge. */
.wp-block-table.gr-cost-table :where(td) {
	font-family: var(--wp--preset--font-family--jetbrains-mono);
	font-variant-numeric: tabular-nums;
	text-align: right;
}

.wp-block-table.gr-cost-table thead th {
	text-align: right;
}

.wp-block-table.gr-cost-table :where(td, th):first-child {
	text-align: left;
}

.wp-block-table.gr-cost-table tbody td:nth-child(2) {
	font-weight: 700;
	color: var(--wp--preset--color--coral-ink);
	font-size: 1.15em;
}

.wp-block-table.gr-cost-table figcaption {
	margin-top: var(--wp--preset--spacing--30);
	color: var(--wp--preset--color--taupe-ink);
	font-size: var(--wp--preset--font-size--small);
}

/* Risk reversal restated under the final CTA, separated by a hairline so it
   reads as a footnote to the decision rather than another paragraph. */
.gr-risk-strip {
	border-top: 1px solid rgba(255, 255, 255, 0.14);
	padding-top: var(--wp--preset--spacing--40);
	max-width: 62ch;
	margin-top: var(--wp--preset--spacing--50);
}

/* Paired columns where the left runs short: stretch it and pin its closing
   element to the bottom, so the whitespace sits between the paragraphs and
   the anchor instead of pooling as a void under the column. Why-us pins the
   automation link (107px void); the closing section pins the risk strip,
   which otherwise floated 144px above the form at the decision moment. */
@media (min-width: 782px) {
	.gr-why-cols > .wp-block-column:first-child,
	.gr-close .wp-block-columns > .wp-block-column:first-child {
		align-self: stretch;
		display: flex;
		flex-direction: column;
	}

	.gr-why-cols > .wp-block-column:first-child > .gr-link-arrow,
	.gr-close .wp-block-columns > .wp-block-column:first-child > .gr-risk-strip {
		margin-top: auto;
		padding-top: var(--wp--preset--spacing--40);
	}
}

/* ---------------------------------------------------------------------------
 * 13b. Homepage closing section
 *
 * The audit form inline, so the ask does not cost a page load. Five stacked
 * fields make a very tall column, which left the copy beside it trailing off
 * into empty space; pairing the four short fields two-up on wide screens brings
 * the two columns to roughly the same height without touching the shortcode.
 * ------------------------------------------------------------------------ */

.gr-close-steps {
	padding-left: 1.1rem;
	margin-bottom: var(--wp--preset--spacing--50);
}

.gr-close-steps li {
	margin-bottom: 0.45rem;
}

.gr-close-steps li::marker {
	color: var(--wp--preset--color--amber);
}

.gr-close-form {
	padding: var(--wp--preset--spacing--50);
}

@media (min-width: 900px) {
	/* Hidden inputs are display:none and the honeypot is absolutely positioned,
	   so neither becomes a grid item. The six paragraphs are the only children
	   that lay out here. */
	.gr-close-form .gr-form {
		display: grid;
		grid-template-columns: 1fr 1fr;
		column-gap: 1rem;
	}

	.gr-close-form .gr-form > p:nth-of-type(5),
	.gr-close-form .gr-form > p:nth-of-type(6) {
		grid-column: 1 / -1;
	}
}

.wp-block-table.is-style-compare table {
	border-collapse: collapse;
	min-width: 34rem;
}

.wp-block-table.is-style-compare :where(th, td) {
	border: 1px solid rgba(58, 46, 46, 0.12);
	padding: 0.85rem 1rem;
	text-align: left;
	vertical-align: middle;
}

.wp-block-table.is-style-compare thead th {
	background: var(--wp--preset--color--cocoa);
	color: var(--wp--preset--color--white);
	font-family: var(--wp--preset--font-family--space-grotesk);
	font-weight: 600;
}

.wp-block-table.is-style-compare tbody tr:nth-child(odd) td {
	background: var(--wp--preset--color--mist);
}

/* Highlight the "ours" column. */
.wp-block-table.is-style-compare :where(th, td):nth-child(2) {
	background: rgba(255, 90, 95, 0.07);
	font-weight: 500;
}

.wp-block-table.is-style-compare thead th:nth-child(2) {
	background: var(--wp--preset--color--coral-ink);
}

/* ---------------------------------------------------------------------------
 * 11. Lists
 * ------------------------------------------------------------------------ */

.wp-block-list.is-style-check,
.wp-block-list.is-style-arrow {
	list-style: none;
	padding-left: 0;
}

.wp-block-list.is-style-check li,
.wp-block-list.is-style-arrow li {
	position: relative;
	padding-left: 1.6em;
	margin-bottom: 0.5em;
}

.wp-block-list.is-style-check li::before {
	content: "\2713";
	position: absolute;
	left: 0;
	color: var(--wp--preset--color--coral-ink);
	font-weight: 700;
}

.wp-block-list.is-style-arrow li::before {
	content: "\2192";
	position: absolute;
	left: 0;
	color: var(--wp--preset--color--amber);
	font-weight: 700;
}

/* ---------------------------------------------------------------------------
 * 12. Sticky header
 * ------------------------------------------------------------------------ */

.gr-header {
	transition: box-shadow 0.2s ease;
}

.gr-header.is-scrolled {
	box-shadow: var(--wp--preset--shadow--nav);
}

/* Site Editor sticky-position fallback: a sticky Group inside a template part
   only sticks to its wrapper, so promote the wrapper itself. */
.wp-site-blocks > header:has(.gr-header) {
	position: sticky;
	top: 0;
	z-index: 100;
}

/* The sticky header otherwise covers whatever a fragment jump or sequential
   focus lands on: the in-page CTAs point at #contact-form, the thank-you
   redirect targets #gr-form-thanks, and tabbing must never put focus under
   the bar. Values track the measured header heights (~87px desktop, ~69px
   mobile) plus breathing room. */
html {
	scroll-padding-top: 104px;
}

@media (max-width: 781px) {
	html {
		scroll-padding-top: 84px;
	}
}

/* Sized by height so the lockup scales predictably. The trimmed artwork is a
   4.4:1 wordmark, so it grows wide fast and it shares a nowrap row with the
   menu toggle and the CTA. At 360px a 44px logo left the CTA only 58px, which
   wrapped "Get a Free Audit" onto four lines and made a 157px-tall button.
   The logo steps down and the CTA shortens to "Free Audit" to prevent that. */
.gr-header .wp-block-site-logo img {
	height: 36px;
	width: auto;
	max-width: none;
}

/* 320px is the WCAG reflow floor and the row still has to hold logo, toggle
   and CTA. A 36px logo is 159px wide, which pushed the row to 355px; 30px
   brings it to ~132px and the whole row back inside the viewport. The inner
   header row also gets a tighter gap at this width. */
@media (max-width: 399.98px) {
	.gr-header .wp-block-site-logo img {
		height: 30px;
	}

	.gr-header .wp-block-group.is-nowrap {
		gap: 0.5rem;
	}
}

@media (min-width: 480px) {
	.gr-header .wp-block-site-logo img {
		height: 44px;
	}
}

@media (min-width: 600px) {
	.gr-header .wp-block-site-logo img {
		height: 52px;
	}
}

/* The header CTA must never wrap: a squeezed multi-line pill is the single
   ugliest thing a visitor sees first. Below the desktop breakpoint it drops the
   "Get a " and tightens, so it stays one line and stays tappable at 44px. */
.gr-header .wp-block-button__link {
	white-space: nowrap;
}

/* The menu toggle rendered at 24x24: the primary navigation control on mobile,
   at about a quarter of the recommended tap area. The icon keeps its size, the
   hit area grows around it.

   The static nav below replaced the core navigation block and its 135KB
   Interactivity API runtime. Progressive enhancement runs in the safe
   direction: without JS the toggle stays hidden and the menu renders in full,
   so no script failure can ever lose the navigation. interactions.js adds
   .gr-nav-js and drives the drawer. */
.gr-nav-toggle {
	min-width: 44px;
	min-height: 44px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: transparent;
	border: 0;
	padding: 0;
	color: var(--wp--preset--color--cocoa);
	cursor: pointer;
}

.gr-nav-toggle[hidden] {
	display: none;
}

@media (min-width: 782px) {
	.gr-nav-toggle {
		display: none !important;
	}
}

.gr-nav-menu,
.gr-nav-sub {
	list-style: none;
	margin: 0;
	padding: 0;
}

.gr-nav-menu > li > a,
.gr-nav-sub-btn {
	color: var(--wp--preset--color--cocoa);
	text-decoration: none;
	font-weight: 500;
	background: transparent;
	border: 0;
	padding: 0;
	font-size: inherit;
	font-family: inherit;
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	gap: 0.35em;
}

/* Desktop: inline row with a hover / focus-within dropdown. */
@media (min-width: 782px) {
	.gr-nav-menu {
		display: flex;
		align-items: center;
		gap: var(--wp--preset--spacing--50);
	}

	.gr-nav-has-sub {
		position: relative;
	}

	.gr-nav-sub {
		position: absolute;
		top: calc(100% + 10px);
		left: 50%;
		transform: translateX(-50%);
		background: var(--wp--preset--color--cocoa);
		border: 1px solid rgba(255, 255, 255, 0.12);
		border-radius: 10px;
		padding: 6px 0;
		box-shadow: 0 18px 40px rgba(58, 46, 46, 0.28);
		min-width: 232px;
		display: none;
		z-index: 60;
	}

	/* Hover bridge: without it the pointer falls into the 10px gap between the
	   trigger and the panel and the menu snaps shut mid-travel. */
	.gr-nav-has-sub::after {
		content: "";
		position: absolute;
		inset: 100% 0 -12px 0;
		display: none;
	}

	.gr-nav-has-sub:hover::after,
	.gr-nav-has-sub:focus-within::after,
	.gr-nav-has-sub:hover > .gr-nav-sub,
	.gr-nav-has-sub:focus-within > .gr-nav-sub {
		display: block;
	}

	.gr-nav-sub a {
		display: flex;
		align-items: center;
		padding: 9px 18px;
		color: var(--wp--preset--color--white);
		text-decoration: none;
	}

	.gr-nav-sub a:hover,
	.gr-nav-sub a:focus-visible {
		color: var(--wp--preset--color--amber);
	}
}

/* Mobile: with JS, the menu is a drawer under the header; the Services group
   renders always-open, so there is no second tap and no sub-toggle script. */
@media (max-width: 781.98px) {
	.gr-nav-js .gr-nav-menu {
		display: none;
	}

	.gr-nav.is-open .gr-nav-menu {
		display: block;
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		background: var(--wp--preset--color--cocoa);
		padding: var(--wp--preset--spacing--50) var(--wp--custom--gutter) var(--wp--preset--spacing--60);
		box-shadow: 0 24px 40px rgba(58, 46, 46, 0.35);
		z-index: 90;
	}

	.gr-header .wp-block-group.is-nowrap {
		position: relative;
	}

	.gr-nav-menu > li {
		border-bottom: 1px solid rgba(255, 255, 255, 0.12);
	}

	.gr-nav-menu > li > a {
		display: flex;
		align-items: center;
		width: 100%;
		min-height: 48px;
		padding-block: 0.65rem;
		color: var(--wp--preset--color--white);
		font-size: var(--wp--preset--font-size--lg);
	}

	/* Group label, not a control, in the drawer. */
	.gr-nav-sub-btn {
		pointer-events: none;
		color: rgba(255, 255, 255, 0.6);
		font-family: var(--wp--preset--font-family--jetbrains-mono);
		font-size: 0.72rem;
		letter-spacing: 0.08em;
		text-transform: uppercase;
		padding-block: 0.65rem 0.15rem;
	}

	.gr-nav-sub-btn svg {
		display: none;
	}

	.gr-nav-sub a {
		display: flex;
		align-items: center;
		width: 100%;
		min-height: 48px;
		padding: 0.5rem 0 0.5rem 0.9rem;
		color: var(--wp--preset--color--white);
		font-size: var(--wp--preset--font-size--lg);
		text-decoration: none;
	}
}

/* No-JS mobile: the menu simply renders stacked below the logo row — plain,
   but complete and usable. */
@media (max-width: 781.98px) {
	.gr-nav:not(.gr-nav-js) .gr-nav-menu > li > a,
	.gr-nav:not(.gr-nav-js) .gr-nav-sub a {
		color: var(--wp--preset--color--cocoa);
	}

	.gr-nav:not(.gr-nav-js) .gr-nav-sub-btn {
		color: var(--wp--preset--color--taupe-ink);
	}
}

/* "All Services" hub link: a view-all affordance at the foot of the Services
   dropdown so /services/ — and the supporting service pages it links — stays one
   click from the nav. Divider + weight set it apart from the pillar links. */
.gr-nav-sub-all {
	border-top: 1px solid rgba(255, 255, 255, 0.12);
	margin-top: 4px;
}

.gr-nav-sub-all a {
	font-weight: 600;
}

/* A 1x1 skip link is technically present and practically unusable for the
   keyboard users it exists to serve. It stays visually hidden until focused,
   then becomes a real control. */
.skip-link:focus,
.skip-link:focus-visible {
	position: fixed !important;
	top: 12px;
	left: 12px;
	z-index: 1000;
	width: auto !important;
	height: auto !important;
	clip: auto !important;
	clip-path: none !important;
	padding: 0.75rem 1.1rem;
	background: var(--wp--preset--color--cocoa);
	color: var(--wp--preset--color--white);
	border-radius: var(--wp--custom--radius--sm);
	font-size: var(--wp--preset--font-size--small);
	text-decoration: none;
}

@media (max-width: 781px) {
	.gr-header .gr-cta-long {
		display: none;
	}

	.gr-header .wp-block-button__link {
		font-size: 0.82rem !important;
		padding: 11px 14px !important;
		/* Tightening the padding to fit the row dropped the pill to 38px tall.
		   44px is the floor for a touch target, so it is enforced here rather
		   than left to whatever the font and padding happen to produce. */
		min-height: 44px;
		display: inline-flex;
		align-items: center;
	}
}

/* Inline links inside running text get an underline, so they are distinguishable
   without relying on colour (WCAG link-in-text-block). Arrow-links, buttons, and
   nav are excluded: those are distinguishable by position or shape.
   The list-item half is scoped to content areas on purpose. WCAG 1.4.1 is about
   links sitting inside a block of text, where colour alone leaves them ambiguous.
   In the footer columns and the Services dropdown every item is a link, so there
   is nothing to disambiguate and the underlines are just noise. */
:where(.gr-prose, .gr-faq, main .wp-block-column, .entry-content) p:not(.gr-link-arrow) a,
:where(.gr-prose, .gr-faq, main .wp-block-column, .entry-content) li a:not(.wp-block-navigation-item__content) {
	text-decoration: underline;
	text-underline-offset: 0.15em;
	text-decoration-thickness: 1px;
}

/* The full-size logo waits until 900px: at exactly 782px the inline menu and
   the 62px logo (274px wide) together overflowed the row by one pixel. */
@media (min-width: 900px) {
	.gr-header .wp-block-site-logo img {
		height: 62px;
	}
}

/* ---------------------------------------------------------------------------
 * 13. Footer
 * ------------------------------------------------------------------------ */

/* The CTA band and the footer are both cocoa, so the default block gap between
   <main> and the footer template part showed up as a white sliver dividing two
   identical dark surfaces. Close it so the page ends in one continuous dark
   zone, and mark the boundary with a hairline instead: the CTA is the decision
   moment, the footer is navigation, and they still need to read as separate. */
.wp-site-blocks > footer {
	margin-block-start: 0;
}

.gr-footer {
	border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.gr-footer .wp-block-image img {
	height: 64px;
	width: auto;
	max-width: none;
}

.gr-footer :where(p, li, a) {
	color: rgba(255, 255, 255, 0.72);
}

/* Link columns are navigation, not prose: no bullets, flush left. */
.gr-footer .wp-block-list {
	list-style: none;
	padding-left: 0;
	margin-left: 0;
}

/* Belt and braces against any inherited underline in the two link lists. Hover
   and focus still change colour, and the global focus ring is untouched, so
   these stay distinguishable without the rules. */
.gr-footer a,
.gr-footer a:hover,
.gr-footer a:focus-visible,
.gr-header .wp-block-navigation__submenu-container a,
.gr-header .wp-block-navigation__submenu-container a:hover,
.gr-header .wp-block-navigation__submenu-container a:focus-visible {
	text-decoration: none;
}

.gr-footer a:hover {
	color: var(--wp--preset--color--white);
}

.gr-footer h2,
.gr-footer h3 {
	color: var(--wp--preset--color--white);
	font-size: var(--wp--preset--font-size--small);
	text-transform: uppercase;
	letter-spacing: 0.08em;
	font-family: var(--wp--preset--font-family--jetbrains-mono);
	font-weight: 500;
}

/* ---------------------------------------------------------------------------
 * 14. Forms
 * ------------------------------------------------------------------------ */

.gr-form :where(input[type="text"], input[type="email"], input[type="tel"], input[type="url"], textarea, select) {
	/* Form controls do not inherit the document's border-box sizing, so
	   width:100% plus 1.8rem of padding and 2px of border made every field
	   about 31px wider than the column holding it. In a single-column form that
	   only spilled past the edge; side by side it made the fields overlap each
	   other outright. */
	box-sizing: border-box;
	width: 100%;
	font-family: var(--wp--preset--font-family--inter);
	font-size: var(--wp--preset--font-size--base);
	color: var(--wp--preset--color--cocoa);
	background: var(--wp--preset--color--white);
	border: 1px solid rgba(58, 46, 46, 0.18);
	border-radius: var(--wp--custom--radius--sm);
	padding: 0.75rem 0.9rem;
	/* 16px minimum prevents iOS Safari from zooming on focus. */
	min-height: 44px;
}

/* Full-strength ring: the old 25%-alpha wash measured 1.47:1 against white,
   invisible to exactly the low-vision users a focus ring exists for. */
.gr-form :where(input, textarea, select):focus {
	border-color: var(--wp--preset--color--coral-ink);
	outline: 2px solid var(--wp--preset--color--coral-ink);
	outline-offset: 2px;
}

.gr-form label {
	display: block;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	color: var(--wp--preset--color--cocoa);
	margin-bottom: 0.35rem;
}

/* Required marker. Coral-ink rather than plain coral so the small text still
   clears AA on both white and mist, and the whole thing reads as one phrase
   with the label rather than as a floating symbol. */
.gr-form .gr-req {
	font-weight: 400;
	font-size: 0.78em;
	letter-spacing: 0.02em;
	color: var(--wp--preset--color--coral-ink);
	white-space: nowrap;
}

.gr-form .gr-optional {
	font-weight: 400;
	font-size: 0.78em;
	color: var(--wp--preset--color--taupe-ink);
	white-space: nowrap;
}

/* Validation errors render in place above the fields, get focus, and link to
   the fields they name. Coral-ink on a pale wash clears AA. */
.gr-form-error {
	grid-column: 1 / -1;
	background: rgba(198, 53, 59, 0.07);
	border: 1px solid rgba(198, 53, 59, 0.35);
	border-radius: var(--wp--custom--radius--sm);
	padding: 0.9rem 1.1rem;
	margin-bottom: var(--wp--preset--spacing--30);
}

.gr-form-error p {
	margin: 0 0 0.35rem;
	color: var(--wp--preset--color--coral-ink);
}

.gr-form-error ul {
	margin: 0;
	padding-left: 1.1rem;
}

.gr-form-error a {
	color: var(--wp--preset--color--coral-ink);
	text-decoration: underline;
	text-underline-offset: 0.15em;
}

.gr-form-error:focus {
	outline: 3px solid var(--wp--preset--color--coral-ink);
	outline-offset: 3px;
}

.gr-form :where(input, textarea)[aria-invalid="true"] {
	border-color: var(--wp--preset--color--coral-ink);
}

/* The data-handling note spans both columns of the form grid; half-width it
   would reintroduce the whitespace imbalance beside the button. */
.gr-form-note {
	grid-column: 1 / -1;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--taupe-ink);
	line-height: 1.6;
	margin-top: 0.25rem;
}

/* Focus lands on the thank-you heading programmatically after the redirect,
   so this uses :focus (not :focus-visible, which script focus does not
   always trigger). */
.gr-form-thanks-title:focus {
	outline: 3px solid var(--wp--preset--color--coral-ink);
	outline-offset: 4px;
}

.gr-form p {
	margin: 0 0 1rem;
}

.gr-form button {
	cursor: pointer;
	border: 0;
	width: 100%;
}

@media (min-width: 480px) {
	.gr-form button {
		width: auto;
	}
}

.gr-form-thanks {
	background: var(--wp--preset--color--mist);
	border-left: 4px solid var(--wp--preset--color--coral);
	border-radius: var(--wp--custom--radius--base);
	padding: var(--wp--preset--spacing--60);
}

.gr-form-thanks p:last-child {
	margin-bottom: 0;
}

/* ---------------------------------------------------------------------------
 * 14b. Inline SVG diagrams
 *
 * On-brand vector illustrations built in place, in the Sunrise Coral palette.
 * Deliberately used instead of stock photography: crisp at any size, a few KB,
 * no external request, and a better fit for an engineer-led brand than a
 * generic photo. A max-width keeps them from ballooning on wide screens.
 * ------------------------------------------------------------------------ */

.gr-diagram {
	max-width: 760px;
	margin-inline: 0;
}

.gr-diagram svg {
	width: 100%;
	height: auto;
}

/* On a cocoa section the node fills and text need to stay legible; these
   diagrams are authored for light sections, so keep them on mist/white bands. */

.gr-diagram figcaption {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--taupe-ink);
	margin-top: var(--wp--preset--spacing--30);
}

/* ---------------------------------------------------------------------------
 * 14c. Product mockups (app-window screenshots with sample data)
 *
 * Honest alternative to a faked screenshot: a real HTML/CSS representation of
 * the software, always paired with a visible "sample data" caption. This is how
 * you show what a system looks like without leaking a customer's private data
 * or inventing a screenshot. Every .gr-mock must sit next to a .gr-mock-note.
 * ------------------------------------------------------------------------ */

.gr-mock {
	background: var(--wp--preset--color--white);
	border: 1px solid rgba(58, 46, 46, 0.14);
	border-radius: var(--wp--custom--radius--lg);
	box-shadow: var(--wp--preset--shadow--pop);
	overflow: hidden;
}

.gr-mock-bar {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.7rem 0.9rem;
	background: var(--wp--preset--color--mist);
	border-bottom: 1px solid rgba(58, 46, 46, 0.1);
}

.gr-mock-bar i {
	width: 10px;
	height: 10px;
	border-radius: 50%;
	background: rgba(58, 46, 46, 0.18);
}

.gr-mock-bar span {
	margin-left: 0.4rem;
	font-family: var(--wp--preset--font-family--jetbrains-mono);
	font-size: 0.7rem;
	letter-spacing: 0.04em;
	color: var(--wp--preset--color--taupe-ink);
}

.gr-mock-body {
	padding: 1.1rem;
}

.gr-mock-tiles {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 0.7rem;
	margin-bottom: 1rem;
}

.gr-mock-tile {
	background: var(--wp--preset--color--mist);
	border-radius: var(--wp--custom--radius--sm);
	padding: 0.7rem 0.8rem;
}

.gr-mock-tile b {
	display: block;
	font-family: var(--wp--preset--font-family--space-grotesk);
	font-size: 1.15rem;
	color: var(--wp--preset--color--cocoa);
	line-height: 1.1;
}

.gr-mock-tile b.pos {
	color: #2e7d52;
}

.gr-mock-tile b.neg {
	color: var(--wp--preset--color--coral-ink);
}

.gr-mock-tile small {
	font-size: 0.7rem;
	color: var(--wp--preset--color--taupe-ink);
}

.gr-mock table {
	width: 100%;
	border-collapse: collapse;
	font-size: 0.78rem;
}

.gr-mock th,
.gr-mock td {
	text-align: left;
	padding: 0.5rem 0.55rem;
	border-bottom: 1px solid rgba(58, 46, 46, 0.08);
}

.gr-mock th {
	font-family: var(--wp--preset--font-family--jetbrains-mono);
	font-size: 0.66rem;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--wp--preset--color--taupe-ink);
}

.gr-mock .pill {
	display: inline-block;
	padding: 0.1rem 0.5rem;
	border-radius: var(--wp--custom--radius--pill);
	font-size: 0.68rem;
	font-weight: 600;
}

.gr-mock .pill.done {
	background: rgba(46, 125, 82, 0.12);
	/* Darkened from #2e7d52 (4.29:1) to pass AA on the light-green pill. */
	color: #1f6a42;
}

.gr-mock .pill.due {
	background: rgba(255, 182, 39, 0.18);
	color: #8a6400;
}

.gr-mock-note {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--taupe-ink);
	margin-top: var(--wp--preset--spacing--30);
	font-style: italic;
}

/* ---------------------------------------------------------------------------
 * 14d. Mechanism flow (the hero illustration)
 *
 * A sequence diagram, not a screenshot. It replaced a dashboard of invented
 * performance figures, so the one rule that matters here is that it must never
 * become convincing as a captured conversation: no carrier bar, no battery
 * icon, no avatars, no chat bubbles, no green/blue message tinting. Timestamps
 * are set in the mono "instrumentation" face to read as annotation, and the
 * connecting rule makes it read as a flow rather than a transcript.
 * ------------------------------------------------------------------------ */

.gr-flow-steps {
	list-style: none;
	margin: 0;
	padding: 0;
}

/* The marker and its spine live in the gutter between the timestamp and the
   text. Positioning them inside the timestamp column overlaps the figures and
   eats a digit, which is easy to miss at a glance and unreadable up close. */
.gr-flow-steps li {
	position: relative;
	display: grid;
	grid-template-columns: 4rem 1fr;
	gap: 1.6rem;
	padding: 0 0 var(--wp--preset--spacing--30) 0;
}

.gr-flow-steps li:last-child {
	padding-bottom: 0;
}

.gr-flow-steps li::after {
	content: "";
	position: absolute;
	left: 4.7rem;
	top: 0.42rem;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--wp--preset--color--coral-ink);
}

.gr-flow-steps li:not(:last-child)::before {
	content: "";
	position: absolute;
	left: calc(4.7rem + 3px);
	top: 1.1rem;
	bottom: 0.1rem;
	width: 1px;
	background: rgba(58, 46, 46, 0.16);
}

.gr-flow-time {
	font-family: var(--wp--preset--font-family--jetbrains-mono);
	font-size: 0.68rem;
	font-variant-numeric: tabular-nums;
	letter-spacing: 0.02em;
	color: var(--wp--preset--color--taupe-ink);
	padding-top: 0.15em;
}

.gr-flow-text {
	font-size: 0.86rem;
	line-height: 1.5;
	color: var(--wp--preset--color--cocoa);
}

/* The reply is the turn that matters, so it carries the only emphasis. */
.gr-flow-steps li:nth-child(3) .gr-flow-text {
	font-weight: 600;
}

/* Narrow phones: the fixed 4.4rem timestamp gutter squeezed the text to
   ~16-character lines in the block that carries the hero's whole explanation.
   The timestamp stacks above the text and the spine/marker hide, since their
   fixed offsets no longer line up with anything. */
@media (max-width: 480px) {
	.gr-flow .gr-flow-steps li {
		grid-template-columns: 1fr;
		gap: 0.15rem;
		padding-left: 0;
	}

	.gr-flow .gr-flow-steps li::before,
	.gr-flow .gr-flow-steps li::after {
		display: none;
	}
}

/* On a phone the hero has to stay short enough that the primary CTA is not
   pushed under the fold, so the diagram drops its last beat. The three that
   remain still carry the whole mechanism: missed, answered, replied. */
@media (max-width: 781px) {
	.gr-flow-steps li:last-child {
		display: none;
	}

	.gr-flow-steps li:nth-last-child(2) {
		padding-bottom: 0;
	}

	.gr-flow-steps li:nth-last-child(2)::before {
		display: none;
	}
}

/* ---------------------------------------------------------------------------
 * 15. Prose measure on long-form content
 * ------------------------------------------------------------------------ */

.gr-prose > :where(p, ul, ol, h2, h3, h4, blockquote) {
	max-width: 68ch;
}

/* ===========================================================================
 * PREMIUM VISUAL LAYER (depth, grain, mesh, bento, device frame, type)
 * The redesign's "material" rules. Warm developer-tooling, set editorially.
 * ======================================================================== */

/* --- Film grain: kills gradient banding, adds tactile richness on cocoa --- */
.gr-hero,
.gr-cta,
.gr-dark {
	position: relative;
	isolation: isolate;
}

/* Grain is deferred to post-load (html.gr-motion-ready) so its blended layer
   never competes with the hero's LCP paint. No-JS still gets a clean hero. */
html.gr-motion-ready .gr-hero::after,
html.gr-motion-ready .gr-cta::after,
html.gr-motion-ready .gr-dark.gr-grain::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	opacity: 0.5;
	mix-blend-mode: soft-light;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Keep hero/CTA content above the grain + glow layers. */
.gr-hero > *,
.gr-cta > * {
	position: relative;
	z-index: 1;
}

/* --- Animated sunrise mesh drift behind cocoa heroes (barely perceptible) --- */
.gr-hero::before {
	background:
		radial-gradient(60% 55% at 15% 10%, rgba(255, 90, 95, 0.26) 0%, transparent 60%),
		radial-gradient(52% 50% at 88% 85%, rgba(255, 134, 39, 0.18) 0%, transparent 60%),
		radial-gradient(40% 40% at 60% 40%, rgba(255, 90, 95, 0.10) 0%, transparent 70%);
	transform: translate3d(var(--gr-px, 0), var(--gr-py, 0), 0);
}

/* The mesh only drifts once the page is interactive, so it never gates LCP.
   motion.js adds .gr-motion-ready after init. */
html.gr-motion-ready .gr-hero::before {
	background-size: 160% 160%, 170% 170%, 150% 150%;
	animation: gr-mesh 26s ease-in-out 1s infinite alternate;
}

@keyframes gr-mesh {
	0%   { background-position: 0% 0%, 100% 100%, 50% 50%; }
	100% { background-position: 20% 15%, 80% 85%, 60% 40%; }
}

/* Faint precision grid on cocoa surfaces (the "engineered" texture).
   Deferred to post-load so the masked layer never gates the hero LCP paint. */
html.gr-motion-ready .gr-hero .gr-hero-split::before,
html.gr-motion-ready .gr-hero .gr-hero-inner::before {
	content: "";
	position: absolute;
	inset: -40px 0;
	z-index: -1;
	pointer-events: none;
	background-image:
		linear-gradient(rgba(255, 255, 255, 0.035) 1px, transparent 1px),
		linear-gradient(90deg, rgba(255, 255, 255, 0.035) 1px, transparent 1px);
	background-size: 44px 44px;
	mask-image: radial-gradient(75% 75% at 25% 40%, #000 0%, transparent 78%);
	-webkit-mask-image: radial-gradient(75% 75% at 25% 40%, #000 0%, transparent 78%);
}

.gr-hero-inner,
.gr-hero-split {
	position: relative;
}

/* --- Depth tokens: longer, warmer, cocoa-tinted shadows --- */
.gr-shadow-lift {
	box-shadow: 0 18px 50px -18px rgba(58, 46, 46, 0.28), 0 4px 14px -8px rgba(58, 46, 46, 0.18);
}

/* --- Type: louder display, tighter tracking --- */
.gr-hero h1 {
	font-size: clamp(2.4rem, 5.2vw, 4.4rem) !important;
	line-height: 1.03;
	letter-spacing: -0.025em;
	max-width: 15ch;
}

/* --- Split hero (asymmetric on desktop, stacked on mobile) --- */
@media (min-width: 900px) {
	.gr-hero-split {
		display: grid;
		grid-template-columns: 1.15fr 0.85fr;
		gap: clamp(2rem, 5vw, 4.5rem);
		align-items: center;
	}
}

.gr-hero-visual {
	position: relative;
	display: flex;
	justify-content: center;
}

/* --- Phone device frame + live SMS demo (product = our "photography") --- */
.gr-phone {
	position: relative;
	width: min(300px, 78vw);
	aspect-ratio: 300 / 620;
	background: #241c1c;
	border-radius: 40px;
	padding: 12px;
	box-shadow: 0 40px 80px -30px rgba(0, 0, 0, 0.55), inset 0 0 0 1px rgba(255, 255, 255, 0.06);
}

.gr-phone::before {
	content: "";
	position: absolute;
	top: 14px;
	left: 50%;
	transform: translateX(-50%);
	width: 42%;
	height: 20px;
	background: #241c1c;
	border-radius: 0 0 14px 14px;
	z-index: 3;
}

.gr-phone-screen {
	height: 100%;
	border-radius: 30px;
	background: linear-gradient(180deg, #fbf4f1 0%, #ffffff 100%);
	overflow: hidden;
	display: flex;
	flex-direction: column;
}

.gr-phone-top {
	background: var(--wp--preset--color--cocoa);
	color: #fff;
	padding: 30px 16px 12px;
	font-family: var(--wp--preset--font-family--space-grotesk);
	font-weight: 600;
	font-size: 0.9rem;
	display: flex;
	align-items: center;
	gap: 8px;
}

.gr-phone-top small {
	display: block;
	font-family: var(--wp--preset--font-family--jetbrains-mono);
	font-weight: 400;
	font-size: 0.62rem;
	color: rgba(255, 255, 255, 0.55);
}

.gr-phone-thread {
	flex: 1;
	padding: 14px 12px;
	display: flex;
	flex-direction: column;
	gap: 9px;
	overflow: hidden;
}

.gr-missed {
	align-self: center;
	font-family: var(--wp--preset--font-family--jetbrains-mono);
	font-size: 0.6rem;
	letter-spacing: 0.03em;
	color: var(--wp--preset--color--coral-ink);
	background: rgba(255, 90, 95, 0.1);
	padding: 4px 10px;
	border-radius: 999px;
}

.gr-bubble {
	max-width: 78%;
	padding: 9px 12px;
	border-radius: 16px;
	font-size: 0.78rem;
	line-height: 1.35;
	opacity: 0;
	transform: translateY(8px);
	animation: gr-bubble-in 0.5s ease forwards;
}

.gr-bubble.out {
	align-self: flex-end;
	background: var(--wp--preset--gradient--sunrise);
	color: var(--wp--preset--color--cocoa);
	border-bottom-right-radius: 5px;
}

.gr-bubble.in {
	align-self: flex-start;
	background: var(--wp--preset--color--mist);
	color: var(--wp--preset--color--cocoa);
	border: 1px solid rgba(58, 46, 46, 0.08);
	border-bottom-left-radius: 5px;
}

.gr-bubble.b1 { animation-delay: 0.6s; }
.gr-missed   { animation: gr-bubble-in 0.5s ease forwards; animation-delay: 0.2s; opacity: 0; }
.gr-bubble.b2 { animation-delay: 1.5s; }
.gr-bubble.b3 { animation-delay: 2.6s; }
.gr-bubble.b4 { animation-delay: 3.6s; }

.gr-bubble .t {
	display: block;
	font-family: var(--wp--preset--font-family--jetbrains-mono);
	font-size: 0.55rem;
	opacity: 0.6;
	margin-top: 3px;
}

@keyframes gr-bubble-in {
	to { opacity: 1; transform: translateY(0); }
}

/* --- Mini growth bar chart (for the hero results dashboard) --- */
.gr-bars {
	display: flex;
	align-items: flex-end;
	gap: 7px;
	height: 84px;
	margin-top: 4px;
}

.gr-bars span {
	flex: 1;
	border-radius: 4px 4px 0 0;
	background: linear-gradient(180deg, rgba(255, 90, 95, 0.25), rgba(255, 134, 39, 0.25));
	position: relative;
	min-height: 8px;
}

.gr-bars span:last-child {
	background: var(--wp--preset--gradient--sunrise);
}

/* --- Bento grid for services --- */
.gr-bento {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--wp--preset--spacing--50);
}

@media (min-width: 640px) {
	.gr-bento { grid-template-columns: repeat(2, 1fr); }
	.gr-bento .gr-span-2 { grid-column: span 2; }
}

@media (min-width: 1000px) {
	.gr-bento { grid-template-columns: repeat(3, 1fr); }
	.gr-bento .gr-span-2 { grid-column: span 2; }
}

/* --- Ghosted oversized numerals for editorial depth --- */
.gr-ghost-num {
	position: absolute;
	top: -0.35em;
	right: 0.1em;
	font-family: var(--wp--preset--font-family--space-grotesk);
	font-weight: 700;
	font-size: 5.5rem;
	line-height: 1;
	color: var(--wp--preset--color--cocoa);
	opacity: 0.05;
	pointer-events: none;
	z-index: 0;
}

/* --- Data chips / spec-sheet --- */
.gr-chip {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	font-family: var(--wp--preset--font-family--jetbrains-mono);
	font-size: 0.72rem;
	letter-spacing: 0.02em;
	color: var(--wp--preset--color--cocoa);
	background: var(--wp--preset--color--white);
	border: 1px solid rgba(58, 46, 46, 0.12);
	border-radius: 999px;
	padding: 0.4rem 0.85rem;
}

.gr-chip::before {
	content: "";
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: var(--wp--preset--gradient--sunrise);
}

/* --- Enhanced card hover (lift + coral hairline + shadow) --- */
.wp-block-group.is-style-card {
	position: relative;
	border: 1px solid rgba(58, 46, 46, 0.08);
	transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.22s ease, border-color 0.22s ease;
}

.wp-block-group.is-style-card:hover {
	transform: translateY(-4px);
	border-color: rgba(255, 90, 95, 0.4);
	box-shadow: 0 22px 50px -20px rgba(58, 46, 46, 0.3);
}

/* Gradient top-accent that grows on hover. */
.wp-block-group.is-style-card::after {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	height: 3px;
	width: 0;
	border-radius: 3px 3px 0 0;
	background: var(--wp--preset--gradient--sunrise);
	transition: width 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}

.wp-block-group.is-style-card:hover::after {
	width: 100%;
}

/* ---------------------------------------------------------------------------
 * 17. Motion: no-flash reveal states
 *
 * The inline head guard (functions.php) adds html.gr-motion pre-paint ONLY when
 * JS is on and motion is allowed. So reveal targets are born hidden with no
 * flash; motion.js (GSAP) reveals them. Only opacity is set here so GSAP fully
 * owns the transform (no CSS/GSAP translate conflict). The failsafe and the
 * absence of gr-motion (no-JS / reduced-motion) both leave content visible.
 * ------------------------------------------------------------------------ */

html.gr-motion .gr-reveal {
	opacity: 0;
}

html.gr-motion-failsafe .gr-reveal {
	opacity: 1 !important;
	transform: none !important;
}

/* Numeric stats hold their width while counting up, so CLS stays 0. */
.gr-stat-value {
	font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------------
 * 16. Motion preferences
 * ------------------------------------------------------------------------ */

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

/* ---------------------------------------------------------------------------
 * 18. How-It-Works journey flow
 *
 * Reuses the hero's .gr-flow-steps primitive. The hero trims its last beat
 * below 781px to stay above the fold (section 14d); the journey visual is not
 * the hero and wants all four beats, so .gr-flow-journey opts back in. Split at
 * 480px because below that the flow is single-column and its connector spine is
 * hidden, so only the row is restored there, never the mis-aligned spine.
 * ------------------------------------------------------------------------ */

@media (min-width: 481px) and (max-width: 781px) {
	.gr-flow-steps.gr-flow-journey li:last-child {
		display: grid;
	}

	.gr-flow-steps.gr-flow-journey li:nth-last-child(2) {
		padding-bottom: var(--wp--preset--spacing--30);
	}

	.gr-flow-steps.gr-flow-journey li:nth-last-child(2)::before {
		display: block;
	}
}

@media (max-width: 480px) {
	.gr-flow-steps.gr-flow-journey li:last-child {
		display: grid;
	}

	.gr-flow-steps.gr-flow-journey li:nth-last-child(2) {
		padding-bottom: var(--wp--preset--spacing--30);
	}
}

/* ---------------------------------------------------------------------------
 * 19. Per-page hero visuals
 *
 * Each service/landing hero carries a right-column illustration matched to that
 * page's subject, built from the same .gr-mock / .gr-phone / .gr-flow primitives
 * as the home hero so the set reads as one system. Same honesty rule as section
 * 14d: every panel shows a mechanism or a clearly-labelled example, never a
 * fabricated result. Only the pieces the shared primitives do not already cover
 * are defined here.
 * ------------------------------------------------------------------------ */

/* Custom Software: a neutral "not started yet" pill, alongside .done / .due. */
.gr-mock .pill.wait {
	background: rgba(58, 46, 46, 0.08);
	color: var(--wp--preset--color--taupe-ink);
}

/* Social Media: an example post card. No follower or engagement counts — the
   honesty rule forbids inventing numbers, so it shows only the content style. */
.gr-post-head {
	display: flex;
	align-items: center;
	gap: 0.7rem;
	margin-bottom: 0.9rem;
}

.gr-post-avatar {
	flex: none;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--wp--preset--gradient--sunrise);
	color: var(--wp--preset--color--cocoa);
	font-family: var(--wp--preset--font-family--space-grotesk);
	font-weight: 700;
	font-size: 0.85rem;
	letter-spacing: 0.02em;
}

.gr-post-name {
	font-family: var(--wp--preset--font-family--space-grotesk);
	font-weight: 600;
	font-size: 0.9rem;
	color: var(--wp--preset--color--cocoa);
	line-height: 1.2;
}

.gr-post-name small {
	display: block;
	font-family: var(--wp--preset--font-family--jetbrains-mono);
	font-weight: 400;
	font-size: 0.62rem;
	color: var(--wp--preset--color--taupe-ink);
	margin-top: 2px;
}

.gr-post-photo {
	aspect-ratio: 16 / 9;
	border-radius: var(--wp--custom--radius--sm);
	background:
		linear-gradient(135deg, rgba(255, 134, 39, 0.16), rgba(255, 90, 95, 0.14)),
		var(--wp--preset--color--mist);
	display: flex;
	align-items: center;
	justify-content: center;
	margin-bottom: 0.8rem;
}

.gr-post-photo span {
	font-family: var(--wp--preset--font-family--jetbrains-mono);
	font-size: 0.66rem;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--taupe-ink);
}

.gr-post-caption {
	font-size: 0.82rem;
	line-height: 1.5;
	color: var(--wp--preset--color--cocoa);
	margin: 0 0 0.7rem;
}

.gr-post-stars {
	font-size: 0.76rem;
	line-height: 1.4;
	color: var(--wp--preset--color--taupe-ink);
	margin: 0;
}

.gr-post-stars .gr-stars {
	color: #e0982f;
	letter-spacing: 0.08em;
	margin-right: 0.25rem;
}

/* About: marketing and software as one system, joined at the seam the page
   argues is where the expensive problems hide. A diagram, not a metric. */
.gr-system-node {
	border: 1px solid rgba(58, 46, 46, 0.14);
	border-radius: var(--wp--custom--radius--sm);
	background: var(--wp--preset--color--mist);
	padding: 0.7rem 0.9rem;
	text-align: center;
}

.gr-system-node b {
	display: block;
	font-family: var(--wp--preset--font-family--space-grotesk);
	font-size: 1.05rem;
	color: var(--wp--preset--color--cocoa);
	line-height: 1.15;
}

.gr-system-node small {
	font-family: var(--wp--preset--font-family--jetbrains-mono);
	font-size: 0.64rem;
	letter-spacing: 0.02em;
	color: var(--wp--preset--color--taupe-ink);
}

.gr-system-seam {
	position: relative;
	display: flex;
	justify-content: center;
	padding: 0.55rem 0;
}

.gr-system-seam::before {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	left: 50%;
	width: 2px;
	transform: translateX(-50%);
	background: repeating-linear-gradient(
		to bottom,
		var(--wp--preset--color--coral-ink) 0,
		var(--wp--preset--color--coral-ink) 4px,
		transparent 4px,
		transparent 8px
	);
}

.gr-system-seam span {
	position: relative;
	background: var(--wp--preset--color--white);
	border: 1px solid rgba(255, 90, 95, 0.35);
	border-radius: var(--wp--custom--radius--pill);
	padding: 0.2rem 0.7rem;
	font-family: var(--wp--preset--font-family--jetbrains-mono);
	font-size: 0.62rem;
	letter-spacing: 0.03em;
	color: var(--wp--preset--color--coral-ink);
}
