/*
 * Base layer — reset, element defaults, focus treatment, motion policy.
 *
 * Everything here is unclassed: it styles elements, not components. If you find
 * yourself adding a class to this file, it probably belongs in components/.
 */

/* ─────────────────────────────────────────────────────────── reset ───── */

*,
*::before,
*::after {
	box-sizing: border-box;
}

* {
	margin: 0;
	padding: 0;
}

html {
	-webkit-text-size-adjust: 100%;
	text-size-adjust: 100%;
	scroll-behavior: smooth;
	/* Clears the fixed header when an in-page anchor is followed. */
	scroll-padding-top: 6rem;
}

body {
	min-height: 100dvh;
	background-color: var(--color-canvas);
	color: var(--color-ink);
	font-family: var(--font-sans);
	font-size: 1rem;
	line-height: 1.5;
	font-synthesis-weight: none;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	overflow-x: clip;
}

/* Display sizes need the width axis pulled in slightly and the weight up;
   at 100% width Archivo reads too wide to set large. */
h1,
h2,
h3,
h4,
h5,
h6 {
	font-family: var(--font-display);
	font-weight: 600;
	font-stretch: 96%;
	font-size: inherit;
	line-height: inherit;
}

p,
h1,
h2,
h3,
h4,
h5,
h6 {
	overflow-wrap: break-word;
}

ul,
ol {
	list-style: none;
}

img,
picture,
video,
canvas,
svg {
	display: block;
	max-width: 100%;
}

img {
	height: auto;
}

a {
	color: inherit;
	text-decoration: none;
}

button,
input,
select,
textarea {
	font: inherit;
	color: inherit;
	background: none;
	border: none;
	border-radius: 0;
}

button {
	cursor: pointer;
}

textarea {
	resize: vertical;
}

address {
	font-style: normal;
}

hr {
	border: 0;
	border-top: 1px solid var(--color-line);
}

fieldset {
	border: 0;
}

table {
	border-collapse: collapse;
}

/* ────────────────────────────────────────────────────── defaults ───── */

/* Every figure in the system aligns down a column. */
.font-mono,
[data-numeric],
table,
time {
	font-variant-numeric: tabular-nums;
}

::selection {
	background-color: var(--tpl-accent);
	color: var(--color-signal-dark);
}

:focus-visible {
	outline: 2px solid var(--color-signal);
	outline-offset: 2px;
}

[data-surface='dark'] :focus-visible {
	outline-color: var(--tpl-accent);
}

:where(a, button, summary) {
	-webkit-tap-highlight-color: transparent;
}

input[type='range'],
input[type='checkbox'],
input[type='radio'] {
	accent-color: var(--color-signal);
}

* {
	scrollbar-width: thin;
	scrollbar-color: var(--color-ink-4) transparent;
}

::-webkit-scrollbar {
	width: 10px;
	height: 10px;
}

::-webkit-scrollbar-track {
	background: transparent;
}

::-webkit-scrollbar-thumb {
	background-color: var(--color-ink-5);
	border: 3px solid var(--color-canvas);
}

::-webkit-scrollbar-thumb:hover {
	background-color: var(--color-ink-4);
}

/*
 * Motion policy. Every animated affordance is additive — the site is fully
 * usable with all of it switched off, and this block does exactly that.
 */
@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}

	[data-reveal] {
		opacity: 1 !important;
		transform: none !important;
		clip-path: none !important;
	}
}


/*
 * Disclosure, built on <details>/<summary>.
 *
 * Native semantics mean it works with JavaScript switched off and its contents
 * stay findable by the browser's own in-page search. The open/close animation
 * is a grid-template-rows transition, which needs no height measurement.
 */

.accordion {
	border-bottom: 1px solid var(--ink-10);
}

.accordion__summary {
	display: flex;
	cursor: pointer;
	list-style: none;
	align-items: center;
	justify-content: space-between;
	gap: 1.5rem;
	padding-block: 1.25rem;
	text-align: left;
}

.accordion__summary::-webkit-details-marker {
	display: none;
}

.accordion__title {
	font-family: var(--font-display);
	font-size: 1.0625rem;
	font-weight: 600;
	font-stretch: 96%;
	letter-spacing: -0.015em;
	color: var(--color-ink);
}

.accordion--warning .accordion__title {
	color: var(--color-danger);
}

/* A plus that rotates into a minus. Two absolutely positioned rules. */
.accordion__marker {
	position: relative;
	display: grid;
	place-items: center;
	width: 1.75rem;
	height: 1.75rem;
	flex: none;
	box-shadow: inset 0 0 0 1px var(--ink-12);
	transition:
		background-color var(--duration-calm) var(--ease-linear-out),
		box-shadow var(--duration-calm) var(--ease-linear-out);
}

.accordion[open] .accordion__marker {
	background-color: var(--color-ink);
	box-shadow: inset 0 0 0 1px var(--color-ink);
}

.accordion__marker::before,
.accordion__marker::after {
	content: '';
	position: absolute;
	background-color: var(--color-ink-2);
	transition:
		background-color var(--duration-calm) var(--ease-linear-out),
		transform var(--duration-calm) var(--ease-precise);
}

.accordion__marker::before {
	width: 0.75rem;
	height: 1px;
}

.accordion__marker::after {
	width: 1px;
	height: 0.75rem;
}

.accordion[open] .accordion__marker::before,
.accordion[open] .accordion__marker::after {
	background-color: #fff;
}

.accordion[open] .accordion__marker::after {
	transform: rotate(90deg);
}

/*
 * The body animates its own height. `<details>` only toggles display, so the
 * transition is carried by an inner grid whose single row grows from 0fr to 1fr.
 */
.accordion__body {
	display: grid;
	grid-template-rows: 0fr;
	transition: grid-template-rows 420ms var(--ease-precise);
}

.accordion[open] .accordion__body {
	grid-template-rows: 1fr;
}

.accordion__body-inner {
	overflow: hidden;
}

.accordion__content {
	padding-bottom: 1.5rem;
	padding-right: 2.5rem;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: var(--color-ink-2);
}

.accordion__content > * + * {
	margin-top: 0.75rem;
}


/*
 * Specimen tags — classification, stock state, order status, saving flags.
 *
 * Always monospace, always uppercase, always square. The tone carries the
 * meaning; the shape never changes.
 */

.badge {
	display: inline-flex;
	align-items: center;
	font-family: var(--font-mono);
	text-transform: uppercase;
	white-space: nowrap;
	border: 1px solid transparent;
}

/* ─────────────────────────────────────────────────────────── sizes ───── */

.badge--sm {
	height: 1.15rem;
	padding-inline: 0.375rem;
	font-size: 0.5625rem;
	letter-spacing: 0.14em;
}

.badge--md {
	height: 1.5rem;
	padding-inline: 0.5rem;
	font-size: 0.625rem;
	letter-spacing: 0.13em;
}

/* ────────────────────────────────────────────────────────── tones ───── */

.badge--neutral {
	background-color: var(--color-line);
	color: var(--color-ink-2);
}

.badge--forest {
	background-color: var(--color-ink);
	color: #fff;
}

.badge--moss {
	background-color: var(--color-canvas-2);
	color: var(--color-ink);
}

.badge--brass {
	background-color: var(--color-signal-tint);
	color: var(--color-signal-dark);
}

.badge--signal {
	background-color: var(--color-signal);
	color: #fff;
}

.badge--accent {
	background-color: var(--tpl-accent);
	color: var(--color-signal-dark);
}

.badge--outline {
	background-color: transparent;
	color: var(--color-ink-2);
	border-color: rgb(10 15 12 / 0.22);
}

.badge--outline-light {
	background-color: transparent;
	color: var(--paper-80);
	border-color: var(--paper-25);
}

.badge--danger {
	background-color: var(--color-danger-tint);
	color: var(--color-danger);
}

.badge--caution {
	background-color: var(--color-caution-tint);
	color: var(--color-caution);
}

.badge--affirm {
	background-color: var(--color-signal-tint);
	color: var(--color-signal);
}

/*
 * Flags that sit over a packshot. Same language as the badge, but sized by
 * padding rather than a fixed height so they hug short labels tightly.
 */
.flag {
	display: inline-block;
	padding: 0.25rem 0.5rem;
	font-family: var(--font-mono);
	font-size: 0.5625rem;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	white-space: nowrap;
}

.flag--sold-out {
	background-color: var(--color-ink);
	color: #fff;
}

.flag--accent {
	background-color: var(--tpl-accent);
	color: var(--color-signal-dark);
}

.flag--low-stock {
	border: 1px solid var(--ink-25);
	background-color: rgb(255 255 255 / 0.9);
	color: var(--color-ink-2);
}

.flag--signal {
	background-color: var(--color-signal);
	color: #fff;
}

.flag--outline {
	border: 1px solid var(--ink-20);
	color: var(--color-ink-2);
}


/*
 * The one button in the system.
 *
 * Use `<a class="button">` when it navigates and `<button class="button">` when
 * it acts — semantics follow behaviour, never appearance.
 *
 * Square corners, hairline borders, monospace label: a specimen tag rather than
 * a pill.
 *
 *   .button--primary       filled signal green. One per view, ideally.
 *   .button--secondary     ruled, ink type. The workhorse.
 *   .button--accent        yellow-green. The single thing that must be found.
 *   .button--ghost         borderless until hovered.
 *   .button--light         white on a dark surface.
 *   .button--outline-light ruled white on a dark surface.
 */

.button {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-family: var(--font-mono);
	text-transform: uppercase;
	letter-spacing: 0.14em;
	text-align: center;
	border: 1px solid transparent;
	transition:
		background-color 280ms var(--ease-precise),
		color 280ms var(--ease-precise),
		border-color 280ms var(--ease-precise),
		opacity 280ms var(--ease-precise);
}

.button:disabled,
.button[aria-disabled='true'] {
	cursor: not-allowed;
	opacity: 0.55;
}

/* ─────────────────────────────────────────────────────────── sizes ───── */

.button--sm {
	height: 2.25rem;
	padding-inline: 1rem;
	font-size: 0.625rem;
	gap: 0.5rem;
}

.button--md {
	height: 2.75rem;
	padding-inline: 1.5rem;
	font-size: 0.6875rem;
	gap: 0.625rem;
}

.button--lg {
	height: 3.5rem;
	padding-inline: 2rem;
	font-size: 0.75rem;
	gap: 0.75rem;
}

.button--full {
	width: 100%;
}

/* ────────────────────────────────────────────────────────── variants ───── */

.button--primary {
	background-color: var(--color-signal);
	color: #fff;
}

.button--primary:hover:not(:disabled) {
	background-color: var(--color-signal-dark);
}

.button--primary:disabled {
	background-color: var(--color-ink-4);
}

.button--secondary {
	background-color: transparent;
	color: var(--color-ink);
	border-color: var(--ink-25);
}

.button--secondary:hover:not(:disabled) {
	border-color: var(--ink-70);
	background-color: rgb(10 15 12 / 0.03);
}

.button--accent {
	background-color: var(--tpl-accent);
	color: var(--color-signal-dark);
}

.button--accent:hover:not(:disabled) {
	background-color: var(--tpl-accent-dark);
}

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

.button--ghost:hover:not(:disabled) {
	border-color: var(--ink-25);
}

.button--light {
	background-color: #fff;
	color: var(--color-ink);
}

.button--light:hover:not(:disabled) {
	background-color: var(--color-canvas-2);
}

.button--outline-light {
	background-color: transparent;
	color: #fff;
	border-color: var(--paper-30);
}

.button--outline-light:hover:not(:disabled) {
	border-color: var(--paper-80);
	background-color: rgb(255 255 255 / 0.06);
}

/* ────────────────────────────────────────────────────────── loading ───── */

/*
 * `aria-busy="true"` swaps the label for a spinner without changing the
 * button's measured width, so a row of buttons never reflows mid-submit.
 */
.button[aria-busy='true'] .button__label {
	visibility: hidden;
}

.button__spinner {
	display: none;
	position: absolute;
	inset: 0;
	place-items: center;
}

.button[aria-busy='true'] .button__spinner {
	display: grid;
}

.button__spinner::before {
	content: '';
	width: 0.875rem;
	height: 0.875rem;
	border: 1px solid currentColor;
	border-top-color: transparent;
	border-radius: 50%;
	opacity: 0.7;
	animation: spin 700ms linear infinite;
}

/* A row of buttons, wrapping on narrow screens. */
.button-row {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
}


/*
 * Site footer — newsletter, link columns, opening hours, regulatory small print.
 *
 * A single dark green field. `data-surface="dark"` on the element flips the
 * shared focus ring and hairline utilities to their light variants.
 */

.site-footer {
	position: relative;
	overflow: hidden;
	background-color: var(--color-signal);
	color: var(--paper-75);
}

/* ───────────────────────────────────────────────────── newsletter ───── */

.newsletter {
	display: grid;
	gap: 2.5rem;
	border-bottom: 1px solid var(--paper-10);
	padding-block: 4rem;
}

@media (width >= 64rem) {
	.newsletter {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 5rem;
		padding-block: 5rem;
	}

	/* Drops the form to sit level with the body copy rather than the headline. */
	.newsletter__form-column {
		padding-top: 3.5rem;
	}
}

.newsletter__title {
	margin-top: 1.25rem;
	color: #fff;
}

.newsletter__body {
	margin-top: 1.25rem;
	max-width: 28rem;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: var(--paper-60);
}

.newsletter__form {
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
}

@media (width >= 40rem) {
	.newsletter__form {
		flex-direction: row;
	}
}

.newsletter__input-wrap {
	flex: 1;
}

.newsletter__input {
	height: 3.5rem;
	width: 100%;
	border: 1px solid var(--paper-20);
	background-color: rgb(255 255 255 / 0.06);
	padding-inline: 1.5rem;
	font-size: 0.9375rem;
	color: #fff;
	transition: border-color var(--duration-calm) var(--ease-linear-out);
}

.newsletter__input::placeholder {
	color: var(--paper-60);
}

.newsletter__input:hover {
	border-color: rgb(255 255 255 / 0.35);
}

.newsletter__input:focus {
	outline: none;
	border-color: var(--color-line);
	box-shadow: 0 0 0 2px var(--paper-25);
}

.newsletter__note {
	margin-top: 0.875rem;
	font-size: 0.75rem;
	color: var(--paper-70);
}

.newsletter__confirmation {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	background-color: rgb(255 255 255 / 0.08);
	padding: 1.25rem 1.5rem;
	font-size: 0.9375rem;
	color: #fff;
}

.newsletter__confirmation svg {
	width: 1.25rem;
	height: 1.25rem;
	flex: none;
	color: var(--paper-60);
}

/* ─────────────────────────────────────────────────── link columns ───── */

.footer-columns {
	display: grid;
	gap: 3rem;
	padding-block: 4rem;
}

