/*
 * The theme's own sections.
 *
 * style.css holds the ground, the rail, and the shared furniture. This file is
 * one block per section, in the order they appear on the front page, so someone
 * changing the hero never has to read the ledger.
 *
 * No colour literal appears here. Everything resolves through the --sd-* tokens
 * that style.css maps onto theme.json presets, which is what keeps rebranding a
 * palette swap.
 */

/* ══════ hero ══════ */

/*
 * The hero fills the viewport and splits it: words at the top, figures on the
 * floor.
 *
 * Centring the whole block was the first arrangement and it wasted the top
 * third while pushing the stat row's labels under the fold. Pinning the figures
 * to the bottom edge does two things: the words start reading immediately, and
 * the row of numbers sitting on the fold is what tells a visitor there is more
 * page below it.
 */
.sd-hero {
	position: relative;
	min-height: 100svh;
	display: flex;
	align-items: stretch;
	overflow: hidden;
	/*
	 * The plugin gives every `.itwt-section` vertical padding, which is right
	 * for a band in the middle of a page and wrong for one that is supposed to
	 * be exactly one screen. With it the hero measured 1022px against a 900px
	 * viewport, so there was no floor for the stat row's auto margin to reach
	 * and the figures ended up wherever the overflow put them. The hero owns
	 * its own spacing.
	 */
	padding-top: 0;
	padding-bottom: 0;
}

/*
 * The field of work behind the headline.
 *
 * Wider and denser than the first draft, which ran three columns across 62% of
 * the screen and made each piece about 380px wide: eight tiles visible at once,
 * which reads as a slideshow rather than as output at volume. The tile count is
 * the argument, so the grid is driven by the section's column arg.
 */
.sd-hero__cols {
	position: absolute;
	top: -14%;
	right: -6%;
	bottom: -14%;
	width: min( 74%, 96rem );
	display: grid;
	grid-template-columns: repeat( var( --sd-hero-cols, 5 ), minmax( 0, 1fr ) );
	gap: 0.5rem;
	transform: rotate( -4deg ) scale( 1.14 );
	transform-origin: 62% 50%;
}

@media ( max-width: 62rem ) {
	.sd-hero__cols {
		width: 128%;
		right: -22%;
		opacity: 0.5;
	}
}

.sd-hero__col {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	will-change: transform;
}

.sd-hero__col > .sd-fr {
	flex: none;
}

/*
 * Each column holds its pieces twice, so translating by exactly half the track
 * lands on an identical frame and the loop has no seam. Two directions and
 * three durations, because three columns moving in step reads as one image
 * sliding rather than as a wall of separate work.
 */
.sd-hero__col--up { animation: sd-drift-up var( --sd-drift, 58s ) linear infinite; }
.sd-hero__col--down { animation: sd-drift-down var( --sd-drift, 68s ) linear infinite; }

@keyframes sd-drift-up {
	from { transform: translateY( 0 ); }
	to { transform: translateY( -50% ); }
}

@keyframes sd-drift-down {
	from { transform: translateY( -50% ); }
	to { transform: translateY( 0 ); }
}

@media ( prefers-reduced-motion: reduce ) {
	.sd-hero__col {
		animation: none !important;
	}
}

/* The scrim is its own element rather than a pseudo-element on the section, so
   the stacking order stays explicit: pieces, scrim, words. */
.sd-hero__scrim {
	position: absolute;
	inset: 0;
	z-index: 2;
	pointer-events: none;
	background:
		linear-gradient( 90deg, var( --sd-ground ) 26%, color-mix( in srgb, var( --sd-ground ) 86%, transparent ) 48%, color-mix( in srgb, var( --sd-ground ) 18%, transparent ) 78%, color-mix( in srgb, var( --sd-ground ) 55%, transparent ) 100% ),
		linear-gradient( 0deg, var( --sd-ground ) 0%, transparent 26% );
}

.sd-hero__inner {
	position: relative;
	z-index: 3;
	width: 100%;
	display: flex;
	flex-direction: column;
	/* Clears the fixed header, and nothing more: the words start high. */
	padding-top: clamp( 7rem, 13vh, 10rem );
	/* The figures sit on the floor, not against it. */
	padding-bottom: clamp( 2.25rem, 5.5vh, 4rem );
}

