/**
 * charterspace.io editorial pages (ER-09, prompts/Enhancement-Request-09.md) — CSS for the sections
 * in wp-cli/content/home.html AND wp-cli/content/about.html (scope extension, 2026-09-03), plus the
 * [cs_home_stats] markup contract documented in home.html. `.cs-home` is the shared page wrapper for
 * both (frame, sections, eyebrow, buttons, hero, boundaries panels, notice, CTA band); About adds
 * `.cs-home--about` on the wrapper and a small `.cs-about-*` block at the end of this file. One
 * stylesheet, one enqueue ([cs_home_assets]) — deliberately shared so the two pages read as one system. A separate
 * file, same reasoning and same shape as divi-child/assets/provider-home.css: registered as
 * `cs-home` in divi-child/functions.php, enqueued only by [cs_home_assets] on the page that needs it.
 * Built entirely on the `--cs-*` token system (docs/38) — no new colours, spacing, radii or
 * breakpoints. The one local addition is `--cs-home-display`, a hero-only display size one step above
 * `--cs-text-3xl`, stated in the ticket doc as a deliberate deviation.
 *
 * Layout facts this file depends on (measured on the live page, 2026-09-02): the front page renders
 * in Divi's default page template, so the content column is `.container` — 80% of the viewport,
 * max 1080px, centered — not a Theme Builder row (92% / 1200px). Full-bleed bands below use the
 * `margin-inline: calc(50% - 50vw)` breakout .cs-city-hero / .cs-page--browse .cs-filters already
 * use, with padding that lands their contents back on the container's own left edge:
 * max(10vw, calc(50vw - 540px)). `overflow-x: clip` goes on `#main-content` (viewport-wide) because
 * this page has no Theme Builder section to carry it; `clip`, not `hidden`, so nothing becomes a
 * scroll container.
 */

/* -----------------------------------------------------------------------------
   Generic scroll-reveal (scroll-reveal.js's [data-cs-reveal] contract). Same 10 lines as
   provider-home.css — duplicated rather than shared because the two stylesheets are enqueued on
   different sites and neither should have to load the other. Guarded on prefers-reduced-motion as
   defence in depth; the script already refuses to add these classes under reduce.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
	.cs-reveal-pending {
		opacity: 0;
		transform: translateY(1rem);
		transition: opacity 420ms ease, transform 420ms ease;
	}

	.cs-reveal-pending.cs-reveal-visible {
		opacity: 1;
		transform: none;
	}
}

/* -----------------------------------------------------------------------------
   Page frame
   -------------------------------------------------------------------------- */
/* Two selectors per rule, in separate blocks on purpose: `body.home` is what the real front page
   carries; `body:has(.cs-home)` keys the same rules off this page's own wrapper so the identical
   markup also frames correctly on a page that is NOT the front page — the logged-in-only private
   preview page team-lead stands up before release, and any future re-provisioning under a new
   slug. Separate blocks, not one comma list, because a browser without :has() drops the entire
   rule a selector list containing it belongs to; kept apart, the body.home half always survives. */
body.home #main-content {
	overflow-x: clip;
}

body:has(.cs-home) #main-content {
	overflow-x: clip;
}

/* Divi's default page template pads .container 58px above the content and #left-area ~23px below
   it; both would show as bare canvas strips between the fixed header and the hero, and between the
   closing CTA band and the footer. Removed for this page only. */
body.home #main-content .container {
	padding-top: 0;
}

body:has(.cs-home) #main-content .container {
	padding-top: 0;
}

body.home #left-area {
	padding-bottom: 0;
}

body:has(.cs-home) #left-area {
	padding-bottom: 0;
}

.cs-home,
.cs-home * {
	box-sizing: border-box;
}

.cs-home {
	--cs-home-display: clamp(2.25rem, 1.6rem + 2.8vw, 3.5rem);
	--cs-home-gutter: max(10vw, calc(50vw - 540px));
	color: var(--cs-text);
	line-height: var(--cs-leading-normal);
}

.cs-home section {
	padding-block: var(--cs-space-2xl);
}

@media (min-width: 981px) {
	.cs-home section {
		padding-block: var(--cs-space-3xl);
	}
}

.cs-home__bleed {
	margin-inline: calc(50% - 50vw);
	padding-inline: var(--cs-home-gutter);
}

.cs-home h2 {
	max-width: 24ch;
	margin: 0 0 var(--cs-space-sm);
	color: var(--cs-text-strong);
	font-size: var(--cs-text-2xl);
	line-height: var(--cs-leading-snug);
	letter-spacing: var(--cs-tracking-tight);
}

.cs-home h3 {
	margin: 0 0 var(--cs-space-2xs);
	color: var(--cs-text-strong);
	font-size: var(--cs-text-lg);
	line-height: var(--cs-leading-snug);
}

.cs-home p {
	max-width: 68ch;
}

/* Prose rhythm applies to unclassed paragraphs only; every classed paragraph below carries its own
   margins (a bare `.cs-home p` shorthand would outrank them by specificity and zero their tops). */
.cs-home p:not([class]) {
	margin: 0 0 var(--cs-space-sm);
}

.cs-home p:not([class]):last-child {
	margin-bottom: 0;
}

.cs-home a:not([class]) {
	color: var(--cs-link);
	text-decoration: underline;
	text-underline-offset: 0.15em;
}

.cs-home a:not([class]):hover,
.cs-home a:not([class]):focus {
	color: var(--cs-link-hover);
}

.cs-home a:focus-visible,
.cs-home-btn:focus-visible {
	outline: 3px solid var(--cs-link);
	outline-offset: 2px;
}

.cs-home__eyebrow {
	margin: 0 0 var(--cs-space-xs);
	/* brand-300, not brand-400: qa-2 measured the eyebrow at 1.7–2.8:1 against the brightest pixels
	   behind it in the hero photo; brand-300 clears 4.5:1 there with the darker scrim below. */
	color: var(--cs-brand-300);
	font-family: var(--cs-font-mono);
	font-size: var(--cs-text-sm);
	font-weight: 600;
	letter-spacing: var(--cs-tracking-label);
	text-transform: uppercase;
}

/* Divi's own dynamic CSS styles lists via `#left-area ul` / `#left-area ol` (specificity 1,0,1 —
   memory: "Divi CSS specificity"), which beats any class rule below and re-adds native markers and
   indents. Every list this page owns is reset against the same ID so the reset actually wins. */
#left-area .cs-home-how__steps,
#left-area .cs-home-stats {
	margin-left: 0;
	padding-left: 0;
	list-style: none;
}

#left-area .cs-home-how__steps > li,
#left-area .cs-home-stats > li {
	margin: 0;
	list-style: none;
}

/* Buttons — the same fill/border/focus recipe .cs-provider-hero__cta restates from .cs-button, under
   this page's own class so the homepage never depends on a class another file may re-tune. */
.cs-home-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--cs-space-2xs);
	min-height: var(--cs-tap-target);
	padding: var(--cs-space-2xs) var(--cs-space-md);
	border: 1px solid var(--cs-brand-500);
	border-radius: var(--cs-radius-sm);
	background: var(--cs-brand-500);
	color: var(--cs-on-brand);
	font-size: var(--cs-text-base);
	font-weight: 600;
	line-height: var(--cs-leading-snug);
	text-decoration: none;
	transition: background-color var(--cs-transition), border-color var(--cs-transition), color var(--cs-transition);
}

.cs-home-btn:hover,
.cs-home-btn:focus {
	background: var(--cs-brand-600);
	border-color: var(--cs-brand-500);
	color: var(--cs-on-brand);
}

.cs-home-btn--secondary {
	background: transparent;
	color: var(--cs-brand-300);
	border-color: var(--cs-brand-400);
}

