/*
 * Steps. An ordered list on a vertical rail: the rail is a pseudo-element on
 * the list, the numbered node sits in its own grid column, and the panel
 * carries the copy. No JavaScript — the reference's scroll-traced fill is
 * rendered in its fully-drawn state.
 */

/*
 * The reference gives this section no padding of its own and pads three inner
 * bands instead, which makes it the one section on the homepage that is not on
 * the shared rhythm: more air below the call to action than above the header,
 * and a wider gap between the header and the rail than between the rail and the
 * call to action. Reproduced here by overriding the shell's bottom padding and
 * the two internal gaps rather than by wrapping the markup in three bands.
 */
/*
 * Two classes, not one. `.cobell-section` sets `padding-block` from the theme
 * stylesheet, which is enqueued after the block styles — so a single-class rule
 * here ties on specificity and loses on order. Anything overriding the section
 * shell's own padding has to carry both classes.
 */
/*
 * The top is stated, not inherited. All three reference components open this
 * section with `pt-28` — 112 — where the interior shell gives 96, and this block
 * used to get 112 for the wrong reason: the shell's mobile token was itself 112,
 * the homepage's value, so `steps` read correct on every page by accident.
 * Correcting the token to live's interior 96 took 16px off the top of every
 * steps section on eight pages at once, and it showed up as an exact −16 per
 * page in the sweep, which is what pointed here.
 *
 * The block already owned its bottom, so owning both is the honest shape — this
 * padding is the reference's, not the shell's, and it should not move when the
 * shell does.
 */
.cobell-section.cobell-steps {
	padding-top: 7rem;
	padding-bottom: 8rem;
}

/*
 * The reference closes this section with `pb-24 md:pb-32` where no call to
 * action follows the rail — 96 and 128 against the 128 and 160 the CTA register
 * carries. Both of its no-CTA consumers are the two `heading_scale: default`
 * pages, but the trigger is the CTA rather than the register: the button repeater
 * is what live's variant switch actually keys on, so `:has()` reads it off the
 * rendered markup instead of asking the editor to keep two fields agreeing.
 */
.cobell-section.cobell-steps:not( :has( .cobell-steps__cta ) ) {
	padding-bottom: 6rem;
}

/*
 * Header and rail are both **narrower than their max-width reads**, and this is
 * the single largest geometry error the block has had.
 *
 * The reference wraps each in a Tailwind container — `max-w-3xl px-6 md:px-14`
 * for the header, `max-w-5xl px-6 md:px-14` for the rail — and Tailwind's
 * preflight sets `box-sizing: border-box`, so that padding comes *out* of the
 * 48rem and 64rem rather than sitting outside it. The drawn column is 41rem and
 * 57rem at `md` and up, not 48 and 64. Ours ran 112px wide on both, which put
 * the section heading on one line where live wraps it to two and left every step
 * panel 56px wider than live's.
 *
 * The `100vw` term is the same arithmetic below the cap, where the viewport is
 * what binds rather than the max-width. It cannot be `100%`: this element sits
 * inside the section shell, whose gutter has already been subtracted, and the
 * reference's container has no shell around it to subtract.
 *
 * Two classes on the header, not one. It also carries
 * `.cobell-section__inner--narrow`, which sets `max-width` from the theme
 * stylesheet — enqueued after the block styles, so a single-class rule here ties
 * and loses. It read as working only because `contentSize` happens to be 48rem.
 */
.cobell-steps .cobell-steps__header {
	max-width: min( 41rem, 100vw - 3rem );
	margin-inline: auto;
	margin-bottom: 4rem;
	text-align: center;
}

/*
 * This heading is its own register, not the xxx-large preset the other section
 * headings share, and the block serves two of them — set here rather than on
 * the preset, which is right for the eight blocks that consume it.
 *
 * Regular is the base: 52px at 1440 on 400, which is what the reference's
 * HistoryTimeline and ApplicationSteps write directly (/our-history and
 * /how-to-apply). Display is the walkthrough register — the homepage, the six
 * scholarship pages and /support/students all route through SectionHeader,
 * which adds `font-bold` and a step of size on looser tracking. Weight, size
 * and tracking all move together, so it is one field, not three.
 */