/*
 * The headline.
 *
 * The measure is set to the longest line the copy actually has, not to a round
 * number. At 11ch, which suited a four-word line, a headline whose longest line
 * is sixteen characters wrapped every one of its authored lines in half and the
 * whole hero, sub-headline and buttons included, fell below the fold.
 *
 * The line breaks are the writer's: one row of the field is one line. The
 * measure only exists to stop a long line running under the media.
 */
.sd-hero__headline {
	font-family: var( --sd-display );
	font-weight: 400;
	font-size: clamp( 2.6rem, 0.6rem + 7.4vw, 8.6rem );
	line-height: 0.9;
	letter-spacing: -0.032em;
	max-width: 17ch;
	text-wrap: balance;
	margin: 0;
}

/*
 * The accent phrase is upright, not italic.
 *
 * Set in the italic it reads as a script dropped into the middle of a sentence,
 * which is a change of voice rather than an emphasis, and on a face with a true
 * calligraphic italic it looks like two headlines spliced together. Colour and a
 * little extra weight emphasise the words while keeping one speaker.
 */
.sd-hero__headline em {
	font-style: normal;
	font-weight: 800;
	color: var( --sd-accent-2 );
}

/* Each line is masked so it can rise into place. The script adds is-lit once
   the document is ready; without JavaScript the lines are simply already up. */
.sd-hero__line {
	display: block;
	overflow: hidden;
}

.sd-hero__line > span {
	display: block;
}

.js .sd-hero__line > span {
	transform: translateY( 103% );
}

.js .sd-hero.is-lit .sd-hero__line > span {
	transform: none;
	transition: transform 1.15s cubic-bezier( 0.16, 1, 0.3, 1 );
}

.js .sd-hero.is-lit .sd-hero__line:nth-child( 2 ) > span { transition-delay: 0.09s; }
.js .sd-hero.is-lit .sd-hero__line:nth-child( 3 ) > span { transition-delay: 0.18s; }
.js .sd-hero.is-lit .sd-hero__line:nth-child( 4 ) > span { transition-delay: 0.27s; }
.js .sd-hero.is-lit .sd-hero__line:nth-child( 5 ) > span { transition-delay: 0.36s; }

@media ( prefers-reduced-motion: reduce ) {
	.js .sd-hero__line > span {
		transform: none !important;
		transition: none !important;
	}
}

/*
 * The sub-headline and the buttons stack under the headline, in the copy
 * column.
 *
 * They were a two-column grid with the buttons in a right-hand cell, which on a
 * wide screen parked them over the middle of the media, half a screen from the
 * words they belong to and directly under the identical button in the header.
 * Two gold buttons that far apart do not read as a primary and a secondary,
 * they read as a duplicate.
 */
.sd-hero__lower {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 1.6rem;
	margin-top: clamp( 1.5rem, 2.8vw, 2.4rem );
	/*
	 * A floor under the words, so the figures cannot ride up against the
	 * buttons on a short viewport. The auto margin on the stat row absorbs
	 * whatever is left after this.
	 */
	margin-bottom: clamp( 2rem, 6vh, 4.5rem );
}

.sd-hero__sub {
	font-size: clamp( 1rem, 0.93rem + 0.42vw, 1.28rem );
	line-height: 1.48;
	color: var( --sd-ink-2 );
	max-width: 44ch;
	margin: 0;
}

.sd-hero__acts {
	display: flex;
	flex-wrap: wrap;
	gap: 0.7rem;
}

.sd-hero__stats {
	display: flex;
	flex-wrap: wrap;
	gap: clamp( 1.5rem, 5vw, 4.5rem );
	/* auto is what puts them on the floor of the viewport rather than a fixed
	   distance below the buttons. */
	margin: auto 0 0;
	padding-top: 1.3rem;
	border-top: 1px solid var( --sd-line-2 );
}

.sd-hero__stat-value {
	font-family: var( --sd-display );
	font-size: clamp( 1.5rem, 1rem + 1.9vw, 2.7rem );
	line-height: 1;
	font-variant-numeric: tabular-nums;
}

