/*
 * The Crypto Secret — the reviews marquee and the guarantee band (Story 2.5).
 * Sections 9 and 10 of the locked order.
 *
 * Source of truth: design/canvas/Main.dc.html:422-450 (reviews) and :452-464
 * (guarantee), with design/canvas/HomeMobile.dc.html:124-137 for the mobile
 * review stack. Where this file departs from a board, the reason is written at
 * the rule.
 *
 * ═══════════════════════════════════════════════════════════════════════════
 * WHAT THIS FILE CONSUMES RATHER THAN RE-DECLARES
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * motion.css owns ALL OF THE MOTION IN THIS FILE, and that is not a stylistic
 * preference — it is the story's hardest constraint. There is no @keyframes
 * here, no animation-duration, no pause-on-hover rule and no reduced-motion
 * rule for a track. Every one of those already exists and is already correct:
 *
 *   .tcs-marquee__view                  motion.css:183   the clipping viewport
 *   .tcs-marquee__track                 motion.css:189   the only moving box
 *   .tcs-marquee__track--reverse        motion.css:200   row B's direction
 *   .tcs-marquee__track--reviews-a      motion.css:209   40s
 *   .tcs-marquee__track--reviews-b      motion.css:213   46s
 *   :hover / :focus-within → paused     motion.css:221   both rows at once
 *   the whole reduced-motion treatment  motion.css:418-462
 *
 * Writing any of them a second time would create a second place for the
 * timings to drift, and re-declaring the reduced-motion block would be worse
 * than redundant: motion.css:460 carries an `!important` on .tcs-marquee__dup
 * that exists specifically to beat the inline `display: flex` a track's copy
 * carries, and a weaker restatement here would look like it was working.
 *
 * sections.css owns both bands' grounds, their padding modifiers and their
 * type pairing — .tcs-band--cream, .tcs-band--orange, .tcs-band--bleed-x
 * (92px 0 88px, Main.dc.html:423) and .tcs-band--short (66px, :453). Both
 * modifiers were declared in story 1.2 FROM THESE TWO ARTBOARD LINES, so this
 * file applies them rather than respelling their padding.
 *
 * tokens.css owns every value. There is not one literal colour, radius, size
 * or duration below — the whole Story 2.5 block was added to tokens.css first
 * for exactly that reason, and verify-foundation.sh asserts the absence of a
 * hex here.
 *
 * ═══════════════════════════════════════════════════════════════════════════
 * THE THREE THINGS THIS FILE EXISTS TO GET RIGHT
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * 1. THE REVIEWER NAME PASSES AA. The board paints it #8B877D, which is
 *    --tcs-muted and measures 3.58:1 on the white card. At 13px that is
 *    interface text and the floor is 4.5:1, so it fails — for the FOURTH time
 *    across this epic. The fix is already in the token layer:
 *    --tcs-label-on-white (#767164) measures 4.87:1 on white and keeps the
 *    name visually subordinate to the quote, which is the design intent. The
 *    artboards win on a visual conflict; they do not win on an accessibility
 *    failure.
 *
 * 2. THE TRACKS STRETCH, THEY DO NOT CENTRE. motion.css:191 sets
 *    `align-items: center` on .tcs-marquee__track, which is right for a strip
 *    of single-line asset chips and wrong for a row of cards whose quotes run
 *    to one, two or three lines: centred, their tops and bottoms are both
 *    ragged. Overriding it to `stretch` is the concrete reason reviews.css
 *    must be enqueued AFTER motion.css — emitted before it, the two rules tie
 *    on specificity and the earlier one loses.
 *
 * 3. NOTHING OVERFLOWS THE DOCUMENT. Two tracks at `width: max-content` are
 *    deliberately several times wider than the viewport. .tcs-bands already
 *    carries `overflow-x: clip` (sections.css:89) and .tcs-marquee__view
 *    carries `overflow: hidden` (motion.css:186), so the width is contained —
 *    but only as long as nothing here re-opens either. The guarantee band's
 *    grid is the other half: `minmax(0, 1fr)` on its copy column, never a bare
 *    1fr, because a grid item's implicit min-width is `auto` and a 34px
 *    headline beside a `white-space: nowrap` link would otherwise push the
 *    band sideways.
 */

