/**
 * Redwood — layout and components.
 *
 * Loaded after style.css (tokens + reset) and vendor/lenis.css.
 * Breakpoints pivot on two lines only: 48rem/768px and 64rem/1024px. The
 * desktop nav and the two-column layouts switch on the same 1024px line, so
 * there is no band where a desktop nav sits over a stacked layout.
 */

/* ==========================================================================
   Smooth-scroll guard — must stay above everything else
   ==========================================================================
   assets/css/vendor/lenis.css carries upstream's
   `.lenis.lenis-smooth { scroll-behavior: auto !important }`, which is not
   quite enough on its own: Lenis only adds `lenis-smooth` while a scroll is
   ALREADY in flight, so at rest the root carries only `lenis` and the first
   window.scrollTo() of each wheel gesture still lands under
   `scroll-behavior: smooth`. The !important is required because
   ScrollTrigger writes `scroll-behavior: smooth` back as an inline style
   after every refresh, and only !important outranks an inline declaration.
   ========================================================================== */
html.lenis {
	scroll-behavior: auto !important;
}

/* ==========================================================================
   Layout primitives
   ========================================================================== */
.container {
	width: 100%;
	max-width: var(--container-max);
	margin-inline: auto;
	padding-inline: var(--container-pad);
}

.section {
	padding-block: var(--space-section);
}

.section--lg {
	padding-block: var(--space-section-lg);
}

.section--alt {
	background: var(--color-bg-alt);
}

.screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

.skip-link {
	position: absolute;
	top: 0;
	left: 50%;
	transform: translate(-50%, -120%);
	z-index: 999;
	background: var(--color-accent);
	color: var(--color-ink);
	padding: var(--space-2xs) var(--space-sm);
	transition: transform var(--transition-fast);
}

.skip-link:focus {
	transform: translate(-50%, 0);
	clip-path: none;
	width: auto;
	height: auto;
	margin: 0;
	white-space: normal;
}

/* ==========================================================================
   Typographic elements
   ========================================================================== */

/* Small letterspaced label, often prefixed with ® like the reference. */
.label {
	display: block;
	font-family: var(--font-body);
	font-size: var(--fs-label);
	font-weight: 600;
	letter-spacing: var(--tracking-label);
	text-transform: uppercase;
	color: var(--color-ink);
	margin-bottom: var(--space-md);
}

.label::before {
	content: "\00AE\00A0";
	color: var(--color-accent-text);
}

.label--plain::before {
	content: none;
}

.lead {
	font-size: var(--fs-lead);
	color: var(--color-ink-muted);
	max-width: var(--measure);
}

/* Section heading — the 92px-class display type from the reference. */
.section-head {
	display: grid;
	gap: var(--space-md);
	margin-bottom: var(--space-lg);
}

.section-head h2 {
	font-size: var(--fs-h1);
	margin: 0;
	max-width: 14ch;
}

@media (min-width: 64rem) {
	.section-head {
		grid-template-columns: minmax(0, 1fr) minmax(0, 26rem);
		align-items: end;
		gap: var(--space-xl);
	}
}

/* Two-tone paragraph: opens white, tails off to grey. */
.statement__text {
	font-family: var(--font-display);
	font-weight: 600;
	font-size: var(--fs-h2);
	line-height: 1.08;
	letter-spacing: var(--tracking-display);
	text-transform: uppercase;
	color: var(--color-ink-muted);
	margin: 0;
}

.statement__text .u-lead-in {
	color: var(--color-ink);
}

.text-link {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	font-size: var(--fs-body);
	font-weight: 500;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--color-ink);
	border-bottom: 1px solid var(--color-hairline);
	padding-bottom: 0.3rem;
	transition: color var(--transition-fast), border-color var(--transition-fast);
}

.text-link::after {
	content: "\2197";
	color: var(--color-accent-text);
}

.text-link:hover,
.text-link:focus-visible {
	color: var(--color-accent-text);
	border-bottom-color: var(--color-accent);
}

/* ==========================================================================
   Pills and buttons
   ========================================================================== */
.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.55rem;
	min-height: 3rem;
	padding: 0 1.75rem;
	border: 1px solid transparent;
	border-radius: var(--radius-pill);
	font-family: var(--font-body);
	font-size: var(--fs-body);
	font-weight: 500;
	letter-spacing: 0.02em;
	cursor: pointer;
	transition: background-color var(--transition-fast), color var(--transition-fast), border-color var(--transition-fast);
}

/* The dot that precedes label text on filled pills in the reference. */
.btn--dot::before,
.site-nav__contact::before {
	content: "";
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: currentColor;
	flex: none;
}

.btn--primary {
	background: var(--color-light);
	color: var(--color-on-light);
	border-color: var(--color-light);
}

.btn--primary:hover,
.btn--primary:focus-visible {
	background: var(--color-accent);
	border-color: var(--color-accent);
	color: var(--color-ink);
}

.btn--accent {
	background: var(--color-accent);
	color: var(--color-ink);
	border-color: var(--color-accent);
}

.btn--accent:hover,
.btn--accent:focus-visible {
	background: var(--color-accent-hot);
	border-color: var(--color-accent-hot);
}

.btn--ghost {
	background: transparent;
	color: var(--color-ink);
	border-color: var(--color-line);
}

.btn--ghost:hover,
.btn--ghost:focus-visible {
	background: var(--color-light);
	color: var(--color-on-light);
	border-color: var(--color-light);
}

.btn--block {
	display: flex;
	width: 100%;
}

/* ==========================================================================
   Site header — pill navigation
   ========================================================================== */
.site-header {
	position: sticky;
	top: 0;
	z-index: 100;
	background: transparent;
	border-bottom: 1px solid transparent;
	transition: background-color var(--transition), border-color var(--transition);
}

/* backdrop-filter is deliberately NOT transitioned: animating a blur radius
   forces a re-blur of everything behind the header on every frame, which is
   a real scroll-jank source. It snaps on, masked by the background fade. */
.site-header.is-scrolled {
	background: rgba(13, 13, 13, 0.9);
	backdrop-filter: blur(14px);
	-webkit-backdrop-filter: blur(14px);
	border-bottom-color: var(--color-hairline);
}

.site-header__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-md);
	min-height: 5rem;
}

.site-title {
	font-family: var(--font-display);
	font-weight: 700;
	font-size: 1.5rem;
	line-height: 1;
	letter-spacing: 0.01em;
	text-transform: uppercase;
	color: var(--color-ink);
	white-space: nowrap;
}

.site-title sup {
	font-size: 0.45em;
	vertical-align: super;
}

.custom-logo {
	max-height: 2.25rem;
	width: auto;
}

/* --- Nav pills ----------------------------------------------------------- */
.site-nav__list {
	display: flex;
	align-items: center;
	gap: 0.35rem;
}

.site-nav__list a {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.5rem 1.125rem;
	border-radius: var(--radius-pill);
	font-size: var(--fs-nav);
	font-weight: 500;
	color: var(--color-ink);
	transition: background-color var(--transition-fast), color var(--transition-fast);
}

.site-nav__list a:hover,
.site-nav__list a:focus-visible {
	background: rgba(255, 255, 255, 0.1);
}

/* Filled active pill. */
.site-nav__list .current-menu-item > a,
.site-nav__list .current_page_item > a,
.site-nav__list .current-menu-ancestor > a {
	background: var(--color-light);
	color: var(--color-on-light);
}

.site-nav__list .current-menu-item > a::before,
.site-nav__list .current_page_item > a::before {
	content: "";
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: currentColor;
	flex: none;
}

