/* ═══════════════════════════════════════════════════════════════
   Velmont Dials — storefront
   ═══════════════════════════════════════════════════════════════

   Ink on cream. An achromatic luxury palette: ink for every brand surface,
   hairline borders instead of tint. The two panel washes carry a trace of
   warmth so plates read as paper rather than grey.

   Depth is expressed with borders, surfaces and rings — this sheet ships zero
   box-shadows on the storefront by design. Only focus rings are allowed to
   break that rule, because they have to be visible.
   ═════════════════════════════════════════════════════════════ */

/* ── The brand face ──────────────────────────────────────────────
   Monterchi Serif is a commercial family; the licensed Regular and Bold are
   self-hosted here, and the bold face covers 600–700 because no SemiBold is
   licensed. Anything the files do not cover falls through to Cormorant. */

@font-face {
	font-family: "Monterchi Serif";
	src:
		local("Monterchi Serif"),
		local("MonterchiSerif-Regular"),
		url("../fonts/MonterchiSerif-Regular.ttf") format("truetype");
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: "Monterchi Serif";
	src:
		local("Monterchi Serif Bold"),
		local("MonterchiSerif-Bold"),
		url("../fonts/MonterchiSerif-Bold.ttf") format("truetype");
	font-weight: 600 700;
	font-style: normal;
	font-display: swap;
}

/* ── Design tokens ─────────────────────────────────────────── */

:root {
	--font-heading: "Monterchi Serif", "Cormorant Garamond", Georgia, "Times New Roman", serif;
	--font-body: "Montserrat", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;

	/* Brand surfaces.

	   Still ink on cream, still achromatic in effect — every neutral simply
	   carries a trace of the same warm hue (~70) instead of being a true grey,
	   so the paper reads as paper under a warm light rather than as screen
	   white. The chroma values are deliberately tiny; anything higher and this
	   becomes the cream-and-brass artisan palette, which is a default, not a
	   decision. Gilt stays reserved for ratings alone. */
	--brand: oklch(0.19 0.006 60);          /* ink, the "brand" colour          */
	--brand-strong: oklch(0.115 0.006 60);  /* pressed / near-black             */
	--brand-accent: oklch(0.44 0.005 60);   /* graphite, for rules and marks    */
	--brand-ink: oklch(0.172 0.008 70);     /* ground for the dark bands        */
	--brand-gilt: oklch(0.795 0.052 85);    /* the one warmed mark — ratings    */
	--brand-soft: oklch(0.963 0.008 85);    /* cream panel wash                 */
	--brand-muted: oklch(0.925 0.009 85);   /* tinted surface                   */
	--brand-foreground: oklch(1 0 0);

	--background: oklch(0.994 0.003 85);    /* paper, not screen white          */
	--foreground: oklch(0.185 0.006 60);
	--card: oklch(1 0 0);
	--muted-foreground: oklch(0.505 0.008 70);
	--border: oklch(0.905 0.004 85);
	/* The finest rule the sheet draws. Used where a hairline is structure
	   rather than a boundary, so it should be felt more than seen. */
	--border-soft: oklch(0.935 0.004 85);
	--ring: oklch(0.44 0.005 60);
	--destructive: oklch(0.577 0.245 27.325);
	--success: oklch(0.62 0.16 152);
	--whatsapp: #1aab52;

	/* Tighter than before. A case-maker's radius: present, precise, and never
	   the first thing you notice about a plate. */
	--radius: 0.5rem;
	--radius-sm: calc(var(--radius) * 0.6);

	--ease: cubic-bezier(0.22, 1, 0.36, 1);

	--shell: 80rem;         /* max-w-7xl                        */
	--gutter: 1.5rem;       /* px-6                             */

	/* ── The scroll runtime's tokens ──────────────────────────────
	   scrollcraft.css ships its own palette and type ramp. It loads before
	   this sheet, so re-point its six colour roles at the Velmont ones here
	   and the engine's devices inherit the brand rather than the default.
	   The engine's `--sc-*` names are the only ones it reads; nothing above
	   is renamed. */
	--sc-canvas: var(--background);
	--sc-surface: var(--brand-soft);
	--sc-ink: var(--foreground);
	--sc-ink-soft: var(--muted-foreground);
	--sc-accent: var(--brand);
	--sc-accent-ink: var(--brand-foreground);
	--sc-font-display: var(--font-heading);
	--sc-font-text: var(--font-body);
	--sc-ease-out: var(--ease);
}

@media (min-width: 640px) {
	:root { --gutter: 2rem; }
}

@media (min-width: 1024px) {
	:root { --gutter: 2.5rem; }
}

/* ── Reset ───────────────────────────────────────────────────── */

*,
*::before,
*::after {
	box-sizing: border-box;
	border: 0 solid var(--border);
}

* {
	margin: 0;
	padding: 0;
}

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
	height: 100%;
}

body {
	min-height: 100%;
	display: flex;
	flex-direction: column;
	background: var(--background);
	color: var(--foreground);
	font-family: var(--font-body);
	font-size: 16px;
	line-height: 1.5;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

/* The storefront's headings take the serif brand face; small uppercase labels
   opt back out with `.font-body`. The admin panel has its own sheet and keeps
   an all-sans hierarchy. */
h1, h2, h3, h4, h5, h6 {
	font-family: var(--font-heading);
	font-weight: 500;
	letter-spacing: 0.01em;
	line-height: 1.15;
}

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

/* `hidden` has to outrank the component rules below it.
   The attribute's own UA rule is `display: none` at the lowest specificity, so
   any `.thing { display: flex }` silently defeats it — which is how a hidden
   search form, an empty cart badge and every closed submenu all end up on
   screen at once. This is the one place the sheet reaches for !important. */
[hidden] {
	display: none !important;
}

img { height: auto; }

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

button, input, select, textarea {
	font: inherit;
	color: inherit;
	background: none;
}

ul, ol { list-style: none; }

::selection {
	background-color: var(--brand-muted);
	color: var(--brand-strong);
}

/* Every clickable control gets a pointer cursor. */
button,
summary,
[role="button"],
label:has(> input[type="file"]) {
	cursor: pointer;
}

button:disabled,
[aria-disabled="true"] {
	cursor: not-allowed;
}

:focus-visible {
	outline: 2px solid var(--brand-accent);
	outline-offset: 2px;
}

/* ── The scroll runtime, made safe to lose ────────────────────────
   scrollcraft.css parks `[data-sc-cue]`, `[data-sc-in]` and the children of
   `[data-sc-stagger]` at zero opacity and waits for the engine to bring them
   in. That is correct for a page whose only job is the choreography, and
   wrong here: with JavaScript off, or with the script blocked, it would hide
   the house standard and the arrivals strip outright.

   The engine puts `.sc-ready` on the document element the moment it mounts,
   so the hidden state is scoped to the one condition under which something is
   guaranteed to undo it. Everywhere else the page renders complete and
   static, which is the same promise the cart and the checkout already make. */
:root:not(.sc-ready) [data-sc-cue],
:root:not(.sc-ready) [data-sc-in],
:root:not(.sc-ready) [data-sc-stagger] > * {
	opacity: 1;
	transform: none;
}

/* Form controls signal focus with a darker 1px border instead of a ring. */
input:focus,
input:focus-visible,
select:focus,
select:focus-visible,
textarea:focus,
textarea:focus-visible {
	outline: none;
	box-shadow: none;
}

.sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border-width: 0;
}

.skip-link {
	position: absolute;
	top: -100%;
	left: 1rem;
	z-index: 200;
	padding: 0.75rem 1.25rem;
	background: var(--brand);
	color: #fff;
	border-radius: var(--radius-sm);
	font-size: 0.85rem;
}

.skip-link:focus {
	top: 1rem;
}

/* ── Layout primitives ───────────────────────────────────────── */

.shell {
	width: 100%;
	max-width: var(--shell);
	margin-inline: auto;
	padding-inline: var(--gutter);
}

main { flex: 1 1 auto; }

/* Fluid so a phone does not inherit desktop air, and generous at the top end:
   the space between bands is what makes each one read as its own surface. */
.section {
	padding-block: clamp(5rem, 9vw, 9rem);
}

.section--tight { padding-block: 0 clamp(5rem, 9vw, 9rem); }

/* `--tight` drops the top padding because the band above is normally a light
   surface that has already left air. The vitrine is not: its pinned stage ends
   flush on a dark edge, so the next heading would sit hard against it. Put the
   air back at that one boundary, and keep it larger than the gap below the
   heading, because the space belongs to the seam between bands. */
.vitrine + .section--tight { padding-top: clamp(4.5rem, 8vw, 8rem); }

/* The rule under every section title.

   The gap above the rule is larger than the gap below it, because the space
   belongs to the boundary between bands rather than to the title-and-grid
   pair beneath. */
.section-head {
	border-bottom: 1px solid var(--border-soft);
	padding-bottom: 1.75rem;
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 1.5rem;
}

.section-title {
	font-size: clamp(2.25rem, 5vw, 3.75rem);
	letter-spacing: -0.025em;
	text-wrap: balance;
	color: var(--foreground);
}

.section-meta {
	font-family: var(--font-body);
	font-size: 0.875rem;
	color: color-mix(in oklch, var(--foreground) 68%, transparent);
}

.eyebrow {
	font-family: var(--font-body);
	font-size: 0.7rem;
	text-transform: uppercase;
	letter-spacing: 0.18em;
	/* Measured on the render rather than picked by eye: at 50% this label sat
	   at 3.5:1 on the paper ground, and it is body-sized text. */
	color: color-mix(in oklch, var(--foreground) 66%, transparent);
}