.cobell-steps__heading {
	margin: 0;
	font-size: clamp( 2rem, 4.2vw, 3.25rem );
	font-weight: 400;
	line-height: 1;
	letter-spacing: -0.015em;
}

.cobell-steps--display .cobell-steps__heading {
	font-size: clamp( 2rem, 4.5vw, 3.5rem );
	font-weight: 700;
	letter-spacing: -0.01em;
}

/*
 * The intro rides `heading_scale`, same as the heading — the two registers
 * write different copy sizes and they move together.
 *
 * Regular is `text-base md:text-lg leading-relaxed`, 16px to 768 and 18px
 * above, which is what --cobell-body-size already does. Display is flat
 * `text-base` on 1.5 at every width: the reference's SectionHeader does not
 * step its intro up, so riding the body token there ran it 2px large at
 * desktop and wrapped a one-line sentence onto two on eight pages.
 */
.cobell-steps__intro {
	max-width: 42rem;
	margin-inline: auto;
	margin-top: 1.5rem;
	color: color-mix( in srgb, var( --wp--preset--color--forest ) 70%, transparent );
	font-size: var( --cobell-body-size );
	line-height: 1.625;
}

/* Both registers write this subhead at `text-[#26352a]/70` directly rather than
   taking the register every other section intro uses — a 5% step off the shared
   body token, but it is the line directly under the largest heading on the page.
   The display register also holds the size flat and the leading tighter. */
.cobell-steps--display .cobell-steps__intro {
	font-size: 1rem;
	line-height: 1.5;
}

@media ( min-width: 48rem ) {
	/* `pt-36` on the reference's header, against the 8rem the interior shell
	   gives. The homepage already sits at 9rem from the `body.home` exception, so
	   this only moves the eight interior placements — and it moves them onto the
	   value the homepage was already using. */
	.cobell-section.cobell-steps {
		padding-top: 9rem;
		padding-bottom: 10rem;
	}

	.cobell-section.cobell-steps:not( :has( .cobell-steps__cta ) ) {
		padding-bottom: 8rem;
	}

	.cobell-steps .cobell-steps__header {
		max-width: min( 41rem, 100vw - 7rem );
		margin-bottom: 6rem;
	}

	/* `mb-8 md:mb-10` on the two hand-written headers, where the shared
	   `.cobell-eyebrow` stops at 2rem — which is `SectionHeader`'s own default and
	   so already correct for the display register. Eight pixels, and it moves the
	   whole rail down with it. */
	.cobell-steps:not( .cobell-steps--display ) .cobell-steps__header .cobell-eyebrow {
		margin-bottom: 2.5rem;
	}
}

/*
 * The display register's eyebrow is block-level, and this is worth 10px of dead
 * space above every one of them.
 *
 * `.cobell-eyebrow` is `inline-flex`, which is right for the two hand-written
 * headers — the reference writes those as `inline-flex` too. `SectionHeader`, which
 * the other seven placements go through, uses `flex justify-center`. An
 * inline-level box sits on a line box and inherits the container's 1.6 leading as
 * half-leading above it; a block-level one starts at the container's top edge.
 * Nothing about the eyebrow itself looks different, which is why it read as a
 * padding bug in the header.
 */
.cobell-steps--display .cobell-steps__header .cobell-eyebrow {
	display: flex;
	justify-content: center;
}

.cobell-steps__list {
	position: relative;
	margin-inline: auto;
	margin-block: 0;
	padding: 0;
	max-width: min( 57rem, 100vw - 3rem );
	list-style: none;
}

/* Declared after the base rule rather than in the block above: a media query
   adds no specificity, so the two single-class rules are decided on source
   order and the base one would win at every width. */
@media ( min-width: 48rem ) {
	.cobell-steps__list {
		max-width: min( 57rem, 100vw - 7rem );
	}
}

/*
 * The rail. Drawn behind the nodes, inset to pass through their centres. Stops
 * short at both ends so it does not overshoot the first and last node.
 *
 * Track colour is the reference's cool forest hairline, not a dilute clay. The
 * track is the *unwalked* path and the clay fill draws over it, so a warm track
 * leaves almost nothing between drawn and undrawn and the trace stops reading
 * as progress at all.
 */