.sd-hero__stats dd {
	margin: 0.4rem 0 0;
}

/* ══════ statement marquee ══════ */

.sd-marquee {
	padding: clamp( 2.5rem, 6vw, 5rem ) 0;
	overflow: hidden;
	border-top: 1px solid var( --sd-line );
	border-bottom: 1px solid var( --sd-line );
}

.sd-marquee__track {
	display: flex;
	width: max-content;
	animation: sd-slide 40s linear infinite;
}

.sd-marquee__item {
	font-family: var( --sd-display );
	font-size: clamp( 3rem, 1rem + 8vw, 9rem );
	line-height: 1;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	white-space: nowrap;
	padding-right: 0.5em;
	color: transparent;
	-webkit-text-stroke: 1px var( --sd-accent );
}

.sd-marquee__item em {
	font-style: normal;
	color: var( --sd-accent-2 );
	-webkit-text-stroke: 0;
}

@keyframes sd-slide {
	from { transform: translateX( 0 ); }
	to { transform: translateX( -50% ); }
}

@media ( prefers-reduced-motion: reduce ) {
	.sd-marquee__track {
		animation: none;
	}
}

/* ══════ asset sheet ══════ */

.sd-sheet__intro {
	margin-top: 1.5rem;
}

.sd-sheet__body {
	margin-top: clamp( 2.5rem, 5vw, 4rem );
}

.sd-sheet__doc {
	display: grid;
	grid-template-columns: minmax( 0, 1fr ) minmax( 0, 19rem );
	gap: clamp( 1.75rem, 4vw, 3.5rem );
	border-top: 1px solid var( --sd-accent );
	padding: clamp( 1.5rem, 3vw, 2.75rem ) 0;
	background: linear-gradient( 180deg, color-mix( in srgb, var( --sd-accent ) 6%, transparent ), transparent 40% );
}

@media ( max-width: 58rem ) {
	.sd-sheet__doc {
		grid-template-columns: 1fr;
	}
}

.sd-sheet__top {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 0.5rem 1.5rem;
}

.sd-sheet__name {
	font-family: var( --sd-display );
	font-size: clamp( 1.6rem, 1rem + 2vw, 2.9rem );
	letter-spacing: 0.22em;
	text-transform: uppercase;
}

.sd-sheet__rows {
	display: grid;
	grid-template-columns: 7rem minmax( 0, 1fr );
	gap: 0.75rem 1.75rem;
	margin: 1.75rem 0 0;
	font-size: 0.94rem;
}

@media ( max-width: 40rem ) {
	.sd-sheet__rows {
		grid-template-columns: 1fr;
		gap: 0.1rem;
	}

	.sd-sheet__rows dd {
		margin-bottom: 0.95rem;
	}
}

.sd-sheet__rows dt {
	font-family: var( --sd-mono );
	font-size: 0.62rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var( --sd-faint );
	padding-top: 0.3rem;
}

.sd-sheet__rows dd {
	margin: 0;
	color: var( --sd-ink-2 );
	max-width: 58ch;
}

.sd-sheet__sw {
	display: inline-block;
	width: 2rem;
	height: 2rem;
	vertical-align: middle;
	margin-right: 0.3rem;
}

.sd-sheet__ref-cap {
	display: block;
	margin-top: 0.7rem;
}

.sd-sheet__fan {
	display: block;
	width: 100%;
	height: clamp( 3rem, 6vw, 5rem );
}

.sd-sheet__fan path {
	fill: none;
	stroke: var( --sd-accent );
	stroke-opacity: 0.6;
	stroke-width: 1;
}

.sd-sheet__outs {
	display: grid;
	grid-template-columns: repeat( var( --sd-outs, 6 ), minmax( 0, 1fr ) );
	gap: 0.7rem;
}

@media ( max-width: 60rem ) {
	.sd-sheet__outs {
		grid-template-columns: repeat( 3, minmax( 0, 1fr ) );
	}
}

.sd-sheet__channels {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: 0.5rem 1.5rem;
	margin-top: 1.1rem;
}

/* ══════ media wall ══════ */

