
/* ===== assets/tokens.css ===== */
/* ==========================================================================
   TEEMCW — DESIGN TOKENS
   The whole palette, type scale and spacing rhythm, in one place.

   The brief asks for white and pink. Pink is the accent, never the canvas:
   backgrounds stay white or a barely-there blush, and rose appears only where
   it carries meaning — an action, a price, a sale badge, a focus ring. That
   restraint is what separates a premium storefront from a novelty one.
   ========================================================================== */

:root {
	/* ---- Canvas -------------------------------------------------------- */
	--white: #ffffff;
	--blush-1: #fff9fb;   /* section banding */
	--blush-2: #fff4f7;   /* cards, wells */
	--blush-3: #ffedf2;   /* hover on blush surfaces */

	/* ---- Rose ramp ----------------------------------------------------- */
	--rose-50: #fff0f4;
	--rose-100: #ffe0e9;
	--rose-200: #ffc2d4;
	--rose-300: #f79ab5;
	--rose-400: #e97396;
	--rose-500: #d6537c;   /* primary action */
	--rose-600: #b93c63;   /* hover */
	--rose-700: #972f4f;   /* active, headings on blush */
	--rose-800: #74243d;
	--rose-900: #551a2c;

	/* Dusty rose, for decorative rules and quiet borders. */
	--dusty: #c99aa8;
	--dusty-soft: #e8ccd5;

	/* ---- Ink ----------------------------------------------------------- */
	--ink: #23191d;        /* dark charcoal, warmed a touch toward the rose */
	--ink-2: #4a3e43;      /* body copy */
	--ink-3: #6f6266;      /* secondary */
	--ink-4: #9a8f93;      /* meta, placeholders */

	/* ---- Lines and shadows --------------------------------------------- */
	--line: #f0e4e8;
	--line-2: #e4d4da;
	--line-strong: #d3bdc5;

	--shadow-sm: 0 1px 2px rgba(35, 25, 29, .06);
	--shadow: 0 4px 16px rgba(35, 25, 29, .07);
	--shadow-md: 0 10px 30px rgba(35, 25, 29, .09);
	--shadow-lg: 0 20px 50px rgba(35, 25, 29, .12);
	--shadow-rose: 0 8px 24px rgba(214, 83, 124, .22);

	/* ---- State --------------------------------------------------------- */
	--ok: #2e7d5b;
	--ok-bg: #eaf6f0;
	--warn: #9a6b16;
	--warn-bg: #fdf4e3;
	--err: #b3261e;
	--err-bg: #fdecea;

	/* ---- Type ---------------------------------------------------------- */
	--font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	--font-display: "Fraunces", "Iowan Old Style", Georgia, "Times New Roman", serif;

	--fs-xs: .75rem;
	--fs-sm: .8125rem;
	--fs-base: .9375rem;
	--fs-md: 1rem;
	--fs-lg: 1.125rem;
	--fs-xl: 1.375rem;
	--fs-2xl: clamp(1.5rem, 1.2rem + 1.1vw, 2rem);
	--fs-3xl: clamp(1.875rem, 1.4rem + 1.9vw, 2.75rem);
	--fs-4xl: clamp(2.25rem, 1.5rem + 3.2vw, 4rem);

	--lh-tight: 1.15;
	--lh-snug: 1.35;
	--lh-base: 1.65;

	--ls-tight: -.02em;
	--ls-wide: .08em;
	--ls-caps: .14em;

	/* ---- Spacing ------------------------------------------------------- */
	--sp-1: .25rem;
	--sp-2: .5rem;
	--sp-3: .75rem;
	--sp-4: 1rem;
	--sp-5: 1.5rem;
	--sp-6: 2rem;
	--sp-7: 2.5rem;
	--sp-8: 3rem;
	--sp-9: 4rem;
	--sp-10: 5rem;
	--sp-11: 6.5rem;
	--sp-12: 8rem;

	--gutter: clamp(1rem, 4vw, 2.5rem);
	--shell: 1280px;
	--shell-narrow: 780px;

	/* ---- Radius -------------------------------------------------------- */
	--r-xs: 4px;
	--r-sm: 8px;
	--r-md: 12px;
	--r-lg: 18px;
	--r-xl: 26px;
	--r-pill: 999px;

	/* ---- Motion -------------------------------------------------------- */
	--dur-fast: 140ms;
	--dur: 240ms;
	--dur-slow: 420ms;
	--ease: cubic-bezier(.22, .61, .36, 1);
	--ease-out: cubic-bezier(.16, 1, .3, 1);

	/* ---- Chrome -------------------------------------------------------- */
	--header-h: 4.5rem;
	--ann-h: 2.25rem;
	--z-ann: 90;
	--z-header: 100;
	--z-drawer: 200;
	--z-modal: 300;
	--z-toast: 400;
}

@media (max-width: 782px) {
	:root {
		--header-h: 3.75rem;
		--ann-h: 2rem;
	}
}

/* Respect a reduced-motion preference everywhere, once. */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: .01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: .01ms !important;
		scroll-behavior: auto !important;
	}
}

/* ===== assets/base.css ===== */
/* ==========================================================================
   TEEMCW — BASE
   Reset, typography, shared primitives (buttons, forms, badges, shell).
   Loaded after tokens.css.
   ========================================================================== */

*,
*::before,
*::after { box-sizing: border-box; }

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
	scroll-padding-top: calc(var(--header-h) + var(--sp-4));
}

body {
	margin: 0;
	background: var(--white);
	color: var(--ink-2);
	font-family: var(--font-body);
	font-size: var(--fs-base);
	line-height: var(--lh-base);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	overflow-x: clip;
}

/* Nothing may push the document wider than the viewport. */
img, svg, video, canvas, iframe { max-width: 100%; }
img, svg, video { height: auto; display: block; }

h1, h2, h3, h4, h5, h6 {
	margin: 0 0 var(--sp-3);
	color: var(--ink);
	font-family: var(--font-display);
	font-weight: 600;
	line-height: var(--lh-tight);
	letter-spacing: var(--ls-tight);
}

h1 { font-size: var(--fs-4xl); }
h2 { font-size: var(--fs-3xl); }
h3 { font-size: var(--fs-2xl); }
h4 { font-size: var(--fs-xl); }
h5, h6 { font-size: var(--fs-lg); }

p { margin: 0 0 var(--sp-4); }
p:last-child { margin-bottom: 0; }

a {
	color: var(--rose-600);
	text-decoration: none;
	transition: color var(--dur-fast) var(--ease);
}
a:hover { color: var(--rose-700); }

/* A visible focus ring is a requirement, not a decoration. */
:focus-visible {
	outline: 2px solid var(--rose-500);
	outline-offset: 2px;
	border-radius: var(--r-xs);
}

ul, ol { margin: 0 0 var(--sp-4); padding-left: 1.25rem; }
li { margin-bottom: var(--sp-1); }

hr {
	border: 0;
	border-top: 1px solid var(--line);
	margin: var(--sp-7) 0;
}

strong, b { color: var(--ink); font-weight: 600; }

::selection { background: var(--rose-100); color: var(--rose-800); }

/* --------------------------------------------------------------------------
   Layout shell
   -------------------------------------------------------------------------- */

.tw-shell {
	width: 100%;
	max-width: var(--shell);
	margin-inline: auto;
	padding-inline: var(--gutter);
}

.tw-shell--narrow { max-width: var(--shell-narrow); }

.tw-sec { padding-block: var(--sp-10); }
.tw-sec--tight { padding-block: var(--sp-8); }
.tw-sec--blush { background: var(--blush-1); }
.tw-sec--blush-2 { background: var(--blush-2); }

@media (max-width: 782px) {
	.tw-sec { padding-block: var(--sp-8); }
	.tw-sec--tight { padding-block: var(--sp-6); }
}

/* Notched phones: keep the gutter clear of rounded corners. */
@supports (padding: max(0px)) {
	.tw-shell {
		padding-left: max(var(--gutter), env(safe-area-inset-left));
		padding-right: max(var(--gutter), env(safe-area-inset-right));
	}
}

/* --------------------------------------------------------------------------
   Section headings
   -------------------------------------------------------------------------- */

.tw-head {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--sp-5);
	margin-bottom: var(--sp-7);
}

.tw-head__in { max-width: 44rem; }

.tw-head__eyebrow {
	display: block;
	margin-bottom: var(--sp-2);
	color: var(--rose-500);
	font-size: var(--fs-xs);
	font-weight: 600;
	letter-spacing: var(--ls-caps);
	text-transform: uppercase;
}

.tw-head__title { margin-bottom: var(--sp-2); }

.tw-head__sub {
	margin: 0;
	color: var(--ink-3);
	font-size: var(--fs-md);
	line-height: var(--lh-snug);
}

.tw-head--center {
	flex-direction: column;
	align-items: center;
	text-align: center;
}
.tw-head--center .tw-head__in { margin-inline: auto; }

@media (max-width: 680px) {
	.tw-head { flex-direction: column; align-items: flex-start; }
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.tw-btn,
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce #respond input#submit,
.wp-block-button__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--sp-2);
	padding: .8125rem 1.5rem;
	border: 1px solid transparent;
	border-radius: var(--r-pill);
	background: var(--rose-500);
	color: var(--white);
	font-family: var(--font-body);
	font-size: var(--fs-base);
	font-weight: 600;
	line-height: 1.2;
	letter-spacing: .01em;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
	transition: background var(--dur-fast) var(--ease),
	            transform var(--dur-fast) var(--ease),
	            box-shadow var(--dur-fast) var(--ease);
}

.tw-btn:hover,
.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce #respond input#submit:hover {
	background: var(--rose-600);
	color: var(--white);
	transform: translateY(-1px);
	box-shadow: var(--shadow-rose);
}

.tw-btn:active { transform: translateY(0); }

.tw-btn[disabled],
.tw-btn.is-loading,
.woocommerce button.button:disabled,
.woocommerce button.button[disabled] {
	opacity: .55;
	cursor: not-allowed;
	transform: none;
	box-shadow: none;
}

/* Secondary: outline on white. */
.tw-btn--ghost,
.woocommerce a.button.alt--ghost {
	background: var(--white);
	border-color: var(--line-2);
	color: var(--ink);
}
.tw-btn--ghost:hover {
	background: var(--blush-2);
	border-color: var(--dusty-soft);
	color: var(--rose-700);
	box-shadow: var(--shadow-sm);
}

/* Quiet: text only. */

.tw-btn--sm { padding: .5rem 1rem; font-size: var(--fs-sm); }
.tw-btn--lg { padding: 1rem 2rem; font-size: var(--fs-md); }
.tw-btn--block { width: 100%; }

.tw-btn svg { width: 1.125em; height: 1.125em; flex: none; }

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */

input[type="text"],
input[type="email"],
input[type="tel"],
input[type="url"],
input[type="password"],
input[type="search"],
input[type="number"],
input[type="date"],
select,
textarea,
.woocommerce form .form-row input.input-text,
.woocommerce form .form-row textarea,
.woocommerce form .form-row select,
.select2-container--default .select2-selection--single {
	width: 100%;
	padding: .75rem 1rem;
	border: 1px solid var(--line-2);
	border-radius: var(--r-sm);
	background: var(--white);
	color: var(--ink);
	font-family: var(--font-body);
	font-size: var(--fs-base);
	line-height: 1.5;
	transition: border-color var(--dur-fast) var(--ease),
	            box-shadow var(--dur-fast) var(--ease);
}

input:focus,
select:focus,
textarea:focus,
.woocommerce form .form-row input.input-text:focus {
	outline: none;
	border-color: var(--rose-300);
	box-shadow: 0 0 0 3px var(--rose-50);
}

input::placeholder,
textarea::placeholder { color: var(--ink-4); }

label {
	display: block;
	margin-bottom: var(--sp-2);
	color: var(--ink);
	font-size: var(--fs-sm);
	font-weight: 600;
}

textarea { min-height: 8rem; resize: vertical; }

/* --------------------------------------------------------------------------
   Badges and pills
   -------------------------------------------------------------------------- */

.tw-badge {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-1);
	padding: .3125rem .625rem;
	border-radius: var(--r-pill);
	background: var(--rose-50);
	color: var(--rose-700);
	font-size: var(--fs-xs);
	font-weight: 600;
	letter-spacing: .02em;
	line-height: 1;
	white-space: nowrap;
}

.tw-badge--sale { background: var(--rose-500); color: var(--white); }
.tw-badge--new { background: var(--ink); color: var(--white); }

.tw-badge--out { background: #f2eef0; color: var(--ink-3); }

/* --------------------------------------------------------------------------
   Utilities
   -------------------------------------------------------------------------- */

.screen-reader-text,
.tw-sr {
	position: absolute !important;
	width: 1px; height: 1px;
	margin: -1px; padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* Skip link, visible only when focused. */
.tw-skip {
	position: absolute;
	top: -100px; left: var(--sp-4);
	z-index: var(--z-modal);
	padding: var(--sp-3) var(--sp-5);
	background: var(--rose-500);
	color: var(--white);
	border-radius: 0 0 var(--r-sm) var(--r-sm);
	font-weight: 600;
	transition: top var(--dur) var(--ease);
}
.tw-skip:focus { top: 0; color: var(--white); }

.tw-muted { color: var(--ink-3); }
.tw-small { font-size: var(--fs-sm); }
.tw-center { text-align: center; }


/* ===== assets/layout.css ===== */
/* ==========================================================================
   TEEMCW — LAYOUT
   Announcement bar, header, panels, footer, and the page shell.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Announcement bar
   -------------------------------------------------------------------------- */

.tw-ann {
	position: relative;
	z-index: var(--z-ann);
	min-height: var(--ann-h);
	background: var(--ink);
	color: #fff;
	font-size: var(--fs-xs);
	letter-spacing: .03em;
}

.tw-ann__in {
	position: relative;
	display: grid;
	place-items: center;
	min-height: var(--ann-h);
}

.tw-ann__item {
	grid-area: 1 / 1;
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	margin: 0;
	opacity: 0;
	transform: translateY(4px);
	transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
	pointer-events: none;
	text-align: center;
}

.tw-ann__item.is-on { opacity: 1; transform: none; }
.tw-ann__item svg { opacity: .8; }

/* Without JavaScript the rotation never starts, so show the first message. */
html.no-js .tw-ann__item:first-child { opacity: 1; transform: none; }

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.tw-hd {
	position: sticky;
	top: 0;
	z-index: var(--z-header);
	background: rgba(255, 255, 255, .92);
	backdrop-filter: saturate(160%) blur(14px);
	-webkit-backdrop-filter: saturate(160%) blur(14px);
	border-bottom: 1px solid transparent;
	transition: border-color var(--dur) var(--ease),
	            box-shadow var(--dur) var(--ease),
	            transform var(--dur) var(--ease);
}

.tw-hd.is-stuck {
	border-bottom-color: var(--line);
	box-shadow: var(--shadow-sm);
}

/* Hidden while scrolling down, so the content gets the screen. */
.tw-hd.is-away { transform: translateY(-100%); }

.tw-hd__in {
	display: grid;
	/* The wordmark gets a reserved track. With `auto` the nav could grow past
	   the shell and squeeze the logo to zero width, which is exactly what a
	   long menu did. Now the nav is the column that has to give way. */
	grid-template-columns: minmax(9.5rem, auto) minmax(0, 1fr) auto;
	align-items: center;
	gap: var(--sp-4);
	min-height: var(--header-h);
}

.tw-hd__burger { display: none; }

.tw-hd__brand { justify-self: start; }

.tw-logo-link {
	display: inline-flex;
	align-items: center;
	/* The whole wordmark is the click target back to the home page, and it
	   gets the same hover treatment as the rest of the header. */
	padding: .25rem;
	margin: -.25rem;
	border-radius: var(--r-sm);
	transition: opacity var(--dur-fast) var(--ease);
}
.tw-logo-link:hover { opacity: .78; }

/* The source lockup is 183x88. Height is fixed to the header and the width
   follows, so the aspect ratio never distorts and no reflow happens while the
   image loads (the width/height attributes reserve the box). */
.tw-logo__img,
.custom-logo {
	display: block;
	width: auto;
	height: 2.25rem;
	max-height: 60%;
	object-fit: contain;
}

/* In the mobile drawer and the footer it can breathe a little more. */
.tw-mob__top .tw-logo__img,
.tw-mob__top .custom-logo { height: 2rem; }

.tw-ft__brand .tw-logo__img,
.tw-ft__brand .custom-logo { height: 2.5rem; margin-bottom: var(--sp-3); }

.tw-logo {
	display: inline-flex;
	align-items: center;
	gap: .5rem;
	color: var(--ink);
	font-family: var(--font-display);
	font-size: 1.3rem;
	font-weight: 600;
	letter-spacing: -.01em;
}

/* Primary navigation */
.tw-hd__nav { justify-self: center; }

.tw-nav {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-wrap: nowrap;
	gap: var(--sp-2);
	min-width: 0;
	margin: 0;
	padding: 0;
	list-style: none;
}

.tw-nav li { margin: 0; position: relative; }

.tw-nav > li > a {
	display: block;
	padding: .5rem 0;
	color: var(--ink-2);
	font-size: var(--fs-base);
	font-weight: 500;
	white-space: nowrap;
}

.tw-nav > li > a::after {
	content: "";
	display: block;
	height: 1.5px;
	margin-top: 3px;
	background: var(--rose-500);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform var(--dur) var(--ease);
}

.tw-nav > li > a:hover,
.tw-nav > li.current-menu-item > a { color: var(--rose-600); }

.tw-nav > li > a:hover::after,
.tw-nav > li.current-menu-item > a::after { transform: scaleX(1); }

/* Second level */
.tw-nav .sub-menu {
	position: absolute;
	top: 100%;
	left: 50%;
	min-width: 13rem;
	margin: 0;
	padding: var(--sp-2);
	list-style: none;
	background: var(--white);
	border: 1px solid var(--line);
	border-radius: var(--r-md);
	box-shadow: var(--shadow-md);
	opacity: 0;
	visibility: hidden;
	transform: translate(-50%, 6px);
	transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease), visibility var(--dur);
}

.tw-nav li:hover > .sub-menu,
.tw-nav li:focus-within > .sub-menu {
	opacity: 1;
	visibility: visible;
	transform: translate(-50%, 0);
}

.tw-nav .sub-menu a {
	display: block;
	padding: .5rem .75rem;
	border-radius: var(--r-sm);
	color: var(--ink-2);
	font-size: var(--fs-sm);
}
.tw-nav .sub-menu a:hover { background: var(--blush-2); color: var(--rose-700); }

/* Tools */
.tw-hd__tools {
	justify-self: end;
	display: flex;
	align-items: center;
	gap: var(--sp-1);
}

.tw-icon-btn {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.5rem;
	height: 2.5rem;
	padding: 0;
	border: 0;
	border-radius: var(--r-pill);
	background: transparent;
	color: var(--ink-2);
	cursor: pointer;
	transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.tw-icon-btn:hover { background: var(--blush-2); color: var(--rose-600); }

.tw-icon-btn__n,
.tw-bag__count {
	position: absolute;
	top: .25rem;
	right: .2rem;
	min-width: 1.05rem;
	height: 1.05rem;
	padding: 0 .25rem;
	border-radius: var(--r-pill);
	background: var(--rose-500);
	color: #fff;
	font-size: .625rem;
	font-weight: 700;
	line-height: 1.05rem;
	text-align: center;
}

.tw-icon-btn__n.is-empty,
.tw-bag__count.is-empty { display: none; }

/* --------------------------------------------------------------------------
   Search panel
   -------------------------------------------------------------------------- */

.tw-search {
	position: fixed;
	inset: 0 0 auto;
	z-index: var(--z-drawer);
	padding-block: var(--sp-5) var(--sp-6);
	background: var(--white);
	border-bottom: 1px solid var(--line);
	box-shadow: var(--shadow-lg);
	opacity: 0;
	transform: translateY(-12px);
	transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
	max-height: 100dvh;
	overflow-y: auto;
}

.tw-search.is-on { opacity: 1; transform: none; }

.tw-search__form {
	position: relative;
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	padding-bottom: var(--sp-4);
	border-bottom: 1px solid var(--line);
}

.tw-search__form > svg { color: var(--ink-4); flex: none; }

.tw-search__form input[type="search"] {
	flex: 1;
	padding: .5rem 0;
	border: 0;
	font-size: var(--fs-xl);
	font-family: var(--font-display);
}
.tw-search__form input[type="search"]:focus { box-shadow: none; }

.tw-search__out { padding-top: var(--sp-4); }

.tw-search__list { margin: 0; padding: 0; list-style: none; }

.tw-search__list a {
	display: grid;
	grid-template-columns: 56px 1fr auto;
	align-items: center;
	gap: var(--sp-4);
	padding: var(--sp-3);
	border-radius: var(--r-md);
	color: var(--ink);
}
.tw-search__list a:hover { background: var(--blush-1); }

.tw-search__list img {
	width: 56px; height: 56px;
	object-fit: cover;
	border-radius: var(--r-sm);
	background: var(--blush-2);
}

.tw-search__name { font-weight: 500; }
.tw-search__price { color: var(--rose-600); font-weight: 600; white-space: nowrap; }
.tw-search__hint { color: var(--ink-4); padding: var(--sp-3); margin: 0; }
.tw-search__all { margin: var(--sp-3) 0 0; padding-left: var(--sp-3); }

/* --------------------------------------------------------------------------
   Mobile menu
   -------------------------------------------------------------------------- */

.tw-mob { position: fixed; inset: 0; z-index: var(--z-drawer); }

.tw-mob__scrim {
	position: absolute;
	inset: 0;
	border: 0;
	padding: 0;
	background: rgba(35, 25, 29, .38);
	opacity: 0;
	transition: opacity var(--dur) var(--ease);
	cursor: pointer;
}
.tw-mob.is-on .tw-mob__scrim { opacity: 1; }

.tw-mob__panel {
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	width: min(88vw, 22rem);
	height: 100%;
	padding: var(--sp-5);
	background: var(--white);
	box-shadow: var(--shadow-lg);
	transform: translateX(-100%);
	transition: transform var(--dur-slow) var(--ease-out);
	overflow-y: auto;
}
.tw-mob.is-on .tw-mob__panel { transform: none; }

.tw-mob__top {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding-bottom: var(--sp-5);
	border-bottom: 1px solid var(--line);
}

.tw-mob__nav { flex: 1; padding-block: var(--sp-4); }

.tw-mob__list { margin: 0; padding: 0; list-style: none; }
.tw-mob__list li { margin: 0; }

.tw-mob__list a {
	display: block;
	padding: var(--sp-3) 0;
	border-bottom: 1px solid var(--line);
	color: var(--ink);
	font-size: var(--fs-lg);
	font-family: var(--font-display);
}
.tw-mob__list a:hover { color: var(--rose-600); }

.tw-mob__list .sub-menu {
	margin: 0 0 var(--sp-2) var(--sp-4);
	padding: 0;
	list-style: none;
}
.tw-mob__list .sub-menu a {
	font-family: var(--font-body);
	font-size: var(--fs-base);
	padding: var(--sp-2) 0;
	border-bottom: 0;
	color: var(--ink-3);
}

.tw-mob__foot { padding-top: var(--sp-4); border-top: 1px solid var(--line); }

.tw-mob__note {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	margin: var(--sp-4) 0 0;
	color: var(--ink-3);
	font-size: var(--fs-xs);
}

body.tw-locked { overflow: hidden; }

/* --------------------------------------------------------------------------
   Breadcrumbs
   -------------------------------------------------------------------------- */

.tw-crumbs {
	padding-block: var(--sp-4);
	border-bottom: 1px solid var(--line);
	font-size: var(--fs-sm);
}

.tw-crumbs__in,
.woocommerce-breadcrumb {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--sp-2);
	color: var(--ink-4);
	margin: 0;
}

.tw-crumbs a,
.woocommerce-breadcrumb a { color: var(--ink-3); }
.tw-crumbs a:hover,
.woocommerce-breadcrumb a:hover { color: var(--rose-600); }

.tw-crumbs__sep { color: var(--line-strong); }

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.tw-ft { background: var(--white); border-top: 1px solid var(--line); }

.tw-ft__main { padding-block: var(--sp-9) var(--sp-8); }

.tw-ft__cols {
	display: grid;
	grid-template-columns: 1.6fr repeat(4, 1fr);
	gap: var(--sp-7) var(--sp-5);
}

.tw-ft__tag {
	margin: var(--sp-3) 0 var(--sp-4);
	color: var(--ink-3);
	font-size: var(--fs-sm);
	max-width: 22rem;
}

.tw-ft__promise { margin: 0; padding: 0; list-style: none; }

.tw-ft__promise li {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	margin-bottom: var(--sp-2);
	color: var(--ink-3);
	font-size: var(--fs-sm);
}
.tw-ft__promise svg { color: var(--rose-400); flex: none; }

.tw-ft__h {
	margin-bottom: var(--sp-4);
	color: var(--ink);
	font-family: var(--font-body);
	font-size: var(--fs-xs);
	font-weight: 700;
	letter-spacing: var(--ls-caps);
	text-transform: uppercase;
}

.tw-ft__list { margin: 0; padding: 0; list-style: none; }
.tw-ft__list li { margin-bottom: var(--sp-2); }

.tw-ft__list a {
	color: var(--ink-3);
	font-size: var(--fs-sm);
}
.tw-ft__list a:hover { color: var(--rose-600); }

.tw-ft__hours { color: var(--ink-4); font-size: var(--fs-sm); }

.tw-ft__trust {
	padding-block: var(--sp-5);
	background: var(--blush-1);
	border-top: 1px solid var(--line);
}

.tw-ft__trust-in {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: var(--sp-4);
}

.tw-ft__pay { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }

.tw-ft__pay-label {
	color: var(--ink-4);
	font-size: var(--fs-xs);
	letter-spacing: var(--ls-wide);
	text-transform: uppercase;
}

.tw-ft__secure {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	margin: 0;
	color: var(--ink-3);
	font-size: var(--fs-xs);
}
.tw-ft__secure svg { color: var(--ok); flex: none; }

.tw-ft__legal { padding-block: var(--sp-4); border-top: 1px solid var(--line); }

.tw-ft__legal-in {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: var(--sp-3);
	color: var(--ink-4);
	font-size: var(--fs-xs);
}

.tw-ft__legal p { margin: 0; }

/* --------------------------------------------------------------------------
   Toast
   -------------------------------------------------------------------------- */

.tw-toast {
	position: fixed;
	left: 50%;
	bottom: var(--sp-6);
	z-index: var(--z-toast);
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	padding: .75rem 1.25rem;
	border-radius: var(--r-pill);
	background: var(--ink);
	color: #fff;
	font-size: var(--fs-sm);
	font-weight: 500;
	box-shadow: var(--shadow-lg);
	opacity: 0;
	transform: translate(-50%, 12px);
	pointer-events: none;
	transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}

.tw-toast.is-on { opacity: 1; transform: translate(-50%, 0); }
.tw-toast svg { color: var(--rose-300); flex: none; }

/* ===== assets/components.css ===== */
/* ==========================================================================
   TEEMCW — COMPONENTS
   Hero, trust row, collections, cards, story, reviews, FAQ, newsletter.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Reveal on scroll
   -------------------------------------------------------------------------- */

.tw-rv {
	opacity: 0;
	transform: translateY(14px);
	transition: opacity var(--dur-slow) var(--ease-out),
	            transform var(--dur-slow) var(--ease-out);
}
.tw-rv.is-in { opacity: 1; transform: none; }

/* Without JavaScript nothing ever adds .is-in, so never hide in the first
   place. The same applies when the visitor asked for reduced motion. */
html.no-js .tw-rv { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
	.tw-rv { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

.tw-hero {
	position: relative;
	overflow: hidden;
	background:
		radial-gradient(60rem 40rem at 82% 8%, var(--rose-50), transparent 62%),
		linear-gradient(180deg, var(--white), var(--blush-1));
}

.tw-hero__in {
	display: grid;
	grid-template-columns: 1.05fr .95fr;
	align-items: center;
	gap: var(--sp-8);
	padding-block: var(--sp-10) var(--sp-9);
}

.tw-hero__eyebrow {
	display: inline-block;
	margin-bottom: var(--sp-4);
	padding: .35rem .8rem;
	border: 1px solid var(--rose-200);
	border-radius: var(--r-pill);
	background: var(--white);
	color: var(--rose-600);
	font-size: var(--fs-xs);
	font-weight: 600;
	letter-spacing: var(--ls-caps);
	text-transform: uppercase;
}

.tw-hero__title {
	margin-bottom: var(--sp-4);
	font-size: var(--fs-4xl);
	font-weight: 500;
	max-width: 15ch;
}

.tw-hero__sub {
	max-width: 42ch;
	margin-bottom: var(--sp-6);
	color: var(--ink-2);
	font-size: var(--fs-lg);
	line-height: var(--lh-snug);
}

.tw-hero__cta { display: flex; flex-wrap: wrap; gap: var(--sp-3); }

.tw-hero__points {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-5);
	margin: var(--sp-7) 0 0;
	padding: 0;
	list-style: none;
}

.tw-hero__points li {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	margin: 0;
	color: var(--ink-3);
	font-size: var(--fs-sm);
}
.tw-hero__points svg { color: var(--rose-400); flex: none; }

/* --------------------------------------------------------------------------
   Trust row
   -------------------------------------------------------------------------- */

.tw-trust {
	display: grid;
	grid-template-columns: repeat(5, 1fr);
	gap: var(--sp-5);
	margin: 0;
	padding: 0;
	list-style: none;
}

.tw-trust__item {
	display: flex;
	align-items: flex-start;
	gap: var(--sp-3);
	margin: 0;
}

.tw-trust__icon {
	display: grid;
	place-items: center;
	width: 2.5rem;
	height: 2.5rem;
	flex: none;
	border-radius: var(--r-pill);
	background: var(--white);
	color: var(--rose-500);
	box-shadow: var(--shadow-sm);
}

.tw-trust__body { display: flex; flex-direction: column; gap: .15rem; }

.tw-trust__title {
	color: var(--ink);
	font-size: var(--fs-sm);
	font-weight: 600;
}

.tw-trust__text {
	color: var(--ink-3);
	font-size: var(--fs-xs);
	line-height: 1.45;
}

/* --------------------------------------------------------------------------
   Collections
   -------------------------------------------------------------------------- */

.tw-coll {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--sp-5);
	margin: 0;
	padding: 0;
	list-style: none;
}

.tw-coll__item { margin: 0; }

.tw-coll__link {
	display: block;
	border-radius: var(--r-lg);
	overflow: hidden;
	background: var(--blush-1);
	border: 1px solid var(--line);
	transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.tw-coll__link:hover {
	transform: translateY(-3px);
	box-shadow: var(--shadow-md);
}

.tw-coll__media {
	display: block;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	background: var(--blush-2);
}

.tw-coll__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform var(--dur-slow) var(--ease);
}
.tw-coll__link:hover .tw-coll__media img { transform: scale(1.04); }

.tw-coll__body {
	display: block;
	padding: var(--sp-4) var(--sp-5) var(--sp-5);
	background: var(--white);
}

.tw-coll__name {
	display: block;
	color: var(--ink);
	font-family: var(--font-display);
	font-size: var(--fs-xl);
	font-weight: 600;
}

.tw-coll__n {
	display: block;
	margin-top: .15rem;
	color: var(--ink-4);
	font-size: var(--fs-sm);
}

.tw-coll__cta {
	display: inline-flex;
	align-items: center;
	gap: .35rem;
	margin-top: var(--sp-3);
	color: var(--rose-600);
	font-size: var(--fs-sm);
	font-weight: 600;
}
.tw-coll__link:hover .tw-coll__cta svg { transform: translateX(3px); }
.tw-coll__cta svg { transition: transform var(--dur) var(--ease); }

/* --------------------------------------------------------------------------
   Product grid and card
   -------------------------------------------------------------------------- */

.tw-grid,
.woocommerce ul.products {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: var(--sp-5);
	margin: 0;
	padding: 0;
	list-style: none;
}

.tw-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.tw-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

.tw-grid::before,
.tw-grid::after,
.woocommerce ul.products::before,
.woocommerce ul.products::after { content: none; }

.tw-card,
.woocommerce ul.products li.product {
	position: relative;
	display: flex;
	flex-direction: column;
	margin: 0 !important;
	width: auto !important;
	float: none !important;
	clear: none !important;
}

.tw-card__media {
	position: relative;
	display: block;
	aspect-ratio: 4 / 5;
	border-radius: var(--r-lg);
	overflow: hidden;
	background: var(--blush-2);
	margin-bottom: var(--sp-3);
}

.tw-card__link { display: block; width: 100%; height: 100%; }

.tw-card__img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: contain;
	padding: var(--sp-3);
	transition: opacity var(--dur) var(--ease), transform var(--dur-slow) var(--ease);
}