.cobell-steps__list::before {
	content: "";
	position: absolute;
	top: 1.375rem;
	bottom: 1.375rem;
	left: 1.375rem;
	width: 1px;
	background-color: color-mix( in srgb, var( --wp--preset--color--forest ) 15%, transparent );
}

/*
 * The traced fill, drawn over the track. motion.js scrubs
 * --cobell-rail-progress against scroll; the default of 1 is the fully-drawn
 * state, which is what a reader gets with no scripting and what the reference
 * itself renders under reduced motion. Nothing here depends on the script
 * arriving.
 */
.cobell-steps__list::after {
	content: "";
	position: absolute;
	top: 1.375rem;
	bottom: 1.375rem;
	left: 1.375rem;
	width: 1px;
	background-color: var( --wp--preset--color--clay );
	transform: scaleY( var( --cobell-rail-progress, 1 ) );
	transform-origin: top center;
}

/*
 * Node state. Absence of the attribute is the lit state, so the nodes read as
 * reached until the script says otherwise — again, no-JS lands on the finished
 * composition rather than an unlit one.
 */
.cobell-steps__item[ data-rail-reached="false" ] .cobell-steps__number {
	border-color: color-mix( in srgb, var( --wp--preset--color--forest ) 30%, transparent );
	color: color-mix( in srgb, var( --wp--preset--color--forest ) 55%, transparent );
	box-shadow: 0 0 0 0.25rem transparent;
}

.cobell-steps__number,
.cobell-steps__eyebrow {
	transition: color 500ms ease, border-color 500ms ease, box-shadow 500ms ease;
}

/*
 * The copy dims with its node. Applied to the panel rather than the whole item
 * because motion.js owns the item's opacity for the section entrance, and an
 * inline opacity there would override the reveal and strand the step.
 */
.cobell-steps__panel {
	transition: opacity 200ms linear;
}

@media ( prefers-reduced-motion: reduce ) {
	.cobell-steps__number,
	.cobell-steps__eyebrow,
	.cobell-steps__marker::before,
	.cobell-steps__panel {
		transition: none;
	}
}

/*
 * The item is lifted above the rail as a whole, and this is what actually
 * keeps the hairline out of the numbered circle.
 *
 * An opaque background on the node is not enough, and neither is a z-index on
 * the node alone: motion.css's section entrance matches `[class*="__item"]`,
 * so every revealed step carries `filter: blur(0)`, and any filter other than
 * `none` makes the element a stacking context. That traps the node's z-index
 * inside the item, where it cannot be compared against the rail — which is a
 * positioned pseudo-element on the list and so paints after the item either
 * way. Positioning the item and giving it a z-index moves the whole row into
 * that same pass, ahead of the rail.
 *
 * The row has no background of its own, so the rail still shows through
 * everywhere except the circle, which is the effect wanted.
 *
 * Reading the node's computed `z-index` says `1` and proves nothing — the
 * declaration applies, it just has nothing to win against. Screenshot the
 * junction instead.
 */
.cobell-steps__item {
	position: relative;
	z-index: 1;
	display: grid;
	grid-template-columns: 2.75rem 1fr;
	align-items: start;
	gap: 1.5rem;
	padding-bottom: 5rem;
}

/*
 * Live's rhythm is 5rem between rows and 7rem from 48rem up, and it is written
 * out rather than taken from `--wp--preset--spacing--60`, which resolves to
 * 2.25rem — see the note on the spacing scale in CLAUDE.md. Ours was landing
 * 76px tight per row, which compounds: node centres sat 179px apart against
 * live's 248px.
 */
@media ( min-width: 48rem ) {
	.cobell-steps__item {
		padding-bottom: 7rem;
	}
}

.cobell-steps__item:last-child {
	padding-bottom: 0;
}

.cobell-steps__marker {
	display: flex;
	justify-content: center;
}