.cs-home-btn--secondary:hover,
.cs-home-btn--secondary:focus {
	background: var(--cs-surface-accent);
	border-color: var(--cs-brand-300);
	color: var(--cs-text-on-accent);
}

/* -----------------------------------------------------------------------------
   1. Hero (#cs-home-hero)
   Background is the NASA/JAXA ISS Milky Way photograph already in the repo, re-derived at two sizes
   (divi-child/assets/textures/SOURCES.md). 960px/39 KB below 981px, 1920px/154 KB from 981px up; no
   background-attachment: fixed (repaints on mid-range mobile). The scrim is the .cs-city-hero__scrim
   recipe — heaviest where the copy sits, and the void-900 fill under it carries contrast while the
   image is still loading or blocked.
   -------------------------------------------------------------------------- */
.cs-home-hero {
	position: relative;
	isolation: isolate;
	overflow: hidden;
	/* Phone tier first (docs/06): xl/lg keeps the primary CTA inside a 640px-tall viewport at 360px
	   (qa-2 measured 701px with 3xl); 3xl returns from 981px where there is room. */
	padding-block: var(--cs-space-xl) var(--cs-space-lg);
	background-color: var(--cs-void-900);
	background-image: url("home/starfield-hero-960.webp");
	background-position: center 30%;
	background-size: cover;
	background-repeat: no-repeat;
}

.cs-home-hero::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	/* Heaviest at the top, where the eyebrow/h1 sit over the Milky Way band. qa-2 measured worst-case
	   pixel contrast (not the flat-canvas token ratio) — at α≈0.75 the brightest star behind the
	   eyebrow drops to L≈0.06, putting brand-300 at ≈5.1:1. */
	background: linear-gradient(
		180deg,
		rgba(6, 10, 19, 0.78) 0%,
		rgba(6, 10, 19, 0.70) 45%,
		rgba(6, 10, 19, 0.96) 100%
	);
}

@media (min-width: 981px) {
	.cs-home-hero {
		min-height: min(44rem, 88vh);
		/* ER-18: bottom trimmed from --cs-space-2xl (4rem) to --cs-space-lg (2rem) — "bring the next
		   section closer" (user). #cs-home-margin's own top padding is trimmed to match (see its
		   981px+ rule below), so the two moves close the gap from both sides rather than leaving one
		   section's padding doing all the work. */
		padding-block: var(--cs-space-3xl) var(--cs-space-lg);
		background-image: url("home/starfield-hero-1920.webp");
		display: grid;
		align-content: center;
	}

	.cs-home-hero::before {
		background: linear-gradient(
			100deg,
			rgba(6, 10, 19, 0.88) 0%,
			rgba(6, 10, 19, 0.72) 48%,
			rgba(6, 10, 19, 0.28) 100%
		),
		linear-gradient(180deg, rgba(6, 10, 19, 0) 70%, var(--cs-void-900) 100%);
	}
}

.cs-home-hero__inner {
	display: grid;
	gap: var(--cs-space-xl);
	align-items: center;
}

@media (min-width: 981px) {
	/* ER-18: the art no longer occupies its own column at this tier (it moves to an absolutely
	   positioned layer behind the copy — see .cs-home-hero__art below), so the copy takes the full
	   row. h1/lead already cap their own max-width (16ch/56ch), so the copy does not stretch
	   awkwardly wide just because the column freed up. */
	.cs-home-hero__inner {
		grid-template-columns: minmax(0, 1fr);
	}
}

.cs-home-hero h1 {
	max-width: 16ch;
	margin: 0 0 var(--cs-space-sm);
	color: var(--cs-text-strong);
	font-size: var(--cs-home-display);
	font-weight: 600;
	line-height: var(--cs-leading-tight);
	letter-spacing: var(--cs-tracking-tight);
}

.cs-home-hero__lead {
	max-width: 56ch;
	margin: 0 0 var(--cs-space-md);
	color: var(--cs-ink-300);
	font-size: var(--cs-text-md);
	line-height: var(--cs-leading-normal);
}

.cs-home-hero__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--cs-space-sm);
}

/* Phone tier keeps the h1/lead margins one step tighter so the primary CTA sits inside a 640px-tall
   viewport at 360px (qa-2 r2: 15px under with md/lg); the fuller rhythm returns from 768px. */
@media (min-width: 768px) {
	.cs-home-hero h1 {
		margin-bottom: var(--cs-space-md);
	}

	.cs-home-hero__lead {
		margin-bottom: var(--cs-space-lg);
	}
}

/* The hero's photo credit line was removed from both heroes (user, 2026-09-03: a credit belongs in
   an image-credits page, not in page content) — wp-cli/content/image-credits.html carries it, linked
   from the footer's legal column. The hero's own padding-block closes the space; nothing replaces
   the rule here. */

/* [cs_home_stats] — three live counts. Mono, tabular numerals: these are measured facts from the
   platform, not prose (docs/49 §49.4). The shortcode returns nothing when there is nothing open, so
   this list either exists with real numbers or is absent — never zeros. */
.cs-home-stats {
	display: flex;
	flex-wrap: wrap;
	gap: var(--cs-space-md) var(--cs-space-xl);
	margin: var(--cs-space-xl) 0 0;
	padding: 0;
	list-style: none;
}

.cs-home-stats li {
	display: flex;
	flex-direction: column;
	gap: var(--cs-space-3xs);
	padding-left: var(--cs-space-sm);
	border-left: 2px solid var(--cs-brand-500);
}

.cs-home-stats__value {
	color: var(--cs-text-strong);
	font-family: var(--cs-font-mono);
	font-size: var(--cs-text-2xl);
	font-variant-numeric: tabular-nums;
	line-height: var(--cs-leading-tight);
}

.cs-home-stats__label {
	color: var(--cs-ink-300); /* ink-400 measured 3.5:1 over the photo at 768 (qa-2) */
	font-size: var(--cs-text-xs);
	letter-spacing: var(--cs-tracking-label);
	text-transform: uppercase;
}

/* Orbital schematic — the page's signature, so it is present at every tier: a 15rem instance
   centred under the copy on phones (below the CTAs, so it never costs the fold), 24rem stacked
   under the copy 768–980px, an absolutely-positioned layer BEHIND the copy from 981px (ER-18).

   ER-18 (2026-09-04): "make the hero globe SVG about 20% larger" (desktop) / "increase the size...
   by 50%" (mobile) (user). Mobile went 10rem -> 15rem (+50%); desktop went 30rem -> 36rem (+20%,
   30 * 1.2). Mobile/tablet (<981px) is unaffected below 768px other than the base width bump —
   it stays in normal flow, centred under the copy, same as before. */
.cs-home-hero__art {
	display: block;
	justify-self: center;
	width: 15rem;
	margin-top: var(--cs-space-sm);
}

.cs-home-hero__art svg {
	display: block;
	width: 100%;
	height: auto;
}

@media (min-width: 768px) {
	.cs-home-hero__art {
		width: min(100%, 24rem);
		margin-top: 0;
	}
}

@media (min-width: 981px) {
	/* "It can also fit behind content" (user) — taken as licence to let the now-larger art overlap
	   the copy rather than stay confined to its own grid column (.cs-home-hero__inner dropped that
	   column above). z-index -2 matches the .cs-home-cta__earth/ring pattern: it sits BELOW
	   .cs-home-hero::before (z-index -1, inset: 0 — the section's existing scrim), so the scrim
	   still covers the art's full, now-larger footprint automatically, as long as the art stays
	   within .cs-home-hero's own bounds (enforced by that element's `overflow: hidden`) — no new
	   scrim math needed, only that constraint. Positioned toward the right/lower area of the hero,
	   which is where the lighter half of the 100deg scrim gradient already sits, so the planet still
	   reads with some presence rather than being crushed to black. */
	.cs-home-hero__art {
		position: absolute;
		z-index: -2;
		right: -2rem;
		bottom: -2rem;
		width: 36rem;
		margin-top: 0;
	}
}