.tw-card__img--hover { opacity: 0; }

@media (hover: hover) {
	.tw-card:hover .tw-card__img--hover { opacity: 1; }
	.tw-card:hover .tw-card__img:not(.tw-card__img--hover) { opacity: 0; }
	.tw-card:hover .tw-card__img { transform: scale(1.03); }
}

.tw-card__flags {
	position: absolute;
	top: var(--sp-3);
	left: var(--sp-3);
	display: flex;
	flex-direction: column;
	gap: var(--sp-1);
	z-index: 2;
	pointer-events: none;
}

.tw-card__wish {
	position: absolute;
	top: var(--sp-3);
	right: var(--sp-3);
	z-index: 2;
	display: grid;
	place-items: center;
	width: 2rem;
	height: 2rem;
	padding: 0;
	border: 0;
	border-radius: var(--r-pill);
	background: rgba(255, 255, 255, .92);
	color: var(--ink-3);
	cursor: pointer;
	box-shadow: var(--shadow-sm);
	opacity: 0;
	transform: translateY(-4px);
	transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease),
	            color var(--dur-fast) var(--ease);
}

.tw-card:hover .tw-card__wish,
.tw-card__wish:focus-visible,
.tw-card__wish.is-on { opacity: 1; transform: none; }

.tw-card__wish:hover { color: var(--rose-500); }
.tw-card__wish.is-on { color: var(--rose-500); }
.tw-card__wish.is-on svg { fill: var(--rose-500); }

/* Add button, tucked into the corner of the image. */
.tw-card__add {
	position: absolute;
	right: var(--sp-3);
	bottom: var(--sp-3);
	z-index: 2;
	display: inline-flex;
	align-items: center;
	gap: 0;
	max-width: 2.25rem;
	height: 2.25rem;
	padding: 0 .55rem;
	border: 0;
	border-radius: var(--r-pill);
	background: var(--rose-500);
	color: #fff;
	font-size: var(--fs-sm);
	font-weight: 600;
	cursor: pointer;
	overflow: hidden;
	white-space: nowrap;
	box-shadow: var(--shadow-rose);
	opacity: 0;
	transform: translateY(6px);
	transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease),
	            max-width var(--dur) var(--ease), background var(--dur-fast) var(--ease);
}

.tw-card__add svg { flex: none; }

.tw-card__add-text {
	max-width: 0;
	opacity: 0;
	transition: max-width var(--dur) var(--ease), opacity var(--dur) var(--ease),
	            margin var(--dur) var(--ease);
}

.tw-card:hover .tw-card__add,
.tw-card__add:focus-visible { opacity: 1; transform: none; }

.tw-card__add:hover {
	background: var(--rose-600);
	max-width: 8rem;
}
.tw-card__add:hover .tw-card__add-text {
	max-width: 5rem;
	opacity: 1;
	margin-left: .35rem;
}

.tw-card__add.is-busy { opacity: .7; pointer-events: none; }
.tw-card__add.is-done { background: var(--ok); }

.tw-card__body { display: flex; flex-direction: column; flex: 1; gap: .3rem; }

.tw-card__cat {
	color: var(--ink-4);
	font-size: var(--fs-xs);
	letter-spacing: var(--ls-wide);
	text-transform: uppercase;
}

.tw-card__name,
.woocommerce ul.products li.product .woocommerce-loop-product__title {
	margin: 0;
	padding: 0;
	font-family: var(--font-body);
	font-size: var(--fs-base);
	font-weight: 600;
	line-height: 1.35;
	letter-spacing: 0;
	overflow-wrap: anywhere;
}

.tw-card__name a { color: var(--ink); }
.tw-card__name a:hover { color: var(--rose-600); }

.tw-card__desc {
	margin: 0;
	color: var(--ink-3);
	font-size: var(--fs-xs);
	line-height: 1.5;
}

.tw-card__rating { margin-top: .15rem; }

.tw-card__foot {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--sp-2);
	margin-top: auto;
	padding-top: var(--sp-2);
}

.tw-card__price,
.woocommerce ul.products li.product .price {
	margin: 0;
	color: var(--ink) !important;
	font-size: var(--fs-md);
	font-weight: 700;
}

.tw-card__price del,
.woocommerce ul.products li.product .price del {
	margin-right: .35rem;
	color: var(--ink-4) !important;
	font-size: .85em;
	font-weight: 400;
	opacity: 1;
}

.tw-card__price ins,
.woocommerce ul.products li.product .price ins {
	background: none;
	color: var(--rose-600) !important;
	text-decoration: none;
}

.tw-card__stock {
	display: inline-flex;
	align-items: center;
	gap: .2rem;
	color: var(--ok);
	font-size: var(--fs-xs);
	white-space: nowrap;
}

/* --------------------------------------------------------------------------
   Stars
   -------------------------------------------------------------------------- */

.tw-stars { display: inline-flex; align-items: center; gap: .3rem; }
.tw-stars__row { display: inline-flex; gap: .05rem; }

.tw-star { color: var(--line-strong); line-height: 0; }
.tw-star.is-on { color: var(--rose-400); }
.tw-star.is-on svg { fill: var(--rose-400); }
.tw-star.is-half { color: var(--rose-300); }

.tw-stars__count { color: var(--ink-4); font-size: var(--fs-xs); }

/* --------------------------------------------------------------------------
   Story
   -------------------------------------------------------------------------- */

.tw-story__in {
	display: grid;
	grid-template-columns: 1fr 1.1fr;
	gap: var(--sp-8);
	align-items: center;
}

.tw-story__points {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--sp-5);
	margin: 0;
	padding: 0;
	list-style: none;
}

.tw-story__points li {
	margin: 0;
	padding: var(--sp-5);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--white);
}

.tw-story__points h3 {
	margin-bottom: .35rem;
	font-family: var(--font-body);
	font-size: var(--fs-base);
	font-weight: 600;
}

.tw-story__points p {
	margin: 0;
	color: var(--ink-3);
	font-size: var(--fs-sm);
	line-height: 1.5;
}

/* --------------------------------------------------------------------------
   Reviews
   -------------------------------------------------------------------------- */

.tw-revs {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--sp-5);
	margin: 0;
	padding: 0;
	list-style: none;
}

.tw-rev {
	margin: 0;
	padding: var(--sp-6);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--white);
}

.tw-rev__text {
	margin: var(--sp-3) 0 var(--sp-4);
	padding: 0;
	border: 0;
	color: var(--ink-2);
	font-family: var(--font-display);
	font-size: var(--fs-lg);
	line-height: 1.5;
	quotes: "\201C" "\201D";
}
.tw-rev__text::before { content: open-quote; color: var(--rose-300); }
.tw-rev__text::after { content: close-quote; color: var(--rose-300); }

.tw-rev__who {
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	flex-wrap: wrap;
	margin: 0;
	color: var(--ink);
	font-size: var(--fs-sm);
	font-weight: 600;
}

.tw-rev__verified {
	display: inline-flex;
	align-items: center;
	gap: .2rem;
	color: var(--ok);
	font-size: var(--fs-xs);
	font-weight: 500;
}

/* --------------------------------------------------------------------------
   FAQ
   -------------------------------------------------------------------------- */

.tw-faq { border-top: 1px solid var(--line); }

.tw-faq__item { border-bottom: 1px solid var(--line); }

.tw-faq__q {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-4);
	padding: var(--sp-4) 0;
	color: var(--ink);
	font-family: var(--font-display);
	font-size: var(--fs-lg);
	font-weight: 500;
	cursor: pointer;
	list-style: none;
}
.tw-faq__q::-webkit-details-marker { display: none; }
.tw-faq__q:hover { color: var(--rose-600); }
.tw-faq__q svg { flex: none; color: var(--rose-400); transition: transform var(--dur) var(--ease); }

.tw-faq__item[open] .tw-faq__q svg { transform: rotate(180deg); }

.tw-faq__a { padding-bottom: var(--sp-4); }
.tw-faq__a p { margin: 0; color: var(--ink-3); }

/* --------------------------------------------------------------------------
   Newsletter
   -------------------------------------------------------------------------- */

.tw-news__in {
	display: grid;
	grid-template-columns: 1fr 1fr;
	align-items: center;
	gap: var(--sp-7);
}

.tw-news__title { margin-bottom: var(--sp-2); }
.tw-news__sub { margin: 0; color: var(--ink-3); }

.tw-news__form {
	display: grid;
	grid-template-columns: 1fr auto;
	gap: var(--sp-3);
}

.tw-news__note {
	grid-column: 1 / -1;
	margin: 0;
	color: var(--ink-4);
	font-size: var(--fs-xs);
}

/* --------------------------------------------------------------------------
   Empty states
   -------------------------------------------------------------------------- */

.tw-empty {
	padding: var(--sp-9) var(--sp-5);
	text-align: center;
	color: var(--ink-3);
	background: var(--blush-1);
	border-radius: var(--r-lg);
}

/* ===== assets/woocommerce.css ===== */
/* ==========================================================================
   TEEMCW — WOOCOMMERCE
   Shop, single product, cart, checkout, account. Restyles WooCommerce's own
   markup rather than replacing it, so its behaviour stays intact.
   ========================================================================== */

.tw-woo { padding-block: var(--sp-7) var(--sp-10); }

.woocommerce-products-header { margin-bottom: var(--sp-6); }

.woocommerce-products-header__title,
.woocommerce .page-title {
	margin-bottom: var(--sp-2);
	font-size: var(--fs-3xl);
}

.term-description { color: var(--ink-3); max-width: 60ch; }

/* --------------------------------------------------------------------------
   Toolbar
   -------------------------------------------------------------------------- */

.tw-toolbar {
	display: flex;
	align-items: center;
	gap: var(--sp-4);
	padding: var(--sp-3) 0 var(--sp-5);
	margin-bottom: var(--sp-5);
	border-bottom: 1px solid var(--line);
}

.tw-toolbar__filter { display: none; }

.tw-toolbar__count { flex: 1; }

.woocommerce .woocommerce-result-count {
	margin: 0;
	color: var(--ink-4);
	font-size: var(--fs-sm);
}

.woocommerce .woocommerce-ordering { margin: 0; }

.woocommerce .woocommerce-ordering select {
	width: auto;
	min-width: 12rem;
	padding: .55rem 2rem .55rem .875rem;
	font-size: var(--fs-sm);
	border-radius: var(--r-pill);
	appearance: none;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236f6266' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right .75rem center;
}

/* --------------------------------------------------------------------------
   Pagination
   -------------------------------------------------------------------------- */

.woocommerce nav.woocommerce-pagination {
	margin-top: var(--sp-8);
	text-align: center;
}

.woocommerce nav.woocommerce-pagination ul {
	display: inline-flex;
	gap: var(--sp-1);
	border: 0;
	margin: 0;
	padding: 0;
}

.woocommerce nav.woocommerce-pagination ul li {
	border: 0;
	margin: 0;
	overflow: visible;
}

.woocommerce nav.woocommerce-pagination ul li a,
.woocommerce nav.woocommerce-pagination ul li span {
	display: grid;
	place-items: center;
	min-width: 2.5rem;
	height: 2.5rem;
	padding: 0 .6rem;
	border-radius: var(--r-pill);
	background: var(--white);
	border: 1px solid var(--line);
	color: var(--ink-2);
	font-size: var(--fs-sm);
	font-weight: 500;
}

.woocommerce nav.woocommerce-pagination ul li a:hover {
	background: var(--blush-2);
	border-color: var(--dusty-soft);
	color: var(--rose-700);
}

.woocommerce nav.woocommerce-pagination ul li span.current {
	background: var(--rose-500);
	border-color: var(--rose-500);
	color: #fff;
}

/* --------------------------------------------------------------------------
   Single product
   -------------------------------------------------------------------------- */

.woocommerce div.product {
	display: grid;
	grid-template-columns: minmax(0, 1.05fr) minmax(320px, .95fr);
	gap: var(--sp-8);
	align-items: start;
}

.woocommerce div.product .woocommerce-product-gallery {
	position: sticky;
	top: calc(var(--header-h) + var(--sp-4));
	width: 100% !important;
	float: none !important;
	margin-bottom: 0;
}

.woocommerce div.product div.images img {
	border-radius: var(--r-lg);
	background: var(--blush-2);
}

.woocommerce div.product .flex-control-thumbs {
	display: grid;
	grid-template-columns: repeat(5, 1fr);
	gap: var(--sp-2);
	margin-top: var(--sp-3);
	padding: 0;
}

.woocommerce div.product .flex-control-thumbs li {
	width: 100%;
	float: none;
	margin: 0;
	list-style: none;
}

.woocommerce div.product .flex-control-thumbs img {
	border-radius: var(--r-sm);
	border: 1px solid var(--line);
	opacity: .65;
	transition: opacity var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.woocommerce div.product .flex-control-thumbs img:hover,
.woocommerce div.product .flex-control-thumbs img.flex-active {
	opacity: 1;
	border-color: var(--rose-300);
}

.woocommerce div.product .summary { margin: 0 !important; width: 100% !important; float: none !important; }

.woocommerce div.product .product_title {
	margin-bottom: var(--sp-3);
	font-size: var(--fs-3xl);
}

.woocommerce div.product .woocommerce-product-rating {
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	margin-bottom: var(--sp-4);
}

.woocommerce div.product p.price,
.woocommerce div.product span.price {
	margin-bottom: var(--sp-4);
	color: var(--ink);
	font-size: var(--fs-2xl);
	font-weight: 700;
}

.woocommerce div.product p.price del { color: var(--ink-4); font-size: .6em; font-weight: 400; }
.woocommerce div.product p.price ins { background: none; color: var(--rose-600); text-decoration: none; }

.woocommerce div.product .woocommerce-product-details__short-description {
	margin-bottom: var(--sp-5);
	padding-bottom: var(--sp-5);
	border-bottom: 1px solid var(--line);
	color: var(--ink-2);
	font-size: var(--fs-md);
	line-height: var(--lh-snug);
}

.woocommerce div.product .stock {
	display: inline-flex;
	align-items: center;
	gap: .3rem;
	margin-bottom: var(--sp-4);
	font-size: var(--fs-sm);
	font-weight: 600;
}
.woocommerce div.product .stock.in-stock { color: var(--ok); }
.woocommerce div.product .stock.out-of-stock { color: var(--err); }

/* Add to cart row */
.woocommerce div.product form.cart {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-3);
	margin-bottom: var(--sp-5);
}

.woocommerce div.product form.cart .quantity {
	display: flex;
	align-items: center;
	border: 1px solid var(--line-2);
	border-radius: var(--r-pill);
	overflow: hidden;
	background: var(--white);
}

.woocommerce div.product form.cart .quantity input.qty {
	width: 3.25rem;
	padding: .8rem .25rem;
	border: 0;
	text-align: center;
	font-weight: 600;
	appearance: textfield;
}
.woocommerce div.product form.cart .quantity input.qty::-webkit-outer-spin-button,
.woocommerce div.product form.cart .quantity input.qty::-webkit-inner-spin-button {
	appearance: none; margin: 0;
}
.woocommerce div.product form.cart .quantity input.qty:focus { box-shadow: none; }

.tw-qty-btn {
	display: grid;
	place-items: center;
	width: 2.5rem;
	height: 2.75rem;
	border: 0;
	background: transparent;
	color: var(--ink-3);
	cursor: pointer;
}
.tw-qty-btn:hover { background: var(--blush-2); color: var(--rose-600); }

.woocommerce div.product form.cart button.single_add_to_cart_button { flex: 1; min-width: 12rem; }

/* Assurances */
.tw-assure {
	margin: var(--sp-5) 0 0;
	padding: var(--sp-5);
	list-style: none;
	background: var(--blush-1);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
}

.tw-assure li {
	display: flex;
	align-items: flex-start;
	gap: var(--sp-3);
	margin-bottom: var(--sp-4);
	font-size: var(--fs-sm);
	color: var(--ink-3);
	line-height: 1.5;
}
.tw-assure li:last-child { margin-bottom: 0; }
.tw-assure svg { flex: none; color: var(--rose-500); margin-top: .1rem; }
.tw-assure strong { display: block; color: var(--ink); }

.woocommerce div.product .product_meta {
	margin-top: var(--sp-5);
	padding-top: var(--sp-4);
	border-top: 1px solid var(--line);
	color: var(--ink-4);
	font-size: var(--fs-xs);
}
.woocommerce div.product .product_meta > span { display: block; margin-bottom: .25rem; }

/* Tabs */
.woocommerce div.product .woocommerce-tabs {
	grid-column: 1 / -1;
	margin-top: var(--sp-8);
}

.woocommerce div.product .woocommerce-tabs ul.tabs {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-1);
	margin: 0 0 var(--sp-6);
	padding: 0 0 var(--sp-1);
	border-bottom: 1px solid var(--line);
}
.woocommerce div.product .woocommerce-tabs ul.tabs::before { display: none; }

.woocommerce div.product .woocommerce-tabs ul.tabs li {
	margin: 0;
	padding: 0;
	border: 0;
	background: transparent;
	border-radius: 0;
}
.woocommerce div.product .woocommerce-tabs ul.tabs li::before,
.woocommerce div.product .woocommerce-tabs ul.tabs li::after { display: none; }

.woocommerce div.product .woocommerce-tabs ul.tabs li a {
	display: block;
	padding: .75rem 1.1rem;
	border-radius: var(--r-sm) var(--r-sm) 0 0;
	color: var(--ink-3);
	font-weight: 600;
	font-size: var(--fs-sm);
}

.woocommerce div.product .woocommerce-tabs ul.tabs li a:hover { color: var(--rose-600); }

.woocommerce div.product .woocommerce-tabs ul.tabs li.active a {
	color: var(--rose-700);
	box-shadow: inset 0 -2px 0 var(--rose-500);
}

.woocommerce div.product .woocommerce-tabs .panel {
	max-width: 70ch;
	margin: 0;
	padding: 0;
}
.woocommerce div.product .woocommerce-tabs .panel h2 { font-size: var(--fs-xl); }
.woocommerce div.product .woocommerce-tabs .panel h3 { font-size: var(--fs-lg); margin-top: var(--sp-5); }

.woocommerce table.shop_attributes {
	width: 100%;
	border: 1px solid var(--line);
	border-radius: var(--r-md);
	overflow: hidden;
	border-collapse: collapse;
}
.woocommerce table.shop_attributes th,
.woocommerce table.shop_attributes td {
	padding: .75rem 1rem;
	border-bottom: 1px solid var(--line);
	font-size: var(--fs-sm);
	text-align: left;
	font-style: normal;
}
.woocommerce table.shop_attributes th { background: var(--blush-1); color: var(--ink); width: 34%; }

/* Related */
.woocommerce .related,
.woocommerce .upsells {
	grid-column: 1 / -1;
	margin-top: var(--sp-9);
	padding-top: var(--sp-8);
	border-top: 1px solid var(--line);
}
.woocommerce .related > h2,
.woocommerce .upsells > h2 { margin-bottom: var(--sp-6); font-size: var(--fs-2xl); }

/* Reviews */
.woocommerce #reviews #comments ol.commentlist { padding: 0; }

.woocommerce #reviews #comments ol.commentlist li {
	margin-bottom: var(--sp-5);
	padding: var(--sp-5);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--white);
}

.woocommerce #reviews #comments ol.commentlist li img.avatar {
	position: static;
	float: left;
	width: 2.75rem;
	margin-right: var(--sp-3);
	padding: 0;
	border: 0;
	border-radius: var(--r-pill);
	background: var(--blush-2);
}

.woocommerce #reviews #comments ol.commentlist li .comment-text {
	margin: 0;
	padding: 0;
	border: 0;
	overflow: hidden;
}

.woocommerce #review_form #respond textarea { min-height: 7rem; }

/* --------------------------------------------------------------------------
   Notices
   -------------------------------------------------------------------------- */

.woocommerce-message,
.woocommerce-info,
.woocommerce-error,
.woocommerce-noreviews {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--sp-3);
	margin: 0 0 var(--sp-5);
	padding: var(--sp-4) var(--sp-5);
	border: 1px solid var(--line);
	border-left: 3px solid var(--rose-400);
	border-radius: var(--r-md);
	background: var(--blush-1);
	color: var(--ink-2);
	font-size: var(--fs-sm);
	list-style: none;
}
.woocommerce-message::before,
.woocommerce-info::before,
.woocommerce-error::before { display: none; }

.woocommerce-message { border-left-color: var(--ok); background: var(--ok-bg); }
.woocommerce-error { border-left-color: var(--err); background: var(--err-bg); }

.woocommerce-message .button,
.woocommerce-info .button { margin-left: auto; }

.tw-discreet,
.tw-secure {
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	margin: 0 0 var(--sp-5);
	padding: var(--sp-4);
	border: 1px dashed var(--dusty-soft);
	border-radius: var(--r-md);
	background: var(--blush-1);
	color: var(--ink-3);
	font-size: var(--fs-sm);
}
.tw-discreet svg, .tw-secure svg { flex: none; color: var(--rose-500); }
.tw-secure { border-style: solid; margin-block: var(--sp-4); }
.tw-secure svg { color: var(--ok); }

/* --------------------------------------------------------------------------
   Cart
   -------------------------------------------------------------------------- */

.woocommerce-cart .woocommerce {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(300px, 380px);
	gap: var(--sp-7);
	align-items: start;
}

.woocommerce-cart form.woocommerce-cart-form { grid-column: 1; }
.woocommerce-cart .cart-collaterals { grid-column: 2; width: 100%; }
.woocommerce-cart .cart-collaterals .cart_totals {
	width: 100% !important;
	float: none !important;
	position: sticky;
	top: calc(var(--header-h) + var(--sp-4));
}

.woocommerce table.shop_table {
	width: 100%;
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	border-collapse: separate;
	border-spacing: 0;
	overflow: hidden;
}

.woocommerce table.shop_table th {
	padding: var(--sp-4);
	background: var(--blush-1);
	color: var(--ink);
	font-size: var(--fs-xs);
	font-weight: 700;
	letter-spacing: var(--ls-wide);
	text-transform: uppercase;
	text-align: left;
}

.woocommerce table.shop_table td {
	padding: var(--sp-4);
	border-top: 1px solid var(--line);
	vertical-align: middle;
}

.woocommerce table.shop_table img { width: 64px; border-radius: var(--r-sm); background: var(--blush-2); }

.woocommerce a.remove {
	display: grid;
	place-items: center;
	width: 1.75rem;
	height: 1.75rem;
	border-radius: var(--r-pill);
	color: var(--ink-4) !important;
	font-size: 1.1rem;
	line-height: 1;
}
.woocommerce a.remove:hover { background: var(--err-bg); color: var(--err) !important; }

.woocommerce .cart_totals h2 { font-size: var(--fs-xl); margin-bottom: var(--sp-4); }

.woocommerce-cart .cart_totals table { border-radius: var(--r-lg); }
.woocommerce-cart .cart_totals table th { text-transform: none; letter-spacing: 0; font-size: var(--fs-sm); }

.woocommerce .wc-proceed-to-checkout { padding: var(--sp-4) 0 0; }
.woocommerce .wc-proceed-to-checkout a.checkout-button { width: 100%; }

.tw-freeship { margin-bottom: var(--sp-4); }

.tw-freeship__msg {
	display: flex;
	align-items: center;
	gap: .4rem;
	margin: 0 0 var(--sp-2);
	color: var(--ink-2);
	font-size: var(--fs-sm);
}
.tw-freeship__msg svg { color: var(--ok); }

.tw-freeship__bar {
	height: 5px;
	border-radius: var(--r-pill);
	background: var(--line);
	overflow: hidden;
}
.tw-freeship__bar span {
	display: block;
	height: 100%;
	border-radius: inherit;
	background: linear-gradient(90deg, var(--rose-400), var(--rose-500));
	transition: width var(--dur-slow) var(--ease);
}

/* Coupon */
.woocommerce .coupon { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.woocommerce .coupon input#coupon_code { width: auto; min-width: 11rem; }

/* --------------------------------------------------------------------------
   Checkout
   -------------------------------------------------------------------------- */

.woocommerce-checkout form.checkout {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(320px, 420px);
	gap: var(--sp-7);
	align-items: start;
}

.woocommerce-checkout #customer_details { grid-column: 1; }
.woocommerce-checkout h3 { font-size: var(--fs-xl); margin-bottom: var(--sp-4); }

.woocommerce-checkout .col2-set,
.woocommerce-checkout .col2-set .col-1,
.woocommerce-checkout .col2-set .col-2 { width: 100%; float: none; }

.woocommerce form .form-row { margin-bottom: var(--sp-4); padding: 0; }
.woocommerce form .form-row label { margin-bottom: var(--sp-2); }
.woocommerce form .form-row .required { color: var(--rose-500); text-decoration: none; }

.woocommerce-checkout .woocommerce-checkout-review-order {
	grid-column: 2;
	position: sticky;
	top: calc(var(--header-h) + var(--sp-4));
	padding: var(--sp-5);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--blush-1);
}

.woocommerce-checkout #order_review table.shop_table { background: var(--white); }

.woocommerce-checkout #payment {
	background: transparent;
	border-radius: 0;
	padding: 0;
	margin-top: var(--sp-4);
}

.woocommerce-checkout #payment ul.payment_methods {
	padding: 0;
	border: 0;
	margin: 0 0 var(--sp-4);
	list-style: none;
}

.woocommerce-checkout #payment ul.payment_methods li {
	margin-bottom: var(--sp-2);
	padding: var(--sp-4);
	border: 1px solid var(--line-2);
	border-radius: var(--r-md);
	background: var(--white);
}

.woocommerce-checkout #payment ul.payment_methods li label {
	display: inline;
	margin: 0;
	font-weight: 600;
}