/*
 * The panel is capped, and the cap is what makes the copy wrap the way live's
 * does. The reference's StepPanel is `max-w-sm` — 24rem — at every width, so a
 * step's title breaks over two lines rather than running the width of its
 * column. Without it the panel simply filled the 1fr track.
 *
 * The 1rem toward the rail is the wrapper's `md:pr-4` / `md:pl-4`. It sits on
 * the panel here rather than on a wrapper element, which lands in the same place
 * because the theme is content-box: 24rem of content plus 1rem of padding is
 * 400px against a 394px column, so the column binds and the copy measures 378 —
 * live's number to the pixel. The `auto` margin only bites if a column ever
 * exceeds 400px, which is the same thing the reference's `ml-auto` is there for.
 */
.cobell-steps__panel {
	max-width: 24rem;
}

/*
 * Number node. The opaque background is what the rail disappears behind; the
 * row above it is what puts the two in the right order. The `z-index` here is
 * the reference's `relative z-10` and is kept for the same reason, but on its
 * own it decides nothing — see the note on the item.
 *
 * The halo is the reference's second ring (`ring-4 ring-[#b85a32]/15`), a
 * 4px pool of warm light that fades in when the rail's leading edge reaches
 * the node. Drawn as a box-shadow rather than a second element: it sits outside
 * the border box the same way, and there is nothing for a spare span to carry.
 * Present at rest because absence of the attribute is the lit state.
 *
 * Numerals are set the way live sets them, measured on the deployed site:
 * tabular figures, `tracking-tight`, and the two variation axes. Warbler
 * Display draws its tabular set wider and more evenly spaced than its
 * proportional one — 20.5px against 17.1px for "02" — which is the whole of
 * why ours read as a tighter, heavier pair of digits at the same 15px.
 *
 * `box-sizing` is declared because the theme has no global reset: 2.75rem plus
 * two 1px borders made the circle 46px tall inside a 44px column, so it was a
 * very slightly vertical ellipse.
 *
 * Clay, not ember. Live's lit numeral and ring are both full clay, which is
 * 3.72:1 on cream where 15px text wants 4.5:1. Kept at live's value, the same
 * call recorded at the top of need-help.css: the numeral is `aria-hidden` and
 * the `<ol>` is what conveys order, so nothing depends on reading it. Ember
 * clears at 6.94:1 and is the one-declaration swap if that is ever reversed.
 */
.cobell-steps__number {
	position: relative;
	z-index: 1;
	box-sizing: border-box;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 2.75rem;
	height: 2.75rem;
	border: 1px solid var( --wp--preset--color--clay );
	border-radius: 999px;
	background-color: var( --wp--preset--color--cream );
	box-shadow: 0 0 0 0.25rem color-mix( in srgb, var( --wp--preset--color--clay ) 15%, transparent );
	color: var( --wp--preset--color--clay );
	font-family: var( --wp--preset--font-family--serif );
	font-feature-settings: "tnum";
	font-variation-settings: "SOFT" 50, "opsz" 48;
	font-size: 0.9375rem;
	line-height: 1;
	letter-spacing: -0.025em;
}

/*
 * Row title. Three things here were not the reference's, and only the size shows
 * at desktop: it was a flat 2rem where live ramps `clamp(1.5rem, 2.6vw, 2rem)`,
 * so it agreed at 1231px and up and ran as much as 8px large below that.
 *
 * The tracking was inheriting the theme's `--heading-tracking` of -0.015em where
 * the reference sets -0.01em, and the optical size axis was unset. Warbler
 * Display is variable and the reference pins `opsz 72` here — a heavier, more
 * open drawing than the axis default, which is the difference a reader sees
 * before they can name it.
 *
 * The 0.5rem of top padding was ours. The reference's panel starts at the item's
 * top edge, and on the rows with no year eyebrow that put the title 8px below
 * live's.
 */
.cobell-steps__title {
	margin: 0;
	font-size: clamp( 1.5rem, 2.6vw, 2rem );
	line-height: 1.05;
	letter-spacing: -0.01em;
	font-variation-settings: "SOFT" 50, "opsz" 72;
}

/*
 * 70%, not 85, and 1.625 leading rather than 1.6. The reference's StepPanel sets
 * this copy at `text-[#26352a]/70 leading-relaxed` with no active variant, so it
 * is one constant across every row and both registers — the rail component is
 * shared with the history timeline.
 *
 * Worth knowing how this hid: the two colours are written in different notations
 * on the two sides, `color(srgb …)` here against live's `lab(…)`, so a string
 * comparison of computed values reports a difference on every tinted element on
 * the page and a reader dismisses the lot as noise. Rasterise the colour and
 * compare the bytes — 0.85 is rgb(70,83,74) against live's rgb(103,113,105).
 */