/* ===========================================================================
 * 1. THE REVIEWS BAND  —  Main.dc.html:422-450
 * ========================================================================= */

/*
 * The band is --bleed-x: 92px 0 88px, no side padding, because the tracks run
 * edge to edge. The HEAD is not edge to edge, so it sits in a .tcs-band__inner
 * which sections.css:230 gives the side padding the band gave up.
 */
.tcs-reviews__inner {
	display: flex;
	flex-direction: column;
}

/* ---------------------------------------------------------------------------
 * 1a. The head — Main.dc.html:424-427.
 *
 * h2 left, lede right, BOTTOM-aligned. The same two-column head the comparison
 * band uses one band earlier, and it takes the same 44px gap to the content
 * below it (--tcs-compare-head-gap) rather than a second name for the same
 * measurement.
 * ------------------------------------------------------------------------- */

.tcs-reviews__head {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--tcs-cred-col-gap);
	margin-bottom: var(--tcs-compare-head-gap);
}

/*
 * NO COLOUR HERE. .tcs-band--cream already resolves an h2 to --tcs-black
 * (18.09:1 on the cream ground). A second declaration would be a second place
 * for the palette rule to drift.
 */
.tcs-reviews__headline {
	margin: 0;
	font-size: var(--tcs-fs-h2);
	line-height: var(--tcs-lh-h2);
	letter-spacing: var(--tcs-ls-h2);
	font-weight: var(--tcs-fw-semibold);
}

/*
 * The figure and its `+` are spans so the headline can be read as one
 * sentence while the number keeps its own identity — the same treatment
 * .tcs-figure__value gives it in the credibility band. NO SEPARATE COLOUR: at
 * 54px inside a headline the figure is already the loudest thing in the band,
 * and painting it orange here would put a second accent in the same viewport
 * as the guarantee band's full orange ground directly below.
 */
.tcs-reviews__figure,
.tcs-reviews__plus {
	color: inherit;
}

.tcs-reviews__lede {
	margin: 0;
	max-width: var(--tcs-review-lede-max);
	font-size: var(--tcs-fs-body);
	line-height: var(--tcs-lh-lede);
	color: var(--tcs-body);   /* 6.91:1 on cream */
}

/* ---------------------------------------------------------------------------
 * 1b. The two tracks and the mask — Main.dc.html:428.
 *
 * ONE viewport holds BOTH tracks. That is what makes hovering either row pause
 * both: motion.css:221 pauses `.tcs-marquee__view:hover .tcs-marquee__track`,
 * a descendant selector, so a single hovered view stops every track inside it.
 * Giving each row its own view would have been the obvious build and would
 * have let one row keep sliding while a reader stopped to read the other.
 * ------------------------------------------------------------------------- */

.tcs-reviews__marquee {
	/*
	 * .tcs-marquee is `display: flex` (motion.css:171) with a label as the
	 * first child; there is no label here, so the single view child takes the
	 * full width. Stated rather than assumed, because a flex item's default
	 * `flex: 0 1 auto` would size the view to its max-content track.
	 */
	display: block;
}

.tcs-reviews__view {
	/*
	 * Two rows stacked. The gap between them is the same 14px that separates
	 * card from card, which is the board's own rhythm (Main.dc.html:428).
	 */
	display: flex;
	flex-direction: column;
	gap: var(--tcs-review-track-gap);

	/*
	 * THE EDGE MASK, both ends (Main.dc.html:428). Cards should read as
	 * continuing past the viewport rather than being guillotined by it, and
	 * because these tracks run in OPPOSITE directions a one-sided fade would
	 * be correct for one row and wrong for the other. -webkit- is still
	 * required by Safari, which has not unprefixed mask-image.
	 *
	 * WRITTEN AS AN ALPHA, NOT AS A COLOUR, following noise.css:140-148: the
	 * artboard's stop is `#000`, but a mask reads only the alpha channel, so
	 * `#000` there means "fully opaque" and not "black". Nothing in this
	 * gradient is ever painted, and spelling it rgb(0 0 0 / 1) keeps a
	 * non-design colour out of the palette the gate scans.
	 */
	-webkit-mask-image: linear-gradient(
		90deg,
		transparent,
		rgb(0 0 0 / 1) var(--tcs-review-mask-in),
		rgb(0 0 0 / 1) var(--tcs-review-mask-out),
		transparent
	);
	mask-image: linear-gradient(
		90deg,
		transparent,
		rgb(0 0 0 / 1) var(--tcs-review-mask-in),
		rgb(0 0 0 / 1) var(--tcs-review-mask-out),
		transparent
	);
}