/* Standalone filled Contact pill, right of the nav. */
.site-nav__contact {
	display: inline-flex;
	align-items: center;
	gap: 0.55rem;
	padding: 0.5rem 1.125rem;
	border-radius: var(--radius-pill);
	background: var(--color-light);
	color: var(--color-on-light);
	font-size: var(--fs-body);
	font-weight: 500;
	white-space: nowrap;
	transition: background-color var(--transition-fast), color var(--transition-fast);
}

.site-nav__contact:hover,
.site-nav__contact:focus-visible {
	background: var(--color-accent);
	color: var(--color-ink);
}

.nav-toggle {
	display: none;
	flex-direction: column;
	justify-content: center;
	gap: 5px;
	width: 2.75rem;
	height: 2.75rem;
	padding: 0;
	background: transparent;
	border: 1px solid var(--color-line);
	border-radius: var(--radius-pill);
	cursor: pointer;
}

.nav-toggle__bar {
	display: block;
	width: 1.1rem;
	height: 2px;
	margin: 0 auto;
	background: var(--color-ink);
	transition: transform var(--transition-fast), opacity var(--transition-fast);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(1) {
	transform: translateY(7px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(2) {
	opacity: 0;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(3) {
	transform: translateY(-7px) rotate(-45deg);
}

/* Mobile navigation.
   minmax(0, ...) rather than a bare 0fr: an fr track keeps an `auto`
   minimum, so the list's own padding inflated the collapsed panel and
   leaked the first menu item under the header. This also animates to the
   panel's real height at any item count — no magic max-height cap. */
@media (max-width: 63.9375rem) {
	.nav-toggle {
		display: flex;
	}

	.site-header__inner {
		position: relative;
	}

	.site-nav {
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		display: grid;
		grid-template-rows: minmax(0, 0fr);
		/*
		 * The row collapses to 0, but the list inside keeps its vertical
		 * padding (~52px), which min-height cannot compress — so without
		 * clipping here the top of the first link poked out under the header
		 * as a half "Home" pill on every page.
		 */
		overflow: hidden;
		background: var(--color-bg);
		border-bottom: 1px solid transparent;
		/* Hidden once collapsed, so closed links are not reachable by Tab.
		   The visibility change waits for the collapse to finish. */
		visibility: hidden;
		transition: grid-template-rows var(--transition), border-color var(--transition), visibility 0s linear 0.4s;
	}

	.site-nav > * {
		overflow: hidden;
		min-height: 0;
	}

	.site-nav.is-open {
		grid-template-rows: minmax(0, 1fr);
		border-bottom-color: var(--color-hairline);
		visibility: visible;
		transition: grid-template-rows var(--transition), border-color var(--transition), visibility 0s;
	}

	.site-nav__list {
		flex-direction: column;
		align-items: stretch;
		gap: 0.25rem;
		padding: var(--space-sm) var(--container-pad) var(--space-md);
	}

	.site-nav__list a {
		font-size: 1.25rem;
		padding: 0.75rem 1.125rem;
	}

	.site-nav__list .sub-menu a {
		padding-left: 2.25rem;
		color: var(--color-ink-muted);
	}

	.site-nav__contact {
		display: none;
	}
}

@media (min-width: 64rem) {
	.site-nav__list li {
		position: relative;
	}

	.site-nav__list .sub-menu {
		position: absolute;
		top: 100%;
		left: 50%;
		transform: translateX(-50%);
		min-width: 12rem;
		padding: 0.5rem;
		background: var(--color-surface);
		border: 1px solid var(--color-hairline);
		border-radius: 1.25rem;
		opacity: 0;
		visibility: hidden;
		transition: opacity var(--transition-fast), visibility var(--transition-fast);
	}

	.site-nav__list li:hover > .sub-menu,
	.site-nav__list li:focus-within > .sub-menu {
		opacity: 1;
		visibility: visible;
	}
}

/* ==========================================================================
   Hero — full-bleed duotone media with an oversized wordmark
   ==========================================================================
   The red treatment is applied in CSS, not baked into the file: the media is
   desaturated, then a red gradient is multiplied over it. That means any
   photograph — including the unrelated placeholder currently in the media
   library — resolves to the same art direction, and real product photography
   drops in later through the Customizer with no layout change.
   ========================================================================== */
.hero {
	position: relative;
	display: flex;
	flex-direction: column;
	/*
	 * The header is sticky and therefore in flow above the hero, so a plain
	 * 100svh hero overshot the viewport by the header's 5rem and pushed the
	 * two CTAs below the fold on a normal laptop.
	 */
	min-height: min(calc(100svh - 5rem), 58rem);
	padding-block: calc(var(--space-md) + 4rem) var(--space-md);
	overflow: hidden;
	/*
	 * Near-black with a faint red glow where the 3D mark sits. This is both
	 * the backdrop for the dither canvas and the whole hero when WebGL is
	 * unavailable, so it has to look finished on its own.
	 */
	background:
		radial-gradient(ellipse 50% 55% at 66% 42%, rgba(229, 25, 42, 0.16), transparent 70%),
		var(--color-bg);
}

@media (max-width: 47.9375rem) {
	.hero {
		background:
			radial-gradient(ellipse 80% 45% at 50% 36%, rgba(229, 25, 42, 0.16), transparent 70%),
			var(--color-bg);
	}
}

.hero__media {
	position: absolute;
	inset: 0;
	z-index: 0;
}

/* The duotone overlay only has something to tint when media is chosen. */
.hero__media:empty::after {
	display: none;
}

/* Live dithered mark (hero-dither.js). Pointer events stay on the hero
   itself so the buttons above remain clickable. */
.hero__canvas {
	position: absolute;
	inset: 0;
	z-index: 0;
	width: 100%;
	height: 100%;
	display: block;
	pointer-events: none;
	opacity: 0;
	transition: opacity 1.2s var(--ease);
}

.hero--dither-ready .hero__canvas {
	opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
	.hero__canvas {
		transition: none;
	}
}

.hero__media img,
.hero__media video {
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Step 1 of the duotone: strip the original colour. */
	filter: grayscale(1) contrast(1.18) brightness(0.82);
}

/* Step 2: multiply the brand red over the desaturated image. */
.hero__media::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(115deg, var(--color-accent) 0%, #8d1220 42%, #2c0609 100%);
	mix-blend-mode: multiply;
	pointer-events: none;
}

/* Legibility scrim, kept separate so the duotone stays a pure colour pass. */
.hero__scrim {
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
	background:
		linear-gradient(180deg, rgba(13, 13, 13, 0.75) 0%, transparent 32%),
		linear-gradient(0deg, var(--color-bg) 2%, rgba(13, 13, 13, 0.35) 38%, transparent 62%);
}

.hero__inner {
	position: relative;
	z-index: 2;
	width: 100%;
	/* Fill the hero and push the wordmark block to the bottom, so the
	   composition sits inside one viewport instead of overflowing it. */
	flex: 1;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: var(--space-md);
}

.hero__top {
	display: grid;
	gap: var(--space-lg);
}

.hero__intro {
	font-size: var(--fs-body);
	color: var(--color-ink);
	max-width: 26ch;
	margin: 0;
}


.hero__bottom {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--space-lg);
	flex-wrap: wrap;
}

/* The oversized wordmark. Overlaps the image by design. */
.hero__title {
	font-size: var(--fs-display);
	line-height: 0.85;
	letter-spacing: -0.035em;
	margin: 0;
	flex: 1 1 auto;
}

.hero__title sup {
	font-size: 0.22em;
	vertical-align: super;
	letter-spacing: 0;
}

.hero__subtitle {
	font-size: var(--fs-lead);
	color: var(--color-ink);
	max-width: 34ch;
	margin: var(--space-sm) 0 0;
}

.hero__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-sm);
	margin-top: var(--space-md);
}

@media (max-width: 63.9375rem) {
	.hero {
		min-height: min(calc(100svh - 5rem), 46rem);
	}

}

@media (max-width: 30rem) {
	.hero__actions .btn {
		width: 100%;
	}
}

/* ==========================================================================
   Marquee band
   ==========================================================================
   Pure CSS: the track holds two identical runs and translates by exactly
   -50%, so the loop is seamless. Stopped entirely under prefers-reduced-
   motion by the global rule in style.css.
   ========================================================================== */
.marquee-band {
	position: relative;
	overflow: hidden;
	padding-block: var(--space-lg);
	background: var(--color-bg);
	display: grid;
	gap: 0.25rem;
}

.marquee {
	overflow: hidden;
	/* Slight tilt, oversized and pulled back so the rotation never exposes
	   a corner of the viewport. */
	width: 116%;
	margin-left: -8%;
	transform: rotate(-3deg);
	border-block: 1px solid var(--color-hairline);
	background: var(--color-bg-alt);
}

.marquee__track {
	display: flex;
	width: max-content;
	animation: redwood-marquee 38s linear infinite;
}

.marquee--reverse .marquee__track {
	animation-direction: reverse;
}

.marquee--fast .marquee__track {
	animation-duration: 26s;
}

.marquee__run {
	display: flex;
	align-items: center;
	flex: none;
}

.marquee__item {
	font-family: var(--font-display);
	font-weight: 700;
	font-size: var(--fs-marquee);
	line-height: 1.2;
	letter-spacing: var(--tracking-display);
	text-transform: uppercase;
	padding-inline: 1.25rem;
	white-space: nowrap;
}

.marquee__star {
	color: var(--color-accent);
	font-size: calc(var(--fs-marquee) * 0.55);
	line-height: 1;
}

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

/* ==========================================================================
   Numbered process cards
   ========================================================================== */
.process-grid {
	display: grid;
	gap: var(--space-md);
}

@media (min-width: 48rem) {
	.process-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: 0;
	}

	/* Staggered like the reference: middle card drops below its siblings. */
	.process-card:nth-child(2) {
		margin-top: var(--space-xl);
	}
}