.cobell-steps__body {
	margin-top: 0.75rem;
	color: color-mix( in srgb, var( --wp--preset--color--forest ) 70%, transparent );
	font-size: 0.9375rem;
	line-height: 1.625;
}

/* `text-[15px] md:text-base`. This copy does not ride --cobell-body-size: the
   shared token steps 16 → 18 and the rail steps 15 → 16. */
@media ( min-width: 48rem ) {
	.cobell-steps__body {
		font-size: 1rem;
	}
}

/*
 * The reference passes this body as a string, so its container has no paragraph
 * inside it; ours is a WYSIWYG field and does. The UA's 1em paragraph margin then
 * escapes the container at both ends — it collapses through, because nothing here
 * has a border or padding to stop it. That read as 4px too much air above the copy
 * and 16px too much below the panel, on every row of every placement.
 *
 * Only the outer edges are zeroed. `.cobell-prose > * + *` owns the rhythm
 * between paragraphs and is left to it.
 */
.cobell-steps__body > :first-child {
	margin-top: 0;
}

.cobell-steps__body > :last-child {
	margin-bottom: 0;
}

/*
 * Per-row eyebrow. The history timeline puts each milestone's year here, so it
 * sits above the row's heading and reads before it.
 *
 * 1rem below it, the reference's `mb-4`. It was `--wp--preset--spacing--20`,
 * which resolves to 0.44rem and not the 0.5rem theme.json's array reads as, so
 * the year sat 9px tight against its title — see the spacing-scale note in
 * CLAUDE.md.
 *
 * Clay lit, forest at 65% unlit, which is the reference's pair. The year lights
 * with its node rather than sitting at one colour, and ember was the substitute
 * this theme has already decided against twice. It costs 1.4.3 the same way the
 * other clay does: 3.72:1 at 10px where normal-size text wants 4.5:1. Ember is
 * 6.26:1 and is the one-declaration swap if that trade is reversed — do not make
 * it silently.
 *
 * Tabular figures for the same reason the node numerals carry them: these are
 * years, and Warbler Display's proportional set draws 1 narrow enough that a
 * column of them reads ragged.
 */
.cobell-steps__eyebrow {
	margin: 0 0 1rem;
	color: var( --wp--preset--color--clay );
	font-feature-settings: "tnum";
	font-size: var( --wp--custom--eyebrow-size );
	font-weight: 600;
	line-height: 1.5;
	letter-spacing: var( --wp--custom--eyebrow-tracking );
	text-transform: uppercase;
}

.cobell-steps__item[ data-rail-reached="false" ] .cobell-steps__eyebrow {
	color: color-mix( in srgb, var( --wp--preset--color--forest ) 65%, transparent );
}

.cobell-section--dark .cobell-steps__eyebrow {
	color: var( --wp--preset--color--flame );
}

/*
 * Supporting receipts under a row's body — a compact hairline-marked list.
 *
 * Live's register is `mt-5 space-y-2 text-[13px] md:text-[14px] leading-snug`.
 * The 1.25rem and 0.5rem are those two literal Tailwind steps, not
 * `--wp--preset--spacing--30`, which resolves to 0.67rem — the same trap the
 * spacing-scale note in CLAUDE.md describes.
 */
.cobell-steps__details {
	margin: 1.25rem 0 0;
	padding: 0;
	list-style: none;
	color: color-mix( in srgb, var( --wp--preset--color--forest ) 75%, transparent );
	font-size: 0.8125rem;
	line-height: 1.375;
}

@media ( min-width: 48rem ) {
	.cobell-steps__details {
		font-size: var( --wp--preset--font-size--small );
	}
}

/*
 * The hairline marker hangs off the row rather than the list, which is what lets
 * it swap sides with the panel below. Live's `pl-4` and `w-2.5` are the indent
 * and the rule; the colour tracks the rail the way the numeral and the closing
 * line do, so an unwalked row's receipts are quiet and light as it is reached.
 */