.woocommerce-checkout #payment div.payment_box {
	margin: var(--sp-3) 0 0;
	padding: var(--sp-3);
	border-radius: var(--r-sm);
	background: var(--blush-2);
	color: var(--ink-3);
	font-size: var(--fs-sm);
}
.woocommerce-checkout #payment div.payment_box::before { display: none; }

/* Let the gateway's own iframe size itself: forcing a height here is what
   produces the scrollbars inside a payment frame. */
.woocommerce-checkout #payment iframe { width: 100%; border: 0; }

.woocommerce-checkout #payment #place_order { width: 100%; margin-top: var(--sp-3); }

.woocommerce-checkout .woocommerce-terms-and-conditions-wrapper { margin-bottom: var(--sp-4); font-size: var(--fs-sm); }

/* --------------------------------------------------------------------------
   Account
   -------------------------------------------------------------------------- */

.woocommerce-account .woocommerce {
	display: grid;
	grid-template-columns: 230px minmax(0, 1fr);
	gap: var(--sp-7);
	align-items: start;
}

.woocommerce-account .woocommerce-MyAccount-navigation ul {
	margin: 0;
	padding: 0;
	list-style: none;
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	overflow: hidden;
}

.woocommerce-account .woocommerce-MyAccount-navigation li { margin: 0; border-bottom: 1px solid var(--line); }
.woocommerce-account .woocommerce-MyAccount-navigation li:last-child { border-bottom: 0; }

.woocommerce-account .woocommerce-MyAccount-navigation li a {
	display: block;
	padding: .8rem 1rem;
	color: var(--ink-2);
	font-size: var(--fs-sm);
	font-weight: 500;
}
.woocommerce-account .woocommerce-MyAccount-navigation li a:hover { background: var(--blush-1); color: var(--rose-600); }

.woocommerce-account .woocommerce-MyAccount-navigation li.is-active a {
	background: var(--rose-500);
	color: #fff;
}

.woocommerce-account .woocommerce-MyAccount-content { min-width: 0; }

.woocommerce-account .woocommerce-form-login,
.woocommerce-account .woocommerce-form-register {
	max-width: 30rem;
	margin-inline: auto;
	padding: var(--sp-6);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--white);
}

/* --------------------------------------------------------------------------
   Filter drawer
   -------------------------------------------------------------------------- */

.tw-filters { position: fixed; inset: 0; z-index: var(--z-drawer); }

.tw-filters__scrim {
	position: absolute; inset: 0;
	border: 0; padding: 0;
	background: rgba(35, 25, 29, .38);
	opacity: 0;
	transition: opacity var(--dur) var(--ease);
}
.tw-filters.is-on .tw-filters__scrim { opacity: 1; }

.tw-filters__panel {
	position: absolute;
	inset: 0 0 0 auto;
	width: min(90vw, 22rem);
	padding: var(--sp-5);
	background: var(--white);
	box-shadow: var(--shadow-lg);
	transform: translateX(100%);
	transition: transform var(--dur-slow) var(--ease-out);
	overflow-y: auto;
}
.tw-filters.is-on .tw-filters__panel { transform: none; }

.tw-widget { margin-bottom: var(--sp-6); }
.tw-widget__title {
	margin-bottom: var(--sp-3);
	font-family: var(--font-body);
	font-size: var(--fs-xs);
	font-weight: 700;
	letter-spacing: var(--ls-caps);
	text-transform: uppercase;
}
.tw-widget ul { margin: 0; padding: 0; list-style: none; }
.tw-widget li { margin-bottom: var(--sp-2); font-size: var(--fs-sm); }
.tw-widget a { color: var(--ink-2); }
.tw-widget a:hover { color: var(--rose-600); }

/* --------------------------------------------------------------------------
   PRODUCT GALLERY
   WooCommerce's own stylesheets are dequeued, and one of them (flexslider)
   carries the layout the gallery slider needs. Without it the slides stack
   vertically and the thumbnail strip never appears, so the rules are restated
   here in the theme's own terms.

   The inline `opacity: 0` WooCommerce prints is cleared by its script once
   flexslider initialises. The fallback below guarantees the images are
   visible even if that script fails, because a blank product page is far
   worse than an un-sliding one.
   -------------------------------------------------------------------------- */

.woocommerce div.product .woocommerce-product-gallery {
	opacity: 1 !important;
}

.woocommerce div.product .woocommerce-product-gallery__wrapper {
	margin: 0;
	padding: 0;
	transition: transform .4s var(--ease);
}

.woocommerce div.product .woocommerce-product-gallery__image {
	margin: 0;
	list-style: none;
}

.woocommerce div.product .woocommerce-product-gallery__image a {
	display: block;
}

.woocommerce div.product .woocommerce-product-gallery__image img {
	width: 100%;
	height: auto;
	display: block;
	border-radius: var(--r-lg);
	background: var(--blush-2);
}

/* Flexslider viewport: one slide wide, the rest carried off to the side. */
.woocommerce div.product .flex-viewport {
	position: relative;
	overflow: hidden;
	border-radius: var(--r-lg);
	max-height: none;
}

.woocommerce div.product .flex-viewport .woocommerce-product-gallery__wrapper {
	display: flex;
	width: 100%;
}

.woocommerce div.product .flex-viewport .woocommerce-product-gallery__image {
	flex: 0 0 auto;
	width: 100%;
}

/* Before the script runs, only the first image should be on screen: otherwise
   seven full-size photographs stack down the page. */
.woocommerce div.product .woocommerce-product-gallery:not(.tw-ready)
	> .woocommerce-product-gallery__wrapper > .woocommerce-product-gallery__image:not(:first-child) {
	display: none;
}

/* Once flexslider has built the viewport, every slide is back in play. */
.woocommerce div.product .flex-viewport .woocommerce-product-gallery__image {
	display: block !important;
}

/* Flexslider's own direction arrows, restyled rather than hidden. */
.woocommerce div.product .flex-direction-nav {
	margin: 0;
	padding: 0;
	list-style: none;
}

.woocommerce div.product .flex-direction-nav a {
	position: absolute;
	top: 50%;
	z-index: 3;
	display: grid;
	place-items: center;
	width: 2.5rem;
	height: 2.5rem;
	margin-top: -1.25rem;
	border-radius: var(--r-pill);
	background: rgba(255, 255, 255, .94);
	border: 1px solid var(--line);
	box-shadow: var(--shadow-sm);
	color: var(--ink-2);
	font-size: 0;
	opacity: 0;
	transition: opacity var(--dur) var(--ease), background var(--dur-fast) var(--ease);
}

.woocommerce div.product .images:hover .flex-direction-nav a,
.woocommerce div.product .flex-direction-nav a:focus-visible { opacity: 1; }

.woocommerce div.product .flex-direction-nav a:hover {
	background: var(--rose-500);
	border-color: var(--rose-500);
	color: #fff;
}

.woocommerce div.product .flex-direction-nav .flex-prev { left: var(--sp-3); }
.woocommerce div.product .flex-direction-nav .flex-next { right: var(--sp-3); }

/* The arrows are text links in the markup, so the chevron is drawn here. */
.woocommerce div.product .flex-direction-nav a::before {
	content: "";
	width: .6rem;
	height: .6rem;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: rotate(-45deg);
	margin-left: -.15rem;
}
.woocommerce div.product .flex-direction-nav .flex-prev::before {
	transform: rotate(135deg);
	margin-left: .15rem;
}

/* Zoom hint on the main image. */
.woocommerce div.product .woocommerce-product-gallery__trigger {
	position: absolute;
	top: var(--sp-3);
	right: var(--sp-3);
	z-index: 3;
	display: grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	border-radius: var(--r-pill);
	background: rgba(255, 255, 255, .94);
	border: 1px solid var(--line);
	box-shadow: var(--shadow-sm);
	color: var(--ink-2);
	font-size: 0;
	text-decoration: none;
}
.woocommerce div.product .woocommerce-product-gallery__trigger:hover {
	background: var(--rose-500);
	border-color: var(--rose-500);
	color: #fff;
}
.woocommerce div.product .woocommerce-product-gallery__trigger::before {
	content: "";
	width: .85rem;
	height: .85rem;
	border: 2px solid currentColor;
	border-radius: 50%;
}
.woocommerce div.product .woocommerce-product-gallery__trigger::after {
	content: "";
	position: absolute;
	right: .5rem;
	bottom: .5rem;
	width: .42rem;
	height: 2px;
	background: currentColor;
	transform: rotate(45deg);
}

.woocommerce div.product .images { position: relative; }

/* ===== assets/motion.css ===== */
/* ==========================================================================
   TEEMCW — MOTION, HERO, DRAWER, LOADER
   Loaded after woocommerce.css, before responsive.css.

   Everything here animates transform or opacity only. No width, height, top
   or left is ever transitioned, so the compositor does the work and a 144Hz
   panel gets 144 distinct frames instead of 144 copies of the same one.
   ========================================================================== */

/* Let the browser skip work for offscreen sections entirely. */
.tw-sec {
	content-visibility: auto;
	contain-intrinsic-size: auto 600px;
}

/* --------------------------------------------------------------------------
   Page loader
   -------------------------------------------------------------------------- */

.tw-loader {
	position: fixed;
	inset: 0;
	z-index: 9999;
	display: grid;
	place-items: center;
	gap: var(--sp-5);
	background: var(--white);
	/* The loader must never be what stops someone using the site. It is a
	   first-paint cover, not a modal: clicks pass straight through it, so a
	   script that fails to load cannot leave the page unusable. */
	pointer-events: none;
	transition: opacity 420ms var(--ease), visibility 420ms;
}

/* Without JavaScript nothing ever adds .is-done, so the cover would sit over
   the page forever. It is hidden outright in that case. */
html.no-js .tw-loader { display: none; }

/* A CSS-only deadline, so the cover clears even if the script never runs. */
@media (prefers-reduced-motion: no-preference) {
	.tw-loader { animation: tw-loader-out 2.4s forwards; }
}

@keyframes tw-loader-out {
	0%, 82%  { opacity: 1; visibility: visible; }
	100%     { opacity: 0; visibility: hidden; }
}

@media (prefers-reduced-motion: reduce) {
	.tw-loader { display: none; }
}

.tw-loader.is-done {
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
}

.tw-loader__in {
	display: grid;
	justify-items: center;
	gap: var(--sp-5);
}

.tw-loader__logo {
	width: 148px;
	height: auto;
	animation: tw-pulse 1.5s var(--ease) infinite;
}

@keyframes tw-pulse {
	0%, 100% { opacity: 1; transform: scale(1); }
	50%      { opacity: .74; transform: scale(.975); }
}

@keyframes tw-slide {
	0%   { transform: translateX(-110%); }
	100% { transform: translateX(360%); }
}

@media (prefers-reduced-motion: reduce) {
	.tw-loader__logo,

}

/* --------------------------------------------------------------------------
   Scroll progress
   -------------------------------------------------------------------------- */

.tw-progress {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	height: 2px;
	z-index: calc(var(--z-header) + 5);
	pointer-events: none;
	background: transparent;
}

.tw-progress__bar {
	height: 100%;
	transform-origin: 0 50%;
	transform: scaleX(0);
	background: linear-gradient(90deg, var(--rose-300), var(--rose-500), var(--rose-600));
	will-change: transform;
}

/* --------------------------------------------------------------------------
   Reveal
   -------------------------------------------------------------------------- */

.tw-rv {
	opacity: 0;
	transform: translate3d(0, 18px, 0);
	transition: opacity 620ms var(--ease-out), transform 620ms var(--ease-out);
	will-change: opacity, transform;
}

.tw-rv.is-in {
	opacity: 1;
	transform: none;
	will-change: auto;
}

html.no-js .tw-rv { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
	.tw-rv { opacity: 1 !important; transform: none !important; transition: none; }
}

/* --------------------------------------------------------------------------
   Hero carousel
   -------------------------------------------------------------------------- */

.tw-hero {
	position: relative;
	overflow: hidden;
	isolation: isolate;
}

.tw-hero__bg {
	position: absolute;
	inset: 0;
	z-index: -1;
	background:
		radial-gradient(52rem 34rem at 78% 12%, var(--rose-50), transparent 64%),
		radial-gradient(38rem 30rem at 8% 92%, var(--blush-3), transparent 62%),
		linear-gradient(180deg, var(--white) 0%, var(--blush-1) 100%);
}

.tw-hero__in {
	position: relative;
	padding-block: var(--sp-9) var(--sp-8);
}

/* All slides stack; only the active one is painted. */
.tw-hero__stage {
	display: grid;
	min-height: 30rem;
}

.tw-slide {
	grid-area: 1 / 1;
	display: grid;
	grid-template-columns: 1.05fr .95fr;
	align-items: center;
	gap: var(--sp-8);
	opacity: 0;
	visibility: hidden;
	transform: translate3d(0, 14px, 0);
	transition: opacity 760ms var(--ease-out),
	            transform 760ms var(--ease-out),
	            visibility 760ms;
	pointer-events: none;
}

.tw-slide.is-on {
	opacity: 1;
	visibility: visible;
	transform: none;
	pointer-events: auto;
}

/* The copy arrives just after the slide, which reads as intentional rather
   than as a single hard cut. */
.tw-slide__copy > * {
	opacity: 0;
	transform: translate3d(0, 12px, 0);
	transition: opacity 560ms var(--ease-out), transform 560ms var(--ease-out);
}

.tw-slide.is-on .tw-slide__copy > * { opacity: 1; transform: none; }
.tw-slide.is-on .tw-slide__copy > *:nth-child(1) { transition-delay: 90ms; }
.tw-slide.is-on .tw-slide__copy > *:nth-child(2) { transition-delay: 160ms; }
.tw-slide.is-on .tw-slide__copy > *:nth-child(3) { transition-delay: 230ms; }
.tw-slide.is-on .tw-slide__copy > *:nth-child(4) { transition-delay: 300ms; }

.tw-slide__art {
	position: relative;
	aspect-ratio: 1 / 1;
	border-radius: var(--r-xl);
	overflow: hidden;
	background: var(--blush-2);
	box-shadow: var(--shadow-md);
}

.tw-slide__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transform: scale(1.06);
	transition: transform 1100ms var(--ease-out);
}
.tw-slide.is-on .tw-slide__img { transform: scale(1); }

@media (prefers-reduced-motion: reduce) {
	.tw-slide,
	.tw-slide__copy > *,
	.tw-slide__img { transition: none; transform: none; }
	.tw-slide__img { transform: none; }
}

/* Carousel controls */
.tw-hero__nav {
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	margin-top: var(--sp-6);
}

.tw-hero__arrow {
	display: grid;
	place-items: center;
	width: 2.5rem;
	height: 2.5rem;
	border: 1px solid var(--line-2);
	border-radius: var(--r-pill);
	background: var(--white);
	color: var(--ink-2);
	cursor: pointer;
	transition: background var(--dur-fast) var(--ease),
	            border-color var(--dur-fast) var(--ease),
	            color var(--dur-fast) var(--ease),
	            transform var(--dur-fast) var(--ease);
}

.tw-hero__arrow:first-child svg { transform: rotate(180deg); }

.tw-hero__arrow:hover {
	background: var(--rose-500);
	border-color: var(--rose-500);
	color: #fff;
	transform: translateY(-1px);
}

.tw-hero__dots { display: flex; gap: var(--sp-2); }

.tw-hero__dot {
	position: relative;
	width: 2.25rem;
	height: 3px;
	padding: 0;
	border: 0;
	border-radius: var(--r-pill);
	background: var(--rose-100);
	cursor: pointer;
	overflow: hidden;
}

.tw-hero__dot-fill {
	position: absolute;
	inset: 0;
	border-radius: inherit;
	background: var(--rose-500);
	transform: scaleX(0);
	transform-origin: 0 50%;
}

.tw-hero__dot.is-on .tw-hero__dot-fill {
	animation: tw-dot 6500ms linear forwards;
}

@keyframes tw-dot {
	from { transform: scaleX(0); }
	to   { transform: scaleX(1); }
}

@media (prefers-reduced-motion: reduce) {
	.tw-hero__dot.is-on .tw-hero__dot-fill { animation: none; transform: scaleX(1); }
}

/* --------------------------------------------------------------------------
   Promotional strip
   -------------------------------------------------------------------------- */

.tw-promo { padding-block: var(--sp-6); background: var(--white); }

.tw-promo__list {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--sp-4);
	margin: 0;
	padding: 0;
	list-style: none;
}

.tw-promo__item { margin: 0; }

.tw-promo__link {
	display: flex;
	align-items: center;
	gap: var(--sp-4);
	height: 100%;
	padding: var(--sp-4) var(--sp-5);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--blush-1);
	color: var(--ink);
	transition: transform var(--dur) var(--ease),
	            box-shadow var(--dur) var(--ease),
	            border-color var(--dur) var(--ease),
	            background var(--dur) var(--ease);
}

.tw-promo__link:hover {
	transform: translateY(-2px);
	background: var(--white);
	border-color: var(--rose-200);
	box-shadow: var(--shadow-md);
	color: var(--ink);
}

.tw-promo__icon {
	display: grid;
	place-items: center;
	width: 2.75rem;
	height: 2.75rem;
	flex: none;
	border-radius: var(--r-pill);
	background: var(--white);
	border: 1px solid var(--rose-100);
	color: var(--rose-500);
}
.tw-promo__link:hover .tw-promo__icon { background: var(--rose-50); }

.tw-promo__body { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.tw-promo__title { font-size: var(--fs-base); font-weight: 600; }
.tw-promo__text { color: var(--ink-3); font-size: var(--fs-xs); }

.tw-promo__cta {
	display: inline-flex;
	align-items: center;
	gap: .2rem;
	margin-left: auto;
	color: var(--rose-600);
	font-size: var(--fs-xs);
	font-weight: 600;
	white-space: nowrap;
}
.tw-promo__cta svg { transition: transform var(--dur) var(--ease); }
.tw-promo__link:hover .tw-promo__cta svg { transform: translateX(3px); }

/* --------------------------------------------------------------------------
   Side cart
   -------------------------------------------------------------------------- */

.tw-drawer { position: fixed; inset: 0; z-index: var(--z-drawer); }

.tw-drawer__scrim {
	position: absolute;
	inset: 0;
	border: 0;
	padding: 0;
	background: rgba(35, 25, 29, .4);
	opacity: 0;
	transition: opacity 320ms var(--ease);
	cursor: pointer;
}
.tw-drawer.is-on .tw-drawer__scrim { opacity: 1; }

.tw-drawer__panel {
	position: absolute;
	inset: 0 0 0 auto;
	display: flex;
	flex-direction: column;
	width: min(92vw, 26rem);
	background: var(--white);
	box-shadow: var(--shadow-lg);
	transform: translate3d(100%, 0, 0);
	transition: transform 420ms var(--ease-out);
	will-change: transform;
}
.tw-drawer.is-on .tw-drawer__panel { transform: none; }

.tw-drawer__top {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-3);
	padding: var(--sp-4) var(--sp-5);
	border-bottom: 1px solid var(--line);
}

.tw-drawer__title {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	margin: 0;
	font-family: var(--font-body);
	font-size: var(--fs-md);
	font-weight: 700;
}
.tw-drawer__title svg { color: var(--rose-500); }
.tw-drawer__n { color: var(--ink-4); font-weight: 500; }

.tw-drawer__body {
	flex: 1;
	display: flex;
	flex-direction: column;
	overflow-y: auto;
	overscroll-behavior: contain;
	transition: opacity var(--dur) var(--ease);
}
.tw-drawer__body.is-busy { opacity: .5; pointer-events: none; }

.tw-drawer__ship { padding: var(--sp-4) var(--sp-5); border-bottom: 1px solid var(--line); }

.tw-drawer__ship-msg {
	display: flex;
	align-items: center;
	gap: .35rem;
	margin: 0 0 var(--sp-2);
	font-size: var(--fs-sm);
	color: var(--ink-2);
}
.tw-drawer__ship-msg svg { color: var(--ok); flex: none; }

.tw-drawer__ship-bar {
	height: 4px;
	border-radius: var(--r-pill);
	background: var(--line);
	overflow: hidden;
}
.tw-drawer__ship-bar span {
	display: block;
	height: 100%;
	border-radius: inherit;
	background: linear-gradient(90deg, var(--rose-400), var(--rose-500));
	transition: width 520ms var(--ease);
}

.tw-drawer__items { margin: 0; padding: 0; list-style: none; flex: 1; }

.tw-dline {
	position: relative;
	display: grid;
	grid-template-columns: 68px 1fr;
	gap: var(--sp-3);
	margin: 0;
	padding: var(--sp-4) var(--sp-5);
	border-bottom: 1px solid var(--line);
}

.tw-dline__media img {
	width: 68px;
	height: 68px;
	object-fit: contain;
	border-radius: var(--r-sm);
	background: var(--blush-2);
	padding: 4px;
}

.tw-dline__body { min-width: 0; padding-right: var(--sp-4); }

.tw-dline__name {
	margin: 0 0 .2rem;
	font-size: var(--fs-sm);
	font-weight: 600;
	line-height: 1.35;
}
.tw-dline__name a { color: var(--ink); }
.tw-dline__name a:hover { color: var(--rose-600); }

.tw-dline__meta { margin: 0 0 .3rem; color: var(--ink-4); font-size: var(--fs-xs); }

.tw-dline__foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-2);
	margin-top: var(--sp-2);
}

.tw-dline__qty {
	display: inline-flex;
	align-items: center;
	border: 1px solid var(--line-2);
	border-radius: var(--r-pill);
	overflow: hidden;
}

.tw-dline__qty .tw-qty-btn { width: 1.9rem; height: 1.9rem; }
.tw-dline__n { min-width: 1.6rem; text-align: center; font-size: var(--fs-sm); font-weight: 600; }
.tw-dline__price { font-size: var(--fs-sm); font-weight: 700; color: var(--ink); }