.process-card {
	position: relative;
	padding: var(--space-md);
	border: 1px solid var(--color-hairline);
	transition: background-color var(--transition), border-color var(--transition);
}

.process-card:hover {
	background: var(--color-surface);
	border-color: var(--color-line);
}

.process-card__num {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 3.25rem;
	height: 3.25rem;
	margin-bottom: var(--space-lg);
	background: var(--color-light);
	color: var(--color-on-light);
	font-family: var(--font-display);
	font-weight: 700;
	font-size: 1.25rem;
	line-height: 1;
}

.process-card:hover .process-card__num {
	background: var(--color-accent);
	color: var(--color-ink);
}

.process-card__title {
	font-size: var(--fs-h3);
	margin-bottom: var(--space-2xs);
}

.process-card__text {
	font-size: var(--fs-body);
	color: var(--color-ink-muted);
	margin: 0;
}

/* ==========================================================================
   Seed grid + card
   ========================================================================== */
.seed-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 26rem));
	justify-content: center;
	gap: clamp(1.5rem, 3vw, 2.5rem);
}

.seed-card {
	position: relative;
}

.seed-card__link {
	display: block;
}

/* Product packshots are transparent cut-outs at ratio ~1.115. The frame
   is 10/9 (1.111, within 0.4% of native) and uses contain, not cover, so
   the packet is never sliced. The old 4/5 cover frame cropped 28% of the
   width and cut into the packet edges. */
.seed-card__figure {
	position: relative;
	aspect-ratio: 10 / 9;
	overflow: hidden;
	background: var(--color-surface);
	margin-bottom: var(--space-sm);
}

.seed-card__figure img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	padding: var(--space-2xs);
	transition: transform 0.9s var(--ease);
}

.seed-card:hover .seed-card__figure img,
.seed-card__link:focus-visible .seed-card__figure img {
	transform: scale(1.04);
}

/* Red wash that lifts on hover. */
.seed-card__figure::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(160deg, transparent 40%, rgba(229, 25, 42, 0.55) 100%);
	opacity: 0;
	transition: opacity var(--transition);
	pointer-events: none;
}

.seed-card:hover .seed-card__figure::after {
	opacity: 1;
}

.seed-card__placeholder {
	width: 100%;
	height: 100%;
	background: linear-gradient(160deg, var(--color-surface), var(--color-bg));
}

.seed-card__strain {
	position: absolute;
	top: var(--space-sm);
	left: var(--space-sm);
	z-index: 1;
	padding: 0.3rem 0.75rem;
	border-radius: var(--radius-pill);
	background: var(--color-accent);
	color: var(--color-ink);
	font-size: var(--fs-label);
	font-weight: 600;
	letter-spacing: var(--tracking-label);
	text-transform: uppercase;
}

.seed-card__body {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--space-sm);
	padding-top: var(--space-2xs);
	border-top: 1px solid var(--color-hairline);
}

.seed-card__title {
	font-size: clamp(1.5rem, 2.4vw, 2.25rem);
	margin: 0;
}

.seed-card__meta {
	margin: 0;
	font-family: var(--font-display);
	font-weight: 600;
	font-size: 1.25rem;
	color: var(--color-accent-text);
	white-space: nowrap;
}

/* ==========================================================================
   Page heads + archive
   ========================================================================== */
.page-head {
	/*
	 * Plain --space-xl. This used to add a further 3.5rem on top of the token,
	 * which is not clearance for anything: the header is sticky and therefore
	 * still in flow, so .page-head already starts below it. The addend just
	 * pushed every page down by an extra 56px.
	 */
	padding-top: var(--space-xl);
	padding-bottom: var(--space-lg);
}

/*
 * A .section straight after a .page-head would otherwise stack two blocks of
 * vertical padding — the head's --space-lg bottom plus the section's
 * --space-section top, 146px of dead space before the first real content.
 * The head's own bottom padding is the separation; the section adds nothing.
 */
.page-head + .section,
.page-head + .section--lg {
	padding-top: 0;
}

.page-head h1 {
	font-size: var(--fs-h1);
	margin: 0 0 var(--space-md);
	max-width: 16ch;
}

.archive-toolbar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-sm);
	margin-top: var(--space-lg);
	padding-top: var(--space-sm);
	border-top: 1px solid var(--color-hairline);
}

.archive-toolbar__count {
	margin: 0;
	font-size: var(--fs-body);
	color: var(--color-ink-muted);
}

.strain-filter select {
	appearance: none;
	background: transparent;
	color: var(--color-ink);
	border: 1px solid var(--color-line);
	border-radius: var(--radius-pill);
	padding: 0.6rem 2.75rem 0.6rem 1.25rem;
	font-size: var(--fs-body);
	cursor: pointer;
	background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
	background-position: calc(100% - 1.35rem) 55%, calc(100% - 1.05rem) 55%;
	background-size: 5px 5px, 5px 5px;
	background-repeat: no-repeat;
}

.strain-filter select:hover {
	border-color: var(--color-ink);
}

.archive-empty {
	color: var(--color-ink-muted);
	max-width: var(--measure);
}

.pagination {
	margin-top: var(--space-xl);
	padding-top: var(--space-md);
	border-top: 1px solid var(--color-hairline);
}

.pagination .nav-links {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2xs);
	justify-content: center;
}

.pagination .page-numbers {
	min-width: 2.75rem;
	min-height: 2.75rem;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding-inline: 0.75rem;
	border-radius: var(--radius-pill);
	font-size: var(--fs-body);
	color: var(--color-ink-muted);
	transition: background-color var(--transition-fast), color var(--transition-fast);
}