.font-body { font-family: var(--font-body); }

/* ═══ Buttons ══════════════════════════════════════════════════
   Square-cornered, matching the plates and panels. Motion is three layered,
   shadow-free effects: a hover lift, a press compression, and a light band
   that sweeps across the face. */

.btn {
	position: relative;
	isolation: isolate;
	display: inline-flex;
	flex-shrink: 0;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	height: 3rem;
	padding-inline: 1.75rem;
	overflow: hidden;
	border: 1px solid transparent;
	border-radius: var(--radius-sm);
	background-clip: padding-box;
	font-family: var(--font-body);
	font-size: 0.875rem;
	font-weight: 500;
	white-space: nowrap;
	user-select: none;
	cursor: pointer;
	transition:
		color 0.35s var(--ease),
		background-color 0.35s var(--ease),
		border-color 0.35s var(--ease),
		transform 0.35s var(--ease);
}

.btn:hover:not(:disabled) { transform: translateY(-2px); }

.btn:active:not(:disabled) {
	transform: translateY(0) scale(0.975);
	transition-duration: 0.09s;
}

.btn:disabled,
.btn[aria-disabled="true"] {
	pointer-events: none;
	opacity: 0.45;
}

/* The sheen: a light band travelling across the face on hover. `--sheen` is
   white on the solid ink face; light-surfaced buttons take an ink tint. */
.btn::before {
	content: "";
	position: absolute;
	inset: -1px;
	z-index: -1;
	border-radius: inherit;
	background: linear-gradient(100deg, transparent 20%, var(--sheen, rgb(255 255 255 / 0.32)) 48%, transparent 76%);
	transform: translateX(-120%);
	transition: transform 0.85s var(--ease);
}

.btn:hover:not(:disabled)::before { transform: translateX(120%); }

.btn svg {
	width: 1rem;
	height: 1rem;
	flex-shrink: 0;
	pointer-events: none;
	transition: transform 0.35s var(--ease);
}

.btn:hover [data-icon="inline-end"] { transform: translateX(3px); }
.btn:hover [data-icon="inline-start"] { transform: translateX(-3px); }

.btn--primary {
	background: var(--brand);
	color: var(--brand-foreground);
}

.btn--primary:hover:not(:disabled) { background: var(--brand-strong); }

/* Hover is the sheen alone — border and fill hold still. */
.btn--outline {
	border-color: color-mix(in oklch, var(--brand) 25%, transparent);
	background: #fff;
	color: var(--brand);
	--sheen: color-mix(in oklch, var(--brand) 16%, transparent);
}

.btn--outline-light {
	border-color: rgb(255 255 255 / 0.35);
	background: transparent;
	color: #fff;
}

.btn--outline-light:hover:not(:disabled) {
	border-color: rgb(255 255 255 / 0.6);
	background: rgb(255 255 255 / 0.08);
}

.btn--secondary {
	background: var(--brand-soft);
	color: var(--brand);
	--sheen: color-mix(in oklch, var(--brand) 16%, transparent);
}

.btn--ghost {
	color: color-mix(in oklch, var(--foreground) 80%, transparent);
	--sheen: color-mix(in oklch, var(--brand) 16%, transparent);
}

.btn--ghost:hover:not(:disabled) {
	background: var(--brand-soft);
	color: var(--brand);
}

.btn--destructive {
	background: color-mix(in oklch, var(--destructive) 10%, transparent);
	color: var(--destructive);
	--sheen: color-mix(in oklch, var(--destructive) 16%, transparent);
}

.btn--sm {
	height: 2.5rem;
	padding-inline: 1.5rem;
	font-size: 0.75rem;
	letter-spacing: 0.2em;
}

.btn--lg {
	height: 3.5rem;
	padding-inline: 2.25rem;
	font-size: 1rem;
}

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

.btn--upper {
	text-transform: uppercase;
	font-size: 0.75rem;
	letter-spacing: 0.2em;
}

/* Icon-only buttons stay circular: a round target is the clearer affordance
   for a bare glyph. */
.btn--icon {
	width: 3rem;
	height: 3rem;
	padding: 0;
	border-radius: 9999px;
}

.btn--icon-sm {
	width: 2.5rem;
	height: 2.5rem;
	padding: 0;
	border-radius: 9999px;
}

.btn--icon svg,
.btn--icon-sm svg {
	width: 1.25rem;
	height: 1.25rem;
}

/* Underline links sweep in from the leading edge. */
.link-underline {
	position: relative;
	transition: color 0.3s var(--ease);
}

.link-underline::after {
	content: "";
	position: absolute;
	bottom: -2px;
	left: 0;
	height: 1px;
	width: 100%;
	background: currentColor;
	transform: scaleX(0);
	transform-origin: right;
	transition: transform 0.35s var(--ease);
}

.link-underline:hover::after {
	transform: scaleX(1);
	transform-origin: left;
}

/* ═══ Header ═══════════════════════════════════════════════════
   On the homepage the bar floats over the hero, transparent, in white and
   glass. Everywhere else it is sticky with a frosted pane behind it. */

.site-header {
	position: sticky;
	top: 0;
	z-index: 40;
	isolation: isolate;
	border-bottom: 1px solid rgb(0 0 0 / 0.06);
	background: color-mix(in oklch, var(--background) 75%, transparent);
	backdrop-filter: blur(20px) saturate(150%);
	-webkit-backdrop-filter: blur(20px) saturate(150%);
}

.site-header--overlay {
	position: absolute;
	inset-inline: 0;
	top: 0;
	border-bottom-color: transparent;
	background: transparent;
	backdrop-filter: none;
	-webkit-backdrop-filter: none;
}

/* Any open panel needs a solid surface to stay legible against whatever
   scrolls beneath it, so the overlay drops its transparency. */
.site-header--overlay.is-open {
	background: color-mix(in oklch, var(--background) 95%, transparent);
	backdrop-filter: blur(20px);
	-webkit-backdrop-filter: blur(20px);
}

.header-bar {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 2rem;
	padding-block: 1.5rem;
}

.header-bar--mobile {
	padding-block: 1rem;
	gap: 0.75rem;
}

@media (min-width: 1024px) {
	.header-bar--mobile { display: none; }
}

.header-desktop { display: none; }

@media (min-width: 1024px) {
	.header-desktop { display: block; }
}

.header-side {
	display: flex;
	align-items: center;
	width: 17rem;
	flex-shrink: 0;
	gap: 0.5rem;
}

.header-side--end { justify-content: flex-end; }

.header-mobile-brand {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	pointer-events: none;
}

.header-mobile-brand > a { pointer-events: auto; }

.header-nav {
	display: flex;
	flex: 1 1 auto;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 0.5rem 2rem;
}

.header-nav__link {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	white-space: nowrap;
	font-size: 0.875rem;
	text-transform: uppercase;
	color: color-mix(in oklch, var(--foreground) 85%, transparent);
	transition: color 0.25s var(--ease);
	background: none;
	border: 0;
	cursor: pointer;
}

.header-nav__link:hover,
.header-nav__link[aria-expanded="true"] { color: var(--brand); }

.header-nav__link svg {
	width: 0.875rem;
	height: 0.875rem;
	transition: transform 0.25s var(--ease);
}

.header-nav__link[aria-expanded="true"] svg { transform: rotate(180deg); }

/* Glass discs. Translucent, so they sit *in* the frosted bar rather than on
   it — white glass over the hero, tinted ink everywhere else. */
.header-icon {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 3rem;
	height: 3rem;
	border: 1px solid rgb(0 0 0 / 0.06);
	border-radius: 9999px;
	background: rgb(0 0 0 / 0.04);
	color: color-mix(in oklch, var(--foreground) 85%, transparent);
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
	transition: border-color 0.25s var(--ease), background-color 0.25s var(--ease),
		color 0.25s var(--ease), transform 0.35s var(--ease);
	cursor: pointer;
}

.header-icon:hover {
	transform: translateY(-2px);
	border-color: rgb(0 0 0 / 0.15);
	background: rgb(0 0 0 / 0.07);
	color: var(--foreground);
}

.header-icon svg {
	width: 1.25rem;
	height: 1.25rem;
}

.header-icon__badge {
	position: absolute;
	top: -0.25rem;
	right: -0.25rem;
	z-index: 10;
	display: flex;
	align-items: center;
	justify-content: center;
	min-width: 1.25rem;
	height: 1.25rem;
	padding-inline: 0.25rem;
	border-radius: 9999px;
	background: var(--brand);
	color: var(--brand-foreground);
	font-family: var(--font-body);
	font-size: 0.65rem;
	font-weight: 500;
	pointer-events: none;
}

/* Over the hero, everything in the bar flips to white. */
.site-header--overlay:not(.is-open) .header-icon {
	border-color: rgb(255 255 255 / 0.25);
	background: rgb(255 255 255 / 0.1);
	color: #fff;
}

.site-header--overlay:not(.is-open) .header-icon:hover {
	border-color: rgb(255 255 255 / 0.45);
	background: rgb(255 255 255 / 0.2);
}

.site-header--overlay:not(.is-open) .header-nav__link {
	color: rgb(255 255 255 / 0.9);
}

.site-header--overlay:not(.is-open) .header-nav__link:hover,
.site-header--overlay:not(.is-open) .header-nav__link[aria-expanded="true"] {
	color: #fff;
}