@media (prefers-reduced-motion: no-preference) {
	.cs-home-orbit--spin {
		animation: cs-home-orbit-spin 96s linear infinite;
	}

	.cs-home-orbit--spin-slow {
		animation: cs-home-orbit-spin 150s linear infinite reverse;
	}
}

@keyframes cs-home-orbit-spin {
	to {
		transform: rotate(360deg);
	}
}

/* -----------------------------------------------------------------------------
   2. Why there is capacity (#cs-home-margin) + the illustrative two-layer gauge
   Track = the vehicle's lift, fill = residual — the exact semantics of the real capacity gauge
   (docs/49 §49.7: "the full track is total capacity, the fill is remaining"), same void-600 track and
   brand-500 fill, so a visitor who later meets the real gauge on a listing has already read one.
   -------------------------------------------------------------------------- */
@media (min-width: 981px) {
	/* ER-18: top trimmed from the generic `.cs-home section` 981px+ padding-block (--cs-space-3xl,
	   6rem) to --cs-space-lg (2rem) — "bring the next section closer" (user), paired with the hero's
	   own bottom-padding trim above. Bottom is left at the generic 6rem so the rhythm below this
	   section (into #cs-home-fleet etc.) is untouched. An ID selector always outranks the
	   `.cs-home section` compound (1-0-0 vs 0-1-1), so this needs no `.cs-home section#cs-home-margin`
	   trick — see the `.cs-home section.cs-home-cta` note elsewhere in this file for why that trick
	   is sometimes necessary and why it isn't here. */
	#cs-home-margin {
		padding-block: var(--cs-space-lg) var(--cs-space-3xl);
	}
}

.cs-home-margin__grid {
	display: grid;
	gap: var(--cs-space-xl);
	align-items: center;
}

@media (min-width: 981px) {
	.cs-home-margin__grid {
		grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	}
}

.cs-home-gauge {
	margin: 0;
	padding: var(--cs-space-lg) var(--cs-space-md);
	border: 1px solid var(--cs-border-surface);
	border-radius: var(--cs-radius-md);
	background: var(--cs-surface);
}

.cs-home-gauge__row + .cs-home-gauge__row {
	margin-top: var(--cs-space-md);
}

.cs-home-gauge__label {
	display: flex;
	justify-content: space-between;
	gap: var(--cs-space-sm);
	margin-bottom: var(--cs-space-2xs);
	color: var(--cs-text);
	font-size: var(--cs-text-sm);
}

.cs-home-gauge__tag {
	flex: 0 0 auto;
	color: var(--cs-brand-300);
	font-family: var(--cs-font-mono);
	font-size: var(--cs-text-xs);
	letter-spacing: var(--cs-tracking-label);
	text-transform: uppercase;
}

.cs-home-gauge__track {
	height: 0.875rem;
	overflow: hidden;
	border-radius: var(--cs-radius-sm);
	background: var(--cs-void-600);
}

.cs-home-gauge__fill {
	height: 100%;
	border-radius: var(--cs-radius-sm);
	background: var(--cs-brand-500);
}

.cs-home-gauge figcaption {
	margin-top: var(--cs-space-md);
	color: var(--cs-text-muted);
	font-size: var(--cs-text-sm);
	line-height: var(--cs-leading-normal);
}

/* -----------------------------------------------------------------------------
   3. How it works (#cs-home-how) — three step cards. The 3px brand→cyan top edge on hover/focus is
   the card pattern's one flourish (docs/49 §49.7); it is additive only, never the focus indicator.
   -------------------------------------------------------------------------- */
.cs-home-how__steps {
	display: grid;
	gap: var(--cs-space-md);
	margin: var(--cs-space-lg) 0 0;
	padding: 0;
	list-style: none;
}

/* Below 981px the three cards stack, each with the icon in a left rail and number/title/copy to
   its right — 3-up inside a 614px container at 768 gave a 17ch paragraph measure (qa-2). Multi-column
   starts at 981, the same line the rest of the page uses. */
.cs-home-step {
	position: relative;
	display: grid;
	grid-template-columns: 2.5rem minmax(0, 1fr);
	column-gap: var(--cs-space-md);
	row-gap: var(--cs-space-2xs);
	align-items: start;
	overflow: hidden;
	padding: var(--cs-space-lg) var(--cs-space-md);
	border: 1px solid var(--cs-border-surface);
	border-radius: var(--cs-radius-md);
	background: var(--cs-surface);
}

.cs-home-step__icon {
	grid-row: 1 / span 3;
}

.cs-home-step__num,
.cs-home-step h3,
.cs-home-step p {
	grid-column: 2;
}

@media (min-width: 981px) {
	.cs-home-how__steps {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}

	.cs-home-step {
		display: block;
	}

	.cs-home-step__num,
	.cs-home-step__icon {
		margin-bottom: var(--cs-space-sm);
	}
}

.cs-home-step::before {
	content: "";
	position: absolute;
	inset: 0 0 auto;
	height: 3px;
	background: linear-gradient(90deg, var(--cs-brand-500), var(--cs-accent-400));
	opacity: 0;
	transition: opacity var(--cs-transition);
}

.cs-home-step:hover::before,
.cs-home-step:focus-within::before {
	opacity: 1;
}

.cs-home-step__num {
	display: block;
	margin: 0;
	color: var(--cs-brand-400);
	font-family: var(--cs-font-mono);
	font-size: var(--cs-text-sm);
	letter-spacing: var(--cs-tracking-label);
}

.cs-home-step__icon {
	display: block;
	width: 2.5rem;
	height: 2.5rem;
	margin: 0;
	color: var(--cs-accent-400);
}

.cs-home-step p {
	margin: 0;
	color: var(--cs-text);
	font-size: var(--cs-text-base);
}

.cs-home p.cs-home-how__foot {
	margin: var(--cs-space-lg) 0 0;
}

/* -----------------------------------------------------------------------------
   4. Open capacity (#cs-home-open) — a sunken full-bleed band around the existing compact strip.
   -------------------------------------------------------------------------- */
.cs-home-open {
	border-block: 1px solid var(--cs-border);
	background: var(--cs-surface-sunken);
}

.cs-home-open__head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--cs-space-sm) var(--cs-space-lg);
	margin-bottom: var(--cs-space-lg);
}

.cs-home-open__head h2,
.cs-home-open__head .cs-home__eyebrow {
	margin-bottom: 0;
}

.cs-home-open__head .cs-home__eyebrow {
	margin-bottom: var(--cs-space-xs);
}

.cs-home p.cs-home-open__foot {
	margin: var(--cs-space-lg) 0 0;
	color: var(--cs-text-muted);
}

/* -----------------------------------------------------------------------------
   5. Fleet (#cs-home-fleet) — [cs_vehicle_showcase] brings its own card CSS: style.css's
   .cs-vehicle-index__* plus provider-home.css's showcase additions. provider-home.css IS loaded
   here — shortcode_vehicle_showcase() enqueues `cs-provider-home` itself on whichever site it
   renders — but only for the request in which the showcase actually rendered a card, and before
   this file in the cascade. The two small additions are restated below under this section's own
   scope so the fleet section never depends on another page's stylesheet having been enqueued
   first; at equal specificity this later file wins, so the restatement is also what applies.
   -------------------------------------------------------------------------- */
/* style.css's .cs-vehicle-index__list reads this custom property from 60em (default 3). Four cards
   on three columns orphan one; four columns at the 981 tier are ~185px each (qa-2). So: 2x2 from 60em,
   4-up from 1200px — a documented extra width (docs/38 §38.5), chosen because it is where the
   1080px-max container actually reaches 4 x ~250px, not a new general breakpoint. */