.pagination .page-numbers:hover {
	background: rgba(255, 255, 255, 0.1);
	color: var(--color-ink);
}

.pagination .page-numbers.current {
	background: var(--color-accent);
	color: var(--color-ink);
}

/* ==========================================================================
   Single seed
   ==========================================================================
   The featured image appears exactly once, full-bleed at the top. The main
   column carries the written content and the gallery only.
   ========================================================================== */
.seed-hero {
	position: relative;
	display: flex;
	align-items: flex-end;
	min-height: min(78svh, 46rem);
	padding-top: calc(var(--space-xl) + 4rem);
	padding-bottom: var(--space-lg);
	overflow: hidden;
	background: var(--color-bg-alt);
}

.seed-hero__media {
	position: absolute;
	inset: 0;
	z-index: 0;
}

.seed-hero__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	filter: grayscale(0.6) contrast(1.1) brightness(0.8);
}

.seed-hero__media::after {
	content: "";
	position: absolute;
	inset: 0;
	background:
		linear-gradient(0deg, var(--color-bg) 3%, rgba(13, 13, 13, 0.4) 45%, transparent 75%),
		linear-gradient(115deg, rgba(229, 25, 42, 0.5) 0%, transparent 65%);
}

.seed-hero--textonly {
	min-height: auto;
	padding-top: calc(var(--space-xl) + 3rem);
}

.seed-hero__inner {
	position: relative;
	z-index: 1;
	width: 100%;
}

.seed-hero h1 {
	font-size: var(--fs-h1);
	margin: 0;
	max-width: 14ch;
}

.spec-chips {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-sm) var(--space-lg);
	margin-top: var(--space-md);
	padding-top: var(--space-sm);
	border-top: 1px solid var(--color-line);
}

.spec-chip {
	display: flex;
	flex-direction: column;
	gap: 0.1rem;
}

.spec-chip__label {
	font-size: var(--fs-label);
	letter-spacing: var(--tracking-label);
	text-transform: uppercase;
	color: var(--color-ink-muted);
}

.spec-chip__value {
	font-family: var(--font-display);
	font-weight: 700;
	font-size: 1.75rem;
	line-height: 1;
	text-transform: uppercase;
}

.seed-layout {
	display: grid;
	gap: var(--space-xl);
	align-items: start;
}

@media (min-width: 64rem) {
	.seed-layout {
		grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
	}

	.seed-layout__aside {
		position: sticky;
		top: 7rem;
	}
}

.seed-gallery {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
	gap: var(--space-sm);
	margin-bottom: var(--space-lg);
}

.seed-gallery__item {
	margin: 0;
	aspect-ratio: 10 / 9;
	overflow: hidden;
	background: var(--color-surface);
}

.seed-gallery__item img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	padding: var(--space-sm);
}

.specs {
	margin: 0 0 var(--space-lg);
	border-top: 1px solid var(--color-line);
}

.specs__row {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--space-sm);
	padding: var(--space-xs) 0;
	border-bottom: 1px solid var(--color-hairline);
}

.specs__key {
	margin: 0;
	font-size: var(--fs-label);
	letter-spacing: var(--tracking-label);
	text-transform: uppercase;
	color: var(--color-ink-muted);
}

.specs__value {
	margin: 0;
	text-align: right;
	font-weight: 500;
}

.seed-cta {
	padding: var(--space-md);
	border: 1px solid var(--color-hairline);
	background: var(--color-surface);
}

.seed-cta p {
	font-size: var(--fs-body);
	color: var(--color-ink-muted);
	margin-bottom: var(--space-sm);
}

/* ==========================================================================
   Prose
   ========================================================================== */
.prose {
	max-width: var(--measure);
	color: var(--color-ink-muted);
}

.prose > * + * {
	margin-top: var(--space-sm);
}

.prose h2,
.prose h3 {
	color: var(--color-ink);
	margin-top: var(--space-lg);
}

.prose h2 {
	font-size: var(--fs-h3);
}

.prose a:not(.btn) {
	color: var(--color-ink);
	border-bottom: 1px solid var(--color-accent);
}

.prose a:not(.btn):hover {
	color: var(--color-accent-text);
}

.prose blockquote {
	margin: var(--space-lg) 0;
	padding-left: var(--space-md);
	border-left: 2px solid var(--color-accent);
	font-family: var(--font-display);
	font-size: var(--fs-h3);
	text-transform: uppercase;
	color: var(--color-ink);
}

/* ==========================================================================
   Contact
   ========================================================================== */
.contact-layout {
	display: grid;
	gap: var(--space-xl);
	align-items: start;
}

@media (min-width: 64rem) {
	.contact-layout {
		grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
	}
}

.contact-methods {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-sm);
	margin-top: var(--space-lg);
}

.contact-direct {
	margin: 0;
	font-size: var(--fs-body);
	color: var(--color-ink-muted);
}

.contact-direct a {
	color: var(--color-ink);
	border-bottom: 1px solid var(--color-accent);
}

.contact-form__field {
	margin-bottom: var(--space-sm);
}

.contact-form__field label {
	display: block;
	font-size: var(--fs-label);
	letter-spacing: var(--tracking-label);
	text-transform: uppercase;
	color: var(--color-ink-muted);
	margin-bottom: var(--space-2xs);
}

.contact-form input[type="text"],
.contact-form input[type="email"],
.contact-form textarea {
	width: 100%;
	padding: 0.85rem 0;
	background: transparent;
	color: var(--color-ink);
	border: 0;
	border-bottom: 1px solid var(--color-line);
	border-radius: 0;
	transition: border-color var(--transition-fast);
}

.contact-form input:focus,
.contact-form textarea:focus {
	border-bottom-color: var(--color-accent);
	outline: none;
}

.contact-form textarea {
	resize: vertical;
	min-height: 8rem;
}

.contact-form__hp {
	position: absolute !important;
	left: -9999px;
}

.form-message {
	padding: var(--space-sm) var(--space-md);
	border-left: 2px solid;
	margin-bottom: var(--space-md);
	font-size: var(--fs-body);
}

.form-message--success {
	border-color: #5f9e57;
	background: rgba(95, 158, 87, 0.1);
}

.form-message--error {
	border-color: var(--color-accent);
	background: rgba(229, 25, 42, 0.12);
}

/* ==========================================================================
   Age gate
   ========================================================================== */
body.age-gate-open {
	overflow: hidden;
}

.age-gate {
	position: fixed;
	inset: 0;
	z-index: 1000;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--container-pad);
	background: var(--color-overlay);
	transition: opacity var(--transition);
}

.age-gate--dismissed {
	opacity: 0;
	pointer-events: none;
}

.age-gate__panel {
	width: min(36rem, 100%);
	padding: clamp(2rem, 5vw, 3.5rem);
	background: var(--color-surface);
	border: 1px solid var(--color-hairline);
	text-align: center;
}

.age-gate__title {
	font-size: clamp(2rem, 5vw, 3.25rem);
	margin-bottom: var(--space-sm);
}

.age-gate__text {
	color: var(--color-ink-muted);
	margin-bottom: var(--space-lg);
}

.age-gate__actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--space-sm);
	margin-bottom: var(--space-md);
}

.age-gate__legal {
	margin: 0;
	font-size: 0.75rem;
	line-height: 1.6;
	color: var(--color-ink-muted);
}

@media (max-width: 30rem) {
	.age-gate__actions .btn {
		width: 100%;
	}
}

/* ==========================================================================
   Footer
   ========================================================================== */
.site-footer {
	border-top: 1px solid var(--color-hairline);
	background: var(--color-bg);
}