.cobell-steps__details li {
	position: relative;
	padding-inline-start: 1rem;
}

.cobell-steps__details li + li {
	margin-top: 0.5rem;
}

.cobell-steps__details li::before {
	content: "";
	position: absolute;
	top: 0.65em;
	left: 0;
	width: 0.625rem;
	height: 1px;
	background-color: var( --wp--preset--color--clay );
	transition: background-color 500ms ease;
}

.cobell-steps__item[ data-rail-reached="false" ] .cobell-steps__details li::before {
	background-color: color-mix( in srgb, var( --wp--preset--color--forest ) 30%, transparent );
}

@media ( prefers-reduced-motion: reduce ) {
	.cobell-steps__details li::before {
		transition: none;
	}
}

/*
 * The closing line of each step is clay on live, not forest — a coloured aside
 * rather than dimmer body copy, which is why it read as the wrong colour here.
 * 12px, 1.5 leading, and the reference's tracking-wide.
 *
 * Clay on cream is 3.72:1 where 12px needs 4.5:1. Matching live is the call
 * this theme has already made, so it is recorded here the way need-help.css
 * records its own: forest 75% clears at 5.20:1 and is the one-declaration swap
 * if that trade is ever reversed.
 */
.cobell-steps__note {
	margin: 1.25rem 0 0;
	color: var( --wp--preset--color--clay );
	font-family: var( --wp--preset--font-family--serif );
	font-size: 0.75rem;
	font-style: italic;
	font-variation-settings: "SOFT" 70, "opsz" 48;
	line-height: 1.5;
	letter-spacing: 0.025em;
	transition: color 500ms ease;
}

/*
 * Clay is the *reached* colour, not the only one. The reference switches this
 * line with the rail — `group-data-[active=true]:text-[#b85a32]` against
 * `group-data-[active=false]:text-[#26352a]/60` — so an unwalked step's aside is
 * quiet forest and lights to clay as the rail arrives, the same way the numeral
 * beside it does.
 *
 * The lit colour stays on the base rule and the unlit one is added here, because
 * absence of the attribute is the reached state: with no scripting every note is
 * clay, which is the finished composition rather than a permanently dimmed page.
 *
 * This is also why measuring it against live needs care — live was sampled with
 * these rows unlit and read forest/60, which looks like a colour bug against our
 * lit clay and is really two different states.
 */
.cobell-steps__item[ data-rail-reached="false" ] .cobell-steps__note {
	color: color-mix( in srgb, var( --wp--preset--color--forest ) 60%, transparent );
}

/*
 * `pt-8 md:pt-16` between the rail and the pill, and it is one gap, not two.
 *
 * It used to be `--wp--preset--spacing--60` on the wrapper plus 2rem on the
 * button row — 36 + 24, because the row's own 4rem lost to `.cobell-buttons` in
 * the theme stylesheet on source order, and because two stacked margins are hard
 * to read as one number. The wrapper owns the gap now and the row is zeroed
 * against the theme with a second class.
 */
.cobell-steps__cta {
	display: flex;
	justify-content: center;
	margin-top: 2rem;
}

.cobell-steps .cobell-steps__buttons {
	margin-top: 0;
	justify-content: center;
}

@media ( min-width: 48rem ) {
	.cobell-steps__cta {
		margin-top: 4rem;
	}
}

/*
 * Live pads this CTA a step past the shared pill — 14px × 28px against the
 * base's 12 × 24, so it stands 48px tall rather than 44. It closes a numbered
 * sequence rather than sitting beside body copy, which is the difference.
 *
 * Three classes, not one: a single-class rule ties with .btn in the theme
 * stylesheet and loses on source order — the same cascade trap the section
 * shell has. The :not() also keeps this off the bare text link, whose padding
 * is the absence of a pill.
 */
.cobell-steps .btn:not( .btn--ghost ) {
	padding: 0.875rem 1.75rem;
}

/*
 * Alternating layout. Above the fold width the rail moves to the centre and
 * panels sit either side of it. Rendered with an explicit three-column grid
 * rather than by floating panels, so source order stays the reading order —
 * a screen reader and a keyboard walk the steps 1, 2, 3 regardless of which
 * side each one is painted on.
 *
 * 48rem, which is the reference's `md`. It was 56rem, and in the 128px between
 * the two the layout was a different composition from live's: one wide column of
 * 384px panels beside a left-hand rail where live already has the centred rail
 * and 250px panels either side of it. Live is cramped there and does it anyway.
 */