.site-header--overlay:not(.is-open) .brand-lockup__mark { filter: brightness(0) invert(1); }
.site-header--overlay:not(.is-open) .brand-lockup__words { color: #fff; }

/* Sub-categories drop below the strip; collapsed to zero height when shut.
   Always on a solid pane — an open state, never the resting overlay. */
.header-submenu {
	overflow: hidden;
	max-height: 0;
	opacity: 0;
	transition: max-height 0.2s var(--ease), opacity 0.2s var(--ease);
}

.header-submenu.is-open {
	max-height: 13rem;
	opacity: 1;
	background: color-mix(in oklch, var(--background) 95%, transparent);
	backdrop-filter: blur(20px);
	-webkit-backdrop-filter: blur(20px);
}

.header-submenu__inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 0.75rem 2.5rem;
	padding-bottom: 1.25rem;
}

.header-submenu__link {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	font-size: 0.875rem;
	text-transform: uppercase;
	color: color-mix(in oklch, var(--foreground) 75%, transparent);
	transition: color 0.25s var(--ease);
}

.header-submenu__link:hover { color: var(--brand); }
.header-submenu__link svg { width: 0.875rem; height: 0.875rem; }

.header-mobile-panel {
	display: none;
	border-top: 1px solid rgb(0 0 0 / 0.06);
	background: color-mix(in oklch, var(--background) 97%, transparent);
	backdrop-filter: blur(20px);
	-webkit-backdrop-filter: blur(20px);
}

.header-mobile-panel.is-open { display: block; }

@media (min-width: 1024px) {
	.header-mobile-panel { display: none !important; }
}

.header-mobile-panel__inner {
	display: flex;
	flex-direction: column;
	gap: 1rem;
	padding-block: 1rem;
}

.header-mobile-panel__link {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding-block: 0.75rem;
	border-bottom: 1px solid color-mix(in oklch, var(--border) 70%, transparent);
	font-size: 0.875rem;
	text-transform: uppercase;
	color: color-mix(in oklch, var(--foreground) 85%, transparent);
}

.header-mobile-panel__link--sub {
	padding-left: 1rem;
	font-size: 0.8rem;
	color: color-mix(in oklch, var(--foreground) 65%, transparent);
}

/* Search */
.header-search {
	display: flex;
	width: 100%;
	align-items: center;
	gap: 0.75rem;
}

.search-field {
	position: relative;
	flex: 1 1 auto;
}

.search-field svg {
	position: absolute;
	top: 50%;
	left: 1.25rem;
	width: 1rem;
	height: 1rem;
	transform: translateY(-50%);
	color: var(--brand);
	pointer-events: none;
}

.search-field input {
	width: 100%;
	height: 3rem;
	padding: 0 1.25rem 0 3rem;
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	background: color-mix(in oklch, var(--brand-soft) 60%, transparent);
	font-size: 0.9rem;
	outline: none;
	transition: border-color 0.25s var(--ease);
}

.search-field input::placeholder { color: color-mix(in oklch, var(--muted-foreground) 80%, transparent); }
.search-field input:focus { border-color: var(--brand); }

/* ── Brand lockup ────────────────────────────────────────────
   The watch mark on the left with the wordmark stacked to its right, scaling
   together off a single size token so header, mobile header and footer stay
   in proportion. */

.brand-lockup {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
}

.brand-lockup__mark {
	flex-shrink: 0;
	width: auto;
	object-fit: contain;
	transition: filter 0.25s var(--ease);
}

.brand-lockup__words {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 0.25rem;
	line-height: 1;
	color: #000;
}

.brand-lockup__primary {
	font-family: var(--font-heading);
	font-weight: 500;
	text-transform: uppercase;
}

.brand-lockup__secondary {
	font-family: var(--font-body);
	font-weight: 500;
	text-transform: uppercase;
}

.brand-lockup--sm { gap: 0.375rem; }
.brand-lockup--sm .brand-lockup__mark { height: 2.25rem; }
.brand-lockup--sm .brand-lockup__words { margin-top: -5px; }
.brand-lockup--sm .brand-lockup__primary { font-size: 0.95rem; letter-spacing: 0.28em; }
.brand-lockup--sm .brand-lockup__secondary { font-size: 0.5rem; letter-spacing: 0.46em; margin-top: -0.25rem; padding-left: 2px; }

.brand-lockup--md .brand-lockup__mark { height: 2.75rem; }
.brand-lockup--md .brand-lockup__words { margin-top: -6px; }
.brand-lockup--md .brand-lockup__primary { font-size: 1.125rem; letter-spacing: 0.3em; }
.brand-lockup--md .brand-lockup__secondary { font-size: 0.58rem; letter-spacing: 0.5em; margin-top: -0.375rem; padding-left: 2px; }

.brand-lockup--lg .brand-lockup__mark { height: 3.5rem; }
.brand-lockup--lg .brand-lockup__words { margin-top: -7px; }
.brand-lockup--lg .brand-lockup__primary { font-size: 1.5rem; letter-spacing: 0.32em; }
.brand-lockup--lg .brand-lockup__secondary { font-size: 0.68rem; letter-spacing: 0.54em; margin-top: -0.375rem; padding-left: 3px; }

/* ═══ Hero ═════════════════════════════════════════════════════
   A full-viewport dark editorial stage. The studio still behind it is a
   single frame rather than video, so it never fights the reading pace of the
   page; slides with their own artwork paint over it. */

.hero {
	position: relative;
	width: 100%;
	height: 100svh;
	overflow: hidden;
	background: #000;
}

.hero__backdrop,
.hero__slide {
	position: absolute;
	inset: 0;
}

.hero__backdrop img,
.hero__backdrop video,
.hero__slide img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: 70% center;
}

@media (min-width: 1024px) {
	.hero__backdrop img,
	.hero__slide img { object-position: center; }

	/* The clip carries its dark stone on the left and the watch right of
	   centre. Anchoring the crop left keeps that stone under the headline
	   instead of cropping it away and pushing the dial under the type. */
	.hero__backdrop video { object-position: 22% center; }
}

/* Oversized so the backdrop's parallax travel never walks an edge into frame.
   The scale lives on the media because the wrapper carries the engine's
   transform, and two devices cannot share one element. */
.hero__backdrop img,
.hero__backdrop video { transform: scale(1.08); }

.hero__slide {
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.7s var(--ease);
}

.hero__slide.is-active {
	opacity: 1;
	pointer-events: auto;
}

/* Scrims — a lighter wash on the reading side, a faint vignette elsewhere.

   The horizontal gradient works because the copy is anchored to the left half
   on a wide screen: it puts the density where the text is and leaves the rest
   of the photograph alone. */
.hero__scrim {
	position: absolute;
	inset: 0;
	background:
		linear-gradient(to top, rgb(0 0 0 / 0.45), transparent 50%, rgb(0 0 0 / 0.25)),
		linear-gradient(to right, rgb(0 0 0 / 0.6), rgb(0 0 0 / 0.3) 50%, transparent);
}

/* Below the desktop breakpoint the copy stops being a left-hand column and
   spans the whole frame, so a gradient running left to right no longer sits
   under it. A band does: dense through the middle where the headline, the
   lede and the button are, easing off at the top and bottom so the watch is
   still a photograph rather than a flat grey field. */
@media (max-width: 1023px) {
	.hero__scrim {
		background: linear-gradient(
			to bottom,
			rgb(0 0 0 / 0.52) 0%,
			rgb(0 0 0 / 0.32) 17%,
			rgb(0 0 0 / 0.7) 38%,
			rgb(0 0 0 / 0.7) 76%,
			rgb(0 0 0 / 0.46) 100%
		);
	}
}

.hero__content {
	position: relative;
	display: flex;
	flex-direction: column;
	justify-content: center;
	height: 100%;
}

.hero__copy {
	max-width: 42rem;
	animation: hero-in 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
}

@keyframes hero-in {
	from { opacity: 0; transform: translateY(20px); }
	to   { opacity: 1; transform: translateY(0); }
}

.hero__subtitle {
	margin-bottom: 1.25rem;
	font-family: var(--font-body);
	font-size: 0.65rem;
	font-weight: 500;
	text-transform: uppercase;
	letter-spacing: 0.32em;
	color: rgb(255 255 255 / 0.65);
}

@media (min-width: 640px) {
	.hero__subtitle { font-size: 0.75rem; }
}

.hero__title {
	font-size: clamp(2.25rem, 6vw, 4.5rem);
	line-height: 1.06;
	letter-spacing: -0.01em;
	color: #fff;
}

.hero__lede {
	margin-top: 1.5rem;
	max-width: 36rem;
	font-family: var(--font-body);
	font-size: 0.875rem;
	line-height: 1.7;
	color: rgb(255 255 255 / 0.65);
}

@media (min-width: 640px) {
	.hero__lede { font-size: 1rem; }
}

/* The CTA stays white throughout — the sheen is the whole hover effect.
   Filling it with ink sinks it into the backdrop. */
.hero__cta {
	display: inline-flex;
	align-items: center;
	height: 3.5rem;
	margin-top: 2.25rem;
	padding-inline: 2.5rem;
	background: #fff;
	color: #171717;
	--sheen: color-mix(in oklch, var(--brand) 16%, transparent);
}