.cs-home-fleet {
	--cs-vehicle-index-columns: 2;
}

@media (min-width: 1200px) {
	.cs-home-fleet {
		--cs-vehicle-index-columns: 4;
	}
}

.cs-home p.cs-home-fleet__lead {
	margin: 0 0 var(--cs-space-lg);
	color: var(--cs-text-muted);
	font-size: var(--cs-text-md);
}

/* Divi's #left-area ul indents the showcase grid; reset against the same ID (see the list note above). */
#left-area .cs-home-fleet .cs-vehicle-index__list {
	margin-left: 0;
	padding-left: 0;
	list-style: none;
}

.cs-home-fleet .cs-vehicle-showcase__title-row {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: var(--cs-space-2xs);
	margin: var(--cs-space-sm) var(--cs-space-sm) 0;
}

.cs-home-fleet .cs-vehicle-showcase__title-row .cs-vehicle-index__name {
	margin: 0;
}

.cs-home-fleet .cs-vehicle-showcase__item .cs-vehicle-hero__credit {
	margin: var(--cs-space-2xs) var(--cs-space-sm) var(--cs-space-sm);
}

.cs-home-fleet .cs-vehicle-showcase__see-all {
	display: flex;
	flex-wrap: wrap;
	gap: var(--cs-space-2xs);
	margin: var(--cs-space-lg) 0 0;
}

/* -----------------------------------------------------------------------------
   6. What we are / are not (#cs-home-boundaries)
   -------------------------------------------------------------------------- */
.cs-home-boundaries__grid {
	display: grid;
	gap: var(--cs-space-md);
	margin-top: var(--cs-space-lg);
}

@media (min-width: 768px) {
	.cs-home-boundaries__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

.cs-home-boundaries__panel {
	padding: var(--cs-space-lg) var(--cs-space-md);
	border: 1px solid var(--cs-border-surface);
	border-left-width: 3px;
	border-radius: var(--cs-radius-md);
	background: var(--cs-surface);
}

.cs-home-boundaries__panel--do {
	border-left-color: var(--cs-brand-400);
}

.cs-home-boundaries__panel--not {
	border-left-color: var(--cs-border-strong);
}

/* Divi's #left-area ul rule (memory: "Divi CSS specificity") outranks a class selector, so the
   list reset is written against the same ID to actually win. */
#left-area .cs-home-boundaries__panel ul {
	margin: 0;
	padding: 0 0 0 var(--cs-space-md);
	line-height: var(--cs-leading-normal);
}

.cs-home-boundaries__panel li + li {
	margin-top: var(--cs-space-2xs);
}

/* Info tint, not warning: docs/49 §49.2 — compliance language reassures, it doesn't alarm.
   `p.` qualifier so this outranks the generic `.cs-home p` 68ch measure. */
.cs-home p.cs-home-notice {
	max-width: none;
	margin: var(--cs-space-lg) 0 0;
	padding: var(--cs-space-sm) var(--cs-space-md);
	border-radius: var(--cs-radius-sm);
	background: var(--cs-info-tint);
	color: var(--cs-info-text);
	font-size: var(--cs-text-sm);
	line-height: var(--cs-leading-normal);
}

.cs-home-notice strong {
	color: var(--cs-text-strong);
}

.cs-home-notice a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 0.15em;
}

/* -----------------------------------------------------------------------------
   7. Closing CTA (#cs-home-cta) — brand-900 band, the provider-home conic orbit ring reused
   (decorative, desktop-only, motion gated).
   -------------------------------------------------------------------------- */
.cs-home-cta {
	position: relative;
	overflow: hidden;
	isolation: isolate;
	background: var(--cs-surface-accent);
	color: var(--cs-text-on-accent);
	text-align: center;
}

.cs-home-cta h2 {
	max-width: 22ch;
	margin-inline: auto;
}

.cs-home-cta p:not([class]) {
	margin: 0 auto var(--cs-space-sm);
}

.cs-home-cta p {
	max-width: 52ch;
	color: var(--cs-text-on-accent);
}

.cs-home-cta__actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--cs-space-sm);
	margin-top: var(--cs-space-lg);
}

.cs-home-cta .cs-home-btn--secondary {
	color: var(--cs-brand-200);
	border-color: var(--cs-brand-300);
}

.cs-home-cta .cs-home-btn--secondary:hover,
.cs-home-cta .cs-home-btn--secondary:focus {
	background: var(--cs-brand-800);
	color: var(--cs-white);
}

.cs-home p.cs-home-cta__provider {
	margin: var(--cs-space-lg) auto 0;
	font-size: var(--cs-text-sm);
}

/* Homepage only: the one-line pointer to About's "what we are, and what we are not" + the two legal
   pages, standing in for the boundaries section that moved to About (user request, 2026-09-03). */
.cs-home p.cs-home-cta__legal {
	margin: var(--cs-space-2xs) auto 0;
	color: var(--cs-brand-200);
	font-size: var(--cs-text-xs);
}

.cs-home-cta__legal a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 0.15em;
}

.cs-home-cta__ring {
	display: none;
	position: absolute;
	top: 50%;
	right: -14rem;
	z-index: -1;
	width: 36rem;
	height: 36rem;
	transform: translateY(-50%);
	border-radius: 50%;
	background: conic-gradient(
		from 0deg,
		transparent 0%,
		var(--cs-brand-500) 6%,
		transparent 18%,
		transparent 74%,
		var(--cs-accent-400) 84%,
		transparent 96%
	);
	opacity: 0.18;
	filter: blur(1px);
	pointer-events: none;
}

@media (min-width: 981px) {
	.cs-home-cta__ring {
		display: block;
	}
}

@media (min-width: 981px) and (prefers-reduced-motion: no-preference) {
	.cs-home-cta__ring {
		animation: cs-home-ring-spin 90s linear infinite;
	}
}

@keyframes cs-home-ring-spin {
	to {
		transform: translateY(-50%) rotate(360deg);
	}
}

/* =============================================================================
   About (wp-cli/content/about.html) — `.cs-home--about` modifiers and `.cs-about-*` additions.
   Everything else on that page reuses the rules above verbatim.
   ============================================================================= */

/* Shorter hero: About's job is to be read, not to sell — no art column, no stat strip, and a
   min-height that doesn't push the first section below the fold on desktop. */
.cs-home-hero--about h1 {
	max-width: 14ch;
}

@media (min-width: 981px) {
	.cs-home-hero--about {
		min-height: 0;
	}

	.cs-home-hero--about .cs-home-hero__inner {
		grid-template-columns: minmax(0, 1fr);
	}

	.cs-home-hero--about .cs-home-hero__lead {
		max-width: 62ch;
	}
}

/* Two-column split: prose left, a supporting panel right, from 981px. `--even` splits 1:1 for the
   live/roadmap pair, where neither side is the primary. */
.cs-about-split {
	display: grid;
	gap: var(--cs-space-xl);
	align-items: start;
}