@media (width >= 48rem) {
	.footer-columns {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (width >= 64rem) {
	.footer-columns {
		grid-template-columns: repeat(6, minmax(0, 1fr));
		gap: 2rem;
	}

	.footer-columns__identity {
		grid-column: span 2;
	}
}

.footer-columns__description {
	margin-top: 1.5rem;
	max-width: 20rem;
	font-size: 0.875rem;
	line-height: 1.7;
	color: var(--paper-60);
}

.footer-columns__address {
	margin-top: 1.75rem;
	font-size: 0.875rem;
	line-height: 1.6;
	color: var(--paper-60);
}

.footer-columns__contact {
	margin-top: 1.25rem;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.375rem;
	font-size: 0.875rem;
	color: #fff;
}

.footer-column__heading {
	font-size: 0.6875rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.2em;
	color: var(--color-ink-4);
}

.footer-column__list {
	margin-top: 1.25rem;
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
}

.footer-column__link {
	font-size: 0.875rem;
	color: var(--paper-75);
	transition: color var(--duration-calm) var(--ease-linear-out);
}

.footer-column__link:hover {
	color: var(--tpl-accent);
}

/* ─────────────────────────────────────────────────── opening hours ───── */

.footer-hours {
	display: grid;
	gap: 2rem;
	border-top: 1px solid var(--paper-10);
	padding-block: 2.5rem;
}

@media (width >= 40rem) {
	.footer-hours {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (width >= 64rem) {
	.footer-hours {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

.footer-hours__slot {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
}

@media (width >= 40rem) {
	.footer-hours__slot {
		flex-direction: column;
		gap: 0.25rem;
	}
}

.footer-hours__days {
	font-size: 0.75rem;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--color-ink-4);
}

.footer-hours__time {
	font-size: 0.9375rem;
	color: #fff;
	font-variant-numeric: tabular-nums;
}

/* ─────────────────────────────────────────────────────── regulatory ───── */

.footer-legal {
	border-top: 1px solid var(--paper-10);
	padding-block: 2rem;
}

.footer-legal__statement {
	max-width: 56rem;
	font-size: 0.75rem;
	line-height: 1.7;
	color: var(--paper-80);
}

.footer-legal__meta {
	margin-top: 1.75rem;
	display: flex;
	flex-direction: column-reverse;
	align-items: flex-start;
	justify-content: space-between;
	gap: 1.25rem;
}

@media (width >= 40rem) {
	.footer-legal__meta {
		flex-direction: row;
		align-items: center;
	}
}

.footer-legal__copyright {
	font-size: 0.75rem;
	color: var(--color-ink-4);
}

.footer-legal__links {
	display: flex;
	align-items: center;
	gap: 1.5rem;
}

.footer-legal__link {
	font-size: 0.75rem;
	color: var(--paper-60);
	transition: color var(--duration-swift) var(--ease-linear-out);
}

.footer-legal__link:hover {
	color: #fff;
}


/*
 * Form controls.
 *
 * Text inputs use a floating label: it rests raised, and only drops back into
 * the control while the field is empty and unfocused. That is driven entirely
 * by `:placeholder-shown`, so it needs no JavaScript — but it does need a
 * placeholder to be present. A single space is enough, and every text input in
 * the template carries `placeholder=" "` for exactly this reason.
 *
 * Selects and textareas use a conventional label above the control, because a
 * select is never empty and a textarea is too tall for the label to travel.
 */

.field {
	display: block;
}

.field__control-wrap {
	position: relative;
}

/* Shared skin for every control. */
.field__control {
	width: 100%;
	border: 1px solid var(--ink-15);
	background-color: var(--color-surface);
	padding-inline: 1rem;
	font-size: 0.9375rem;
	color: var(--color-ink);
	transition:
		border-color var(--duration-calm) var(--ease-linear-out),
		box-shadow var(--duration-calm) var(--ease-linear-out);
}

.field__control::placeholder {
	color: transparent;
}

.field__control:hover {
	border-color: rgb(10 15 12 / 0.3);
}

.field__control:focus {
	outline: none;
	border-color: var(--color-signal);
	box-shadow: 0 0 0 2px rgb(7 42 29 / 0.15);
}

/* Text and select controls share a height; the input reserves room for the
   raised label by padding its top edge. */
.field__control--input,
.field__control--select {
	height: 3.5rem;
}

.field__control--input {
	padding-top: 1.75rem;
	padding-bottom: 0.5rem;
}

.field__control--select {
	appearance: none;
	padding-block: 0.75rem;
	padding-right: 2.5rem;
	cursor: pointer;
}

.field__control--textarea {
	padding-block: 0.875rem;
	resize: vertical;
	line-height: 1.6;
}

.field__chevron {
	pointer-events: none;
	position: absolute;
	right: 1rem;
	top: 50%;
	transform: translateY(-50%);
	width: 1rem;
	height: 1rem;
	color: var(--color-ink-3);
}

/* ─────────────────────────────────────────────────── floating label ───── */

.field__label-floating {
	pointer-events: none;
	position: absolute;
	left: 1rem;
	top: 0.375rem;
	transform-origin: top left;
	transform: scale(0.78);
	font-size: 0.9375rem;
	color: var(--color-ink-3);
	transition: all 280ms var(--ease-precise);
}

/* Rest state: centred in the control, at full size. */
.field__control--input:placeholder-shown + .field__label-floating {
	top: 50%;
	transform: translateY(-50%) scale(1);
}

/* Focus wins over the rest state, so it is declared last. */
.field__control--input:focus + .field__label-floating {
	top: 0.375rem;
	transform: scale(0.78);
	color: var(--color-signal);
}

/* Conventional label, above the control. */
.field__label {
	display: block;
	margin-bottom: 0.375rem;
	font-size: 0.8125rem;
	font-weight: 500;
	color: var(--color-ink-2);
}

.field__required {
	color: var(--color-danger);
}

/* ──────────────────────────────────────────────── hints and errors ───── */

.field__hint {
	margin-top: 0.375rem;
	font-size: 0.75rem;
	color: var(--color-ink-3);
}

.field__error {
	margin-top: 0.375rem;
	display: flex;
	align-items: center;
	gap: 0.375rem;
	font-size: 0.75rem;
	color: var(--color-danger);
}

.field__error svg {
	width: 0.875rem;
	height: 0.875rem;
	flex: none;
}

/* Invalid state. Driven by `aria-invalid`, the same attribute assistive
   technology reads, so the two can never disagree. */
.field__control[aria-invalid='true'] {
	border-color: var(--color-danger);
}

.field__control[aria-invalid='true']:focus {
	border-color: var(--color-danger);
	box-shadow: 0 0 0 2px rgb(200 50 26 / 0.2);
}

/* ──────────────────────────────────────────────────────── choices ───── */

.checkbox-row {
	display: flex;
	align-items: flex-start;
	gap: 0.75rem;
	cursor: pointer;
	font-size: 0.875rem;
	color: var(--color-ink-2);
}

.checkbox-row__box {
	margin-top: 0.25rem;
	width: 1rem;
	height: 1rem;
	flex: none;
}

/* A radio rendered as a selectable card — checkout's delivery/collection pair. */
.choice-card {
	display: block;
	cursor: pointer;
	border: 1px solid var(--color-line);
	padding: 1.25rem;
	transition: border-color var(--duration-swift) var(--ease-linear-out);
}

.choice-card:hover {
	border-color: rgb(10 15 12 / 0.4);
}

.choice-card:has(input:checked) {
	border-color: var(--color-signal);
	background-color: var(--color-surface);
}

.choice-card:has(input:focus-visible) {
	outline: 2px solid var(--color-signal);
	outline-offset: 2px;
}

.choice-card__title {
	display: block;
	font-size: 0.9375rem;
	font-weight: 600;
	color: var(--color-ink);
}

.choice-card__detail {
	display: block;
	margin-top: 0.25rem;
}

/* ────────────────────────────────────────────────────────── layout ───── */

/* Two-column form grid, collapsing to one on narrow screens. */
.form-grid {
	display: grid;
	gap: 1.25rem;
}

@media (width >= 40rem) {
	.form-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.form-grid__full {
		grid-column: 1 / -1;
	}
}

/* ───────────────────────────────────────────────── date &amp; time ───── */

/* Native date/time inputs already inherit .field__control — this just tints
   the built-in picker glyph to sit quietly until it's actually useful. */
.field__control--input[type='date']::-webkit-calendar-picker-indicator,
.field__control--input[type='time']::-webkit-calendar-picker-indicator {
	cursor: pointer;
	opacity: 0.6;
	transition: opacity var(--duration-swift) var(--ease-linear-out);
}

.field__control--input[type='date']:hover::-webkit-calendar-picker-indicator,
.field__control--input[type='time']:hover::-webkit-calendar-picker-indicator {
	opacity: 1;
}

/* Two linked date fields. js/forms.js sets each one's min/max off the
   other's value on change — pure enhancement, both fields work unwired. */
.date-range {
	display: flex;
	align-items: center;
	gap: 0.75rem;
}

.date-range .field {
	flex: 1;
	min-width: 0;
}

.date-range__sep {
	flex: none;
	margin-top: 1rem;
	color: var(--color-ink-4);
}

/* ────────────────────────────────────────────────────────── switch ───── */

/* A checkbox, semantically — <input type="checkbox"> underneath, styled as a
   track and thumb instead of a box. Pair it with .checkbox-row for the label. */
.switch-box {
	appearance: none;
	flex: none;
	margin-top: 0.125rem;
	width: 2.5rem;
	height: 1.375rem;
	border: 1px solid var(--ink-20);
	background-color: var(--color-canvas-2);
	position: relative;
	cursor: pointer;
	transition:
		background-color var(--duration-swift) var(--ease-linear-out),
		border-color var(--duration-swift) var(--ease-linear-out);
}

.switch-box::before {
	content: '';
	position: absolute;
	top: 1px;
	left: 1px;
	width: 1.125rem;
	height: 1.125rem;
	background-color: var(--color-surface);
	box-shadow: 0 1px 2px rgb(11 12 11 / 0.25);
	transition: transform var(--duration-swift) var(--ease-linear-out);
}

.switch-box:checked {
	background-color: var(--color-signal);
	border-color: var(--color-signal);
}

.switch-box:checked::before {
	transform: translateX(1.125rem);
}

.switch-box:focus-visible {
	outline: 2px solid var(--color-signal);
	outline-offset: 2px;
}

.switch-box:disabled {
	opacity: 0.4;
	cursor: not-allowed;
}

/* ─────────────────────────────────────────────────── password field ───── */

.field__control-wrap:has(.field__password-toggle) .field__control--input {
	padding-right: 2.75rem;
}

.field__password-toggle {
	position: absolute;
	right: 0.75rem;
	top: 50%;
	transform: translateY(-50%);
	display: grid;
	place-items: center;
	width: 1.75rem;
	height: 1.75rem;
	color: var(--color-ink-3);
	transition: color var(--duration-swift) var(--ease-linear-out);
}

.field__password-toggle:hover {
	color: var(--color-ink);
}

.field__password-toggle svg {
	width: 1.125rem;
	height: 1.125rem;
}

/* ───────────────────────────────────────────────── multi-select list ───── */

/* A checkbox list in a bordered, scrollable box — the same accessible
   semantics as a native <select multiple>, styleable and keyboard-navigable
   without fighting <option> rendering across browsers. */
.field__listbox {
	border: 1px solid var(--ink-15);
	background-color: var(--color-surface);
	max-height: 11rem;
	overflow-y: auto;
	padding-inline: 1rem;
}

.field__listbox .checkbox-row {
	padding-block: 0.625rem;
}

.field__listbox .checkbox-row + .checkbox-row {
	border-top: 1px solid var(--color-line);
}

/* ──────────────────────────────────────────────────────── range slider ───── */

.range-slider {
	appearance: none;
	width: 100%;
	height: 1.25rem;
	background: transparent;
	cursor: pointer;
}

.range-slider::-webkit-slider-runnable-track {
	height: 2px;
	background: var(--ink-20);
}

.range-slider::-moz-range-track {
	height: 2px;
	background: var(--ink-20);
}

.range-slider::-webkit-slider-thumb {
	appearance: none;
	margin-top: -0.6875rem;
	width: 1.25rem;
	height: 1.25rem;
	background-color: var(--color-signal);
	border: 2px solid var(--color-surface);
	box-shadow: 0 0 0 1px var(--color-signal);
	cursor: pointer;
	transition: background-color var(--duration-swift) var(--ease-linear-out);
}

.range-slider::-moz-range-thumb {
	width: 1.25rem;
	height: 1.25rem;
	border: 2px solid var(--color-surface);
	background-color: var(--color-signal);
	box-shadow: 0 0 0 1px var(--color-signal);
	border-radius: 0;
	cursor: pointer;
}

.range-slider:hover::-webkit-slider-thumb,
.range-slider:hover::-moz-range-thumb {
	background-color: var(--color-signal-bright);
}

.range-slider:focus-visible {
	outline: 2px solid var(--color-signal);
	outline-offset: 4px;
}

.range-slider:disabled {
	opacity: 0.4;
	cursor: not-allowed;
}

.range-slider__output {
	margin-top: 0.5rem;
	font-size: 0.8125rem;
	color: var(--color-ink-3);
}

/* ───────────────────────────────────────────────────────── file field ───── */

.field__control--file {
	display: block;
	width: 100%;
	border: 1px dashed var(--ink-20);
	background-color: var(--color-surface);
	padding: 1rem;
	font-size: 0.8125rem;
	color: var(--color-ink-3);
	cursor: pointer;
	transition: border-color var(--duration-swift) var(--ease-linear-out);
}

.field__control--file:hover {
	border-color: rgb(10 15 12 / 0.4);
}

.field__control--file:focus-visible {
	outline: 2px solid var(--color-signal);
	outline-offset: 2px;
}

.field__control--file::file-selector-button {
	margin-right: 1rem;
	border: 1px solid var(--color-signal);
	background-color: var(--color-signal);
	color: #fff;
	padding: 0.5rem 1rem;
	font-size: 0.8125rem;
	font-weight: 600;
	cursor: pointer;
	transition: background-color var(--duration-swift) var(--ease-linear-out);
}

.field__control--file::file-selector-button:hover {
	background-color: var(--color-signal-bright);
}

.field__file-name {
	margin-top: 0.5rem;
	font-size: 0.8125rem;
	color: var(--color-ink-2);
}

/* The confirmation panel a form is replaced by once it succeeds. */
.form-confirmation {
	border: 1px solid var(--color-signal);
	background-color: var(--color-surface);
	padding: 2rem;
}

.form-confirmation__title {
	margin-top: 1rem;
	color: var(--color-ink);
}

.form-confirmation__body {
	margin-top: 1rem;
	max-width: 32rem;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: var(--color-ink-2);
}


/*
 * Site header — fixed bar, wordmark, primary navigation, utilities, and the
 * two mega panels.
 *
 * The bar has two characters, switched by `.site-header--over-media`:
 *
 *   over media  transparent, light type. Set on pages whose first section is a
 *               full-bleed dark hero that runs underneath the header. js/header.js
 *               removes it once the page scrolls past the hero, or while a mega
 *               panel is open.
 *   resting     white, blurred, hairline-ruled, dark type. The default.
 *
 * The class and `<body data-full-bleed>` are a pair: header.js reads the body
 * attribute to decide whether the bar may go transparent at all, so a page that
 * ships the class without the attribute would have light type on a light
 * background until the first scroll — and no type at all with scripting off.
 * Add or remove the two together. Four pages carry them: the home page, about,
 * prescriptions and services.
 */

.skip-link {
	position: fixed;
	left: 1.25rem;
	top: 1.25rem;
	z-index: var(--z-skip);
	background-color: var(--color-ink);
	color: #fff;
	padding: 0.75rem 1.25rem;
	font-family: var(--font-mono);
	font-size: 0.6875rem;
	text-transform: uppercase;
	letter-spacing: 0.14em;
}

.site-header {
	position: fixed;
	inset-inline: 0;
	top: 0;
	z-index: var(--z-header);
	border-bottom: 1px solid var(--ink-12);
	background-color: rgb(255 255 255 / 0.92);
	backdrop-filter: blur(12px);
	transition:
		background-color var(--duration-slow) var(--ease-precise),
		border-color var(--duration-slow) var(--ease-precise);
}

.site-header--over-media {
	background-color: transparent;
	border-bottom-color: transparent;
	backdrop-filter: none;
}

.site-header__inner {
	margin-inline: 1.25rem;
}

.site-header__bar {
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: center;
	height: 4rem;
}

@media (width >= 64rem) {
	.site-header__inner {
		margin-inline: 1.75rem;
	}

	.site-header__bar {
		grid-template-columns: 1fr auto 1fr;
		height: 4.5rem;
	}
}

/* ─────────────────────────────────────────────────────── wordmark ───── */

.logo {
	display: inline-flex;
	align-items: center;
	gap: 0.625rem;
	justify-self: start;
}

.logo__mark {
	display: grid;
	place-items: center;
	width: 1.5rem;
	height: 1.5rem;
	flex: none;
	background-color: var(--color-signal);
	color: #fff;
	font-size: 0.6875rem;
	font-weight: 600;
	line-height: 1;
	letter-spacing: -0.01em;
}

.logo__name {
	font-size: 0.8125rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.18em;
	color: var(--color-ink);
}

/* Light tone — over dark media, and in the footer. */
.logo--light .logo__mark {
	background-color: #fff;
	color: var(--color-ink);
}

.logo--light .logo__name {
	color: #fff;
}

.site-header--over-media .logo__mark {
	background-color: #fff;
	color: var(--color-ink);
}

.site-header--over-media .logo__name {
	color: #fff;
}

/* ───────────────────────────────────────────── the navigation link ───── */

/*
 * One link treatment across the whole bar: mono, uppercase, letterspaced. The
 * three tones (resting, active, over-media) differ only in colour.
 */
.nav-link {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	font-family: var(--font-mono);
	font-size: 0.6875rem;
	text-transform: uppercase;
	letter-spacing: 0.16em;
	color: var(--color-ink-3);
	transition: color var(--duration-calm) var(--ease-linear-out);
}

.nav-link:hover,
.nav-link[aria-current='page'],
.nav-link[aria-expanded='true'] {
	color: var(--color-ink);
}

.nav-link__icon {
	width: 1rem;
	height: 1rem;
	flex: none;
}

.site-header--over-media .nav-link {
	color: var(--paper-70);
}

.site-header--over-media .nav-link:hover,
.site-header--over-media .nav-link[aria-current='page'],
.site-header--over-media .nav-link[aria-expanded='true'] {
	color: #fff;
}

/* The bag link is always at full strength — it carries a count. */
.nav-link--emphasis {
	color: var(--color-ink);
}

.site-header--over-media .nav-link--emphasis {
	color: #fff;
}

/* ────────────────────────────────────────────── primary navigation ───── */

.primary-nav {
	display: none;
}

@media (width >= 64rem) {
	.primary-nav {
		display: flex;
		align-items: center;
		gap: 2rem;
		justify-self: center;
	}
}

/* ────────────────────────────────────────────────────── utilities ───── */

.header-tools {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 1.25rem;
}

/* Search and Account collapse away on the narrowest screens. */
.header-tools__optional {
	display: none;
}

@media (width >= 40rem) {
	.header-tools__optional {
		display: inline-flex;
	}
}

/* ──────────────────────────────────────────────────────────── bag ───── */

.bag {
	position: relative;
}

.bag__icon-wrap {
	position: relative;
	display: inline-flex;
}

.bag__count {
	position: absolute;
	right: -0.375rem;
	top: -0.375rem;
	display: grid;
	place-items: center;
	height: 0.9rem;
	min-width: 0.9rem;
	padding-inline: 0.25rem;
	background-color: var(--tpl-accent);
	color: var(--color-signal-dark);
	font-size: 0.5rem;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

/*
 * Hover preview. A convenience only — the bag itself is a plain link to
 * cart.html, so nothing here is reachable by hovering alone.
 */
.bag__preview {
	position: absolute;
	right: 0;
	top: 100%;
	width: 20rem;
	border: 1px solid var(--color-line);
	background-color: var(--color-surface);
	padding: 1rem;
	box-shadow: var(--shadow-card);
	animation: drop-in 200ms var(--ease-precise) both;
}

/* Pointer-driven, so it never appears on touch devices. */
@media (hover: none) {
	.bag__preview {
		display: none !important;
	}
}

.bag__lines {
	margin-top: 1rem;
	max-height: 16rem;
	overflow-y: auto;
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
}

.bag__line {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 0.75rem;
	font-size: 0.8125rem;
}

.bag__line-name {
	color: var(--color-ink-2);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.bag__line-quantity {
	font-family: var(--font-mono);
	font-variant-numeric: tabular-nums;
}

.bag__line-total {
	flex: none;
	font-family: var(--font-mono);
	color: var(--color-ink);
	font-variant-numeric: tabular-nums;
}

.bag__subtotal {
	margin-top: 1rem;
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	border-top: 1px solid var(--color-line);
	padding-top: 0.75rem;
	font-size: 0.875rem;
	color: var(--color-ink-2);
}

.bag__subtotal-value {
	font-family: var(--font-mono);
	font-weight: 600;
	color: var(--color-ink);
	font-variant-numeric: tabular-nums;
}

.bag__actions {
	margin-top: 1rem;
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 0.5rem;
}

/* ────────────────────────────────────────────────── menu toggle ───── */

.menu-toggle {
	position: relative;
	width: 1.5rem;
	height: 1rem;
	color: var(--color-ink);
}

@media (width >= 64rem) {
	.menu-toggle {
		display: none;
	}
}

.site-header--over-media .menu-toggle {
	color: #fff;
}

.menu-toggle__bar {
	position: absolute;
	left: 0;
	display: block;
	width: 100%;
	height: 1px;
	background-color: currentColor;
	transition: all 420ms var(--ease-precise);
}

.menu-toggle__bar:first-child {
	top: 0.25rem;
}

.menu-toggle__bar:last-child {
	top: calc(100% - 0.25rem);
}

.menu-toggle[aria-expanded='true'] .menu-toggle__bar:first-child {
	top: 50%;
	transform: rotate(45deg);
}

.menu-toggle[aria-expanded='true'] .menu-toggle__bar:last-child {
	top: 50%;
	transform: rotate(-45deg);
}

/* ───────────────────────────────────────────────────── mega panel ───── */

.mega-panel {
	display: none;
	position: absolute;
	inset-inline: 0;
	top: 100%;
	border-block: 1px solid var(--ink-12);
	background-color: #fff;
	animation: drop-in 280ms var(--ease-precise) both;
}

/* Pointer-driven and wide — never opened on small screens. */
@media (width >= 64rem) {
	.mega-panel[data-open] {
		display: block;
	}
}

.mega-panel__inner {
	margin-inline: 1.75rem;
	padding-block: 3rem;
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	column-gap: 2rem;
}

.mega-panel__heading {
	grid-column: span 2;
}

/*
 * The ruled index of categories.
 *
 * Rows deliberately stretch to fill the panel — its height is set by the taller
 * "Selected" column beside it, and that spare height is what opens up the space
 * beneath each category name. Do not add `align-content: start` here.
 */
.mega-index {
	grid-column: span 6;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	column-gap: 2rem;
}

.mega-index--wide {
	grid-column: span 10;
	grid-template-columns: repeat(3, minmax(0, 1fr));
}

.mega-index__item {
	border-bottom: 1px solid var(--ink-10);
}

.mega-index__link {
	display: flex;
	align-items: baseline;
	gap: 1rem;
	padding-block: 0.75rem;
}

.mega-index__name {
	font-family: var(--font-display);
	font-size: 1.25rem;
	font-weight: 600;
	font-stretch: 96%;
	letter-spacing: -0.01em;
	color: var(--color-ink);
	transition: opacity var(--duration-calm) var(--ease-linear-out);
}

.mega-index__link:hover .mega-index__name {
	opacity: 0.55;
}

/* Services entries carry a summary line under the name. */
.mega-index__link--stacked {
	display: block;
	padding-block: 1rem;
}

.mega-index__row {
	display: flex;
	align-items: baseline;
	gap: 0.75rem;
}

.mega-index__summary {
	margin-top: 0.5rem;
	padding-left: 2rem;
	font-size: 0.8125rem;
	line-height: 1.6;
	color: var(--color-ink-3);
}

/* Two featured packshots at the right edge of the shop panel. */
.mega-featured {
	grid-column: span 4;
}

.mega-featured__grid {
	margin-top: 1.25rem;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 1rem;
}

.mega-featured__image {
	transition: opacity var(--duration-slow) var(--ease-linear-out);
}

.mega-featured__link:hover .mega-featured__image {
	opacity: 0.8;
}

.mega-featured__item-no {
	margin-top: 0.75rem;
	font-family: var(--font-mono);
	font-size: 0.625rem;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--color-ink-3);
}

.mega-featured__name {
	margin-top: 0.25rem;
	font-size: 0.8125rem;
	line-height: 1.35;
	color: var(--color-ink);
}

.mega-featured__price {
	margin-top: 0.25rem;
	font-family: var(--font-mono);
	font-size: 0.6875rem;
	color: var(--color-ink-3);
	font-variant-numeric: tabular-nums;
}

/* "+2 more" under a truncated preview list. */
.bag__more {
	margin-top: 0.5rem;
}

/*
 * No scripting: keep the resting bar.
 *
 * The transparent character depends on js/header.js handing the bar back to
 * resting once the hero has scrolled away. With scripting off that never
 * happens, so light type would carry on over the light content below and the
 * whole bar would disappear. A solid header over the hero is a small
 * aesthetic loss next to an unreadable one.
 *
 * Written as an override rather than by wrapping the rules above in
 * `scripting: enabled`, so a browser that doesn't know the feature simply
 * behaves as it always did instead of losing the treatment entirely.
 */
@media (scripting: none) {
	.site-header--over-media {
		background-color: rgb(255 255 255 / 0.92);
		border-bottom-color: var(--ink-12);
		backdrop-filter: blur(12px);
	}

	.site-header--over-media .logo__mark {
		background-color: var(--color-signal);
		color: #fff;
	}

	.site-header--over-media .logo__name {
		color: var(--color-ink);
	}

	.site-header--over-media .nav-link {
		color: var(--color-ink-3);
	}

	.site-header--over-media .nav-link:hover,
	.site-header--over-media .nav-link[aria-current='page'],
	.site-header--over-media .nav-link[aria-expanded='true'],
	.site-header--over-media .nav-link--emphasis {
		color: var(--color-ink);
	}

	.site-header--over-media .menu-toggle {
		color: var(--color-ink);
	}
}

/* ──────────────────────────────────────── the free edition's navigation ───
 *
 * Added by build.js when it assembles the free edition. The nav items with no
 * page behind them go nowhere, and the one link that does leave is the one
 * that says where to. Not part of the full template, which has every page
 * these name and needs none of this.
 */

/* Stood down: no page behind them, no store either. Still legible — these name
   the pages the full edition has, which is the point of leaving them in the bar.

   They keep the pointer. An <a> with no href gets the arrow cursor by default,
   and on a demo that reads as a broken link rather than a deliberate one: the
   whole bar is here to be looked at, and half of it feeling dead underfoot is
   worse than half of it going nowhere quietly. */
.nav-link--inert,
a.nav-link--inert:hover {
	color: var(--color-ink-3);
	cursor: pointer;
	opacity: 0.5;
}

/* Everything else the rewrite reached: mega-panel rows, footer columns, journal
   cards, body buttons. Undimmed, so they still show the component off — and
   still feel like the thing they look like. */
[data-inert] {
	cursor: pointer;
}

.site-header--over-media .nav-link--inert,
.site-header--over-media a.nav-link--inert:hover {
	color: var(--paper-70);
}

/* The one live link in the bar. A pill rather than accent text: #cdeb3f is
   bright enough to carry on the dark over-media header and far too light to
   read as text on the white one, and this link has to work on both. */
.nav-link--upgrade {
	background: var(--tpl-accent);
	color: var(--color-signal-dark);
	padding: 0.45em 0.85em;
	border-radius: 2px;
	transition: background var(--duration-calm) var(--ease-linear-out);
}

.nav-link--upgrade:hover,
.site-header--over-media .nav-link--upgrade:hover {
	background: var(--tpl-accent-dark);
	color: var(--color-signal-dark);
}

.site-header--over-media .nav-link--upgrade {
	color: var(--color-signal-dark);
}


/*
 * Imagery.
 *
 * Every photograph in the template sits inside a `.plate` — a box with a fixed
 * aspect ratio, so space is reserved before the file decodes and nothing on the
 * page shifts as it arrives. Set the ratio inline where it differs from the
 * default:  <div class="plate" style="--plate-ratio: 4 / 5">
 */

.plate {
	position: relative;
	overflow: hidden;
	background-color: var(--color-canvas-2);
	aspect-ratio: var(--plate-ratio, 4 / 5);
}

.plate > img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Packshots are photographed on white; the plate should match. */
.plate--lit {
	background-color: #fff;
}

/* Fills its parent instead of imposing a ratio — for hero backdrops. */
.plate--fill {
	aspect-ratio: auto;
	height: 100%;
	width: 100%;
}

/* ─────────────────────────────────────────────────── media banner ───── */

/*
 * The full-bleed photographic masthead used by About, Services and
 * Prescriptions. The header draws over the top of it, so the copy is anchored
 * to the bottom edge.
 */
.media-banner {
	position: relative;
	height: 52svh;
	min-height: 20rem;
	width: 100%;
	overflow: hidden;
}

.media-banner--tall {
	height: 58svh;
}

/* Legibility wash. Deep enough to carry white display type at any size. */
.media-banner__wash {
	position: absolute;
	inset: 0;
	background-color: rgb(4 27 18 / 0.72);
}

.media-banner__content {
	position: absolute;
	inset-inline: 0;
	bottom: 0;
	padding-bottom: 3rem;
}

.media-banner__title {
	margin-top: 1.25rem;
	max-width: 48rem;
	color: #fff;
}

.media-banner__title--wide {
	max-width: 56rem;
}

/* ─────────────────────────────────────────────────────── figures ───── */

.figure-caption {
	margin-top: 0.875rem;
	font-family: var(--font-mono);
	font-size: var(--text-data);
	color: var(--color-ink-3);
}


/*
 * The two full-screen overlays: the mobile menu and site search.
 *
 * Both share a shape — a scrim that closes on click, and a panel that drops
 * from the top edge — so the scrim and dialog rules are written once and the
 * differences are kept to the panel itself.
 *
 * Both are plain markup in the page, hidden with the `hidden` attribute and
 * shown by js/overlays.js. Focus is trapped inside the panel while it is open.
 */

.overlay {
	position: fixed;
	inset: 0;
	z-index: var(--z-overlay);
}

.overlay--nav {
	z-index: var(--z-rail);
}

/* The mobile menu has no purpose at desktop widths. */
@media (width >= 64rem) {
	.overlay--nav {
		display: none;
	}
}

.overlay__scrim {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	cursor: default;
	background-color: rgb(10 15 12 / 0.35);
	backdrop-filter: blur(4px);
	animation: fade-in 260ms var(--ease-linear-out) both;
}

.overlay--search .overlay__scrim {
	background-color: rgb(10 15 12 / 0.45);
}

.overlay__panel {
	position: absolute;
	inset-inline: 0;
	top: 0;
	max-height: 100dvh;
	overflow-y: auto;
	background-color: var(--color-surface);
	box-shadow: var(--shadow-raised);
	animation: drop-in 420ms var(--ease-precise) both;
}

/* Clears the fixed header, which stays visible above the menu. */
.overlay--nav .overlay__panel {
	padding-top: 5.5rem;
	padding-bottom: 2.5rem;
}

/* ─────────────────────────────────────────────────────── mobile nav ───── */

.mobile-nav__link {
	display: flex;
	align-items: center;
	justify-content: space-between;
	border-bottom: 1px solid var(--ink-08);
	padding-block: 1rem;
	font-family: var(--font-display);
	font-size: var(--text-h2);
	line-height: var(--leading-h2);
	font-weight: 600;
	font-stretch: 96%;
	letter-spacing: -0.02em;
	color: var(--color-ink);
	/* Each row arrives a beat after the one above it; --row-index is set inline. */
	animation: rise-in 420ms var(--ease-linear-out) both;
	animation-delay: calc(90ms + var(--row-index, 0) * 45ms);
}

.mobile-nav__chevron {
	width: 1rem;
	height: 1rem;
	color: var(--color-ink-4);
}

.mobile-nav__section {
	animation: rise-in 420ms var(--ease-linear-out) 320ms both;
}

.mobile-nav__heading {
	margin-top: 2.25rem;
}

.mobile-nav__chips {
	margin-top: 1rem;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}

.mobile-nav__footer {
	margin-top: 2.25rem;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.75rem;
	border-top: 1px solid var(--ink-08);
	padding-top: 1.75rem;
	font-size: 0.875rem;
	color: var(--color-ink-2);
}

/*
 * The soft chip used for categories and search suggestions. Square, like
 * everything else — the fill is what marks it as tappable.
 */
.chip {
	display: inline-flex;
	background-color: var(--color-canvas-2);
	padding: 0.5rem 1rem;
	font-size: 0.8125rem;
	color: var(--color-ink);
	transition: background-color var(--duration-swift) var(--ease-linear-out);
}

.chip:hover {
	background-color: var(--color-ink-5);
}

/* ──────────────────────────────────────────────────── search overlay ───── */

.overlay--search .overlay__panel {
	padding-block: 2rem;
}

@media (width >= 40rem) {
	.overlay--search .overlay__panel {
		padding-block: 3rem;
	}
}

.search-field {
	position: relative;
	margin-top: 1.25rem;
	display: flex;
	align-items: center;
	gap: 1rem;
	border-bottom: 1px solid var(--ink-15);
	padding-bottom: 1rem;
	transition: border-color var(--duration-swift) var(--ease-linear-out);
}

.search-field:focus-within {
	border-bottom-color: var(--color-ink-2);
}

.search-field__icon {
	width: 1.25rem;
	height: 1.25rem;
	flex: none;
	color: var(--color-ink-3);
}

.search-field__input {
	width: 100%;
	background: transparent;
	font-family: var(--font-display);
	font-size: var(--text-h2);
	font-weight: 600;
	font-stretch: 96%;
	letter-spacing: -0.02em;
	color: var(--color-ink);
}

.search-field__input::placeholder {
	color: var(--color-ink-4);
}

.search-field__input:focus {
	outline: none;
}

.search-field__close {
	flex: none;
	padding: 0.5rem;
	color: var(--color-ink-3);
	transition: color var(--duration-swift) var(--ease-linear-out);
}

.search-field__close:hover {
	color: var(--color-ink);
}

.search-results {
	margin-top: 1.25rem;
	display: grid;
	column-gap: 2rem;
	row-gap: 0.5rem;
}

@media (width >= 40rem) {
	.search-results {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

.search-result__link {
	display: flex;
	align-items: center;
	gap: 1rem;
	padding: 0.5rem;
	transition: background-color var(--duration-calm) var(--ease-linear-out);
}

.search-result__link:hover {
	background-color: var(--color-canvas-2);
}

.search-result__thumb {
	width: 3.5rem;
	flex: none;
	overflow: hidden;
}

.search-result__text {
	min-width: 0;
	flex: 1;
}

.search-result__name {
	font-family: var(--font-display);
	font-size: 0.9375rem;
	font-weight: 600;
	font-stretch: 96%;
	color: var(--color-ink);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.search-result__subtitle {
	font-size: 0.8125rem;
	color: var(--color-ink-3);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.search-result__price {
	flex: none;
	font-size: 0.875rem;
	color: var(--color-ink-2);
	font-variant-numeric: tabular-nums;
}

.search-empty {
	margin-top: 2rem;
	font-size: 0.9375rem;
	color: var(--color-ink-3);
}

.search-suggestions {
	margin-top: 2rem;
	display: grid;
	gap: 2rem;
}

@media (width >= 40rem) {
	.search-suggestions {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

.search-suggestions__chips {
	margin-top: 1rem;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}

.search-suggestions__links {
	margin-top: 1rem;
	display: flex;
	flex-wrap: wrap;
	column-gap: 1.25rem;
	row-gap: 0.5rem;
	font-size: 0.875rem;
	color: var(--color-ink-2);
}

.search-results-block {
	margin-top: 2rem;
}


/*
 * Pager.
 *
 * Previous / position / next, on a rule. Shown by whatever is doing the paging
 * — js/pager.js for plain lists, js/shop-filters.js on the shop, where paging
 * has to survive a filter change — and hidden when there is only one page.
 *
 * The markup is three children and no wrapper logic, so it works the same
 * whether a script is driving it or a server rendered it with real links.
 */

.pager {
	margin-top: 3rem;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	border-top: 1px solid var(--color-line);
	padding-top: 1.5rem;
}

.pager__step {
	border: 1px solid var(--ink-20);
	padding: 0.625rem 1.25rem;
	font-family: var(--font-mono);
	font-size: 0.6875rem;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--color-ink);
	transition: border-color var(--duration-swift) var(--ease-linear-out);
}

.pager__step:hover:not(:disabled) {
	border-color: var(--ink-70);
}

.pager__step:disabled {
	opacity: 0.35;
	cursor: not-allowed;
}

.pager__position {
	font-family: var(--font-mono);
	font-size: 0.75rem;
	color: var(--color-ink-3);
}


/*
 * Product tile.
 *
 * Framed like a dispensing label: a ruled header carrying the catalogue number
 * and legal classification, the packshot on a lit plate, then the clinical
 * detail. The tile lifts on hover and an accent rule draws across the top, so
 * the card reads as an object rather than a bare image.
 */

.product-card {
	position: relative;
	display: flex;
	height: 100%;
	flex-direction: column;
	border: 1px solid var(--color-line);
	background-color: var(--color-surface);
	transition:
		border-color 420ms var(--ease-precise),
		box-shadow 420ms var(--ease-precise),
		transform 420ms var(--ease-precise);
}

.product-card:hover {
	transform: translateY(-0.25rem);
	border-color: var(--ink-25);
	box-shadow: var(--shadow-card);
}

/* Accent rule, drawn on hover. */
.product-card::before {
	content: '';
	position: absolute;
	inset-inline: 0;
	top: -1px;
	z-index: 10;
	height: 3px;
	background-color: var(--tpl-accent);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform 420ms var(--ease-precise);
}

.product-card:hover::before {
	transform: scaleX(1);
}

.product-card__link {
	display: flex;
	flex: 1;
	flex-direction: column;
}

/* ─────────────────────────────────────────────────── label header ───── */

.product-card__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.75rem;
	border-bottom: 1px solid var(--color-line);
	padding: 0.625rem 1rem;
}

.product-card__classification {
	font-family: var(--font-mono);
	font-size: 0.5625rem;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--color-ink-3);
}

/* ─────────────────────────────────────────────────────────── plate ───── */

.product-card__plate {
	position: relative;
	overflow: hidden;
	background-color: #fff;
}

.product-card__image {
	transition: transform 900ms var(--ease-precise);
}

.product-card:hover .product-card__image {
	transform: scale(1.04);
}

/* Flags, stacked at the top-left of the plate. */
.product-card__flags {
	pointer-events: none;
	position: absolute;
	left: 0.75rem;
	top: 0.75rem;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.375rem;
}

.product-card__advice {
	pointer-events: none;
	position: absolute;
	right: 0.75rem;
	top: 0.75rem;
	background-color: var(--color-signal);
	color: var(--tpl-accent);
	padding: 0.25rem 0.5rem;
	font-family: var(--font-mono);
	font-size: 0.5625rem;
	text-transform: uppercase;
	letter-spacing: 0.14em;
}

/* ────────────────────────────────────────────────────────── detail ───── */

.product-card__body {
	display: flex;
	flex: 1;
	flex-direction: column;
	padding: 1rem;
}

.product-card__name {
	font-size: 0.9375rem;
	font-weight: 600;
	line-height: 1.35;
	letter-spacing: -0.012em;
	color: var(--color-ink);
}

.product-card__ingredient {
	margin-top: 0.375rem;
	color: var(--color-signal);
}

.product-card__specification {
	margin-top: 0.125rem;
	padding-bottom: 1rem;
	color: var(--color-ink-4);
}

.product-card__price-row {
	margin-top: auto;
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 0.75rem;
	border-top: 1px solid var(--color-line);
	padding-top: 0.75rem;
}

.product-card__price {
	font-family: var(--font-mono);
	font-size: 0.9375rem;
	color: var(--color-ink);
	font-variant-numeric: tabular-nums;
}

.product-card__compare-price {
	font-family: var(--font-mono);
	font-size: 0.75rem;
	color: var(--color-ink-4);
	text-decoration: line-through;
	font-variant-numeric: tabular-nums;
}

/* ────────────────────────────────────────────────────────── add ───── */

/*
 * Always rendered, never hover-gated — a keyboard user has to be able to reach
 * it. Hovering the card only changes its colour.
 */
.product-card__add {
	height: 2.75rem;
	width: 100%;
	border-top: 1px solid var(--color-line);
	background-color: var(--color-surface);
	font-family: var(--font-mono);
	font-size: 0.6875rem;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--color-ink-2);
	transition:
		background-color var(--duration-swift) var(--ease-linear-out),
		color var(--duration-swift) var(--ease-linear-out);
}

.product-card:hover .product-card__add {
	background-color: var(--color-signal);
	color: #fff;
}

.product-card__add:hover {
	background-color: var(--tpl-accent);
	color: var(--color-signal-dark);
}

/* ────────────────────────────────────────────────────────── grids ───── */

/* The catalogue grid. Column count steps up with the viewport. */
.product-grid {
	display: grid;
	grid-template-columns: repeat(1, minmax(0, 1fr));
	column-gap: 1.5rem;
	row-gap: 3rem;
}

@media (width >= 40rem) {
	.product-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (width >= 48rem) {
	.product-grid--three {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}

	.product-grid--four {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

@media (width >= 80rem) {
	.product-grid--three {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}

	.product-grid--four {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}


/*
 * Progress bar and spinner — determinate and indeterminate feedback.
 *
 * The bar's fill is a percentage set inline via --progress-value, the same
 * pattern .rating uses for its star fill — no JavaScript required unless
 * you want to animate the value as it changes. The spinner reuses the same
 * @keyframes spin as the one built into .button__spinner (css/motion.css).
 */

.progress {
	width: 100%;
	height: 0.375rem;
	background-color: var(--color-canvas-2);
}

.progress__bar {
	height: 100%;
	width: var(--progress-value, 0%);
	background-color: var(--color-signal);
	transition: width var(--duration-calm) var(--ease-linear-out);
}

.progress--accent .progress__bar {
	background-color: var(--tpl-accent);
}

.progress--sm {
	height: 0.25rem;
}

.progress__meta {
	margin-top: 0.5rem;
	display: flex;
	justify-content: space-between;
	font-size: 0.75rem;
	color: var(--color-ink-3);
}

/* No known duration — a segment sweeps back and forth instead of filling. */
.progress--indeterminate .progress__bar {
	width: 40%;
	animation: progress-sweep 1.4s var(--ease-linear-out) infinite;
}

@keyframes progress-sweep {
	0% {
		transform: translateX(-100%);
	}
	100% {
		transform: translateX(250%);
	}
}

/* ─────────────────────────────────────────────────────────── spinner ───── */

.spinner {
	display: inline-block;
	flex: none;
	width: 1.25rem;
	height: 1.25rem;
	border: 2px solid var(--ink-15);
	border-top-color: var(--color-signal);
	border-radius: 50%;
	animation: spin 700ms linear infinite;
}

.spinner--sm {
	width: 0.875rem;
	height: 0.875rem;
	border-width: 1.5px;
}

.spinner--lg {
	width: 2rem;
	height: 2rem;
	border-width: 3px;
}

/* For dropping onto a dark or signal-coloured surface. */
.spinner--light {
	border-color: var(--paper-25);
	border-top-color: #fff;
}


/*
 * Quantity stepper — a ruled box holding decrement, value, increment.
 *
 * Used on the product page and on every line in the bag. The buttons are real
 * <button> elements with accessible names that include the product, because on
 * the bag page there are several steppers and "Increase quantity" alone would
 * not say of what.
 */

.quantity {
	display: flex;
	align-items: center;
	border: 1px solid var(--ink-20);
}

.quantity__button {
	display: grid;
	place-items: center;
	width: 2.75rem;
	height: 3rem;
	color: var(--color-ink-2);
	transition: color var(--duration-swift) var(--ease-linear-out);
}

.quantity__button:hover:not(:disabled) {
	color: var(--color-ink);
}

.quantity__button:disabled {
	opacity: 0.3;
	cursor: not-allowed;
}

.quantity__button svg {
	width: 0.75rem;
	height: 0.75rem;
}

.quantity__value {
	width: 2rem;
	text-align: center;
	font-family: var(--font-mono);
	font-size: 0.875rem;
	font-variant-numeric: tabular-nums;
}

/* Compact variant, for bag lines. */
.quantity--sm .quantity__button {
	width: 2.25rem;
	height: 2.25rem;
}

.quantity--sm .quantity__value {
	font-size: 0.8125rem;
}


/*
 * Star rating.
 *
 * A filled row is clipped over an empty one, so a partial star stays crisp at
 * any size and no half-star glyph is needed. The fill width is set inline as
 * `--rating-fill` (rating ÷ 5, as a percentage).
 *
 * The whole graphic is aria-hidden; the accessible name lives on the wrapper's
 * `aria-label`, which reads "Rated 4.8 out of 5 from 512 reviews".
 */

.rating {
	display: flex;
	align-items: center;
	gap: 0.5rem;
}

.rating__stars {
	position: relative;
	display: inline-flex;
}

.rating__row {
	display: flex;
	gap: 0.125rem;
}

.rating__row--empty {
	color: var(--color-ink-5);
}

.rating__row--filled {
	position: absolute;
	inset: 0;
	overflow: hidden;
	color: var(--color-caution);
	width: var(--rating-fill, 0%);
}

.rating__row--filled svg {
	flex: none;
}

.rating__star {
	width: 0.875rem;
	height: 0.875rem;
}

.rating--sm .rating__star {
	width: 0.75rem;
	height: 0.75rem;
}

.rating--lg .rating__star {
	width: 1.05rem;
	height: 1.05rem;
}

/* On a dark surface the empty row becomes translucent paper. */
[data-surface='dark'] .rating__row--empty {
	color: var(--paper-60);
}

.rating__value {
	font-size: 0.8125rem;
	font-weight: 500;
	color: var(--color-ink-2);
	font-variant-numeric: tabular-nums;
}

.rating__count {
	font-size: 0.8125rem;
	color: var(--color-ink-3);
	font-variant-numeric: tabular-nums;
}


/*
 * Recurring section furniture: the ruled heading block, breadcrumbs, the ruled
 * index list, the figure row, and the bordered notices.
 *
 * These are the pieces that appear on almost every page. Anything used once
 * lives in its page stylesheet instead.
 */

/* ───────────────────────────────────────────────── section heading ───── */

/*
 * Label, display headline, optional lede — sitting above a hairline that closes
 * the block off from the content beneath.
 */
.section-heading {
	border-bottom: 1px solid var(--color-line);
	padding-bottom: 1.5rem;
}

.section-heading--strong {
	border-bottom-color: var(--color-ink);
}

.section-heading__title {
	margin-top: 1rem;
	color: var(--color-ink);
}

/* For page titles that should break onto a second line rather than run the
   full width of the shell. */
.section-heading__title--measure {
	max-width: 48rem;
}

.section-heading__lede {
	margin-top: 1.5rem;
	max-width: 36rem;
	color: var(--color-ink-2);
}

/* Variant with the lede pulled out to a second column on wide screens. */
.section-heading--split {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	align-items: end;
	column-gap: 2rem;
	row-gap: 1.25rem;
}

.section-heading--split .section-heading__main {
	grid-column: span 12;
}

.section-heading--split .section-heading__aside {
	grid-column: span 12;
	max-width: 28rem;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: var(--color-ink-2);
}

@media (width >= 64rem) {
	.section-heading--split .section-heading__main {
		grid-column: span 7;
	}

	.section-heading--split .section-heading__aside {
		grid-column: 9 / span 4;
	}
}

[data-surface='dark'] .section-heading {
	border-bottom-color: var(--paper-15);
}

[data-surface='dark'] .section-heading__title {
	color: #fff;
}

[data-surface='dark'] .section-heading__lede {
	color: var(--paper-75);
}

/* ──────────────────────────────────────────────────── breadcrumbs ───── */

.breadcrumb__list {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem;
}

.breadcrumb__current {
	color: var(--color-ink);
}

/* ─────────────────────────────────────────────────────── index list ───── */

/*
 * The numbered, ruled list used for process steps and service summaries. Each
 * row is a twelve-column grid so the number and the copy align down the page.
 */
.index-list__item {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	column-gap: 1.5rem;
	border-top: 1px solid var(--color-line);
	padding-block: 1.75rem;
}

.index-list__item:last-child {
	border-bottom: 1px solid var(--color-line);
}

.index-list__number {
	grid-column: span 2;
}

.index-list__content {
	grid-column: span 10;
}

@media (width >= 64rem) {
	.index-list__number {
		grid-column: span 1;
	}

	.index-list__content {
		grid-column: span 11;
	}
}

.index-list__title {
	color: var(--color-ink);
}

.index-list__body {
	margin-top: 0.5rem;
	max-width: 36rem;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: var(--color-ink-2);
}

/* ───────────────────────────────────────────────────── figure row ───── */

/* The four counted statistics. Values animate up on first view. */
.figure-row {
	margin-top: 5rem;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	column-gap: 2rem;
	row-gap: 2.5rem;
	border-top: 1px solid var(--color-ink);
	padding-top: 2.5rem;
}

@media (width >= 64rem) {
	.figure-row {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

.figure-row__value {
	display: block;
	font-family: var(--font-display);
	font-size: var(--text-d3);
	line-height: var(--leading-d3);
	letter-spacing: var(--tracking-d3);
	font-weight: 600;
	font-stretch: 96%;
	color: var(--color-ink);
	font-variant-numeric: tabular-nums;
}

.figure-row__label {
	display: block;
	margin-top: 0.75rem;
	max-width: 14rem;
}

/* ────────────────────────────────────────────────────────── notice ───── */

/*
 * A bordered aside. The left rule carries the meaning: accent for a pharmacist's
 * note, red for a safety warning, green for a confirmation.
 */
.notice {
	border-left: 2px solid var(--tpl-accent);
	background-color: var(--color-surface);
	padding: 1.25rem;
}

.notice--roomy {
	padding: 1.5rem;
}

.notice--danger {
	border-left-color: var(--color-danger);
	background-color: var(--color-canvas);
}

.notice--signal {
	border-left-color: var(--color-signal);
	background-color: var(--color-canvas);
}

.notice--on-canvas {
	background-color: var(--color-canvas);
}

.notice__body {
	margin-top: 0.75rem;
	font-size: 0.875rem;
	line-height: 1.7;
	color: var(--color-ink-2);
}

.notice__body--lead {
	font-size: 0.9375rem;
}

/* ───────────────────────────────────────────────── definition rows ───── */

/* Label / value pairs, ruled between — registration details, account details. */
.detail-list__row {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	gap: 1rem;
	padding-block: 1rem;
	border-top: 1px solid var(--color-line);
}

.detail-list__row:first-child {
	border-top: 0;
}

.detail-list__term {
	grid-column: span 12;
}

.detail-list__value {
	grid-column: span 12;
	font-size: 0.875rem;
	color: var(--color-ink);
}

.detail-list__value--mono {
	font-family: var(--font-mono);
	font-size: 0.8125rem;
}

@media (width >= 40rem) {
	.detail-list__term {
		grid-column: span 5;
	}

	.detail-list__value {
		grid-column: span 7;
	}
}

/* ──────────────────────────────────────────────────── closing block ───── */

/* The address-and-actions block that closes the home page. */
.closing-block {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	align-items: end;
	column-gap: 2rem;
	row-gap: 2rem;
	border-top: 1px solid var(--color-ink);
	padding-top: 2.5rem;
}

.closing-block__title {
	grid-column: span 12;
	color: var(--color-ink);
}

.closing-block__aside {
	grid-column: span 12;
}

@media (width >= 64rem) {
	.closing-block__title {
		grid-column: span 7;
	}

	.closing-block__aside {
		grid-column: 9 / span 4;
	}
}


/*
 * Data table.
 *
 * Rules and space, no fills and no zebra striping — a header band, a hairline
 * under every row, and nothing else. The same treatment the documentation uses
 * for its own tables, lifted into the shared system.
 *
 * Wrap the table in `.table-wrap` so a wide one scrolls inside its own box
 * rather than pushing the page sideways. The wrapper carries `tabindex="0"`
 * and an accessible name in the markup, because a scrollable region has to be
 * reachable from the keyboard.
 */

.table-wrap {
	overflow-x: auto;
	/* Stops the flex/grid parent from letting the table dictate the page width. */
	min-width: 0;
	max-width: 100%;
}

.table-wrap:focus-visible {
	outline: 2px solid var(--color-signal);
	outline-offset: 2px;
}

.table {
	width: 100%;
	border-collapse: collapse;
	/* Wide tables scroll rather than crushing their columns. */
	min-width: 32rem;
	font-size: 0.875rem;
	line-height: 1.55;
	color: var(--color-ink-2);
}

.table caption {
	margin-bottom: 0.75rem;
	color: var(--color-ink-3);
	font-size: 0.875rem;
	text-align: left;
}

.table th,
.table td {
	padding: 0.6rem 0.75rem;
	border-bottom: 1px solid var(--color-line);
	text-align: left;
	vertical-align: top;
}

.table thead th {
	background: var(--color-canvas-2);
	color: var(--color-ink);
	font-family: var(--font-mono);
	font-size: var(--text-label);
	font-weight: 400;
	letter-spacing: var(--tracking-label);
	text-transform: uppercase;
	white-space: nowrap;
}

/* A row header, for tables whose first column names the row. */
.table tbody th {
	color: var(--color-ink);
	font-weight: 600;
}

.table code {
	white-space: nowrap;
}

/*
 * Numbers line up when they share a column, so set them in the mono face.
 * Scoped through .table because `.table th, .table td` above is one type
 * selector more specific than a bare class, and would win the text-align.
 */
.table .table__cell--numeric {
	font-family: var(--font-mono);
	font-size: var(--text-data);
	font-variant-numeric: tabular-nums;
	text-align: right;
	white-space: nowrap;
}

/* The last row's rule is usually redundant against whatever follows. */
.table--flush tbody tr:last-child th,
.table--flush tbody tr:last-child td {
	border-bottom: 0;
}

/* Denser, for long reference tables. */
.table--compact th,
.table--compact td {
	padding: 0.4rem 0.6rem;
}

/* On a dark section. */
.table--on-signal {
	color: var(--paper-80);
}

.table--on-signal th,
.table--on-signal td {
	border-bottom-color: var(--paper-15);
}

.table--on-signal thead th {
	background: var(--paper-10);
	color: #fff;
}

.table--on-signal tbody th {
	color: #fff;
}


/*
 * Toasts — short-lived confirmations ("Added to bag").
 *
 * The container is present on every page and announced as a polite live region,
 * so a toast added to it is read out without stealing focus. js/toasts.js does
 * the adding and the removing.
 */

.toast-region {
	pointer-events: none;
	position: fixed;
	inset-inline: 0;
	bottom: 0;
	z-index: var(--z-toast);
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.5rem;
	padding: 1rem;
}

@media (width >= 40rem) {
	.toast-region {
		align-items: flex-end;
		padding: 1.5rem;
	}
}

.toast {
	pointer-events: auto;
	display: flex;
	width: 100%;
	max-width: 24rem;
	align-items: flex-start;
	gap: 0.75rem;
	background-color: var(--color-ink);
	color: #fff;
	padding: 0.875rem 1rem;
	box-shadow: var(--shadow-raised);
	animation: rise-in 420ms var(--ease-linear-out) both;
}

/* Set by js/toasts.js just before the element is removed. */
.toast--leaving {
	animation: fade-in 200ms var(--ease-linear-out) reverse both;
}

.toast__icon {
	margin-top: 0.125rem;
	display: grid;
	place-items: center;
	width: 1.25rem;
	height: 1.25rem;
	flex: none;
	border-radius: 50%;
	background-color: rgb(255 255 255 / 0.2);
	color: #fff;
}

.toast--success .toast__icon {
	background-color: var(--tpl-accent);
	color: var(--color-signal-dark);
}

.toast__icon svg {
	width: 0.75rem;
	height: 0.75rem;
}

.toast__text {
	min-width: 0;
	flex: 1;
}

.toast__message {
	font-size: 0.875rem;
	font-weight: 500;
}

.toast__detail {
	font-size: 0.8125rem;
	color: var(--paper-75);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.toast__dismiss {
	margin: -0.25rem;
	padding: 0.25rem;
	flex: none;
	color: var(--paper-75);
	transition: color var(--duration-swift) var(--ease-linear-out);
}

.toast__dismiss:hover {
	color: #fff;
}

.toast__dismiss svg {
	width: 1rem;
	height: 1rem;
}


/*
 * Tooltip — a short, supplementary label revealed on hover or keyboard
 * focus. Pure CSS: the trigger and bubble are siblings inside .tooltip,
 * shown via :hover / :focus-within, so it works from the keyboard with no
 * JavaScript. The trigger carries aria-describedby pointing at the bubble's
 * id, and the bubble carries role="tooltip" — belt and braces for
 * assistive tech that doesn't infer the relationship from proximity alone.
 */

.tooltip {
	position: relative;
	display: inline-flex;
}

.tooltip__trigger {
	display: inline-grid;
	place-items: center;
	width: 1.125rem;
	height: 1.125rem;
	border: 1px solid var(--color-ink-3);
	color: var(--color-ink-3);
	font-family: var(--font-mono);
	font-size: 0.625rem;
	cursor: help;
	transition:
		color var(--duration-swift) var(--ease-linear-out),
		border-color var(--duration-swift) var(--ease-linear-out);
}

.tooltip:hover .tooltip__trigger,
.tooltip__trigger:focus-visible {
	color: var(--color-ink);
	border-color: var(--color-ink);
}

.tooltip__bubble {
	pointer-events: none;
	position: absolute;
	bottom: calc(100% + 0.5rem);
	left: 50%;
	transform: translateX(-50%) translateY(4px);
	width: max-content;
	max-width: 16rem;
	background-color: var(--color-signal);
	color: #fff;
	padding: 0.5rem 0.75rem;
	font-size: 0.75rem;
	line-height: 1.5;
	opacity: 0;
	transition:
		opacity var(--duration-swift) var(--ease-linear-out),
		transform var(--duration-swift) var(--ease-linear-out);
	z-index: var(--z-header);
}

.tooltip:hover .tooltip__bubble,
.tooltip:focus-within .tooltip__bubble {
	opacity: 1;
	transform: translateX(-50%) translateY(0);
}


/*
 * Self-hosted typefaces.
 *
 * Split by unicode-range so the browser only fetches the subsets a page
 * actually renders. Two families, no more:
 *
 *   Archivo Variable — a technical grotesque with width and weight axes, used
 *                      for both display and interface text. One file covers
 *                      every weight and width the site uses.
 *   IBM Plex Mono    — every dose, price, reference number and timestamp.
 *
 * Only the Latin and Latin-Extended subsets are shipped. If you localise into
 * Cyrillic, Greek or Vietnamese, copy the matching `.woff2` files alongside
 * these and add the corresponding @font-face blocks.
 */

/* ─────────────────────────────────────────────── Archivo Variable ───── */

@font-face {
	font-family: 'Archivo Variable';
	font-style: normal;
	font-display: swap;
	font-weight: 100 900;
	font-stretch: 62% 125%;
	src: url('tfonts/archivo-latin-wdth-normal.woff2') format('woff2-variations');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
		U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'Archivo Variable';
	font-style: normal;
	font-display: swap;
	font-weight: 100 900;
	font-stretch: 62% 125%;
	src: url('tfonts/archivo-latin-ext-wdth-normal.woff2') format('woff2-variations');
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
		U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
		U+2C60-2C7F, U+A720-A7FF;
}

/* ───────────────────────────────────────────────── IBM Plex Mono ───── */

@font-face {
	font-family: 'IBM Plex Mono';
	font-style: normal;
	font-display: swap;
	font-weight: 400;
	src: url('tfonts/ibm-plex-mono-latin-400-normal.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
		U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'IBM Plex Mono';
	font-style: normal;
	font-display: swap;
	font-weight: 400;
	src: url('tfonts/ibm-plex-mono-latin-ext-400-normal.woff2') format('woff2');
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
		U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
		U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: 'IBM Plex Mono';
	font-style: normal;
	font-display: swap;
	font-weight: 500;
	src: url('tfonts/ibm-plex-mono-latin-500-normal.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
		U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'IBM Plex Mono';
	font-style: normal;
	font-display: swap;
	font-weight: 500;
	src: url('tfonts/ibm-plex-mono-latin-ext-500-normal.woff2') format('woff2');
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
		U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
		U+2C60-2C7F, U+A720-A7FF;
}


/*
 * A1 Pharmacy — stylesheet entry point.
 *
 * Every page links this one file. It pulls in the layers that apply everywhere:
 * tokens, fonts, the reset, typography, utilities, motion, and the components
 * that appear in the shared header and footer or on more than one page.
 *
 * Page-specific stylesheets are NOT imported here — each page links its own
 * after this file, e.g.
 *
 *     <link rel="stylesheet" href="css/main.css" />
 *     <link rel="stylesheet" href="css/pages/shop.css" />
 *
 * Order matters. Later layers are written to override earlier ones, so keep
 * the sequence below as it stands when adding to it.
 *
 * ── Production note ──────────────────────────────────────────────────────────
 * @import costs one extra round trip before the imported files are discovered.
 * That is a fair trade while you are editing. Before going live, concatenate
 * these files in this order into a single stylesheet and link that instead —
 * any minifier will do it (`npx lightningcss --bundle --minify css/main.css`).
 */

/* 1 — Foundations. Custom properties and @font-face; no rules of their own. */


/* 2 — Element defaults. The reset and unclassed element styles. */

/* 3 — Typography. The type scale, the label system, long-form prose. */

/* 4 — Utilities. Gutters, hairlines, section rhythm, visually-hidden. */

/* 5 — Motion. Reveal states and shared keyframes. */

/* 6 — Shared components. */

















/* ─────────────────────────────────────────────────────── page shell ───── */

/*
 * The page frame itself. The header is fixed, so `<main>` normally has to start
 * below it — except on routes whose first section is a full-bleed hero that is
 * meant to run underneath. Those pages carry `data-full-bleed` on <body>.
 */
.page {
	display: flex;
	min-height: 100dvh;
	flex-direction: column;
}

.page__main {
	flex: 1;
	padding-top: var(--header-height);
}

[data-full-bleed] .page__main {
	padding-top: 0;
}


/*
 * Reveal states, driven by js/reveal.js.
 *
 * The hidden state is scoped to `.js-motion`, a class the script sets on <html>
 * as soon as it runs. Without JavaScript the selector never matches and
 * everything renders visible — content is never trapped behind a script.
 *
 * Distances are deliberately short. This is an archive: things settle into
 * position, they do not fly in.
 */

.js-motion [data-reveal] {
	opacity: 0;
	transition-property: opacity, transform, clip-path;
	transition-duration: var(--reveal-duration, 760ms);
	transition-timing-function: var(--ease-archive);
	transition-delay: var(--reveal-delay, 0ms);
	will-change: opacity, transform;
}

.js-motion [data-reveal='up'] {
	transform: translate3d(0, 1.1rem, 0);
}

.js-motion [data-reveal='down'] {
	transform: translate3d(0, -1.1rem, 0);
}

.js-motion [data-reveal='left'] {
	transform: translate3d(-1.4rem, 0, 0);
}

.js-motion [data-reveal='right'] {
	transform: translate3d(1.4rem, 0, 0);
}

.js-motion [data-reveal='scale'] {
	transform: scale(0.985);
}

/* For imagery: a plate uncovering from the lower edge. */
.js-motion [data-reveal='clip'] {
	clip-path: inset(0 0 100% 0);
}

/* Hairline rules draw in from the leading edge. */
.js-motion [data-reveal='rule'] {
	opacity: 1;
	transform: scaleX(0);
	transform-origin: left;
}

/* The settled state. `~=` matches the "<variant> in" pair the script writes. */
.js-motion [data-reveal~='in'] {
	opacity: 1;
	transform: none;
	clip-path: inset(0 0 0 0);
}

/*
 * Word-by-word headline reveal, built by js/reveal.js from `[data-reveal-words]`.
 *
 * Display type runs at a line-height below 1, so the inline box is shorter than
 * the glyphs it contains. The mask is padded out on both edges (and pulled back
 * by an equal negative margin) to give ascenders and descenders room, otherwise
 * `overflow: hidden` shears the tops and tails off the words.
 */
.reveal-words {
	display: inline;
}

.reveal-words__mask {
	display: inline-block;
	overflow: hidden;
	vertical-align: bottom;
	padding: 0.18em 0.04em 0.28em;
	margin: -0.18em -0.04em -0.28em;
}

.reveal-words__word {
	display: inline-block;
	will-change: transform;
	transition: transform 900ms var(--ease-archive);
	transition-delay: var(--word-delay, 0ms);
}

.js-motion .reveal-words:not([data-revealed]) .reveal-words__word {
	transform: translate3d(0, 108%, 0);
}

/* ─────────────────────────────────────────────────────── keyframes ───── */

/* The bottom-edge rail's live dot, and the hero's colour bloom. */
@keyframes pulse-dot {
	0%,
	100% {
		opacity: 1;
	}
	50% {
		opacity: 0.35;
	}
}

/* Panels and toasts entering. */
@keyframes rise-in {
	from {
		opacity: 0;
		transform: translate3d(0, 1rem, 0);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

@keyframes drop-in {
	from {
		opacity: 0;
		transform: translate3d(0, -1.5rem, 0);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

@keyframes fade-in {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}

@keyframes spin {
	to {
		transform: rotate(360deg);
	}
}


/*
 * About — the intro columns, the team grid, and the registration table.
 */

.about-intro {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	column-gap: 2rem;
	row-gap: 2.5rem;
}

.about-intro__label,
.about-intro__copy {
	grid-column: span 12;
}

@media (width >= 64rem) {
	.about-intro__label {
		grid-column: span 5;
	}

	.about-intro__copy {
		grid-column: span 7;
	}
}

.about-intro__copy {
	color: var(--color-ink-2);
}

.about-intro__copy > p + p {
	margin-top: 1.5rem;
}

/* ────────────────────────────────────────────────────────── team ───── */

.team-section {
	background-color: var(--color-surface);
	padding-block: 5rem;
	/* Clears the fixed header when arriving at #team from another page. */
	scroll-margin-top: 7rem;
}

@media (width >= 64rem) {
	.team-section {
		padding-block: 7rem;
	}
}

.team-grid {
	margin-top: 3rem;
	display: grid;
	column-gap: 2rem;
	row-gap: 3.5rem;
}

@media (width >= 48rem) {
	.team-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

.team-member__portrait {
	background-color: var(--color-canvas);
}

.team-member__name {
	margin-top: 1.5rem;
	color: var(--color-ink);
}

.team-member__role {
	margin-top: 0.5rem;
}

.team-member__bio {
	margin-top: 1rem;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: var(--color-ink-2);
}

.team-member__specialisms {
	margin-top: 1.25rem;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}

/* ─────────────────────────────────────────────────── registration ───── */

.about-registration {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	column-gap: 2rem;
	row-gap: 2rem;
}

.about-registration__intro,
.about-registration__list {
	grid-column: span 12;
}

@media (width >= 64rem) {
	.about-registration__intro {
		grid-column: span 5;
	}

	.about-registration__list {
		grid-column: 7 / span 6;
	}
}

.about-registration__title {
	margin-top: 1rem;
	color: var(--color-ink);
}

.about-registration__body {
	margin-top: 1.5rem;
	max-width: 28rem;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: var(--color-ink-2);
}

.about-registration__action {
	margin-top: 2rem;
}


/*
 * Account — the header, tab strip, and the three panels behind it.
 */

.account-header {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: 1.5rem;
	border-bottom: 1px solid var(--color-ink);
	padding-bottom: 1.5rem;
}

.account-header__name {
	margin-top: 1rem;
	color: var(--color-ink);
}

.account-header__meta {
	margin-top: 0.5rem;
}

.account-header__nomination {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	font-family: var(--font-mono);
	font-size: 0.6875rem;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--color-signal);
}

.account-header__dot {
	width: 0.375rem;
	height: 0.375rem;
	background-color: var(--tpl-accent);
}

/* ──────────────────────────────────────────────────────────── tabs ───── */

.account-tabs {
	margin-top: 2rem;
	display: flex;
	gap: 0.25rem;
	border-bottom: 1px solid var(--color-line);
}

.account-tab {
	position: relative;
	padding: 0.75rem 1rem;
	font-family: var(--font-mono);
	font-size: 0.6875rem;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--color-ink-3);
	transition: color var(--duration-swift) var(--ease-linear-out);
}

.account-tab:hover {
	color: var(--color-ink);
}

.account-tab[aria-selected='true'] {
	color: var(--color-ink);
}

.account-tab[aria-selected='true']::after {
	content: '';
	position: absolute;
	inset-inline: 0;
	bottom: -1px;
	height: 2px;
	background-color: var(--color-signal);
}

.account-panel {
	padding-top: 2.5rem;
}

.account-panel:focus {
	outline: none;
}

.account-panel__bar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
}

.account-list {
	margin-top: 1.5rem;
}

/* ─────────────────────────────────────────────────── prescriptions ───── */

.account-row {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	column-gap: 1.5rem;
	row-gap: 0.75rem;
	border-bottom: 1px solid var(--color-line);
	padding-block: 1.5rem;
}

.account-row__main,
.account-row__status,
.account-row__due {
	grid-column: span 12;
}

@media (width >= 40rem) {
	.account-row__status,
	.account-row__due {
		grid-column: span 6;
	}
}

@media (width >= 64rem) {
	.account-row__main {
		grid-column: span 6;
	}

	.account-row__status {
		grid-column: span 3;
	}

	.account-row__due {
		grid-column: span 3;
		text-align: right;
	}
}

.account-row__title {
	font-size: 0.9375rem;
	font-weight: 600;
	color: var(--color-ink);
}

.account-row__detail,
.account-row__note {
	margin-top: 0.25rem;
}

.account-row__prescriber {
	margin-top: 0.25rem;
	color: var(--color-ink-4);
}

.account-row__note {
	margin-top: 0.5rem;
}

.account-row__due-date {
	margin-top: 0.25rem;
	font-family: var(--font-mono);
	font-size: 0.8125rem;
	color: var(--color-ink);
	font-variant-numeric: tabular-nums;
}

/* ──────────────────────────────────────────────────────────── orders ───── */

.account-order {
	border-bottom: 1px solid var(--color-line);
	padding-block: 1.5rem;
}

.account-order__head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
}

.account-order__reference {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 1rem;
}

.account-order__number {
	font-family: var(--font-mono);
	font-size: 0.8125rem;
	color: var(--color-ink);
}

.account-order__total {
	font-family: var(--font-mono);
	font-size: 0.875rem;
	color: var(--color-ink);
	font-variant-numeric: tabular-nums;
}

.account-order__items {
	margin-top: 1rem;
	display: flex;
	flex-direction: column;
	gap: 0.375rem;
}

.account-order__item {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	font-size: 0.8125rem;
	color: var(--color-ink-2);
}

.account-order__quantity,
.account-order__price {
	font-family: var(--font-mono);
	font-variant-numeric: tabular-nums;
}

.account-order__placed {
	margin-top: 0.75rem;
}

/* ─────────────────────────────────────────────────────────── details ───── */

.account-details {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	column-gap: 2rem;
	row-gap: 3rem;
}

.account-details__list,
.account-details__addresses {
	grid-column: span 12;
}

@media (width >= 64rem) {
	.account-details__list {
		grid-column: span 6;
	}

	.account-details__addresses {
		grid-column: 8 / span 5;
	}
}

.address-list {
	margin-top: 1.25rem;
	display: flex;
	flex-direction: column;
	gap: 1rem;
}

.address-card {
	border: 1px solid var(--color-line);
	background-color: var(--color-surface);
	padding: 1.25rem;
}

.address-card__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
}

.address-card__label {
	font-family: var(--font-mono);
	font-size: 0.6875rem;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--color-ink-2);
}

.address-card__lines {
	margin-top: 0.75rem;
	font-size: 0.875rem;
	line-height: 1.7;
	color: var(--color-ink-2);
}

.account-footnote {
	margin-top: 3.5rem;
	max-width: 42rem;
	border-top: 1px solid var(--color-line);
	padding-top: 1.5rem;
}

/* ───────────────────────────────────────────── narrow screens ───── */

/*
 * Both lists stack into a single column below 40rem, and at that width the
 * default rhythm stops doing enough work: every line lands in the same mono
 * grey at nearly the same size, and a repeat item reads as one paragraph
 * rather than three pieces of information. These rules put the grouping back.
 */
@media (width < 40rem) {
	/*
	 * Each item onto its own surface. On the canvas, separated only by a hairline,
	 * a tall stacked item has nothing marking where it ends and the next begins.
	 * A white card and a gap does that with no extra ink.
	 */
	.account-list {
		display: flex;
		flex-direction: column;
		gap: 0.75rem;
	}

	.account-row,
	.account-order {
		background: var(--color-surface);
		border: 1px solid var(--color-line);
		padding: 1.25rem;
	}

	/* Space between the three blocks, so they read as three and not as prose. */
	.account-row {
		row-gap: 1.25rem;
	}

	.account-row__title {
		font-size: 1rem;
	}

	/*
	 * "Next due" is a date and a countdown, but stacked flush left it looks like
	 * two more sentences. A rule above it and the values against the right edge
	 * make it read as the data it is.
	 */
	.account-row__due {
		display: grid;
		grid-template-columns: auto minmax(0, 1fr);
		column-gap: 1rem;
		align-items: baseline;
		border-top: 1px solid var(--color-line);
		padding-top: 0.75rem;
	}

	.account-row__due dt {
		grid-column: 1;
		grid-row: 1;
	}

	.account-row__due dd {
		grid-column: 2;
		margin-inline-start: 0;
		text-align: right;
	}

	.account-row__due-date {
		margin-top: 0;
	}

	/*
	 * The order header is a flex row that wraps, which at this width leaves the
	 * total stranded on a line of its own, reading like another line item. Two
	 * columns instead: the reference wraps in the first, the total stays pinned
	 * top-right where a total belongs.
	 */
	.account-order__head {
		display: grid;
		grid-template-columns: minmax(0, 1fr) auto;
		column-gap: 1rem;
		align-items: baseline;
	}

	.account-order__reference {
		gap: 0.5rem 0.75rem;
	}
}


/*
 * Bag page — lines on the left, summary panel on the right.
 *
 * The lines are built by js/bag-page.js from the <template> in cart.html,
 * because the bag only exists in localStorage. Everything here styles markup
 * that is in the HTML file either way.
 */

.bag-empty {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 1.5rem;
	padding-block: 4rem;
}

.bag-empty__body {
	max-width: 28rem;
	color: var(--color-ink-2);
}

.bag-layout {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	column-gap: 2rem;
	row-gap: 3rem;
	padding-top: 2rem;
}

.bag-lines,
.bag-summary {
	grid-column: span 12;
}

@media (width >= 64rem) {
	.bag-lines {
		grid-column: span 7;
	}

	.bag-summary {
		grid-column: 9 / span 4;
	}
}

/* ───────────────────────────────────────────────────────── lines ───── */

.bag-line {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	column-gap: 1.25rem;
	border-bottom: 1px solid var(--color-line);
	padding-block: 1.5rem;
}

.bag-line__thumb {
	grid-column: span 3;
	background-color: var(--color-surface);
	/* Without this the anchor stretches to the row's height while the plate
	   inside keeps its 1/1 ratio, leaving a strip of surface below the image
	   on any line tall enough to wrap. */
	align-self: start;
}

.bag-line__detail {
	grid-column: span 9;
}

@media (width >= 40rem) {
	.bag-line__thumb {
		grid-column: span 2;
	}

	.bag-line__detail {
		grid-column: span 10;
	}
}

.bag-line__head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	column-gap: 1.5rem;
	row-gap: 0.25rem;
}

.bag-line__name {
	font-size: 0.9375rem;
	font-weight: 600;
	color: var(--color-ink);
	transition: color var(--duration-swift) var(--ease-linear-out);
}

.bag-line__name:hover {
	color: var(--color-signal);
}

.bag-line__total {
	font-family: var(--font-mono);
	font-size: 0.875rem;
	color: var(--color-ink);
	font-variant-numeric: tabular-nums;
}

.bag-line__subtitle {
	margin-top: 0.25rem;
}

.bag-line__controls {
	margin-top: 1rem;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
}

.bag-line__remove {
	text-decoration: underline;
	text-underline-offset: 4px;
	transition: color var(--duration-swift) var(--ease-linear-out);
}

.bag-line__remove:hover {
	color: var(--color-danger);
}

/* ─────────────────────────────────────────────────────── summary ───── */

.bag-summary__panel {
	border: 1px solid var(--color-line);
	background-color: var(--color-surface);
	padding: 1.5rem;
}

.bag-summary__totals {
	margin-top: 1.5rem;
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
	font-size: 0.875rem;
}

.bag-summary__row {
	display: flex;
	justify-content: space-between;
	color: var(--color-ink-2);
}

.bag-summary__row dd {
	font-family: var(--font-mono);
	font-variant-numeric: tabular-nums;
}

.bag-summary__row--total {
	border-top: 1px solid var(--color-line);
	padding-top: 0.75rem;
	font-weight: 600;
	color: var(--color-ink);
}

.bag-summary__progress {
	margin-top: 1.25rem;
}

.bag-summary__track {
	margin-top: 0.5rem;
	height: 3px;
	background-color: var(--color-canvas-2);
}

.bag-summary__bar {
	height: 100%;
	background-color: var(--tpl-accent);
	transition: width var(--duration-slow) var(--ease-precise);
}

.bag-summary__advice {
	margin-top: 1.25rem;
	border-left: 2px solid var(--color-signal);
	background-color: var(--color-canvas);
	padding: 0.75rem;
	font-size: 0.75rem;
	line-height: 1.7;
	color: var(--color-ink-2);
}

.bag-summary__actions {
	margin-top: 1.5rem;
	display: flex;
	flex-direction: column;
	gap: 0.625rem;
}

/* ───────────────────────────────────────────────── order summary ───── */

/* Shared with checkout, which links this file too. */
.order-summary__panel {
	border: 1px solid var(--color-line);
	background-color: var(--color-surface);
	padding: 1.5rem;
}

.order-summary__lines {
	margin-top: 1.25rem;
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
}

.order-summary__line {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	font-size: 0.8125rem;
	color: var(--color-ink-2);
}

.order-summary__quantity {
	font-family: var(--font-mono);
	font-variant-numeric: tabular-nums;
}

.order-summary__value {
	flex: none;
	font-family: var(--font-mono);
	color: var(--color-ink);
	font-variant-numeric: tabular-nums;
}

.order-summary__totals {
	margin-top: 1.5rem;
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
	border-top: 1px solid var(--color-line);
	padding-top: 1.25rem;
	font-size: 0.875rem;
}

.order-summary__row {
	display: flex;
	justify-content: space-between;
	color: var(--color-ink-2);
}

.order-summary__row dd {
	font-family: var(--font-mono);
	font-variant-numeric: tabular-nums;
}

.order-summary__row--total {
	border-top: 1px solid var(--color-line);
	padding-top: 0.75rem;
	font-weight: 600;
	color: var(--color-ink);
}


/*
 * Checkout — progress rail, the stepped form, and the confirmation panel.
 * The order summary panel is styled in cart.css, which this page also links.
 */

.checkout-progress {
	margin-top: 2rem;
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 0.5rem;
}

.checkout-progress__bar {
	height: 3px;
	background-color: var(--color-canvas-2);
	transition: background-color var(--duration-calm) var(--ease-linear-out);
}

.checkout-progress__bar--done {
	background-color: var(--color-signal);
}

.checkout-progress .label {
	margin-top: 0.5rem;
}

.checkout-layout {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	column-gap: 2rem;
	row-gap: 3rem;
	padding-top: 2.5rem;
}

.checkout-form,
.order-summary {
	grid-column: span 12;
}

@media (width >= 64rem) {
	.checkout-form {
		grid-column: span 7;
	}

	.order-summary {
		grid-column: 9 / span 4;
	}
}

.checkout-form__legend {
	margin-bottom: 1rem;
}

/* Fieldsets carry no margin of their own, so consecutive groups would other-
   wise sit flush and the legend would land on top of the previous field's
   hint. Matches the step above the form's actions. */
.checkout-form fieldset + fieldset {
	margin-top: 2.5rem;
}

.checkout-choices {
	display: grid;
	gap: 0.75rem;
}

@media (width >= 40rem) {
	.checkout-choices {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

.checkout-form__addresses {
	margin-top: 1.25rem;
}

.checkout-form__demo-notice {
	margin-bottom: 1.5rem;
}

.checkout-form__actions {
	margin-top: 2.5rem;
}

.checkout-confirmation,
.checkout-empty {
	max-width: 36rem;
	padding-block: 4rem;
}

.checkout-confirmation__title {
	margin-top: 1.25rem;
	color: var(--color-ink);
}

.checkout-confirmation__body {
	margin-top: 1.5rem;
	color: var(--color-ink-2);
}

.checkout-confirmation__actions,
.checkout-empty__action {
	margin-top: 2rem;
}


/*
 * Component showcase — layout for the specimens only. Every component itself
 * is styled entirely by css/components/*.css; nothing here overrides them.
 */

.showcase-header {
	max-width: 42rem;
}

.showcase-header__lede {
	margin-top: 1rem;
}

.showcase-toc {
	margin-top: 2rem;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 1.5rem;
}

.showcase-section + .showcase-section {
	border-top: 1px solid var(--color-line);
}

.showcase-block {
	margin-top: 2.5rem;
}

.showcase-block:first-child {
	margin-top: 2rem;
}

.showcase-block__label {
	margin-bottom: 1rem;
}

.showcase-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 1rem;
}

.showcase-row--start {
	align-items: flex-start;
}

.showcase-grid {
	display: grid;
	gap: 1.5rem;
	grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}

.showcase-grid--forms {
	grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
	row-gap: 2rem;
}

.showcase-caption {
	margin-top: 0.75rem;
	font-size: 0.8125rem;
	color: var(--color-ink-3);
}

.showcase-sample {
	margin-top: 0.75rem;
	overflow-x: auto;
	background-color: var(--color-canvas-2);
	border: 1px solid var(--color-line);
	padding: 1rem 1.25rem;
	font-family: var(--font-mono);
	font-size: 0.8125rem;
	line-height: 1.6;
	color: var(--color-ink-2);
	white-space: pre;
}

.showcase-swatch {
	width: 100%;
	max-width: 22rem;
}

/* A plain centred dialog, built on the same .overlay markup as search/nav. */
.overlay--demo .overlay__panel {
	position: static;
	inset: auto;
	max-width: 28rem;
	margin: 10vh auto 0;
	padding: 2rem;
}

.overlay--demo .overlay__scrim {
	position: fixed;
}

/* The pager demo needs a plain list to page through. */
.showcase-pager-list {
	margin: 0 0 1rem;
	padding: 0;
	list-style: none;
	border-top: 1px solid var(--color-line);
}

.showcase-pager-list li {
	padding: 0.75rem 0;
	border-bottom: 1px solid var(--color-line);
}


/*
 * Contact — details column beside the form.
 */

.contact-layout {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	column-gap: 2rem;
	row-gap: 3.5rem;
	padding-top: 3rem;
}

.contact-details,
.contact-form {
	grid-column: span 12;
}

@media (width >= 64rem) {
	.contact-details {
		grid-column: span 4;
	}

	.contact-form {
		grid-column: 6 / span 7;
	}
}

.contact-details__row {
	border-top: 1px solid var(--color-line);
	padding-block: 1.5rem;
}

.contact-details__row:first-child {
	border-top: 0;
	padding-top: 0;
}

.contact-details__value {
	margin-top: 0.75rem;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: var(--color-ink-2);
}

.contact-hours {
	margin-top: 0.75rem;
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
}

.contact-hours__row {
	display: flex;
	justify-content: space-between;
	gap: 1rem;
	font-size: 0.875rem;
	color: var(--color-ink-2);
}

.contact-hours__time {
	font-family: var(--font-mono);
	color: var(--color-ink);
	font-variant-numeric: tabular-nums;
}

.contact-emergency {
	margin-top: 2rem;
}

/* Submission failures sit above the button, not against a single field. */
.form-submit-error {
	margin-bottom: 1rem;
}


/*
 * Hero carousel — the featured-product showcase at the top of the home page.
 *
 * Composed as a packaging proof rather than a split hero: the packshot sits on
 * a lit plate inside registration marks, with a clinical specification grid
 * under the name and a vertical rail of dispensing data down the right edge.
 *
 * Every slide ships in the markup. Only the one carrying `data-active` is
 * displayed, so with JavaScript off the first slide simply stays put.
 */

.hero {
	position: relative;
	display: flex;
	min-height: 100svh;
	flex-direction: column;
	justify-content: center;
	overflow: hidden;
	background-color: var(--color-signal);
	color: #fff;
	padding-top: 7rem;
	padding-bottom: 2rem;
	/* Horizontal drags change slide; vertical ones must still scroll the page. */
	touch-action: pan-y;
}

@media (width >= 64rem) {
	.hero {
		padding-top: 8rem;
	}
}

/* ─────────────────────────────────────────────────────── backdrop ───── */

.hero__backdrop {
	pointer-events: none;
	position: absolute;
	inset: 0;
	overflow: hidden;
}

/* 1 — photographic texture */
.hero__texture {
	position: absolute;
	inset: 0;
	opacity: 0.22;
}

.hero__texture img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* 2 — per-slide colour bloom, taken from the packshot itself */
.hero-bloom {
	position: absolute;
	right: -15%;
	top: 50%;
	height: 42rem;
	width: 42rem;
	transform: translateY(-50%);
	filter: blur(110px);
	opacity: 0;
	transition: opacity 1200ms var(--ease-precise);
}

.hero-bloom[data-active] {
	opacity: 0.45;
}

.hero-bloom img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	filter: saturate(1.5);
}

@media (prefers-reduced-motion: no-preference) {
	.hero-bloom[data-active] {
		animation: pulse-dot 2.4s ease-in-out infinite;
	}
}

/* 3 — legibility wash */
.hero__wash {
	position: absolute;
	inset: 0;
	background-image: linear-gradient(
		to right,
		var(--color-signal-dark),
		rgb(4 27 18 / 0.9) 50%,
		rgb(7 42 29 / 0.7)
	);
}

.hero__wash--foot {
	background-image: linear-gradient(to top, rgb(4 27 18 / 0.8), transparent);
}

/* 4 — ruled column guides */
.hero__guides {
	position: absolute;
	inset: 0;
	opacity: 0.06;
	background-image: repeating-linear-gradient(to right, #fff 0 1px, transparent 1px 12.5%);
}

/* ──────────────────────────────────────────────── bled type marks ───── */

.hero__catalogue-number {
	pointer-events: none;
	position: absolute;
	left: -2.5rem;
	top: 3rem;
	user-select: none;
	font-family: var(--font-mono);
	font-size: 13rem;
	line-height: 1;
	color: rgb(255 255 255 / 0.05);
}

@media (width >= 64rem) {
	.hero__catalogue-number {
		font-size: 24rem;
	}
}

.hero__vertical-rail {
	pointer-events: none;
	display: none;
	position: absolute;
	right: 0.75rem;
	top: 50%;
	transform: translateY(-50%);
	writing-mode: vertical-rl;
	font-family: var(--font-mono);
	font-size: 0.625rem;
	text-transform: uppercase;
	letter-spacing: 0.32em;
	color: rgb(255 255 255 / 0.35);
}

@media (width >= 80rem) {
	.hero__vertical-rail {
		display: block;
	}
}

.hero__inner {
	position: relative;
}

/* ──────────────────────────────────────────────────────── slides ───── */

/*
 * Slides are stacked in one grid cell rather than hidden, so the section keeps
 * the height of its tallest slide and nothing jumps as they change.
 */
.hero__slides {
	display: grid;
	grid-template-areas: 'slide';
}

.hero-slide {
	grid-area: slide;
	visibility: hidden;
	opacity: 0;
	transition: opacity var(--duration-calm) var(--ease-linear-out);
}

.hero-slide[data-active] {
	visibility: visible;
	opacity: 1;
}

.hero-slide__grid {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	align-items: center;
	column-gap: 2rem;
	row-gap: 3rem;
}

.hero-slide__detail {
	grid-column: span 12;
	order: 2;
}

.hero-slide__packshot {
	grid-column: span 12;
	order: 1;
}

@media (width >= 64rem) {
	.hero-slide__detail {
		grid-column: span 6;
		order: 0;
	}

	.hero-slide__packshot {
		grid-column: 8 / span 5;
		order: 0;
	}
}

/*
 * Each element of the active slide rises in, one beat after the last. The
 * animation is re-triggered by js/slider.js, which removes and re-adds
 * `data-active`.
 */
.hero-slide[data-active] .hero-slide__eyebrow,
.hero-slide[data-active] .hero-slide__title,
.hero-slide[data-active] .hero-spec,
.hero-slide[data-active] .hero-slide__summary,
.hero-slide[data-active] .hero-slide__price {
	animation: rise-in 800ms var(--ease-precise) both;
}

.hero-slide[data-active] .hero-slide__title {
	animation-delay: 70ms;
}

.hero-slide[data-active] .hero-spec {
	animation-delay: 150ms;
}

.hero-slide[data-active] .hero-slide__summary {
	animation-delay: 210ms;
}

.hero-slide[data-active] .hero-slide__price {
	animation-delay: 270ms;
}

.hero-slide__title {
	margin-top: 1.5rem;
	color: #fff;
}

/* ─────────────────────────────────────────── specification grid ───── */

.hero-spec {
	margin-top: 2.25rem;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	border-top: 1px solid var(--paper-20);
}

@media (width >= 40rem) {
	.hero-spec {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

.hero-spec__cell {
	border-bottom: 1px solid var(--paper-12);
	border-right: 1px solid var(--paper-12);
	padding-block: 1rem;
	padding-right: 1rem;
}

.hero-spec__cell:last-child {
	border-right: 0;
}

.hero-spec__term {
	font-family: var(--font-mono);
	font-size: 0.5625rem;
	text-transform: uppercase;
	letter-spacing: 0.16em;
	color: var(--tpl-accent);
}

.hero-spec__value {
	margin-top: 0.5rem;
	font-family: var(--font-mono);
	font-size: 0.75rem;
	line-height: 1.35;
	color: var(--paper-80);
}

.hero-slide__summary {
	margin-top: 1.75rem;
	max-width: 28rem;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: rgb(255 255 255 / 0.65);
}

/* ────────────────────────────────────────────── price and actions ───── */

.hero-slide__actions {
	margin-top: 2.25rem;
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	column-gap: 2rem;
	row-gap: 1.25rem;
}

.hero-slide__price-row {
	margin-top: 0.375rem;
	display: flex;
	align-items: baseline;
	gap: 0.75rem;
}

.hero-slide__price-value {
	font-family: var(--font-mono);
	font-size: 2.25rem;
	line-height: 1;
	color: #fff;
	font-variant-numeric: tabular-nums;
}

.hero-slide__price-compare {
	font-family: var(--font-mono);
	font-size: 0.9375rem;
	color: var(--paper-45);
	text-decoration: line-through;
	font-variant-numeric: tabular-nums;
}

/* ────────────────────────────────────────────────────── packshot ───── */

.hero-plate {
	position: relative;
	margin-inline: auto;
	max-width: 28rem;
}

.hero-plate__image {
	position: relative;
	aspect-ratio: 1 / 1;
	overflow: hidden;
	background-color: #fff;
}

.hero-plate__image img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/*
 * Slice transition.
 *
 * On a slide change the incoming packshot is rebuilt from vertical strips that
 * drop in from alternating edges. js/slider.js builds the strips, sets the
 * column count and each strip's slot, delay and direction, then throws the
 * whole overlay away once they have landed — so at rest this is a single
 * seamless image with no extra nodes, exactly as it was before.
 *
 * Strips sit above the image and below the registration marks and the tag,
 * both of which are z-index 20.
 */
.hero-plate__slices {
	pointer-events: none;
	position: absolute;
	inset: 0;
	z-index: 10;
	display: grid;
	grid-template-columns: repeat(var(--slice-count, 7), 1fr);
}

.hero-plate__slice {
	position: relative;
	overflow: hidden;
	background-color: #fff;
}

/*
 * The strip itself. Every one carries the whole image, scaled so that exactly
 * one column's worth shows through, and offset to its own slot — so the strips
 * reassemble into the original picture rather than repeating it.
 */
.hero-plate__slice::after {
	content: '';
	position: absolute;
	inset: 0;
	background-image: var(--slice-image);
	background-repeat: no-repeat;
	background-size: calc(var(--slice-count, 7) * 100%) 100%;
	background-position: var(--slice-position, 0%) center;
	animation: hero-slice-in 780ms var(--ease-precise) var(--slice-delay, 0ms) both;
}

@keyframes hero-slice-in {
	from {
		transform: translateY(var(--slice-from, -101%));
	}

	to {
		transform: translateY(0);
	}
}

/* Registration marks at the four corners. */
.hero-plate__mark {
	pointer-events: none;
	position: absolute;
	z-index: 20;
	width: 1.25rem;
	height: 1.25rem;
	border-color: var(--tpl-accent);
	border-style: solid;
	border-width: 0;
}

.hero-plate__mark--tl {
	top: -0.75rem;
	left: -0.75rem;
	border-top-width: 1px;
	border-left-width: 1px;
}

.hero-plate__mark--tr {
	top: -0.75rem;
	right: -0.75rem;
	border-top-width: 1px;
	border-right-width: 1px;
}

.hero-plate__mark--bl {
	bottom: -0.75rem;
	left: -0.75rem;
	border-bottom-width: 1px;
	border-left-width: 1px;
}

.hero-plate__mark--br {
	bottom: -0.75rem;
	right: -0.75rem;
	border-bottom-width: 1px;
	border-right-width: 1px;
}

/*
 * The two tags sit on the wrapper rather than inside the plate: the plate clips
 * its own overflow, which would shear them at the edge.
 */
.hero-plate__tag {
	position: absolute;
	left: -1rem;
	bottom: 1.5rem;
	z-index: 20;
	background-color: var(--color-signal-dark);
	padding: 0.5rem 0.75rem;
	box-shadow: var(--shadow-raised);
}

.hero-plate__tag-text,
.hero-plate__advice {
	font-family: var(--font-mono);
	font-size: 0.5625rem;
	text-transform: uppercase;
	letter-spacing: 0.16em;
	color: var(--tpl-accent);
}

.hero-plate__advice {
	position: absolute;
	right: -1rem;
	top: 1.5rem;
	z-index: 20;
	background-color: var(--color-signal-dark);
	padding: 0.5rem 0.75rem;
	letter-spacing: 0.14em;
	box-shadow: var(--shadow-raised);
}

/* ─────────────────────────────────────────────────── thumbnail rail ───── */

.hero-rail {
	margin-top: 3.5rem;
	border-top: 1px solid var(--paper-15);
	padding-top: 1.25rem;
}

.hero-rail__row {
	display: flex;
	align-items: center;
	gap: 1.5rem;
}

.hero-rail__counter {
	flex: none;
}

.hero-rail__list {
	display: flex;
	flex: 1;
	gap: 0.75rem;
}

.hero-rail__item {
	min-width: 0;
	flex: 1;
}

.hero-rail__button {
	display: block;
	width: 100%;
	text-align: left;
}

.hero-rail__track {
	position: relative;
	display: block;
	height: 2px;
	width: 100%;
	background-color: var(--paper-20);
}

/*
 * The progress bar. On the current slide it sweeps across over the autoplay
 * interval; on the others it is a hover affordance only.
 */
.hero-rail__progress {
	position: absolute;
	inset-block: 0;
	left: 0;
	display: block;
	width: 100%;
	transform-origin: left;
	transform: scaleX(0);
	background-color: var(--paper-60);
	transition: transform var(--duration-calm) var(--ease-linear-out);
}

.hero-rail__button:hover .hero-rail__progress {
	transform: scaleX(1);
}

.hero-rail__button[aria-current='true'] .hero-rail__progress {
	background-color: var(--tpl-accent);
	transition: none;
	animation: hero-progress var(--hero-interval, 7000ms) linear both;
}

/* Paused, or motion reduced: the bar simply sits full. */
.hero-rail[data-paused] .hero-rail__button[aria-current='true'] .hero-rail__progress {
	animation-play-state: paused;
}

@media (prefers-reduced-motion: reduce) {
	.hero-rail__button[aria-current='true'] .hero-rail__progress {
		animation: none;
		transform: scaleX(1);
	}
}

@keyframes hero-progress {
	from {
		transform: scaleX(0);
	}
	to {
		transform: scaleX(1);
	}
}

.hero-rail__name {
	display: none;
	margin-top: 0.75rem;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-family: var(--font-mono);
	font-size: 0.625rem;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--paper-45);
	transition: color var(--duration-calm) var(--ease-linear-out);
}

@media (width >= 40rem) {
	.hero-rail__name {
		display: block;
	}
}

.hero-rail__button:hover .hero-rail__name {
	color: var(--paper-80);
}

.hero-rail__button[aria-current='true'] .hero-rail__name {
	color: #fff;
}

.hero-rail__controls {
	display: none;
	align-items: center;
	gap: 0.25rem;
}

@media (width >= 40rem) {
	.hero-rail__controls {
		display: flex;
	}
}

.hero-rail__control {
	display: grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	color: var(--paper-55);
	transition: color var(--duration-swift) var(--ease-linear-out);
}

.hero-rail__control:hover {
	color: var(--tpl-accent);
}

.hero-rail__icon {
	width: 1rem;
	height: 1rem;
}


/*
 * Home page — the sections below the hero.
 *
 * Several of these blocks (the journal grid, the split block) are also used on
 * the journal index and the prescriptions page, which link this stylesheet for
 * exactly that reason.
 */

.home-range__grid {
	margin-top: 3rem;
}

.home-range__footer {
	margin-top: 3.5rem;
}

/* ─────────────────────────────────────────────────── category grid ───── */

/*
 * Eight tiles separated by hairlines. The gap is 1px over a line-coloured
 * background, so the rules between tiles need no borders of their own.
 */
.category-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 1px;
	background-color: var(--color-line);
}

@media (width >= 48rem) {
	.category-grid {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

.category-tile {
	position: relative;
	isolation: isolate;
	display: flex;
	height: 100%;
	flex-direction: column;
	justify-content: space-between;
	gap: 2.5rem;
	overflow: hidden;
	background-color: var(--color-canvas);
	padding: 1.5rem;
}

@media (width >= 64rem) {
	.category-tile {
		padding: 2rem;
	}
}

/* A ghosted packshot that saturates and warms under a green wash on hover. */
.category-tile__backdrop {
	position: absolute;
	inset: 0;
	z-index: -1;
}

.category-tile__image {
	width: 100%;
	height: 100%;
	object-fit: cover;
	filter: grayscale(1);
	opacity: 0.14;
	transition:
		filter 700ms var(--ease-precise),
		opacity 700ms var(--ease-precise),
		transform 700ms var(--ease-precise);
}

.category-tile:hover .category-tile__image {
	filter: grayscale(0);
	opacity: 1;
	transform: scale(1.06);
}

.category-tile__wash {
	position: absolute;
	inset: 0;
	z-index: -1;
	background-color: rgb(242 243 241 / 0.7);
	transition: background-color var(--duration-slow) var(--ease-precise);
}

.category-tile:hover .category-tile__wash {
	background-color: rgb(7 42 29 / 0.85);
}

.category-tile__rule {
	position: absolute;
	inset-inline: 0;
	bottom: 0;
	height: 3px;
	background-color: var(--tpl-accent);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform var(--duration-slow) var(--ease-precise);
}

.category-tile:hover .category-tile__rule {
	transform: scaleX(1);
}

.category-tile__number,
.category-tile__name,
.category-tile__tagline {
	transition: color var(--duration-slow) var(--ease-linear-out);
}

.category-tile__name {
	color: var(--color-ink);
}

.category-tile__tagline {
	margin-top: 0.5rem;
}

.category-tile:hover .category-tile__number {
	color: var(--tpl-accent);
}

.category-tile:hover .category-tile__name {
	color: #fff;
}

.category-tile:hover .category-tile__tagline {
	color: var(--paper-70);
}

/* ──────────────────────────────────────────────────── split block ───── */

/* A narrow column of copy beside a wider column of ruled rows. */
.split-block {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	column-gap: 2rem;
	row-gap: 3rem;
}

.split-block__aside,
.split-block__main {
	grid-column: span 12;
}

@media (width >= 64rem) {
	.split-block__aside {
		grid-column: span 4;
	}

	.split-block__main {
		grid-column: 6 / span 7;
	}
}

.split-block__title {
	margin-top: 1rem;
	color: var(--color-ink);
}

.split-block__body {
	margin-top: 1.5rem;
	max-width: 28rem;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: var(--color-ink-2);
}

.split-block__actions {
	margin-top: 2rem;
}

/* ────────────────────────────────────────────────────── quote block ───── */

.quote-section {
	background-color: var(--color-signal);
	color: #fff;
	padding-block: 6rem;
}

@media (width >= 64rem) {
	.quote-section {
		padding-block: 8rem;
	}
}

.quote-section__grid {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	align-items: center;
	column-gap: 2rem;
	row-gap: 3rem;
}

.quote-section__portrait {
	grid-column: span 12;
}

.quote-section__body {
	grid-column: span 12;
}

@media (width >= 40rem) {
	.quote-section__portrait {
		grid-column: span 6;
	}
}

@media (width >= 64rem) {
	.quote-section__portrait {
		grid-column: span 4;
	}

	.quote-section__body {
		grid-column: 6 / span 7;
	}
}

.quote-section__quote {
	margin-top: 1.5rem;
}

.quote-section__text {
	font-weight: 600;
	line-height: 1.1;
	color: #fff;
}

.quote-section__attribution {
	margin-top: 2rem;
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	column-gap: 1rem;
	row-gap: 0.25rem;
	border-top: 1px solid var(--paper-20);
	padding-top: 1.25rem;
}

.quote-section__name {
	font-size: 1.0625rem;
	font-weight: 600;
	color: #fff;
}

.quote-section__bio {
	margin-top: 1.75rem;
	max-width: 36rem;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: var(--paper-70);
}

.quote-section__actions {
	margin-top: 2rem;
}

/* ───────────────────────────────────────────────────── service rows ───── */

.service-row {
	border-bottom: 1px solid var(--color-line);
}

.service-row__link {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	align-items: baseline;
	column-gap: 1rem;
	row-gap: 0.5rem;
	padding-block: 1.5rem;
}

@media (width >= 64rem) {
	.service-row__link {
		column-gap: 2rem;
	}
}

.service-row__number {
	grid-column: span 2;
}

.service-row__name {
	grid-column: span 10;
	color: var(--color-ink);
	transition: color var(--duration-calm) var(--ease-linear-out);
}

.service-row__link:hover .service-row__name {
	color: var(--color-signal);
}

.service-row__summary {
	grid-column: 3 / span 10;
	font-size: 0.875rem;
	line-height: 1.7;
	color: var(--color-ink-2);
}

.service-row__price {
	grid-column: span 12;
}

@media (width >= 40rem) {
	.service-row__number {
		grid-column: span 1;
	}

	.service-row__name {
		grid-column: span 5;
	}

	.service-row__summary {
		grid-column: span 4;
	}

	.service-row__price {
		grid-column: span 2;
	}
}

@media (width >= 64rem) {
	.service-row__name {
		grid-column: span 4;
	}

	.service-row__summary {
		grid-column: span 5;
	}

	.service-row__price {
		text-align: right;
	}
}

/* ───────────────────────────────────────────────────── journal grid ───── */

.journal-grid {
	display: grid;
	column-gap: 2rem;
	row-gap: 3rem;
	margin-top: 2.5rem;
}

@media (width >= 48rem) {
	.journal-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

.journal-card {
	display: block;
}

.journal-card__plate {
	overflow: hidden;
	background-color: var(--color-surface);
}

.journal-card__image {
	transition: transform 900ms var(--ease-precise);
}

.journal-card:hover .journal-card__image {
	transform: scale(1.03);
}

.journal-card__meta {
	margin-top: 1.25rem;
}

.journal-card__title {
	margin-top: 0.75rem;
	color: var(--color-ink);
	transition: color var(--duration-calm) var(--ease-linear-out);
}

.journal-card:hover .journal-card__title {
	color: var(--color-signal);
}

.journal-card__excerpt {
	margin-top: 0.75rem;
	font-size: 0.875rem;
	line-height: 1.7;
	color: var(--color-ink-2);
}

.journal-card__byline {
	margin-top: 1rem;
}

.closing-block__actions {
	margin-top: 1.75rem;
}


/*
 * Journal — the lead article on the index, and the article page itself.
 *
 * The three-across card grid it shares with the home page lives in home.css,
 * which every page using this file also links.
 */

.journal-lead {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	column-gap: 2rem;
	row-gap: 1.5rem;
	margin-top: 3rem;
}

.journal-lead__plate,
.journal-lead__detail {
	grid-column: span 12;
}

@media (width >= 64rem) {
	.journal-lead__plate {
		grid-column: span 7;
	}

	.journal-lead__detail {
		grid-column: 9 / span 4;
		align-self: center;
	}
}

.journal-lead__plate {
	overflow: hidden;
	background-color: var(--color-surface);
}

.journal-lead__image {
	transition: transform 900ms var(--ease-precise);
}

.journal-lead:hover .journal-lead__image {
	transform: scale(1.02);
}

.journal-lead__title {
	margin-top: 1rem;
	color: var(--color-ink);
	transition: color var(--duration-calm) var(--ease-linear-out);
}

.journal-lead:hover .journal-lead__title {
	color: var(--color-signal);
}

.journal-lead__standfirst {
	margin-top: 1rem;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: var(--color-ink-2);
}

.journal-lead__byline {
	margin-top: 1.25rem;
}

.journal-grid--ruled {
	margin-top: 4rem;
	row-gap: 3.5rem;
}

.journal-grid--ruled > li {
	border-top: 1px solid var(--color-line);
	padding-top: 2rem;
}

/* ─────────────────────────────────────────────────────── article ───── */

.article {
	padding-block: 3rem;
}

@media (width >= 64rem) {
	.article {
		padding-block: 4rem;
	}
}

.article__kicker {
	margin-top: 2rem;
}

.article__title {
	margin-top: 1.25rem;
	max-width: 56rem;
	color: var(--color-ink);
}

.article__standfirst {
	margin-top: 1.75rem;
	max-width: 42rem;
	color: var(--color-ink-2);
}

.article__byline {
	margin-top: 2.25rem;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	column-gap: 1.5rem;
	row-gap: 0.75rem;
	border-top: 1px solid var(--color-line);
	padding-top: 1.5rem;
}

.article__author {
	display: flex;
	align-items: center;
	gap: 0.75rem;
}

.article__avatar {
	width: 2.5rem;
	flex: none;
}

.article__author-name {
	font-size: 0.875rem;
	font-weight: 600;
	color: var(--color-ink);
}

.article__date {
	margin-left: auto;
}

.article__hero {
	margin-top: 3rem;
}

.article__hero .plate {
	background-color: var(--color-surface);
}

.article__body {
	margin-top: 3.5rem;
}

.article__reminder {
	margin-top: 4rem;
	padding: 1.5rem;
}

.article__reminder-action {
	margin-top: 1.5rem;
}


/*
 * Legal pages (privacy, terms, accessibility) and the 404.
 *
 * Body copy is set by the shared `.prose` rules in typography.css; this file
 * only handles the header block and the page's own rhythm.
 */

.legal {
	padding-block: 3rem;
}

@media (width >= 64rem) {
	.legal {
		padding-block: 5rem;
	}
}

.legal__header {
	margin-top: 2rem;
	border-bottom: 1px solid var(--color-ink);
	padding-bottom: 2rem;
}

.legal__title {
	color: var(--color-ink);
}

.legal__standfirst {
	margin-top: 1.25rem;
	color: var(--color-ink-2);
}

.legal__updated {
	margin-top: 1.5rem;
}

.legal__body {
	margin-top: 3rem;
}

/* ────────────────────────────────────────────────────────── error ───── */

.error-page {
	display: flex;
	min-height: 70svh;
	flex-direction: column;
	justify-content: center;
	padding-block: 5rem;
}

.error-page__title {
	margin-top: 1.5rem;
	max-width: 48rem;
	color: var(--color-ink);
}

.error-page__body {
	margin-top: 1.75rem;
	max-width: 32rem;
	color: var(--color-ink-2);
}

.error-page__actions {
	margin-top: 2.5rem;
}


/*
 * Prescriptions — the order form block. The step list and FAQ reuse the
 * .split-block and .index-list patterns, so this page also links home.css.
 */

.prescription-order {
	background-color: var(--color-surface);
	padding-block: 5rem;
	/* Clears the fixed header when arriving at #order from another page. */
	scroll-margin-top: 5rem;
}

@media (width >= 64rem) {
	.prescription-order {
		padding-block: 7rem;
	}
}

.prescription-order__grid {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	column-gap: 2rem;
	row-gap: 3rem;
}

.prescription-order__aside,
.prescription-order__main {
	grid-column: span 12;
}

@media (width >= 64rem) {
	.prescription-order__aside {
		grid-column: span 4;
	}

	.prescription-order__main {
		grid-column: 6 / span 7;
	}
}

.prescription-order__title {
	margin-top: 1rem;
	color: var(--color-ink);
}

.prescription-order__body {
	margin-top: 1.5rem;
	max-width: 28rem;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: var(--color-ink-2);
}

.prescription-order__urgent {
	margin-top: 2rem;
}

.prescription-order__privacy {
	margin-top: 1rem;
	max-width: 32rem;
}

.prescription-order__confirmation-action {
	margin-top: 1.75rem;
}


/*
 * Product page — gallery, buy panel, composition tables, reviews.
 */

.product-page {
	padding-block: 2.5rem;
}

@media (width >= 64rem) {
	.product-page {
		padding-block: 3.5rem;
	}
}

.product-page__grid {
	margin-top: 2rem;
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	column-gap: 2rem;
	row-gap: 2.5rem;
}

/* Stacked by default; side by side from the large breakpoint up. This base rule
   must stay above the media query — same specificity, so source order decides. */
.product-gallery,
.product-buy {
	grid-column: span 12;
}

@media (width >= 64rem) {
	.product-page__grid {
		margin-top: 3rem;
	}

	.product-gallery {
		grid-column: span 6;
	}

	.product-buy {
		grid-column: 8 / span 5;
	}
}

/* ─────────────────────────────────────────────────────── gallery ───── */

.product-gallery__thumbnails {
	margin-top: 0.75rem;
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 0.75rem;
}

.product-gallery__thumbnail {
	display: block;
	width: 100%;
	border: 1px solid transparent;
	transition: border-color var(--duration-swift) var(--ease-linear-out);
}

.product-gallery__thumbnail:hover {
	border-color: var(--ink-25);
}

.product-gallery__thumbnail[aria-current='true'] {
	border-color: var(--color-signal);
}

/* ────────────────────────────────────────────────────── buy panel ───── */

.product-buy__tags {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.75rem;
}

.product-buy__name {
	margin-top: 1.25rem;
	color: var(--color-ink);
}

.product-buy__ingredient {
	margin-top: 0.5rem;
}

.product-buy__rating {
	margin-top: 1rem;
}

.product-buy__description {
	margin-top: 1.75rem;
	max-width: 60ch;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: var(--color-ink-2);
}

.product-buy__price-row {
	margin-top: 2rem;
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	column-gap: 1rem;
	row-gap: 0.5rem;
	border-top: 1px solid var(--color-line);
	padding-top: 1.5rem;
}

.product-buy__price {
	font-family: var(--font-mono);
	font-size: 1.5rem;
	color: var(--color-ink);
	font-variant-numeric: tabular-nums;
}

.product-buy__compare {
	font-family: var(--font-mono);
	font-size: 0.9375rem;
	color: var(--color-ink-4);
	text-decoration: line-through;
	font-variant-numeric: tabular-nums;
}

.product-buy__stock {
	margin-left: auto;
}

.product-buy__specification {
	margin-top: 0.5rem;
}

.product-buy__actions {
	margin-top: 1.5rem;
	display: flex;
	flex-wrap: wrap;
	align-items: stretch;
	gap: 0.75rem;
}

.product-buy__add {
	flex: 1;
}

.product-buy__limits {
	margin-top: 0.75rem;
}

.product-buy__note {
	margin-top: 2rem;
}

.product-buy__detail {
	margin-top: 2.5rem;
}

/* ─────────────────────────────────────────────────── composition ───── */

.composition__row {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	column-gap: 1.5rem;
	row-gap: 0.25rem;
	padding-block: 0.625rem;
	border-top: 1px solid var(--color-line);
}

.composition__row:first-child {
	border-top: 0;
}

.composition__name {
	font-size: 0.875rem;
	color: var(--color-ink);
}

.composition__amount {
	text-align: right;
}

/* A ruled tick rather than a bullet, in the warning colour. */
.warning-list__item {
	display: flex;
	gap: 0.75rem;
}

.warning-list__item + .warning-list__item {
	margin-top: 0.625rem;
}

.warning-list__tick {
	margin-top: 0.5rem;
	height: 1px;
	width: 0.75rem;
	flex: none;
	background-color: var(--color-danger);
}

/* ─────────────────────────────────────────────────────── reviews ───── */

.review-grid {
	display: grid;
	column-gap: 2rem;
}

@media (width >= 48rem) {
	.review-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

.review {
	border-bottom: 1px solid var(--color-line);
	padding-block: 1.75rem;
}

.review__head {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 0.75rem;
}

.review__title {
	margin-top: 0.75rem;
	font-weight: 600;
	color: var(--color-ink);
}

.review__body {
	margin-top: 0.5rem;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: var(--color-ink-2);
}

.review__author {
	margin-top: 0.75rem;
}

.product-related {
	margin-top: 2.5rem;
}


/*
 * Services — the intro bar, the ruled service entries, and the closing panel.
 */

.services-intro {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	column-gap: 2rem;
	row-gap: 1.5rem;
	border-bottom: 1px solid var(--color-ink);
	padding-bottom: 2rem;
}

.services-intro__copy {
	grid-column: span 12;
	max-width: 42rem;
	color: var(--color-ink-2);
}

.services-intro__action {
	grid-column: span 12;
}

@media (width >= 64rem) {
	.services-intro__copy {
		grid-column: span 7;
	}

	.services-intro__action {
		grid-column: 9 / span 4;
	}
}

/* ───────────────────────────────────────────────── service entries ───── */

.service-entry {
	border-bottom: 1px solid var(--color-line);
	/* Clears the fixed header when arriving from the mega menu. */
	scroll-margin-top: 7rem;
}

.service-entry__grid {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	column-gap: 2rem;
	row-gap: 1.5rem;
	padding-block: 2.5rem;
}

@media (width >= 64rem) {
	.service-entry__grid {
		padding-block: 3.5rem;
	}
}

.service-entry__headline {
	grid-column: span 12;
	display: flex;
	align-items: flex-start;
	gap: 1.25rem;
}

.service-entry__number {
	padding-top: 0.5rem;
}

.service-entry__name {
	color: var(--color-ink);
}

.service-entry__summary {
	margin-top: 0.75rem;
	max-width: 28rem;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: var(--color-ink-2);
}

.service-entry__description {
	grid-column: span 12;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: var(--color-ink-2);
}

.service-entry__meta {
	grid-column: span 12;
}

.service-entry__meta-row {
	margin-top: 0.75rem;
}

.service-entry__value {
	margin-top: 0.25rem;
	font-family: var(--font-mono);
	font-size: 0.875rem;
	color: var(--color-ink);
}

.service-entry__includes {
	grid-column: span 12;
	display: grid;
	column-gap: 2rem;
	row-gap: 0.5rem;
	border-top: 1px solid var(--color-line);
	padding-top: 1.5rem;
}

@media (width >= 40rem) {
	.service-entry__includes {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (width >= 64rem) {
	.service-entry__headline {
		grid-column: span 5;
	}

	.service-entry__description {
		grid-column: span 4;
	}

	.service-entry__meta {
		grid-column: 11 / span 2;
	}

	.service-entry__includes {
		grid-column: 2 / span 9;
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

.service-include {
	display: flex;
	gap: 0.75rem;
	font-size: 0.875rem;
	color: var(--color-ink-2);
}

/* A ruled tick rather than a bullet. */
.service-include__tick {
	margin-top: 0.625rem;
	height: 1px;
	width: 0.75rem;
	flex: none;
	background-color: var(--tpl-accent);
}

/* ──────────────────────────────────────────────────── closing panel ───── */

.services-cta {
	background-color: var(--color-signal);
	color: #fff;
	padding-block: 5rem;
}

@media (width >= 64rem) {
	.services-cta {
		padding-block: 7rem;
	}
}

.services-cta__grid {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	align-items: center;
	column-gap: 2rem;
	row-gap: 2rem;
}

.services-cta__copy {
	grid-column: span 12;
}

.services-cta__actions {
	grid-column: span 12;
}

@media (width >= 64rem) {
	.services-cta__copy {
		grid-column: span 7;
	}

	.services-cta__actions {
		grid-column: 9 / span 4;
	}
}

.services-cta__title {
	margin-top: 1.25rem;
	color: #fff;
}

.services-cta__body {
	margin-top: 1.25rem;
	max-width: 32rem;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: var(--paper-70);
}


/*
 * Shop — masthead, filter rail, results grid.
 *
 * The whole catalogue is in the page; js/shop-filters.js hides, shows and
 * reorders it. Nothing here depends on that script having run.
 */

.shop-masthead {
	position: relative;
	overflow: hidden;
	border-bottom: 1px solid var(--ink-10);
	background-color: var(--color-canvas-2);
}

.shop-masthead__inner {
	position: relative;
	padding-block: 4rem;
}

@media (width >= 64rem) {
	.shop-masthead__inner {
		padding-block: 5rem;
	}
}

.shop-masthead__title {
	margin-top: 1.75rem;
	max-width: 48rem;
	color: var(--color-ink);
}

.shop-masthead__lede {
	margin-top: 1.5rem;
	max-width: 36rem;
	color: var(--color-ink-2);
}

/* ─────────────────────────────────────────────────────── layout ───── */

.shop-layout {
	padding-block: 3rem;
}

@media (width >= 64rem) {
	.shop-layout {
		display: grid;
		grid-template-columns: repeat(12, minmax(0, 1fr));
		gap: 3rem;
		padding-block: 4rem;
	}

	.shop-filters {
		grid-column: span 3;
	}

	.shop-results {
		grid-column: span 9;
	}
}

/* ─────────────────────────────────────────────────────── filters ───── */

.filter-toggle {
	display: flex;
	width: 100%;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	border: 1px solid var(--ink-15);
	padding: 1rem 1.25rem;
	font-size: 0.875rem;
	font-weight: 500;
	color: var(--color-ink);
}

@media (width >= 64rem) {
	.filter-toggle {
		display: none;
	}
}

.filter-toggle__label {
	display: flex;
	align-items: center;
	gap: 0.625rem;
}

.filter-toggle__label svg {
	width: 1rem;
	height: 1rem;
}

.filter-toggle__count {
	display: grid;
	place-items: center;
	height: 1.5rem;
	min-width: 1.5rem;
	padding-inline: 0.375rem;
	background-color: var(--color-ink);
	color: #fff;
	font-size: 0.6875rem;
}

/*
 * Hidden on small screens until the toggle above opens it; always visible from
 * the large breakpoint up, where the rail has a column of its own.
 */
.filter-panel {
	display: none;
	margin-top: 1.5rem;
}

.filter-panel[data-open] {
	display: block;
}

@media (width >= 64rem) {
	.filter-panel {
		display: block;
		margin-top: 0;
	}
}

.filter-group + .filter-group,
.filter-panel > .checkbox-row,
.filter-panel > .filter-clear {
	margin-top: 2.25rem;
}

@media (width >= 64rem) {
	.filter-group + .filter-group,
	.filter-panel > .checkbox-row,
	.filter-panel > .filter-clear {
		margin-top: 2.5rem;
	}
}

.filter-search {
	position: relative;
	margin-top: 1rem;
}

.filter-search__input {
	height: 2.75rem;
	width: 100%;
	border: 1px solid var(--ink-15);
	background-color: var(--color-surface);
	padding-left: 2.5rem;
	padding-right: 1rem;
	font-size: 0.875rem;
	transition: border-color var(--duration-calm) var(--ease-linear-out);
}

.filter-search__input:hover {
	border-color: rgb(10 15 12 / 0.3);
}

.filter-search__input:focus {
	outline: none;
	border-color: var(--color-signal);
	box-shadow: 0 0 0 2px rgb(7 42 29 / 0.15);
}

.filter-search__icon {
	pointer-events: none;
	position: absolute;
	left: 0.875rem;
	top: 50%;
	transform: translateY(-50%);
	width: 1rem;
	height: 1rem;
	color: var(--color-ink-3);
}

.filter-options {
	margin-top: 1rem;
	display: flex;
	flex-direction: column;
	gap: 0.125rem;
}

.filter-option {
	display: flex;
	width: 100%;
	align-items: center;
	justify-content: space-between;
	gap: 0.75rem;
	padding: 0.5rem 0.75rem;
	text-align: left;
	font-size: 0.875rem;
	color: var(--color-ink-2);
	transition:
		background-color var(--duration-calm) var(--ease-linear-out),
		color var(--duration-calm) var(--ease-linear-out);
}

.filter-option:hover {
	background-color: var(--color-canvas-2);
}

.filter-option[aria-pressed='true'] {
	background-color: var(--color-signal);
	color: #fff;
}

.filter-option__count {
	font-size: 0.75rem;
	color: var(--color-ink-4);
}

.filter-option[aria-pressed='true'] .filter-option__count {
	color: var(--paper-60);
}

.filter-chips {
	margin-top: 1rem;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}

.filter-chip {
	padding: 0.5rem 0.875rem;
	background-color: var(--color-canvas-2);
	font-size: 0.8125rem;
	color: var(--color-ink-2);
	transition:
		background-color var(--duration-calm) var(--ease-linear-out),
		color var(--duration-calm) var(--ease-linear-out);
}

.filter-chip:hover {
	background-color: var(--color-ink-5);
}

.filter-chip[aria-pressed='true'] {
	background-color: var(--color-signal);
	color: #fff;
}

/* Thumb and track come from the shared .range-slider skin (css/components/forms.css) —
   this just places it in the filter column. */
.filter-range {
	margin-top: 1rem;
}

.filter-range__label {
	margin-top: 0.5rem;
	font-size: 0.8125rem;
	color: var(--color-ink-3);
}

.filter-clear {
	display: block;
	font-size: 0.8125rem;
	color: var(--color-ink-3);
	text-decoration: underline;
	text-underline-offset: 4px;
	transition: color var(--duration-swift) var(--ease-linear-out);
}

.filter-clear:hover {
	color: var(--color-danger);
}

/* ─────────────────────────────────────────────────────── results ───── */

.shop-results {
	margin-top: 2.5rem;
}

@media (width >= 64rem) {
	.shop-results {
		margin-top: 0;
	}
}

.shop-results__bar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	border-bottom: 1px solid var(--ink-10);
	padding-bottom: 1.25rem;
}

.shop-results__count {
	font-size: 0.875rem;
	color: var(--color-ink-2);
}

.shop-results__sort {
	display: flex;
	align-items: center;
	gap: 0.75rem;
}

.shop-results__sort-label {
	font-size: 0.8125rem;
	color: var(--color-ink-3);
}

.shop-results__select {
	height: 2.5rem;
	cursor: pointer;
	border: 1px solid var(--ink-15);
	background-color: var(--color-surface);
	padding-left: 1rem;
	padding-right: 2.25rem;
	font-size: 0.875rem;
	transition: border-color var(--duration-calm) var(--ease-linear-out);
}

.shop-results__select:hover {
	border-color: rgb(10 15 12 / 0.3);
}

.shop-results__select:focus {
	outline: none;
	border-color: var(--color-signal);
}

.shop-results__grid {
	margin-top: 2.5rem;
}

/* Each card sits in a wrapper the filter script can hide and reorder. */
.product-grid__cell {
	height: 100%;
}

.shop-empty {
	margin-top: 4rem;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 1.5rem;
	background-color: var(--color-canvas-2);
	padding: 5rem 2rem;
	text-align: center;
}

.shop-empty__title {
	color: var(--color-ink);
}

.shop-empty__body {
	margin-inline: auto;
	margin-top: 0.75rem;
	max-width: 24rem;
	font-size: 0.9375rem;
	color: var(--color-ink-2);
}

.shop-empty__actions {
	justify-content: center;
}

/*
 * Paging jumps here, and the header is fixed, so the results need to clear it.
 */
.shop-results {
	scroll-margin-top: calc(var(--header-height) + 1rem);
}

/* ────────────────────────────────────────────────────── pagination ───── */

/*
 * Paging jumps here, and the header is fixed, so the results need to clear it.
 * The pager itself is a shared component — css/components/pager.css.
 */
.shop-results {
	scroll-margin-top: calc(var(--header-height) + 1rem);
}


/*
 * A1 Pharmacy — design tokens
 * ---------------------------
 * Spacious, minimal, technical. The reference is medical instrumentation and
 * product design, not botany: a near-white canvas, near-black ink, one
 * saturated pharmacy green, and monospace for every number.
 *
 * Deliberate constraints:
 *   · Square corners. No decorative radius anywhere.
 *   · Two typefaces only — a technical grotesque and a mono for data.
 *   · Colour is structural, never ornamental. Green means "pharmacy", and is
 *     used for action and status, never as a wash or a tint.
 *   · Space does the work that decoration would otherwise do.
 *
 * Every value the rest of the stylesheets use is declared here. Rebranding the
 * template is, in the ordinary case, a matter of editing this file alone.
 */

:root {
	/* ---------------------------------------------------------------- fonts */
	/* Archivo carries width and weight axes, so display and interface text can
	   share one family without the headline looking like enlarged body copy. */
	--font-sans: 'Archivo Variable', ui-sans-serif, system-ui, -apple-system, sans-serif;
	--font-display: 'Archivo Variable', ui-sans-serif, system-ui, sans-serif;
	/* Doses, prices, reference numbers, timestamps. */
	--font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;

	/* --------------------------------------------------------------- canvas */
	/* Cool and clinical rather than warm — this is a dispensary, not a spa. */
	--color-canvas: #f2f3f1;
	--color-canvas-2: #e7e9e6;
	--color-surface: #ffffff;
	--color-line: #d8dcd8;

	/* ------------------------------------------------------------------ ink */
	--color-ink: #0a0f0c;
	--color-ink-2: #363c38;
	--color-ink-3: #666d68;
	--color-ink-4: #969c98;
	--color-ink-5: #c2c7c3;

	/* --------------------------------------------------------------- signal */
	/* Dark green is the brand: large flat fields, primary actions, dark
	   sections. Deep enough to carry white type at any size, and to make the
	   yellow-green accent sing against it. */
	--color-signal: #072a1d;
	--color-signal-dark: #041b12;
	--color-signal-bright: #0f4530;
	--color-signal-tint: #e0e9e4;

	/* --------------------------------------------------------------- accent */
	/* Yellow-green. Deployed sparingly and at small scale — live status, the
	   active progress segment, hover states, and the one thing on a page that
	   must be found. Never as a background for body text. */
	--tpl-accent: #cdeb3f;
	--tpl-accent-dark: #a8c422;
	--tpl-accent-tint: #f2f8d4;

	/* ------------------------------------------------------------- semantic */
	--color-danger: #c8321a;
	--color-danger-tint: #fbe7e3;
	--color-caution: #a76a00;
	--color-caution-tint: #fdf0da;

	/* Translucent ink and paper, for hairlines drawn over unknown backgrounds. */
	--ink-08: rgb(10 15 12 / 0.08);
	--ink-10: rgb(10 15 12 / 0.1);
	--ink-12: rgb(10 15 12 / 0.12);
	--ink-15: rgb(10 15 12 / 0.15);
	--ink-20: rgb(10 15 12 / 0.2);
	--ink-25: rgb(10 15 12 / 0.25);
	--ink-70: rgb(10 15 12 / 0.7);
	--paper-10: rgb(255 255 255 / 0.1);
	--paper-12: rgb(255 255 255 / 0.12);
	--paper-15: rgb(255 255 255 / 0.15);
	--paper-20: rgb(255 255 255 / 0.2);
	--paper-25: rgb(255 255 255 / 0.25);
	--paper-30: rgb(255 255 255 / 0.3);
	--paper-45: rgb(255 255 255 / 0.45);
	--paper-55: rgb(255 255 255 / 0.55);
	--paper-60: rgb(255 255 255 / 0.6);
	--paper-70: rgb(255 255 255 / 0.7);
	--paper-75: rgb(255 255 255 / 0.75);
	--paper-80: rgb(255 255 255 / 0.8);

	/* ------------------------------------------------------------ type scale */
	/* A wide gap between display and interface sizes. Big statements, small
	   precise everything-else — that contrast is what reads as spacious. */
	--text-d1: clamp(2.75rem, 7.5vw, 7rem);
	--leading-d1: 0.94;
	--tracking-d1: -0.035em;

	--text-d2: clamp(2.25rem, 5vw, 4.5rem);
	--leading-d2: 0.98;
	--tracking-d2: -0.032em;

	--text-d3: clamp(1.75rem, 3.2vw, 2.75rem);
	--leading-d3: 1.04;
	--tracking-d3: -0.026em;

	--text-h1: clamp(1.5rem, 2.4vw, 2rem);
	--leading-h1: 1.12;
	--tracking-h1: -0.022em;

	--text-h2: clamp(1.25rem, 1.8vw, 1.5rem);
	--leading-h2: 1.2;
	--tracking-h2: -0.018em;

	--text-h3: 1.0625rem;
	--leading-h3: 1.35;
	--tracking-h3: -0.012em;

	--text-lead: clamp(1rem, 1.15vw, 1.125rem);
	--leading-lead: 1.62;
	--tracking-lead: -0.008em;

	/* Monospace label — section markers, field labels, metadata. */
	--text-label: 0.6875rem;
	--tracking-label: 0.12em;

	--text-data: 0.75rem;
	--leading-data: 1.5;
	--tracking-data: 0.005em;

	/* --------------------------------------------------------------- easing */
	--ease-precise: cubic-bezier(0.16, 1, 0.3, 1);
	--ease-linear-out: cubic-bezier(0.25, 0.46, 0.45, 0.94);
	--ease-glide: cubic-bezier(0.65, 0, 0.35, 1);
	/* The reveal curve. Named separately so motion can be retimed on its own. */
	--ease-archive: cubic-bezier(0.16, 1, 0.3, 1);

	/* ------------------------------------------------------------- duration */
	--duration-swift: 150ms;
	--duration-calm: 320ms;
	--duration-slow: 600ms;

	/* ---------------------------------------------------------------- shell */
	/* Page gutters, widened at each breakpoint. */
	--shell-max: 96rem;
	--shell-max-tight: 48rem;
	--shell-max-wide: 120rem;
	--shell-gutter: 1.25rem;

	/* --------------------------------------------------------------- header */
	--header-height: 4rem;

	/* -------------------------------------------------------------- shadows */
	/* Barely there. Depth comes from rules and tone. */
	--shadow-card: 0 1px 2px rgb(11 12 11 / 0.04), 0 16px 32px -24px rgb(11 12 11 / 0.3);
	--shadow-raised: 0 24px 48px -32px rgb(11 12 11 / 0.4);

	/* ---------------------------------------------------------------- layer */
	--z-rail: 40;
	--z-header: 50;
	--z-overlay: 60;
	--z-toast: 100;
	--z-skip: 120;
}

@media (width >= 40rem) {
	:root {
		--shell-gutter: 2rem;
	}
}

@media (width >= 64rem) {
	:root {
		--shell-gutter: 3rem;
		--header-height: 4.5rem;
	}
}


/*
 * Typography — the type scale, the monospace label system, and long-form prose.
 *
 * Two families do all the work. Display sizes (`.text-d1` … `.text-h3`) are
 * Archivo; anything that is data rather than prose (`.label`, `.data`,
 * `.index-no`) is IBM Plex Mono, uppercase, and letterspaced.
 */

/* ─────────────────────────────────────────────────── display scale ───── */

.text-d1 {
	font-size: var(--text-d1);
	line-height: var(--leading-d1);
	letter-spacing: var(--tracking-d1);
}

.text-d2 {
	font-size: var(--text-d2);
	line-height: var(--leading-d2);
	letter-spacing: var(--tracking-d2);
}

.text-d3 {
	font-size: var(--text-d3);
	line-height: var(--leading-d3);
	letter-spacing: var(--tracking-d3);
}

.text-h1 {
	font-size: var(--text-h1);
	line-height: var(--leading-h1);
	letter-spacing: var(--tracking-h1);
}

.text-h2 {
	font-size: var(--text-h2);
	line-height: var(--leading-h2);
	letter-spacing: var(--tracking-h2);
}

.text-h3 {
	font-size: var(--text-h3);
	line-height: var(--leading-h3);
	letter-spacing: var(--tracking-h3);
}

/* Display classes are often applied to <p> and <span>; make the family stick. */
.text-d1,
.text-d2,
.text-d3,
.text-h1,
.text-h2,
.text-h3 {
	font-family: var(--font-display);
	font-stretch: 96%;
	text-wrap: balance;
}

/* The standfirst paragraph that follows a headline. */
.text-lead {
	font-size: var(--text-lead);
	line-height: var(--leading-lead);
	letter-spacing: var(--tracking-lead);
}

/* ──────────────────────────────────────────────── the label system ───── */

/*
 * The monospace label. Section markers, field labels, product metadata —
 * anything that is data rather than prose.
 */
.label {
	display: block;
	font-family: var(--font-mono);
	font-size: var(--text-label);
	line-height: 1;
	letter-spacing: var(--tracking-label);
	text-transform: uppercase;
	font-weight: 400;
	color: var(--color-ink-3);
}

.label--ink {
	color: var(--color-ink);
}

.label--light {
	color: var(--paper-55);
}

.label--signal {
	color: var(--color-signal);
}

.label--accent {
	color: var(--tpl-accent);
}

.label--danger {
	color: var(--color-danger);
}

/*
 * Section marker. A short accent rule ahead of the label — the main way the
 * yellow-green reads on a resting page.
 */
.label--mark {
	display: flex;
	align-items: center;
	gap: 0.7rem;
}

.label--mark::before {
	content: '';
	width: 1.5rem;
	height: 3px;
	flex: none;
	background-color: var(--tpl-accent);
}

.label--centred {
	justify-content: center;
}

/* Metadata rows: "Capsules · 120 · 60 days" */
.data {
	font-family: var(--font-mono);
	font-size: var(--text-data);
	line-height: var(--leading-data);
	letter-spacing: var(--tracking-data);
	color: var(--color-ink-3);
}

.data--ink {
	color: var(--color-ink);
}

.data--signal {
	color: var(--color-signal);
}

.data--danger {
	color: var(--color-danger);
}

.data--light {
	color: var(--paper-60);
}

/* Item number in an index. */
.index-no {
	font-family: var(--font-mono);
	font-size: var(--text-label);
	line-height: 1;
	letter-spacing: 0.06em;
	color: var(--color-ink-4);
	font-variant-numeric: tabular-nums;
}

/* ───────────────────────────────────────────────────────── links ───── */

/* Underline that draws in from the leading edge. */
.link-rule {
	position: relative;
	display: inline-block;
}

.link-rule::after {
	content: '';
	position: absolute;
	left: 0;
	bottom: -0.18em;
	width: 100%;
	height: 1px;
	background-color: currentColor;
	transform: scaleX(0);
	transform-origin: right;
	transition: transform var(--duration-calm) var(--ease-precise);
}

.link-rule:hover::after,
.link-rule:focus-visible::after {
	transform: scaleX(1);
	transform-origin: left;
}

/* ────────────────────────────────────────────────────────── prose ───── */

/* Long-form editorial typography. Applied to a wrapper; styles descendants. */
.prose {
	color: var(--color-ink-2);
	font-size: 1.0625rem;
	line-height: 1.7;
}

.prose > * + * {
	margin-top: 1.4em;
}

.prose h2 {
	margin-top: 2.4em;
	font-size: var(--text-h1);
	line-height: var(--leading-h1);
	letter-spacing: var(--tracking-h1);
	color: var(--color-ink);
}

.prose h3 {
	margin-top: 1.9em;
	font-size: var(--text-h2);
	line-height: var(--leading-h2);
	color: var(--color-ink);
}

.prose a {
	color: var(--color-signal);
	text-decoration: underline;
	text-underline-offset: 0.18em;
	text-decoration-thickness: 1px;
	text-decoration-color: color-mix(in oklab, var(--color-signal) 40%, transparent);
	transition: text-decoration-color var(--duration-swift) var(--ease-linear-out);
}

.prose a:hover {
	text-decoration-color: currentColor;
}

.prose strong {
	color: var(--color-ink);
	font-weight: 600;
}

.prose ul,
.prose ol {
	padding-left: 1.5em;
}

.prose ul {
	list-style: none;
}

.prose ul > li {
	position: relative;
}

/* A ruled tick rather than a bullet. */
.prose ul > li::before {
	content: '';
	position: absolute;
	left: -1.3em;
	top: 0.75em;
	width: 0.7em;
	height: 3px;
	background-color: var(--tpl-accent);
}

.prose ol {
	list-style: decimal;
}

.prose li + li {
	margin-top: 0.5em;
}

.prose blockquote {
	padding-left: 1.5rem;
	border-left: 3px solid var(--tpl-accent);
	font-size: var(--text-h1);
	line-height: 1.3;
	letter-spacing: -0.02em;
	color: var(--color-ink);
}

.prose figure figcaption {
	font-family: var(--font-mono);
	margin-top: 0.85rem;
	font-size: var(--text-data);
	color: var(--color-ink-3);
}


/*
 * Utilities — the small set of single-purpose classes the template leans on.
 *
 * Kept deliberately short. If a rule describes what something *is* rather than
 * one property it sets, it belongs in components/ instead.
 */

/* ────────────────────────────────────────────────────────── shell ───── */

/* Page gutter. Every full-width section wraps its contents in one of these. */
.shell {
	width: 100%;
	margin-inline: auto;
	max-width: var(--shell-max);
	padding-inline: var(--shell-gutter);
}

/*
 * Reading measure — legal pages and article bodies.
 *
 * Deliberately keeps the narrower gutter: --shell-gutter widens to 3rem on
 * large screens, which would eat into a column that is only 48rem wide to
 * begin with.
 */
.shell--tight {
	max-width: var(--shell-max-tight);
	padding-inline: 1.25rem;
}

@media (width >= 40rem) {
	.shell--tight {
		padding-inline: 2rem;
	}
}

.shell--wide {
	max-width: var(--shell-max-wide);
}

/* ────────────────────────────────────────────────────────── rules ───── */

/* Hairlines — the primary structural device in the design. */
.rule-t {
	border-top: 1px solid var(--color-line);
}

.rule-b {
	border-bottom: 1px solid var(--color-line);
}

/* Emphatic rule: full-strength ink, used to open a major section. */
.rule-t--strong {
	border-top-color: var(--color-ink);
}

.rule-b--strong {
	border-bottom-color: var(--color-ink);
}

/* On dark surfaces the hairline becomes translucent paper. */
[data-surface='dark'] .rule-t,
.rule-t--light {
	border-top-color: var(--paper-10);
}

[data-surface='dark'] .rule-b,
.rule-b--light {
	border-bottom-color: var(--paper-10);
}

/* ──────────────────────────────────────────────────────── section ───── */

/*
 * Vertical rhythm between major page sections. Three steps, largest first:
 *
 *   .section          the home page's generous spacing
 *   .section--page    interior pages (About, Services, Prescriptions)
 *   .section--snug    dense, listing-style pages (Shop, Journal, Bag, Account)
 */
.section {
	padding-block: 6rem;
}

.section--page {
	padding-block: 5rem;
}

.section--snug {
	padding-block: 3rem;
}

@media (width >= 64rem) {
	.section {
		padding-block: 8rem;
	}

	.section--page {
		padding-block: 7rem;
	}

	.section--snug {
		padding-block: 4rem;
	}
}

/* Trims the padding on one edge where two sections butt together. */
.section--flush-top {
	padding-top: 0;
}

.section--flush-bottom {
	padding-bottom: 0;
}

/* ───────────────────────────────────────────────────── structure ───── */

/* Places children in one cell so they can be layered. */
.stack {
	display: grid;
	grid-template-areas: 'stack';
}

.stack > * {
	grid-area: stack;
}

/* The twelve-column grid the editorial pages are set on. */
.grid-12 {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	column-gap: 2rem;
	row-gap: 2rem;
}

/* ───────────────────────────────────────────────── accessibility ───── */

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

/* Hidden until focused — the skip link. */
.visually-hidden-focusable:not(:focus):not(:focus-within) {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border-width: 0;
}

/* Applied by JavaScript to elements whose visibility it controls. */
[hidden] {
	display: none !important;
}


/* ===== whitegen hooks: наши шрифты и палитры ===== */
:root {
  --font-display: var(--font-heading), "Archivo", sans-serif;
  --font-sans: var(--font-body), "Archivo", sans-serif;
}
/* акцент палитры генератора -> фирменный тёмный цвет шаблона (signal,
   на нём белый текст) и светлый акцент (на нём тёмный текст) — контраст
   сохраняется при любой палитре */
@supports (color: color-mix(in srgb, red, blue)) {
  :root {
    --color-signal: color-mix(in srgb, var(--color-accent, #0f4530) 55%, #000);
    --color-signal-dark: color-mix(in srgb, var(--color-accent, #0f4530) 38%, #000);
    --color-signal-bright: color-mix(in srgb, var(--color-accent, #0f4530) 75%, #000);
    --color-signal-tint: color-mix(in srgb, var(--color-accent, #0f4530) 12%, #fff);
    --tpl-accent: color-mix(in srgb, var(--color-accent, #a8c422) 38%, #fff);
    --tpl-accent-dark: color-mix(in srgb, var(--color-accent, #a8c422) 55%, #fff);
    --tpl-accent-tint: color-mix(in srgb, var(--color-accent, #a8c422) 12%, #fff);
  }
}



@font-face {
    font-family: 'Raleway';
    src: url('fonts/raleway-400.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Raleway';
    src: url('fonts/raleway-700.woff2') format('woff2');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Archivo';
    src: url('fonts/archivo-400.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Archivo';
    src: url('fonts/archivo-700.woff2') format('woff2');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

:root {
    --font-heading: 'Raleway';
    --font-body: 'Archivo';
}


:root {
    --color-bg: #160f1a;
    --color-bg-alt: #211729;
    --color-text: #f3edf7;
    --color-muted: #b3a3bd;
    --color-accent: #c14fd6;
}