/*
 * Paid Ads — the visuals particular to this page.
 *
 * The shell (hero, beat scaffolding, scope, objections, the `--lit` primitive)
 * lives in service-story.css, which loads first. Everything here is specific to
 * this service: the leak bar, the sideways line-up, the intent tiers, the weekly
 * ring and the report card.
 */
/* ============================================================
   01 — The leak
   ============================================================ */

.gd-leak { display: grid; gap: clamp(1.5rem, 2.6vw, 2.25rem); }

.gd-leak__bar {
	display: flex;
	overflow: hidden;
	width: 100%;
	height: clamp(44px, 5.5vw, 68px);
	border-radius: var(--gd-radius-sm);
	background: var(--gd-glass);
	box-shadow: inset 0 0 0 1px var(--gd-glass-line);
}

/*
 * Width is the item's share of the bar, scaled by how lit it is — so the bar
 * fills left to right in four moves rather than growing as one block.
 */
.gd-leak__seg {
	width: calc(1% * var(--share, 0) * var(--lit));
	transition: none;
}

/*
 * Each waste band a step paler than the one before, so three abutting panels
 * read as three quantities rather than one long block. The divider alone was
 * not enough to separate them.
 */
.gd-leak__seg--waste {
	background: linear-gradient(180deg, rgba(124, 92, 255, 0.42), rgba(124, 92, 255, 0.24));
	box-shadow: inset -1px 0 0 var(--gd-void);
}

.gd-leak__seg--waste:nth-of-type(2) {
	background: linear-gradient(180deg, rgba(124, 92, 255, 0.29), rgba(124, 92, 255, 0.16));
}

.gd-leak__seg--waste:nth-of-type(3) {
	background: linear-gradient(180deg, rgba(124, 92, 255, 0.17), rgba(124, 92, 255, 0.09));
}

.gd-leak__seg--intent {
	background: linear-gradient(90deg, var(--gd-violet), var(--gd-cyan));
	box-shadow: 0 0 26px rgba(34, 211, 238, 0.45);
}

.gd-leak__key {
	display: grid;
	margin: 0;
	padding: 0;
	gap: 0.85rem clamp(1.25rem, 2.4vw, 2.25rem);
	grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
	list-style: none;
}

.gd-leak__item {
	display: grid;
	padding-top: 0.85rem;
	border-top: 1px solid var(--gd-glass-line);
	gap: 0.2rem;
	opacity: calc(0.22 + var(--lit) * 0.78);
	transform: translate3d(0, calc((1 - var(--lit)) * 10px), 0);
}

.gd-leak__pct {
	color: var(--gd-text);
	font-size: clamp(1.35rem, 2.2vw, 1.9rem);
	font-weight: 800;
	font-variant-numeric: tabular-nums;
	letter-spacing: -0.02em;
}

.gd-leak__item--intent .gd-leak__pct {
	background: linear-gradient(90deg, var(--gd-violet), var(--gd-cyan));
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
}

.gd-leak__label { color: var(--gd-text); font-size: 0.95rem; font-weight: 650; line-height: 1.35; }
.gd-leak__note { color: var(--gd-text-3); font-size: 0.83rem; line-height: 1.5; }

/* ============================================================
   02 — The audit, as a line-up moving sideways
   ============================================================ */

/*
 * The one beat that does not share the page's shape.
 *
 * Its neighbours are all copy on the left and a figure on the right, and this
 * is the section that carries the most weight — so it takes the whole stage and
 * moves on the other axis. The checks travel left past a fixed reading position
 * as the page scrolls down; the card sitting in that position is the one being
 * read, and the rest are waiting or done.
 */
.gd-lineup {
	display: grid;
	width: 100%;
	gap: clamp(1.5rem, 3.5vw, 2.75rem);
}

/*
 * The head is a `.gd-container`, which centres itself with auto margins — so a
 * narrower max-width here centred the copy instead of constraining it. The
 * limit belongs on the text, not on the container carrying it.
 */
.gd-lineup__head .gd-beat__title { max-width: 18ch; }
.gd-lineup__head .gd-beat__text { max-width: 54ch; }

/*
 * Clips the track, so the overhang never reaches the document. The mask softens
 * both edges — a card cut off mid-word at a hard border reads as a bug rather
 * than as something on its way past.
 */