.tw-dline__remove {
	position: absolute;
	top: var(--sp-3);
	right: var(--sp-4);
	display: grid;
	place-items: center;
	width: 1.6rem;
	height: 1.6rem;
	border: 0;
	border-radius: var(--r-pill);
	background: transparent;
	color: var(--ink-4);
	cursor: pointer;
	transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.tw-dline__remove:hover { background: var(--err-bg); color: var(--err); }

.tw-drawer__foot {
	padding: var(--sp-5);
	border-top: 1px solid var(--line);
	background: var(--blush-1);
}

.tw-drawer__discreet {
	display: flex;
	align-items: center;
	gap: .4rem;
	margin: 0 0 var(--sp-3);
	color: var(--ink-3);
	font-size: var(--fs-xs);
}
.tw-drawer__discreet svg { color: var(--rose-400); flex: none; }

.tw-drawer__sub {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	margin-bottom: .2rem;
	font-size: var(--fs-md);
}
.tw-drawer__sub strong { font-size: var(--fs-lg); color: var(--ink); }

.tw-drawer__note { margin: 0 0 var(--sp-4); color: var(--ink-4); font-size: var(--fs-xs); }
.tw-drawer__foot .tw-btn + .tw-btn { margin-top: var(--sp-2); }

.tw-drawer__empty {
	display: grid;
	justify-items: center;
	gap: var(--sp-4);
	padding: var(--sp-9) var(--sp-5);
	text-align: center;
	color: var(--ink-3);
}

.tw-drawer__empty-icon {
	display: grid;
	place-items: center;
	width: 4rem;
	height: 4rem;
	border-radius: var(--r-pill);
	background: var(--blush-2);
	color: var(--rose-300);
}

.tw-drawer__empty .tw-btn { max-width: 16rem; }

/* --------------------------------------------------------------------------
   Definition: rings and edges
   The brief asked for more enclosure, so the interactive elements now sit in
   a visible container rather than floating on the white.
   -------------------------------------------------------------------------- */

/* Navigation links get a pill that fills on hover. */
.tw-nav > li > a {
	padding: .45rem .8rem;
	border: 1px solid transparent;
	border-radius: var(--r-pill);
	transition: background var(--dur-fast) var(--ease),
	            border-color var(--dur-fast) var(--ease),
	            color var(--dur-fast) var(--ease);
}

.tw-nav > li > a::after { display: none; }

.tw-nav > li > a:hover,
.tw-nav > li.current-menu-item > a {
	background: var(--blush-2);
	border-color: var(--rose-100);
	color: var(--rose-700);
}

/* The whole tool cluster sits in one container. */
.tw-hd__tools {
	padding: .25rem;
	border: 1px solid var(--line);
	border-radius: var(--r-pill);
	background: var(--blush-1);
}

.tw-icon-btn:hover { background: var(--white); box-shadow: var(--shadow-sm); }

/* Primary buttons get a soft ring that lifts on hover. */
.tw-btn {
	box-shadow: 0 1px 2px rgba(35, 25, 29, .06),
	            0 0 0 1px rgba(214, 83, 124, .16);
}

.tw-btn:hover {
	box-shadow: var(--shadow-rose),
	            0 0 0 1px rgba(214, 83, 124, .3);
}

.tw-btn--ghost {
	box-shadow: 0 1px 2px rgba(35, 25, 29, .05),
	            0 0 0 1px rgba(35, 25, 29, .06);
}
.tw-btn--ghost:hover {
	box-shadow: var(--shadow),
	            0 0 0 1px var(--rose-200);
}

/* Product cards sit on a defined surface instead of bare white. */
.tw-card__media {
	border: 1px solid var(--line);
	transition: border-color var(--dur) var(--ease),
	            box-shadow var(--dur) var(--ease),
	            transform var(--dur) var(--ease);
}

.tw-card:hover .tw-card__media {
	border-color: var(--rose-200);
	box-shadow: var(--shadow-md);
	transform: translateY(-3px);
}

/* Section headings carry a rule that ties the block together. */
.tw-head {
	padding-bottom: var(--sp-4);
	border-bottom: 1px solid var(--line);
}

.tw-head--center { border-bottom: 0; padding-bottom: 0; }

.tw-head__eyebrow {
	display: inline-flex;
	align-items: center;
	padding: .3rem .7rem;
	border: 1px solid var(--rose-100);
	border-radius: var(--r-pill);
	background: var(--rose-50);
}

/* Trust items become cards. */
.tw-trust__item {
	padding: var(--sp-4);
	border: 1px solid var(--line);
	border-radius: var(--r-md);
	background: var(--white);
	transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.tw-trust__item:hover { border-color: var(--rose-200); box-shadow: var(--shadow-sm); }

/* FAQ rows get a container each. */
.tw-faq { border-top: 0; display: grid; gap: var(--sp-2); }

.tw-faq__item {
	border: 1px solid var(--line);
	border-radius: var(--r-md);
	background: var(--white);
	padding-inline: var(--sp-4);
	transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.tw-faq__item[open] { border-color: var(--rose-200); box-shadow: var(--shadow-sm); }

/* Sticky section headings on long catalogue pages. */
.tw-woo .woocommerce-products-header {
	position: sticky;
	top: calc(var(--header-h) + var(--sp-2));
	z-index: 5;
	padding-block: var(--sp-2);
	background: linear-gradient(180deg, var(--white) 72%, transparent);
}

/* ==========================================================================
   MEGA MENU, STICKY STORY, FIGURES, PRODUCT EXTRAS
   skill.md 05, 07, 11.E. Transform and opacity only.
   ========================================================================== */

.tw-nav .tw-has-mega { position: static; }
.tw-hd__nav { position: static; }

.tw-mega {
	position: absolute;
	top: 100%;
	left: 0;
	right: 0;
	z-index: var(--z-header);
	padding-block: var(--sp-6);
	background: var(--white);
	border-top: 1px solid var(--line);
	box-shadow: var(--shadow-lg);
	opacity: 0;
	visibility: hidden;
	/* The panel is as wide as the header, so while it is closed it would sit
	   over every other menu item and swallow their clicks. visibility alone
	   does not prevent that mid-transition. */
	pointer-events: none;
	transform: translateY(-8px);
	transition: opacity var(--dur) var(--ease),
	            transform var(--dur) var(--ease),
	            visibility var(--dur);
}

.tw-has-mega:hover > .tw-mega,
.tw-has-mega:focus-within > .tw-mega {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transform: none;
}

/* Each item needs its own stacking context above the closed panel, so a click
   always lands on the link and never on the sheet behind it. */
.tw-nav > li { position: relative; z-index: 1; }
.tw-nav .tw-has-mega { position: static; }
.tw-nav > li > a { position: relative; z-index: 2; }

.tw-mega__in {
	display: grid;
	grid-template-columns: 2fr 1fr 1fr;
	gap: var(--sp-7);
	align-items: start;
}

.tw-mega__cats {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--sp-3);
}

.tw-mega__cat {
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	padding: var(--sp-2);
	border: 1px solid transparent;
	border-radius: var(--r-md);
	color: var(--ink);
	transition: background var(--dur-fast) var(--ease),
	            border-color var(--dur-fast) var(--ease);
}

.tw-mega__cat:hover {
	background: var(--blush-1);
	border-color: var(--rose-100);
	color: var(--ink);
}

.tw-mega__cat-media {
	flex: none;
	width: 3.5rem;
	height: 3.5rem;
	border-radius: var(--r-sm);
	overflow: hidden;
	background: var(--blush-2);
}
.tw-mega__cat-media img { width: 100%; height: 100%; object-fit: contain; padding: 3px; }

.tw-mega__cat-name { display: block; font-size: var(--fs-sm); font-weight: 600; }
.tw-mega__cat-n { display: block; color: var(--ink-4); font-size: var(--fs-xs); }

.tw-mega__h {
	margin: 0 0 var(--sp-2);
	font-family: var(--font-body);
	font-size: var(--fs-xs);
	font-weight: 700;
	letter-spacing: var(--ls-caps);
	text-transform: uppercase;
	color: var(--ink-4);
}
.tw-mega__links ul + .tw-mega__h { margin-top: var(--sp-5); }

.tw-mega__links ul { margin: 0; padding: 0; list-style: none; }
.tw-mega__links li { margin-bottom: var(--sp-2); }
.tw-mega__links a { color: var(--ink-2); font-size: var(--fs-sm); }
.tw-mega__links a:hover { color: var(--rose-600); }

.tw-mega__feature {
	display: block;
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	overflow: hidden;
	background: var(--blush-1);
	color: var(--ink);
	transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.tw-mega__feature:hover { border-color: var(--rose-200); box-shadow: var(--shadow); color: var(--ink); }

.tw-mega__feature-media { display: block; aspect-ratio: 4 / 3; overflow: hidden; background: var(--blush-2); }
.tw-mega__feature-media img { width: 100%; height: 100%; object-fit: contain; padding: var(--sp-2); }

.tw-mega__feature-body { display: block; padding: var(--sp-3) var(--sp-4) var(--sp-4); background: var(--white); }

.tw-mega__feature-label {
	display: block;
	margin-bottom: .2rem;
	color: var(--rose-500);
	font-size: var(--fs-xs);
	font-weight: 600;
}
.tw-mega__feature-name { display: block; font-size: var(--fs-sm); font-weight: 600; line-height: 1.35; }
.tw-mega__feature-price { display: block; margin-top: .25rem; font-weight: 700; }

/* ---- Sticky storytelling ------------------------------------------------ */

.tw-story__in {
	display: grid;
	grid-template-columns: 1fr 1.15fr;
	gap: var(--sp-9);
	align-items: start;
}

.tw-story__stick {
	position: sticky;
	top: calc(var(--header-h) + var(--sp-8));
}

.tw-story__stick h2 { margin-bottom: var(--sp-4); }
.tw-story__stick p { color: var(--ink-2); margin-bottom: var(--sp-5); max-width: 42ch; }

.tw-story__steps {
	display: grid;
	gap: var(--sp-4);
	margin: 0;
	padding: 0;
	list-style: none;
}

.tw-step {
	position: relative;
	margin: 0;
	padding: var(--sp-6);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--white);
	transition: border-color var(--dur) var(--ease),
	            box-shadow var(--dur) var(--ease),
	            transform var(--dur) var(--ease);
}

.tw-step:hover {
	border-color: var(--rose-200);
	box-shadow: var(--shadow);
	transform: translateY(-2px);
}

.tw-step__icon {
	display: grid;
	place-items: center;
	width: 2.75rem;
	height: 2.75rem;
	margin-bottom: var(--sp-3);
	border-radius: var(--r-md);
	background: var(--blush-2);
	color: var(--rose-500);
}

.tw-step h3 {
	margin-bottom: .35rem;
	font-family: var(--font-body);
	font-size: var(--fs-md);
	font-weight: 600;
}
.tw-step p { margin: 0; color: var(--ink-3); font-size: var(--fs-sm); line-height: 1.55; }

/* ---- Figures ------------------------------------------------------------ */

.tw-figures { background: var(--blush-1); }

.tw-figures__in {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: var(--sp-5);
}

.tw-figure { text-align: center; }

.tw-figure__n {
	display: block;
	color: var(--rose-600);
	font-family: var(--font-display);
	font-size: clamp(2rem, 1.4rem + 2.4vw, 3rem);
	font-weight: 600;
	line-height: 1;
	font-variant-numeric: tabular-nums;
}

.tw-figure__label {
	display: block;
	margin-top: var(--sp-2);
	color: var(--ink-3);
	font-size: var(--fs-sm);
}

/* ---- Product extras ----------------------------------------------------- */

.tw-buynow { width: 100%; margin-top: var(--sp-2); }

.tw-eta {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	margin: var(--sp-4) 0 0;
	padding: var(--sp-3) var(--sp-4);
	border: 1px solid var(--rose-100);
	border-radius: var(--r-md);
	background: var(--blush-1);
	color: var(--ink-2);
	font-size: var(--fs-sm);
}
.tw-eta svg { flex: none; color: var(--rose-500); }
.tw-eta strong { color: var(--ink); white-space: nowrap; }

/* The 46rem cap is deliberate: it keeps the answers at a readable measure.
   The rule above them was inheriting it, so the border stopped two thirds of
   the way across and read as a broken layout at widths between about 1000px
   and 1280px. The section now spans the grid and the cap moves to the text
   inside it. */
.tw-pfaq {
	grid-column: 1 / -1;
	margin-top: var(--sp-8);
	padding-top: var(--sp-7);
	border-top: 1px solid var(--line);
}

.tw-pfaq > * { max-width: 46rem; }

.tw-pfaq__title { margin-bottom: var(--sp-5); font-size: var(--fs-2xl); }

/* --------------------------------------------------------------------------
   HERO SIZING
   skill.md 04 and taste 4.7: the first viewport must carry the headline, the
   subtext and the CTA. A seven-word headline at the largest display size ran
   to four lines and pushed the buttons below the fold, so the scale is planned
   against the copy length rather than set to the maximum.
   -------------------------------------------------------------------------- */

.tw-hero__title {
	/* Two lines at 1440px for a 7 word headline. */
	font-size: clamp(2rem, 1.1rem + 2.6vw, 3.25rem);
	line-height: 1.08;
	max-width: 18ch;
	margin-bottom: var(--sp-4);
}

.tw-hero__sub {
	max-width: 40ch;
	font-size: var(--fs-md);
	margin-bottom: var(--sp-5);
}

.tw-hero__in {
	padding-block: var(--sp-7) var(--sp-7);
}

.tw-hero__stage { min-height: 0; }

/* The art column fills its own half instead of floating between the two. */
.tw-slide {
	grid-template-columns: minmax(0, 1fr) minmax(0, .92fr);
	gap: var(--sp-7);
	align-items: center;
}

.tw-slide__art {
	width: 100%;
	max-width: 30rem;
	margin-left: auto;
	aspect-ratio: 4 / 5;
}

/* The three reassurance points sit under the copy, not adrift in the gap. */
.tw-hero__points {
	margin-top: var(--sp-5);
	padding-top: var(--sp-4);
	border-top: 1px solid var(--line);
}

/* --------------------------------------------------------------------------
   SECTION SEPARATION
   The brief asks for clearer zoning. Alternating tint alone was too subtle at
   this page length, so each section also carries a hairline, and the tinted
   ones get a soft edge where they meet white.
   -------------------------------------------------------------------------- */

.tw-sec + .tw-sec { border-top: 1px solid var(--line); }

.tw-sec--blush,
.tw-sec--blush-2 { border-top-color: var(--line-2); }

/* A section that follows a tinted one does not need a second rule. */
.tw-sec--blush + .tw-sec--blush,
.tw-sec--blush-2 + .tw-sec--blush-2 { border-top: 0; }

.tw-promo { border-top: 1px solid var(--line); }
.tw-figures { border-block: 1px solid var(--line-2); }

/* --------------------------------------------------------------------------
   HEADER SHRINK
   The header gives back a little height once the page has moved, so the
   catalogue gets the screen. Only the custom property animates, and the two
   things that read from it follow.
   -------------------------------------------------------------------------- */

.tw-hd {
	transition: border-color var(--dur) var(--ease),
	            box-shadow var(--dur) var(--ease),
	            transform var(--dur) var(--ease),
	            background var(--dur) var(--ease);
}

.tw-hd__in {
	min-height: var(--header-h);
	transition: min-height var(--dur) var(--ease);
}

.tw-hd.is-stuck .tw-hd__in { min-height: 3.6rem; }

.tw-logo__img {
	transition: height var(--dur) var(--ease);
}
.tw-hd.is-stuck .tw-logo__img { height: 1.9rem; }

.tw-hd.is-stuck { background: rgba(255, 255, 255, .96); }

@media (prefers-reduced-motion: reduce) {
	.tw-hd__in, .tw-logo__img { transition: none; }
}

/* --------------------------------------------------------------------------
   STICKY BUY BAR, MOBILE
   skill brief 8: the add to cart must stay reachable on a phone. It appears
   once the real button has scrolled away, so it never doubles up.
   -------------------------------------------------------------------------- */

.tw-buybar {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: var(--z-header);
	display: none;
	align-items: center;
	gap: var(--sp-3);
	padding: var(--sp-3) var(--gutter);
	padding-bottom: max(var(--sp-3), env(safe-area-inset-bottom));
	background: rgba(255, 255, 255, .97);
	backdrop-filter: blur(12px);
	-webkit-backdrop-filter: blur(12px);
	border-top: 1px solid var(--line);
	box-shadow: 0 -4px 20px rgba(35, 25, 29, .08);
	transform: translateY(100%);
	transition: transform var(--dur) var(--ease-out);
}

.tw-buybar.is-on { transform: none; }

.tw-buybar__info { flex: 1; min-width: 0; }

.tw-buybar__name {
	display: block;
	font-size: var(--fs-xs);
	color: var(--ink-3);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.tw-buybar__price { display: block; font-size: var(--fs-md); font-weight: 700; color: var(--ink); }

.tw-buybar .tw-btn { flex: none; min-width: 9rem; }

@media (max-width: 900px) {
	body.single-product .tw-buybar { display: flex; }
	/* Room for the bar so it never covers the last of the page. */
	body.single-product { padding-bottom: 4.5rem; }
}

@media (prefers-reduced-motion: reduce) {
	.tw-buybar { transition: none; }
}

/* --------------------------------------------------------------------------
   QUICK VIEW
   -------------------------------------------------------------------------- */

.tw-qv {
	position: fixed;
	inset: 0;
	z-index: var(--z-modal);
	display: grid;
	place-items: center;
	padding: var(--gutter);
}

/* A `display` rule beats the [hidden] attribute, so a hidden overlay was still
   laid out: invisible, but its scrim covered the viewport and swallowed every
   click. Any panel that hides with [hidden] must say so in CSS too. */
.tw-qv[hidden],
.tw-drawer[hidden],
.tw-mob[hidden],
.tw-search[hidden],
.tw-filters[hidden] {
	display: none !important;
}

.tw-qv__scrim {
	position: absolute;
	inset: 0;
	border: 0;
	padding: 0;
	background: rgba(35, 25, 29, .42);
	opacity: 0;
	transition: opacity var(--dur) var(--ease);
	cursor: pointer;
}
.tw-qv.is-on .tw-qv__scrim { opacity: 1; }

.tw-qv__panel {
	position: relative;
	z-index: 1;
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--sp-6);
	width: min(58rem, 100%);
	max-height: 86dvh;
	overflow-y: auto;
	padding: var(--sp-6);
	border-radius: var(--r-lg);
	background: var(--white);
	box-shadow: var(--shadow-lg);
	opacity: 0;
	transform: translateY(12px) scale(.985);
	transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}
.tw-qv.is-on .tw-qv__panel { opacity: 1; transform: none; }

.tw-qv__close {
	position: absolute;
	top: var(--sp-3);
	right: var(--sp-3);
	z-index: 2;
}

.tw-qv__media {
	aspect-ratio: 1 / 1;
	border-radius: var(--r-md);
	overflow: hidden;
	background: var(--blush-2);
}
.tw-qv__media img { width: 100%; height: 100%; object-fit: contain; padding: var(--sp-3); }

.tw-qv__title { margin-bottom: var(--sp-2); font-size: var(--fs-2xl); }
.tw-qv__price { margin-bottom: var(--sp-4); font-size: var(--fs-xl); font-weight: 700; color: var(--ink); }
.tw-qv__desc { margin-bottom: var(--sp-5); color: var(--ink-3); font-size: var(--fs-sm); }
.tw-qv__actions { display: grid; gap: var(--sp-2); }

.tw-card__qv {
	position: absolute;
	left: var(--sp-3);
	bottom: var(--sp-3);
	z-index: 2;
	display: inline-flex;
	align-items: center;
	gap: .35rem;
	height: 2.25rem;
	padding: 0 .75rem;
	border: 0;
	border-radius: var(--r-pill);
	background: rgba(255, 255, 255, .94);
	color: var(--ink-2);
	font-size: var(--fs-xs);
	font-weight: 600;
	cursor: pointer;
	box-shadow: var(--shadow-sm);
	opacity: 0;
	transform: translateY(6px);
	transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease),
	            background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.tw-card:hover .tw-card__qv,
.tw-card__qv:focus-visible { opacity: 1; transform: none; }
.tw-card__qv:hover { background: var(--ink); color: #fff; }

@media (max-width: 680px) {
	.tw-qv__panel { grid-template-columns: 1fr; padding: var(--sp-5); }
	.tw-qv__media { max-width: 16rem; margin-inline: auto; }
	/* Touch has no hover, and the card already carries two controls. */
	.tw-card__qv { display: none; }
}

@media (prefers-reduced-motion: reduce) {
	.tw-qv__scrim, .tw-qv__panel { transition: none; }
}

/* --------------------------------------------------------------------------
   SHIPPING ORIGIN NOTE
   Shown on the product page, in quick view and at checkout. A US buyer needs
   to know the parcel leaves Hong Kong before they pay, not after.
   -------------------------------------------------------------------------- */

.tw-shipnote {
	display: flex;
	align-items: flex-start;
	gap: var(--sp-2);
	margin: var(--sp-3) 0 0;
	padding: var(--sp-3);
	border: 1px solid var(--line);
	border-radius: var(--r-sm);
	background: var(--blush-1);
	color: var(--ink-3);
	font-size: var(--fs-xs);
	line-height: 1.5;
}
.tw-shipnote svg { flex: none; color: var(--rose-400); margin-top: .1rem; }

/* --------------------------------------------------------------------------
   MERGED ASSURANCE PANEL
   One container with internal dividers, replacing four stacked boxes whose
   margins compounded into a gap that read as a fault.
   -------------------------------------------------------------------------- */

.tw-assure {
	margin: var(--sp-4) 0 0;
	padding: 0;
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--blush-1);
	overflow: hidden;
}

.tw-assure__list { margin: 0; padding: 0; list-style: none; }

.tw-assure__list li {
	display: flex;
	align-items: flex-start;
	gap: var(--sp-3);
	margin: 0;
	padding: var(--sp-4);
	border-bottom: 1px solid var(--line);
	color: var(--ink-3);
	font-size: var(--fs-sm);
	line-height: 1.5;
}
.tw-assure__list li:last-child { border-bottom: 0; }
.tw-assure__list svg { flex: none; color: var(--rose-500); margin-top: .1rem; }
.tw-assure__list strong { display: block; color: var(--ink); }
.tw-assure__list em { font-style: normal; color: var(--ok); font-weight: 600; }

.tw-assure__pay {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--sp-2) var(--sp-3);
	padding: var(--sp-3) var(--sp-4);
	border-top: 1px solid var(--line);
	background: var(--white);
}

.tw-assure__pay-label {
	display: inline-flex;
	align-items: center;
	gap: .3rem;
	color: var(--ok);
	font-size: var(--fs-xs);
	font-weight: 600;
}

/* --------------------------------------------------------------------------
   PAYMENT BRAND MARKS
   -------------------------------------------------------------------------- */

.tw-marks {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--sp-2);
	margin: 0;
	padding: 0;
	list-style: none;
}

.tw-marks li { margin: 0; line-height: 0; }

.tw-marks svg {
	display: block;
	height: 24px;
	width: auto;
	border-radius: 3px;
}

/* The delivery estimate sits above the panel and keeps its own frame, because
   it is the one line that changes per visit. */
.tw-eta { margin-top: var(--sp-4); }

@media (max-width: 680px) {
	.tw-assure__list li { padding: var(--sp-3); }
	.tw-assure__pay { padding: var(--sp-3); }
	.tw-marks svg { height: 21px; }
}

/* --------------------------------------------------------------------------
   FOOTER ADDRESSES
   Two places, labelled distinctly. A buyer reading the footer should be able
   to tell at a glance which one the parcel leaves from.
   -------------------------------------------------------------------------- */

.tw-ft__addr {
	display: grid;
	gap: var(--sp-4);
	margin-top: var(--sp-4);
	padding-top: var(--sp-4);
	border-top: 1px solid var(--line);
}

.tw-ft__place {
	margin: 0;
	color: var(--ink-3);
	font-size: var(--fs-xs);
	font-style: normal;
	line-height: 1.6;
}

.tw-ft__place-label {
	display: block;
	margin-bottom: .2rem;
	color: var(--ink);
	font-size: var(--fs-xs);
	font-weight: 700;
	letter-spacing: var(--ls-wide);
	text-transform: uppercase;
}

.tw-ft__place-note {
	display: block;
	margin-top: .15rem;
	color: var(--rose-600);
	font-size: var(--fs-xs);
	font-weight: 600;
}

@media (max-width: 680px) {
	.tw-ft__addr { grid-template-columns: repeat(2, 1fr); gap: var(--sp-3); }
}

@media (max-width: 420px) {
	.tw-ft__addr { grid-template-columns: 1fr; }
}

/* ==========================================================================
   PRODUCT PAGE PROPORTIONS
   Measured on the live page: the gallery ran to 1703px against an 884px
   summary, leaving 914px of empty column before the tabs. The image is capped
   so the two columns finish within sight of each other.
   ========================================================================== */

.woocommerce div.product .woocommerce-product-gallery__image img,
.woocommerce div.product div.images img {
	max-height: 34rem;
	object-fit: contain;
	background: var(--blush-2);
}

.woocommerce div.product .flex-viewport {
	max-height: 34rem;
}

/* The thumbnail strip sits under the image, not 200px into it. */
.woocommerce div.product .flex-control-thumbs {
	grid-template-columns: repeat(6, 1fr);
	margin-top: var(--sp-3);
}

.woocommerce div.product .flex-control-thumbs img {
	aspect-ratio: 1 / 1;
	object-fit: contain;
	padding: 2px;
	background: var(--blush-2);
}

/* Tabs follow the taller of the two columns without a gulf in between. */
.woocommerce div.product .woocommerce-tabs {
	margin-top: var(--sp-7);
	padding-top: var(--sp-6);
	border-top: 1px solid var(--line);
}

.woocommerce .related,
.woocommerce .upsells {
	margin-top: var(--sp-8);
	padding-top: var(--sp-7);
}

/* ==========================================================================
   PAGINATION
   Twenty-one numbered circles is a wall of near-identical targets. The list is
   condensed and the current page is the only filled one.
   ========================================================================== */

.woocommerce nav.woocommerce-pagination {
	margin-top: var(--sp-7);
	padding-top: var(--sp-6);
	border-top: 1px solid var(--line);
}

.woocommerce nav.woocommerce-pagination ul {
	gap: var(--sp-1);
	flex-wrap: wrap;
	justify-content: center;
}

.woocommerce nav.woocommerce-pagination ul li a,
.woocommerce nav.woocommerce-pagination ul li span {
	min-width: 2.375rem;
	height: 2.375rem;
	font-variant-numeric: tabular-nums;
}

/* The ellipsis is not a destination, so it does not look like one. */
.woocommerce nav.woocommerce-pagination ul li span.dots {
	border-color: transparent;
	background: transparent;
	color: var(--ink-4);
	min-width: 1.5rem;
}

/* Prev and next read as direction, not as another number. */
.woocommerce nav.woocommerce-pagination ul li a.prev,
.woocommerce nav.woocommerce-pagination ul li a.next {
	padding-inline: 1rem;
	font-weight: 600;
}

/* ==========================================================================
   FOOTER PAYMENT MARKS
   The row was a label and five logos with nothing separating them from the
   rest of the strip. It now reads as one deliberate group.
   ========================================================================== */

.tw-ft__trust-in {
	gap: var(--sp-5);
}

.tw-ft__pay {
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	padding: var(--sp-3) var(--sp-4);
	border: 1px solid var(--line);
	border-radius: var(--r-md);
	background: var(--white);
}

.tw-ft__pay-label {
	color: var(--ink-3);
	font-size: var(--fs-xs);
	font-weight: 600;
	letter-spacing: var(--ls-wide);
	text-transform: uppercase;
	white-space: nowrap;
}

.tw-ft__pay .tw-marks svg {
	height: 26px;
	border: 1px solid var(--line);
}

@media (max-width: 680px) {
	.tw-ft__pay { flex-direction: column; align-items: flex-start; }
	.tw-ft__pay .tw-marks svg { height: 22px; }

	.woocommerce div.product .woocommerce-product-gallery__image img,
	.woocommerce div.product .flex-viewport { max-height: 24rem; }

	.woocommerce div.product .flex-control-thumbs { grid-template-columns: repeat(5, 1fr); }
}

/* ==========================================================================
   POLICY PAGES
   The content was right but read as one long column. Each section now sits in
   its own zone with an icon, and the facts people scan for are lifted into a
   strip at the top.
   ========================================================================== */

.tw-policy .tw-page-hero {
	padding-block: var(--sp-8) var(--sp-6);
	background: linear-gradient(180deg, var(--blush-1), var(--white));
	border-bottom: 1px solid var(--line);
}

.tw-policy .tw-page-hero__title { margin: 0; }

/* ---- Summary strip ---------------------------------------------------- */

.tw-pol__cards {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: var(--sp-3);
	margin: 0 0 var(--sp-7);
	padding: 0;
	list-style: none;
}

.tw-pol__card {
	display: grid;
	gap: .2rem;
	margin: 0;
	padding: var(--sp-4);
	border: 1px solid var(--line);
	border-radius: var(--r-md);
	background: var(--blush-1);
	text-align: center;
}

.tw-pol__card-icon {
	display: grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	margin: 0 auto var(--sp-1);
	border-radius: var(--r-pill);
	background: var(--white);
	border: 1px solid var(--rose-100);
	color: var(--rose-500);
}

.tw-pol__card-k {
	color: var(--ink-4);
	font-size: var(--fs-xs);
	letter-spacing: var(--ls-wide);
	text-transform: uppercase;
}

.tw-pol__card-v {
	color: var(--ink);
	font-size: var(--fs-base);
	font-weight: 700;
	line-height: 1.3;
}

/* ---- Sections --------------------------------------------------------- */

.tw-pol__body h2 {
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	margin-top: var(--sp-7);
	margin-bottom: var(--sp-4);
	padding-top: var(--sp-6);
	border-top: 1px solid var(--line);
	font-size: var(--fs-xl);
}

.tw-pol__body h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }

.tw-pol__h-icon {
	display: grid;
	place-items: center;
	width: 2rem;
	height: 2rem;
	flex: none;
	border-radius: var(--r-sm);
	background: var(--blush-2);
	color: var(--rose-500);
}

.tw-pol__body h3 {
	margin-top: var(--sp-5);
	margin-bottom: var(--sp-2);
	font-family: var(--font-body);
	font-size: var(--fs-md);
	font-weight: 700;
}

.tw-pol__body p { color: var(--ink-2); line-height: 1.7; }

.tw-pol__body ul,
.tw-pol__body ol {
	margin: 0 0 var(--sp-4);
	padding-left: 0;
	list-style: none;
}

/* A list in a policy is a set of conditions, so each one gets its own row
   rather than a bullet in a wall of text. */
.tw-pol__body ul > li {
	position: relative;
	margin-bottom: var(--sp-2);
	padding: var(--sp-3) var(--sp-4) var(--sp-3) 2.5rem;
	border: 1px solid var(--line);
	border-radius: var(--r-sm);
	background: var(--white);
	color: var(--ink-2);
	font-size: var(--fs-sm);
	line-height: 1.6;
}

.tw-pol__body ul > li::before {
	content: "";
	position: absolute;
	left: 1rem;
	top: 1.15rem;
	width: .45rem;
	height: .45rem;
	border-radius: 50%;
	background: var(--rose-400);
}

.tw-pol__body ol { counter-reset: tw-pol; }

.tw-pol__body ol > li {
	counter-increment: tw-pol;
	position: relative;
	margin-bottom: var(--sp-2);
	padding: var(--sp-3) var(--sp-4) var(--sp-3) 3rem;
	border: 1px solid var(--line);
	border-radius: var(--r-sm);
	background: var(--white);
	color: var(--ink-2);
	font-size: var(--fs-sm);
	line-height: 1.6;
}

.tw-pol__body ol > li::before {
	content: counter(tw-pol);
	position: absolute;
	left: .9rem;
	top: .85rem;
	display: grid;
	place-items: center;
	width: 1.5rem;
	height: 1.5rem;
	border-radius: 50%;
	background: var(--rose-500);
	color: #fff;
	font-size: var(--fs-xs);
	font-weight: 700;
}

.tw-pol__body strong { color: var(--ink); }

.tw-pol__body a { text-decoration: underline; text-underline-offset: 2px; }

@media (max-width: 900px) {
	.tw-pol__cards { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 480px) {
	.tw-pol__cards { grid-template-columns: 1fr; }
	.tw-pol__card { display: flex; align-items: center; gap: var(--sp-3); text-align: left; }
	.tw-pol__card-icon { margin: 0; }
	.tw-pol__body h2 { font-size: var(--fs-lg); }
}

/* ==========================================================================
   CHAT
   A launcher bottom right that opens a small panel. Deliberately quiet: it
   sits above the page, never over the buy button, and it hides entirely when
   a drawer or modal already has the screen.
   ========================================================================== */

.tw-chat {
	position: fixed;
	right: var(--sp-5);
	bottom: var(--sp-5);
	z-index: calc(var(--z-drawer) - 5);
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: var(--sp-3);
}

body.tw-locked .tw-chat { display: none; }

.tw-chat__launch {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-2);
	height: 3rem;
	padding: 0 1.15rem;
	border: 0;
	border-radius: var(--r-pill);
	background: var(--rose-500);
	color: #fff;
	font-size: var(--fs-sm);
	font-weight: 600;
	cursor: pointer;
	box-shadow: var(--shadow-rose);
	transition: background var(--dur-fast) var(--ease),
	            transform var(--dur-fast) var(--ease);
}

.tw-chat__launch:hover { background: var(--rose-600); transform: translateY(-2px); }
.tw-chat__launch svg { flex: none; }

.tw-chat__panel {
	width: min(22rem, calc(100vw - 2 * var(--sp-5)));
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--white);
	box-shadow: var(--shadow-lg);
	overflow: hidden;
	opacity: 0;
	transform: translateY(10px) scale(.98);
	transform-origin: bottom right;
	transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}

.tw-chat.is-on .tw-chat__panel { opacity: 1; transform: none; }

.tw-chat__top {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-3);
	padding: var(--sp-4);
	border-bottom: 1px solid var(--line);
	background: var(--blush-1);
}

.tw-chat__who { display: flex; align-items: center; gap: var(--sp-3); font-size: var(--fs-sm); }

.tw-chat__avatar {
	display: grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	flex: none;
	border-radius: var(--r-pill);
	background: var(--rose-500);
	color: #fff;
}

.tw-chat__who strong { display: block; color: var(--ink); }
.tw-chat__hours { display: block; color: var(--ink-4); font-size: var(--fs-xs); }

.tw-chat__body {
	max-height: 18rem;
	overflow-y: auto;
	padding: var(--sp-4);
	display: grid;
	gap: var(--sp-3);
}

.tw-chat__msg {
	margin: 0;
	padding: var(--sp-3);
	border-radius: var(--r-md);
	font-size: var(--fs-sm);
	line-height: 1.55;
}

.tw-chat__msg--them { background: var(--blush-2); color: var(--ink-2); }

.tw-chat__msg--me {
	background: var(--rose-500);
	color: #fff;
	justify-self: end;
	max-width: 85%;
}

.tw-chat__note { margin: 0; color: var(--ink-4); font-size: var(--fs-xs); line-height: 1.5; }

.tw-chat__form { padding: var(--sp-3) var(--sp-4) var(--sp-4); border-top: 1px solid var(--line); }
.tw-chat__form input[type="email"] { margin-bottom: var(--sp-2); font-size: var(--fs-sm); }

.tw-chat__row { display: grid; grid-template-columns: 1fr auto; gap: var(--sp-2); align-items: end; }
.tw-chat__row textarea { min-height: 2.75rem; resize: none; font-size: var(--fs-sm); padding: .6rem .75rem; }

.tw-chat__send { width: 2.75rem; height: 2.75rem; padding: 0; }
.tw-chat__send svg { transform: rotate(-90deg); }

@media (max-width: 680px) {
	.tw-chat { right: var(--sp-4); bottom: var(--sp-4); }
	.tw-chat__launch-text { display: none; }
	.tw-chat__launch { width: 3rem; padding: 0; justify-content: center; }
	body.single-product .tw-chat { bottom: 5rem; }
}

@media (prefers-reduced-motion: reduce) {
	.tw-chat__panel, .tw-chat__launch { transition: none; }
}

/* ==========================================================================
   HERO, RICHER
   More colour without losing the white canvas: depth comes from layered
   washes and a soft ring behind the product, not from filling the page.
   ========================================================================== */