@media ( min-width: 48rem ) {
	.cobell-steps--alternate .cobell-steps__list::before {
		left: 50%;
		transform: translateX( -50% );
	}

	/* The fill has to carry the centring translate as well as its own scale —
	   a second transform declaration would replace the first, not add to it. */
	.cobell-steps--alternate .cobell-steps__list::after {
		left: 50%;
		transform: translateX( -50% ) scaleY( var( --cobell-rail-progress, 1 ) );
	}

	/*
	 * 2.5rem written out, not `--wp--preset--spacing--50`. That token resolves
	 * to 1.5rem, not the 2.5rem theme.json's `spacingSizes` array reads as, so
	 * the gutter was 24px and the 24px connector below spanned all of it and
	 * butted straight into the copy. The reference's gutter is 2.5rem.
	 */
	.cobell-steps--alternate .cobell-steps__item {
		grid-template-columns: 1fr 2.75rem 1fr;
		gap: 2.5rem;
	}

	.cobell-steps--alternate .cobell-steps__marker {
		position: relative;
		grid-column: 2;
		grid-row: 1;
	}

	/*
	 * Connector. A hairline from the node out to whichever side that step's
	 * panel is on, tying the two together across the gutter — the second cue
	 * the reference gives that a panel belongs to its node once the rail is
	 * centred and the panels alternate.
	 *
	 * Only exists in this layout. Below 56rem every panel sits to the right of
	 * a left-hand rail and is already adjacent to its node, which is why the
	 * reference draws no connector on mobile either.
	 *
	 * 1.5rem of the 2.5rem gutter, at the node's vertical centre, leaving the
	 * remaining 1rem clear of the copy.
	 */
	.cobell-steps--alternate .cobell-steps__marker::before {
		content: "";
		position: absolute;
		top: 1.375rem;
		width: 1.5rem;
		height: 1px;
		background-color: color-mix( in srgb, var( --wp--preset--color--clay ) 60%, transparent );
		transition: opacity 500ms ease;
	}

	.cobell-steps--alternate .cobell-steps__item:nth-child( odd ) .cobell-steps__marker::before {
		right: 100%;
	}

	.cobell-steps--alternate .cobell-steps__item:nth-child( even ) .cobell-steps__marker::before {
		left: 100%;
	}

	.cobell-steps--alternate .cobell-steps__item[ data-rail-reached="false" ] .cobell-steps__marker::before {
		opacity: 0.3;
	}

	/*
	 * 1rem of clearance toward the rail — the reference's `md:pr-4` / `md:pl-4` on
	 * the cell holding the panel.
	 *
	 * No `auto` margin here, deliberately, though the reference's panel carries
	 * `md:ml-auto`. An auto margin on a grid item stops it stretching and sizes it
	 * to its content instead, so a row with a short title and no body collapsed to
	 * the width of the title — 213px against live's 378 on the scholarship pages.
	 * The margin has nothing to do anyway: the track cannot exceed the 25rem the
	 * cap plus the padding comes to, because the list is capped at 57rem.
	 */
	.cobell-steps--alternate .cobell-steps__item:nth-child( odd ) .cobell-steps__panel {
		grid-column: 1;
		grid-row: 1;
		padding-inline-end: 1rem;
		text-align: right;
	}

	.cobell-steps--alternate .cobell-steps__item:nth-child( even ) .cobell-steps__panel {
		grid-column: 3;
		grid-row: 1;
		padding-inline-start: 1rem;
	}

	/* The receipts' markers follow the panel across the rail — the reference's
	   `pr-4` / `right-0` on a right-aligned row. Left on both sides would put
	   them against the rail, where they read as part of it. */
	.cobell-steps--alternate .cobell-steps__item:nth-child( odd ) .cobell-steps__details li {
		padding-inline: 0 1rem;
	}

	.cobell-steps--alternate .cobell-steps__item:nth-child( odd ) .cobell-steps__details li::before {
		right: 0;
		left: auto;
	}
}