@media (min-width: 981px) {
	.cs-about-split {
		grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
	}

	.cs-about-split--even {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

.cs-about-panel {
	margin: 0;
	padding: var(--cs-space-lg) var(--cs-space-md);
	border: 1px solid var(--cs-border-surface);
	border-radius: var(--cs-radius-md);
	background: var(--cs-surface);
}

.cs-about-panel h3 {
	display: flex;
	align-items: center;
	gap: var(--cs-space-2xs);
	margin-bottom: var(--cs-space-sm);
	font-size: var(--cs-text-base);
}

/* Divi's #left-area ul rule outranks class resets (see the list note near the top of this file). */
#left-area .cs-about-panel__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

#left-area .cs-about-panel__list li {
	position: relative;
	margin: 0 0 var(--cs-space-2xs);
	padding-left: var(--cs-space-md);
	color: var(--cs-text);
	line-height: var(--cs-leading-normal);
}

.cs-about-panel__list li::before {
	content: "";
	position: absolute;
	top: 0.65em;
	left: 0;
	width: 0.75rem;
	height: 1px;
	background: var(--cs-brand-400);
}

/* Live / roadmap state marks — shape + label, never colour alone (docs/49 §49.3): filled disc for
   live, hollow ring for roadmap, drawn in the same token so the shape is the whole signal. */
.cs-about-state {
	flex: 0 0 auto;
	width: 0.625rem;
	height: 0.625rem;
	border: 1.5px solid var(--cs-accent-400);
	border-radius: 50%;
}

.cs-about-state--live {
	background: var(--cs-accent-400);
}

.cs-about-panel--roadmap {
	background: var(--cs-surface-sunken);
}

.cs-about-panel--roadmap .cs-about-panel__list li::before {
	background: var(--cs-border-strong);
}

.cs-about-panel--roadmap .cs-about-panel__list li {
	color: var(--cs-text-muted);
}

/* The positioning line as the page's typographic signature (docs/49 §49.1's one sentence every
   surface has to hold): the claim alone at display size, the qualifying sentence beneath at lead
   size, on a brand-500 rule — not a paragraph set large (qa-2 r4: an 8-line block at 1440 read as
   body copy, not emphasis). */
.cs-about-quote {
	max-width: 48rem; /* rem, not body ch: the claim is display-size and must sit on one line at 1440 */
	margin: var(--cs-space-lg) 0 var(--cs-space-xl);
	padding: var(--cs-space-2xs) 0 var(--cs-space-2xs) var(--cs-space-md);
	border-left: 3px solid var(--cs-brand-500);
}

.cs-home p.cs-about-quote__claim {
	max-width: none;
	margin: 0 0 var(--cs-space-xs);
	color: var(--cs-text-strong);
	font-size: var(--cs-home-display);
	font-weight: 600;
	line-height: var(--cs-leading-tight);
	letter-spacing: var(--cs-tracking-tight);
}

.cs-home p.cs-about-quote__qualifier {
	max-width: 46ch;
	margin: 0;
	color: var(--cs-text);
	font-size: var(--cs-text-md);
	line-height: var(--cs-leading-normal);
}

.cs-home p.cs-about-boundaries__why {
	margin: var(--cs-space-lg) 0 0;
	color: var(--cs-text-muted);
}

/* Fact list in the compliance panel: mono terms, plain definitions — a specification, not prose. */
.cs-about-facts {
	display: grid;
	gap: var(--cs-space-sm);
	margin: 0;
}

.cs-about-facts > div {
	padding-top: var(--cs-space-sm);
	border-top: 1px solid var(--cs-border);
}

.cs-about-facts dt {
	color: var(--cs-brand-300);
	font-family: var(--cs-font-mono);
	font-size: var(--cs-text-xs);
	letter-spacing: var(--cs-tracking-label);
	text-transform: uppercase;
}

.cs-about-facts dd {
	margin: var(--cs-space-3xs) 0 0;
	color: var(--cs-text);
	font-size: var(--cs-text-sm);
	line-height: var(--cs-leading-normal);
}

.cs-home p.cs-about-roadmap__foot {
	margin: var(--cs-space-lg) 0 0;
	color: var(--cs-text-muted);
	font-style: italic;
}

/* Wording-of-record line closing the compliance prose column — the Disclaimer/Terms/Privacy links
   from the removed #cs-about-operator section. Muted like `.cs-about-boundaries__why`: it qualifies
   the section above it rather than making a new claim. */
.cs-home p.cs-about-compliance__legal {
	margin: var(--cs-space-md) 0 0;
	color: var(--cs-text-muted);
}

/* Secondary line under a panel's primary action — "browsing needs no account" sits below the button
   it qualifies, at the same muted weight as the wording-of-record line above. */
.cs-home p.cs-about-sides__note {
	margin: var(--cs-space-xs) 0 0;
	color: var(--cs-text-muted);
	font-size: var(--cs-text-sm);
}

/* =============================================================================
   ER-12 — the CTA's decorative Earth backdrop ("HUGE render of earth ... like looking over the big
   marble view, up close. have it slowly autorotate too", user 2026-09-03).

   Layering inside .cs-home-cta, which already carries position/overflow/isolation and so needs no
   new stacking-context work: the section's own --cs-surface-accent background paints first, then
   negative-z-index children (the Earth at -2, the retired ring at -1), then in-flow content. That
   ordering is what makes a negative z-index safe here rather than sending the canvas behind the
   section entirely.
   ============================================================================= */

.cs-home-cta__earth {
	position: absolute;
	inset: 0;
	z-index: -2;
	pointer-events: none;
	/* Phone/tablet tier: a pre-rendered still of the same framing, no WebGL at all (Vivian-2's ER-12
	   review). A second WebGL context on the marketing entry point is a real cost on an older phone,
	   this is decorative, and a deterministic still also makes the 360px contrast pass reproducible
	   instead of a sample of one animation frame. Same two-derivative pattern as .cs-home-hero's
	   starfield directly above. */
	background-image: url("home/earth-cta-phone.webp");
	background-position: center bottom;
	/* `100% auto`, NOT `cover` — and this is the whole reason the phone tier read as a gradient
	   artefact rather than a planet. This element is `inset: 0`, so it spans the entire section, and
	   `cover` fitting a landscape still into a tall narrow phone section scales to the HEIGHT and
	   crops horizontally: at 360x712 with the old 1200x900 still that left only the central 38% of
	   the image width visible. The centre of an arc is its flattest part, so cover was discarding
	   precisely the curvature that makes it read as a planet. Sizing to the width instead shows the
	   full arc, and `bottom` anchors it into the band the padding above opens.
	   The still is cut at the band's own aspect for the same reason.

	   PER-TIER ART DIRECTION, deliberate and worth stating because it looks like drift: ER-12b moved
	   the DESKTOP composition to a zoomed-out body offset right, at the user's request. The phone
	   still keeps a horizon framing instead. A wide-short 2.25 strip showing a zoomed-out body leaves
	   most of the band empty with a small planet in one corner — both were rendered and compared. The
	   strip wants a horizon; the desktop frame wants a body. Same reason the two tiers already have
	   different pitches. Regenerate the still with CAMERA_DIST 1.15 / pitch 45.78 / yaw 0 at
	   1080x480; the runtime constants in earth-backdrop.js are the DESKTOP framing and are not what
	   this file was cut at. */
	background-size: 100% auto;
	background-repeat: no-repeat;
}

/* THE CONTRAST GUARANTEE. Bound to the element that owns the copy, not to viewport percentages.

   Why this shape rather than a gradient (Celeste-2's review, adopted over both my original
   edge-falloff and the vertical falloff that replaced it):

   - **It is an invariant, not a proof.** A percentage-based gradient has to be re-established at
     every breakpoint and after every copy edit — the h2 is `max-width: 22ch` centred, the legal line
     wraps differently at 320/360/390/768/981/1440, and the person who edits that copy has no reason
     to know a contrast floor depends on where their line breaks. Keying the scrim to the box the
     text actually occupies means it is where the text is by construction. Nothing to re-prove.
   - **Flat `rgba()`, deliberately not a gradient**, for TWO reasons that must be read together.
     First: a `linear-gradient`/`color-mix()` may interpolate in oklab, which is increasingly the CSS
     default — and then the composite is NOT what the sRGB arithmetic below predicts and the whole
     derivation silently stops describing reality.
     Second, and this is the one that is easy to miss: **the flat fill is what makes the horizontal
     unbounding below safe.** With uniform α, extent is irrelevant to the guarantee — every text
     pixel sits over the same 0.86 no matter where the scrim's edges are, so covering strictly more
     genuinely cannot weaken it. With a gradient that stops being true: extending sideways could put
     a lower-α region under text, and the "covers strictly more, costs nothing" argument below would
     become false while still reading as correct. If you are about to turn this into a gradient, the
     unbounding has to be reconsidered in the same edit. (Celeste-2, ER-12 review.)

   0.86 against a pure-white worst case keeps `.cs-home-cta__legal` (--cs-brand-200 at --cs-text-xs,
   the binding case at 4.5:1) above threshold. Celeste-2 recomputed the minimum independently as
   α = 0.7217 for brand-200, 0.6925 for the brand-300 border, 0.6629 for brand-100 body, matching my
   0.722 — and measured the Blue Marble tiles to confirm white is the ACTUAL extremum, not a
   conservative stand-in: the tiles contain true 1.0 pixels, and 13.4% of the texture is ≥90%
   brightness, so it is over an eighth of the image passing under the copy on every rotation.

   The monotonicity that makes "brightest backdrop = worst case" valid holds only while the composite
   stays below the text luminance. It does here by a wide margin. If anyone ever tries a LIGHT scrim,
   that argument inverts silently and this comment stops applying.

   rgba() literal rather than a token because this codebase has no rgb-triple or color-mix convention
   (home.css already carries 7 such literals, incl. six in the ER-9 hero scrims). The value is
   **--cs-brand-900 (#10224A)**, and ER-12 is the first place that hardcode backs a DERIVATION rather
   than a measurement: the 0.7217 α floor was computed from this exact colour, so retuning
   --cs-brand-900 without revisiting this voids the guarantee with nothing to notice it. If that token
   moves, recompute the floor — do not just match the new hex here.

   THE GUARANTEE IS THREE NUMBERS, NOT ONE: α (0.86), the vertical inset (-3rem) and the blur radius
   (1.25rem). A blurred edge feathers, so the EFFECTIVE α at the copy box's own boundary is
   α × Φ(inset/σ), not α. Celeste-2 computed it (ER-12 review):

       inset 1rem    -> effective 0.678   BELOW the 0.7217 floor
       inset 1.25rem -> effective 0.724   marginal
       inset 2rem    -> effective 0.813
       inset 3rem    -> effective 0.853   <- shipped, 2.4x the minimum inset

   **Minimum safe inset is ~1.24rem at this α and blur.** There is real margin at 3rem and nothing to
   change — but a layout-motivated trim of that inset would break the guarantee SILENTLY, visible only
   at the very edge of the copy box, where no measurement in this ticket would catch it. If you shrink
   the inset, recompute; if you raise the blur, recompute. They move together.

   The blur itself is safe: blurring a large uniform fill leaves the interior exactly 0.86 and
   feathers only the outer band. */
.cs-home-cta__copy {
	position: relative; /* NOT `isolation: isolate` — ::before must reach the section's stacking
	                       context at z-index -1, above the Earth at -2 and below the copy. */
}

/* Vertically bound to the copy box (the guarantee); horizontally unbounded (aesthetics only).
   `-50vw` runs it past both section edges, where `.cs-home-cta`'s existing `overflow: hidden` clips
   it. Bounding it horizontally too left a visible soft-edged rectangle around the copy — the scrim
   box stops at the section's gutter, which is 180px in from each side at 1440. Extending sideways
   costs nothing: the guarantee only requires covering AT LEAST the text box, and this covers
   strictly more. It also converges with what Vivian-2 wanted visually — feathering on the vertical
   axis only, full width at every stop — while keeping the element binding that makes it an
   invariant rather than a percentage that needs re-proving. */
.cs-home-cta__copy::before {
	content: "";
	position: absolute;
	inset: -3rem -50vw;
	z-index: -1;
	background: rgba(16, 34, 74, 0.86);
	filter: blur(1.25rem);
}

/* Phone/tablet: open a band below the copy for the planet to read in. Without it the copy fills the
   section, the scrim must cover the copy, and the still is left as a slightly darker strip at the
   very bottom edge — which a visitor reads as a gradient artefact rather than a planet, i.e. worse
   than either doing it properly or not at all (Vivian-2, ER-12).

   docs/06 mandates designing the 480 tier first, so "it's a desktop ask" is not available as a
   reason to skip this. Additive: it sits below the last content on the page and the space it opens
   is filled by planet rather than void. */
@media (max-width: 980px) {
	/* `.cs-home section.cs-home-cta`, not `.cs-home-cta` — the base rule is `.cs-home section`
	   (0-1-1), which outranks a bare class (0-1-0), so the obvious selector silently loses and the
	   band stays 16px. Measured, not assumed: the first attempt at this changed nothing at all. */
	.cs-home section.cs-home-cta {
		/* The band has to scale with the STILL, not sit at a fixed rem. The still is width-fitted
		   (`background-size: 100% auto` below), so its rendered height is viewport-width / its own
		   2.25 aspect: 160px at 360, but 341px at 768. A fixed 13rem band worked at 360 and failed at
		   768 — measured, not predicted: the arc landed above the band and back under the scrim, and
		   the curve test found no limb there at all while passing at 360.
		   Deriving the padding from the same aspect keeps the whole arc inside the band at every
		   phone width. +3rem clears the scrim's feather. */
		padding-block-end: calc(100vw / 2.25 + 3rem);
	}
}

.cs-home-cta__earth-canvas {
	display: none;
	width: 100%;
	height: 100%;
}

@media (min-width: 981px) {
	.cs-home-cta {
		/* Room for the planet to read as huge without crossing into the fleet band — Vivian-2's
		   "give the CTA room rather than span two sections", settled at 48rem after measuring what
		   height actually buys.

		   The copy block is a fixed ~401px, so a taller section shrinks it as a FRACTION and the
		   difference goes to unscrimmed planet below it: at 38rem the copy took 66% of the band and
		   left ~9% showing the limb at full strength; at 48rem it takes ~52% and leaves ~18%. Height
		   and CAMERA_PITCH_RAD are one decision, not two — without re-deriving the pitch, extra
		   height just buys more SCRIMMED planet and the curve stays muted behind the copy. */
		min-height: 48rem;
		display: grid;
		/* `start`, not `center` — Vivian-2's ER-12 call, and the lever that was missing from the
		   height-only options. Under a container-bound scrim, centring is what forces the scrim into
		   the middle of the frame and splits the unscrimmed area into two thin strips. Moving the copy
		   up takes the scrim with it and leaves ONE continuous band at the bottom: 238px here against
		   135px for the same height centred, without adding a pixel of section.

		   Centring was never load-bearing. It is inherited from ER-9's band, when this background was
		   a flat colour and there was nothing for the copy to be positioned relative to. There is now.
		   Height, copy position and earth-backdrop.js's CAMERA_PITCH_RAD are one decision — changing
		   any one of them without the others puts the limb back under the copy. */
		align-content: start;
	}

	.cs-home-cta__earth {
		background-image: none; /* The live canvas takes over from the still. */
	}

	.cs-home-cta__earth-canvas {
		display: block;
	}

	/* Vivian-2: two orbital devices in one band compete, and the ring's job — a hint of orbit — is
	   done far better by an actual planet. Retired only once earth-backdrop.js has a real context, a
	   linked program and geometry, at which point it sets [data-cs-earth-backdrop-ready]. If WebGL
	   is unavailable, the context is lost, or a texture tile fails, the attribute is absent or gets
	   removed and the ring comes back — so the band degrades to exactly what shipped in ER-9, which
	   is already contrast-proven, rather than to a flat colour. */
	.cs-home-cta__earth[data-cs-earth-backdrop-ready] ~ .cs-home-cta__ring {
		display: none;
	}
}

/* =============================================================================
   .cs-home--signup — the Create an Account page (ER-21, wp-cli/content/signup.html)

   Third page on this stylesheet after the landing page and About, and the scope
   extension is the same one home.css's own docblock describes: one file, one
   enqueue, so the pages read as one system.

   THE FORM IS THE ART. On the landing page the hero's right-hand side carries the
   Earth; here it carries [cs_signup_form]. That is the whole design idea — on a
   signup page the form is what the visitor came for, and the previous version
   put it above 436 words of prose in four sections, which is the "wall of text"
   this ticket exists to remove. The panel is opaque `--cs-surface-panel`, so it
   reads as an object floating on the starfield and every contrast pair inside it
   is unaffected by what is behind it.

   IT DOES NOT FORK `.cs-form`. The only rule below that touches the component is
   a width, which is a layout slot deciding how wide its content sits — the same
   thing a grid column does. Nothing here restyles a field, a label, an error or
   the honeypot, and nothing may: two forms consume that contract
   (docs/68-shared-form-ui-contract.md) and a page-level override would fork it
   for one of them.
   ============================================================================= */

/* Divi renders the page title as `h1.entry-title` inside the article, ABOVE this
   file's markup and outside `.cs-home` — verified on the live page, one h1,
   `article > h1.entry-title.main_title`. The landing and About pages avoid the
   duplicate by carrying a mapped Theme Builder body, which suppresses it; this
   page has none, and mapping one is a deploy hazard this ticket is not taking on.

   `display: none` rather than a visual hide: it removes the element from the
   accessibility tree entirely, so exactly one h1 is announced — the hero's. A
   clip/offscreen technique would leave two.

   Own block, no comma list, matching this file's existing `:has()` convention —
   a browser without `:has()` drops the whole rule a `:has()` selector belongs to,
   and here that degrades to a visible duplicate heading rather than to a page
   with no heading at all. */
article:has(.cs-home--signup) h1.entry-title {
	display: none;
}

/* The hero headline is a sentence of two clauses rather than the landing page's
   noun phrase, so the landing page's 16ch cap clips it into five lines.

   `text-wrap: balance` is doing the real work and is not decoration: at 22ch the
   first render broke as "Browse without an / account. Request with / one." — a
   two-word orphan on the third line, which is the one thing a display headline
   cannot have. Balance evens the lines instead of filling greedily. It degrades
   to normal wrapping where unsupported, which is the pre-balance render: legible,
   just less good. */
/* Two pages, one headline treatment. Splitting the modifiers keeps the type
   treatment shared and the layout choice separate — one modifier doing two
   unrelated jobs is what made that hard to vary.

   ER-26 CORRECTION: this comment used to say `--provider` deliberately carries no
   two-column grid. It carries one now, and the reason the original gave is intact
   — what measured 7.9x the height of its own copy was the FOURTEEN-FIELD FORM in
   that slot, not the slot. The column now holds a three-item list roughly the
   height of the copy beside it. The form is still not allowed in there. Corrected
   here rather than only in the content file, because this is where the next person
   copies the pattern from. */
.cs-home-hero--signup h1,
.cs-home-hero--provider h1 {
	max-width: 22ch;
	text-wrap: balance;
}

/* Phone tier first: copy, then the form beneath it. No column rule needed —
   `.cs-home-hero__inner` is already a single-column grid at this width. */
.cs-signup-panel {
	min-width: 0;
}

/* The width is set on the slot, not on the component: `.cs-form` caps itself at
   min(46rem, 100%) for a full-width page, and inside a hero column that cap is
   the column's job instead. */
.cs-signup-panel .cs-form {
	max-width: 100%;
	margin: 0;
}

@media (min-width: 981px) {
	/* Two columns here, overriding the single-column rule the landing page needs
	   (its art moved to an absolute layer behind the copy; this page's "art" is a
	   real element that has to hold its own space). The form column is fixed-ish
	   so the copy takes the slack: a form that grows with the viewport puts its
	   labels a long way from its inputs. */
	/* Same split on both pages, and the same 27rem, on purpose: the two heroes then
	   rhyme, and the right-hand slot means the same thing on each — the thing you
	   act on (/signup/'s form) or the thing you check first (the provider signup page's
	   qualification list). `start` rather than the base `center`, because two
	   columns of unequal height centred against each other leaves the shorter one
	   floating with no relationship to the headline above it. */
	.cs-home-hero--signup .cs-home-hero__inner,
	.cs-home-hero--provider .cs-home-hero__inner {
		grid-template-columns: minmax(0, 1fr) minmax(0, 27rem);
		align-items: start;
	}
}

/* -----------------------------------------------------------------------------
   SECTION RHYTHM. `.cs-home section` sets padding-block to --cs-space-3xl (96px)
   at >=981px, which is right for the landing page's tall content blocks and much
   too loose for this page's short ones — measured before fixing: 96px of padding
   under a 60px-tall three-up, reading as dead space rather than as breathing
   room. It also overrode the hero's OWN bottom padding, because `.cs-home
   section` (0,1,1) outranks `.cs-home-hero` (0,1,0).

   Overridden by ID, which is this file's established idiom for exactly this — see
   the `#cs-home-margin` note above, and its explanation of why an ID (1,0,0) needs
   no `.cs-home section#id` trick.
   -------------------------------------------------------------------------- */

@media (min-width: 981px) {
	/* The hero's intended shape, restored: generous above, tight below, so the
	   next section sits close. Same values `.cs-home-hero` asks for. */
	#cs-signup-hero,
	#cs-provider-hero {
		padding-block: var(--cs-space-3xl) var(--cs-space-lg);
	}

	/* ER-26 removed #cs-signup-uses and #cs-provider-uses from this list. They are
	   inside the hero now, not siblings of it, so `.cs-home section`'s block padding
	   never reaches them and there is nothing here to override — leaving them listed
	   would have added 48px/32px on top of their own panel padding. */
	#cs-provider-form,
	#cs-provider-next {
		padding-block: var(--cs-space-xl) var(--cs-space-lg);
	}

	#cs-signup-why {
		padding-block: 0 var(--cs-space-xl);
	}
}