/*
 * THE OVERRIDE THIS FILE'S ENQUEUE ORDER EXISTS FOR. motion.css:191 centres a
 * track's children, which is right for single-line asset chips and wrong for
 * cards whose quotes run to one, two or three lines. `stretch` makes every
 * card in a row the height of the tallest, which is how the board draws them.
 *
 * NO ANIMATION, NO DURATION, NO DIRECTION HERE. Those are the --reviews-a,
 * --reviews-b and --reverse modifiers already on the elements.
 */
.tcs-reviews__track {
	align-items: stretch;
}

/*
 * One copy — four quotes twice, per the note at tcs_review_marquee_copy(). The
 * gap after the copy is the same card gap, so the seam between copy one and
 * copy two is invisible; without it the loop shows a double-width gap once per
 * cycle, which reads as a stutter.
 */
.tcs-reviews__copy {
	display: flex;
	align-items: stretch;
	gap: var(--tcs-review-track-gap);
	padding-left: var(--tcs-review-track-gap);
	flex: 0 0 auto;
}

/* ---------------------------------------------------------------------------
 * 1c. The card — Main.dc.html:430.
 * ------------------------------------------------------------------------- */

/*
 * NOT .tcs-card. The hover lift (motion.css:330-349) belongs to a card the
 * reader can act on; these are quotations, they are not interactive, and a
 * card that lifts under the cursor inside a track that has just paused reads
 * as two competing responses to one gesture.
 *
 * The width is FIXED rather than a flex share: inside a `width: max-content`
 * track there is no containing block for a percentage to resolve against, and
 * a flexible card would collapse to its longest word.
 */
.tcs-review {
	flex: 0 0 auto;
	width: var(--tcs-review-card-w);
	margin: 0;                                   /* <figure> ships with one */
	display: flex;
	flex-direction: column;
	gap: var(--tcs-review-card-gap);
	padding: var(--tcs-review-card-pad);
	background: var(--tcs-white);
	border: var(--tcs-border-width) solid var(--tcs-border);
	border-radius: var(--tcs-radius-figure-card);
}

/*
 * The quote. 18px / 500 / 1.46 / -.018em — a pull quote, set tighter and
 * heavier than --tcs-fs-body so it reads as someone speaking.
 *
 * --tcs-black on --tcs-white is 19.55:1. <blockquote> ships with a 40px UA
 * margin, which would indent every quote inside its own card.
 */
.tcs-review__quote {
	margin: 0;
	font-size: var(--tcs-fs-review-quote);
	font-weight: var(--tcs-fw-medium);
	line-height: var(--tcs-lh-review-quote);
	letter-spacing: var(--tcs-ls-review-quote);
	color: var(--tcs-black);
}

/*
 * THE NAME, AND THE COLOUR CORRECTION THIS BAND IS MOST LIKELY TO LOSE.
 *
 * --tcs-label-on-white (#767164) at 4.87:1, NOT the board's --tcs-muted
 * (#8B877D) at 3.58:1. 13px is interface text, so the floor is 4.5:1 and the
 * board's colour misses it. This exact substitution has now been made in three
 * prior stories for the same reason; the token exists so it does not have to
 * be re-derived a fourth time.
 */
.tcs-review__name {
	font-size: var(--tcs-fs-review-name);
	line-height: var(--tcs-lh-body-sm);
	color: var(--tcs-label-on-white);
}