.tw-hero__bg {
	background:
		radial-gradient(44rem 30rem at 82% 6%, var(--rose-100), transparent 58%),
		radial-gradient(34rem 26rem at 4% 88%, var(--blush-3), transparent 60%),
		radial-gradient(28rem 22rem at 52% 50%, var(--rose-50), transparent 66%),
		linear-gradient(170deg, var(--white) 0%, var(--blush-1) 62%, var(--blush-2) 100%);
}

/* A slow drift, so the wash is alive without asking for attention. */
@media (prefers-reduced-motion: no-preference) {
	.tw-hero__bg { animation: tw-wash 22s ease-in-out infinite alternate; }
}

@keyframes tw-wash {
	from { transform: translate3d(0, 0, 0) scale(1); }
	to   { transform: translate3d(-1.5%, 1%, 0) scale(1.05); }
}

/* A ring behind the product, which reads as depth rather than decoration. */
.tw-slide__art {
	position: relative;
	isolation: isolate;
	box-shadow: var(--shadow-lg), 0 0 0 1px var(--rose-100);
}

.tw-slide__art::before {
	content: "";
	position: absolute;
	inset: -8%;
	z-index: -1;
	border-radius: 50%;
	background: radial-gradient(circle, var(--rose-200), transparent 62%);
	opacity: .5;
	filter: blur(24px);
}

.tw-hero__eyebrow {
	background: linear-gradient(120deg, var(--white), var(--rose-50));
	box-shadow: 0 1px 2px rgba(214, 83, 124, .12);
}

/* ==========================================================================
   CHECKOUT
   Two columns that stay two columns: form on the left, order on the right,
   the right column pinned so the total is always in view.
   ========================================================================== */

.woocommerce-checkout .tw-woo { padding-block: var(--sp-6) var(--sp-9); }

.woocommerce-checkout form.checkout {
	grid-template-columns: minmax(0, 1.25fr) minmax(19rem, .75fr);
	gap: var(--sp-7);
	align-items: start;
}

.woocommerce-checkout #customer_details .col-1,
.woocommerce-checkout #customer_details .col-2 { margin: 0; }

.woocommerce-checkout h3 {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	margin: 0 0 var(--sp-4);
	padding-bottom: var(--sp-3);
	border-bottom: 1px solid var(--line);
	font-family: var(--font-body);
	font-size: var(--fs-md);
	font-weight: 700;
	letter-spacing: var(--ls-wide);
	text-transform: uppercase;
}

.woocommerce-checkout #customer_details {
	padding: var(--sp-6);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--white);
}

/* Two fields per row where they belong together, one where they do not. */
.woocommerce form .form-row-first,
.woocommerce form .form-row-last {
	width: calc(50% - var(--sp-2));
	float: none;
	display: inline-block;
	vertical-align: top;
}
.woocommerce form .form-row-first { margin-right: var(--sp-3); }
.woocommerce form .form-row-wide { width: 100%; }

.woocommerce-checkout .woocommerce-checkout-review-order {
	position: sticky;
	top: calc(var(--header-h) + var(--sp-4));
	padding: var(--sp-5);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--blush-1);
}

.woocommerce-checkout #order_review table.shop_table {
	border: 0;
	background: transparent;
	margin-bottom: var(--sp-4);
}

.woocommerce-checkout #order_review table.shop_table th {
	padding: 0 0 var(--sp-3);
	background: transparent;
	border-bottom: 1px solid var(--line);
}

.woocommerce-checkout #order_review table.shop_table td {
	padding: var(--sp-3) 0;
	border-top: 0;
	border-bottom: 1px solid var(--line);
	font-size: var(--fs-sm);
}

.woocommerce-checkout #order_review tfoot th,
.woocommerce-checkout #order_review tfoot td {
	padding: var(--sp-2) 0;
	font-size: var(--fs-sm);
}

.woocommerce-checkout #order_review tfoot .order-total th,
.woocommerce-checkout #order_review tfoot .order-total td {
	padding-top: var(--sp-3);
	border-top: 1px solid var(--line-2);
	border-bottom: 0;
	font-size: var(--fs-lg);
	font-weight: 700;
	color: var(--ink);
}

.woocommerce-checkout #payment ul.payment_methods {
	padding: 0;
	background: transparent;
	border: 0;
}

.woocommerce-checkout #payment ul.payment_methods li {
	padding: var(--sp-3) var(--sp-4);
	border-radius: var(--r-md);
	background: var(--white);
}

.woocommerce-checkout #payment #place_order {
	height: 3.25rem;
	font-size: var(--fs-md);
}

@media (max-width: 900px) {
	.woocommerce-checkout form.checkout { grid-template-columns: 1fr; }
	.woocommerce-checkout .woocommerce-checkout-review-order { position: static; }
	.woocommerce-checkout #customer_details { padding: var(--sp-4); }
	.woocommerce form .form-row-first,
	.woocommerce form .form-row-last { width: 100%; margin-right: 0; display: block; }
}

/* Search results: categories above products, so a broad word offers a whole
   section rather than six near-identical items. */
.tw-search__label {
	margin: var(--sp-3) 0 var(--sp-2);
	color: var(--ink-4);
	font-size: var(--fs-xs);
	font-weight: 700;
	letter-spacing: var(--ls-caps);
	text-transform: uppercase;
}
.tw-search__label:first-child { margin-top: 0; }

.tw-search__cats { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: 0 0 var(--sp-2); padding: 0; list-style: none; }

.tw-search__cats a {
	display: inline-flex;
	align-items: center;
	gap: .4rem;
	padding: .4rem .8rem;
	border: 1px solid var(--line-2);
	border-radius: var(--r-pill);
	color: var(--ink-2);
	font-size: var(--fs-sm);
}
.tw-search__cats a:hover { background: var(--blush-2); border-color: var(--rose-200); color: var(--rose-700); }
.tw-search__cats span { color: var(--ink-4); font-size: var(--fs-xs); }

.tw-search__hint a { text-decoration: underline; }

/* The review column was landing on a second grid row because WooCommerce
   emits #customer_details and #order_review as siblings without explicit
   placement. Pinning each to its own column keeps them side by side. */
.woocommerce-checkout form.checkout > #customer_details {
	grid-column: 1;
	grid-row: 1;
}

.woocommerce-checkout form.checkout > h3#order_review_heading,
.woocommerce-checkout form.checkout > #order_review {
	grid-column: 2;
}

.woocommerce-checkout form.checkout > h3#order_review_heading { grid-row: 1; align-self: start; margin-bottom: 0; }
.woocommerce-checkout form.checkout > #order_review { grid-row: 2; }

/* When the heading is present the review block starts on row 2, so the form
   column has to span both rows to stay level with it. */
.woocommerce-checkout form.checkout > #customer_details { grid-row: 1 / span 2; }

@media (max-width: 900px) {
	.woocommerce-checkout form.checkout > #customer_details,
	.woocommerce-checkout form.checkout > h3#order_review_heading,
	.woocommerce-checkout form.checkout > #order_review {
		grid-column: 1;
		grid-row: auto;
	}
}

/* The page title had the full section rhythm above the form, and the order
   heading sat in its own grid row away from the table it labels. Both are
   pulled in so the form starts where the eye expects it. */

.woocommerce-checkout .tw-page-hero { padding-block: var(--sp-6) var(--sp-4); }
.woocommerce-checkout .tw-woo { padding-block: var(--sp-5) var(--sp-8); }

.woocommerce-checkout .woocommerce-form-coupon-toggle { margin-bottom: var(--sp-4); }

/* Heading and table become one block in the right column. */
.woocommerce-checkout form.checkout > h3#order_review_heading {
	grid-row: 1;
	margin: 0;
	padding: var(--sp-5) var(--sp-5) var(--sp-3);
	border: 1px solid var(--line);
	border-bottom: 0;
	border-radius: var(--r-lg) var(--r-lg) 0 0;
	background: var(--blush-1);
}

.woocommerce-checkout form.checkout > #order_review {
	grid-row: 2;
	margin-top: 0;
	padding-top: var(--sp-2);
	border-radius: 0 0 var(--r-lg) var(--r-lg);
	border-top: 0;
}

/* The two rows of the right column must not stretch apart. */
.woocommerce-checkout form.checkout {
	grid-template-rows: auto 1fr;
	align-items: start;
}

.woocommerce-checkout form.checkout > #customer_details { grid-row: 1 / span 2; }

@media (max-width: 900px) {
	.woocommerce-checkout form.checkout { grid-template-rows: auto; }
	.woocommerce-checkout form.checkout > h3#order_review_heading {
		border-radius: var(--r-lg) var(--r-lg) 0 0;
		margin-top: var(--sp-5);
	}
}

/* Measured on the live page: checkout renders through page.php, not the
   WooCommerce wrapper, so the earlier .tw-woo rules never applied. These
   target what is actually there. */

.woocommerce-checkout .tw-sec { padding-block: var(--sp-5) var(--sp-8); }
.woocommerce-checkout .tw-page-hero { padding-block: var(--sp-6) var(--sp-4); }

/* The heading and its table were 40px apart in the same column. */
.woocommerce-checkout form.checkout > h3#order_review_heading {
	padding-bottom: var(--sp-4);
	margin-bottom: 0;
}

.woocommerce-checkout form.checkout > #order_review {
	margin-top: -1px;
	padding-top: 0;
}

/* The order table sits flush inside the panel it belongs to. */
.woocommerce-checkout #order_review table.shop_table { margin-bottom: var(--sp-3); }
.woocommerce-checkout #order_review table.shop_table thead th { padding-top: var(--sp-2); }

/* #order_review wraps the table in its own div, so the gap lives on the
   child, not on the block the previous rule reached. */
.woocommerce-checkout #order_review > * { margin-top: 0; }
.woocommerce-checkout #order_review table.shop_table:first-child { margin-top: 0; }
.woocommerce-checkout #order_review table.shop_table thead th { padding-top: 0; }

/* ==========================================================================
   PRODUCT TABS
   The list markers were showing because the <li> kept display: list-item and
   an inherited disc. Measured on the live page, not guessed.
   ========================================================================== */

.woocommerce div.product .woocommerce-tabs ul.tabs,
.woocommerce div.product .woocommerce-tabs ul.wc-tabs {
	list-style: none;
}

.woocommerce div.product .woocommerce-tabs ul.tabs > li,
.woocommerce div.product .woocommerce-tabs ul.wc-tabs > li {
	display: block;
	list-style: none;
}

.woocommerce div.product .woocommerce-tabs ul.tabs > li::marker,
.woocommerce div.product .woocommerce-tabs ul.wc-tabs > li::marker {
	content: "";
}

/* ==========================================================================
   CART
   The form column was 280px wide while the table inside it measured 491px, so
   every row overflowed its own container. The columns are sized from the
   content instead of from a guess.
   ========================================================================== */

.woocommerce-cart .woocommerce {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(17rem, 22rem);
	gap: var(--sp-6);
	align-items: start;
}

.woocommerce-cart form.woocommerce-cart-form {
	grid-column: 1;
	min-width: 0;
}

.woocommerce-cart .cart-collaterals {
	grid-column: 2;
	width: 100%;
	float: none;
	min-width: 0;
}

.woocommerce-cart .cart-collaterals .cart_totals {
	width: 100% !important;
	float: none !important;
	position: sticky;
	top: calc(var(--header-h) + var(--sp-4));
	padding: var(--sp-5);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--blush-1);
}

.woocommerce-cart .cart_totals h2 {
	margin: 0 0 var(--sp-4);
	padding-bottom: var(--sp-3);
	border-bottom: 1px solid var(--line);
	font-family: var(--font-body);
	font-size: var(--fs-md);
	font-weight: 700;
	letter-spacing: var(--ls-wide);
	text-transform: uppercase;
}

.woocommerce-cart .cart_totals table {
	width: 100%;
	border: 0;
	background: transparent;
	margin: 0 0 var(--sp-4);
}

.woocommerce-cart .cart_totals table th,
.woocommerce-cart .cart_totals table td {
	padding: var(--sp-2) 0;
	border: 0;
	border-bottom: 1px solid var(--line);
	background: transparent;
	font-size: var(--fs-sm);
	text-transform: none;
	letter-spacing: 0;
}

.woocommerce-cart .cart_totals .order-total th,
.woocommerce-cart .cart_totals .order-total td {
	border-bottom: 0;
	padding-top: var(--sp-3);
	font-size: var(--fs-lg);
	font-weight: 700;
	color: var(--ink);
}

/* The line-item table must never be wider than the column holding it. */
.woocommerce-cart table.shop_table {
	width: 100%;
	table-layout: fixed;
}

.woocommerce-cart table.shop_table th,
.woocommerce-cart table.shop_table td {
	overflow-wrap: anywhere;
}

.woocommerce-cart table.shop_table .product-remove    { width: 3rem; }
.woocommerce-cart table.shop_table .product-thumbnail { width: 5.5rem; }
.woocommerce-cart table.shop_table .product-price,
.woocommerce-cart table.shop_table .product-subtotal  { width: 6rem; }
.woocommerce-cart table.shop_table .product-quantity  { width: 7rem; }

.woocommerce-cart table.shop_table img {
	width: 4.5rem !important;
	height: auto;
	border-radius: var(--r-sm);
	background: var(--blush-2);
}

.woocommerce-cart table.shop_table td.actions {
	padding: var(--sp-4);
	background: var(--blush-1);
}

.woocommerce-cart .coupon {
	display: flex;
	gap: var(--sp-2);
	flex-wrap: wrap;
	align-items: center;
}
.woocommerce-cart .coupon input#coupon_code { width: auto; min-width: 10rem; flex: 1 1 10rem; }
.woocommerce-cart td.actions > button[name="update_cart"] { margin-left: auto; }

@media (max-width: 900px) {
	.woocommerce-cart .woocommerce { grid-template-columns: 1fr; }
	.woocommerce-cart form.woocommerce-cart-form,
	.woocommerce-cart .cart-collaterals { grid-column: 1; }
	.woocommerce-cart .cart-collaterals .cart_totals { position: static; }
}

@media (max-width: 680px) {
	/* The table becomes a card per row; auto layout is what makes that work. */
	.woocommerce-cart table.shop_table { table-layout: auto; }
	.woocommerce-cart table.shop_table .product-remove,
	.woocommerce-cart table.shop_table .product-thumbnail,
	.woocommerce-cart table.shop_table .product-price,
	.woocommerce-cart table.shop_table .product-subtotal,
	.woocommerce-cart table.shop_table .product-quantity { width: auto; }

	.woocommerce-cart td.actions > button[name="update_cart"] { margin-left: 0; }
}

/* ==========================================================================
   CART, CORRECTED
   The previous pass squeezed the item column so hard that overflow-wrap broke
   words to one letter per line. Fixed table layout plus a narrow track is the
   wrong combination here: the table needs to size itself from its content.
   ========================================================================== */

.woocommerce-cart .woocommerce {
	grid-template-columns: minmax(28rem, 1fr) minmax(16rem, 20rem);
	gap: var(--sp-5);
}

/* Auto layout, so columns take the width their content needs. */
.woocommerce-cart table.shop_table {
	table-layout: auto;
	width: 100%;
}

/* Only the product name may wrap mid-word, and only as a last resort. */
.woocommerce-cart table.shop_table th,
.woocommerce-cart table.shop_table td { overflow-wrap: normal; }
.woocommerce-cart td.product-name { overflow-wrap: break-word; min-width: 11rem; }

.woocommerce-cart table.shop_table .product-remove    { width: 2.5rem; }
.woocommerce-cart table.shop_table .product-thumbnail { width: 4.5rem; }
.woocommerce-cart table.shop_table .product-price,
.woocommerce-cart table.shop_table .product-subtotal  { width: 5.5rem; white-space: nowrap; }
.woocommerce-cart table.shop_table .product-quantity  { width: 6.5rem; }

.woocommerce-cart table.shop_table th { white-space: nowrap; }

/* The quantity control must not be wider than its own column. */
.woocommerce-cart .quantity { display: inline-flex; align-items: center; }
.woocommerce-cart .quantity input.qty { width: 2.75rem; text-align: center; }

@media (max-width: 1100px) {
	/* Below this the two columns cannot both hold their minimum, so the
	   summary goes underneath rather than crushing the items. */
	.woocommerce-cart .woocommerce { grid-template-columns: 1fr; }
	.woocommerce-cart form.woocommerce-cart-form,
	.woocommerce-cart .cart-collaterals { grid-column: 1; }
	.woocommerce-cart .cart-collaterals { max-width: 24rem; margin-left: auto; }
	.woocommerce-cart .cart-collaterals .cart_totals { position: static; }
}

@media (max-width: 680px) {
	.woocommerce-cart .cart-collaterals { max-width: none; margin-left: 0; }
	.woocommerce-cart td.product-name { min-width: 0; }
}

/* The table still measured wider than its track because minmax() gives the
   first column a fixed floor rather than letting it take the space left over.
   A fr unit with min-width: 0 lets it grow to whatever the table needs. */
.woocommerce-cart .woocommerce {
	grid-template-columns: 1fr minmax(15rem, 19rem);
}

.woocommerce-cart form.woocommerce-cart-form { min-width: 0; overflow-x: auto; }

/* The fixed widths on five columns plus an 11rem floor on the name added up
   to more than the track could ever be. The floors go; the name column takes
   what is left and the rest stay as narrow as their content allows. */
.woocommerce-cart td.product-name { min-width: 0; }

.woocommerce-cart table.shop_table .product-remove,
.woocommerce-cart table.shop_table .product-thumbnail,
.woocommerce-cart table.shop_table .product-price,
.woocommerce-cart table.shop_table .product-subtotal,
.woocommerce-cart table.shop_table .product-quantity { width: 1%; white-space: nowrap; }

.woocommerce-cart table.shop_table .product-name { width: auto; }

/* The thumbnail is the one thing that needs a real size. */
.woocommerce-cart table.shop_table img { width: 3.5rem !important; }

.woocommerce-cart form.woocommerce-cart-form { overflow-x: visible; }

/* Measured: the table needs about 543px at this content, and the shell is
   1200px inside its gutters. Giving the items two thirds and the summary one
   third fits both without either overflowing. */
.woocommerce-cart .woocommerce {
	grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
	gap: var(--sp-5);
}

/* Below the width where the table genuinely fits, it stacks rather than
   clipping. 1100px is where 2fr stops being enough for six columns. */
@media (max-width: 1100px) {
	.woocommerce-cart .woocommerce { grid-template-columns: 1fr; }
}

/* ==========================================================================
   CART AND CHECKOUT WIDTH
   Both render through page.php, which wraps content in .tw-shell--narrow at
   780px. That measure is right for prose and far too tight for a six-column
   order table, which is why the cart columns were crushing their own text.
   These two screens get the full shell.
   ========================================================================== */

.woocommerce-cart .tw-shell--narrow,
.woocommerce-checkout .tw-shell--narrow {
	max-width: var(--shell);
}

/* The article wrapper carries a reading measure too. */
.woocommerce-cart .tw-prose,
.woocommerce-checkout .tw-prose {
	max-width: none;
}

/* The quantity field was 2.75rem wide with centred text, which clipped the
   number out of view on the cart table. */
.woocommerce-cart .quantity input.qty {
	width: 3.25rem;
	min-width: 3.25rem;
	padding: .5rem .25rem;
	font-size: var(--fs-sm);
	opacity: 1;
	color: var(--ink);
}

.woocommerce-cart .quantity {
	border: 1px solid var(--line-2);
	border-radius: var(--r-pill);
	overflow: hidden;
	background: var(--white);
}

.woocommerce-cart .quantity .tw-qty-btn { width: 2rem; height: 2.25rem; }

/* Cart and checkout titles carried the full section rhythm above content that
   starts with a notice, which read as a hole rather than as space. */
.woocommerce-cart .tw-page-hero,
.woocommerce-checkout .tw-page-hero { padding-block: var(--sp-6) var(--sp-4); }

.woocommerce-cart .tw-sec { padding-block: var(--sp-5) var(--sp-8); }

/* ==========================================================================
   HOME: WHAT HAPPENS AFTER YOU ORDER
   A numbered sequence, because the question it answers is about order, and a
   grid of equal cards would lose that.
   ========================================================================== */

.tw-steps__list {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: var(--sp-4);
	margin: 0;
	padding: 0;
	list-style: none;
	counter-reset: tw-step;
}

.tw-steps__item {
	counter-increment: tw-step;
	position: relative;
	margin: 0;
	padding: var(--sp-5);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--white);
	transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.tw-steps__item:hover { border-color: var(--rose-200); box-shadow: var(--shadow); }

/* The number sits on the edge, so the sequence reads without a label. */
.tw-steps__item::before {
	content: counter(tw-step);
	position: absolute;
	top: var(--sp-4);
	right: var(--sp-4);
	display: grid;
	place-items: center;
	width: 1.6rem;
	height: 1.6rem;
	border-radius: 50%;
	background: var(--blush-2);
	color: var(--rose-600);
	font-size: var(--fs-xs);
	font-weight: 700;
	font-variant-numeric: tabular-nums;
}

.tw-steps__icon {
	display: grid;
	place-items: center;
	width: 2.75rem;
	height: 2.75rem;
	margin-bottom: var(--sp-3);
	border-radius: var(--r-md);
	background: var(--blush-2);
	color: var(--rose-500);
}

.tw-steps__item h3 {
	margin-bottom: .35rem;
	font-family: var(--font-body);
	font-size: var(--fs-md);
	font-weight: 600;
}

.tw-steps__item p {
	margin: 0 0 var(--sp-3);
	color: var(--ink-3);
	font-size: var(--fs-sm);
	line-height: 1.55;
}

.tw-steps__when {
	display: inline-block;
	padding: .25rem .65rem;
	border-radius: var(--r-pill);
	background: var(--blush-1);
	border: 1px solid var(--rose-100);
	color: var(--rose-700);
	font-size: var(--fs-xs);
	font-weight: 600;
}

/* ==========================================================================
   HOME: THE TWO QUESTIONS
   Two wide cards rather than four narrow ones: these need room to be read.
   ========================================================================== */

.tw-assure-home__in {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--sp-5);
}

.tw-assure-home__card {
	padding: var(--sp-7);
	border: 1px solid var(--line);
	border-radius: var(--r-xl);
	background: linear-gradient(160deg, var(--blush-1), var(--white) 70%);
}

.tw-assure-home__icon {
	display: grid;
	place-items: center;
	width: 3.25rem;
	height: 3.25rem;
	margin-bottom: var(--sp-4);
	border-radius: var(--r-lg);
	background: var(--white);
	border: 1px solid var(--rose-100);
	color: var(--rose-500);
	box-shadow: var(--shadow-sm);
}

.tw-assure-home__card h2 {
	margin-bottom: var(--sp-3);
	font-size: var(--fs-xl);
	max-width: 22ch;
}

.tw-assure-home__card p {
	margin-bottom: var(--sp-4);
	color: var(--ink-3);
	font-size: var(--fs-sm);
	line-height: 1.65;
}

@media (max-width: 1100px) {
	.tw-steps__list { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 780px) {
	.tw-assure-home__in { grid-template-columns: 1fr; }
	.tw-assure-home__card { padding: var(--sp-5); }
}

@media (max-width: 560px) {
	.tw-steps__list { grid-template-columns: 1fr; }
}

/* ==========================================================================
   DUAL-ARC LOADER
   Two arcs turning in opposite directions, in the brand rose. Built from
   borders rather than a library: the published component is a React module,
   and a WordPress theme should not carry a bundler for one spinner.
   ========================================================================== */

/* The old indeterminate bar is replaced by the arcs. */

.tw-loader__in { gap: var(--sp-4); }
.tw-loader__logo { width: 132px; }

@media (prefers-reduced-motion: reduce) {
	.tw-loader__arc::before,
	.tw-loader__arc::after { animation: none; }
	.tw-loader__arc::before { border-color: var(--rose-200); }
	.tw-loader__arc::after  { border-color: var(--rose-400); }
}

/* ==========================================================================
   HERO POINT SLIDER
   The three reassurances were a static row. They now advance one at a time
   with a parallax lift, so the strip carries motion without another marquee.
   One slide is visible at a time, which is what makes each one readable.
   ========================================================================== */

.tw-hero__points {
	position: relative;
	display: block;
	min-height: 2.75rem;
	margin-top: var(--sp-5);
	padding-top: var(--sp-4);
	border-top: 1px solid var(--line);
	overflow: hidden;
}

.tw-hero__points > li {
	position: absolute;
	top: var(--sp-4);
	left: 0;
	display: inline-flex;
	align-items: center;
	gap: var(--sp-2);
	margin: 0;
	padding: .45rem .9rem;
	border: 1px solid var(--rose-100);
	border-radius: var(--r-pill);
	background: linear-gradient(120deg, var(--white), var(--rose-50));
	color: var(--ink-2);
	font-size: var(--fs-sm);
	font-weight: 600;
	white-space: nowrap;
	box-shadow: var(--shadow-sm);

	/* Off to the right, scaled down: the two together read as depth rather
	   than as a plain slide. */
	opacity: 0;
	transform: translate3d(2.5rem, 0, 0) scale(.92);
	transition: opacity 620ms var(--ease-out), transform 620ms var(--ease-out);
	pointer-events: none;
}

.tw-hero__points > li.is-on {
	opacity: 1;
	transform: none;
	pointer-events: auto;
}

/* Leaving to the left, so the sequence has a direction. */
.tw-hero__points > li.is-out {
	opacity: 0;
	transform: translate3d(-2.5rem, 0, 0) scale(.92);
}

.tw-hero__points svg { color: var(--rose-500); flex: none; }

/* Progress pips, so the strip shows there is more than one. */
.tw-hero__pips {
	position: absolute;
	right: 0;
	top: calc(var(--sp-4) + .9rem);
	display: flex;
	gap: .3rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.tw-hero__pip {
	width: .4rem;
	height: .4rem;
	border-radius: 50%;
	background: var(--rose-100);
	transition: background var(--dur) var(--ease), transform var(--dur) var(--ease);
}

.tw-hero__pip.is-on { background: var(--rose-500); transform: scale(1.3); }

/* Without JavaScript nothing rotates, so the first one simply stays put and
   the rest are hidden instead of stacking on top of each other. */
html.no-js .tw-hero__points > li { position: static; opacity: 1; transform: none; }
html.no-js .tw-hero__points > li + li { display: none; }
html.no-js .tw-hero__pips { display: none; }

@media (prefers-reduced-motion: reduce) {
	.tw-hero__points > li { transition: none; }
}

@media (max-width: 680px) {
	.tw-hero__points { min-height: 2.5rem; }
	.tw-hero__points > li { font-size: var(--fs-xs); padding: .4rem .75rem; }
	.tw-hero__pips { display: none; }
}

/* ==========================================================================
   PAGINATION
   The list markers were still showing: the earlier fix reached the product
   tabs but not this list.
   ========================================================================== */

.woocommerce nav.woocommerce-pagination ul,
.woocommerce nav.woocommerce-pagination ul li {
	list-style: none;
}

.woocommerce nav.woocommerce-pagination ul li {
	display: block;
}

.woocommerce nav.woocommerce-pagination ul li::marker { content: ""; }
.woocommerce nav.woocommerce-pagination ul li::before { content: none; }

/* The catalogue heading was pinned, which left it sitting over the product
   grid as the page scrolled. A page title is not a control: it belongs at the
   top and should scroll away with everything else. */
.tw-woo .woocommerce-products-header {
	position: static;
	background: none;
	padding-block: 0;
}

/* ==========================================================================
   HERO ASSURANCE STRIP
   The strip sits below the slider, which spans the whole shell, while the
   copy it belongs to only occupies the left column. Left unconstrained, the
   single visible point drifted into the empty right half and read as a bug.
   It is now held to the copy column's width, with the pips at its right edge.
   ========================================================================== */

.tw-hero__assure {
	/* .tw-hero__in is a two-column grid, so the strip was landing as a third
	   item in the right-hand column of a second row. It has to span both
	   columns first; only then does a width constraint mean anything. */
	grid-column: 1 / -1;
	justify-self: start;
	width: 100%;
	max-width: 32rem;

	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-4);
	min-height: 2.75rem;
	margin-top: var(--sp-5);
	padding-top: var(--sp-4);
	border-top: 1px solid var(--line);
}

/* The list is now the positioning context, so a slide travels inside the
   strip rather than across the whole hero. */
.tw-hero__points {
	position: relative;
	flex: 1 1 auto;
	min-height: 2.25rem;
	margin: 0;
	padding: 0;
	border-top: 0;
	overflow: hidden;
}

.tw-hero__points > li {
	top: 0;
	left: 0;
}

/* Back in normal flow: the strip is flex now, so the pips need no offset. */
.tw-hero__pips {
	position: static;
	flex: none;
	align-self: center;
}

@media (max-width: 1024px) {
	/* One column below this width, so the strip takes the full measure. */
	.tw-hero__assure { max-width: none; }
}

@media (max-width: 680px) {
	.tw-hero__assure { min-height: 2.5rem; }
}

/* ==========================================================================
   LOADER, REBUILT
   Two short arcs on opposite sides, turning together. The previous version
   used half-borders, which draws two long half-rings rather than the pair of
   clipped strokes in the reference.
   ========================================================================== */

.tw-loader {
	/* A blush wash rather than flat white: on a white site a white cover is
	   indistinguishable from a page that has not painted yet. */
	background: radial-gradient(38rem 28rem at 50% 42%, var(--blush-2), var(--white) 72%);
}

.tw-loader__arc {
	position: relative;
	width: 4.25rem;
	height: 4.25rem;
	animation: tw-arc-spin 1s linear infinite;
}

/* Each half draws one arc via a conic gradient masked to a ring: a gradient
   can stop mid-sweep, which is what gives the short stroke and the gap. */
.tw-loader__arc::before,
.tw-loader__arc::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 50%;

	/* A 70deg sweep, then nothing, leaving the arc and its gap. */
	background: conic-gradient(from 0deg, var(--rose-500) 0deg 78deg, transparent 78deg);

	/* Punch out the middle so the disc becomes a ring. */
	-webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 5px), #000 calc(100% - 5px));
	        mask: radial-gradient(farthest-side, transparent calc(100% - 5px), #000 calc(100% - 5px));
}