.gd-lineup__viewport {
	position: relative;
	overflow: hidden;
	width: 100%;
	padding-block: clamp(0.5rem, 1.5vw, 1rem);
	-webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 88%, transparent);
	mask-image: linear-gradient(90deg, transparent, #000 5%, #000 88%, transparent);
	/* Card and gap are shared with the track's travel sum below. */
	--card: clamp(232px, 25vw, 330px);
	--gap: clamp(0.75rem, 1.6vw, 1.25rem);
	/*
	 * The reading slot sits exactly on the container's left edge, so the card
	 * being read lines up with the heading above it. A plain viewport fraction
	 * does not: at most widths it landed short of the column and the active
	 * card hung out into the gutter.
	 *
	 * Same expression the homepage carousels use — measured from the element's
	 * own width rather than 100vw, which counts the scrollbar and would put it
	 * a few pixels out.
	 */
	--read: max(var(--gd-gutter), calc((100% - var(--gd-container)) / 2 + var(--gd-gutter)));
}

/*
 * The reading position — a soft pool of light the cards pass through, set a
 * little wider than a card so it reads as a spotlight behind one rather than a
 * second border drawn around it.
 */
.gd-lineup__focus {
	position: absolute;
	top: 0;
	bottom: 0;
	left: calc(var(--read) - 14px);
	z-index: 0;
	width: calc(var(--card) + 28px);
	border-radius: calc(var(--gd-radius-lg) + 8px);
	background: radial-gradient(60% 70% at 50% 45%, color-mix(in srgb, var(--gd-violet) 13%, transparent), transparent 70%);
	pointer-events: none;
}

/*
 * Travel is the whole track minus the one card that stays in the reading
 * position, so the last card lands there exactly at the end of the beat.
 */
.gd-lineup__track {
	position: relative;
	z-index: 1;
	display: flex;
	margin: 0;
	padding: 0 0 0 var(--read);
	gap: var(--gap);
	list-style: none;
	transform: translate3d(
		calc(-1 * var(--p, 0) * (var(--count, 1) - 1) * (var(--card) + var(--gap))), 0, 0);
}

.gd-lineup__card {
	position: relative;
	display: grid;
	width: var(--card);
	flex: none;
	align-content: start;
	padding: clamp(1.1rem, 2.2vw, 1.6rem);
	border: 1px solid var(--gd-glass-line);
	border-radius: var(--gd-radius-lg);
	background: var(--gd-glass);
	gap: 0.5rem;
	/*
	 * A triangular window centred on this card's turn in the reading position,
	 * built from two clamps rather than abs() so it works on older Safari.
	 */
	--focus: calc(
		clamp(0, (var(--p, 0) - var(--at, 0) + 0.5 / (var(--count, 1) - 1)) * (var(--count, 1) - 1) * 2, 1) *
		clamp(0, (var(--at, 0) - var(--p, 0) + 0.5 / (var(--count, 1) - 1)) * (var(--count, 1) - 1) * 2, 1)
	);
	opacity: calc(0.28 + var(--focus) * 0.72);
	transform: scale(calc(0.94 + var(--focus) * 0.06));
}