.hero__cta:hover:not(:disabled) { background: #fff; }

.hero__arrow {
	position: absolute;
	top: 50%;
	display: none;
	align-items: center;
	justify-content: center;
	width: 2.75rem;
	height: 2.75rem;
	transform: translateY(-50%);
	border: 1px solid rgb(255 255 255 / 0.2);
	border-radius: 9999px;
	background: rgb(255 255 255 / 0.1);
	color: #fff;
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
	transition: border-color 0.25s var(--ease), background-color 0.25s var(--ease), transform 0.35s var(--ease);
	cursor: pointer;
}

@media (min-width: 640px) {
	.hero__arrow { display: flex; }
}

.hero__arrow:hover {
	border-color: rgb(255 255 255 / 0.5);
	background: rgb(255 255 255 / 0.2);
}

.hero__arrow svg { width: 1.25rem; height: 1.25rem; }
.hero__arrow--prev { left: 1rem; }
.hero__arrow--next { right: 1rem; }

@media (min-width: 1024px) {
	.hero__arrow--prev { left: 1.5rem; }
	.hero__arrow--next { right: 1.5rem; }
}

/* Dots — bottom right, mirroring the copy block's baseline. */
.hero__dots {
	position: absolute;
	bottom: 2.5rem;
	left: 50%;
	display: flex;
	align-items: center;
	gap: 0.75rem;
	transform: translateX(-50%);
}

@media (min-width: 640px) {
	.hero__dots {
		left: auto;
		right: 2rem;
		transform: none;
	}
}

@media (min-width: 1024px) {
	.hero__dots { right: 3rem; }
}

.hero__dot {
	width: 0.625rem;
	height: 0.625rem;
	border-radius: 9999px;
	background: rgb(255 255 255 / 0.35);
	/* Named rather than `all`: a blanket transition animates properties nobody
	   meant to animate, and it is the reason a dot re-lays out on hover. */
	transition: background-color 0.3s var(--ease), transform 0.3s var(--ease);
	cursor: pointer;
}

.hero__dot:hover { background: rgb(255 255 255 / 0.6); }

.hero__dot[aria-current="true"] {
	background: #fff;
	transform: scale(1.1);
}

.hero__progress {
	position: absolute;
	bottom: 0;
	left: 0;
	width: 100%;
	height: 2px;
	overflow: hidden;
}

.hero__progress span {
	display: block;
	height: 100%;
	background: rgb(255 255 255 / 0.6);
	animation: hero-progress linear both;
}

@keyframes hero-progress {
	from { width: 0%; }
	to   { width: 100%; }
}

/* ═══ Product cards ════════════════════════════════════════════ */

.product-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 3rem 2rem;
	margin-top: 3rem;
}

@media (min-width: 640px) {
	.product-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 1024px) {
	.product-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* The catalogue proper runs denser than the arrivals strip: same plate and
   copy treatment, tighter gutters. Scale rather than colour separates them. */
.product-grid--dense { gap: 2.5rem 1.5rem; }

.product-card {
	display: flex;
	flex-direction: column;
}

.product-card__plate {
	position: relative;
	overflow: hidden;
	aspect-ratio: 1 / 1;
	border-radius: var(--radius-sm);
	background: var(--brand-soft);
}

/* The shot fills the plate edge to edge — no inset, no letterboxing. */
.product-card__plate img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.7s var(--ease);
}

.product-card:hover .product-card__plate img { transform: scale(1.05); }

/* Shared pill — "50% OFF", "Featured", … */
.product-tag {
	position: absolute;
	top: 1rem;
	left: 1rem;
	z-index: 20;
	padding: 0.375rem 1rem;
	border-radius: 9999px;
	background: #fff;
	font-family: var(--font-body);
	font-size: 0.7rem;
	font-weight: 500;
	letter-spacing: 0.02em;
	color: var(--foreground);
}

/* "Featured" reads as an endorsement rather than a discount, so it carries
   its own colour instead of the plain white plate. */
.product-tag--featured {
	background: oklch(0.52 0.13 152);
	color: #fff;
}

/* A markdown shouts; it is the one thing on a card allowed to. */
.product-tag--sale {
	background: oklch(0.55 0.21 27);
	color: #fff;
}

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

.product-grid--dense .product-card__body { gap: 0.5rem; margin-top: 1rem; }

/* Two lines reserved so prices sit on one baseline across the row however
   long the names run. */
.product-card__name {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	min-height: 2.6em;
	font-family: var(--font-body);
	font-size: 0.8rem;
	font-weight: 600;
	line-height: 1.35;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--foreground);
	transition: color 0.25s var(--ease);
}

.product-grid--dense .product-card__name { font-size: 0.75rem; }

.product-card:hover .product-card__name { color: var(--brand-accent); }

.product-card__price {
	display: flex;
	align-items: baseline;
	gap: 0.5rem;
	font-family: var(--font-body);
	font-size: 0.875rem;
	letter-spacing: 0.02em;
	color: color-mix(in oklch, var(--foreground) 60%, transparent);
}

.product-card__price del {
	font-size: 0.8rem;
	color: color-mix(in oklch, var(--foreground) 40%, transparent);
}

/* ── Pagination ──────────────────────────────────────────────
   Real links rather than a "view all" toggle: they give crawlers a path
   through the catalogue and cost nothing to render. */

.pager {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	margin-top: 3rem;
	flex-wrap: wrap;
}

.pager .btn { min-width: 2.5rem; }

.pager__current {
	background: var(--foreground);
	color: var(--background);
	border-color: transparent;
}

/* ═══ The house standard ═══════════════════════════════════════
   The four-point promise, unchanged in wording, staged inside a pinned
   vitrine: a caseback that unscrews and lifts away to the movement beneath
   while the four points arrive one at a time around it.

   The band is the one dark surface between the arrivals strip and the
   catalogue. Both plates are the same shot under the same light, cropped
   square to the disc, so they register exactly on top of one another at any
   viewport and the lift needs no alignment maths.

   Everything the scroll drives here is transform and opacity, read from the
   engine's `--sc-p`. Nothing is masked and nothing is filtered per frame.

   Two things this block deliberately does NOT set: `position` and `height` on
   the stage. The engine adds `.sc-stage`, which makes it sticky and a
   viewport tall; this sheet loads later, so restating either one here would
   win the cascade and the act would scroll away instead of pinning. For the
   same reason `.vitrine` carries no `overflow`. */

.vitrine {
	background: var(--brand-ink);
	color: var(--brand-foreground);
}

/* `color` is inherited as a computed value, so the ink is restated on the
   stage rather than only re-tokenised. Without this every line under the band
   keeps the page's near-black and renders invisible on the dark ground. */
.vitrine__stage {
	display: flex;
	align-items: center;
	padding-inline: var(--gutter);
	color: var(--brand-foreground);
	/* The engine sets `overflow: clip` here, which Safari only understood from
	   version 16. On anything older the oversized rotating ground escapes the
	   stage and widens the whole document, and every band below this one then
	   renders cut off at the right edge on the phone while looking perfect in a
	   desktop browser. `hidden` is understood everywhere and, on the sticky
	   element itself, does not affect its own stickiness. */
	overflow: hidden;
}

/* ── The ground ────────────────────────────────────────────────
   A machined steel plate behind everything, turning slowly and closing in as
   the act runs. It is what stops the band being a watch floating in a void.

   Oversized well past the stage on every side: a rotating rectangle sweeps its
   own corners through the frame, and at this scale nothing short of that keeps
   the edges out of view. */
.vitrine__ground {
	position: absolute;
	inset: -30%;
	z-index: 0;
	background-image: url("../img/images/house-standard-ground.webp");
	background-size: cover;
	background-position: center;
	/* The plate turns about a fifth of a rotation across the whole act and
	   pushes in slightly, so the movement of the ground is felt rather than
	   watched. Any faster and it competes with the case for attention. */
	transform:
		rotate(calc(var(--sc-p, 0) * 21deg))
		scale(calc(1.02 + 0.1 * var(--sc-p, 0)));
	opacity: 0.3;
	pointer-events: none;
	will-change: transform;
}

/* Held down hard in the middle, where the four points and the title sit. The
   ground is texture at the edges of vision, never something copy competes
   with: without this the specular sunburst runs straight under the type. */
.vitrine__stage::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background:
		radial-gradient(
			ellipse 62% 70% at 50% 52%,
			var(--brand-ink) 24%,
			color-mix(in oklch, var(--brand-ink) 55%, transparent) 58%,
			transparent 82%
		),
		radial-gradient(
			ellipse 55% 65% at 50% 55%,
			color-mix(in oklch, var(--brand-accent) 30%, transparent),
			transparent 72%
		);
	pointer-events: none;
}

/* Everything the reader looks at sits above both layers. */
.vitrine__grid { z-index: 2; }

@media (prefers-reduced-motion: reduce) {
	.vitrine__ground { transform: none; }
}

.vitrine__grid {
	position: relative;
	display: grid;
	grid-template-columns: 1fr 1fr;
	grid-template-areas:
		"head  head"
		"plate plate"
		"lead  trail";
	align-items: center;
	gap: 1.25rem 1.25rem;
	width: 100%;
}

@media (min-width: 1024px) {
	.vitrine__grid {
		grid-template-columns: 1fr auto 1fr;
		grid-template-areas: "lead plate trail";
		gap: 3.5rem;
	}
}

.vitrine__head { grid-area: head; }
.vitrine__plate { grid-area: plate; }
.vitrine__column--lead { grid-area: lead; }
.vitrine__column--trail { grid-area: trail; }

/* On a wide screen the title lifts out of the grid and sits against the top
   of the stage, so the four points can flank the plate on one optical line. */
@media (min-width: 1024px) {
	.vitrine__head {
		position: absolute;
		top: 0;
		left: 0;
	}
}

.vitrine__title {
	font-size: clamp(1.6rem, 4vw, 3.25rem);
	letter-spacing: -0.02em;
	text-wrap: balance;
	color: var(--brand-foreground);
}