/* The mobile stack is hidden at desktop; the media query at section 3 swaps
 * the pair. Both are in the served HTML at every width. */
.tcs-reviews__mobile {
	display: none;
}

/* ===========================================================================
 * 2. THE GUARANTEE BAND  —  Main.dc.html:452-464
 *
 * The climax beat of the primary buyer journey. Its ground is
 * .tcs-band--orange, which sections.css:127-130 pairs with --tcs-black text
 * and --tcs-black links — orange-on-orange being invisible, and amber being a
 * light-ground link colour. Nothing here re-declares either.
 * ========================================================================= */

/*
 * `84px minmax(0, 1fr) auto` — badge, copy, link. NEVER a bare 1fr: a grid
 * item's implicit min-width is `auto`, so the copy column would size to its
 * longest unbroken run and push the nowrap link past the right edge, which is
 * the horizontal-overflow failure the I/O matrix forbids. This is a grid rule,
 * not a preference.
 */
.tcs-guarantee__inner {
	display: grid;
	grid-template-columns: var(--tcs-guarantee-badge) minmax(0, 1fr) auto;
	gap: var(--tcs-guarantee-gap);
	align-items: center;
}

/*
 * The black disc. --tcs-black on --tcs-orange is 8.51:1, so the glyph inside
 * it is legible by a wide margin — but the disc is decoration either way: it
 * is aria-hidden in the markup and says nothing the headline does not.
 *
 * The glyph takes `currentColor` from the disc, so the two colours cannot
 * drift apart: one declaration, two elements.
 */
.tcs-guarantee__badge {
	width: var(--tcs-guarantee-badge);
	height: var(--tcs-guarantee-badge);
	flex: 0 0 auto;
	border-radius: var(--tcs-radius-full);
	background: var(--tcs-black);
	color: var(--tcs-orange);
	display: flex;
	align-items: center;
	justify-content: center;
}

/*
 * The stroke weight is set HERE rather than as a stroke-width attribute on
 * each <path>, for the reason every other value in this file is a token: the
 * board draws 1.7 (Main.dc.html:456) and two paths carrying it as a
 * presentation attribute would be two places for one number to drift. A CSS
 * declaration also beats a presentation attribute in the cascade, so the
 * token is what paints regardless of what the markup happens to carry.
 */
.tcs-guarantee__glyph {
	width: var(--tcs-guarantee-glyph);
	height: var(--tcs-guarantee-glyph);
	stroke-width: var(--tcs-guarantee-stroke);
}

.tcs-guarantee__body {
	display: flex;
	flex-direction: column;
	gap: var(--tcs-guarantee-copy-gap);
}

/*
 * NO COLOUR. .tcs-band--orange resolves an h2 to --tcs-black at 8.51:1
 * (sections.css:137-140).
 *
 * 34px is this band's own size, not --tcs-fs-h2-mobile, which happens to share
 * the number: the headline shares a row with an 84px badge and a nowrap link,
 * and at 54px there is no room for either.
 */
.tcs-guarantee__headline {
	margin: 0;
	font-size: var(--tcs-fs-guarantee-h2);
	line-height: var(--tcs-lh-guarantee-h2);
	letter-spacing: var(--tcs-ls-guarantee-h2);
	font-weight: var(--tcs-fw-semibold);
}

/*
 * THE BODY COPY, AND THE ONE COLOUR IN THIS BAND THAT NEEDED A DECISION.
 *
 * The board draws rgba(12,12,13,.72), which composites over --tcs-orange to
 * #4E3211 and measures 5.11:1 — comfortably AA. It ships as that opaque value
 * rather than as the rgba, for two reasons that point the same way: the colour
 * is only ever seen composited against this one ground, and the contrast gate
 * composites an element's cumulative OPACITY rather than the alpha inside a
 * `color`, so the rgba form would be measured as plain black at 8.51:1 — a
 * number no reader ever sees.
 *
 * DO NOT SUBSTITUTE --tcs-amber-2 (2.17:1 on orange, and scoped to chapter
 * numerals) OR --tcs-body-dark (documented for black grounds only). The band's
 * drawn colours pass and are not to be "improved".
 */