.footer-cta {
	padding-block: var(--space-section-lg) var(--space-section);
	text-align: center;
}

.footer-cta h2 {
	font-size: var(--fs-h1);
	margin-bottom: var(--space-md);
}

.footer-cta__lead {
	color: var(--color-ink-muted);
	max-width: 44ch;
	margin-inline: auto;
	margin-bottom: var(--space-md);
}

.footer-cta__email {
	display: inline-block;
	font-family: var(--font-display);
	font-weight: 700;
	font-size: clamp(1.5rem, 3.5vw, 2.75rem);
	line-height: 1;
	letter-spacing: var(--tracking-display);
	text-transform: uppercase;
	color: var(--color-ink);
	border-bottom: 2px solid var(--color-accent);
	padding-bottom: 0.3rem;
	transition: color var(--transition-fast);
}

.footer-cta__email:hover {
	color: var(--color-accent-text);
}

.site-footer__cols {
	display: grid;
	gap: var(--space-lg);
	padding-block: var(--space-lg);
	border-top: 1px solid var(--color-hairline);
}

@media (min-width: 48rem) {
	.site-footer__cols {
		grid-template-columns: 1fr auto;
		align-items: start;
		gap: var(--space-xl);
	}
}

.site-footer__nav-list {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-sm) var(--space-md);
}

.site-footer__nav-list a {
	font-size: var(--fs-body);
	font-weight: 500;
	text-transform: uppercase;
	color: var(--color-ink-muted);
	transition: color var(--transition-fast);
}

.site-footer__nav-list a:hover {
	color: var(--color-ink);
}

.age-disclaimer {
	font-size: 0.75rem;
	line-height: 1.7;
	color: var(--color-ink-muted);

	/* Span every track of .site-footer__cols, gap included, so the block is
	   exactly as wide as the hairline rule above it. Without this it sat in
	   the 1fr track only and stopped 96px short even with the cap removed —
	   the grid reserves its column gap whether or not a footer nav exists. */
	grid-column: 1 / -1;

	/* The --measure cap is gone, but at 0.75rem a single column across the
	   full 1350px would run to roughly 195 characters, which is genuinely
	   unreadable. Flowing into columns of --measure keeps each line at the
	   line near its original measure while the block itself fills the full
	   width. 22rem is chosen so three columns fit at desktop widths; columns
	   expand to fill, so a larger value yields fewer, longer lines.
	   column-width (not column-count) means this collapses to one column on
	   narrow screens by itself. */
	column-width: 22rem;
	column-gap: var(--space-lg);
}

.copyright {
	margin: 0;
	font-size: var(--fs-body);
	color: var(--color-ink-muted);
	padding-bottom: var(--space-lg);
}

/* The oversized closing wordmark banner. */
.wordmark-banner {
	overflow: hidden;
	background: var(--color-accent);
	color: var(--color-on-accent);
	padding-block: clamp(1.5rem, 4vw, 3rem);
}

.wordmark-banner .marquee {
	width: 100%;
	margin-left: 0;
	transform: none;
	border: 0;
	background: transparent;
}

.wordmark-banner .marquee__item {
	font-size: clamp(3rem, 9vw, 9rem);
	padding-inline: 1.5rem;
}

.wordmark-banner .marquee__star {
	color: var(--color-on-accent);
	font-size: clamp(1.5rem, 4vw, 4rem);
}

/* Optional line under the wordmark, used by the About page's closing banner. */
.wordmark-banner__sublabel {
	margin: clamp(0.5rem, 1.5vw, 1.25rem) 0 0;
	padding-inline: var(--container-pad);
	text-align: center;
	font-family: var(--font-body);
	font-size: var(--fs-label);
	font-weight: 600;
	letter-spacing: 0.34em;
	text-transform: uppercase;
	color: var(--color-on-accent);
}

/* ==========================================================================
   About page
   ==========================================================================
   Long-form editorial copy. Three passage types carry the rhythm, and they
   are deliberately distinct from one another:

     .about-body     — ordinary prose, capped at the reading measure.
     .about-lines    — a stanza of short lines, one thought per line, set
                       larger and lighter than the prose around it.
     .about-lines--statement — the closing couplets, in the display face, so
                       a section ends on a beat rather than trailing off.
     .about-lines--staccato  — the tight single-word runs, set to be read
                       fast down the page.

   The stanzas use <br> inside one <p> rather than a stack of separate
   paragraphs: it is one sentence-group semantically, and it keeps the breaks
   with CSS disabled.
   ========================================================================== */
.about-title {
	max-width: 20ch;
}

.about-section + .about-section {
	margin-top: var(--space-xl);
	padding-top: var(--space-lg);
	border-top: 1px solid var(--color-hairline);
}

.about-section__title {
	font-size: var(--fs-h1);
	margin: 0 0 var(--space-md);
	max-width: 16ch;
}

.about-statement {
	max-width: 24ch;
}

.about-body {
	max-width: var(--measure);
	color: var(--color-ink-muted);
}

.about-body p {
	margin: 0 0 var(--space-sm);
}

.about-body p:last-child {
	margin-bottom: 0;
}

/* --- Stanzas ------------------------------------------------------------- */
.about-lines {
	margin: var(--space-lg) 0 0;
	font-size: clamp(1.15rem, 2vw, 1.75rem);
	font-weight: 400;
	/*
	 * Tighter than body copy so the lines group as a block, but loose enough
	 * that a line which wraps on a narrow screen still separates from the next.
	 */
	line-height: 1.32;
	color: var(--color-ink);
	text-wrap: balance;
}

/*
 * Each line becomes a block so it can carry its own spacing. The <br> stays in
 * the markup and is hidden here: with CSS off the spans go back to being
 * inline and the <br> is what preserves the breaks.
 *
 * The spacing matters most on narrow screens. A line long enough to wrap —
 * "The expression that makes you stop and smell twice." — would otherwise be
 * separated from the next line by nothing but leading, making a wrap
 * indistinguishable from an intended break and flattening the stanza back into
 * a paragraph, which is exactly what this treatment exists to avoid.
 */
.about-lines__line {
	display: block;
}

.about-lines br {
	display: none;
}

/* Not `span + span`: the <br> sits between them and breaks adjacency. */
.about-lines__line:not(:first-child) {
	margin-top: 0.18em;
}

.about-lines--statement .about-lines__line:not(:first-child) {
	margin-top: 0.06em;
}

.about-lines--staccato .about-lines__line:not(:first-child) {
	margin-top: 0.02em;
}

@media (max-width: 47.99rem) {
	.about-lines__line:not(:first-child) {
		margin-top: 0.6em;
	}

	.about-lines--statement .about-lines__line:not(:first-child) {
		margin-top: 0.2em;
	}

	.about-lines--staccato .about-lines__line:not(:first-child) {
		margin-top: 0.06em;
	}
}

.about-lines + .about-body,
.about-lines + .about-list,
.about-body + .about-lines {
	margin-top: var(--space-lg);
}

/* Closing couplets: display face, so a section lands rather than fades out. */
.about-lines--statement {
	font-family: var(--font-display);
	font-weight: 600;
	font-size: var(--fs-h2);
	line-height: 1.08;
	letter-spacing: var(--tracking-display);
	text-transform: uppercase;
}

/* The single-word runs. Tight leading is the point — these read as a list of
   variables, not as sentences. */
.about-lines--staccato {
	font-family: var(--font-display);
	font-weight: 600;
	font-size: clamp(1.5rem, 3.2vw, 2.5rem);
	line-height: 1.06;
	letter-spacing: var(--tracking-display);
	text-transform: uppercase;
	color: var(--color-ink);
}