/* The second arc is the same stroke, half a turn away. */
.tw-loader__arc::after {
	transform: rotate(180deg);
}

@keyframes tw-arc-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
	.tw-loader__arc { animation-duration: 3s; }
}

/* ==========================================================================
   HERO PROPORTIONS
   The slider divides the shell, then each slide divides again, leaving the
   copy column under 300px: the headline broke to five lines and the art
   floated into the middle. The copy gets the room it needs, and the art is
   pinned to the right edge so the two halves read as halves.
   ========================================================================== */

/* The stage holds the whole slider, so it has to span both tracks of
   .tw-hero__in. It was sitting in the left track alone, which meant each
   slide subdivided 605px into a 320px headline and a 237px image while the
   right half of the hero stayed empty. */
.tw-hero__stage { grid-column: 1 / -1; }

.tw-slide {
	grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
	gap: var(--sp-8);
}

.tw-slide__copy { max-width: 34rem; }

.tw-slide__art {
	max-width: 30rem;
	justify-self: end;
}

@media (max-width: 1024px) {
	.tw-slide__copy { max-width: none; }
}

/* ==========================================================================
   MY ACCOUNT, SIGNED OUT
   The sidebar grid belongs to the signed-in dashboard. Applied to the login
   page it left a 230px empty column, pushed both forms into the right-hand
   track and stacked them vertically. Logged out, the page is a plain
   two-card layout instead.
   ========================================================================== */

/* The account page is a WP Page, so it inherits the narrow prose measure.
   The card wants a measure of its own, set below. */
body.woocommerce-account .tw-shell.tw-shell--narrow { max-width: var(--shell); }

/* The sidebar grid belongs to the signed-in dashboard. Logged out there is
   no sidebar, so the column must not be reserved. */
body.woocommerce-account:not(.logged-in) .woocommerce { display: block; }

/* WooCommerce wraps the two forms in .u-columns > .u-column1/.u-column2 and
   floats them at 48%. One pane shows at a time, so the float goes and the
   wrapper becomes a plain single column. */
body.woocommerce-account:not(.logged-in) .woocommerce > .u-columns,
body.woocommerce-account:not(.logged-in) .woocommerce > .col2-set {
	display: block;
	float: none;
	width: auto;
	max-width: 30rem;
	margin-inline: auto;
}

body.woocommerce-account:not(.logged-in) .u-column1,
body.woocommerce-account:not(.logged-in) .u-column2 {
	float: none;
	width: auto;
	margin: 0;
}

/* Only the active pane is in the document. Hidden rather than merely
   invisible: a hidden form must not be tabbable or submittable. The
   :not(.logged-in) matches the specificity of the float reset below, which
   would otherwise win on source order and show both forms. */
body.woocommerce-account:not(.logged-in).tw-acct--login .u-column2,
body.woocommerce-account:not(.logged-in).tw-acct--register .u-column1 { display: none; }

body.woocommerce-account:not(.logged-in) .u-column1 > h2,
body.woocommerce-account:not(.logged-in) .u-column2 > h2 {
	margin: 0 0 var(--sp-3);
	font-size: var(--fs-2xl);
	text-align: center;
}

body.woocommerce-account:not(.logged-in) .woocommerce-form-login,
body.woocommerce-account:not(.logged-in) .woocommerce-form-register {
	max-width: none;
	margin-inline: 0;
	padding: var(--sp-6);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--white);
	box-shadow: var(--shadow-sm);
}

/* The link to the other pane. Separated by a rule so it reads as a way out
   of the form rather than another field. */
body.woocommerce-account .tw-acct-swap {
	margin: var(--sp-4) 0 0;
	padding-top: var(--sp-4);
	border-top: 1px solid var(--line);
	color: var(--ink-3);
	font-size: var(--fs-sm);
	text-align: center;
}

body.woocommerce-account .tw-acct-swap a {
	color: var(--rose-600);
	font-weight: 600;
	text-decoration: underline;
	text-underline-offset: 3px;
}

body.woocommerce-account .tw-acct-swap a:hover { color: var(--rose-700); }

/* The note sits above the swap link, so it keeps its own separation. */
body.woocommerce-account .woocommerce-form-register .tw-acct-note {
	margin-top: var(--sp-4);
}

body.woocommerce-account .woocommerce-form-row { margin-bottom: var(--sp-4); }

body.woocommerce-account .woocommerce-form__label-for-checkbox {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	margin-bottom: var(--sp-4);
	font-size: var(--fs-sm);
	color: var(--ink-3);
}

body.woocommerce-account .woocommerce-form-login__submit,
body.woocommerce-account .woocommerce-form-register__submit {
	width: 100%;
	height: 3rem;
	margin: 0 0 var(--sp-3);
}

body.woocommerce-account .woocommerce-LostPassword { margin: 0; font-size: var(--fs-sm); }

/* The password field has a show/hide button. Unstyled it rendered as a small
   grey slab below the input; it belongs inside the field, on the right. */
.woocommerce-account .password-input,
.woocommerce-account .woocommerce-password-input { position: relative; display: block; }

.woocommerce-account .password-input .show-password-input,
.woocommerce-password-input .show-password-input {
	--eye: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7-10-7-10-7z"/><circle cx="12" cy="12" r="3"/></svg>');
	position: absolute;
	top: 50%;
	right: .85rem;
	transform: translateY(-50%);
	width: 1.25rem;
	height: 1.25rem;
	padding: 0;
	border: 0;
	background: none;
	color: var(--ink-4);
	cursor: pointer;
}

/* WooCommerce ships this as a background-image sprite that does not load in
   a custom theme, so the eye is drawn here. */
.woocommerce-account .password-input .show-password-input::before,
.woocommerce-password-input .show-password-input::before {
	content: "";
	display: block;
	width: 100%;
	height: 100%;
	background: currentColor;
	-webkit-mask: var(--eye) center / contain no-repeat;
	        mask: var(--eye) center / contain no-repeat;
}

.woocommerce-account .password-input .show-password-input:hover { color: var(--rose-500); }
.woocommerce-account .password-input .show-password-input.display-password { color: var(--rose-600); }

.woocommerce-account .password-input input { padding-right: 2.75rem; }

/* A note under the register form: what an account is actually for. */
body.woocommerce-account .tw-acct-note {
	margin: 0;
	padding-top: var(--sp-3);
	border-top: 1px solid var(--rose-100);
	color: var(--ink-4);
	font-size: var(--fs-xs);
	line-height: 1.55;
}

/* The login note sits above the fields, so it needs the border on the other
   side and room beneath it. */
body.woocommerce-account .tw-acct-note--top {
	margin-bottom: var(--sp-4);
	padding-top: 0;
	padding-bottom: var(--sp-3);
	border-top: 0;
	border-bottom: 1px solid var(--line);
}

/* ==========================================================================
   HOME: PROMOTIONAL BANNER
   A wide band that states the delivery offer once, plainly. The figures come
   from the shipping settings, so the banner cannot promise something the
   checkout will not honour.
   ========================================================================== */

.tw-promo-b__in {
	display: grid;
	grid-template-columns: minmax(0, 1.2fr) minmax(0, .8fr);
	gap: var(--sp-8);
	align-items: center;
	padding: var(--sp-8);
	border: 1px solid var(--rose-100);
	border-radius: var(--r-xl);
	background:
		radial-gradient(30rem 20rem at 88% 12%, var(--rose-100), transparent 62%),
		linear-gradient(150deg, var(--blush-1), var(--white) 70%);
}

.tw-promo-b__tag {
	display: inline-block;
	margin-bottom: var(--sp-3);
	padding: .3rem .75rem;
	border-radius: var(--r-pill);
	background: var(--rose-500);
	color: #fff;
	font-size: var(--fs-xs);
	font-weight: 700;
	letter-spacing: var(--ls-caps);
	text-transform: uppercase;
}

.tw-promo-b__title {
	margin: 0 0 var(--sp-3);
	font-size: var(--fs-3xl);
	line-height: 1.1;
	max-width: 18ch;
}

.tw-promo-b__sub {
	margin: 0 0 var(--sp-5);
	max-width: 46ch;
	color: var(--ink-3);
	line-height: 1.6;
}

.tw-promo-b__acts { display: flex; flex-wrap: wrap; gap: var(--sp-3); }

.tw-promo-b__facts {
	display: grid;
	gap: var(--sp-3);
	margin: 0;
	padding: 0;
	list-style: none;
}

.tw-promo-b__facts li {
	display: grid;
	grid-template-columns: auto 1fr;
	grid-template-rows: auto auto;
	column-gap: var(--sp-3);
	align-items: center;
	margin: 0;
	padding: var(--sp-4);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--white);
}

.tw-promo-b__facts svg { grid-row: 1 / 3; color: var(--rose-500); }
.tw-promo-b__facts strong { font-size: var(--fs-md); }
.tw-promo-b__facts span { color: var(--ink-4); font-size: var(--fs-sm); }

/* ==========================================================================
   HOME: MOST WANTED
   A heading with the link to the full shop on the same line, so the row does
   not need a second call to action underneath it.
   ========================================================================== */

.tw-wanted__head {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--sp-5);
	margin-bottom: var(--sp-6);
	padding-bottom: var(--sp-4);
	border-bottom: 1px solid var(--line);
}

.tw-wanted__title { margin: 0 0 .35rem; font-size: var(--fs-3xl); }

.tw-wanted__sub {
	margin: 0;
	max-width: 52ch;
	color: var(--ink-3);
	font-size: var(--fs-sm);
	line-height: 1.6;
}

.tw-wanted__all {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-2);
	flex: none;
	color: var(--rose-600);
	font-size: var(--fs-sm);
	font-weight: 600;
}

.tw-wanted__all:hover { color: var(--rose-700); }
.tw-wanted__all svg { transition: transform var(--dur-fast) var(--ease); }
.tw-wanted__all:hover svg { transform: translateX(3px); }

@media (max-width: 980px) {
	.tw-promo-b__in { grid-template-columns: 1fr; padding: var(--sp-6); }
	.tw-promo-b__facts { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 760px) {
	.tw-promo-b__facts { grid-template-columns: 1fr; }
	.tw-promo-b__title { font-size: var(--fs-2xl); }

	.tw-wanted__head { flex-direction: column; align-items: flex-start; gap: var(--sp-3); }
}

/* ==========================================================================
   BOTTOM NAVIGATION (phones)
   The header's icon row sits at the top of a tall page, which is the hardest
   place to reach one-handed. Below 860px the same destinations move to a
   fixed bar at the bottom and the header keeps only the menu and the logo.
   ========================================================================== */

.tw-bnav { display: none; }

@media (max-width: 860px) {
	.tw-bnav {
		position: fixed;
		left: 0;
		right: 0;
		bottom: 0;
		z-index: calc(var(--z-drawer) - 4);

		display: grid;
		grid-template-columns: repeat(5, 1fr);
		align-items: stretch;

		border-top: 1px solid var(--line);
		background: color-mix(in srgb, var(--white) 92%, transparent);
		-webkit-backdrop-filter: saturate(1.4) blur(12px);
		        backdrop-filter: saturate(1.4) blur(12px);

		/* Clear of the iOS home indicator, and of Android's gesture bar. */
		padding-bottom: env(safe-area-inset-bottom, 0);
	}

	.tw-bnav__item {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		gap: 2px;

		/* 56px of height plus the label keeps every target above the 44px
		   minimum without the bar eating the page. */
		min-height: 3.5rem;
		padding: .45rem 0 .5rem;

		border: 0;
		background: none;
		color: var(--ink-4);
		font-family: inherit;
		font-size: 0;
		cursor: pointer;
		-webkit-tap-highlight-color: transparent;
		transition: color var(--dur-fast) var(--ease);
	}

	.tw-bnav__t {
		font-size: .625rem;
		font-weight: 600;
		letter-spacing: .01em;
		line-height: 1;
	}

	.tw-bnav__ic {
		position: relative;
		display: grid;
		place-items: center;
		width: 1.75rem;
		height: 1.5rem;
	}

	.tw-bnav__item.is-on { color: var(--rose-600); }

	/* A short rule above the active item, so the state reads without relying
	   on colour alone. */
	.tw-bnav__item.is-on::before {
		content: "";
		position: absolute;
		top: 0;
		width: 1.75rem;
		height: 2px;
		border-radius: 0 0 2px 2px;
		background: var(--rose-500);
	}

	.tw-bnav__item { position: relative; }
	.tw-bnav__item:active { color: var(--rose-700); }

	/* Counts, matching the header badges. */
	.tw-bnav__n {
		position: absolute;
		top: -2px;
		right: -2px;
		min-width: 1rem;
		height: 1rem;
		padding: 0 .25rem;
		border-radius: var(--r-pill);
		background: var(--rose-500);
		color: #fff;
		font-size: .5625rem;
		font-weight: 700;
		line-height: 1rem;
		text-align: center;
	}

	.tw-bnav__n.is-empty { display: none; }

	/* The page needs room, or the bar covers the footer and the last row of
	   any list. */
	body { padding-bottom: calc(3.5rem + env(safe-area-inset-bottom, 0px)); }

	/* The header loses its icons: they are all in the bar now, and keeping
	   both would mean two ways to reach the same page on one screen. */
	.tw-hd__tools { display: none; }

	/* Which leaves the burger and the logo. Centre the logo between them. */
	.tw-hd__in {
		grid-template-columns: auto 1fr;
		gap: var(--sp-3);
	}

	.tw-hd__brand { justify-self: center; margin-right: 2.75rem; }

	/* Anything else pinned to the bottom has to sit above the bar. */
	.tw-chat { bottom: calc(4rem + env(safe-area-inset-bottom, 0px)); }

	body.single-product .tw-chat { bottom: calc(8.5rem + env(safe-area-inset-bottom, 0px)); }

	.tw-buybar, [data-buybar] {
		bottom: calc(3.5rem + env(safe-area-inset-bottom, 0px));
	}

	/* A drawer or modal owns the screen; the bar must not float over it. */
	body.tw-locked .tw-bnav { display: none; }
}

@media (prefers-reduced-motion: reduce) {
	.tw-bnav__item { transition: none; }
}

/* ==========================================================================
   PRODUCT GALLERY ON A PHONE
   WooCommerce's FlexSlider lays its slides out in a row as wide as the whole
   set. The viewport it sits in was given a max-width of 34rem, which is
   wider than a phone, so the row ran off the side of the screen and took
   170px of horizontal scroll with it.
   ========================================================================== */

@media (max-width: 600px) {
	.woocommerce div.product .woocommerce-product-gallery {
		max-width: 100%;
		width: 100%;
		margin-inline: 0;
		overflow: hidden;
	}

	.woocommerce div.product .flex-viewport {
		max-width: 100%;
		overflow: hidden;
	}

	/* Each slide is exactly one viewport wide, so the strip cannot overhang. */
	.woocommerce div.product .woocommerce-product-gallery__image {
		max-width: 100%;
	}

	.woocommerce div.product .woocommerce-product-gallery__image img,
	.woocommerce div.product .flex-viewport {
		max-height: 60vh;
	}

	.woocommerce div.product .woocommerce-product-gallery__image img {
		width: 100%;
		height: auto;
		object-fit: contain;
	}

	/* The zoom overlay is a second, full-resolution image absolutely placed
	   over the first. On a phone it is both useless and a source of overflow. */
	.woocommerce div.product img.zoomImg { display: none !important; }

	/* Four thumbnails read better than five at this width. */
	.woocommerce div.product .flex-control-thumbs {
		grid-template-columns: repeat(4, 1fr);
		gap: var(--sp-2);
		max-width: 100%;
	}
}

/* ==========================================================================
   BOTTOM BAR STACKING, corrected
   Three things now want the bottom of a phone screen: the nav, the sticky
   buy bar on a product, and the chat launcher. Measured on a 390x844
   viewport they were overlapping, and the buy bar ran off the bottom
   because it kept its own safe-area padding on top of the nav's offset.
   ========================================================================== */

@media (max-width: 860px) {
	.tw-buybar {
		/* The nav already reserves the safe area, so the bar only needs to
		   clear the nav itself. Keeping both offsets pushed it off-screen.
		   3.5rem is the nav's own height, measured, not guessed. */
		bottom: calc(3.5rem + env(safe-area-inset-bottom, 0px));
		padding-block: var(--sp-2);
		padding-bottom: var(--sp-2);

		/* Above the nav's backdrop, below any drawer. */
		z-index: calc(var(--z-drawer) - 3);
	}

	/* The launcher sits above whichever bar is showing, and never over the
	   product copy: it was landing on the description at 390px. */
	.tw-chat { bottom: calc(4.25rem + env(safe-area-inset-bottom, 0px)); }

	body.single-product .tw-chat {
		bottom: calc(9rem + env(safe-area-inset-bottom, 0px));
	}

	/* A product page carries both bars, so the page needs room for both. */
	body.single-product { padding-bottom: calc(8rem + env(safe-area-inset-bottom, 0px)); }
}

/* ==========================================================================
   GALLERY HEIGHT ON A PHONE
   max-height on the viewport reserved 60vh whether or not the image filled
   it, which left 350px of white under a square product shot. The slider
   needs a fixed frame, so the frame is squared to the image instead.
   ========================================================================== */

@media (max-width: 600px) {
	.woocommerce div.product .flex-viewport,
	.woocommerce div.product .woocommerce-product-gallery__image {
		max-height: none;
	}

	/* Square: every product image in this catalogue is 1:1, and a fixed
	   ratio stops the page reflowing as each slide loads. */
	.woocommerce div.product .woocommerce-product-gallery__image img {
		aspect-ratio: 1 / 1;
		max-height: none;
	}

	/* Thumbnails: keep the last row from stretching when the count is not a
	   multiple of four. */
	.woocommerce div.product .flex-control-thumbs li { aspect-ratio: 1 / 1; }
	.woocommerce div.product .flex-control-thumbs img { height: 100%; object-fit: cover; }
}

/* ==========================================================================
   2px OVERFLOW ON NARROW SCREENS
   Full-bleed fixed elements were sized at 100% of the containing block and
   then given a border, which box-sizing does not absorb on a fixed element
   whose left and right are both 0. Pinning both edges instead of setting a
   width avoids the extra couple of pixels.
   ========================================================================== */

@media (max-width: 860px) {
	.tw-bnav,
	.tw-progress {
		width: auto;
		left: 0;
		right: 0;
		max-width: 100%;
		box-sizing: border-box;
	}

	/* The sort control was wider than its column at 390px. */
	.tw-toolbar__sort,
	.woocommerce-ordering,
	.woocommerce-ordering select.orderby {
		max-width: 100%;
		box-sizing: border-box;
	}
}

/* ==========================================================================
   PROFILE
   The account dashboard, rebuilt as a single screen. Reads as a column on a
   phone, where it is now a primary destination, and keeps the same shape
   beside the sidebar on a desktop.
   ========================================================================== */

.tw-prof { max-width: 40rem; }

.tw-prof__head {
	display: flex;
	align-items: center;
	gap: var(--sp-4);
	padding-bottom: var(--sp-5);
	margin-bottom: var(--sp-5);
	border-bottom: 1px solid var(--line);
}

/* An initial, not an avatar: the shop never asks for a photo, so there is
   none to show and a placeholder silhouette would be pretending. */
.tw-prof__mark {
	display: grid;
	place-items: center;
	width: 3.25rem;
	height: 3.25rem;
	flex: none;
	border-radius: 50%;
	background: linear-gradient(140deg, var(--rose-500), var(--rose-600));
	color: #fff;
	font-size: var(--fs-xl);
	font-weight: 700;
	line-height: 1;
}

.tw-prof__who { min-width: 0; }

.tw-prof__name {
	margin: 0 0 .15rem;
	font-family: var(--font-body);
	font-size: var(--fs-lg);
	font-weight: 700;
}

.tw-prof__mail {
	margin: 0;
	color: var(--ink-4);
	font-size: var(--fs-sm);
	overflow-wrap: anywhere;
}

/* Two counts, each one a link to what it counts. */
.tw-prof__stats {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--sp-3);
	margin: 0 0 var(--sp-5);
	padding: 0;
	list-style: none;
}

.tw-prof__stats li { margin: 0; }

.tw-prof__stats a {
	display: block;
	padding: var(--sp-4);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--white);
	text-align: center;
	transition: border-color var(--dur-fast) var(--ease),
	            background var(--dur-fast) var(--ease);
}

.tw-prof__stats a:hover { border-color: var(--rose-200); background: var(--blush-1); }

.tw-prof__stats strong {
	display: block;
	font-size: var(--fs-2xl);
	font-weight: 700;
	line-height: 1.1;
	font-variant-numeric: tabular-nums;
	color: var(--ink);
}

.tw-prof__stats span {
	display: block;
	margin-top: .2rem;
	color: var(--ink-4);
	font-size: var(--fs-xs);
	font-weight: 600;
	letter-spacing: var(--ls-caps);
	text-transform: uppercase;
}

.tw-prof__card {
	margin-bottom: var(--sp-4);
	padding: var(--sp-5);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--white);
}

.tw-prof__ct {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	margin: 0 0 var(--sp-4);
	font-family: var(--font-body);
	font-size: var(--fs-xs);
	font-weight: 700;
	letter-spacing: var(--ls-caps);
	text-transform: uppercase;
	color: var(--ink-3);
}

.tw-prof__ct svg { color: var(--rose-500); flex: none; }

.tw-prof__orow {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-3);
	margin-bottom: .35rem;
}

.tw-prof__onum { font-size: var(--fs-md); font-weight: 700; font-variant-numeric: tabular-nums; }

.tw-prof__ometa {
	margin: 0 0 var(--sp-4);
	color: var(--ink-4);
	font-size: var(--fs-sm);
}

/* Status colours follow WooCommerce's own vocabulary, so the badge cannot
   claim a state the order is not in. */
.tw-prof__badge {
	flex: none;
	padding: .2rem .6rem;
	border-radius: var(--r-pill);
	background: var(--blush-2);
	color: var(--rose-700);
	font-size: var(--fs-xs);
	font-weight: 700;
	white-space: nowrap;
}