.tcs-guarantee__copy {
	margin: 0;
	max-width: var(--tcs-guarantee-copy-max);
	font-size: var(--tcs-fs-guarantee-copy);
	line-height: var(--tcs-lh-guarantee-copy);
	color: var(--tcs-guarantee-copy-ink);
}

/*
 * The refund window and the price are spans so the gate can find each without
 * parsing a sentence, and so a filter that changes the window changes exactly
 * one element. They inherit the paragraph's colour: highlighting either would
 * put emphasis on the number rather than on the promise, and the promise is
 * what this band is for.
 */
.tcs-guarantee__window,
.tcs-guarantee__price {
	color: inherit;
	font-weight: inherit;
}

/*
 * The policy link. --tcs-black on orange at 8.51:1 comes from
 * sections.css:159-161; only the shape is set here.
 *
 * `white-space: nowrap` is the board's (Main.dc.html:462) and is what the
 * `auto` third column is sized to. The 44px min-height is the epic's tap
 * target floor, which applies to inline text links — the flex centring is how
 * a 14.5px label fills 44px without the underline detaching from the text.
 */
.tcs-guarantee__link {
	display: inline-flex;
	align-items: center;
	min-height: var(--tcs-tap-min);
	font-size: var(--tcs-fs-guarantee-link);
	font-weight: var(--tcs-fw-semibold);
	text-decoration: underline;
	white-space: nowrap;
}

/* ===========================================================================
 * 3. MOBILE  —  HomeMobile.dc.html:124-137, and one band that is not drawn.
 *
 * 768px, the breakpoint every other section sheet in this theme uses.
 * ========================================================================= */

@media (max-width: 768px) {

	/* --- 3a. The reviews become a static stack ------------------------- */

	/*
	 * THE MARQUEE IS SWAPPED OUT, NOT REFLOWED. Two counter-scrolling tracks
	 * at 390px would put a 342px card in a 350px viewport and give a reader a
	 * moving target on the input method least able to hit one — a phone has no
	 * hover, so the pause-on-hover escape hatch does not exist there.
	 *
	 * `display: none` rather than clipping: the tracks must leave the
	 * accessibility tree as well as the layout, or a screen reader announces
	 * all eight quotes twice.
	 */
	.tcs-reviews__desktop {
		display: none;
	}

	.tcs-reviews__mobile {
		display: flex;
		flex-direction: column;
		gap: var(--tcs-review-stack-gap);        /* HomeMobile.dc.html:127 */
		padding-inline: var(--tcs-section-x-mobile);
	}

	/*
	 * ALL EIGHT CARDS, though the board draws three. HomeMobile.dc.html
	 * predates both the marquee and the evidence file; hiding five cleared
	 * quotes to match a stale drawing would delete evidenced proof from the
	 * width most buyers arrive on. The board's CARD is followed exactly —
	 * 22px inside, 11px radius, 17px quote — only the count differs, and the
	 * reason is written here so it is not "corrected" later.
	 */
	.tcs-review--mobile {
		width: auto;
		padding: var(--tcs-review-card-pad-mobile);
		border-radius: var(--tcs-radius-chapter-card-mobile);
	}

	.tcs-review--mobile .tcs-review__quote {
		font-size: var(--tcs-fs-review-quote-mobile);
	}

	/* The head stacks, and the headline drops to the mobile h2. */
	.tcs-reviews__head {
		flex-direction: column;
		align-items: flex-start;
		gap: var(--tcs-review-track-gap);
		margin-bottom: var(--tcs-cred-stack-gap);
	}

	.tcs-reviews__headline {
		font-size: var(--tcs-fs-h2-mobile);      /* 34px, HomeMobile.dc.html:126 */
		line-height: var(--tcs-lh-h2-mobile);
		letter-spacing: var(--tcs-ls-h2-mobile);
	}

	.tcs-reviews__lede {
		max-width: none;
		font-size: var(--tcs-fs-body-sm);
	}

	/* --- 3b. The guarantee band stacks --------------------------------- */

	/*
	 * THIS BAND IS ABSENT FROM HomeMobile.dc.html, so its mobile state is
	 * designed here rather than transcribed, following story 2.3's precedent
	 * for the same situation.
	 *
	 * The arithmetic forces it: an 84px badge, then prose, then a
	 * `white-space: nowrap` link on ONE row needs roughly 84 + 34 + copy + 34
	 * + 110px of link. At 390px with 20px of band padding there are 350px to
	 * work with, which leaves the copy column about 90px wide — three or four
	 * characters per line. Stacking is not a preference here; the row cannot
	 * hold.
	 *
	 * The ORDER is unchanged: badge, then the promise, then the link. The
	 * badge stays at 84px rather than shrinking — it is the only mark in the
	 * band and the band is 66px of padding around a single idea, so there is
	 * height for it.
	 */
	.tcs-guarantee__inner {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--tcs-cred-stack-gap);
		align-items: start;
		justify-items: start;
	}

	.tcs-guarantee__headline {
		font-size: var(--tcs-fs-h2-mobile);
		line-height: var(--tcs-lh-h2-mobile);
		letter-spacing: var(--tcs-ls-h2-mobile);
	}

	.tcs-guarantee__copy {
		max-width: none;
		font-size: var(--tcs-fs-body-sm);
	}

	/*
	 * The link stops being nowrap. At 390 "Read the policy" fits on one line
	 * anyway, but nowrap on a stacked item is a promise this file cannot keep
	 * once the string is translated — and an unbreakable label is exactly the
	 * kind of element that sets a grid column's auto min-width and scrolls the
	 * document sideways.
	 */
	.tcs-guarantee__link {
		white-space: normal;
	}
}