.gd-lineup__card--bad { border-color: color-mix(in srgb, var(--gd-brand, #cc3066) calc(var(--focus) * 55%), var(--gd-glass-line)); }
.gd-lineup__card--warn { border-color: color-mix(in srgb, var(--gd-violet) calc(var(--focus) * 55%), var(--gd-glass-line)); }
.gd-lineup__card--ok { border-color: color-mix(in srgb, var(--gd-cyan) calc(var(--focus) * 55%), var(--gd-glass-line)); }

.gd-lineup__index {
	color: var(--gd-text-3);
	font-size: 0.8rem;
	font-variant-numeric: tabular-nums;
	font-weight: 800;
	letter-spacing: 0.04em;
}

.gd-lineup__index i { font-style: normal; opacity: 0.5; }

.gd-lineup__card--bad .gd-lineup__index { color: color-mix(in srgb, var(--gd-brand, #cc3066) calc(var(--focus) * 100%), var(--gd-text-3)); }
.gd-lineup__card--warn .gd-lineup__index { color: color-mix(in srgb, var(--gd-violet) calc(var(--focus) * 100%), var(--gd-text-3)); }
.gd-lineup__card--ok .gd-lineup__index { color: color-mix(in srgb, var(--gd-cyan) calc(var(--focus) * 100%), var(--gd-text-3)); }

.gd-lineup__name {
	color: var(--gd-text);
	font-size: clamp(1.05rem, 1.7vw, 1.3rem);
	font-weight: 750;
	line-height: 1.2;
	letter-spacing: -0.02em;
}

/* The finding is the payoff, so it belongs to the card being read. */
.gd-lineup__finding {
	color: var(--gd-text-2);
	font-size: 0.86rem;
	line-height: 1.5;
	opacity: calc(0.25 + var(--focus) * 0.75);
}

.gd-lineup__tag {
	justify-self: start;
	margin-top: 0.25rem;
	padding: 0.24rem 0.6rem;
	border: 1px solid var(--gd-glass-line);
	border-radius: 999px;
	color: var(--gd-text-3);
	font-size: 0.66rem;
	font-weight: 800;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	white-space: nowrap;
}

.gd-lineup__card--bad .gd-lineup__tag {
	border-color: color-mix(in srgb, var(--gd-brand, #cc3066) 45%, transparent);
	color: var(--gd-brand, #cc3066);
}

.gd-lineup__card--warn .gd-lineup__tag {
	border-color: color-mix(in srgb, var(--gd-violet) 45%, transparent);
	color: var(--gd-violet);
}

/*
 * Snapping — one card at a time, held still while it is read.
 *
 * Driving the track straight from `--p` meant the strip was always mid-slide:
 * to read any particular card you had to stop scrolling on exactly the right
 * pixel, and most of the time two cards were half-way past the reading
 * position. Rounding the progress down to a whole card fixes the strip in
 * place between steps, and a transition plays the move over a fixed 0.5s — so
 * scrolling advances the queue rather than dragging it.
 *
 * The bar along the bottom of the active card fills over the dwell, so the
 * hold reads as progress toward the next card rather than as nothing
 * happening. When it is full, the next card comes in.
 *
 * Guarded on round(): where it is unsupported the base rules above still apply
 * and the strip keeps its original continuous slide, which is workable — just
 * not as easy to read.
 */
@supports (width: round(down, 1px, 1px)) {
	/*
	 * Each card owns an equal share of the beat — hence `* count`, not
	 * `* (count - 1)`. Dividing by the gaps instead gave the last card only the
	 * single instant at p = 1, so it flashed past unread. The min() catches
	 * that same endpoint, where the floor would otherwise land one past the end.
	 */
	.gd-lineup {
		--step: min(round(down, var(--p, 0) * var(--count, 1), 1), var(--count, 1) - 1);
	}

	.gd-lineup__track {
		transform: translate3d(calc(-1 * var(--step) * (var(--card) + var(--gap))), 0, 0);
		transition: transform 0.5s var(--gd-ease);
	}

	/*
	 * One when this card is the snapped step, zero otherwise — the same shape
	 * of window as before, but measured against the rounded value, so every
	 * rule downstream that reads `--focus` keeps working unchanged.
	 */
	.gd-lineup__card {
		--focus: calc(
			clamp(0, (var(--step) - var(--i, 0) + 0.5) * 2, 1) *
			clamp(0, (var(--i, 0) - var(--step) + 0.5) * 2, 1)
		);
		transition:
			opacity 0.42s var(--gd-ease),
			transform 0.42s var(--gd-ease),
			border-color 0.42s var(--gd-ease);
	}

}

.gd-lineup__foot {
	display: flex;
	align-items: center;
	gap: clamp(1rem, 2.5vw, 2rem);
}

/*
 * One indicator for the whole beat.
 *
 * A stop for each check, spaced by the flexbox rather than by arithmetic, and
 * a head that travels between them. Reaching a stop is what brings that card
 * in, so the rail says both where you are and what happens next — which is why
 * there is no second progress bar on the card itself any more.
 */
.gd-lineup__rail {
	position: relative;
	display: flex;
	height: 10px;
	flex: 1;
	align-items: center;
	justify-content: space-between;
}

/*
 * Inset by half a stop at each end so the line runs between the centres of the
 * first and last stop rather than the outer edges of their boxes — otherwise
 * the head sits a few pixels wide of every stop it is supposed to land on.
 */
.gd-lineup__rail-line,
.gd-lineup__rail-fill {
	position: absolute;
	top: 50%;
	left: 4px;
	height: 2px;
	border-radius: 999px;
	transform: translateY(-50%);
}

.gd-lineup__rail-line { right: 4px; background: var(--gd-glass-line); }

/*
 * Mapped so the head reaches a stop at the exact moment that card takes the
 * reading position: at p = i/count it is i/(count-1) along, which is where stop
 * i sits. It parks on the last stop for the final card's turn.
 */
.gd-lineup__rail-fill {
	width: calc(clamp(0, var(--p, 0) * var(--count, 1) * var(--span, 1), 1) * (100% - 8px));
	background: linear-gradient(90deg, var(--gd-violet), var(--gd-cyan));
}

.gd-lineup__stop {
	position: relative;
	z-index: 1;
	width: 8px;
	height: 8px;
	border-radius: 50%;
	/*
	 * Lit once the head has reached it. A steep ramp through the threshold
	 * rather than a comparison, so it stays a plain calc — and it needs no
	 * division, which keeps it portable.
	 */
	--reached: clamp(0, calc((var(--p, 0) * var(--count, 1) - var(--i, 0)) * 999 + 1), 1);
	/* Filled in once reached, outlined before. */
	background:
		linear-gradient(var(--gd-violet), var(--gd-violet)) no-repeat center /
			calc(var(--reached) * 8px) calc(var(--reached) * 8px),
		var(--gd-void);
	box-shadow:
		inset 0 0 0 1.5px color-mix(in srgb, var(--gd-violet) calc(var(--reached) * 100%), var(--gd-glass-line)),
		0 0 calc(var(--reached) * 10px) color-mix(in srgb, var(--gd-violet) calc(var(--reached) * 55%), transparent);
	transition: box-shadow 0.42s var(--gd-ease), background-size 0.42s var(--gd-ease);
}

.gd-lineup__note {
	margin: 0;
	color: var(--gd-text-3);
	font-size: 0.85rem;
}

/* ============================================================
   03 — The rebuild
   ============================================================ */

.gd-tiers {
	display: grid;
	margin: 0;
	padding: 0;
	gap: clamp(0.5rem, 1.2vw, 0.9rem);
	list-style: none;
}

.gd-tier {
	display: grid;
	align-items: center;
	padding: clamp(0.85rem, 1.7vw, 1.25rem) clamp(1rem, 2vw, 1.5rem);
	border: 1px solid var(--gd-glass-line);
	border-radius: var(--gd-radius);
	background: var(--gd-glass);
	column-gap: clamp(0.85rem, 2vw, 1.5rem);
	grid-template-columns: auto minmax(0, 1.35fr) clamp(80px, 11vw, 150px) 3.2rem;
	opacity: calc(0.2 + var(--lit) * 0.8);
	transform: translate3d(calc((1 - var(--lit)) * -18px), 0, 0);
}

.gd-tier__rank {
	color: var(--gd-text-3);
	font-size: 0.8rem;
	font-variant-numeric: tabular-nums;
	font-weight: 700;
}

.gd-tier__body { display: grid; gap: 0.15rem; }
.gd-tier__name { color: var(--gd-text); font-size: clamp(1rem, 1.7vw, 1.2rem); font-weight: 750; }
.gd-tier__who { color: var(--gd-text-2); font-size: 0.86rem; }
.gd-tier__note { color: var(--gd-text-3); font-size: 0.8rem; }

.gd-tier__meter {
	overflow: hidden;
	height: 6px;
	border-radius: 999px;
	background: var(--gd-glass-line);
}

/*
 * The share, at face value — no scaling up to make the bars look busier. The
 * figure is printed right beside it, and a 46% share filling 92% of its track
 * makes the two disagree.
 */
.gd-tier__fill {
	display: block;
	width: calc(1% * var(--share, 0) * var(--lit));
	max-width: 100%;
	height: 100%;
	border-radius: inherit;
	background: linear-gradient(90deg, var(--gd-violet), var(--gd-cyan));
}

.gd-tier__share {
	color: var(--gd-text);
	font-size: 0.95rem;
	font-variant-numeric: tabular-nums;
	font-weight: 700;
	text-align: right;
}

/* ============================================================
   04 — The loop, read from the middle of the ring
   ============================================================ */

.gd-cycle { display: grid; justify-items: center; }

.gd-cycle__ring {
	position: relative;
	aspect-ratio: 1;
	width: min(100%, clamp(300px, 30vw, 430px));
}

/* Rotated so the arc starts at twelve, where the first marker sits. */
.gd-cycle__svg { width: 100%; height: 100%; transform: rotate(-90deg); }

.gd-cycle__track { stroke: var(--gd-glass-line); stroke-width: 1.5; }

.gd-cycle__arc {
	stroke: var(--gd-violet);
	stroke-width: 3;
	stroke-linecap: round;
	/* 2πr for r=94. */
	stroke-dasharray: 590.6;
	stroke-dashoffset: calc(590.6 * (1 - var(--p, 0)));
	filter: drop-shadow(0 0 8px rgba(124, 92, 255, 0.7));
}

/*
 * Both the marker and the numbered pins are full-size boxes that rotate about
 * the ring's centre; the visible piece is parked on the circumference. Rotating
 * the dot itself would need a transform-origin outside its own box.
 */
.gd-cycle__marker,
.gd-cycle__pin {
	position: absolute;
	inset: 0;
	pointer-events: none;
}

.gd-cycle__marker { transform: rotate(calc(var(--p, 0) * 360deg)); }

.gd-cycle__marker::before {
	content: "";
	position: absolute;
	/* r=94 of a 220 viewBox — 42.73% out from the centre. */
	top: 7.27%;
	left: 50%;
	width: 13px;
	height: 13px;
	margin: -6.5px 0 0 -6.5px;
	border-radius: 50%;
	background: #fff;
	box-shadow: 0 0 10px 2px rgba(167, 139, 250, 1), 0 0 26px 6px rgba(124, 92, 255, 0.8);
}

.gd-cycle__pin {
	transform: rotate(var(--angle, 0deg));
	--lit: clamp(0, (var(--p, 0) - var(--at, 0)) * 400, 1);
}

/* Counter-rotated so every number reads upright wherever it sits. */
.gd-cycle__pin i {
	position: absolute;
	top: 7.27%;
	left: 50%;
	display: grid;
	width: 38px;
	height: 38px;
	margin: -19px 0 0 -19px;
	border: 1px solid var(--gd-glass-line);
	border-radius: 50%;
	background: var(--gd-void);
	color: var(--gd-text-3);
	font-size: 0.76rem;
	font-style: normal;
	font-variant-numeric: tabular-nums;
	font-weight: 700;
	place-items: center;
	transform: rotate(calc(-1 * var(--angle, 0deg)));
}

.gd-cycle__pin {
	--pin-on: var(--lit);
}

.gd-cycle__pin i {
	border-color: color-mix(in srgb, var(--gd-violet) calc(var(--pin-on) * 70%), var(--gd-glass-line));
	color: color-mix(in srgb, var(--gd-text) calc(var(--pin-on) * 100%), var(--gd-text-3));
	transition: border-color 0.26s var(--gd-ease), color 0.26s var(--gd-ease);
}

/* The list lives in the middle of the ring, one entry at a time. */
.gd-cycle__centre {
	position: absolute;
	top: 50%;
	left: 50%;
	display: grid;
	width: 62%;
	margin: 0;
	padding: 0;
	list-style: none;
	place-items: center;
	transform: translate(-50%, -50%);
}

/*
 * On or off, then animated — not scrubbed.
 *
 * Tying opacity smoothly to scroll meant the changeover was spread across
 * whatever distance the reader happened to cover, so two entries sat half-faded
 * over each other and neither was readable. The multiplier here is large enough
 * that `--on` is effectively a switch: an entry is either the current one or it
 * is not. The transition then plays the change over a fixed 260ms of its own,
 * so it reads as a deliberate swap at a consistent speed no matter how fast the
 * page is being scrolled.
 */
.gd-cycle__card {
	display: grid;
	gap: 0.3rem;
	grid-area: 1 / 1;
	text-align: center;
	--on: calc(
		clamp(0, (var(--p, 0) - var(--from, 0)) * 400, 1) *
		clamp(0, (var(--to, 1) - var(--p, 0)) * 400, 1)
	);
	opacity: var(--on);
	transform: translate3d(0, calc((1 - var(--on)) * 10px), 0) scale(calc(0.97 + var(--on) * 0.03));
	transition:
		opacity 0.26s var(--gd-ease),
		transform 0.26s var(--gd-ease);
}

.gd-cycle__step {
	color: var(--gd-brand, #cc3066);
	font-size: 0.68rem;
	font-weight: 800;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

.gd-cycle__name {
	color: var(--gd-text);
	font-size: clamp(1.05rem, 1.8vw, 1.35rem);
	font-weight: 750;
	line-height: 1.2;
	letter-spacing: -0.02em;
}

.gd-cycle__note {
	color: var(--gd-text-3);
	font-size: 0.82rem;
	line-height: 1.5;
}

/*
 * Without JS nothing writes `--p`, so the ring is meaningless and every entry
 * would sit on top of the others. Fall back to the plain numbered list the
 * markup already is.
 */
html:not(.gd-js) .gd-cycle__ring { aspect-ratio: auto; width: 100%; }
html:not(.gd-js) .gd-cycle__svg,
html:not(.gd-js) .gd-cycle__marker,
html:not(.gd-js) .gd-cycle__pin { display: none; }

html:not(.gd-js) .gd-cycle__centre {
	position: static;
	width: 100%;
	gap: 1.25rem;
	transform: none;
}

html:not(.gd-js) .gd-cycle__card {
	grid-area: auto;
	opacity: 1;
	text-align: left;
}

/* ============================================================
   05 — The report
   ============================================================ */

.gd-report { display: grid; justify-items: center; }

.gd-report__card {
	width: min(760px, 100%);
	padding: clamp(1.25rem, 3vw, 2.25rem);
	border: 1px solid var(--gd-glass-line);
	border-radius: var(--gd-radius-lg);
	background: var(--gd-glass);
	box-shadow: 0 40px 90px -60px rgba(10, 14, 34, 0.7);
}

.gd-report__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding-bottom: 1rem;
	border-bottom: 1px solid var(--gd-glass-line);
	gap: 1rem;
}

.gd-report__label { color: var(--gd-text); font-size: 0.95rem; font-weight: 700; }

.gd-report__stamp {
	padding: 0.2rem 0.55rem;
	border: 1px solid var(--gd-glass-line);
	border-radius: 999px;
	color: var(--gd-text-3);
	font-size: 0.68rem;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.gd-report__figures {
	display: grid;
	margin: 0;
	padding: clamp(1rem, 2.4vw, 1.6rem) 0;
	gap: 1rem;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	list-style: none;
}

.gd-report__figures > li {
	display: grid;
	gap: 0.15rem;
	opacity: var(--lit);
	transform: translate3d(0, calc((1 - var(--lit)) * 12px), 0);
}

.gd-report__num {
	color: var(--gd-text);
	font-size: clamp(1.5rem, 3.4vw, 2.4rem);
	font-weight: 800;
	font-variant-numeric: tabular-nums;
	letter-spacing: -0.03em;
	line-height: 1;
}

.gd-report__figures > li:first-child .gd-report__num {
	background: linear-gradient(90deg, var(--gd-violet), var(--gd-cyan));
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
}

.gd-report__unit { color: var(--gd-text-2); font-size: 0.8rem; }
.gd-report__was { color: var(--gd-text-3); font-size: 0.75rem; text-decoration: line-through; }

.gd-report__chart {
	display: flex;
	align-items: flex-end;
	height: clamp(72px, 11vw, 120px);
	padding-bottom: 0.75rem;
	border-bottom: 1px solid var(--gd-glass-line);
	gap: clamp(0.4rem, 1.2vw, 0.9rem);
}

.gd-report__bar {
	flex: 1;
	height: calc(1% * var(--h, 0) * var(--lit));
	border-radius: 5px 5px 0 0;
	background: linear-gradient(180deg, rgba(124, 92, 255, 0.75), rgba(34, 211, 238, 0.35));
}

.gd-report__changes {
	display: grid;
	margin: 0;
	padding: clamp(1rem, 2vw, 1.4rem) 0 0;
	gap: 0.5rem;
	list-style: none;
}

.gd-report__changes > li {
	position: relative;
	padding-left: 1.35rem;
	color: var(--gd-text-2);
	font-size: 0.88rem;
	line-height: 1.5;
	opacity: var(--lit);
	transform: translate3d(calc((1 - var(--lit)) * 10px), 0, 0);
}

.gd-report__changes > li::before {
	content: "";
	position: absolute;
	top: 0.55em;
	left: 0;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: linear-gradient(90deg, var(--gd-violet), var(--gd-cyan));
}

/* ============================================================
   Narrow screens
   ============================================================ */

@media (max-width: 899px) {
	/*
	 * On a phone the strip is swiped, not scrolled through.
	 *
	 * Un-pinned, the beat only has about a screen of travel — nowhere near
	 * enough to give nine cards a readable hold each, and the first card was
	 * gone before it could be read. A native scroll-snap carousel is both the
	 * obvious gesture here and the easiest thing to read: every card is legible,
	 * and you stop on whichever one you want rather than hunting for it with
	 * the page scroll.
	 */
	.gd-lineup__viewport {
		--card: min(74vw, 300px);
		--read: var(--gd-gutter);

		overflow-x: auto;
		scroll-snap-type: x mandatory;
		scroll-padding-left: var(--gd-gutter);
		-webkit-overflow-scrolling: touch;
		scrollbar-width: none;
		/* The mask would hide the card at each end of the swipe. */
		-webkit-mask-image: none;
		mask-image: none;
	}

	.gd-lineup__viewport::-webkit-scrollbar { display: none; }

	.gd-lineup__track {
		transform: none;
		transition: none;
	}

	/*
	 * Room after the last card so it can reach its snap position — without it
	 * the strip stopped 81px short and the ninth check could never be brought
	 * fully into view.
	 *
	 * A spacer rather than padding on the track: a flex container's trailing
	 * padding is dropped from scrollWidth once its children overflow, so the
	 * padding was applied and simply did nothing. A flex item is measured.
	 */
	.gd-lineup__track::after {
		content: "";
		width: max(0px, calc(100% - var(--card) - var(--gap)));
		flex: none;
	}

	.gd-lineup__card {
		--focus: 1;
		scroll-snap-align: start;
		transform: none;
	}

	/* Belongs to the scroll-driven version. */
	.gd-lineup__focus { display: none; }

	.gd-lineup__rail { display: none; }

	/* Side by side, the note squeezed the rail down to nothing. */
	.gd-lineup__foot {
		flex-direction: column;
		align-items: stretch;
		gap: 0.85rem;
	}

	.gd-lineup__rail { flex: none; width: 100%; }

	.gd-tier {
		grid-template-columns: auto minmax(0, 1fr) 3rem;
		row-gap: 0.6rem;
	}

	.gd-tier__meter { grid-row: 2; grid-column: 1 / span 3; }
	.gd-tier__share { grid-row: 1; }

	/*
	 * The ring takes the width it can get and the copy inside it takes more of
	 * the middle, since a narrow ring leaves a very small square to write in.
	 */
	.gd-cycle__ring { width: min(90vw, 400px); }
	.gd-cycle__centre { width: 74%; }
	.gd-cycle__note { font-size: 0.78rem; }
	.gd-cycle__pin i { width: 32px; height: 32px; margin: -16px 0 0 -16px; font-size: 0.7rem; }

	.gd-report__figures { grid-template-columns: minmax(0, 1fr); gap: 0.85rem; }
	.gd-report__figures > li { grid-template-columns: auto minmax(0, 1fr); align-items: baseline; column-gap: 0.6rem; }
	.gd-report__num { font-size: 1.6rem; }
	.gd-report__was { grid-column: 2; }
}


/* ============================================================
   Reduced motion
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
	/*
	 * Nothing here is a transition, so turning off durations would leave the
	 * page blank at every cue. Stand it all up instead.
	 */
	.gd-leak__seg,
	.gd-leak__item,
	.gd-tier,
	.gd-cycle__pin,
	.gd-report__figures > li,
	.gd-report__bar,
	.gd-report__changes > li {
		--lit: 1;
	}

	.gd-leak__item,
	.gd-tier,
	.gd-report__figures > li,
	.gd-report__changes > li { transform: none; }

	/*
	 * The line-up stops travelling and wraps instead, so all nine checks are
	 * readable at once without the horizontal movement.
	 */
	.gd-lineup__viewport { overflow: visible; }
	.gd-lineup__focus { display: none; }

	.gd-lineup__track {
		flex-wrap: wrap;
		padding-left: 0;
		transform: none;
	}

	.gd-lineup__card {
		--focus: 1;
		width: min(100%, 330px);
		flex: 1 1 260px;
		transform: none;
	}

	/*
	 * The ring's entries show one at a time by design, so standing them up
	 * would pile all five on the same spot. Fall back to the stacked list the
	 * markup already is — the same shape used when JavaScript is off.
	 */
	.gd-cycle__ring { aspect-ratio: auto; width: 100%; }
	.gd-cycle__svg,
	.gd-cycle__marker,
	.gd-cycle__pin { display: none; }

	.gd-cycle__centre {
		position: static;
		width: 100%;
		gap: 1.25rem;
		transform: none;
	}

	.gd-cycle__card { grid-area: auto; opacity: 1; text-align: left; }
}