/* ── The plate ─────────────────────────────────────────────────
   Square, so the 16:9 source crops to the disc and nothing else.

   Both remaps are registered rather than left as plain custom properties.
   An unregistered property computes to its raw token, so `getComputedStyle`
   hands back the literal string `clamp(0, calc(…), 1)`; the loupe's gate
   reads `--lift` as a number, and against that string it parses to NaN and
   the lens silently never arms. Registering them makes the computed value the
   number it looks like.

   Both inherit, because they are declared on the plate and read by the two
   images inside it. Registering them as non-inheriting leaves those children
   on the initial value, and the case then never lifts at all. */

@property --unscrew {
	syntax: "<number>";
	inherits: true;
	initial-value: 0;
}

@property --lift {
	syntax: "<number>";
	inherits: true;
	initial-value: 0;
}

.vitrine__plate {
	position: relative;
	aspect-ratio: 1;
	width: min(10.5rem, 37vw);
	margin-inline: auto;
	/* Two remaps of the act's progress, so the case turns before it lifts
	   rather than doing both at once. A screw does not leave the thread it is
	   still on. The first fifth of the act is neither: the case simply sits
	   there, and that stillness is what makes the opening land. */
	--unscrew: clamp(0, calc((var(--sc-p, 0) - 0.18) / 0.42), 1);
	--lift: clamp(0, calc((var(--sc-p, 0) - 0.52) / 0.4), 1);
}

/* Big enough to be the reason the band exists. The cap is on viewport height
   rather than width, because this plate has to clear the stage vertically with
   the title above it and still leave the flanking columns their measure. */
@media (min-width: 1024px) {
	.vitrine__plate { width: min(38rem, 64vh); }
}

@media (min-width: 1440px) {
	.vitrine__plate { width: min(44rem, 70vh); }
}

.vitrine__plate img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	border-radius: 50%;
	will-change: transform, opacity;
}

.vitrine__movement {
	transform: scale(calc(1.06 - 0.06 * var(--lift)));
}

.vitrine__caseback {
	transform:
		rotate(calc(var(--unscrew) * -32deg))
		scale(calc(1 + 0.16 * var(--lift)));
	opacity: calc(1 - var(--lift));
}

/* The light reaching the movement as the case comes off. A veil rather than a
   filter: one composited layer costs nothing per frame, where a `filter` on
   an image this size costs a repaint. */
.vitrine__plate::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 50%;
	background: var(--brand-ink);
	opacity: calc(0.5 * (1 - var(--lift)));
	pointer-events: none;
}

/* The engraved rim. It tightens as the case lifts, so the eye is drawn inward
   to the movement exactly as the movement becomes worth looking at. */
.vitrine__plate::before {
	content: "";
	position: absolute;
	inset: calc(-1.25rem + 0.75rem * var(--lift));
	border: 1px solid color-mix(in oklch, var(--brand-foreground) 16%, transparent);
	border-radius: 50%;
	pointer-events: none;
}

/* ── The four points ───────────────────────────────────────────
   Two to a column on either side of the plate. Museum labels: a term, a
   name, a fact, and no persuasion in any of them. */

.vitrine__column {
	display: flex;
	flex-direction: column;
	gap: 1.25rem;
}

@media (min-width: 1024px) {
	.vitrine__column { gap: 3rem; }
	.vitrine__column--trail { text-align: right; }
}

.vitrine__cell h3 {
	margin-top: 0.375rem;
	font-size: 0.9375rem;
	letter-spacing: -0.01em;
	color: var(--brand-foreground);
}

@media (min-width: 1024px) {
	.vitrine__cell h3 { font-size: 1.375rem; }
}

/* Light on dark optically thins, so this copy is set one step looser and one
   step brighter than the same paragraph would be on paper. */
.vitrine__cell p:last-child {
	margin-top: 0.375rem;
	max-width: 24rem;
	font-family: var(--font-body);
	font-size: 0.75rem;
	line-height: 1.55;
	letter-spacing: 0.005em;
	color: rgb(255 255 255 / 0.72);
}

@media (min-width: 1024px) {
	.vitrine__cell p:last-child { font-size: 0.9375rem; line-height: 1.7; }
	.vitrine__column--trail .vitrine__cell p:last-child { margin-left: auto; }
}

.vitrine__cell .eyebrow {
	font-size: 0.75rem;
	color: rgb(255 255 255 / 0.5);
}

/* Reduced motion: fewer and gentler, not nothing.

   The case coming off is the meaning of this band, not decoration, so the
   dissolve stays and only the position changes go. Dropping the whole thing
   would leave a reader on a sealed caseback for three viewport-heights and
   they would never see the movement, which is a device degrading into missing
   content rather than into stillness.

   `transition` is pinned to none here for a specific reason: the sheet's
   blanket reduced-motion rule gives every property a 0.01ms duration, and
   `transition-property` already defaults to `all`, so these two images end up
   running a real transition on every scroll frame instead of tracking the
   scroll directly. */
@media (prefers-reduced-motion: reduce) {
	.vitrine__plate img { transition: none; }
	.vitrine__movement { transform: none; }
	.vitrine__caseback { transform: none; }
}

/* ═══ Closing banner ═══════════════════════════════════════════
   Copy left, an oversized dial bleeding off the right. Ink at the copy end,
   lifting toward graphite where the photograph begins, so the panel meets the
   shot rather than butting against it. */

.promo {
	position: relative;
	display: grid;
	grid-template-columns: 1fr;
	align-items: center;
	overflow: hidden;
	border-radius: var(--radius-sm);
	/* The lift toward graphite existed to meet a floating cutout. The plate is
	   a bled photograph now, so the panel stays close to ink all the way
	   across and the two surfaces meet without a seam. */
	background: linear-gradient(
		to right,
		var(--brand-ink),
		var(--brand-ink) 50%,
		color-mix(in oklch, var(--brand-accent) 22%, var(--brand-ink))
	);
}

@media (min-width: 1024px) {
	.promo { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.promo__copy {
	padding: 3.5rem 2rem;
}

@media (min-width: 640px) { .promo__copy { padding-inline: 3rem; } }
@media (min-width: 1024px) { .promo__copy { padding-block: 5rem; } }

.promo__eyebrow {
	font-family: var(--font-body);
	font-size: 0.7rem;
	text-transform: uppercase;
	letter-spacing: 0.18em;
	color: rgb(255 255 255 / 0.58);
}

.promo__title {
	margin-top: 1.25rem;
	max-width: 28rem;
	/* Floored lower than the section titles: this one sits in a padded panel
	   that is only ~254px wide on a small phone, so a 2.25rem floor pushed it
	   to five cramped lines. */
	font-size: clamp(1.75rem, 4vw, 3rem);
	line-height: 1.15;
	letter-spacing: -0.02em;
	color: #fff;
}

.promo__lede {
	margin-top: 1.25rem;
	max-width: 28rem;
	font-family: var(--font-body);
	font-size: 0.8125rem;
	color: rgb(255 255 255 / 0.6);
}

@media (min-width: 640px) { .promo__lede { font-size: 1rem; } }

.promo__stars {
	display: flex;
	align-items: center;
	gap: 0.375rem;
	margin-top: 3rem;
}

.promo__stars svg {
	width: 1rem;
	height: 1rem;
	color: var(--brand-gilt);
}

/* Ruled off from the pitch above so these read as evidence rather than
   another line of copy. */
.promo__facts {
	display: grid;
	grid-template-columns: 1fr;
	gap: 1.25rem;
	max-width: 28rem;
	margin-top: 1.5rem;
	padding-top: 1.5rem;
	border-top: 1px solid rgb(255 255 255 / 0.15);
}

@media (min-width: 640px) {
	.promo__facts { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem; }
}

.promo__facts dt {
	font-family: var(--font-body);
	font-size: 0.65rem;
	text-transform: uppercase;
	letter-spacing: 0.18em;
	color: rgb(255 255 255 / 0.56);
}

.promo__facts dd {
	margin-top: 0.375rem;
	font-family: var(--font-body);
	font-size: 0.875rem;
	line-height: 1.4;
	color: rgb(255 255 255 / 0.75);
}

/* The dial plate is graded to the same near-black as the panel's ink end, so
   it bleeds into the gradient rather than sitting on it the way a cutout
   would. That is what keeps this one surface instead of two halves. */
.promo__plate {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 13rem;
	/* The wipe, as a fraction of the band's own progress. On a wide screen the
	   plate is beside the copy and on screen almost immediately, so the window
	   opens early. */
	--wipe: clamp(0, calc((var(--sc-p, 1) - 0.12) / 0.38), 1);
	clip-path: inset(0 calc((1 - var(--wipe)) * 100%) 0 0);
}

/* Stacked under the copy, the plate does not appear until the band is already
   a third through, so an early window means the wipe has finished before it is
   on screen. Opening later is the whole point of driving this from CSS. */
@media (max-width: 1023px) {
	.promo__plate { --wipe: clamp(0, calc((var(--sc-p, 1) - 0.35) / 0.26), 1); }
}

/* A wipe is a position change. The image is simply there. */
@media (prefers-reduced-motion: reduce) {
	.promo__plate { clip-path: none; }
}

@media (min-width: 640px) { .promo__plate { height: 16rem; } }
@media (min-width: 1024px) { .promo__plate { height: 100%; min-height: 20rem; } }

/* Both dimensions are overridden together. Setting only one leaves the other
   resolving to the file's own pixel height, which would push the band's
   bottom edge a screen further down than it looks like it should. */
.promo__plate img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Lateral travel against copy that holds still. Read from the band's own
	   flow progress, so the dial drifts roughly 90px across the whole band:
	   enough to feel like the object is moving past, far short of the ~200px
	   at which differential movement stops reading as depth and starts
	   reading as a bug. The scale is what keeps that travel from walking the
	   panel's own gradient into frame at the trailing edge. */
	transform: translate3d(calc((0.5 - var(--sc-p, 0.5)) * 90px), 0, 0) scale(1.06);
}

@media (prefers-reduced-motion: reduce) {
	.promo__plate img { transform: scale(1.06); }
}

.promo .btn { margin-top: 2.25rem; }

/* The panel's copy column is narrow on a phone, and a full-size CTA in it reads
   as a slab rather than a button. Step it down to the base size and let it sit
   to its natural width instead of filling the column. */
@media (max-width: 1023px) {
	.promo .btn {
		height: 2.75rem;
		margin-top: 1.75rem;
		padding-inline: 1.5rem;
		font-size: 0.875rem;
	}
}

/* ═══ Contact ══════════════════════════════════════════════════ */

.contact {
	border-top: 1px solid var(--border);
	background: color-mix(in oklch, var(--brand-soft) 40%, transparent);
	scroll-margin-top: 10rem;
}

.contact__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 2rem;
	margin-top: 3rem;
}