/* -----------------------------------------------------------------------------
   What the account is for — three lines, not three paragraphs.

   Deliberately a list of one-line items with a left rule, which is the landing
   page's `.cs-home-stats` idiom rather than a new one. The content it replaces
   was two paragraphs of 62 and 80 words saying the same three things.
   -------------------------------------------------------------------------- */

.cs-signup-uses h2 {
	margin: 0 0 var(--cs-space-md);
}

/* Divi's dynamic CSS matches this <ul> via `#left-area ul` (specificity 1,0,1),
   putting back a disc and `padding: 0 0 23px 1em`. An ID beats any class-only
   selector at any source order, so both need !important, and `padding` needs it
   on the SHORTHAND — the declaration being overridden sets all four sides. Same
   fix, same reason, as `#left-area .cs-home-stats` above. */
#left-area .cs-signup-uses__list {
	display: grid;
	gap: var(--cs-space-md);
	margin: 0;
	padding: 0 !important;
	list-style: none !important;
}

@media (min-width: 981px) {
	#left-area .cs-signup-uses__list {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: var(--cs-space-lg);
	}
}

#left-area .cs-signup-uses__list li {
	margin: 0;
	padding-left: var(--cs-space-sm);
	border-left: 2px solid var(--cs-brand-400);
	color: var(--cs-text-muted);
	line-height: var(--cs-leading-normal);
}