/* --- The standard list --------------------------------------------------- */
/*
 * Hairline-separated rows rather than bullets: the section's own claim is
 * that quality is "a system", and a ruled stack reads that way. Markers are
 * removed rather than restyled so nothing hangs into the left margin.
 */
.about-list {
	margin: var(--space-lg) 0 0;
	padding: 0;
	list-style: none;
	max-width: var(--measure);
}

.about-list li {
	padding: var(--space-sm) 0;
	border-top: 1px solid var(--color-hairline);
	font-size: var(--fs-lead);
	line-height: var(--lh-body);
	color: var(--color-ink-muted);
}

.about-list li:last-child {
	border-bottom: 1px solid var(--color-hairline);
}

/* --- Section CTA --------------------------------------------------------- */
.about-links {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-md);
	margin: var(--space-lg) 0 0;
}

/* ==========================================================================
   Reveal system + the has-gsap handshake
   ==========================================================================
   Three layers share these rules:
     - no JS: the <noscript> block in header.php forces everything visible;
     - main.js alone: an IntersectionObserver adds .is-visible;
     - motion.js: sets html.has-gsap and drives the same elements with
       ScrollTrigger instead.

   The bug this must never reintroduce (audit L5): hero copy hidden by CSS
   under html.has-gsap that ONLY the GSAP timeline could reveal, so any
   stall left the headline permanently invisible. Two guarantees:
     1. html.motion-failed — set by main.js when has-gsap appeared but
        motion.js never confirmed with html.motion-active — force-reveals
        everything;
     2. .is-visible always wins, whichever layer applied it.
   Both are !important so no later rule can trap content again.
   ========================================================================== */
.reveal {
	opacity: 0;
	transform: translateY(1.5rem);
	transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
}

.reveal.is-visible {
	opacity: 1;
	transform: none;
}

html.has-gsap .reveal {
	transition: none;
}

html.has-gsap .hero__reveal {
	opacity: 0;
}

html.motion-failed .reveal,
html.motion-failed .hero__reveal,
html.motion-failed .split-char,
.reveal.is-visible,
.hero__reveal.is-visible,
.split-char.is-visible {
	opacity: 1 !important;
	visibility: visible !important;
	transform: none !important;
}

.split-char {
	display: inline-block;
	will-change: transform, opacity;
}

/* ==========================================================================
   404
   ========================================================================== */
.error-404 {
	padding-block: calc(var(--space-xl) + 4rem) var(--space-xl);
	text-align: center;
}

.error-404 h1 {
	font-size: var(--fs-display);
}

.error-404 .lead {
	margin-inline: auto;
	margin-bottom: var(--space-lg);
}

/* ==========================================================================
   Small utilities
   ========================================================================== */

/* Accent word inside a display heading — a red block of type, not italic. */
.u-accent {
	color: var(--color-accent-text);
}

/* Strain type label on a single seed hero. */
.seed-hero__strain {
	color: var(--color-accent-text);
}

/* ==========================================================================
   Single-seed hero — type-led band
   ==========================================================================
   The featured image no longer sits behind this band. Product shots are
   transparent studio packshots at ratio ~1.115; stretching one across a
   ~2.6:1 full-bleed band cropped 57% of its height and then buried the
   remainder under the gradient. The packet now appears at full size in the
   media frames below, and the band is type on black with a red field —
   the same language as the section heads elsewhere.
   ========================================================================== */
.seed-hero--type {
	min-height: 0;
	padding-top: calc(var(--space-xl) + 3.5rem);
	padding-bottom: var(--space-lg);
	background:
		radial-gradient(ellipse 55% 120% at 88% 50%, rgba(229, 25, 42, 0.28), transparent 70%),
		linear-gradient(180deg, var(--color-bg-alt) 0%, var(--color-bg) 100%);
	border-bottom: 1px solid var(--color-hairline);
}

.seed-hero--type h1 {
	font-size: clamp(2.75rem, 8vw, 7rem);
	max-width: 18ch;
}

/* Product media frames sit a little apart from the copy above them. */
.seed-gallery {
	margin-top: var(--space-md);
}

/* ==========================================================================
   Single-seed image slider
   ==========================================================================
   One image at a time, arrows + dots, swipe on touch. Sharp corners, black
   surface, red active states — same language as the rest of the theme.

   No-JS behaviour matters here: without main.js the track stays a
   horizontally scrollable, scroll-snapping strip, so every image is still
   reachable. initSeedSlider() switches it to transform-based paging and
   turns the native scrolling off.
   ========================================================================== */
.seed-slider {
	position: relative;
	margin-top: var(--space-md);
	background: var(--color-surface);
	border: 1px solid var(--color-hairline);
}

.seed-slider__viewport {
	overflow-x: auto;
	overflow-y: hidden;
	scroll-snap-type: x mandatory;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: none;
}

.seed-slider__viewport::-webkit-scrollbar {
	display: none;
}

/* Once JS takes over, paging is done with a transform instead. */
.seed-slider.is-enhanced .seed-slider__viewport {
	overflow: hidden;
	scroll-snap-type: none;
}

.seed-slider__track {
	display: flex;
	margin: 0;
	padding: 0;
	list-style: none;
}

.seed-slider.is-enhanced .seed-slider__track {
	transition: transform 0.5s var(--ease);
	will-change: transform;
}

.seed-slider.is-dragging .seed-slider__track {
	transition: none;
}

.seed-slider__slide {
	flex: 0 0 100%;
	min-width: 0;
	scroll-snap-align: center;
	aspect-ratio: 10 / 9;
	display: flex;
	align-items: center;
	justify-content: center;
}

.seed-slider__slide img {
	width: 100%;
	height: 100%;
	/* contain, never cover: these are transparent packshots and the whole
	   packet has to stay visible. */
	object-fit: contain;
	padding: var(--space-md);
	user-select: none;
	-webkit-user-drag: none;
}

/* --- Arrows -------------------------------------------------------------- */
.seed-slider__nav {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 3rem;
	height: 3rem;
	padding: 0;
	background: rgba(13, 13, 13, 0.72);
	color: var(--color-ink);
	border: 1px solid var(--color-hairline);
	border-radius: 0;
	font-size: 1.1rem;
	line-height: 1;
	cursor: pointer;
	transition: background-color var(--transition-fast), border-color var(--transition-fast);
}

.seed-slider__nav:hover,
.seed-slider__nav:focus-visible {
	background: var(--color-accent);
	border-color: var(--color-accent);
}

.seed-slider__nav--prev {
	left: var(--space-sm);
}

.seed-slider__nav--next {
	right: var(--space-sm);
}

/* Arrows are a JS affordance — without it the strip scrolls natively. */
.seed-slider__nav {
	display: none;
}

.seed-slider.is-enhanced .seed-slider__nav {
	display: flex;
}

/* --- Dots ---------------------------------------------------------------- */
.seed-slider__dots {
	display: flex;
	justify-content: center;
	gap: 0.4rem;
	padding: 0 var(--space-sm) var(--space-sm);
}

.seed-slider__dot {
	width: 2.25rem;
	height: 3px;
	padding: 0;
	background: rgba(255, 255, 255, 0.25);
	border: 0;
	border-radius: 0;
	cursor: pointer;
	transition: background-color var(--transition-fast);
}

.seed-slider__dot:hover {
	background: rgba(255, 255, 255, 0.5);
}

.seed-slider__dot.is-active {
	background: var(--color-accent);
}

@media (max-width: 47.9375rem) {
	.seed-slider__nav {
		width: 2.5rem;
		height: 2.5rem;
	}

	.seed-slider__nav--prev {
		left: var(--space-2xs);
	}

	.seed-slider__nav--next {
		right: var(--space-2xs);
	}

	.seed-slider__slide img {
		padding: var(--space-sm);
	}
}