/*
 * The plugin's stylesheet makes every `.itwt-section` a flex container. For
 * most sections that is harmless, but here it would size the pinned column to
 * its widest child, and the widest child is a track that is deliberately many
 * screens wide. The section would then be wider than the viewport and the page
 * would scroll sideways. Block layout, and the track stays clipped.
 */
.sd-wall {
	display: block;
	position: relative;
	height: calc( ( var( --sd-wall-screens, 3 ) + 1 ) * 100vh );
}

.sd-wall__stick {
	position: sticky;
	top: 0;
	height: 100svh;
	display: flex;
	flex-direction: column;
	justify-content: center;
	overflow: hidden;
}

/*
 * The head and foot are flex items of the pinned column, and `.sd-inner`
 * carries `margin: 0 auto` to constrain a block. On a flex item that stops
 * being a constraint and becomes centring: the item shrinks to its content and
 * the auto margins push it to the middle. Stretching them back is the fix, and
 * it has to be explicit because the default `align-items: stretch` is what the
 * auto margins were overriding.
 */
.sd-wall__head,
.sd-wall__foot {
	width: 100%;
	align-self: stretch;
}

.sd-wall__head {
	padding-bottom: 1.6rem;
}

.sd-wall__viewport {
	overflow: hidden;
}

.sd-wall__track {
	display: flex;
	gap: 0.7rem;
	padding-left: var( --sd-gut );
	will-change: transform;
}

@media ( min-width: 62rem ) {
	.sd-wall__track {
		padding-left: calc( var( --sd-gut ) + var( --sd-rail ) );
	}
}

.sd-wall__track > .sd-fr {
	width: clamp( 9rem, 15vw, 15.5rem );
	height: clamp( 14rem, 27vw, 25rem );
	flex: none;
}

.sd-wall__foot {
	padding-top: 1.6rem;
	display: flex;
	justify-content: space-between;
	gap: 1rem;
	flex-wrap: wrap;
}

/*
 * Without JavaScript the pin cannot be driven, so the wall stops pretending to
 * be one: it becomes an ordinary scrollable strip. Same markup, no dead end.
 */
html:not( .js ) .sd-wall {
	height: auto;
}

html:not( .js ) .sd-wall__stick {
	position: static;
	height: auto;
	padding: 4rem 0;
}

html:not( .js ) .sd-wall__viewport {
	overflow-x: auto;
	padding-bottom: 1rem;
}

@media ( prefers-reduced-motion: reduce ) {
	.sd-wall {
		height: auto;
	}

	.sd-wall__stick {
		position: static;
		height: auto;
		padding: 4rem 0;
	}

	.sd-wall__viewport {
		overflow-x: auto;
		padding-bottom: 1rem;
	}

	.sd-wall__track {
		transform: none !important;
	}
}

/* ══════ argument blocks ══════ */

.sd-arg__grid {
	display: grid;
	gap: clamp( 2rem, 5vw, 5rem );
	align-items: center;
}

.sd-arg--right .sd-arg__grid {
	grid-template-columns: minmax( 0, 0.92fr ) minmax( 0, 1.08fr );
}

.sd-arg--left .sd-arg__grid {
	grid-template-columns: minmax( 0, 1.08fr ) minmax( 0, 0.92fr );
}

.sd-arg--left .sd-arg__copy {
	order: 2;
}

@media ( max-width: 56rem ) {
	.sd-arg--right .sd-arg__grid,
	.sd-arg--left .sd-arg__grid {
		grid-template-columns: 1fr;
	}

	.sd-arg--left .sd-arg__copy {
		order: 0;
	}
}

.sd-arg__copy {
	display: flex;
	flex-direction: column;
	gap: 1.5rem;
}

.sd-arg__fig {
	display: grid;
	gap: 0.7rem;
}

.sd-figcap {
	font-family: var( --sd-mono );
	font-size: 0.6rem;
	letter-spacing: 0.12em;
	color: var( --sd-faint );
	margin: 0;
}

/* ══════ frame compare ══════ */

.sd-cmp {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 0.7rem;
}

.sd-cmp__lay {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: flex-end;
	padding: 1.2rem 1.1rem;
}