.tw-prof__badge--completed { background: #e8f5ec; color: #1f7a3d; }
.tw-prof__badge--processing { background: #e8f0fb; color: #1d4e89; }
.tw-prof__badge--on-hold,
.tw-prof__badge--pending { background: #fdf3e2; color: #8a5a10; }
.tw-prof__badge--cancelled,
.tw-prof__badge--failed,
.tw-prof__badge--refunded { background: #fbeaea; color: #8f2020; }

.tw-prof__empty {
	margin: 0 0 var(--sp-4);
	color: var(--ink-4);
	font-size: var(--fs-sm);
	line-height: 1.6;
}

.tw-prof__addr {
	margin: 0 0 var(--sp-4);
	font-style: normal;
	font-size: var(--fs-sm);
	line-height: 1.65;
	color: var(--ink-2);
}

.tw-prof__links {
	margin-bottom: var(--sp-5);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	overflow: hidden;
	background: var(--white);
}

.tw-prof__links a {
	display: grid;
	grid-template-columns: auto 1fr auto;
	align-items: center;
	gap: var(--sp-3);
	padding: var(--sp-4);
	border-bottom: 1px solid var(--line);
	color: var(--ink-2);
	font-size: var(--fs-sm);
	font-weight: 500;
	transition: background var(--dur-fast) var(--ease);
}

.tw-prof__links a:last-child { border-bottom: 0; }
.tw-prof__links a:hover { background: var(--blush-1); color: var(--rose-700); }
.tw-prof__links a > svg:first-child { color: var(--rose-500); }
.tw-prof__links a > svg:last-child { color: var(--ink-5, var(--ink-4)); }

.tw-prof__out {
	display: block;
	padding: var(--sp-3);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	color: var(--ink-3);
	font-size: var(--fs-sm);
	font-weight: 600;
	text-align: center;
	transition: border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.tw-prof__out:hover { border-color: var(--rose-200); color: var(--rose-700); }

@media (max-width: 600px) {
	.tw-prof__card { padding: var(--sp-4); }
	.tw-prof__head { gap: var(--sp-3); }
	.tw-prof__mark { width: 2.75rem; height: 2.75rem; font-size: var(--fs-lg); }
}

/* ==========================================================================
   ACCOUNT ON A PHONE, SIGNED IN
   The signed-in dashboard keeps WooCommerce's sidebar nav, which becomes a
   horizontal strip below 900px. The strip was sized by its contents rather
   than by the screen, so it ran to 585px inside a 390px viewport and its
   last tabs were unreachable: the page itself does not scroll sideways, so
   there was no way to get to them.

   The strip is given the viewport's width and its own scroll, which is what
   the flex rule in responsive.css was always meant to do.
   ========================================================================== */

@media (max-width: 900px) {
	.woocommerce-account.logged-in .woocommerce,
	.woocommerce-account.logged-in .woocommerce-MyAccount-content,
	.woocommerce-account.logged-in .woocommerce-MyAccount-navigation {
		min-width: 0;
		max-width: 100%;
	}

	.woocommerce-account.logged-in .woocommerce-MyAccount-navigation {
		/* Break out of the prose gutter so the strip can run edge to edge,
		   which is how a scrolling tab bar should read on a phone. */
		margin-inline: calc(var(--gutter) * -1);
		padding-inline: var(--gutter);
		overflow: hidden;
	}

	.woocommerce-account.logged-in .woocommerce-MyAccount-navigation ul {
		max-width: 100%;
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
		border-radius: 0;
		border-left: 0;
		border-right: 0;
	}

	/* The profile column takes the width it is given, never more. */
	.tw-prof { max-width: 100%; }
	.tw-prof__stats { gap: var(--sp-2); }
}

/* ==========================================================================
   HERO DOTS: THE TAP AREA HAS TO BE ON TOP
   The dots are a 3px rule by design, with an invisible ::after around them
   so a thumb has something to hit. Measured on a phone, only the 3px strip
   responded: the ::after was painting underneath .tw-hero__nav, so every
   tap more than a few pixels off centre went to the wrapper instead.

   Raising the button gives its own pseudo-element the stacking context it
   needs. The visual is unchanged; only the reachable area grows.
   ========================================================================== */

/* The button clips its own fill bar with overflow:hidden, which was also
   clipping the ::after that provided the tap area: it was being cut back to
   the same 3px strip, so only a dead-centre tap registered.

   The padding goes on the button instead and the 3px rule becomes a child,
   so the clipping applies to the bar and the target stays large. */
.tw-hero__dot {
	position: relative;
	z-index: 1;

	/* 3px rule plus 14px above and below: a 31px target. */
	width: 2.25rem;
	height: auto;
	padding: 14px 0;
	background: none;
	border-radius: 0;
	overflow: visible;
}

.tw-hero__dot::before {
	content: "";
	display: block;
	height: 3px;
	border-radius: var(--r-pill);
	background: var(--rose-100);
}

/* The fill sits over the rule, and is clipped to it rather than to the
   button, so the larger target costs nothing visually. */
.tw-hero__dot-fill {
	top: 14px;
	bottom: 14px;
	border-radius: var(--r-pill);
}

.tw-hero__nav { position: relative; z-index: 0; }

/* The row was spaced for 3px items; with padding they no longer need it. */
.tw-hero__dots { align-items: center; }

/* ==========================================================================
   PAGINATION OUTSIDE THE SHOP
   Search results and any archive use WordPress's own .nav-links markup, not
   WooCommerce's, so none of the shop pagination styling reached them: the
   page numbers were bare 9x19px text links, too small to tap and out of
   keeping with the rest of the site.

   Same pills, same sizes, applied to the WordPress markup.
   ========================================================================== */

.tw-main .navigation.pagination,
.tw-main nav.pagination {
	margin-top: var(--sp-8);
	text-align: center;
}

.tw-main .nav-links {
	display: inline-flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--sp-1);
}

.tw-main .nav-links .page-numbers {
	display: grid;
	place-items: center;
	min-width: 2.5rem;
	height: 2.5rem;
	padding: 0 .6rem;
	border-radius: var(--r-pill);
	background: var(--white);
	border: 1px solid var(--line);
	color: var(--ink-2);
	font-size: var(--fs-sm);
	font-weight: 500;
	transition: background var(--dur-fast) var(--ease),
	            border-color var(--dur-fast) var(--ease),
	            color var(--dur-fast) var(--ease);
}

.tw-main .nav-links a.page-numbers:hover {
	background: var(--blush-2);
	border-color: var(--rose-200);
	color: var(--rose-700);
}

.tw-main .nav-links .page-numbers.current {
	background: var(--rose-500);
	border-color: var(--rose-500);
	color: #fff;
	font-weight: 700;
}

/* The ellipsis is not a control, so it should not look like one. */
.tw-main .nav-links .page-numbers.dots {
	background: none;
	border-color: transparent;
	color: var(--ink-4);
}

/* Screen-reader heading that WordPress prints above the links. */
.tw-main .navigation .screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
}

/* ==========================================================================
   HINTS
   A "?" beside a term the shop has to use but a first-time buyer may not
   know. The text lives in the page rather than a title attribute, because
   a title never appears on a phone and is announced unreliably.
   ========================================================================== */

.tw-hint {
	position: relative;
	display: inline-flex;
	vertical-align: middle;
	margin-left: .3rem;
}

.tw-hint__btn {
	display: grid;
	place-items: center;
	width: 1.125rem;
	height: 1.125rem;
	padding: 0;
	border: 1px solid var(--rose-200);
	border-radius: 50%;
	background: var(--white);
	color: var(--rose-600);
	font-family: var(--font-body);
	font-size: .6875rem;
	font-weight: 700;
	line-height: 1;
	cursor: pointer;
	transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

/* The circle is small by design, so the tap area is extended past it. */
.tw-hint__btn::after {
	content: "";
	position: absolute;
	inset: -10px;
}

.tw-hint__btn:hover,
.tw-hint.is-on .tw-hint__btn {
	background: var(--rose-500);
	border-color: var(--rose-500);
	color: #fff;
}

.tw-hint__bubble {
	position: absolute;
	bottom: calc(100% + .5rem);
	left: 50%;
	z-index: 40;

	width: max-content;
	max-width: 16rem;
	padding: var(--sp-3);

	border-radius: var(--r-md);
	background: var(--ink);
	color: #fff;
	font-size: var(--fs-xs);
	font-weight: 400;
	line-height: 1.5;
	text-align: left;
	text-transform: none;
	letter-spacing: 0;
	box-shadow: var(--shadow-lg);

	opacity: 0;
	visibility: hidden;
	transform: translate(-50%, 4px);
	transition: opacity var(--dur-fast) var(--ease),
	            transform var(--dur-fast) var(--ease-out),
	            visibility var(--dur-fast);
}

.tw-hint.is-on .tw-hint__bubble {
	opacity: 1;
	visibility: visible;
	transform: translate(-50%, 0);
}

/* The little tail. */
.tw-hint__bubble::after {
	content: "";
	position: absolute;
	top: 100%;
	left: 50%;
	margin-left: -5px;
	border: 5px solid transparent;
	border-top-color: var(--ink);
}

/* Near the edge of a phone a centred bubble runs off the side: measured at
   390px it sat 21px past the left edge. Anchoring its right edge to the
   marker keeps it inside whichever side of the page the marker is on. */
@media (max-width: 720px) {
	/* A centred bubble runs off the side when its marker sits near an edge:
	   measured at 390px it was 21px past the left of the screen.

	   position: fixed was tried and removed. It reported a containing block
	   that was not the viewport, so the offsets landed the bubble below the
	   fold, and chasing that further was not worth the complexity for a
	   tooltip. The marker's own card is a reliable anchor instead: the
	   bubble stretches across it, which is always inside the screen.

	   The card needs a positioning context for this, given below. */
	.tw-hint { position: static; }

	.tw-hint__bubble {
		left: var(--sp-4);
		right: var(--sp-4);
		bottom: auto;
		top: auto;
		width: auto;
		max-width: none;
		transform: translateY(4px);
	}

	.tw-hint.is-on .tw-hint__bubble { transform: translateY(0); }

	/* Spanning the card, a tail pointing at the marker would be wrong more
	   often than right. */
	.tw-hint__bubble::after { display: none; }
}

/* Without the script nothing can open, so the explanation simply shows. */
html.no-js .tw-hint__bubble {
	position: static;
	opacity: 1;
	visibility: visible;
	transform: none;
	display: block;
	max-width: none;
	margin-top: .35rem;
	background: var(--blush-2);
	color: var(--ink-2);
	box-shadow: none;
}

html.no-js .tw-hint__btn { display: none; }
html.no-js .tw-hint__bubble::after { display: none; }
html.no-js .tw-hint { display: block; margin-left: 0; }

@media (prefers-reduced-motion: reduce) {
	.tw-hint__bubble { transition: none; }
}

/* ==========================================================================
   DEAL OF THE DAY
   A real sale price with the clock that ends it. The block is deliberately
   the loudest thing on the page below the hero, because it is the only part
   of it that expires.
   ========================================================================== */

.tw-deal__in {
	display: grid;
	grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr);
	gap: var(--sp-8);
	align-items: center;
	padding: var(--sp-7);
	border: 1px solid var(--rose-200);
	border-radius: var(--r-xl);
	background:
		radial-gradient(26rem 20rem at 10% 10%, var(--rose-100), transparent 60%),
		linear-gradient(145deg, var(--blush-2), var(--white) 72%);
	box-shadow: var(--shadow);
}

.tw-deal__art { position: relative; }

.tw-deal__img {
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	border-radius: var(--r-lg);
	background: var(--white);
}

.tw-deal__flag {
	position: absolute;
	top: var(--sp-3);
	left: var(--sp-3);
	padding: .35rem .8rem;
	border-radius: var(--r-pill);
	background: var(--rose-600);
	color: #fff;
	font-size: var(--fs-xs);
	font-weight: 700;
	letter-spacing: var(--ls-caps);
	text-transform: uppercase;
	box-shadow: var(--shadow-sm);
}

.tw-deal__eyebrow {
	display: inline-block;
	margin-bottom: var(--sp-3);
	padding: .3rem .75rem;
	border: 1px solid var(--rose-200);
	border-radius: var(--r-pill);
	background: var(--white);
	color: var(--rose-700);
	font-size: var(--fs-xs);
	font-weight: 700;
	letter-spacing: var(--ls-caps);
	text-transform: uppercase;
}

.tw-deal__title { margin: 0 0 var(--sp-4); font-size: var(--fs-2xl); line-height: 1.15; }
.tw-deal__title a { color: inherit; }
.tw-deal__title a:hover { color: var(--rose-700); }

.tw-deal__price {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: var(--sp-3);
	margin: 0 0 var(--sp-5);
}

.tw-deal__now .amount { font-size: var(--fs-3xl); font-weight: 700; color: var(--rose-700); }
.tw-deal__was { color: var(--ink-4); text-decoration-thickness: 1px; }

.tw-deal__save {
	padding: .2rem .6rem;
	border-radius: var(--r-pill);
	background: #e8f5ec;
	color: #1f7a3d;
	font-size: var(--fs-xs);
	font-weight: 700;
}

.tw-deal__note {
	margin: var(--sp-4) 0 var(--sp-5);
	color: var(--ink-4);
	font-size: var(--fs-sm);
	line-height: 1.6;
	max-width: 46ch;
}

/* ---- The clock ---------------------------------------------------------- */

.tw-count { display: flex; align-items: flex-start; gap: var(--sp-2); }

.tw-count__cell {
	display: grid;
	justify-items: center;
	gap: .25rem;
	min-width: 3.75rem;
	padding: var(--sp-3) var(--sp-2);
	border: 1px solid var(--line);
	border-radius: var(--r-md);
	background: var(--white);
	box-shadow: var(--shadow-sm);
}

.tw-count__cell strong {
	font-size: var(--fs-xl);
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	line-height: 1;
	color: var(--ink);
}

.tw-count__cell small {
	color: var(--ink-4);
	font-size: .625rem;
	font-weight: 600;
	letter-spacing: var(--ls-caps);
	text-transform: uppercase;
}

.tw-count__sep {
	align-self: center;
	padding-top: .35rem;
	color: var(--rose-300);
	font-size: var(--fs-lg);
	font-weight: 700;
}

/* Fixed-width digits, so a change from 09 to 10 cannot resize the cell and
   force the row to lay out again. */
.tw-count__cell strong { min-width: 2ch; text-align: center; }

/* ==========================================================================
   WHICH KIND SUITS YOU
   Four numbered cards. The number is the ordering device, so the cards need
   no icons competing with it.
   ========================================================================== */

.tw-pick__grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: var(--sp-4);
}

.tw-pick__card {
	position: relative;
	padding: var(--sp-6) var(--sp-5) var(--sp-5);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--white);
	transition: transform var(--dur) var(--ease-out),
	            box-shadow var(--dur) var(--ease-out),
	            border-color var(--dur) var(--ease);
}

.tw-pick__card:hover {
	transform: translateY(-4px);
	border-color: var(--rose-200);
	box-shadow: var(--shadow);
}

.tw-pick__n {
	display: block;
	margin-bottom: var(--sp-3);
	color: var(--rose-300);
	font-family: var(--font-display);
	font-size: var(--fs-2xl);
	font-weight: 700;
	line-height: 1;
	font-variant-numeric: tabular-nums;
}

.tw-pick__card h3 {
	margin: 0 0 var(--sp-2);
	font-family: var(--font-body);
	font-size: var(--fs-md);
	font-weight: 700;
}

.tw-pick__card p {
	margin: 0 0 var(--sp-4);
	color: var(--ink-3);
	font-size: var(--fs-sm);
	line-height: 1.6;
}

.tw-pick__card a {
	display: inline-flex;
	align-items: center;
	gap: .35rem;
	color: var(--rose-600);
	font-size: var(--fs-sm);
	font-weight: 600;
}

.tw-pick__card a:hover { color: var(--rose-700); }
.tw-pick__card a svg { transition: transform var(--dur-fast) var(--ease); }
.tw-pick__card a:hover svg { transform: translateX(3px); }

/* ==========================================================================
   MATERIALS
   A swatch, a name and three facts. The swatch carries the difference in
   finish that the words describe.
   ========================================================================== */

.tw-mat__grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--sp-5);
}

.tw-mat__card {
	padding: var(--sp-5);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background: var(--white);
}

.tw-mat__swatch {
	height: 5rem;
	margin-bottom: var(--sp-4);
	border-radius: var(--r-md);
	border: 1px solid var(--line);
}

/* Matte, slightly soft. */
.tw-mat__swatch--silicone {
	background: linear-gradient(135deg, #e8b4c4, #d16b8a 60%, #b8546f);
}

/* Hard and glossy: a tight highlight rather than a broad one. */
.tw-mat__swatch--abs {
	background:
		linear-gradient(110deg, transparent 38%, rgba(255,255,255,.75) 44%, transparent 50%),
		linear-gradient(135deg, #3a3238, #1f1a1d);
}

/* Metal: several narrow highlights. */
.tw-mat__swatch--steel {
	background:
		linear-gradient(100deg, transparent 20%, rgba(255,255,255,.6) 26%, transparent 32%,
		                        transparent 58%, rgba(255,255,255,.45) 64%, transparent 70%),
		linear-gradient(135deg, #b9bec4, #7d858d 55%, #a8aeb5);
}

.tw-mat__card h3 {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	margin: 0 0 var(--sp-3);
	font-family: var(--font-body);
	font-size: var(--fs-md);
	font-weight: 700;
}

.tw-mat__card ul { margin: 0; padding: 0; list-style: none; }

.tw-mat__card li {
	position: relative;
	margin: 0 0 .5rem;
	padding-left: 1.4rem;
	color: var(--ink-3);
	font-size: var(--fs-sm);
	line-height: 1.55;
}

.tw-mat__card li::before {
	content: "";
	position: absolute;
	left: 0;
	top: .45rem;
	width: .5rem;
	height: .5rem;
	border-radius: 50%;
	background: var(--rose-200);
}

.tw-mat__foot {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--sp-2);
	margin: var(--sp-6) 0 0;
	color: var(--ink-4);
	font-size: var(--fs-sm);
}

.tw-mat__foot svg { color: var(--rose-500); flex: none; }

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */

@media (max-width: 1100px) {
	.tw-pick__grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 980px) {
	.tw-deal__in { grid-template-columns: 1fr; padding: var(--sp-5); }
	.tw-deal__art { max-width: 22rem; }
	.tw-mat__grid { grid-template-columns: 1fr; }
}

@media (max-width: 600px) {
	.tw-pick__grid { grid-template-columns: 1fr; }
	.tw-count__cell { min-width: 3.25rem; padding: var(--sp-2); }
	.tw-count__cell strong { font-size: var(--fs-lg); }
	.tw-deal__now .amount { font-size: var(--fs-2xl); }
}

/* ==========================================================================
   MOTION AND EMPHASIS
   Ten movements and a set of accents. Every one is transform or opacity
   only, so none of them costs a layout pass, and every one is switched off
   under prefers-reduced-motion at the end of this block.
   ========================================================================== */

/* --- 1. Section headings draw a rule as they arrive ---------------------- */
.tw-head { position: relative; }

.tw-head::after {
	content: "";
	position: absolute;
	bottom: -.65rem;
	left: 0;
	width: 3.5rem;
	height: 2px;
	border-radius: 2px;
	background: linear-gradient(90deg, var(--rose-500), var(--rose-200));
	transform: scaleX(0);
	transform-origin: 0 50%;
	transition: transform 640ms var(--ease-out) 180ms;
}

.tw-head.is-in::after { transform: scaleX(1); }

/* Centred heads take a centred rule. */
.tw-head--center::after { left: 50%; transform: translateX(-50%) scaleX(0); transform-origin: 50% 50%; }
.tw-head--center.is-in::after { transform: translateX(-50%) scaleX(1); }

/* --- 2. Product cards lift and the image drifts ------------------------- */
.tw-card__media { overflow: hidden; }

.tw-card__media img {
	transition: transform 700ms var(--ease-out);
}

.tw-card:hover .tw-card__media img { transform: scale(1.06); }

/* --- 3. (A card sheen was tried here and removed: it repainted a full
   card-sized layer on every hover, and the image movement in 2 already
   carries the interaction.) --- */

/* --- 4. Category tiles deepen their wash -------------------------------- */
.tw-coll__item { position: relative; overflow: hidden; }

.tw-coll__item::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
	background: linear-gradient(180deg, transparent 45%, rgba(214,83,124,.22));
	opacity: 0;
	transition: opacity var(--dur) var(--ease);
}

.tw-coll__item:hover::before { opacity: 1; }

/* --- 5. Buttons take a soft press --------------------------------------- */
.tw-btn { transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease),
                      background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease); }
.tw-btn:hover { transform: translateY(-2px); }
.tw-btn:active { transform: translateY(0) scale(.985); }

/* --- 6. The primary button carries a moving highlight ------------------- */
.tw-btn--primary { position: relative; overflow: hidden; }

.tw-btn--primary::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(110deg, transparent 40%, rgba(255,255,255,.28) 50%, transparent 60%);
	transform: translateX(-100%);
	transition: transform 800ms var(--ease-out);
}

.tw-btn--primary:hover::after { transform: translateX(100%); }

/* --- 7. Figures count up into place ------------------------------------- */
.tw-figure__n {
	display: inline-block;
	opacity: 0;
	transform: translateY(12px);
	transition: opacity 560ms var(--ease-out), transform 560ms var(--ease-out);
}

.is-in .tw-figure__n { opacity: 1; transform: none; }

/* --- 8. The steps sequence draws its connecting line -------------------- */
.tw-steps__list { position: relative; }

@media (min-width: 1101px) {
	.tw-steps__list::before {
		content: "";
		position: absolute;
		top: 2.1rem;
		left: 12%;
		right: 12%;
		height: 2px;
		background: repeating-linear-gradient(90deg, var(--rose-200) 0 8px, transparent 8px 16px);
		transform: scaleX(0);
		transform-origin: 0 50%;
		transition: transform 900ms var(--ease-out) 200ms;
	}

	.tw-steps__list.is-in::before { transform: scaleX(1); }
}

/* --- 9. Icons in trust rows settle in ----------------------------------- */
.tw-trust__item svg,
.tw-promo-b__facts svg {
	transition: transform var(--dur) var(--ease-out);
}

.tw-trust__item:hover svg { transform: translateY(-3px) rotate(-4deg); }
.tw-promo-b__facts li:hover svg { transform: scale(1.12); }

/* --- 10. A quiet pulse on the deal badge, since it expires -------------- */
@media (prefers-reduced-motion: no-preference) {
	.tw-deal__flag { animation: tw-pulse 2.6s var(--ease) infinite; }
}

@keyframes tw-pulse {
	0%, 100% { transform: scale(1); box-shadow: var(--shadow-sm); }
	50%      { transform: scale(1.04); box-shadow: 0 6px 18px rgba(214,83,124,.35); }
}

/* ==========================================================================
   ACCENTS
   Small marks that give the page its landmarks without adding noise.
   ========================================================================== */

/* A. Section eyebrows get a leading dash. */
.tw-head__eyebrow { display: inline-flex; align-items: center; gap: .5rem; }
.tw-head__eyebrow::before {
	content: "";
	width: 1.25rem;
	height: 1px;
	background: var(--rose-400);
}

/* B. Alternating sections carry a faint corner wash, so the page has
      rhythm rather than a run of identical white bands. */
.tw-sec--blush { position: relative; }

.tw-sec--blush::before {
	content: "";
	position: absolute;
	top: 0;
	right: 0;
	width: 16rem;
	height: 16rem;
	border-radius: 50%;
	background: radial-gradient(circle, var(--rose-100), transparent 68%);
	opacity: .55;
	pointer-events: none;
}

/* C. Prices read as prices: tabular figures line up down a column. */
.price, .amount, .tw-card__price { font-variant-numeric: tabular-nums; }

/* D. Links in prose underline from the left on hover. */
.tw-prose a:not(.tw-btn) {
	background-image: linear-gradient(var(--rose-400), var(--rose-400));
	background-size: 0 1px;
	background-position: 0 100%;
	background-repeat: no-repeat;
	transition: background-size 320ms var(--ease-out);
	text-decoration: none;
}

.tw-prose a:not(.tw-btn):hover { background-size: 100% 1px; }

/* ==========================================================================
   All of the above, off.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
	.tw-head::after,
	.tw-head--center.is-in::after { transform: none; transition: none; }
	.tw-card__media img,
	.tw-card__media::after,
	.tw-btn,
	.tw-btn--primary::after,
	.tw-coll__item::before,
	.tw-figure__n,
	.tw-steps__list::before,
	.tw-trust__item svg,
	.tw-promo-b__facts svg,
	.tw-prose a:not(.tw-btn) { transition: none; }

	.tw-card:hover .tw-card__media img,
	.tw-btn:hover,
	.tw-btn:active { transform: none; }

	.tw-deal__flag { animation: none; }
	.tw-figure__n { opacity: 1; transform: none; }
	.tw-steps__list::before { transform: scaleX(1); }
}

/* The hint bubble is positioned against the nearest positioned ancestor. On
   a phone that has to be the card, so these get a context of their own. */
@media (max-width: 720px) {
	.tw-mat__card,
	.tw-pick__card,
	.tw-prof__card,
	.woocommerce th,
	.woocommerce label { position: relative; }
}

/* ==========================================================================
   CHECKOUT ON A PHONE: THE TWO BLOCKS MUST NOT SHARE A ROW
   The desktop layout spans the form down both grid rows so it stays level
   with the order summary beside it. Those rules were written without a
   media query and appear after the mobile reset, so they won on a phone
   too: the form took rows 1-2 and the summary took row 2, and the order
   totals were drawn straight over the billing fields.

   Stated last, so nothing later can put them back on the same row.
   ========================================================================== */

@media (max-width: 900px) {
	.woocommerce-checkout form.checkout {
		display: block;
	}

	/* display:block removes the grid entirely, so the placement properties
	   have nothing to act on and the blocks simply stack in source order.
	   Safer than chasing each grid-row rule as more are added. */
	.woocommerce-checkout form.checkout > #customer_details,
	.woocommerce-checkout form.checkout > h3#order_review_heading,
	.woocommerce-checkout form.checkout > #order_review {
		grid-row: auto;
		grid-column: auto;
		width: auto;
		float: none;
	}

	.woocommerce-checkout form.checkout > h3#order_review_heading {
		margin: var(--sp-7) 0 var(--sp-4);
	}

	.woocommerce-checkout .woocommerce-checkout-review-order {
		position: static;
	}

	/* A field pair that is half-width on a desktop is full width here. */
	.woocommerce-checkout form .form-row-first,
	.woocommerce-checkout form .form-row-last {
		width: 100%;
		margin-right: 0;
		display: block;
	}

	/* The order table is a six-column layout on a desktop; on a phone the
	   product name needs the room and the price sits against it. */
	.woocommerce-checkout #order_review table.shop_table th,
	.woocommerce-checkout #order_review table.shop_table td {
		padding-block: var(--sp-3);
		font-size: var(--fs-sm);
	}

	.woocommerce-checkout #order_review table.shop_table td.product-name {
		padding-right: var(--sp-3);
	}

	/* Place order is the last thing on the page, so it gets room. */
	.woocommerce-checkout #payment #place_order {
		width: 100%;
		margin-top: var(--sp-2);
	}
}

/* ==========================================================================
   CHECKOUT DETAILS ON A PHONE
   Three things the stacked layout exposed, measured at 390px.
   ========================================================================== */

@media (max-width: 900px) {
	/* 1. The state dropdown is a select2 widget, which WooCommerce styles
	      for its own theme: the chosen value sat on the element's baseline
	      and printed over the bottom border. */
	.woocommerce-checkout .select2-container .select2-selection--single {
		height: auto;
		min-height: 3rem;
		padding: 0;
		border: 1px solid var(--line);
		border-radius: var(--r-md);
		background: var(--white);
	}

	.woocommerce-checkout .select2-container--default .select2-selection--single .select2-selection__rendered {
		display: flex;
		align-items: center;
		height: 3rem;
		padding: 0 2.25rem 0 .9rem;
		line-height: 1.2;
		color: var(--ink-2);
	}

	.woocommerce-checkout .select2-container--default .select2-selection--single .select2-selection__arrow {
		top: 0;
		right: .6rem;
		height: 3rem;
	}

	/* 2. The shipping method is a single option, so WooCommerce's list
	      marker is a bullet in front of one line of text. */
	.woocommerce-checkout #shipping_method {
		margin: 0;
		padding: 0;
		list-style: none;
		text-align: right;
	}

	.woocommerce-checkout #shipping_method li {
		margin: 0;
		padding: 0;
		list-style: none;
	}

	.woocommerce-checkout #shipping_method li::marker { content: ""; }

	/* 3. Five card marks plus the label do not fit on one 390px line, so
	      the last one dropped alone onto a second row and looked broken.
	      The gateway prints them as bare <img> siblings of the text, so
	      they cannot be wrapped in a container: they are made to wrap as a
	      group by giving the label a line of its own and letting the marks
	      run underneath it, evenly, at a size that fits five across. */
	/* The label was only 123px wide inside a 358px row: its parent is a
	   flex container shared with the radio, and the label was not allowed
	   to grow. Its own content needs 245px, which is why the fifth mark
	   dropped. Letting it take the remaining width fits all five. */
	.woocommerce-checkout ul.payment_methods li {
		display: flex;
		align-items: flex-start;
		gap: var(--sp-2);
		flex-wrap: nowrap;
	}

	.woocommerce-checkout ul.payment_methods li > input[type="radio"] {
		flex: none;
		margin-top: .35rem;
	}

	.woocommerce-checkout ul.payment_methods li label {
		display: block;
		flex: 1 1 auto;
		min-width: 0;
		line-height: 1.5;
	}

	/* Even at full width the text plus five marks needs more than one line,
	   so the marks are given their own. The first one starts the new line;
	   the rest follow it. */
	.woocommerce-checkout ul.payment_methods li label .mecom-paypal-payment-icon:first-of-type {
		margin-left: 0;
		clear: both;
	}

	.woocommerce-checkout ul.payment_methods li label img.mecom-paypal-payment-icon {
		display: inline-block;
		vertical-align: middle;
		max-height: 1.4rem;
		width: auto;
		margin: var(--sp-2) .3rem 0 0;
	}

	/* The marks are wrapped in .tw-paymarks by ui.js, because the gateway
	   prints them as bare siblings of the label text and a replaced element
	   cannot carry generated content to break the line. */
	.woocommerce-checkout ul.payment_methods li label .tw-paymarks {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		gap: .3rem;
		margin-top: var(--sp-2);
	}

	.woocommerce-checkout ul.payment_methods li label .tw-paymarks img {
		margin: 0;
	}
}

/* ==========================================================================
   PRODUCT COLUMNS AT MID WIDTHS
   Between roughly 1000px and 1280px the two columns of the product header
   ended at different heights: the gallery stopped under its thumbnails
   while the summary ran on, and neither reached the rule above the tabs.
   The result was a block of empty page on the right, which is what looks
   broken in the middle of the layout.

   The row is given a single height so the two columns finish together, and
   the gap before the tabs is closed to what the rest of the page uses.
   ========================================================================== */

@media (min-width: 901px) {
	.woocommerce div.product {
		/* The header row takes the height of its taller column; everything
		   below it keeps its own height. */
		grid-auto-rows: min-content;
		align-items: stretch;
	}

	/* The gallery is shorter than the summary beside it. Stretching it to
	   match was tried and made things worse: the main image grew past the
	   summary and overlapped the tabs by 24px.

	   The columns are left at their natural heights, which is correct for a
	   gallery, and the row simply ends where the taller one does. What made
	   the difference look like a fault was the run-in to the tabs below,
	   handled next. */
	.woocommerce div.product .woocommerce-product-gallery,
	.woocommerce div.product .summary {
		align-self: start;
	}

	/* The tabs sat a full section's distance below the shorter column,
	   which read as a hole in the page rather than as spacing. The rule
	   above them is what the eye follows, so it is brought up to a normal
	   separation from whichever column ends last. */
	.woocommerce div.product .woocommerce-tabs {
		margin-top: var(--sp-5);
		padding-top: var(--sp-5);
	}
}

/* Below 1280px the summary column was the one running long, because the
   assurance panel wraps. Giving it a slightly larger share evens the two
   columns out across the range where the gap was visible. */
@media (min-width: 901px) and (max-width: 1400px) {
	/* The product images are square, so the gallery's height follows its
	   column width: at a 1fr/1fr split the image could only be 508px tall
	   against a 900px summary. A wider gallery column makes the image
	   taller, which is the only thing that closes the difference without
	   distorting the photograph or padding the page with filler. */
	.woocommerce div.product {
		grid-template-columns: minmax(0, 1.35fr) minmax(300px, 1fr);
		gap: var(--sp-6);
	}
}

/* Below about 1050px the summary cannot give up any more width without its
   buttons wrapping, so the gallery stops growing and the columns drift
   apart again: 388px at 960px. They stack from here, which is what the
   phone layout already does and reads better than a tall column beside a
   short one.

   Declared last so it wins over the 901-1400px rule above, which covers
   this range too. */
@media (min-width: 901px) and (max-width: 1050px) {
	.woocommerce div.product {
		grid-template-columns: 1fr !important;
		gap: var(--sp-6);
	}

	.woocommerce div.product .woocommerce-product-gallery {
		position: static;
		max-width: 30rem;
		margin-inline: auto;
	}
}

/* ==========================================================================
   PRODUCT COLUMNS: CLOSING THE GAP FROM THE OTHER SIDE
   The gallery column ends 200-300px above the summary beside it, leaving a
   block of blank page on the left at widths between about 1000px and 1400px.

   Three approaches were tried and reverted: stretching the gallery (the main
   image grew past the summary and overlapped the tabs), and putting a panel
   in the space (WooCommerce offers no hook that lands under the gallery in
   the same grid row, so it ended up off-screen, then in the wrong column,
   then in a new row that pushed the tabs 478px away).

   The difference is closed by tightening the summary instead, which is where
   the excess height actually is: the assurance rows carry a section's worth
   of padding for three short lines.
   ========================================================================== */

@media (min-width: 901px) and (max-width: 1400px) {
	.woocommerce div.product .summary .tw-assure {
		margin-top: var(--sp-4);
	}

	/* The product meta is reference information, not something to read, so
	   it sits closer to what it belongs to. */
	.woocommerce div.product .summary .product_meta {
		margin-top: var(--sp-4);
		padding-top: var(--sp-4);
	}

	/* And the tabs follow whichever column ends last at a normal distance
	   rather than a section's worth of space. */
	.woocommerce div.product .woocommerce-tabs {
		margin-top: var(--sp-4);
		padding-top: var(--sp-5);
		border-top: 1px solid var(--line);
	}
}


/* ==========================================================================
   PRODUCT TABS
   Three selections in one block. Replaces three stacked rows that put 28
   cards on the page; the hidden panels are display:none, so only the visible
   eight cost anything to lay out.
   ========================================================================== */

.tw-ptabs__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: var(--sp-4);
	margin-bottom: var(--sp-5);
	padding-bottom: var(--sp-4);
	border-bottom: 1px solid var(--line);
}

.tw-ptabs__title { margin: 0; font-size: var(--fs-3xl); }

.tw-ptabs__tabs {
	display: flex;
	gap: .35rem;
	padding: .3rem;
	border: 1px solid var(--line);
	border-radius: var(--r-pill);
	background: var(--white);
}