/* The global prefers-reduced-motion rule in style.css already collapses the
   track transition; this makes the intent explicit at the component level. */
@media (prefers-reduced-motion: reduce) {
	.seed-slider.is-enhanced .seed-slider__track {
		transition: none;
	}
}

/* ==========================================================================
   Flavour profile — quick-scan pills in the seed hero
   ==========================================================================
   Sits with the THC/CBD/flowering chips because it is scanned the same way.
   Outlined rather than filled so it reads as a secondary band under the
   solid spec figures, and so a long list never becomes a wall of red.
   ========================================================================== */
.flavor-profile {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-xs) var(--space-sm);
	margin-top: var(--space-sm);
}

.flavor-profile__label {
	font-size: var(--fs-label);
	letter-spacing: var(--tracking-label);
	text-transform: uppercase;
	color: var(--color-ink-muted);
}

.flavor-profile__list {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.flavor-tag {
	padding: 0.3rem 0.85rem;
	border: 1px solid var(--color-accent);
	border-radius: var(--radius-pill);
	background: rgba(229, 25, 42, 0.12);
	color: var(--color-ink);
	font-size: var(--fs-label);
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	white-space: nowrap;
}

/* ==========================================================================
   Lineage notes — standalone prose block
   ========================================================================== */
.lineage {
	margin-top: var(--space-xl);
	padding-top: var(--space-lg);
	border-top: 1px solid var(--color-hairline);
}

.lineage__title {
	font-size: var(--fs-h2);
	margin: 0 0 var(--space-sm);
	max-width: 18ch;
}

.lineage__body {
	/* No --measure cap here on purpose. The hairline rule on .lineage spans
	   the full 752px content column, and the 62ch cap stopped this prose
	   179px short of it, which read as a ragged right edge under the rule.
	   Matching the rule wins over the ideal measure: at 16px this runs to
	   about 94 characters, which is long but acceptable for a block of two
	   or three short paragraphs. */
	color: var(--color-ink-muted);
}

.lineage__body p {
	margin: 0 0 var(--space-sm);
}

.lineage__body p:last-child {
	margin-bottom: 0;
}

/* ==========================================================================
   Single-seed lede
   ==========================================================================
   Scoped to the seed page on purpose — the archive, contact and 404 pages
   share the generic .lead and should keep the larger intro size.

   Size: stepped down from --fs-lead (20px) to --fs-body (16px). It sits
   directly above the image slider and was competing with the H1 for weight.
   --fs-body is the floor here: the next token down (--fs-label, 12px) is a
   caption size and would read as smaller than the body copy it introduces.

   Width: .lead caps itself at --measure (62ch = ~717px), but the column it
   lives in is 752px, so the lede's right edge sat 36px short of the slider
   directly beneath it — the visible misalignment. Dropping the cap lets it
   fill the column so both right edges land on the same pixel.

   Trade-off, deliberately taken: at full column width the measure runs
   longer than the 45–75ch ideal. Acceptable for a two-line intro, and the
   smaller font size claws some of it back. Do NOT copy this to long-form
   prose — .lineage__body keeps its --measure cap for that reason.
   ========================================================================== */
.seed-lede {
	font-size: var(--fs-body);
	max-width: none;
}

/* Fade-only reveal: no vertical travel, for elements that must hold their
   position. The single-seed lede uses this because the specs sidebar
   beside it never moves vertically, so any drop-in put the two column tops
   visibly out of line for the length of the animation. This rule covers
   the no-GSAP / IntersectionObserver path; motion.js checks the same class. */
.reveal--fade {
	transform: none;
}

/* Optical alignment of the lede against the specs sidebar.
   ------------------------------------------------------------------------
   With the drop-in animation removed, both column boxes now start on the
   same pixel. But the sidebar opens with a 1px rule sitting exactly on its
   box top, while the lede opens with text — and glyphs sit 8.4px into their
   line box at 16px/1.55 (4.4px half-leading + 4px from em-box top to cap
   height in Inter Tight). So the rule still read as sitting above the text.

   Pulling the lede up by that amount puts the cap-height of the first line
   flush with the rule opposite. Expressed in em so it tracks the font size.
   Desktop only: below 64rem the columns stack and there is nothing to align
   against, so the natural spacing is left alone. */
@media (min-width: 64rem) {
	.seed-lede {
		margin-top: -0.525em;
	}
}

/* ==========================================================================
   Parents genealogy page
   ==========================================================================
   Two renderings of one dataset. The radial chart is desktop-only; the
   expandable cross list carries the same information below 64rem. See the
   header of page-parents.php for why that split exists.
   ========================================================================== */

/* --- Radial chart (>= 64rem only) --------------------------------------- */
.parents-radial {
	display: none;
}

.parents-family {
	display: block;
}

/*
 * The chart needs 80rem, not the 64rem the rest of the theme switches on.
 * Type inside an SVG scales with the viewBox, and a third ring pushed that
 * viewBox to 2800 units wide: at a 1024px viewport the labels rendered at
 * ~11px, too small to read. Rather than shrink the diagram's content to fit a
 * small laptop, the breakpoint moved out — 1024-1280px now gets the list,
 * which carries the same information and is genuinely easier to read there.
 */
@media (min-width: 80rem) {
	.parents-radial {
		display: block;
	}

	.parents-family {
		display: none;
	}
}

.parents-radial__stage {
	position: relative;
	/*
	 * Sized off available width alone. An earlier version capped this at 100vh
	 * so the whole ring sat within one screen, which cost the diagram most of
	 * its presence on a laptop — a spacious chart the page scrolls to reads
	 * better than a small one that fits.
	 */
	max-width: 72rem;
	margin-inline: auto;
	/*
	 * Makes the stage a query container so the centre readout can be sized in
	 * cqw and scale with the ring instead of staying at a fixed rem size and
	 * shrinking away inside it. Each cqw rule below is preceded by a rem
	 * declaration, which is what older engines fall back to.
	 */
	container-type: inline-size;
}

.parents-radial__svg {
	display: block;
	width: 100%;
	height: auto;
	overflow: visible;
}

/* --- Guide rings --------------------------------------------------------- */
.parents-radial__guides circle {
	fill: none;
	stroke: rgba(255, 255, 255, 0.08);
	stroke-width: 1;
}

/* --- Connecting lines ---------------------------------------------------- */
.parents-radial__edge {
	fill: none;
	stroke: rgba(255, 255, 255, 0.2);
	stroke-width: 1.5;
	transition: stroke 0.28s ease, stroke-width 0.28s ease, opacity 0.28s ease;
}

.parents-radial.is-focused .parents-radial__edge {
	opacity: 0.1;
}

.parents-radial.is-focused .parents-radial__edge.is-lit {
	opacity: 1;
	stroke: var(--color-accent);
	stroke-width: 3;
}

/* --- Nodes --------------------------------------------------------------- */
.parents-radial__node {
	cursor: pointer;
	transition: opacity 0.28s ease;
}

.parents-radial.is-focused .parents-radial__node {
	opacity: 0.18;
}

.parents-radial.is-focused .parents-radial__node.is-lit {
	opacity: 1;
}

.parents-radial__node:focus {
	outline: none;
}

.parents-radial__node:focus-visible .parents-radial__box,
.parents-radial__node:focus-visible .parents-radial__tick,
.parents-radial__node:focus-visible .parents-radial__pill {
	stroke: var(--color-ink);
	stroke-width: 2;
}

/*
 * Three rings, three shapes — the shape says how much data is behind a node:
 * filled pill = a strain you can open, outlined box = a parent with a lineage
 * and flavours, bare text = a name-only lineage component.
 */

/* Parent: an outlined box with the name inside. The solid fill matters — the
   grandparent connectors pass beneath it and must not show through. */
.parents-radial__box {
	fill: var(--color-bg);
	stroke: rgba(255, 255, 255, 0.4);
	stroke-width: 1.5;
	transition: stroke 0.28s ease;
}

.parents-radial__node--parent.is-lit .parents-radial__box,
.parents-radial__node--parent:hover .parents-radial__box {
	stroke: var(--color-accent);
}

.parents-radial__parent-name {
	font-family: var(--font-display);
	font-weight: 600;
	/* In viewBox units, so it scales with the chart. Paired with the box-width
	   formula in redwood_get_parent_radial_layout(). */
	font-size: 32px;
	text-transform: uppercase;
	letter-spacing: 0.01em;
	fill: var(--color-ink);
}

/* Grandparent: a tick on the ring and a name. No box, because there is
   nothing behind it to open. */
.parents-radial__tick {
	fill: var(--color-ink-muted);
	transition: fill 0.28s ease;
}

.parents-radial__node--grand.is-lit .parents-radial__tick,
.parents-radial__node--grand:hover .parents-radial__tick {
	fill: var(--color-accent);
}

.parents-radial__grand-name {
	font-family: var(--font-body);
	font-weight: 500;
	font-size: 30px;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	fill: var(--color-ink-muted);
	transition: fill 0.28s ease;
}

.parents-radial__node--grand.is-lit .parents-radial__grand-name,
.parents-radial__node--grand:hover .parents-radial__grand-name {
	fill: var(--color-ink);
}

/* Child: a filled pill on the inner ring. */
.parents-radial__pill {
	fill: var(--color-accent);
	stroke: var(--color-accent);
	stroke-width: 1.5;
	transition: fill 0.28s ease;
}

.parents-radial__node--child.is-source .parents-radial__pill,
.parents-radial__node--child:hover .parents-radial__pill {
	fill: var(--color-bg);
}

.parents-radial__child-name {
	font-family: var(--font-display);
	font-weight: 700;
	/* Paired with the pill-width formula in redwood_get_parent_radial_layout(). */
	font-size: 32px;
	text-transform: uppercase;
	letter-spacing: 0.01em;
	fill: var(--color-ink);
}

/* --- Centre readout ------------------------------------------------------ */
/*
 * Parked in the dead space inside the inner ring, so reading a node's details
 * does not pull the eye away from the diagram. Sized as a share of the stage
 * so it tracks the circle as the chart scales.
 */
.parents-radial__detail {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 21%;
	transform: translate(-50%, -50%);
	text-align: center;
	pointer-events: none;
}

.parents-radial__kind {
	margin: 0 0 0.6rem;
	font-size: var(--fs-label);
	font-size: clamp(0.6rem, 1.05cqw, 0.9rem);
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--color-accent-text);
}