/*
 * The damaged treatment. Every property here is imitating a specific failure a
 * generative model makes with letterforms: the skew and vertical scale are the
 * baseline wandering, the blur is the edge mush, the double text-shadow is the
 * ghosting, and the per-word transforms are the kerning giving up. It is a
 * drawing of the problem, so it is deliberately not subtle.
 */
.sd-cmp__bad {
	font-family: var( --sd-overlay );
	font-size: clamp( 0.95rem, 0.6rem + 1.3vw, 1.8rem );
	line-height: 1.02;
	text-transform: uppercase;
	color: #fff;
	letter-spacing: 0.05em;
	word-spacing: 0.24em;
	transform: skewX( -3deg ) scaleY( 1.05 );
	filter: blur( 0.45px ) contrast( 0.88 );
	text-shadow:
		0.7px 0 0 rgba( 255, 255, 255, 0.45 ),
		-0.6px 0.5px 0 rgba( 255, 255, 255, 0.3 ),
		0 2px 10px rgba( 0, 0, 0, 0.85 );
}

.sd-cmp__bad i {
	font-style: normal;
	display: inline-block;
}

.sd-cmp__bad i:nth-child( 2 ) {
	transform: translateY( 2px ) rotate( 1.3deg ) scaleX( 1.09 );
	letter-spacing: -0.03em;
}

.sd-cmp__bad i:nth-child( 3 ) {
	transform: translateY( -1.5px ) rotate( -1deg ) scaleX( 0.9 );
}

.sd-cmp__bad i:nth-child( 4 ) {
	transform: translateY( 1px ) scaleX( 1.14 );
	filter: blur( 0.85px );
}

.sd-cmp__good {
	font-family: var( --sd-body );
	font-weight: 700;
	font-size: clamp( 0.95rem, 0.6rem + 1.3vw, 1.8rem );
	line-height: 1.04;
	letter-spacing: -0.02em;
	color: #fff;
	text-shadow: 0 2px 12px rgba( 0, 0, 0, 0.75 );
}

.sd-cmp__rule {
	display: block;
	width: 2.6rem;
	height: 3px;
	margin-bottom: 0.7rem;
}

.sd-cmp__labels {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 0.7rem;
}

/* ══════ lineage diagram ══════ */

.sd-dag {
	width: 100%;
	height: auto;
	display: block;
}

.sd-dag text {
	font-family: var( --sd-mono );
	font-size: 9px;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	fill: var( --sd-faint );
}

.sd-dag text.is-on {
	fill: var( --sd-ink );
}

.sd-dag rect {
	fill: var( --sd-raise );
	stroke: var( --sd-line-2 );
}

.sd-dag rect.is-on {
	stroke: var( --sd-accent );
}

.sd-dag path {
	fill: none;
	stroke: var( --sd-line-2 );
}

.sd-dag path.is-on {
	stroke: var( --sd-accent );
	stroke-opacity: 0.85;
}

/* ══════ gate ══════ */

.sd-gate__row {
	display: grid;
	grid-template-columns: repeat( 3, minmax( 0, 1fr ) );
	gap: 0.7rem;
}

/* ══════ client ledger ══════ */

.sd-clients__list {
	margin-top: clamp( 2.5rem, 5vw, 3.5rem );
}

.sd-clients__row {
	display: grid;
	grid-template-columns: minmax( 0, 16rem ) minmax( 0, 1fr ) minmax( 0, 8rem );
	gap: 0.5rem 3rem;
	align-items: baseline;
	padding: 1.8rem 0;
	border-top: 1px solid var( --sd-line );
}

.sd-clients__row:first-child {
	border-top-color: var( --sd-line-2 );
}

@media ( max-width: 52rem ) {
	.sd-clients__row {
		grid-template-columns: 1fr;
		gap: 0.35rem;
	}
}

.sd-clients__name {
	font-family: var( --sd-display );
	font-size: 1.5rem;
}

/*
 * A client name links out when there is somewhere to go.
 *
 * Underlined on the offset rather than boxed or coloured, so a row with a link
 * and a row without still scan as the same kind of thing. The accent arrives on
 * hover, which is the only signal needed once the underline says it is a link.
 */
