/* Brand Hero — three themes of one app, one phone, colour the only difference.

   Geometry from design-preview-v2.pdf page 2, design px at 1440. Every figure
   below was read off the PDF's own vector paths and text matrices, not
   sampled off a screenshot, so they are exact rather than approximate:

     band        full bleed 0 -> 1440, y4598.46 -> y5447.89 (849.43), Deep Green,
                 square corners, warm white above and #F2EFE7 below
     eyebrow     Inter Bold 17.28 / tracking 0 / #00A254, centred, baseline 4707.45
     heading     Playfair 61.92 (cap 43.84 over Playfair's 0.708 cap ratio),
                 -0.03em, #FBFAF7, centred, baseline 4800.46
     intro       Inter Medium 24.888 / -0.055em / leading 1.1, x112.40
     theme rows  x108.71, 374.82 x 70, radius 12, 13.16 apart
                 logo slot 50 x 50 at 10 in; label x185.37; three 13.28 dots on
                 a 17.70 pitch ending 23.67 from the row's right edge
                 inactive: white at 60% over the band; active: opaque white
                 inside a 3px Vivid Green ring, inner radius 9 — concentric
     phone       frame x539.5 -> x897 (357.5), top 4877, bezel 9.5, screen 338,
                 screen radius 45.218, app bar 53.4 tall, logo 41.84 x 43.75
                 centred in it. Cut square by the band's bottom edge — bezel
                 down both sides, NOTHING drawn across the cut, verified at 4x
                 on the strip y5400 -> y5500.
     screen      drawn, not photographed. Figures in the block above .phone-ui.
     notes       x958.5, Inter Medium 24.888 headings, Inter Regular 14.4 /
                 -0.03em / 1.4 copy

   The three columns land on the page grid exactly: 375.5 + 56 + 357.5 + 61.5 +
   373.5 = 1224, the content column. One gap value (58) splits the difference
   and puts every edge within 2px of the comp.

   THREE DEPARTURES FROM THE COMP, all deliberate:

   1. The eyebrow is --thread-green rather than the comp's Vivid Green. It
      was 18.66 Vivid Green for a while — Vivid on Deep Green is 4.48:1,
      under AA's 4.5:1 for normal text, and 18.66/700 is the large-scale
      threshold that makes 3:1 apply — but the theme-wide eyebrow rule now
      sets every eyebrow well under that threshold (2026-08), which puts
      the 4.5 floor back. --thread-green is the token ai-question minted for
      exactly this: green on Deep Green at 4.56:1, clearing the bar instead
      of failing by 0.02. Same solution as cred-panel's eyebrow.

   2. Type on this surface is --ink-inverse (pure white). The comp sets it
      #FBFAF7 in most places and #FFFFFF in others; the theme has already
      ruled that dark surfaces take pure white.

   3. The screen is drawn in Inter and in the theme's own weights. The comp's
      screen is a screenshot of the product, set in a rounded geometric sans
      the theme does not carry. Matching the STRUCTURE, the proportions and
      the type sizes is what makes it read as CINC Connect; matching a font
      the site does not have would mean shipping a fourth family for a
      picture.

   NO SCRIPT. The switch is a radio group and :has(), so the whole thing works
   with JavaScript disabled and there is no module.js to keep in step. */