@media (min-width: 1024px) {
	.contact__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.contact__form {
	display: flex;
	flex-direction: column;
	gap: 1.5rem;
	padding: 1.75rem;
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	background: #fff;
}

@media (min-width: 640px) { .contact__form { padding: 2.25rem; } }

.contact__aside {
	display: flex;
	flex-direction: column;
	gap: 1.5rem;
}

.contact__map {
	position: relative;
	flex: 1 1 auto;
	min-height: 20rem;
	overflow: hidden;
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	background: var(--brand-soft);
}

.contact__map iframe {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
}

.contact__channels {
	display: grid;
	grid-template-columns: 1fr;
	gap: 0.75rem;
}

@media (min-width: 640px) {
	.contact__channels { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.contact__channel {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	padding: 1.25rem;
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	background: #fff;
	transition: border-color 0.25s var(--ease);
}

.contact__channel:hover { border-color: color-mix(in oklch, var(--brand) 40%, transparent); }

.contact__channel svg { width: 1.25rem; height: 1.25rem; color: var(--brand); }

.contact__channel-label {
	font-family: var(--font-body);
	font-size: 0.75rem;
	text-transform: uppercase;
	letter-spacing: 0.15em;
	color: color-mix(in oklch, var(--foreground) 50%, transparent);
}

.contact__channel-value {
	font-family: var(--font-body);
	font-size: 0.875rem;
	overflow-wrap: anywhere;
	color: color-mix(in oklch, var(--foreground) 80%, transparent);
	transition: color 0.25s var(--ease);
}

.contact__channel:hover .contact__channel-value { color: var(--brand); }

/* ── Fields ──────────────────────────────────────────────────── */

.field {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
}

.field__label {
	margin-left: 1.25rem;
	font-family: var(--font-body);
	font-size: 0.75rem;
	text-transform: uppercase;
	letter-spacing: 0.15em;
	color: color-mix(in oklch, var(--foreground) 70%, transparent);
}

.field__label--flush { margin-left: 0; }

.field input,
.field select,
.field textarea {
	width: 100%;
	padding: 0.9rem 1.25rem;
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	background: #fff;
	font-family: var(--font-body);
	font-size: 0.875rem;
	color: var(--foreground);
	outline: none;
	transition: border-color 0.25s var(--ease);
}

.field textarea {
	min-height: 8rem;
	resize: none;
	line-height: 1.6;
}

.field input::placeholder,
.field textarea::placeholder {
	color: color-mix(in oklch, var(--foreground) 35%, transparent);
}

.field input:focus,
.field select:focus,
.field textarea:focus {
	border-color: var(--foreground);
}

.field input:disabled { opacity: 0.5; cursor: not-allowed; }

.field__hint {
	font-family: var(--font-body);
	font-size: 0.75rem;
	color: color-mix(in oklch, var(--foreground) 55%, transparent);
}

.field-row {
	display: grid;
	grid-template-columns: 1fr;
	gap: 1.5rem;
}

@media (min-width: 768px) {
	.field-row--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ═══ Footer ═══════════════════════════════════════════════════ */

.site-footer {
	margin-top: auto;
	border-top: 1px solid var(--border);
	background: var(--background);
}

.site-footer__grid {
	display: grid;
	gap: 3rem;
	padding-block: 3.5rem;
}

@media (min-width: 1024px) {
	.site-footer__grid {
		grid-template-columns: 1.3fr 1.1fr 0.9fr 1.2fr;
		gap: 3.5rem;
		padding-block: 5rem;
	}
}

.site-footer__blurb {
	max-width: 24rem;
	font-size: 0.875rem;
	line-height: 1.9;
	color: color-mix(in oklch, var(--foreground) 65%, transparent);
}

.footer-heading {
	font-family: var(--font-body);
	font-size: 0.75rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.22em;
	color: var(--brand);
}

.footer-stack { display: flex; flex-direction: column; gap: 1.25rem; }
.footer-stack--tight { gap: 0.875rem; }

.footer-link {
	display: inline-block;
	font-size: 0.875rem;
	color: color-mix(in oklch, var(--foreground) 70%, transparent);
}

.footer-link:hover { color: var(--brand); }

.footer-contact {
	display: flex;
	align-items: flex-start;
	gap: 0.75rem;
	font-size: 0.875rem;
	line-height: 1.6;
	color: color-mix(in oklch, var(--foreground) 70%, transparent);
	transition: color 0.25s var(--ease);
}

.footer-contact:hover { color: var(--brand); }

.footer-contact svg {
	flex-shrink: 0;
	width: 1rem;
	height: 1rem;
	margin-top: 0.125rem;
	color: var(--brand);
}

.footer-socials {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
}

.footer-social {
	display: flex;
	flex-shrink: 0;
	align-items: center;
	justify-content: center;
	width: 2.75rem;
	height: 2.75rem;
	border: 1px solid color-mix(in oklch, var(--brand) 20%, transparent);
	border-radius: 9999px;
	color: color-mix(in oklch, var(--brand) 80%, transparent);
	transition: border-color 0.25s var(--ease), color 0.25s var(--ease),
		background-color 0.3s var(--ease), transform 0.35s var(--ease);
}

.footer-social:hover {
	transform: translateY(-2px);
	border-color: color-mix(in oklch, var(--brand) 50%, transparent);
	background: var(--brand-soft);
	color: var(--brand);
}

.footer-social svg { width: 1.125rem; height: 1.125rem; }

.site-footer__legal {
	border-top: 1px solid var(--border);
}

.site-footer__legal .shell {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 0.75rem;
	padding-block: 1.5rem;
	font-size: 0.75rem;
	color: color-mix(in oklch, var(--foreground) 55%, transparent);
}

@media (min-width: 640px) {
	.site-footer__legal .shell { flex-direction: row; }
}

/* ═══ Cart drawer ══════════════════════════════════════════════ */

.cart-scrim {
	position: fixed;
	inset: 0;
	z-index: 60;
	background: color-mix(in oklch, var(--brand-strong) 25%, transparent);
	backdrop-filter: blur(2px);
	-webkit-backdrop-filter: blur(2px);
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.3s var(--ease);
	border: 0;
}

.cart-scrim.is-open {
	opacity: 1;
	pointer-events: auto;
}

.cart-drawer {
	position: fixed;
	top: 0;
	right: 0;
	z-index: 70;
	display: flex;
	flex-direction: column;
	width: 100%;
	max-width: 28rem;
	height: 100%;
	border-left: 1px solid var(--border);
	background: var(--background);
	transform: translateX(100%);
	transition: transform 0.3s var(--ease);
}

@media (min-width: 640px) {
	.cart-drawer { max-width: 32rem; }
}

.cart-drawer.is-open { transform: translateX(0); }

.cart-drawer__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 1.25rem 1.5rem;
	border-bottom: 1px solid var(--border);
}

.cart-drawer__head p {
	font-size: 0.75rem;
	text-transform: uppercase;
	letter-spacing: 0.18em;
	color: color-mix(in oklch, var(--brand) 70%, transparent);
}

.cart-drawer__head h2 { font-size: 1.5rem; }

.cart-drawer__body {
	flex: 1 1 auto;
	overflow-y: auto;
	padding: 1.25rem 1.5rem;
}

.cart-drawer__foot {
	padding: 1.25rem 1.5rem;
	border-top: 1px solid var(--border);
}

.cart-empty {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 1rem;
	height: 100%;
	text-align: center;
}

.cart-empty p:first-child { font-size: 1.125rem; }

.cart-empty p:last-child {
	max-width: 20rem;
	font-size: 0.875rem;
	line-height: 1.6;
	color: color-mix(in oklch, var(--foreground) 60%, transparent);
}

.cart-line {
	display: flex;
	gap: 1rem;
	padding: 1rem;
	border: 1px solid var(--border);
	border-radius: calc(var(--radius) * 1.14);
}

.cart-line + .cart-line { margin-top: 1rem; }

.cart-line__image {
	position: relative;
	flex-shrink: 0;
	display: block;
	width: 6rem;
	aspect-ratio: 1;
	overflow: hidden;
	border: 1px solid var(--border);
	border-radius: var(--radius);
	background: var(--brand-soft);
}

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

.cart-line__body {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	gap: 0.75rem;
	min-width: 0;
}

.cart-line__name {
	font-size: 1rem;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.cart-line__price {
	font-size: 0.875rem;
	color: color-mix(in oklch, var(--foreground) 60%, transparent);
}

.cart-line__price del {
	display: block;
	font-size: 0.75rem;
	color: color-mix(in oklch, var(--foreground) 40%, transparent);
}

.cart-line__controls {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.75rem;
}

.qty {
	display: flex;
	align-items: center;
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
}

.qty button {
	padding: 0.5rem 0.75rem;
	font-size: 0.875rem;
	color: color-mix(in oklch, var(--foreground) 70%, transparent);
	transition: background-color 0.2s var(--ease), color 0.2s var(--ease);
	border: 0;
	cursor: pointer;
}

.qty button:first-child { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.qty button:last-child { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }

.qty button:hover:not(:disabled) {
	background: var(--brand-soft);
	color: var(--brand);
}

.qty span {
	min-width: 2.5rem;
	text-align: center;
	font-size: 0.875rem;
}

.cart-line__remove {
	font-size: 0.75rem;
	text-transform: uppercase;
	letter-spacing: 0.16em;
	color: color-mix(in oklch, var(--foreground) 45%, transparent);
	border: 0;
	cursor: pointer;
}

.cart-line__remove:hover { color: var(--brand); }

.cart-subtotal {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 1rem;
	font-size: 0.875rem;
}

.cart-subtotal span:first-child {
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: color-mix(in oklch, var(--foreground) 50%, transparent);
}

.cart-subtotal span:last-child {
	font-size: 1.125rem;
	font-weight: 500;
	color: var(--brand);
}

.cart-actions { display: flex; gap: 0.75rem; }
.cart-actions .btn { flex: 1 1 0; }

/* ═══ Product detail ═══════════════════════════════════════════ */

.product-detail {
	display: grid;
	grid-template-columns: 1fr;
	gap: 2rem;
	padding-block: 3rem;
}

@media (min-width: 1024px) {
	.product-detail { grid-template-columns: 1.1fr 0.9fr; }
}

.gallery__main {
	position: relative;
	aspect-ratio: 1;
	overflow: hidden;
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	background: var(--brand-soft);
}

.gallery__main img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.7s var(--ease);
}

.gallery__main:hover img { transform: scale(1.05); }

/* ── Sliding between frames ────────────────────────────────────
   Two layers travelling the same distance in the same direction: the frame
   being left, lifted onto `.gallery__slide` by site.js, and the frame arriving,
   which is the plate's own image moved in from the opposite edge. The plate
   already clips its overflow, so both are cut at its border.

   The duration is repeated in site.js as `SLIDE_MS`, which is what removes the
   outgoing layer; the two are meant to match. */
.gallery__main.is-sliding img {
	transition: transform 0.45s var(--ease);
}

.gallery__slide {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Over the plate's own image, under the lens at 3 and the arrows at 4 —
	   a frame on its way out should not be able to cover the control that
	   sent it there. */
	z-index: 2;
	transition: transform 0.45s var(--ease);
}

@media (prefers-reduced-motion: reduce) {
	.gallery__main.is-sliding img,
	.gallery__slide { transition: none; }
}

/* The same circular control the hero carries, in ink on the light plate rather
   than white on film. Kept visible rather than revealed on hover: a control
   that only appears to a mouse is a control a phone never gets, and the phone
   is where a gallery is actually swiped through. Above the loupe lens, which
   sits at z-index 3 and takes no pointer events of its own. */
.gallery__arrow {
	position: absolute;
	top: 50%;
	z-index: 4;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 2.5rem;
	height: 2.5rem;
	transform: translateY(-50%);
	border: 1px solid var(--border);
	border-radius: 9999px;
	background: color-mix(in oklch, var(--background) 82%, transparent);
	color: var(--foreground);
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
	transition: border-color 0.25s var(--ease), background-color 0.25s var(--ease);
	cursor: pointer;
}

.gallery__arrow:hover {
	border-color: var(--brand);
	background: var(--background);
}

.gallery__arrow svg { width: 1.125rem; height: 1.125rem; }
.gallery__arrow--prev { left: 0.75rem; }
.gallery__arrow--next { right: 0.75rem; }

@media (min-width: 1024px) {
	.gallery__arrow--prev { left: 1rem; }
	.gallery__arrow--next { right: 1rem; }
}

.gallery__thumbs {
	display: grid;
	grid-template-columns: repeat(5, minmax(0, 1fr));
	gap: 0.75rem;
	margin-top: 0.75rem;
}

.gallery__thumb {
	position: relative;
	aspect-ratio: 1;
	overflow: hidden;
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	background: var(--brand-soft);
	padding: 0;
	cursor: pointer;
	transition: border-color 0.25s var(--ease);
}

.gallery__thumb img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.gallery__thumb[aria-current="true"],
.gallery__thumb:hover { border-color: var(--brand); }

/* ═══ The loupe ════════════════════════════════════════════════
   A jeweller's loupe that follows the pointer across any surface marked
   `data-loupe`, magnifying the true source rather than decorating it. It is
   the gesture a buyer physically makes in a shop, and it does real work here:
   on a product it shows the actual finish of the actual watch, and on the
   house standard it reads the movement at a magnification the page cannot
   otherwise give.

   Pointer-fine only. A press-and-hold equivalent on touch would have to
   swallow `touchmove` to stay put, and a gesture that fights the page's own
   scrolling is worse than no gesture: a phone can already pinch the gallery.

   Everything the pointer drives is written inline by site.js as one
   `transform`, so a move costs a composite and nothing else. */

[data-loupe] { position: relative; }

.loupe {
	position: absolute;
	top: 0;
	left: 0;
	width: 9.5rem;
	height: 9.5rem;
	border-radius: 50%;
	background-repeat: no-repeat;
	/* A fallback only. site.js replaces this with the surface's own ground, so
	   a transparent product cut-out magnifies onto the same colour the plate
	   sits on rather than onto a disc of ink. */
	background-color: var(--brand-soft);
	/* A real lens has a rim that catches light and a body that casts a
	   shadow. Both have offset and blur; neither is a coloured halo. */
	border: 1px solid color-mix(in oklch, var(--brand-foreground) 55%, transparent);
	box-shadow:
		0 2px 6px rgb(0 0 0 / 0.2),
		0 18px 40px -12px rgb(0 0 0 / 0.38),
		inset 0 0 0 1px rgb(0 0 0 / 0.35);
	opacity: 0;
	pointer-events: none;
	z-index: 3;
	transition: opacity 160ms var(--ease);
}

.loupe.is-open { opacity: 1; }

/* The ground glass: a faint darkening at the very edge of the lens, so the
   magnified image falls off into the rim instead of ending on a hard line. */
.loupe::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 50%;
	background: radial-gradient(circle at 50% 50%, transparent 62%, rgb(0 0 0 / 0.3));
	pointer-events: none;
}

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

.product-detail__body { display: flex; flex-direction: column; }

.product-detail__title {
	margin-top: 1.25rem;
	font-size: clamp(2.25rem, 4vw, 3rem);
	letter-spacing: -0.02em;
}

.product-detail__lede {
	margin-top: 1.25rem;
	font-family: var(--font-body);
	font-size: 0.875rem;
	line-height: 1.75;
	color: color-mix(in oklch, var(--foreground) 65%, transparent);
}

@media (min-width: 640px) { .product-detail__lede { font-size: 1rem; } }

.product-detail__pricing {
	margin-top: 2rem;
	padding-top: 1.5rem;
	border-top: 1px solid var(--border);
}

.product-detail__was {
	font-family: var(--font-body);
	font-size: 0.875rem;
	text-decoration: line-through;
	color: color-mix(in oklch, var(--foreground) 45%, transparent);
}

.product-detail__price {
	font-family: var(--font-body);
	font-size: 1.875rem;
	letter-spacing: -0.02em;
}

/* `gap: 1px` over a border-coloured ground draws the rules between cells, so
   the table needs no per-cell borders to chase. */
.spec-table {
	display: grid;
	grid-template-columns: 1fr;
	gap: 1px;
	margin-top: 2rem;
	overflow: hidden;
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	background: var(--border);
}

@media (min-width: 640px) {
	.spec-table { grid-template-columns: repeat(2, minmax(0, 1fr)); }

	/* An odd number of specs would otherwise leave a blank trailing cell, and
	   because this grid draws its rules with a 1px gap over a border-coloured
	   ground, that blank reads as a hole in the block rather than as space.
	   The last row takes the full width instead. */
	.spec-table > div:last-child:nth-child(odd) { grid-column: 1 / -1; }
}

.spec-table > div {
	padding: 1.25rem;
	background: var(--background);
}

.spec-table dt {
	font-family: var(--font-body);
	font-size: 0.65rem;
	text-transform: uppercase;
	letter-spacing: 0.18em;
	color: color-mix(in oklch, var(--foreground) 45%, transparent);
}

.spec-table dd {
	margin-top: 0.375rem;
	font-family: var(--font-body);
	font-size: 0.875rem;
	color: color-mix(in oklch, var(--foreground) 80%, transparent);
}

.product-detail__actions {
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
	margin-top: 2rem;
}

/* Green stays on the glyph alone. A full green fill would be the one saturated
   block on an achromatic site and reads as a widget. */
.icon-whatsapp { color: var(--whatsapp); }

/* ── Free delivery ─────────────────────────────────────────────
   The only other place colour carries meaning rather than decoration. It is
   green because the page is otherwise ink on paper, so the one tinted chip is
   read before anything else around it — which is the point. */
.perk {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	font-family: var(--font-body);
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.01em;
	color: color-mix(in oklch, var(--success) 80%, black);
}

.perk svg { flex-shrink: 0; width: 1rem; height: 1rem; }

/* On the product page it stands as its own line under the price, so it takes
   the tinted plate the checkout chip does not need. */
.perk--plate {
	display: flex;
	gap: 0.5rem;
	margin-top: 0.875rem;
	padding: 0.5rem 0.75rem;
	border: 1px solid color-mix(in oklch, var(--success) 30%, transparent);
	border-radius: var(--radius-sm);
	background: color-mix(in oklch, var(--success) 8%, transparent);
}

.perk__note { font-weight: 400; color: color-mix(in oklch, var(--success) 65%, black); }

/* ═══ Checkout ═════════════════════════════════════════════════ */

.checkout {
	display: grid;
	grid-template-columns: 1fr;
	gap: 1.5rem;
	padding-block: 2rem;
}

@media (min-width: 1024px) {
	.checkout { grid-template-columns: minmax(0, 1fr) 22rem; }
}

@media (min-width: 1280px) {
	.checkout { grid-template-columns: minmax(0, 1fr) 26rem; }
}

.checkout__main {
	order: 2;
	display: flex;
	flex-direction: column;
	gap: 1.5rem;
}

.checkout__aside { order: 1; }

@media (min-width: 1024px) {
	.checkout__main { order: 1; }
	.checkout__aside { order: 2; }
}

.card {
	border: 1px solid var(--border);
	border-radius: var(--radius);
	background: var(--card);
	overflow: hidden;
}

.card__head {
	padding: 1.5rem;
	border-bottom: 1px solid var(--border);
}

.card__title { font-size: 1.5rem; }

.card__description {
	margin-top: 0.5rem;
	font-family: var(--font-body);
	font-size: 0.875rem;
	line-height: 1.6;
	color: var(--muted-foreground);
}

.card__body {
	display: flex;
	flex-direction: column;
	gap: 1.25rem;
	padding: 1.5rem;
}

@media (min-width: 1024px) {
	.summary { position: sticky; top: 6rem; }
}

.summary__line {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 1rem;
}

.summary__line + .summary__line { margin-top: 1rem; }

.summary__thumb {
	position: relative;
	flex-shrink: 0;
	width: 4rem;
	height: 4rem;
	overflow: hidden;
	border: 1px solid var(--border);
	border-radius: var(--radius);
	background: var(--brand-soft);
}

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

.summary__meta {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	font-size: 0.875rem;
}

.summary__meta + .summary__meta { margin-top: 0.75rem; }

.summary__meta span:first-child { color: var(--muted-foreground); }
.summary__meta span:last-child { font-weight: 500; }

.summary__total {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding-top: 1.25rem;
	border-top: 1px solid var(--border);
	margin-top: 1.25rem;
}

.summary__total span:first-child { font-size: 1.125rem; font-weight: 600; }
.summary__total span:last-child { font-size: 1.25rem; font-weight: 600; }

.checkout-success {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	min-height: 60vh;
	padding: 1.5rem;
	text-align: center;
}

.checkout-success__inner {
	display: flex;
	flex-direction: column;
	gap: 1.5rem;
	max-width: 28rem;
}

.order-reference {
	padding: 1.25rem 1.5rem;
	border: 1px solid var(--border);
	background: color-mix(in oklch, var(--brand-soft) 40%, transparent);
	text-align: left;
}

.order-reference strong {
	display: block;
	margin-top: 0.5rem;
	font-family: var(--font-body);
	font-size: 1.5rem;
	font-weight: 400;
	letter-spacing: 0.2em;
}

/* ═══ Policy pages ═════════════════════════════════════════════ */

.prose {
	max-width: 64rem;
	margin-inline: auto;
	padding-block: 4rem;
}

.prose > * + * { margin-top: 1.5rem; }

.prose h1 {
	font-size: clamp(2.25rem, 5vw, 3rem);
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--brand);
}

.prose h2 {
	margin-top: 3rem;
	font-size: 1.5rem;
	color: var(--brand);
}

.prose p,
.prose li {
	font-size: 0.9375rem;
	line-height: 1.9;
	color: color-mix(in oklch, var(--foreground) 75%, transparent);
}

.prose ul {
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
	padding-left: 1.25rem;
}

.prose li { position: relative; }

.prose li::before {
	content: "";
	position: absolute;
	left: -1.25rem;
	top: 0.75em;
	width: 5px;
	height: 1px;
	background: var(--brand-accent);
}

.prose__lede {
	font-size: 1rem !important;
	line-height: 1.9;
}

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

@media (min-width: 768px) {
	.policy-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.policy-card {
	padding: 1.5rem;
	border: 1px solid var(--border);
	border-radius: var(--radius);
	background: var(--background);
}

.policy-card > * + * { margin-top: 0.75rem; }
.policy-card h2 { margin-top: 0; margin-bottom: 1rem; }

.policy-callout {
	padding: 1.5rem;
	border: 1px solid color-mix(in oklch, var(--brand) 20%, transparent);
	background: color-mix(in oklch, var(--brand) 5%, transparent);
}

@media (min-width: 640px) { .policy-callout { padding: 2rem; } }

/* ═══ Notices ══════════════════════════════════════════════════ */

.notice {
	display: flex;
	align-items: flex-start;
	gap: 0.75rem;
	padding: 1rem 1.25rem;
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	background: var(--brand-soft);
	font-family: var(--font-body);
	font-size: 0.875rem;
	line-height: 1.6;
}

.notice--error {
	border-color: color-mix(in oklch, var(--destructive) 30%, transparent);
	background: color-mix(in oklch, var(--destructive) 6%, transparent);
	color: var(--destructive);
}

.notice--success {
	border-color: color-mix(in oklch, var(--success) 30%, transparent);
	background: color-mix(in oklch, var(--success) 8%, transparent);
	color: color-mix(in oklch, var(--success) 80%, black);
}

.notice svg { flex-shrink: 0; width: 1.125rem; height: 1.125rem; margin-top: 0.125rem; }

/* Toasts — the drawer's "added to bag" acknowledgement. */
.toast-stack {
	position: fixed;
	top: 1.5rem;
	left: 50%;
	z-index: 90;
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	transform: translateX(-50%);
	pointer-events: none;
}

.toast {
	padding: 0.875rem 1.5rem;
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	background: var(--background);
	font-family: var(--font-body);
	font-size: 0.875rem;
	animation: toast-in 0.3s var(--ease) both;
}

.toast--error {
	border-color: color-mix(in oklch, var(--destructive) 35%, transparent);
	color: var(--destructive);
}

@keyframes toast-in {
	from { opacity: 0; transform: translateY(-12px); }
	to   { opacity: 1; transform: translateY(0); }
}

.empty-state {
	padding: 2rem;
	border: 1px solid var(--border);
	border-radius: var(--radius);
	background: var(--card);
	font-family: var(--font-body);
	font-size: 1rem;
	color: color-mix(in oklch, var(--foreground) 65%, transparent);
}

/* ═══ Floating widgets ═════════════════════════════════════════ */

.whatsapp-float {
	position: fixed;
	right: 1.25rem;
	bottom: 1.25rem;
	z-index: 50;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 3rem;
	height: 3rem;
	border-radius: 9999px;
	background: var(--whatsapp);
	color: #fff;
	transition: transform 0.25s var(--ease);
}

.whatsapp-float:hover { transform: scale(1.05); }
.whatsapp-float:active { transform: scale(0.95); }
.whatsapp-float svg { width: 1.5rem; height: 1.5rem; }

@media (min-width: 640px) {
	.whatsapp-float { width: 3.5rem; height: 3.5rem; }
	.whatsapp-float svg { width: 2rem; height: 2rem; }
}

.cookie-consent {
	position: fixed;
	inset: 0;
	z-index: 80;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 1.5rem;
	background: color-mix(in oklch, var(--brand-strong) 60%, transparent);
	backdrop-filter: blur(4px);
	-webkit-backdrop-filter: blur(4px);
}

.cookie-consent[hidden] { display: none; }

.cookie-consent__panel {
	width: 100%;
	max-width: 28rem;
	padding: 2rem;
	border: 1px solid var(--border);
	border-radius: calc(var(--radius) * 2.2);
	background: var(--background);
	display: flex;
	flex-direction: column;
	gap: 1rem;
}

.cookie-consent__panel p:first-child {
	font-size: 0.75rem;
	font-weight: 500;
	text-transform: uppercase;
	letter-spacing: 0.22em;
	color: var(--brand);
}

.cookie-consent__panel p:nth-child(2) {
	font-size: 0.875rem;
	line-height: 1.6;
	color: color-mix(in oklch, var(--foreground) 75%, transparent);
}

.cookie-consent__actions {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
}

@media (min-width: 640px) {
	.cookie-consent__actions { flex-direction: row; }
	.cookie-consent__actions .btn { flex: 1 1 0; }
}

/* ═══ Error pages ══════════════════════════════════════════════ */

.error-page {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 1.5rem;
	min-height: 70vh;
	padding: 3rem 1.5rem;
	text-align: center;
}

.error-page__status {
	font-family: var(--font-body);
	font-size: 0.75rem;
	text-transform: uppercase;
	letter-spacing: 0.3em;
	color: color-mix(in oklch, var(--foreground) 45%, transparent);
}

.error-page h1 { font-size: clamp(2rem, 5vw, 3rem); }

.error-page p {
	max-width: 32rem;
	font-size: 0.9375rem;
	line-height: 1.8;
	color: color-mix(in oklch, var(--foreground) 65%, transparent);
}

/* ═══ Reduced motion ═══════════════════════════════════════════
   An unrequested slide change every five seconds is exactly what this setting
   asks us not to do, so the hero stops advancing entirely. */

@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;
	}

	.btn:hover:not(:disabled),
	.btn:active:not(:disabled),
	.header-icon:hover,
	.footer-social:hover,
	.whatsapp-float:hover { transform: none; }

	.hero__progress { display: none; }
}