.sd-clients__name a {
	color: inherit;
	text-decoration: underline;
	text-decoration-color: var( --sd-line-2 );
	text-decoration-thickness: 1px;
	text-underline-offset: 0.22em;
	transition: color 0.25s ease, text-decoration-color 0.25s ease;
}

.sd-clients__name a:hover,
.sd-clients__name a:focus-visible {
	color: var( --sd-accent-2 );
	text-decoration-color: var( --sd-accent-2 );
}

.sd-clients__what {
	color: var( --sd-ink-2 );
	max-width: 52ch;
}

.sd-clients__result {
	font-family: var( --sd-mono );
	font-size: 0.68rem;
	letter-spacing: 0.12em;
	color: var( --sd-faint );
	font-variant-numeric: tabular-nums;
}

/* ══════ production ledger ══════ */

.sd-prod__head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 0.75rem 2rem;
}

.sd-prod__heading {
	max-width: 18ch;
}

.sd-prod__count {
	font-family: var( --sd-mono );
	font-size: 0.8rem;
	letter-spacing: 0.08em;
	color: var( --sd-accent-2 );
	font-variant-numeric: tabular-nums;
}

/* The table scrolls inside this, never the page. */
.sd-prod__scroll {
	overflow-x: auto;
	margin-top: 2.25rem;
}

.sd-prod__table {
	width: 100%;
	border-collapse: collapse;
	font-size: 0.9rem;
	font-variant-numeric: tabular-nums;
	min-width: 40rem;
}

.sd-prod__table th {
	text-align: left;
	font-family: var( --sd-mono );
	font-weight: 400;
	font-size: 0.6rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var( --sd-faint );
	padding: 0 1.5rem 0.8rem 0;
	border-bottom: 1px solid var( --sd-line-2 );
	white-space: nowrap;
}

.sd-prod__table td {
	padding: 0.72rem 1.5rem 0.72rem 0;
	border-bottom: 1px solid var( --sd-line );
	color: var( --sd-ink-2 );
	white-space: nowrap;
}

.sd-prod__table tr.is-won td {
	color: var( --sd-ink );
}

.sd-prod__table tr.is-won td.sd-prod__status {
	color: var( --sd-accent-2 );
}

.sd-prod__table tr.is-won td:first-child {
	box-shadow: inset 2px 0 0 var( --sd-accent );
	padding-left: 0.8rem;
}

.sd-prod__note {
	font-size: 0.88rem;
	color: var( --sd-faint );
	margin-top: 1.4rem;
}

/* ══════ offer tiers ══════ */

/*
 * Two columns of one document, divided by a hairline. Not cards: no border box,
 * no radius, no shadow, no tier lifted above the other on a plinth. The reader
 * is choosing between two ways of working, and a card grid would make that look
 * like a price comparison between two products.
 *
 * The rewrite that got it here: the first version set the name, then the price,
 * then the summary as three stacked blocks, which left a column of short lines
 * against a lot of empty right-hand space and read as unfinished. Putting the
 * name and the price on one baseline with a rule under them turns the top of
 * each column into a heading that uses its full width, which is what a menu or
 * a spec sheet does.
 */
.sd-offer__grid {
	display: grid;
	grid-template-columns: repeat( var( --sd-tiers, 2 ), minmax( 0, 1fr ) );
	margin-top: clamp( 2.5rem, 5vw, 3.5rem );
	gap: 0;
}

@media ( max-width: 52rem ) {
	.sd-offer__grid {
		grid-template-columns: 1fr;
	}
}

/* Columns are equal height and the buttons line up, because the CTA is pushed
   to the floor rather than following the last list row. */
.sd-offer__tier {
	display: flex;
	flex-direction: column;
	padding: 0 clamp( 1.75rem, 3.5vw, 3.25rem ) 0 0;
	border-right: 1px solid var( --sd-line );
}

.sd-offer__tier:last-child {
	border-right: 0;
	padding-right: 0;
	padding-left: clamp( 1.75rem, 3.5vw, 3.25rem );
}