.parents-radial__title,
.parents-radial__count {
	margin: 0;
	font-family: var(--font-display);
	font-weight: 700;
	font-size: 1.5rem;
	font-size: clamp(1.1rem, 2.4cqw, 2.1rem);
	line-height: 1.1;
	text-transform: uppercase;
	color: var(--color-ink);
}

.parents-radial__lineage {
	margin: 0.6rem 0 0;
	font-size: 0.95rem;
	font-size: clamp(0.8rem, 1.35cqw, 1.2rem);
	color: var(--color-accent-text);
}

.parents-radial__hint {
	margin: 0.7rem 0 0;
	font-size: var(--fs-label);
	font-size: clamp(0.6rem, 1.05cqw, 0.9rem);
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--color-ink-muted);
}

.parents-radial__flavors {
	justify-content: center;
	margin-top: 0.9rem;
}

.parents-radial__flavors .flavor-tag {
	font-size: 0.7rem;
	font-size: clamp(0.62rem, 1.02cqw, 0.95rem);
	padding: 0.25em 0.7em;
}

.parents-radial__go {
	margin: 0.9rem 0 0;
	font-size: var(--fs-label);
	font-size: clamp(0.6rem, 1.05cqw, 0.9rem);
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

/*
 * The highlight is a state change, not an animation — with reduced motion the
 * same information appears, it just arrives instantly.
 */
@media (prefers-reduced-motion: reduce) {
	.parents-radial__edge,
	.parents-radial__node,
	.parents-radial__box,
	.parents-radial__tick,
	.parents-radial__grand-name,
	.parents-radial__pill {
		transition: none;
	}
}

/* --- Mobile + no-JS: the crosses as an expandable list ------------------- */
.parents-family {
	margin: 0;
	padding: 0;
	list-style: none;
	border-top: 1px solid var(--color-hairline);
}

.parents-family__item {
	border-bottom: 1px solid var(--color-hairline);
}

.parents-family__summary {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
	padding: var(--space-sm) 2rem var(--space-sm) 0;
	cursor: pointer;
	list-style: none;
	position: relative;
}

.parents-family__summary::-webkit-details-marker {
	display: none;
}

/* A plus that becomes a minus — no icon font, no inline SVG. */
.parents-family__summary::after {
	content: '+';
	position: absolute;
	right: 0;
	top: 50%;
	transform: translateY(-50%);
	font-size: 1.5rem;
	line-height: 1;
	color: var(--color-accent-text);
}

.parents-family__details[open] .parents-family__summary::after {
	content: '−';
}

.parents-family__name {
	font-family: var(--font-display);
	font-weight: 700;
	font-size: var(--fs-h3);
	text-transform: uppercase;
	color: var(--color-ink);
}

.parents-family__cross {
	font-size: 0.9rem;
	color: var(--color-accent-text);
}

.parents-family__body {
	padding-bottom: var(--space-md);
}

.parents-family__parent {
	padding: var(--space-sm) 0;
	border-top: 1px solid var(--color-hairline);
}

.parents-family__parent-name {
	margin: 0;
	font-family: var(--font-display);
	font-weight: 600;
	font-size: 1.05rem;
	text-transform: uppercase;
	color: var(--color-ink);
}

.parents-family__parent-lineage {
	margin: 0.15rem 0 0;
	font-size: 0.85rem;
	color: var(--color-accent-text);
}

.parents-family__parent-bio {
	margin: 0.6rem 0 0;
	font-size: 0.9rem;
	line-height: var(--lh-body);
	color: var(--color-ink-muted);
}

.parents-family__parent .flavor-profile__list {
	margin-top: 0.75rem;
}

.parents-family__link {
	display: inline-flex;
	align-items: center;
	min-height: 2.75rem;
	margin-top: var(--space-sm);
}

/* Privacy link beside the copyright line (footer.php). */
.copyright__sep {
	margin-inline: 0.5em;
	color: var(--color-hairline);
}

.copyright .privacy-policy-link {
	color: var(--color-ink-muted);
	border-bottom: 1px solid var(--color-hairline);
	transition: color var(--transition-fast), border-color var(--transition-fast);
}

.copyright .privacy-policy-link:hover,
.copyright .privacy-policy-link:focus-visible {
	color: var(--color-ink);
	border-bottom-color: var(--color-accent);
}

/* Homepage statement: link through to the full About page. */
.statement__more {
	margin: var(--space-md) 0 0;
}

/* Strain copy written as a code comment (single-seed.php) — kept as code. */
.seed-lede--code {
	margin: 0;
	padding: var(--space-sm) var(--space-md);
	border-left: 2px solid var(--color-accent);
	background: var(--color-surface);
	overflow-x: auto;
}

.seed-lede--code code {
	font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
	font-size: 0.9rem;
	line-height: 1.7;
	color: var(--color-ink-muted);
	white-space: pre-wrap;
}