section.brand-hero {

	/* Vertical rhythm, solved from the comp's baselines rather than eyeballed.
	   Each is its px value at 1440 expressed as vw so it scales, floored at a
	   value that still reads on a phone. Vertical padding in vw is correct —
	   a percentage on padding-block would resolve against WIDTH. */
	--bandPadTop:    clamp(48px, 6.29vw, 90.6px);   /* band top -> eyebrow line box */
	--bandPadBottom: clamp(48px, 10.97vw, 158px);   /* rows' bottom -> band bottom */
	--headGap:       clamp(16px, 2.24vw, 32.3px);   /* eyebrow -> heading */
	/* TIGHTENED, and the one figure here that is no longer the comp's. The
	   comp measures 157 at 1440 — heading baseline 4800.46 to columns top
	   4962.7 — against a notes column of four short blocks. The live copy runs
	   longer, which makes the band taller, and 157 on top of that read as a
	   hole rather than as air. Cut to 94 at 1440 (109 -> 65 at 1000), and the
	   floor with it. Reinstate 10.9vw / 157px if the comp's own copy ever
	   comes back. */
	--colsGap:       clamp(32px, 6.5vw, 94px);      /* heading -> columns */
	--phoneLift:     clamp(24px, 5.95vw, 85.7px);   /* columns' top -> phone top */

	/* The selected theme's colours. --t1-… through --t4-… ride on this element
	   as inline custom properties written by module.html; the :has() rules
	   below promote whichever one is checked. A theme that supplies only its
	   brand colour still works — every surface on the screen is mixed from it. */
	--themeInk:  var(--t1-ink, var(--ink-deep));
	--themeSoft: var(--t1-soft, color-mix(in srgb, var(--themeInk) 16%, var(--pure-white)));
	--themeLogo: var(--t1-logo, none);

	/* WRITTEN OUT, not looped. This was a `for i in range(1, 5)` emitting the
	   four rules, and HubSpot does not execute it in a module.css: the loop
	   tags came through the compiler as literal text while the loop variable
	   resolved to nothing, so the whole block rendered as ONE rule reading

	       :has(.theme-radio[value=""]:checked) { --themeInk: var(--t-ink, …) }

	   — a selector no radio matches, naming variables that do not exist. The
	   switcher was inert: every theme kept theme 1's colours. Confirmed on the
	   live page, where picking theme 2 left --themeInk at #5C3A6E, and again
	   after this change, where 1/2/3 resolve to #5C3A6E / #273468 / #684616.

	   Note the loop in module.html DOES run — that is what emits the three
	   radios — so this is specific to CSS, not to the module. Do not
	   reintroduce a loop here; four rules is cheaper than a silent failure. */
	&:has(.theme-radio[value="1"]:checked) {
		--themeInk:  var(--t1-ink, var(--ink-deep));
		--themeSoft: var(--t1-soft, color-mix(in srgb, var(--themeInk) 16%, var(--pure-white)));
		--themeLogo: var(--t1-logo, none);
	}

	&:has(.theme-radio[value="2"]:checked) {
		--themeInk:  var(--t2-ink, var(--ink-deep));
		--themeSoft: var(--t2-soft, color-mix(in srgb, var(--themeInk) 16%, var(--pure-white)));
		--themeLogo: var(--t2-logo, none);
	}

	&:has(.theme-radio[value="3"]:checked) {
		--themeInk:  var(--t3-ink, var(--ink-deep));
		--themeSoft: var(--t3-soft, color-mix(in srgb, var(--themeInk) 16%, var(--pure-white)));
		--themeLogo: var(--t3-logo, none);
	}

	&:has(.theme-radio[value="4"]:checked) {
		--themeInk:  var(--t4-ink, var(--ink-deep));
		--themeSoft: var(--t4-soft, color-mix(in srgb, var(--themeInk) 16%, var(--pure-white)));
		--themeLogo: var(--t4-logo, none);
	}

	/* --- The screen's palette: four roles, all derived --------------------

	   The whole screen is drawn, so every pixel of it has to come from the two
	   values above. Four roles are enough to draw the app:

	     --screenInk    headings, labels, and the fill of anything selected
	     --screenTint   the app bar, the search field, the tab strip, the cards
	     --screenBase   the screen's own ground, behind all of it
	     --screenQuiet  secondary type — meta labels, the placeholder, the chevrons

	   Ink and tint are the author's two fields. Base and quiet are mixes of
	   them, at the ratios the comp measures: the screen ground is #F5F7FC
	   against a #D2DEF8 tint, which is 25% of the tint in white; the comp's
	   secondary navy #4F5A7A against a #273468 ink is 85% of the ink in white.
	   Type on a filled chip is --ink-inverse, the theme's own pure white — the
	   one token here that is not derived, and the same choice the band above
	   already makes.

	   LEGIBILITY FOR ANY BRAND COLOUR. CSS cannot branch on luminance, but it
	   can CLAMP one. Relative colour syntax reads the ink's own OKLCH
	   lightness and caps it, keeping hue and chroma:

	     ink  is never lighter than L 0.44   — an ink, i.e. ≥ 6.25:1 on white
	     tint is never darker  than L 0.89, nor more saturated than C 0.045

	   Both clamps are no-ops for a palette that was chosen as a palette: all
	   three of the comp's tints and two of its three inks pass through byte
	   for byte. They only bite on a colour that was never an ink — Silver
	   Grove's #90A095 is 2.75:1 on white, and becomes #48574D: the same sage,
	   dark enough to read. Sweeping the whole sRGB cube with the clamps in
	   force, a theme that supplies ONLY a brand colour holds ≥ 5.21:1 on
	   primary type, ≥ 3.98:1 on secondary, and ≥ 6.25:1 for white on a filled
	   chip; a theme that also supplies a tint — any colour at all — holds
	   ≥ 4.40:1 and ≥ 3.27:1. Measured over 120k random pairs, not assumed.

	   Where relative colour syntax is missing the values fall back to the raw
	   fields, which is exactly what the comp draws and what this module did
	   before. Nothing breaks; a badly chosen colour is simply not rescued. */
	--screenInk:   var(--themeInk);
	--screenTint:  var(--themeSoft);

	@supports (color: oklch(from white calc(l) c h)) {
		--screenInk:  oklch(from var(--themeInk) calc(min(l, .44)) c h);
		--screenTint: oklch(from var(--themeSoft) calc(max(l, .89)) calc(min(c, .045)) h);
	}

	--screenBase:  color-mix(in srgb, var(--screenTint) 25%, var(--pure-white));
	--screenQuiet: color-mix(in srgb, var(--screenInk) 85%, var(--pure-white));

	/* Full bleed and square, against the global section radius — the comp runs
	   the band edge to edge and butts it straight onto the band below.
	   overflow is what cuts the phone off at the bottom edge. */
	border-radius: 0;
	overflow: hidden;

	.container {
		/* The band's own padding. The Layout group's pt-/pb- classes sit on the
		   section and add to it, so an author can still open the band up. */
		padding-block: var(--bandPadTop) var(--bandPadBottom);
	}

	.brand-hero-head {
		text-align: center;
	}

	/* Type comes from the theme-wide eyebrow rule (_typography.css).
	   --thread-green for the contrast reason at the top of this file — not
	   --action (4.48:1, fails by 0.02) and not --signal: Lime is semantic
	   and an eyebrow is not intelligence. */
	.brand-hero-eyebrow {
		color: var(--thread-green);
		margin: 0 0 var(--headGap);
	}

	/* .heading1 is Playfair 61.92 at -0.03em, which is what the comp draws
	   here: cap height 43.84 against Playfair's 708/1000, and the same cap as
	   page 1's H1 and page 2's "Decisions, Prepared." — one display size
	   across the comps, already in the scale. The tag comes from the field. */
	.brand-hero-heading {
		margin: 0;
		color: var(--ink-inverse);
	}

	.rich-heading {
		/* Was Playfair's own bold — a latent control, no comp instance shows
		   it. Capped by the theme-wide Playfair ruling: no Playfair above
		   400, emphasis included. */
		--emphasis-weight: inherit;
		--emphasis-color: inherit;
	}

	.brand-hero-cols {
		display: grid;
		grid-template-columns: minmax(0, 1fr);
		gap: clamp(32px, 4vw, 48px);
		margin-top: var(--colsGap);

		/* 29.2% of the 1224 content column is the phone's 357.5. A percentage
		   track, not vw: it measures the grid's own content box, so the
		   scrollbar is out of it. */
		@media (min-width: 1000px) {
			grid-template-columns: minmax(0, 1fr) 29.2% minmax(0, 1fr);
			column-gap: 58px;
			/* TOP, not centre. Centring is only invisible while the columns are
			   the same height, which is true of the comp and not of the page:
			   with four notes at 1000 the notes column is 571 against a 383
			   left column, so centring dropped the intro 93.8px below the
			   notes' first heading and opened a void under the heading on the
			   left only. Top-aligned, both columns start on the same line and
			   the gap under the heading is --colsGap for all of them. The
			   phone is absolutely positioned and anchored at the cut, so this
			   does not move it. */
			align-items: start;
		}
	}

	/* --- Left column: the statement and the switch --- */

	.brand-hero-intro {
		/* 24.888 / -0.055em / 1.1, all three measured. The size recurs across
		   the comps — magic-moment's media heading is the same 24.888 — and is
		   not on the type scale yet. Weight is the rung above the comp's
		   Medium, as the theme requires. */
		font-size: 2.4888rem;
		line-height: 1.1;
		font-weight: var(--display);
		letter-spacing: -.055em;
		color: var(--ink-inverse);
		margin: 0 0 36.11px;
		text-wrap: balance;
	}

	/* A RADIO GROUP, not a tablist. Nothing is revealed or replaced by picking
	   one — a setting changes and the phone repaints — which is what a radio
	   group is for. It also carries its own keyboard model: one tab stop for
	   the group, arrow keys between the options, "2 of 3" announced, and the
	   checked state exposed without a single line of script. */
	.themes {
		display: flex;
		flex-direction: column;
		gap: 13.16px;
		/* fieldset's UA border, padding and min-width all have to go */
		border: 0;
		margin: 0;
		padding: 0;
		min-width: 0;
	}

	.theme {
		position: relative;
		display: block;
		cursor: pointer;
	}

	/* The real control, laid over its own row so a click lands on it.
	   appearance:none rather than opacity:0 or a clip — the input keeps normal
	   visibility, so it stays in the accessibility tree and in hit testing
	   while painting nothing; the row underneath is the whole visual. */
	.theme-radio {
		position: absolute;
		inset: 0;
		width: 100%;
		height: 100%;
		margin: 0;
		appearance: none;
		-webkit-appearance: none;
		background: transparent;
		border: 0;
		cursor: pointer;
	}

	/* 70 tall, 3px border, 7px padding — which puts the 50px logo slot 10 in
	   from the row's edge and the last swatch 23.67 from its right, both as
	   measured. The border is on every row, transparent until checked, so
	   nothing reflows when the selection moves. */
	.theme-body {
		display: grid;
		grid-template-columns: 50px minmax(0, 1fr) auto;
		align-items: center;
		column-gap: 16.66px;
		min-height: 70px;
		padding: 7px 20.67px 7px 7px;
		border: 3px solid transparent;
		border-radius: var(--rad);
		background: color-mix(in srgb, var(--pure-white) 60%, transparent);
		color: var(--ink-deep);
	}

	/* The selected row. The ring is --action, as the comp draws it, rather than
	   the theme's own colour: a ring in an author-supplied colour would be as
	   legible as that colour happens to be, and this one has to clear 3:1
	   against both the band and the card underneath it. It does — 4.48:1 and
	   3.34:1. The state is also carried by SHAPE and by the row going opaque,
	   so it is not colour alone. */
	.theme-radio:checked + .theme-body {
		background: var(--surface-raised);
		border-color: var(--action);
	}

	/* Gated on a real pointer: on touch, :hover latches after a tap and would
	   leave a row lit that is not the selected one. */
	@media (hover: hover) {
		.theme-radio:not(:checked):hover + .theme-body {
			background: color-mix(in srgb, var(--pure-white) 78%, transparent);
		}
	}

	/* Outside the row, so the ring lands on the band rather than on the white
	   card, where Warm White would be 1.04:1. On the band it is 14.31:1. The
	   3px offset clears the row's own border. */
	.theme-radio:focus-visible + .theme-body {
		outline: 2px solid var(--focus-inverse);
		outline-offset: 3px;
	}

	.theme-logo {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 50px;
		height: 50px;

		img {
			display: block;
			width: 100%;
			height: 100%;
			object-fit: contain;
		}
	}

	.theme-label {
		font-size: 1.728rem;
		line-height: 1.15;
		font-weight: var(--data);
		letter-spacing: -.03em;
	}

	.theme-swatches {
		display: flex;
		gap: 4.42px;
	}

	/* The theme's own colours, on the control, at full strength on every row —
	   the comp dims the whole inactive row to 60% including its swatches, but
	   the swatches are the one place you can compare the palettes, so they stay
	   readable. The hairline is what keeps a pale swatch visible on white. */
	.dot {
		width: 13.28px;
		height: 13.28px;
		border-radius: var(--radPill);
		background: var(--dot);
		box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 12%, transparent);
	}

	/* --- The phone --- */

	/* Stretched so its bottom edge is the row's bottom edge; the phone then
	   hangs from it and the band's own bottom padding is how far it overshoots.
	   cqi measures this column, so every part of the phone scales with its
	   width and nothing is pinned to the viewport. */
	.col-phone {
		position: relative;
		align-self: stretch;
		container-type: inline-size;
	}

	.phone {
		display: flex;
		flex-direction: column;
		/* No bezel along the bottom. Checked against the comp at 4x: at
		   y5447.89 the band's edge cuts straight through the screen — bezel on
		   the left and right, screen content running into the cut, and nothing
		   drawn across it. A padding-bottom here closes the frame over the cut
		   and the phone reads as a short device with a bar under it rather
		   than one running off the band. */
		padding: 2.657cqi 2.657cqi 0;
		/* Square at the foot: the comp cuts the phone off at the band's edge
		   rather than resting it on one. */
		border-radius: 15.3cqi 15.3cqi 0 0;
		/* The comp's bezel is white at 45% down its left edge and 20% down its
		   right — a light source from the left rather than a flat frame. */
		background: linear-gradient(90deg,
			color-mix(in srgb, var(--pure-white) 45%, transparent),
			color-mix(in srgb, var(--pure-white) 20%, transparent));
		overflow: hidden;

		@media (min-width: 1000px) {
			position: absolute;
			inset-inline: 0;
			/* ANCHORED AT THE CUT, NOT STRETCHED BETWEEN BOTH EDGES.

			   Past the edge, not up to it. --bandPadBottom alone lands the
			   frame's own bottom exactly on the band's, so the cut is the end
			   of the element and there is nothing to clip. The extra
			   --space-xl is the largest the Layout group's Space Below can be,
			   so the frame still overshoots the section at every setting and
			   the section's overflow:hidden is what ends it. */
			top: auto;
			bottom: calc(-1 * (var(--bandPadBottom) + var(--space-xl)));

			/* This was `top: calc(-1 * var(--phoneLift))` against the same
			   bottom — the frame stretched between the two, so its height was
			   the GRID ROW's height and its width was the column's. Those are
			   independent, and the row is as tall as the tallest column: at
			   1000 with four notes the notes column is 571 against a 248-wide
			   phone, and the frame came out 248 x 840 — 3.39:1, where a phone
			   is 1.6:1. Everything drawn inside it is in cqi off the width, so
			   the extra 440px landed in the one growing element, .ui-card-tail,
			   as a 500px slab of empty card. Measured, not estimated.

			   min() of the two heights instead:

			     device   159.69cqi is the comp's own 570.89 / 357.5, which is
			              the frame ABOVE the cut. Only --space-xl is added:
			              --bandPadBottom is already inside that 159.69, since
			              the section's edge is --bandPadBottom below the row
			              and the visible frame is measured to that edge. Add
			              it twice and the phone comes out 2.04:1 — measured,
			              which is how the first pass of this was caught.
			     stretch  100% is .col-phone, i.e. the row, which is what the
			              frame used to take unconditionally — a percentage
			              height on an absolutely positioned box resolves
			              against its containing block, and .col-phone is it

			   Whichever is smaller wins, and the bottom is anchored either
			   way, so the cut always lands on the band's edge. Where the row
			   is short the stretch is smaller and the frame reaches
			   --phoneLift above the columns, which is what the comp draws — at
			   1440 with the comp's two notes the two branches agree to within
			   0.2px (714.7 against 714.9), so nothing there moves. Where the
			   row is tall the device height wins and the phone hangs from the
			   cut at 1.597:1 rather than growing into a noodle. */
			height: min(
				calc(159.69cqi + var(--space-xl)),
				calc(100% + var(--phoneLift) + var(--bandPadBottom) + var(--space-xl))
			);
		}
	}

	.phone-screen {
		display: flex;
		flex-direction: column;
		flex: 1;
		min-height: 0;
		/* Concentric inside the frame: 15.3cqi less the 2.657cqi bezel. */
		border-radius: 12.643cqi 12.643cqi 0 0;
		background: var(--screenBase);
		overflow: hidden;
		/* A container of its own, so every figure on the screen is a
		   percentage of the SCREEN's 338 rather than of the frame's 357.5.
		   Nothing below is in rem: this is a picture of a phone, and a reading
		   size raised by the browser would burst the drawn UI out of a frame
		   that cannot grow with it. The type a reader is meant to READ — the
		   heading, the intro, the theme names, the notes — is all in rem. */
		container-type: inline-size;
	}

	/* Bar, logo and both glyphs come from the theme, as they always did — now
	   from --screenInk / --screenTint rather than the raw fields, so the bar
	   and the screen under it are one palette rather than two. For every theme
	   in the comp the two are the same value. */
	.phone-bar {
		flex: none;
		display: flex;
		align-items: center;
		justify-content: space-between;
		height: 15.8cqi;
		padding-inline: 5.84cqi;
		background: var(--screenTint);
		color: var(--screenInk);
	}

	/* Drawn UI inside a picture of a phone, so these are geometry rather than
	   reading sizes and stay proportional to the mockup. A rem here would grow
	   the glyphs out of the bar when a reader raises their text size. */
	.phone-bar-glyph {
		font-size: 4.73cqi;
		line-height: 1;
	}

	.phone-bar-logo {
		width: 12.94cqi;
		height: 12.94cqi;
		background-image: var(--themeLogo);
		background-position: center;
		background-repeat: no-repeat;
		background-size: contain;
	}

	/* --- The screen ------------------------------------------------------

	   Drawn, not photographed, so that all of it repaints with the theme.
	   Measured off comp page 2 at 4x, x539.5–897, screen top y4886.5, band
	   edge y5447.89. Design px at 1440, where the screen is 338 wide, so
	   1 design px = 0.2959cqi and every figure below is its measurement
	   divided by 3.38:

	     gutter        16.5      title row  top +7.0, 18.5 tall
	     search        39.5 tall, r16, +14.5 under the title row
	     tab strip     37.5 tall, r14, 4 inset, two equal halves of 148.5
	     section row   ink 15.5 bold, link 10.4, +16.5 under the strip
	     card          r16, photo 305 x 89.5 (3.408:1), body padding 15
	                   title 13.8 / meta 9.0 / copy 9.6 / chips 29 tall
	     tail card     +18.5 heading, +14 card, cut by the band at y5447.89

	   Type sizes are cap-height solves against Inter's 0.727 ratio. The comp
	   sets this screen in the product's own rounded sans, which the theme does
	   not carry and has no business carrying; it is drawn in Inter. */

	.phone-ui {
		flex: 1;
		min-height: 0;
		display: flex;
		flex-direction: column;
		align-items: stretch;
		padding-inline: 4.882cqi;
		font-family: var(--inter);
		letter-spacing: -.02em;
		background: var(--screenBase);
		color: var(--screenInk);
		/* The tail card runs into the cut. */
		overflow: hidden;
	}

	/* Every drawn line is a <span>, so nothing in here is a heading, a
	   paragraph or a control even before role="img" flattens the subtree.
	   Each one is given its own display — a blanket `.phone-ui span` rule
	   outranks the single-class rules below and flattens the flex rows. */

	.ui-titlerow {
		flex: none;
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 2.96cqi;
		margin-top: 2.071cqi;
	}

	.ui-title {
		display: block;
		font-size: 5.089cqi;
		line-height: 1.08;
		font-weight: var(--bold);
	}

	.ui-info {
		flex: none;
		font-size: 5.473cqi;
		line-height: 1;
		color: var(--screenQuiet);
	}

	.ui-search {
		flex: none;
		display: flex;
		align-items: center;
		gap: 3.254cqi;
		height: 11.686cqi;
		margin-top: 4.290cqi;
		padding-inline: 4.586cqi;
		border-radius: 4.734cqi;
		background: var(--screenTint);
		color: var(--screenQuiet);
	}

	.ui-placeholder {
		display: block;
		font-size: 3.669cqi;
		line-height: 1.2;
		font-weight: var(--medium);
	}

	/* Two equal halves inside a 4-inset track: 305 less 8 is 297, and the
	   comp's selected pill measures 148.5 — exactly half. */
	.ui-segs {
		flex: none;
		display: grid;
		grid-template-columns: 1fr 1fr;
		height: 11.095cqi;
		margin-top: 3.107cqi;
		padding: 1.183cqi;
		border-radius: 4.142cqi;
		background: var(--screenTint);
	}

	.ui-seg {
		display: grid;
		place-items: center;
		border-radius: 2.959cqi;
		font-size: 2.663cqi;
		line-height: 1;
		font-weight: var(--data);
		letter-spacing: .06em;
		text-transform: uppercase;
		color: var(--screenQuiet);

		&.is-on {
			background: var(--screenInk);
			color: var(--ink-inverse);
		}
	}

	.ui-sectionrow {
		flex: none;
		display: flex;
		align-items: baseline;
		justify-content: space-between;
		gap: 2.96cqi;
		margin-top: 4.024cqi;
	}

	.ui-h {
		display: block;
		font-size: 4.586cqi;
		line-height: 1.1;
		font-weight: var(--bold);
	}

	.ui-h-standalone {
		flex: none;
		margin-top: 4.615cqi;
	}

	.ui-link {
		flex: none;
		display: block;
		font-size: 3.077cqi;
		line-height: 1.1;
		font-weight: var(--data);
	}

	.ui-card {
		flex: none;
		margin-top: 3.654cqi;
		border-radius: 4.734cqi;
		background: var(--screenTint);
		overflow: hidden;
	}

	/* The card the cut runs through GROWS to fill whatever is left of the
	   screen. The drawn UI scales with the screen's width while the frame's
	   height is set by the band, so the two only coincide at one width: at
	   1440 the content reaches the band's edge on its own, at 1000 the frame
	   is far taller than the content and without this the screen ends in a
	   panel of empty ground. Growing the tail is what a real screen does —
	   there is always more list under the cut.

	   1 0 auto, not 1: flex:1 sets a flex-basis of 0, which would collapse
	   this card to nothing wherever the content already overflows the frame,
	   which is exactly what happens below the three-column break.

	   Its photograph keeps the same 3.408:1 as the first card's rather than
	   stretching to the new height — at 1440 the cut lands 85.6 into an 89.5
	   photo, as the comp draws it, and a photo grown to fill would be
	   scaled up and cropped to something the comp never shows. The card's own
	   body carries the extra height instead, which is what a second card
	   under the fold actually contains. */
	.ui-card-tail {
		flex: 1 0 auto;
		margin-top: 3.506cqi;
	}

	/* The photographs are the only author fields on this screen. An empty one
	   is a tinted panel at the photo's own proportions — not a stretched
	   placeholder and not a broken image — so the card keeps its shape. */
	.ui-photo {
		display: block;
		width: 100%;
		aspect-ratio: 305 / 89.5;
		object-fit: cover;
		object-position: center;

		&.is-empty {
			background:
				linear-gradient(135deg,
					color-mix(in srgb, var(--screenInk) 22%, var(--screenTint)),
					color-mix(in srgb, var(--screenInk) 8%, var(--screenTint)));
		}
	}

	.ui-cardbody { padding: 3.225cqi 4.438cqi 3.698cqi; }

	.ui-cardtitle {
		display: block;
		font-size: 4.083cqi;
		line-height: 1.1;
		font-weight: var(--bold);
	}

	.ui-meta {
		display: flex;
		align-items: center;
		gap: 3.846cqi;
		margin-top: 3.077cqi;
		font-size: 2.663cqi;
		line-height: 1.1;
		font-weight: var(--medium);
		color: var(--screenQuiet);
	}

	.ui-metaitem {
		display: flex;
		align-items: center;
		gap: 1.627cqi;
		white-space: nowrap;
	}

	.ui-glyph {
		flex: none;
		font-size: 2.811cqi;
		line-height: 1;
	}

	.ui-search .ui-glyph { font-size: 3.107cqi; }

	.ui-copy {
		display: block;
		margin-top: 2.870cqi;
		font-size: 2.840cqi;
		line-height: 1.2;
		font-weight: var(--book);
		color: var(--screenQuiet);
	}

	.ui-chips {
		display: flex;
		align-items: center;
		gap: 3.550cqi;
		margin-top: 2.751cqi;
	}

	.ui-chip {
		flex: none;
		display: grid;
		place-items: center;
		height: 8.580cqi;
		padding-inline: 2.219cqi;
		border-radius: 2.959cqi;
		font-size: 3.047cqi;
		line-height: 1;
		font-weight: var(--data);
		letter-spacing: -.01em;
		white-space: nowrap;
		background: var(--screenInk);
		color: var(--ink-inverse);
	}

	.ui-chev {
		flex: none;
		margin-inline-start: auto;
		font-size: 2.959cqi;
		line-height: 1;
		color: var(--screenQuiet);
	}

	/* --- Right column: the notes --- */

	.col-notes {
		display: flex;
		flex-direction: column;
		gap: 25.3px;
	}

	.note-heading {
		font-size: 2.4888rem;
		line-height: 1.1;
		font-weight: var(--display);
		letter-spacing: -.055em;
		color: var(--ink-inverse);
		margin: 0 0 10.74px;
	}

	.note-copy {
		font-size: 1.44rem;
		line-height: 1.4;
		font-weight: var(--book);
		letter-spacing: -.03em;
		color: var(--ink-inverse);
		margin: 0;
		text-wrap: pretty;
	}

	/* --- Motion ---

	   Nothing moves on its own and there is nothing to autoplay: the only
	   motion is the colour crossing from one theme to the next, at the
	   interface tier because someone has just asked for it. Opted IN under
	   no-preference rather than switched off under reduce, so a reader who has
	   asked for less never has the transition applied at all. */
	@media (prefers-reduced-motion: no-preference) {
		.theme-body,
		.dot,
		.phone-bar,
		.phone-screen,
		.phone-ui,
		.ui-search,
		.ui-segs,
		.ui-seg,
		.ui-card,
		.ui-photo.is-empty,
		.ui-chip {
			transition:
				background-color var(--cascadeDurationUI) var(--easeOut),
				background-image var(--cascadeDurationUI) var(--easeOut),
				border-color var(--cascadeDurationUI) var(--easeOut),
				color var(--cascadeDurationUI) var(--easeOut);
		}
	}

	/* In forced colours every brand value is replaced by the user's palette, so
	   the checked row would lose its ring along with everything else. System
	   keywords are the only legal values in this mode — they are not colours
	   escaping the token layer. */
	@media (forced-colors: active) {
		.theme-body { border-color: ButtonBorder; }
		.theme-radio:checked + .theme-body { border-color: Highlight; }
	}

	/* --- Below the three-column break --- */

	@media (max-width: 999px) {
		.brand-hero-intro { margin-bottom: clamp(24px, 4vw, 36px); }

		.col-phone {
			/* In flow now, so it takes the height the comp shows rather than
			   hanging off the band. */
			max-width: 320px;
			width: 100%;
			margin-inline: auto;
		}

		/* A WHOLE device here, not a cut one. Below the three-column break the
		   phone is in the flow with the notes stacked under it, so there is no
		   band edge for it to run off — and a frame that stopped square in the
		   middle of the band would read as a crop with nothing doing the
		   cropping. So the bezel closes all the way round and the bottom
		   padding comes back. The screen is still cut, as any screenshot is:
		   the tail card runs into the frame's lower edge. */
		.phone {
			aspect-ratio: 357.5 / 570.89;
			padding: 2.657cqi;
			border-radius: 15.3cqi;
		}

		.phone-screen { border-radius: 12.643cqi; }
	}

	/* Under about 440 the row's measured geometry leaves the label 153px and a
	   two-word community name breaks over two lines. The logo slot and the
	   paddings give the label back 28px rather than the name wrapping. */
	@media (max-width: 460px) {
		.theme-body {
			grid-template-columns: 40px minmax(0, 1fr) auto;
			column-gap: 12px;
			padding-inline: 7px 12px;
		}

		.theme-logo {
			width: 40px;
			height: 40px;
		}
	}
}