@media ( max-width: 52rem ) {
	.sd-offer__tier {
		border-right: 0;
		padding: 0 0 2.5rem;
	}

	.sd-offer__tier + .sd-offer__tier {
		border-top: 1px solid var( --sd-line );
		padding: 2.5rem 0 0;
	}
}

/*
 * The heading row. The rule above it is the accent on the tier that carries the
 * main offer and a plain line on the other, which is the whole emphasis: no
 * badge, no "most popular", no lift.
 */
.sd-offer__head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 0.4rem 1.5rem;
	padding: 1.4rem 0 1.2rem;
	border-top: 1px solid var( --sd-line-2 );
}

.sd-offer__tier:last-child .sd-offer__head {
	border-top: 2px solid var( --sd-accent );
}

.sd-offer__name {
	font-family: var( --sd-display );
	font-weight: 400;
	font-size: clamp( 1.5rem, 1rem + 1.1vw, 2rem );
	line-height: 1;
	margin: 0;
}

.sd-offer__price {
	font-family: var( --sd-mono );
	font-size: 0.7rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var( --sd-accent-2 );
	text-align: right;
}

.sd-offer__summary {
	margin: 0 0 1.6rem;
	color: var( --sd-ink-2 );
	font-size: 1rem;
	line-height: 1.5;
	/* Wide enough that a two-line summary does not orphan its last word. */
	max-width: 46ch;
}

/*
 * A list of things, set as a list. No ticks, per standards/design.md.
 *
 * Rows are hairline-separated and tight, so the column reads as one object
 * rather than as five floating sentences. The last rule is dropped because a
 * line under the final item and then a gap before the button reads as a broken
 * table.
 */
.sd-offer__list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.sd-offer__list li {
	padding: 0.72rem 0;
	border-bottom: 1px solid var( --sd-line );
	font-size: 0.95rem;
	line-height: 1.45;
	color: var( --sd-ink-2 );
}

.sd-offer__list li:first-child {
	border-top: 1px solid var( --sd-line );
}

.sd-offer__list li:last-child {
	border-bottom: 0;
}

/*
 * `auto` puts the button on the floor of its column so both tiers' buttons land
 * on one line whatever the lists do. The minimum gap lives on the list's bottom
 * margin rather than on the button, because a margin here would have fought the
 * auto and a padding would have grown the button itself.
 */
.sd-offer__list {
	margin-bottom: 2rem;
}

.sd-offer__cta {
	align-self: flex-start;
	margin-top: auto;
}

/* ══════ booking ══════ */

.sd-book {
	position: relative;
	overflow: hidden;
	padding-top: clamp( 4.5rem, 11vw, 11rem );
	padding-bottom: clamp( 4.5rem, 11vw, 11rem );
	border-top: 1px solid var( --sd-line );
}

.sd-book__bg {
	position: absolute;
	inset: 0;
}

.sd-book__bg img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0.36;
}

.sd-book__bg::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient( 90deg, var( --sd-ground ) 12%, color-mix( in srgb, var( --sd-ground ) 76%, transparent ) 60%, color-mix( in srgb, var( --sd-ground ) 42%, transparent ) );
}

.sd-book__grid {
	position: relative;
	display: grid;
	grid-template-columns: minmax( 0, 1fr ) minmax( 0, 25rem );
	gap: clamp( 2rem, 5vw, 5rem );
	align-items: start;
}

@media ( max-width: 56rem ) {
	.sd-book__grid {
		grid-template-columns: 1fr;
	}
}

.sd-book__copy {
	display: flex;
	flex-direction: column;
	gap: 1.5rem;
}

.sd-book__heading {
	font-family: var( --sd-display );
	font-weight: 400;
	font-size: clamp( 2.3rem, 1rem + 5vw, 6rem );
	line-height: 0.92;
	letter-spacing: -0.028em;
	max-width: 11ch;
	margin: 0;
}

.sd-book__heading em {
	font-style: normal;
	font-weight: 800;
	color: var( --sd-accent-2 );
}

.sd-book__body {
	font-size: clamp( 1rem, 0.93rem + 0.42vw, 1.28rem );
	line-height: 1.48;
	color: var( --sd-ink-2 );
	max-width: 44ch;
	margin: 0;
}