/* ===========================================================================
 * 4. REDUCED MOTION
 *
 * DELIBERATELY ALMOST EMPTY, and that is the point of this section rather
 * than an omission.
 *
 * Every animation in this story belongs to the marquee primitive, and
 * motion.css:418-462 already resolves all of it correctly: the tracks stop and
 * wrap (`:418`), their children lose the scroll-in indent (`:441`), the view
 * stops clipping (`:447`) and the duplicate copies leave the layout entirely
 * (`:460`, whose `!important` beats the inline `display: flex`). Restating any
 * of that here would be a second, weaker copy of a rule that already works.
 *
 * The ONE thing left is the mask, which is not an animation at all — which is
 * exactly why motion.css cannot know about it.
 * ========================================================================= */

@media (prefers-reduced-motion: reduce) {

	/*
	 * The mask comes off. Under reduced motion the tracks no longer scroll out
	 * from under it: motion.css:447 makes the view overflow visible and the
	 * tracks wrap into a static block. A fade over a stationary, wrapped grid
	 * of cards hides the first and last card of every row behind a gradient
	 * for no reason — the same correction noise.css:761-767 makes to the asset
	 * strip's one-sided fade, and for the same reason.
	 */
	.tcs-reviews__view {
		-webkit-mask-image: none;
		mask-image: none;
	}

	/*
	 * NO TRACK-LEVEL RULE HERE, DELIBERATELY (code-review fix, 2026-09-04). A
	 * `.tcs-reviews__track { gap: … }` block used to live in this media query,
	 * on the theory that the track's own wrapped rows needed it. It didn't:
	 * .tcs-marquee__dup hides the entire duplicate copy, so the track is left
	 * with exactly one visible child — its own `gap` is a space between
	 * SIBLINGS and has no effect with only one. The wrapping actually happens
	 * one level down, on .tcs-reviews__copy (:221), which already carries this
	 * same --tcs-review-track-gap unconditionally, motion or not — confirmed
	 * by a byte-identical reduced-motion screenshot at 1024px before and after
	 * removing the track rule. It was also, independently, a rule the story's
	 * own "no new reduced-motion rule for the track" boundary forbids: this
	 * class sits on the SAME element .tcs-marquee__track does (front-page.php
	 * emits both classes on one div), so a `.tcs-reviews__track` block here is
	 * a track rule by another name, not an exception to it.
	 */

}