#left-area .cs-signup-uses__list li strong {
	display: block;
	color: var(--cs-text-strong);
	font-weight: 600;
}

/* -----------------------------------------------------------------------------
   ER-26 — the same list, promoted into the hero on both signup pages.

   The ask was "more visible, more readable". Visible is position and is answered
   by the markup: /signup/ nests it in the hero's copy column under the lead,
   the provider signup page gives it the hero's second column, which was empty. Measured
   on the provider page, the heading moved from 4407px down a 390px phone — 5.2
   viewports, below the entire fourteen-field form — to inside the first screen.

   Readable is this block, and it is three separate things:

   1. AN OPAQUE SURFACE, NOT THE STARFIELD. The hero carries a photographic
      background. `--cs-text-muted` over it has no contrast ratio at all, only a
      worst-case pixel measurement — qa-2 measured exactly that case on this hero
      at 1.7-2.8:1 and it is why `.cs-home__eyebrow` is brand-300 rather than
      brand-400. An opaque panel takes the photo out of the pair entirely, which
      is the same move `.cs-signup-panel` already makes for the form beside it.

   2. THE TEXT COLOUR IS PROMOTED WITH THE BLOCK. `--cs-text-muted` was right for
      a secondary section below the fold and is wrong for the first thing under
      the headline; a de-emphasis token on promoted content is a contradiction.

   3. ONE COLUMN. The three-across grid is right at full content width and wrong
      in a 27rem hero column, where it would put ~14 characters on a line.

   RATIOS ARE A PROPERTY OF THE PAIR, SO THESE ARE REMEASURED, NOT CARRIED OVER.
   The old numbers were against the page canvas `--cs-void-900` and do not survive
   the move to `--cs-surface-panel` (`--cs-void-600`, LIGHTER, so every ratio
   falls). Against #1E2B47:

       --cs-text      #E2E8F0  11.42:1   list text        (was --cs-text-muted, 7.72:1 on canvas)
       --cs-text-strong #F8FAFC 13.45:1  the lead-in and the h2
       --cs-brand-400 #5E8FF0   4.47:1   the 2px rule — a graphic, 1.4.11 wants 3:1

   The list text ends up HIGHER than it was before the move (11.42 vs 7.72) despite
   the background getting lighter, because point 2 more than pays for it. That is
   the readability claim, and it is the reason it is a number here rather than an
   adjective.
   -------------------------------------------------------------------------- */