.sd-book__note {
	font-size: 0.88rem;
	color: var( --sd-faint );
	margin: 0;
}

/*
 * The form mount. Empty until something answers the slot, and collapsed while
 * it is, so a site whose form is not wired yet has no gap in it. That is why
 * the renderer trims the buffered output: one whitespace character and :empty
 * stops matching.
 */
.sd-book__mount:empty {
	display: none;
}

.sd-book__mount {
	border: 1px solid var( --sd-line-2 );
	background: color-mix( in srgb, var( --sd-raise ) 92%, transparent );
	backdrop-filter: blur( 8px );
	padding: clamp( 1.5rem, 3vw, 2.25rem );
}

/* ── the scheduler ─────────────────────────────────────────── */

/*
 * A calendar needs room, so the column it sits in stops being a narrow form
 * slot and becomes half the section.
 */
.sd-book--scheduled .sd-book__grid {
	grid-template-columns: minmax( 0, 0.85fr ) minmax( 0, 1.15fr );
}

@media ( max-width: 64rem ) {
	.sd-book--scheduled .sd-book__grid {
		grid-template-columns: 1fr;
	}
}

/*
 * No mat, no border, nothing behind it.
 *
 * A scheduling widget is somebody else's page and it brings its own card:
 * background, corner radius, and a margin around the lot. Anything drawn behind
 * it therefore shows only in that margin, as a band along the top and bottom
 * that lines up with nothing. Both earlier attempts made it worse, a white mat
 * first and then a surface with a hairline, because the problem was never the
 * colour of the band.
 *
 * So the container gets out of the way and the provider's own card is the
 * object on the page. What shows around it is the page ground, which is what
 * would have been there anyway.
 */
.sd-book__scheduler {
	background: transparent;
	border: 0;
	overflow: hidden;
}

.sd-book__frame {
	display: block;
	width: 100%;
	border: 0;
	/* The inline height is a starting value the provider's resizer overwrites.
	   A min-height stops the frame collapsing to nothing if that never runs. */
	min-height: 32rem;
}

/* ══════ delivery ══════ */

.sd-deliver__grid {
	display: grid;
	grid-template-columns: minmax( 0, 0.85fr ) minmax( 0, 1.15fr );
	gap: clamp( 2rem, 5vw, 5rem );
	align-items: start;
}

@media ( max-width: 56rem ) {
	.sd-deliver__grid {
		grid-template-columns: 1fr;
	}
}

.sd-deliver__copy {
	display: flex;
	flex-direction: column;
	gap: 1.5rem;
}

.sd-deliver__list {
	margin: 0;
	border-top: 1px solid var( --sd-line-2 );
}

/*
 * A delivery note, so the quantity leads and the description follows it. The
 * number column is fixed rather than sized to content, because a ragged left
 * edge on a list of figures reads as an accident.
 */
.sd-deliver__row {
	display: grid;
	grid-template-columns: minmax( 0, 8rem ) minmax( 0, 1fr );
	gap: 0.4rem 2rem;
	align-items: baseline;
	padding: 1.5rem 0;
	border-bottom: 1px solid var( --sd-line );
}

@media ( max-width: 40rem ) {
	.sd-deliver__row {
		grid-template-columns: 1fr;
		gap: 0.3rem;
	}
}

.sd-deliver__count {
	font-family: var( --sd-display );
	font-size: clamp( 1.7rem, 1rem + 1.9vw, 2.7rem );
	line-height: 1;
	font-variant-numeric: tabular-nums;
	color: var( --sd-ink );
}

.sd-deliver__what {
	margin: 0;
	display: flex;
	flex-direction: column;
	gap: 0.3rem;
}

.sd-deliver__thing {
	font-size: 1.05rem;
	color: var( --sd-ink );
}

.sd-deliver__detail {
	font-size: 0.94rem;
	color: var( --sd-ink-2 );
	max-width: 52ch;
}

.sd-deliver__note {
	margin: clamp( 1.75rem, 3vw, 2.5rem ) 0 0;
	font-size: 0.88rem;
	color: var( --sd-faint );
}