.tw-ptabs__tab {
	padding: .55rem 1.1rem;
	border: 0;
	border-radius: var(--r-pill);
	background: none;
	color: var(--ink-3);
	font-family: inherit;
	font-size: var(--fs-sm);
	font-weight: 600;
	white-space: nowrap;
	cursor: pointer;
	transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.tw-ptabs__tab:hover { color: var(--rose-700); }

.tw-ptabs__tab.is-on {
	background: var(--rose-500);
	color: #fff;
	box-shadow: var(--shadow-sm);
}

.tw-ptabs__sub {
	margin: 0 0 var(--sp-5);
	max-width: 58ch;
	color: var(--ink-3);
	font-size: var(--fs-sm);
	line-height: 1.6;
}

/* The panel fades in rather than appearing, so a tab change reads as a
   change of content rather than as the page jumping. */
.tw-ptabs__panel[hidden] { display: none; }

@media (prefers-reduced-motion: no-preference) {
	.tw-ptabs__panel.is-on { animation: tw-panel-in 320ms var(--ease-out); }
}

@keyframes tw-panel-in {
	from { opacity: 0; transform: translateY(6px); }
	to   { opacity: 1; transform: none; }
}

.tw-ptabs__all { margin: var(--sp-5) 0 0; text-align: center; }

.tw-ptabs__all a {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-2);
	color: var(--rose-600);
	font-size: var(--fs-sm);
	font-weight: 600;
}

.tw-ptabs__all a:hover { color: var(--rose-700); }
.tw-ptabs__all svg { transition: transform var(--dur-fast) var(--ease); }
.tw-ptabs__all a:hover svg { transform: translateX(3px); }

@media (max-width: 780px) {
	.tw-ptabs__head { flex-direction: column; align-items: flex-start; }

	/* The three tabs do not fit across a phone, so the row scrolls rather
	   than wrapping into a second line of pills. */
	.tw-ptabs__tabs {
		width: 100%;
		overflow-x: auto;
		scrollbar-width: none;
	}

	.tw-ptabs__tabs::-webkit-scrollbar { display: none; }
	.tw-ptabs__tab { flex: none; }
	.tw-ptabs__title { font-size: var(--fs-2xl); }
}

/* ==========================================================================
   RECENTLY VIEWED
   Quieter than the other product rows: it is a convenience, not a pitch.
   ========================================================================== */

.tw-recent__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: var(--sp-3);
	margin-bottom: var(--sp-5);
	padding-bottom: var(--sp-3);
	border-bottom: 1px solid var(--line);
}

.tw-recent__title {
	margin: 0;
	font-size: var(--fs-xl);
}

.tw-recent__note {
	margin: 0;
	color: var(--ink-4);
	font-size: var(--fs-xs);
}

/* ==========================================================================
   PRODUCT CARDS AT TWO ACROSS
   The column count itself is set in responsive.css, which loads last. These
   are the adjustments a 175px card needs.
   ========================================================================== */

@media (max-width: 420px) {
	.tw-card__desc { display: none; }
	.tw-card__name { font-size: var(--fs-sm); line-height: 1.35; }
	.tw-card__cat { font-size: .625rem; }
	.tw-card__add { right: var(--sp-2); bottom: var(--sp-2); }

	.woocommerce-shop .tw-card__desc,
	.tax-product_cat .tw-card__desc { display: block; }
}


/* ==========================================================================
   HERO DETAIL
   The hero had a headline, two buttons and a photograph. These are the small
   commercial details around them: what the picture costs, what makes it
   worth trusting, and where you are in the sequence.
   ========================================================================== */

/* The card holds the image and everything pinned to it. */
.tw-slide__card {
	position: relative;
	border-radius: var(--r-xl);
	overflow: visible;
}

.tw-slide__card .tw-slide__img {
	display: block;
	width: 100%;
	border-radius: var(--r-xl);
}

/* --- Badge -------------------------------------------------------------- */

.tw-slide__badge {
	position: absolute;
	top: var(--sp-4);
	left: var(--sp-4);
	z-index: 2;

	padding: .4rem .85rem;
	border-radius: var(--r-pill);
	background: var(--rose-600);
	color: #fff;
	font-size: var(--fs-xs);
	font-weight: 700;
	letter-spacing: var(--ls-caps);
	text-transform: uppercase;
	white-space: nowrap;
	box-shadow: 0 4px 14px rgba(178, 58, 96, .28);
}

/* --- Price tag ---------------------------------------------------------- */

.tw-slide__tag {
	position: absolute;
	right: var(--sp-4);
	bottom: var(--sp-4);
	z-index: 2;

	display: grid;
	gap: .1rem;
	max-width: 62%;
	padding: .7rem 1rem;

	border: 1px solid var(--rose-100);
	border-radius: var(--r-lg);
	background: color-mix(in srgb, var(--white) 92%, transparent);
	-webkit-backdrop-filter: blur(10px);
	        backdrop-filter: blur(10px);
	box-shadow: var(--shadow);

	color: var(--ink);
	text-align: right;
	transition: transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease);
}

.tw-slide__tag:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); }

.tw-slide__tag-name {
	color: var(--ink-4);
	font-size: var(--fs-xs);
	line-height: 1.3;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.tw-slide__tag-price {
	font-size: var(--fs-md);
	font-weight: 700;
	font-variant-numeric: tabular-nums;
}

.tw-slide__tag-price .amount { color: var(--ink); }
.tw-slide__tag-price del { display: none; }

/* --- Decorative shapes -------------------------------------------------- */

.tw-slide__blob {
	position: absolute;
	z-index: 0;
	border-radius: 50%;
	pointer-events: none;
}

.tw-slide__blob--a {
	top: -3.5rem;
	right: -2.5rem;
	width: 12rem;
	height: 12rem;
	background: radial-gradient(circle, var(--rose-200), transparent 66%);
	opacity: .5;
}

.tw-slide__blob--b {
	bottom: -3rem;
	left: -3rem;
	width: 9rem;
	height: 9rem;
	background: radial-gradient(circle, var(--blush-3), transparent 70%);
	opacity: .65;
}

/* --- Trust markers ------------------------------------------------------ */

.tw-hero__marks {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-3) var(--sp-5);
	margin: var(--sp-5) 0 0;
	padding: 0;
	list-style: none;
}

.tw-hero__marks li {
	display: inline-flex;
	align-items: center;
	gap: .4rem;
	margin: 0;
	color: var(--ink-4);
	font-size: var(--fs-xs);
	font-weight: 500;
	white-space: nowrap;
}

.tw-hero__marks svg { color: var(--rose-400); flex: none; }

/* --- Slide counter ------------------------------------------------------ */

.tw-hero__count {
	display: inline-flex;
	align-items: baseline;
	gap: .2rem;
	margin-right: var(--sp-3);
	color: var(--ink-4);
	font-size: var(--fs-xs);
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	letter-spacing: .04em;
}

.tw-hero__count strong {
	color: var(--ink);
	font-size: var(--fs-sm);
	font-weight: 700;
}

@media (max-width: 900px) {
	.tw-slide__tag { max-width: 70%; padding: .55rem .8rem; }
	.tw-slide__blob--a { width: 8rem; height: 8rem; top: -2rem; right: -1.5rem; }
	.tw-slide__blob--b { display: none; }
	.tw-hero__marks { gap: var(--sp-2) var(--sp-4); }
}

@media (max-width: 560px) {
	/* Four markers wrap to three lines at this width; two columns keeps them
	   to two and stays readable. */
	.tw-hero__marks {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: var(--sp-2);
	}

	.tw-hero__marks li { font-size: .6875rem; }
	.tw-slide__badge { font-size: .625rem; padding: .3rem .65rem; }
}

/* ==========================================================================
   HERO COMPOSITION
   Measured at 1440x950 the hero ran to 1017px, so its own controls sat below
   the fold: the trust markers had a 195px gap above them and the slide
   counter was at y=1046 on a 950px screen. Everything after the slider was
   stacking in its own row rather than sitting under the copy it belongs to.
   ========================================================================== */

@media (min-width: 901px) {
	/* The slider spans both columns as one grid row, so the markers, the
	   reassurance strip and the arrows are rows of their own beneath it
	   rather than items in the copy column. They are held to the copy
	   column's width so they line up with the headline above.

	   The apparent gap between the buttons and the markers is the bottom of
	   the photograph, which is taller than the copy beside it. That is the
	   layout working, not a spacing fault: closing it would mean cropping
	   the product. */
	.tw-hero__marks,
	.tw-hero__assure,
	.tw-hero__nav {
		grid-column: 1;
		max-width: 34rem;
	}

	/* The buttons and the markers are one group: 147px of air between them
	   read as a gap rather than as spacing. */
	.tw-hero__marks { margin-top: var(--sp-3); }

	.tw-hero__assure {
		width: 100%;
		max-width: 34rem;
		margin-top: var(--sp-3);
		padding-top: var(--sp-3);
	}

	/* The controls have to stay on the first screen: at 950px they were
	   landing at 972. */
	.tw-hero__nav { margin-top: var(--sp-3); }

	/* The slider spans both columns and its height is set by the taller of
	   the two, so the art no longer stretches the section on its own. */
	.tw-hero__in {
		row-gap: 0;
		align-items: start;
		/* 1017px was taller than the screen it opens on. */
		padding-block: var(--sp-5) var(--sp-6);
	}

	/* The photograph sets the height of the row; the copy column is shorter
	   and was being padded out to match. */
	.tw-slide { align-items: center; }

	/* The art column was 600px against a 480px card, leaving 120px of empty
	   pink under the photograph. The column takes the card's height. */
	.tw-slide__art { height: auto; aspect-ratio: auto; }

	/* Four markers on one line: at 34rem they wrapped onto two, which put
	   another 32px between the buttons and the strip below. */
	.tw-hero__marks {
		max-width: none;
		gap: var(--sp-2) var(--sp-4);
	}

	.tw-hero__marks li { font-size: .6875rem; }
}

/* The price tag was overhanging the photograph by a few pixels because the
   card had no clipping and the tag sat at the very edge. */
.tw-slide__card { overflow: hidden; }
.tw-slide__tag { right: var(--sp-3); bottom: var(--sp-3); }

/* A card with overflow hidden clips the badge shadow too, which is fine, but
   the blobs behind it must stay outside the clip. */
.tw-slide__art { overflow: visible; }

/* ===== assets/responsive.css ===== */
/* ==========================================================================
   TEEMCW — RESPONSIVE
   Loaded last. Four breakpoints, plus touch and print.

     1100  small laptop / tablet landscape
      900  tablet portrait
      680  large phones
      420  small phones
   ========================================================================== */

/* --------------------------------------------------------------------------
   Touch
   -------------------------------------------------------------------------- */

@media (hover: none) and (pointer: coarse) {
	/* Card actions never get a hover on touch, so show them. */
	.tw-card__wish,
	.tw-card__add {
		opacity: 1;
		transform: none;
	}

	/* 44px is the smallest reliably tappable target. The visible controls are
	   smaller by design, so the hit area is extended past them instead. */
	.tw-card__wish::after,
	.tw-card__add::after,
	.tw-icon-btn::after {
		content: "";
		position: absolute;
		inset: -7px;
	}

	.tw-card__img--hover { display: none; }
}

/* --------------------------------------------------------------------------
   1100
   -------------------------------------------------------------------------- */

@media (max-width: 1100px) {
	.tw-grid,
	.woocommerce ul.products { grid-template-columns: repeat(3, minmax(0, 1fr)); }

	.tw-coll { grid-template-columns: repeat(2, 1fr); }

	.tw-trust { grid-template-columns: repeat(3, 1fr); }

	.woocommerce div.product {
		grid-template-columns: minmax(0, 1fr) minmax(300px, .9fr);
		gap: var(--sp-6);
	}

	.tw-ft__cols { grid-template-columns: 1.4fr repeat(3, 1fr); }
	.tw-ft__contact { grid-column: span 3; }
}

/* --------------------------------------------------------------------------
   900
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
	/* Primary nav collapses into the drawer. */
	.tw-hd__nav { display: none; }
	.tw-hd__burger { display: inline-flex; align-items: center; justify-content: center;
		width: 2.5rem; height: 2.5rem; padding: 0; border: 0; border-radius: var(--r-pill);
		background: transparent; color: var(--ink); cursor: pointer; }
	.tw-hd__burger:hover { background: var(--blush-2); }

	.tw-hd__in { grid-template-columns: auto 1fr auto; }
	.tw-hd__brand { justify-self: center; }

	.tw-hero__in {
		grid-template-columns: 1fr;
		gap: var(--sp-7);
		padding-block: var(--sp-8);
	}

	.tw-hero__title { max-width: none; }

	.tw-story__in { grid-template-columns: 1fr; gap: var(--sp-6); }

	.tw-revs { grid-template-columns: 1fr; }

	.tw-news__in { grid-template-columns: 1fr; gap: var(--sp-5); }

	/* Single product stacks; the gallery stops sticking. */
	.woocommerce div.product { grid-template-columns: 1fr; }
	.woocommerce div.product .woocommerce-product-gallery {
		position: static;
		max-width: 34rem;
		margin-inline: auto;
	}

	/* Cart and checkout: the summary drops under the form. */
	.woocommerce-cart .woocommerce,
	.woocommerce-checkout form.checkout { grid-template-columns: 1fr; }
	.woocommerce-cart form.woocommerce-cart-form,
	.woocommerce-cart .cart-collaterals,
	.woocommerce-checkout #customer_details,
	.woocommerce-checkout .woocommerce-checkout-review-order { grid-column: 1; }
	.woocommerce-cart .cart-collaterals .cart_totals,
	.woocommerce-checkout .woocommerce-checkout-review-order { position: static; }

	/* Account navigation becomes a scrolling strip. */
	.woocommerce-account .woocommerce { grid-template-columns: 1fr; }
	.woocommerce-account .woocommerce-MyAccount-navigation ul {
		display: flex;
		overflow-x: auto;
		scrollbar-width: none;
	}
	.woocommerce-account .woocommerce-MyAccount-navigation ul::-webkit-scrollbar { display: none; }
	.woocommerce-account .woocommerce-MyAccount-navigation li {
		border-bottom: 0;
		border-right: 1px solid var(--line);
		flex: none;
	}
	.woocommerce-account .woocommerce-MyAccount-navigation li a { white-space: nowrap; }

	/* The filter drawer replaces a sidebar. */
	.tw-toolbar__filter { display: inline-flex; }
}

/* --------------------------------------------------------------------------
   680
   -------------------------------------------------------------------------- */

@media (max-width: 680px) {
	.tw-grid,
	.woocommerce ul.products { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-4); }

	.tw-coll { grid-template-columns: 1fr; }

	.tw-trust { grid-template-columns: 1fr; gap: var(--sp-4); }

	.tw-story__points { grid-template-columns: 1fr; }

	.tw-hero__cta { display: grid; }
	.tw-hero__cta .tw-btn { width: 100%; }

	.tw-hero__points { gap: var(--sp-3) var(--sp-4); }

	.tw-head { flex-direction: column; align-items: flex-start; gap: var(--sp-3); }

	.tw-news__form { grid-template-columns: 1fr; }

	.tw-ft__cols { grid-template-columns: repeat(2, 1fr); }
	.tw-ft__brand { grid-column: 1 / -1; }
	.tw-ft__contact { grid-column: 1 / -1; }

	.tw-ft__legal-in,
	.tw-ft__trust-in { flex-direction: column; align-items: flex-start; }

	/* Card details tighten rather than disappear. */
	.tw-card__desc { display: none; }
	.tw-card__add { opacity: 1; transform: none; }

	/* The cart table is unusable as a table on a phone: each row becomes a
	   card. The remove control stays visible, because hiding it would leave a
	   phone shopper unable to take anything out of the bag. */
	.woocommerce-cart table.shop_table thead { display: none; }

	.woocommerce-cart table.shop_table tbody tr.cart_item {
		display: grid;
		grid-template-columns: 68px 1fr auto;
		grid-template-areas:
			"thumb name  remove"
			"thumb qty   total";
		gap: var(--sp-2) var(--sp-3);
		padding: var(--sp-4);
		border-top: 1px solid var(--line);
		align-items: start;
	}

	.woocommerce-cart table.shop_table tbody tr.cart_item td {
		border: 0;
		padding: 0;
	}

	.woocommerce-cart td.product-thumbnail { grid-area: thumb; }
	.woocommerce-cart td.product-name      { grid-area: name; }
	.woocommerce-cart td.product-remove    { grid-area: remove; }
	.woocommerce-cart td.product-quantity   { grid-area: qty; }
	.woocommerce-cart td.product-subtotal   { grid-area: total; font-weight: 700; text-align: right; }

	/* Unit price is redundant beside the line total. */
	.woocommerce-cart td.product-price { display: none; }

	.woocommerce-cart table.shop_table img { width: 68px !important; }

	.woocommerce-cart table.shop_table tr:not(.cart_item) td.actions {
		display: block;
		padding: var(--sp-4);
	}
	.woocommerce-cart .coupon { display: grid; gap: var(--sp-2); }
	.woocommerce-cart .coupon input#coupon_code,
	.woocommerce-cart .coupon button,
	.woocommerce-cart button[name="update_cart"] { width: 100%; }

	.woocommerce div.product form.cart { flex-direction: column; }
	.woocommerce div.product form.cart .quantity { align-self: flex-start; }
	.woocommerce div.product form.cart button.single_add_to_cart_button { width: 100%; }

	.tw-search__form input[type="search"] { font-size: var(--fs-lg); }
}

/* --------------------------------------------------------------------------
   420
   -------------------------------------------------------------------------- */

@media (max-width: 420px) {
	/* Two across, not one. Eight cards in a single column made the home
	   page tab block 4801px tall at 390px wide, which is five screens of
	   scrolling for one section. At two across a card is still 175px, wide
	   enough for the photograph to read. */
	.tw-grid,
	.woocommerce ul.products {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: var(--sp-3);
	}

	/* The shop archive stays one across: there the description is the point
	   of the listing rather than decoration on a highlight row. */
	.woocommerce-shop .woocommerce ul.products,
	.tax-product_cat .woocommerce ul.products { grid-template-columns: 1fr; }

	.tw-ft__cols { grid-template-columns: 1fr; }

	.tw-hero__title { font-size: clamp(1.9rem, 9vw, 2.4rem); }

	.woocommerce div.product .flex-control-thumbs { grid-template-columns: repeat(4, 1fr); }
}

/* --------------------------------------------------------------------------
   Short landscape
   -------------------------------------------------------------------------- */

@media (max-height: 560px) and (orientation: landscape) {
	.tw-hero__in { padding-block: var(--sp-6); }
	.woocommerce div.product .woocommerce-product-gallery,
	.woocommerce-checkout .woocommerce-checkout-review-order,
	.woocommerce-cart .cart-collaterals .cart_totals { position: static; }
}

/* --------------------------------------------------------------------------
   Print
   -------------------------------------------------------------------------- */

@media print {
	.tw-ann, .tw-hd, .tw-mob, .tw-search, .tw-toast,
	.tw-ft__main, .tw-ft__trust, .tw-news, .tw-card__wish, .tw-card__add {
		display: none !important;
	}

	body { background: #fff; color: #000; }
	.woocommerce-order { max-width: none; }
	a[href]::after { content: " (" attr(href) ")"; font-size: .8em; color: #555; }
}

/* --------------------------------------------------------------------------
   HERO CAROUSEL, PROMO, DRAWER
   Appended after the base breakpoints so these win where they overlap.
   -------------------------------------------------------------------------- */

@media (max-width: 1100px) {
	.tw-promo__list { grid-template-columns: 1fr; }
	.tw-promo__link { padding: var(--sp-3) var(--sp-4); }
}

@media (max-width: 900px) {
	.tw-slide {
		grid-template-columns: 1fr;
		gap: var(--sp-6);
	}

	/* Image first on a phone: it is what sells the slide. */
	.tw-slide__art {
		order: -1;
		max-width: 26rem;
		margin-inline: auto;
		aspect-ratio: 4 / 3;
	}

	.tw-hero__stage { min-height: auto; }
	.tw-hero__in { padding-block: var(--sp-7) var(--sp-6); }

	.tw-hero__nav { justify-content: center; }

	/* The tool cluster loses its container so the header fits. */
	.tw-hd__tools {
		padding: 0;
		border: 0;
		background: transparent;
	}
}

@media (max-width: 680px) {
	.tw-hero__title { font-size: clamp(1.9rem, 8.5vw, 2.6rem); }
	.tw-hero__sub { font-size: var(--fs-md); }

	.tw-hero__points {
		gap: var(--sp-2) var(--sp-4);
		font-size: var(--fs-xs);
	}

	.tw-promo__cta { display: none; }

	.tw-drawer__panel { width: 100%; }

	.tw-dline { grid-template-columns: 56px 1fr; }
	.tw-dline__media img { width: 56px; height: 56px; }

	.tw-loader__logo { width: 120px; }
}

/* Parallax costs more than it gives on a phone, and the hero image is already
   the tallest thing on screen. */
@media (max-width: 900px) {
	[data-parallax] { transform: none !important; }
}

/* On a touch device the card actions are always visible, so the media does
   not need a hover lift that can never fire. */
@media (hover: none) {
	.tw-card:hover .tw-card__media { transform: none; }
}

/* --------------------------------------------------------------------------
   MEGA MENU, STICKY STORY, FIGURES
   skill.md 21: mobile is not a shrunken desktop.
   -------------------------------------------------------------------------- */

@media (max-width: 1100px) {
	.tw-mega__in { grid-template-columns: 1.6fr 1fr; }
	.tw-mega__feature { display: none; }
	.tw-figures__in { grid-template-columns: repeat(2, 1fr); gap: var(--sp-6) var(--sp-4); }
}

@media (max-width: 900px) {
	/* The primary nav is in the drawer below this width, so the panel that
	   hangs off it never renders. */
	.tw-mega { display: none; }

	.tw-story__in { grid-template-columns: 1fr; gap: var(--sp-6); }
	.tw-story__stick { position: static; }
	.tw-story__steps { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 680px) {
	.tw-story__steps { grid-template-columns: 1fr; }
	.tw-step { padding: var(--sp-5); }

	.tw-figures__in { grid-template-columns: repeat(2, 1fr); }

	.tw-eta { align-items: flex-start; }
	.tw-eta strong { white-space: normal; }
}

@media (max-width: 420px) {
	.tw-figures__in { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   HEADER AND HERO AT NARROWER WIDTHS
   -------------------------------------------------------------------------- */

@media (max-width: 1200px) {
	/* Tighten the nav before anything else has to give. */
	.tw-nav { gap: var(--sp-1); }
	.tw-nav > li > a { padding-inline: .6rem; font-size: var(--fs-sm); }
}

@media (max-width: 1000px) {
	.tw-hd__in { grid-template-columns: minmax(8rem, auto) minmax(0, 1fr) auto; }
	.tw-nav > li > a { padding-inline: .45rem; }
}

@media (max-width: 900px) {
	/* Nav moves into the drawer, so the logo takes the middle and the reserved
	   track is no longer needed. */
	.tw-hd__in { grid-template-columns: auto 1fr auto; }

	.tw-hero__title { font-size: clamp(1.9rem, 1.2rem + 3.4vw, 2.75rem); max-width: none; }
	.tw-slide__art { max-width: 24rem; margin-inline: auto; aspect-ratio: 1 / 1; }
	.tw-hero__points { margin-top: var(--sp-4); }
}

@media (max-width: 680px) {
	.tw-hero__title { font-size: clamp(1.75rem, 1.1rem + 4vw, 2.25rem); }
	.tw-hero__sub { font-size: var(--fs-base); }
	.tw-slide__art { max-width: 20rem; }

	/* On a phone the hairline does more work than the tint. */
	.tw-sec + .tw-sec { border-top: 1px solid var(--line); }
}

/* ==========================================================================
   RESPONSIVE, SECOND PASS
   Gaps found by auditing every multi-column grid and every interactive
   element against the real stylesheet rather than by eye.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Touch targets
   WCAG 2.5.8 asks for 24px minimum, and 44px is what a thumb actually needs.
   These controls are small by design, so the hit area is extended past the
   painted box instead of inflating the visual.
   -------------------------------------------------------------------------- */

@media (hover: none) and (pointer: coarse) {
	.woocommerce a.remove,
	.tw-qty-btn,
	.tw-dline__remove,
	.tw-hero__dot,
	.tw-hero__arrow {
		position: relative;
	}

	/* Removing an item from the bag is the control people miss most often on
	   a phone, and it is the smallest one on the page. */
	.woocommerce a.remove::after,
	.tw-dline__remove::after {
		content: "";
		position: absolute;
		inset: -9px;
	}

	.tw-qty-btn::after {
		content: "";
		position: absolute;
		inset: -7px -4px;
	}

	/* Carousel dots are 3px tall by design; the tap area is not. */
	.tw-hero__dot::after {
		content: "";
		position: absolute;
		inset: -14px -4px;
	}

	/* Quantity steppers grow rather than rely on the hit area alone, because
	   they sit side by side and a mis-tap changes the order. */
	.tw-dline__qty .tw-qty-btn {
		width: 2.4rem;
		height: 2.4rem;
	}
}

/* --------------------------------------------------------------------------
   Grids that had no mobile rule
   -------------------------------------------------------------------------- */

@media (max-width: 680px) {
	/* Search results: the price was being squeezed between the thumbnail and
	   the name. It moves under the name instead. */
	.tw-search__list a {
		grid-template-columns: 48px 1fr;
		grid-template-areas:
			"img name"
			"img price";
		gap: var(--sp-1) var(--sp-3);
		align-items: center;
	}
	.tw-search__list img { grid-area: img; width: 48px; height: 48px; }
	.tw-search__name { grid-area: name; }
	.tw-search__price { grid-area: price; font-size: var(--fs-sm); }

	.tw-grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 420px) {
	.tw-grid--2,
	.tw-grid--3 { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   Sticky elements must not stack on a short screen
   Six elements use position: sticky. On a phone the header alone is enough;
   anything else pinned underneath eats the viewport.
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
	.woocommerce-products-header,
	.tw-story__stick {
		position: static;
	}
}

/* --------------------------------------------------------------------------
   Very small phones, 320px
   The narrowest width still in real use. Everything must fit without a
   horizontal scrollbar.
   -------------------------------------------------------------------------- */

@media (max-width: 360px) {
	:root {
		--gutter: .875rem;
		--header-h: 3.5rem;
	}

	.tw-logo__img { height: 1.9rem; }

	/* The tools cluster loses the wishlist before it loses the bag. */
	.tw-hd__wish { display: none; }

	.tw-hero__title { font-size: clamp(1.6rem, 1rem + 4vw, 2rem); }
	.tw-hero__points { font-size: var(--fs-xs); gap: var(--sp-2); }

	.tw-btn { padding-inline: 1.1rem; }
	.tw-btn--lg { padding: .875rem 1.25rem; font-size: var(--fs-base); }

	.tw-drawer__panel,
	.tw-mob__panel { width: 100%; }

	.tw-figure__n { font-size: 1.75rem; }

	/* Cart line items: the thumbnail shrinks so the name keeps its measure. */
	.woocommerce-cart table.shop_table tbody tr.cart_item {
		grid-template-columns: 56px 1fr auto;
	}
	.woocommerce-cart table.shop_table img { width: 56px !important; }
}

/* --------------------------------------------------------------------------
   Landscape phones
   A 700x360 viewport has almost no vertical room, so nothing may be pinned
   and the hero must not reserve a full screen.
   -------------------------------------------------------------------------- */

@media (max-height: 480px) and (orientation: landscape) {
	.tw-hd { position: relative; }
	.tw-ann { display: none; }

	.tw-hero__in { padding-block: var(--sp-5); }
	.tw-slide { grid-template-columns: 1fr 1fr; gap: var(--sp-5); }
	.tw-slide__art { max-width: 16rem; aspect-ratio: 1 / 1; }
	.tw-hero__points { display: none; }

	.tw-drawer__panel,
	.tw-mob__panel { overflow-y: auto; }
}

/* --------------------------------------------------------------------------
   Tablet portrait, 768 to 900
   Between the phone drawer and the desktop nav. The catalogue reads better at
   three across than at two on this width.
   -------------------------------------------------------------------------- */

@media (min-width: 681px) and (max-width: 900px) {
	.tw-grid,
	.woocommerce ul.products { grid-template-columns: repeat(3, minmax(0, 1fr)); }

	.tw-trust { grid-template-columns: repeat(2, 1fr); }
	.tw-promo__list { grid-template-columns: repeat(3, 1fr); }
	.tw-promo__cta { display: none; }
	.tw-figures__in { grid-template-columns: repeat(4, 1fr); }
}

/* --------------------------------------------------------------------------
   Wide screens
   Above 1600px the shell stops growing, so the grid gains a column rather
   than leaving the cards stranded at the centre.
   -------------------------------------------------------------------------- */

@media (min-width: 1600px) {
	:root { --shell: 1440px; }

	.tw-grid,
	.woocommerce ul.products { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

/* --------------------------------------------------------------------------
   Safety net
   One overflowing element gives the whole document a horizontal scrollbar,
   which on a phone reads as a broken site.
   -------------------------------------------------------------------------- */

img, svg, video, iframe, table { max-width: 100%; }

.tw-card__name,
.tw-dline__name,
.woocommerce-loop-product__title,
.product_title,
.tw-search__name { overflow-wrap: anywhere; }

/* WooCommerce prints a few tables the theme does not restyle. */
.woocommerce table:not(.shop_table) { display: block; overflow-x: auto; }