.cs-signup-uses--panel {
	padding: var(--cs-space-md);
	border-radius: var(--cs-radius-md);
	background: var(--cs-surface-panel);

	/* THE PANEL PADDING COMES OUT OF THE LINE LENGTH, AND ON A PHONE THERE IS NONE
	   TO SPARE. Caught by measuring rather than by looking: the first version of
	   this rule took the 390px measure from 34 characters per line to 29, so the
	   block became better lit and harder to read in the same change — a readability
	   regression inside a readability fix, which is exactly the kind that ships.

	   The pull-out is the padding NEGATED, not a round number that looked about
	   right. Padding and margin cancel, so the text sits on the same 312px it had
	   before and the measure is unchanged at 34ch; the panel is paid for out of the
	   hero's gutter instead. An intermediate 16px was tried and measured 32ch —
	   still short, and misaligned from the content edge anyway, so it was paying
	   the alignment cost without buying the measure back.

	   Safe at every width this applies to, because the gutter is
	   `max(10vw, 50vw - 540px)`: 39px at 390, 32px at 320, always more than the
	   24px pulled. `horizontalOverflow` is asserted false at 390 by the harness. */
	margin-inline: calc(var(--cs-space-md) * -1);
}

@media (min-width: 981px) {
	/* No pull-out here: both columns are wide enough that the padding is affordable,
	   and at this tier the panel sits inside a grid column rather than against the
	   page edge, so widening it would break the column, not the gutter. */
	.cs-signup-uses--panel {
		margin-inline: 0;
	}
}

/* Only /signup/ nests this inside the copy column, where it follows the lead and
   has to separate itself from it. On the provider signup page it is a grid child of
   `.cs-home-hero__inner`, whose own `gap` already does that — a margin there would
   double the space on one side only. */
.cs-home-hero__copy .cs-signup-uses--panel {
	margin-top: var(--cs-space-md);
}

/* Both selectors carry `#left-area` because the rules they override do: Divi's
   dynamic CSS reaches these through `#left-area ul` / `#left-area li`, and a
   class-only rule loses to an ID at any source order. Two extra classes past the
   ID, so this beats the base `#left-area .cs-signup-uses__list` unconditionally
   rather than by sitting later in the file. */
#left-area .cs-signup-uses--panel .cs-signup-uses__list {
	grid-template-columns: minmax(0, 1fr);
	gap: var(--cs-space-sm);
}

#left-area .cs-signup-uses--panel .cs-signup-uses__list li {
	color: var(--cs-text);
	/* Divi's `#left-area li` sets 14px on desktop. Fine for a three-across strip of
	   one-liners; not for the first block a visitor reads. Base 16px, stated rather
	   than inherited, so it does not depend on which Divi rule happens to win. */
	font-size: var(--cs-text-base);
}

/* -----------------------------------------------------------------------------
   Why a quote needs a name — an aside, not a loose paragraph.

   The first render left this as bare text floating in the column, because
   `.cs-home-notice` turned out to be a hook with a single `strong` rule and no
   block of its own. Reusing a class without reading it is how that happened; the
   fix is a real block rather than a better guess at someone else's.

   Panel surface with a left accent rule, which is the register this page already
   uses for the three-up above — secondary to the form, but clearly an object
   rather than leftover copy. The prose keeps its 68ch measure inside a full-width
   enclosure, so the line length stays readable while the element does not look
   orphaned.
   -------------------------------------------------------------------------- */

.cs-signup-why {
	/* The enclosure hugs its text rather than spanning the column. Full width left
	   the panel 45% empty on the right at 1440 — measured, and it read as an
	   unfinished box rather than as air, because the prose inside is capped at the
	   68ch measure `.cs-home p` sets and cannot fill it. Slightly wider than that
	   cap so the padding is not doing the capping. */
	max-width: 74ch;
	padding: var(--cs-space-md) var(--cs-space-md) var(--cs-space-md) var(--cs-space-sm);
	border-radius: 0 var(--cs-radius-md) var(--cs-radius-md) 0;

	/* BF-45: the warning ramp, not the neutral panel. On `--cs-surface-panel` with
	   `--cs-text-muted` prose this read as de-emphasised boilerplate — the visual
	   register of a footnote — when its job is to tell someone why the form is
	   asking for identity before they decide to leave. Same `*-text`/`*-tint`
	   pairing the status badges use, so it is an existing register on this site
	   rather than a new one.

	   The pairing matters, not just the colour: `--cs-warning-text` is documented
	   at 8.98:1 ON `--cs-warning-tint`, and that ratio is a property of the pair.
	   Keeping the old panel background while recolouring only the text would have
	   voided the measurement this relies on. */
	border-left: 2px solid var(--cs-warning-text);
	background: var(--cs-warning-tint);
}

.cs-home .cs-signup-why p {
	margin: 0;
	color: var(--cs-warning-text);
	line-height: var(--cs-leading-normal);
}

/* -----------------------------------------------------------------------------
   The return path, as an action rather than a sentence with a link in it.

   `.cs-home p { max-width: 68ch }` is (0,1,1) and caps every paragraph on the
   page — correct for prose and wrong for a control row, which measured 544px
   wide with its divider stopping half way across the column. Two classes plus the
   element (0,2,1) to outrank it, rather than !important.
   -------------------------------------------------------------------------- */

.cs-home p.cs-signup-return {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--cs-space-sm);
	max-width: none;
	margin-block: var(--cs-space-lg) 0;
	padding-top: var(--cs-space-md);
	border-top: 1px solid var(--cs-border-surface);
	color: var(--cs-text-muted);
}
