/**
 * Samsonite theme styles.
 *
 * 1.  Tokens
 * 2.  Reset & base
 * 3.  Utilities
 * 4.  Media placeholders
 * 5.  Buttons & badges
 * 6.  Utility bar
 * 7.  Header & mega menu
 * 8.  Contact bar
 * 9.  Mobile nav
 * 10. Hero
 * 11. Sections & carousels
 * 12. Product cards
 * 13. Category tiles
 * 14. Campaign banners
 * 15. Service promises
 * 16. Newsletter
 * 17. Footer
 * 18. Legal
 * 19. Inner pages
 * 20. Shop archive
 * 21. Product page
 * 22. Account pages
 * 23. Responsive
 * 24. Login page
 * 25. Checkout
 * 26. Cart
 * 27. Compare
 * 28. Registration page
 * 29. Account dashboard
 * 30. Order received
 * 31. Account edit form
 * 32. Account orders
 * 33. Account addresses
 * 34. Account company addresses
 * 35. Account favourites
 * 36. Account newsletter preferences
 * 37. Hero main slider
 * 38. Hero side alignment & wide banner
 * 39. Shop filter panel
 * 40. Mobile refinements
 * 41. Contact page
 * 42. Compact product row
 * 43. Editorial pages
 * 44. Footer refinements
 * 45. Reference parity pass
 * 46. Homepage phone parity
 * 47. Product summary reference parity
 * 48. Sticky shop filters
 * 49. Filter column overflow
 */

/* ------------------------------------------------------------ 1. Tokens - */

:root {
	--black: #000;
	--ink: #1a1a1a;
	--ink-soft: #4a4a4a;
	--muted: #6f6f6f;
	--muted-light: #8d8d8d;
	--line: #e4e4e4;
	--line-strong: #d0d0d0;
	--white: #fff;
	--off: #f7f7f7;
	--sale: #e2001a;
	--sky: #7dc0e8;
	--link: #1b6cb5;
	--teal: #1e9e93;

	--font: "Helvetica Neue", Helvetica, Arial, "Segoe UI", Roboto, system-ui, sans-serif;

	--gutter: clamp(16px, 4vw, 76px);
	--container: 1920px;

	--admin-bar-height: 0px;

	/*
	 * Height of the sticky header: logo row (68) + the rule under it, nav row
	 * (50) + the rule under that. Measured, not guessed -- anything pinned
	 * below the header offsets by this.
	 */
	--header-h: 120px;

	/* Width of the catalogue's filter column, and of the toolbar cell above it. */
	--shop-side: clamp(300px, 24.8vw, 476px);

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

/* --------------------------------------------------- 2. Reset and base - */

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

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

body {
	margin: 0;
	font-family: var(--font);
	font-size: 16px;
	line-height: 1.5;
	color: var(--ink);
	background: var(--white);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

h1,
h2,
h3,
h4,
p,
figure,
blockquote {
	margin: 0;
}

ul,
ol {
	margin: 0;
	padding: 0;
	list-style: none;
}

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

a {
	color: inherit;
	text-decoration: none;
	transition: color 0.2s var(--ease), opacity 0.2s var(--ease);
}

button {
	font: inherit;
	color: inherit;
	background: none;
	border: 0;
	padding: 0;
	cursor: pointer;
}

input,
textarea,
select {
	font: inherit;
	color: inherit;
}

:focus-visible {
	outline: 2px solid var(--ink);
	outline-offset: 3px;
}

/* -------------------------------------------------------- 3. Utilities - */

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

.screen-reader-text {
	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:focus {
	position: fixed !important;
	top: 12px;
	left: 12px;
	z-index: 999;
	width: auto;
	height: auto;
	clip: auto;
	clip-path: none;
	padding: 12px 20px;
	background: var(--black);
	color: var(--white);
}

.overlay {
	position: fixed;
	inset: 0;
	z-index: 60;
	background: rgba(0, 0, 0, 0.45);
	animation: fade 0.25s var(--ease);
}

.overlay[hidden] {
	display: none;
}

@keyframes fade {
	from {
		opacity: 0;
	}
}

.icon {
	flex: none;
}

/* Corner brackets used on campaign artwork. */
.brackets {
	position: absolute;
	inset: 30px;
	pointer-events: none;
}

.brackets::before,
.brackets::after {
	content: "";
	position: absolute;
	width: 44px;
	height: 44px;
	border: 1.5px solid rgba(255, 255, 255, 0.85);
}

.brackets::before {
	top: 0;
	left: 0;
	border-right: 0;
	border-bottom: 0;
	box-shadow: none;
}

.brackets::after {
	right: 0;
	bottom: 0;
	border-top: 0;
	border-left: 0;
}

/* The remaining two corners are painted on the same element, so one span
   covers all four without extra markup. */
.brackets {
	background:
		linear-gradient(to left, rgba(255, 255, 255, 0.85) 44px, transparent 44px) top right / 100% 1.5px no-repeat,
		linear-gradient(to bottom, rgba(255, 255, 255, 0.85) 44px, transparent 44px) top right / 1.5px 100% no-repeat,
		linear-gradient(to right, rgba(255, 255, 255, 0.85) 44px, transparent 44px) bottom left / 100% 1.5px no-repeat,
		linear-gradient(to top, rgba(255, 255, 255, 0.85) 44px, transparent 44px) bottom left / 1.5px 100% no-repeat;
}

.brackets--light::before,
.brackets--light::after {
	border-color: rgba(255, 255, 255, 0.9);
}

/* --------------------------------------------- 4. Media placeholders --- */

/*
 * Artwork slots. A real <img> covers the block when one exists; otherwise the
 * tone gradient holds the exact aspect ratio so the layout never collapses.
 */
.media {
	position: relative;
	display: block;
	overflow: hidden;
	background: #ededed;
	isolation: isolate;
}

.media img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
}

/*
 * The default fit, in :where() so it carries no specificity of its own.
 *
 * Written as `.media img` it is a class plus a type -- which quietly out-weighs
 * every `.thing__img { object-fit: contain }` a later section writes, because
 * those are a single class. Four of them had already lost that fight (the mini
 * cart, the cart line, the checkout summary and the compare table), which is
 * why a portrait product shot arrived cropped top and bottom in all four. At
 * zero specificity the later single-class rule wins on source order instead,
 * and a section that really wants a crop -- the Instagram grid in section 44 --
 * still gets one by saying so.
 */
.media :where(img) {
	object-fit: cover;
}

.media--sand    { background: linear-gradient(150deg, #d9c49b 0%, #cbb489 45%, #b99e70 100%); }
.media--stone   { background: linear-gradient(160deg, #4a5560 0%, #2f3841 55%, #1d242b 100%); }
.media--deep    { background: linear-gradient(160deg, #274a63 0%, #16303f 60%, #0d1c26 100%); }
.media--mist    { background: linear-gradient(160deg, #dfe8ee 0%, #c9d6df 60%, #b8c8d3 100%); }
.media--pale    { background: linear-gradient(160deg, #eef1f3 0%, #dfe4e8 60%, #ced5da 100%); }
.media--peach   { background: linear-gradient(160deg, #f3c7ad 0%, #e9ac8b 60%, #dd9670 100%); }
.media--sage    { background: linear-gradient(160deg, #cdd6c8 0%, #b6c2b0 60%, #9dab96 100%); }
.media--jungle  { background: linear-gradient(150deg, #5c6b4a 0%, #3d4a31 55%, #26301e 100%); }
.media--ice     { background: linear-gradient(155deg, #7fb4d6 0%, #3d7fb0 40%, #1d5580 75%, #123c5e 100%); }
.media--forest  { background: linear-gradient(160deg, #1f6a4c 0%, #12563a 60%, #0b3d29 100%); }
.media--yellow  { background: linear-gradient(160deg, #f4bf52 0%, #eda31d 60%, #d78a0d 100%); }
.media--graphite{ background: linear-gradient(160deg, #55575a 0%, #3a3c3f 60%, #232527 100%); }
.media--silver  { background: linear-gradient(160deg, #d8dcda 0%, #c2c8c6 60%, #a9b1af 100%); }
.media--navy    { background: linear-gradient(160deg, #1d4a80 0%, #123a6b 60%, #0b2749 100%); }
.media--petrol  { background: linear-gradient(160deg, #147078 0%, #0f5f66 60%, #08444a 100%); }

/* --------------------------------------------- 5. Buttons and badges --- */

.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 58px;
	padding: 0 44px;
	font-size: 14px;
	font-weight: 600;
	letter-spacing: 0.11em;
	text-transform: uppercase;
	text-align: center;
	white-space: nowrap;
	transition: background-color 0.22s var(--ease), color 0.22s var(--ease);
}

.btn--light {
	background: var(--white);
	color: var(--black);
}

.btn--light:hover,
.btn--light:focus-visible {
	background: var(--black);
	color: var(--white);
}

.btn--dark {
	background: var(--black);
	color: var(--white);
}

.btn--dark:hover,
.btn--dark:focus-visible {
	background: #333;
}

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

.badge {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 46px;
	height: 27px;
	padding: 0 9px;
	border-radius: 14px;
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.01em;
	line-height: 1;
}

.badge--sale {
	background: var(--sale);
	color: var(--white);
}

/* -------------------------------------------------------- 6. Promo bar - */

.promo-bar {
	background: var(--black);
	color: var(--white);
}

.promo-bar__inner {
	display: flex;
	align-items: center;
	justify-content: space-around;
	gap: 24px;
	min-height: 44px;
}

.promo-bar__item {
	display: flex;
	align-items: center;
	gap: 13px;
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.09em;
	text-transform: uppercase;
	white-space: nowrap;
}

/* ------------------------------------------------------------ 7. Header - */

.header {
	position: sticky;
	top: var(--admin-bar-height);
	z-index: 50;
	background: var(--white);
	border-bottom: 1px solid var(--line);
}

/*
 * The cart panel hangs off the logo row, so it covers the nav row below it.
 *
 * The border is the line the design draws between the logo and the menu. It is
 * dropped again below 1024px, where the menu row is hidden and .header's own
 * border already closes the header off -- two adjacent borders would read as a
 * 2px rule.
 */
.header__top {
	position: relative;
	border-bottom: 1px solid var(--line);
}

.header__top-inner {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 68px;
}

.header__logo {
	line-height: 0;
}

.wordmark {
	display: inline-flex;
	align-items: baseline;
	color: var(--black);
	font-size: 40px;
	font-weight: 500;
	letter-spacing: -0.005em;
	line-height: 1;
}

.wordmark__text {
	display: inline-block;
}

.wordmark__mark {
	width: 0.83em;
	height: 0.83em;
	margin: 0 0.015em;
	transform: translateY(0.045em);
	color: currentColor;
}

.wordmark--light {
	color: var(--white);
}

.header__actions {
	position: absolute;
	right: var(--gutter);
	display: flex;
	align-items: center;
	gap: 22px;
}

.header__action {
	position: relative;
	display: inline-flex;
	align-items: center;
	color: var(--ink);
}

.header__action:hover {
	color: var(--muted);
}

.header__action--search {
	display: none;
}

.header__count {
	position: absolute;
	top: -6px;
	right: -9px;
	min-width: 17px;
	height: 17px;
	padding: 0 4px;
	border-radius: 9px;
	background: var(--sale);
	color: var(--white);
	font-size: 11px;
	font-weight: 700;
	line-height: 17px;
	text-align: center;
}

.header__count.is-empty {
	display: none;
}

.header__burger {
	position: absolute;
	left: var(--gutter);
	display: none;
	align-items: center;
}

.header__bottom-inner {
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	align-items: center;
	gap: 24px;
	min-height: 50px;
}

.header__search {
	justify-self: start;
	width: 100%;
	max-width: 210px;
}

.search-form {
	position: relative;
	display: flex;
	align-items: center;
	gap: 10px;
	border-bottom: 1px solid var(--ink);
	padding-bottom: 3px;
}

.search-form__label {
	display: flex;
	color: var(--ink);
}

.search-form__input {
	width: 100%;
	border: 0;
	background: none;
	font-size: 16px;
	padding: 2px 0;
}

.search-form__input::placeholder {
	color: var(--muted);
	opacity: 1;
}

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

/* Enter in the field submits natively; the button stays for screen readers. */
.search-form__submit {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
}

/* Mini cart -------------------------------------------------------------- */

.cart-menu {
	position: absolute;
	top: 100%;
	right: var(--gutter);
	z-index: 10;
	opacity: 0;
	visibility: hidden;
	transform: translateY(-8px);
	transition: opacity 0.2s var(--ease), transform 0.2s var(--ease), visibility 0.2s;
}

.cart-menu.is-open {
	opacity: 1;
	visibility: visible;
	transform: none;
}

.mini-cart {
	width: min(610px, calc(100vw - 2 * var(--gutter)));
	padding: 20px 26px 26px;
	background: var(--white);
	box-shadow: 0 22px 34px rgba(0, 0, 0, 0.16);
}

.mini-cart:focus {
	outline: none;
}

.mini-cart__empty {
	padding: 8px 0;
	color: var(--ink-soft);
	font-size: 15px;
}

/* Long carts scroll; the totals and the button below stay put. */
.mini-cart__items {
	max-height: min(46vh, 420px);
	overflow-y: auto;
	overscroll-behavior: contain;
}

.mini-cart__item {
	display: grid;
	grid-template-columns: 54px minmax(0, 1fr) auto;
	align-items: start;
	gap: 0 20px;
	padding: 14px 0;
}

.mini-cart__item + .mini-cart__item {
	border-top: 1px solid var(--line);
}

.mini-cart__media {
	aspect-ratio: 4 / 5;
	background: #fff;
}

/* Product shots keep their full silhouette at this size. */
.mini-cart__img {
	object-fit: contain;
}

/* Stands in for the shot while no photography is attached. */
.mini-cart__media[class*="media--"] {
	background-image: none;
	background-color: #fff;
}

.mini-cart__media::after {
	content: "";
	position: absolute;
	inset: 6% 10%;
	border-radius: 8px;
	background: currentColor;
	opacity: 0.1;
}

.mini-cart__media:has(img)::after {
	display: none;
}

.mini-cart__media.media--forest   { color: #12563a; }
.mini-cart__media.media--yellow   { color: #eda31d; }
.mini-cart__media.media--graphite { color: #3a3c3f; }
.mini-cart__media.media--silver   { color: #a9b1af; }
.mini-cart__media.media--navy     { color: #123a6b; }
.mini-cart__media.media--petrol   { color: #0f5f66; }
.mini-cart__media.media--mist     { color: #7d94a4; }
.mini-cart__media.media--sand     { color: #b99e70; }
.mini-cart__media.media--pale     { color: #9aa4ab; }
.mini-cart__media.media--peach    { color: #dd9670; }
.mini-cart__media.media--stone    { color: #2f3841; }
.mini-cart__media.media--sage     { color: #9dab96; }

.mini-cart__name {
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	line-height: 1.3;
}

.mini-cart__summary {
	margin-top: 8px;
	font-size: 15px;
	line-height: 1.4;
}

.mini-cart__qty {
	margin-top: 8px;
	color: var(--muted-light);
	font-size: 15px;
}

/* Prices sit on the baseline of the lines they price, not the item name. */
.mini-cart__price {
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	justify-content: flex-end;
	gap: 8px;
	align-self: end;
	text-align: right;
	white-space: nowrap;
}

.mini-cart__price del {
	color: var(--muted);
	font-size: 15px;
	text-decoration-thickness: 1px;
}

.mini-cart__price ins {
	color: var(--ink);
	font-size: 17px;
	font-weight: 700;
	text-decoration: none;
}

.mini-cart__row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	padding: 18px 0;
	border-top: 1px solid var(--line);
	font-size: 15px;
	font-weight: 600;
}

.mini-cart__row--total {
	font-size: 16px;
	font-weight: 700;
}

.mini-cart__checkout {
	margin-top: 6px;
}

.mini-cart__view {
	display: block;
	margin-top: 22px;
	text-align: center;
	font-size: 15px;
}

.mini-cart__view:hover {
	text-decoration: underline;
}

/* The panel already says what was added, so the store's own follow-up link
   under the card button has nothing left to do. */
.card .added_to_cart {
	display: none;
}

.nav {
	justify-self: center;
}

.nav__list {
	display: flex;
	align-items: center;
	gap: 26px;
}

.nav__list > li > a {
	position: relative;
	display: inline-block;
	padding: 4px 0;
	font-size: 15px;
	font-weight: 600;
	letter-spacing: 0.01em;
	white-space: nowrap;
}

/* Marks the category the visitor is browsing, under its nav item. */
.nav__list > .current-menu-item > a::before,
.nav__list > .current-menu-parent > a::before,
.nav__list > .current-menu-ancestor > a::before,
.nav__list > .current-product-ancestor > a::before {
	content: "";
	position: absolute;
	bottom: -9px;
	left: 50%;
	width: 6px;
	height: 6px;
	margin-left: -3px;
	border-radius: 50%;
	background: var(--sky);
}

.nav__list > li > a:hover {
	color: var(--muted);
}

/* Second level, shown on hover. */
.nav__list li {
	position: relative;
}

.nav__list .sub-menu {
	position: absolute;
	top: 100%;
	left: 50%;
	transform: translateX(-50%);
	min-width: 220px;
	padding: 14px 0;
	background: var(--white);
	border: 1px solid var(--line);
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.2s var(--ease);
	z-index: 5;
}

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

.nav__list .sub-menu a {
	display: block;
	padding: 9px 24px;
	font-size: 14px;
	white-space: nowrap;
}

.nav__list .sub-menu a:hover {
	background: var(--off);
}

/* Mega panels ------------------------------------------------------------ */

/*
 * A panel lives inside its list item but is measured against the whole nav
 * row, so items that own one give up their positioning context.
 */
.header__bottom {
	position: relative;
}

.nav__list > .has-mega {
	position: static;
}

/* The panel stands in for any second level on the same item. */
.nav__list > .has-mega > .sub-menu {
	display: none;
}

.nav__list > .has-mega > a {
	position: relative;
	color: var(--ink);
}

/* Marks the open item, on the bottom edge of the nav row. */
.nav__list > .has-mega > a::after {
	content: "";
	position: absolute;
	right: 0;
	bottom: -18px;
	left: 0;
	height: 2px;
	background: var(--black);
	opacity: 0;
	transition: opacity 0.2s var(--ease);
}

.mega {
	position: absolute;
	top: 100%;
	left: 0;
	z-index: 5;
	width: 100%;
	background: var(--white);
	border-bottom: 1px solid var(--line);
	box-shadow: 0 22px 34px rgba(0, 0, 0, 0.09);
	opacity: 0;
	visibility: hidden;
	transform: translateY(-8px);
	transition: opacity 0.2s var(--ease), transform 0.2s var(--ease), visibility 0.2s;
}

/* Hover alone opens a panel; once the script loads it takes over, adding the
   delays that stop panels flickering as the pointer crosses the bar. */
.nav:not(.is-js) .nav__list > .has-mega:hover > .mega,
.nav__list > .has-mega:focus-within > .mega,
.nav__list > .has-mega.is-open > .mega {
	opacity: 1;
	visibility: visible;
	transform: none;
}

.nav:not(.is-js) .nav__list > .has-mega:hover > a::after,
.nav__list > .has-mega:focus-within > a::after,
.nav__list > .has-mega.is-open > a::after {
	opacity: 1;
}

/* padding-block only: the inline gutters come from .container. */
.mega__inner {
	display: grid;
	/* Three link tracks, then three equal tracks for two cards and the tile, so
	   tile and cards share one width -- and so one height at 2:3. The three are
	   capped, so the shots stay the size of a thumbnail rather than growing with
	   the screen; the links take whatever is left. */
	grid-template-columns: repeat(3, minmax(0, 1fr)) repeat(3, minmax(0, 210px));
	align-items: start;
	gap: 0 clamp(18px, 1.7vw, 32px);
	padding-block: 34px 44px;
}

.mega__group + .mega__group {
	margin-top: 42px;
}

.mega__heading {
	padding-bottom: 13px;
	border-bottom: 1px solid var(--line-strong);
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.mega__heading + .mega__list {
	margin-top: 5px;
}

.mega__link {
	display: block;
	padding: 11px 0;
	color: var(--ink);
	font-size: 13px;
	letter-spacing: 0.04em;
	line-height: 1.35;
	text-transform: uppercase;
}

.mega__link:hover {
	text-decoration: underline;
	text-underline-offset: 5px;
}

/* A column with no heading still starts on the line the headings sit on. */
.mega__col > .mega__group:first-child > .mega__list:first-child li:first-child > .mega__link {
	padding-top: 0;
}

/* A long sub-category list takes two tracks and flows across them under its
   one heading, so the rule under the heading spans both. */
.mega__col--wide {
	grid-column: span 2;
}

.mega__col--wide .mega__list {
	columns: 2;
	column-gap: clamp(18px, 1.7vw, 32px);
}

.mega__col--wide .mega__list li {
	break-inside: avoid;
}

/* Artwork keeps its tracks even in panels with fewer link columns. */
.mega__products {
	grid-column: 4 / span 2;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	/* The panel's own gutter, so each card is exactly one track wide. */
	gap: clamp(18px, 1.7vw, 32px);
}

/* The catalogue's shots are 800x1200, so a 2:3 block lets them fill edge to
   edge with nothing cropped and no gutters. */
.mega__card-media {
	aspect-ratio: 2 / 3;
}

.mega__card-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	margin-top: 24px;
}

/* One line however long the model name runs, so the two cards and the tile's
   title stay on the same row; a name too long for its card is clipped. */
.mega__card-brand {
	min-width: 0;
	overflow: hidden;
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.05em;
	line-height: 1.3;
	text-transform: uppercase;
	white-space: nowrap;
	text-overflow: ellipsis;
}

.mega__card .compare {
	flex: none;
	gap: 5px;
	font-size: 12px;
}

.mega__card-title {
	margin-top: 12px;
	font-size: 14px;
	line-height: 1.4;
}

.mega__card-title a:hover {
	text-decoration: underline;
	text-underline-offset: 4px;
}

.mega__card-price {
	display: flex;
	flex-direction: column;
	gap: 4px;
	margin-top: 10px;
}

.mega__card-price del {
	color: var(--muted);
	font-size: 13px;
	text-decoration-thickness: 1px;
}

.mega__card-price ins {
	color: var(--ink);
	font-size: 15px;
	font-weight: 700;
	text-decoration: none;
}

.mega__promo {
	grid-column: 6;
	display: block;
}

.mega__promo-media {
	aspect-ratio: 2 / 3;
}

/* Set like a card's model name, under the same empty swatch row, so it lands
   on the line the two names sit on. */
.mega__promo-title {
	display: block;
	margin-top: 24px;
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.05em;
	line-height: 1.3;
	text-transform: uppercase;
}

.mega__promo:hover .mega__promo-title {
	text-decoration: underline;
	text-underline-offset: 5px;
}

.header__brand,
.header__brand-list {
	justify-self: end;
	display: flex;
	gap: 26px;
	font-size: 15px;
	font-weight: 600;
	letter-spacing: 0.01em;
}

.header__mobile-search {
	display: none;
	padding: 14px 0 18px;
	border-top: 1px solid var(--line);
}

.header__mobile-search[hidden] {
	display: none;
}

/* ------------------------------------------------------- 8. Contact bar - */

.contact-bar {
	background: var(--sky);
	color: var(--ink);
}

.contact-bar__text {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	min-height: 46px;
	font-size: 16px;
	letter-spacing: 0.02em;
	text-align: center;
}

.contact-bar__text a:hover {
	text-decoration: underline;
}

/* -------------------------------------------------------- 9. Mobile nav - */

.mobile-nav {
	position: fixed;
	top: 0;
	left: 0;
	z-index: 70;
	width: min(84vw, 380px);
	height: 100%;
	background: var(--white);
	display: flex;
	flex-direction: column;
	transform: translateX(-100%);
	transition: transform 0.3s var(--ease);
	overflow-y: auto;
}

.mobile-nav.is-open {
	transform: translateX(0);
}

.mobile-nav__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 20px var(--gutter);
	border-bottom: 1px solid var(--line);
}

.mobile-nav__title {
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.09em;
	text-transform: uppercase;
}

.mobile-nav__body {
	padding: 8px var(--gutter) 40px;
}

.mobile-nav__body .nav__list {
	display: block;
}

.mobile-nav__body .nav__list > li > a,
.mobile-nav__brand {
	display: block;
	padding: 16px 0;
	border-bottom: 1px solid var(--line);
	font-size: 15px;
	font-weight: 600;
	letter-spacing: 0.01em;
}

.mobile-nav__body .sub-menu {
	position: static;
	transform: none;
	opacity: 1;
	visibility: visible;
	border: 0;
	padding: 0 0 10px 14px;
}

/* The mega panel's link groups, laid out as one indented list per group. */
.mobile-nav__panel {
	padding: 14px 0 20px 14px;
	border-bottom: 1px solid var(--line);
}

.mobile-nav__heading {
	margin-top: 14px;
	color: var(--muted);
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.09em;
	text-transform: uppercase;
}

.mobile-nav__panel > .mobile-nav__heading:first-child {
	margin-top: 0;
}

.mobile-nav__list a {
	display: block;
	padding: 9px 0;
	font-size: 14px;
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

/* The item's own link keeps the divider; the panel below it carries the next. */
.mobile-nav__body .nav__list > .has-mega > a {
	border-bottom: 0;
}

/* ------------------------------------------------------------- 10. Hero - */

.hero {
	padding-top: 36px;
}

.hero__grid {
	display: grid;
	grid-template-columns: 3.14fr 1fr;
	gap: 42px;
	align-items: stretch;
}

/* With no side panels configured, the main panel takes the full width. */
.hero__grid--single {
	grid-template-columns: minmax(0, 1fr);
}

.hero__main {
	position: relative;
	aspect-ratio: 16 / 9;
}

.hero__panel {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	width: 91%;
	height: 77%;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 8px;
	padding: 24px;
	background: rgba(216, 199, 168, 0.76);
	text-align: center;
	color: var(--white);
}

.hero__title {
	max-width: 9ch;
	font-size: clamp(40px, 5vw, 96px);
	font-weight: 700;
	line-height: 0.98;
	letter-spacing: 0.01em;
	text-transform: uppercase;
}

.hero__sub {
	font-size: clamp(20px, 2.1vw, 40px);
	font-weight: 400;
	line-height: 1.2;
	margin-bottom: 22px;
}

.hero__side {
	position: relative;
	display: flex;
	flex-direction: column;
}

.hero__slides {
	position: relative;
	flex: 1;
	min-height: 0;
}

.hero__slide {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	padding: 46px 22px 22px;
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.5s var(--ease);
}

.hero__slide.is-active {
	opacity: 1;
	visibility: visible;
}

.hero__slide-body {
	padding-inline: 8px;
}

.hero__slide-title {
	display: flex;
	flex-direction: column;
	gap: 2px;
	color: var(--white);
	/* Capped so "Remarkably light" stays on one line inside the narrow panel. */
	font-size: clamp(20px, 1.6vw, 29px);
	line-height: 1.12;
	text-transform: uppercase;
}

.hero__slide-title strong {
	font-weight: 700;
}

.hero__slide-title em {
	font-style: italic;
	font-weight: 700;
}

.hero__slide .btn {
	min-height: 52px;
	padding-inline: 14px;
	font-size: 13px;
	letter-spacing: 0.08em;
}

.dots {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 22px;
	padding: 18px 0 4px;
}

.dots__dot {
	width: 9px;
	height: 9px;
	border-radius: 50%;
	background: var(--line-strong);
	transition: background-color 0.2s var(--ease);
}

.dots__dot.is-active {
	background: var(--ink);
}

/* ------------------------------------------- 11. Sections and carousels - */

.section {
	padding-top: 46px;
}

.section--newsletter {
	padding-top: 0;
}

.section__title {
	font-size: 18px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	margin-bottom: 30px;
}

.carousel {
	position: relative;
}

.carousel__viewport {
	overflow-x: auto;
	overflow-y: hidden;
	scroll-snap-type: x proximity;
	/* Without this the first item snaps to the scrollport edge and the row
	   starts scrolled past the container gutter. */
	scroll-padding-inline-start: var(--gutter);
	scrollbar-width: none;
	-ms-overflow-style: none;
	scroll-behavior: smooth;
	overscroll-behavior-x: contain;
}

.carousel__viewport::-webkit-scrollbar {
	display: none;
}

.carousel__track {
	display: flex;
	align-items: stretch;
}

.carousel__track::after {
	content: "";
	flex: none;
	width: 1px;
}

.carousel__item {
	flex: none;
	scroll-snap-align: start;
}

.carousel__track--products {
	gap: 18px;
}

/* Five cards fill the viewport, so the row shows whole cards and not a sliver. */
.carousel__track--products > .carousel__item {
	width: calc((100% - (4 * 18px)) / 5);
}

.carousel__track--tiles {
	gap: 58px;
}

.carousel__track--tiles > .carousel__item {
	width: 497px;
}

.carousel__nav {
	position: absolute;
	top: 34%;
	z-index: 4;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	border-radius: 50%;
	background: var(--white);
	color: var(--ink);
	box-shadow: 0 2px 14px rgba(0, 0, 0, 0.16);
	opacity: 0;
	transition: opacity 0.2s var(--ease), background-color 0.2s var(--ease);
}

.carousel:hover .carousel__nav,
.carousel__nav:focus-visible {
	opacity: 1;
}

.carousel__nav[disabled] {
	opacity: 0 !important;
	pointer-events: none;
}

.carousel__nav--prev {
	left: calc(var(--gutter) / 2);
}

.carousel__nav--next {
	right: calc(var(--gutter) / 2);
}

.carousel__progress {
	position: relative;
	width: min(1140px, 62%);
	height: 2px;
	margin: 42px auto 0;
	background: var(--line);
}

.carousel__bar {
	position: absolute;
	top: -0.5px;
	left: 0;
	height: 3px;
	width: 30%;
	background: var(--ink);
	transition: transform 0.15s linear, width 0.15s linear;
}

/* ----------------------------------------------------- 12. Product card - */

.card {
	display: flex;
	flex-direction: column;
	height: 100%;
	padding: 17px;
	transition: box-shadow 0.25s var(--ease);
}

.card:hover {
	box-shadow: 0 4px 26px rgba(0, 0, 0, 0.1);
}

.card__media {
	aspect-ratio: 4 / 5;
	background: #fff;
}

/* Product shots -- on the page and in the mega panels alike -- sit on white in
   the reference design; the tone only shows through as a soft wash while no
   photography is attached. */
:is(.card__media, .mega__card-media)[class*="media--"] {
	background-image: none;
	background-color: #fff;
}

/*
 * A product shot is the whole product against white paper, so it is fitted
 * inside the block rather than cropped to fill it -- .media's own `cover` cuts
 * the handle off a tall case and the wheels off a wide one. The block is
 * already white above, which is the ground these shots are lit on, so the
 * letterboxing the fit leaves is invisible. The mega panel's blocks share the
 * shots' own ratio, so there they fill the block instead (.media's cover).
 */
.card__media img {
	object-fit: contain;
}

/* Stands in for the product shot while no photography is attached. */
.card__media::after,
.mega__card-media::after {
	content: "";
	position: absolute;
	inset: 7% 13%;
	border-radius: 14px;
	background: currentColor;
	opacity: 0.1;
}

.card__media:has(img)::after,
.mega__card-media:has(img)::after {
	display: none;
}

:is(.card__media, .mega__card-media).media--forest   { color: #12563a; }
:is(.card__media, .mega__card-media).media--yellow   { color: #eda31d; }
:is(.card__media, .mega__card-media).media--graphite { color: #3a3c3f; }
:is(.card__media, .mega__card-media).media--silver   { color: #a9b1af; }
:is(.card__media, .mega__card-media).media--navy     { color: #123a6b; }
:is(.card__media, .mega__card-media).media--petrol   { color: #0f5f66; }
:is(.card__media, .mega__card-media).media--mist     { color: #7d94a4; }
:is(.card__media, .mega__card-media).media--sand     { color: #b99e70; }
:is(.card__media, .mega__card-media).media--pale     { color: #9aa4ab; }
:is(.card__media, .mega__card-media).media--peach    { color: #dd9670; }
:is(.card__media, .mega__card-media).media--stone    { color: #2f3841; }
:is(.card__media, .mega__card-media).media--sage     { color: #9dab96; }
:is(.card__media, .mega__card-media).media--ice      { color: #3d7fb0; }
:is(.card__media, .mega__card-media).media--jungle   { color: #3d4a31; }
:is(.card__media, .mega__card-media).media--deep     { color: #16303f; }

.card .badge--sale {
	position: absolute;
	top: 24px;
	left: 24px;
	z-index: 2;
}

.swatches {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	margin-top: 22px;
}

.swatches__dot {
	display: block;
	width: 17px;
	height: 17px;
	border-radius: 50%;
	background: var(--swatch, #101010);
	box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.14);
	transition: transform 0.18s var(--ease);
}

.swatches__dot:hover {
	transform: scale(1.14);
}

/*
 * On a card the dots switch between products, so one of them is the product
 * being shown and wears a ring. The extra gap is the room that ring needs, and
 * is kept off the mega panel's dots, which carry no ring.
 */
.card .swatches {
	flex-wrap: wrap;
	gap: 11px;
}

.swatches__dot.is-current {
	position: relative;
}

.swatches__dot.is-current::after {
	content: "";
	position: absolute;
	inset: -4px;
	border: 1.5px solid var(--ink);
	border-radius: 50%;
}

.swatches--none {
	height: 17px;
}

/* Colours beyond the row's limit, as a count rather than a truncated row. */
.swatches__more {
	color: var(--muted);
	font-size: 13px;
	letter-spacing: 0.02em;
	line-height: 1;
}

.swatches__more a:hover {
	color: var(--ink);
}

.card__head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	justify-content: space-between;
	gap: 14px;
	margin-top: 30px;
}

.card__name {
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	line-height: 1.3;
}

.compare {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	flex: none;
	color: var(--ink-soft);
	font-size: 13px;
	letter-spacing: 0.01em;
}

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

.compare.is-active {
	/* "Added to compare" is a sentence, not a word: on its own row under the
	   name, or it squeezes the title to a word a line. */
	flex-basis: 100%;
	justify-content: flex-start;
	color: var(--sale);
	font-weight: 600;
}

.card__summary {
	margin-top: 10px;
	color: var(--ink-soft);
	font-size: 14px;
	line-height: 1.5;
}

.card__price {
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin-top: 16px;
}

.card__price del {
	color: var(--muted);
	font-size: 15px;
	text-decoration-thickness: 1px;
}

.card__price ins {
	color: var(--ink);
	font-size: 17px;
	font-weight: 700;
	text-decoration: none;
}

.card__price .woocommerce-Price-amount {
	white-space: nowrap;
}

.card__cta {
	margin-top: 18px;
	min-height: 48px;
	font-size: 13px;
	opacity: 0;
	transition: opacity 0.2s var(--ease);
}

.card:hover .card__cta,
.card__cta:focus-visible {
	opacity: 1;
}

/* ---------------------------------------------------- 13. Category tile - */

.tile {
	display: block;
}

.tile__media {
	display: block;
	aspect-ratio: 497 / 300;
}

.tile__name {
	display: block;
	margin-top: 26px;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
}

.tile:hover .tile__name {
	text-decoration: underline;
	text-underline-offset: 5px;
}

/* -------------------------------------------------------- 14. Banners --- */

.split {
	display: grid;
	grid-template-columns: 41% 59%;
	min-height: 555px;
}

.split__copy {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 40px;
	padding: 60px clamp(24px, 7.5vw, 131px);
	background: var(--black);
	color: var(--white);
}

.split__title {
	display: flex;
	flex-direction: column;
	font-size: clamp(34px, 4vw, 76px);
	font-weight: 700;
	font-style: italic;
	line-height: 1.06;
	letter-spacing: 0.005em;
	text-transform: uppercase;
}

.split__kicker {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 18px;
}

.split__kicker-lead {
	font-size: clamp(14px, 1.2vw, 22px);
	font-weight: 400;
	letter-spacing: 0.34em;
	text-transform: uppercase;
}

.split__collection {
	font-size: clamp(20px, 1.7vw, 31px);
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

.split__media {
	position: relative;
	display: flex;
	align-items: flex-end;
	justify-content: flex-end;
	padding: 46px;
}

.split__cta {
	position: relative;
	z-index: 2;
	min-height: 46px;
	padding-inline: 30px;
	font-size: 13px;
}

.section--material {
	padding-top: 46px;
}

.material {
	position: relative;
	display: block;
	width: min(1334px, 100% - (var(--gutter) * 2));
	margin-inline: auto;
	aspect-ratio: 1334 / 780;
	color: var(--white);
}

.material .brackets {
	inset: 48px;
}

.material__logo {
	position: absolute;
	top: 6%;
	left: 50%;
	transform: translateX(-50%);
}

.material__logo .wordmark {
	font-size: 30px;
}

.material__lockup {
	position: absolute;
	bottom: 6%;
	left: 50%;
	transform: translateX(-50%);
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 4px;
	text-align: center;
}

.material__name {
	font-size: clamp(22px, 2.2vw, 34px);
	font-weight: 700;
	letter-spacing: 0.1em;
	line-height: 1;
	text-transform: uppercase;
}

.material__name sup {
	font-size: 0.4em;
	vertical-align: super;
}

.material__caption {
	font-size: clamp(9px, 0.72vw, 12px);
	font-weight: 600;
	letter-spacing: 0.62em;
	text-indent: 0.62em;
	text-transform: uppercase;
}

/* --------------------------------------------- 15. Service promises ----- */

.section--usp {
	padding-top: 64px;
}

.section--usp .container {
	padding-inline: 0;
	max-width: none;
}

.usp {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	border-top: 1px solid var(--line);
}

.usp__item {
	display: flex;
	align-items: flex-start;
	gap: 42px;
	padding: 52px clamp(20px, 5vw, 95px);
	border-bottom: 1px solid var(--line);
}

.usp__item:nth-child(odd) {
	border-right: 1px solid var(--line);
}

.usp__icon {
	flex: none;
	color: var(--ink);
}

.usp__title {
	font-size: 17px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	line-height: 1.35;
}

.usp__text {
	margin-top: 20px;
	max-width: 62ch;
	color: var(--ink-soft);
	font-size: 15px;
	line-height: 1.75;
}

/* ----------------------------------------------------- 16. Newsletter --- */

.section--newsletter {
	margin-top: 0;
	background: var(--off);
}

.newsletter {
	padding: 72px var(--gutter) 92px;
	text-align: center;
}

.newsletter__title {
	font-size: clamp(26px, 2.4vw, 38px);
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

.newsletter__lead {
	margin-top: 16px;
	font-size: 17px;
	color: var(--ink-soft);
}

.newsletter__form {
	position: relative;
	display: flex;
	align-items: center;
	gap: 12px;
	width: min(560px, 100%);
	margin: 30px auto 0;
	border-bottom: 1px solid #999;
	padding-bottom: 8px;
}

.newsletter__input {
	flex: 1;
	min-width: 0;
	border: 0;
	background: none;
	font-size: 17px;
	padding: 6px 0;
}

.newsletter__input:focus {
	outline: none;
}

.newsletter__input::placeholder {
	color: var(--muted);
	opacity: 1;
}

.newsletter__submit {
	display: flex;
	align-items: center;
	color: var(--ink);
	transition: transform 0.2s var(--ease);
}

.newsletter__submit:hover {
	transform: translateX(4px);
}

.newsletter__message {
	min-height: 22px;
	margin-top: 16px;
	font-size: 15px;
}

.newsletter__message.is-error {
	color: var(--sale);
}

.newsletter__message.is-success {
	color: #157a3d;
}

/* Either submit -- the bare arrow, or the labelled button section 44 adds. */
.newsletter.is-busy .newsletter__submit,
.newsletter.is-busy .newsletter__button {
	opacity: 0.5;
	pointer-events: none;
}

/* --------------------------------------------------------- 17. Footer --- */

.footer {
	background: var(--black);
	color: var(--white);
	padding: 62px 0 72px;
}

/*
 * Five columns: the store locator, the brand block, two link lists and the
 * social block. The brand block carries the longest lines of the row, so it is
 * given the widest track and the link lists the narrowest.
 */
.footer__grid {
	display: grid;
	grid-template-columns: 1.4fr 1fr 1fr 1.4fr;
	gap: 40px;
}

/*
 * The four tracks stop fitting well before the tablet breakpoint takes the row
 * down to two, so the row wraps to three first -- the social column drops to a
 * second row. Section 23 overrides this again at 1024px and below.
 */
@media (max-width: 1200px) {
	.footer__grid {
		grid-template-columns: repeat(3, 1fr);
		gap: 44px 30px;
	}
}

.footer__title {
	margin-bottom: 26px;
	color: var(--muted-light);
	font-size: 15px;
	font-weight: 400;
	letter-spacing: 0.02em;
}

.footer__title--tight {
	margin-top: 34px;
	margin-bottom: 16px;
	font-size: 13px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.footer__links li + li {
	margin-top: 24px;
}

.footer__links a {
	font-size: 16px;
}

.footer__links a:hover {
	color: var(--muted-light);
}

/* --- The brand block: logo over address, contact and opening hours. --- */

/*
 * The width cap belongs on the link, not on the image inside it: the link shrinks
 * to fit its content, so a percentage on the image would resolve against the
 * link's own content-derived width and scale the logo down against itself.
 */
.footer__brand-link {
	display: inline-block;
	max-width: 70%;
	margin-bottom: 34px;
	line-height: 0;
}

/* The reference design rules the contact details off from the link lists. Only
   above the three-column step, where the lists still sit beside the block. */
@media (min-width: 1201px) {
	.footer__col--brand {
		padding-right: 40px;
		border-right: 1px solid rgba(255, 255, 255, 0.16);
	}
}

/*
 * The wordmark drawn by the theme takes its colour from .wordmark--light, but an
 * uploaded logo (Site Identity) is a fixed image, and the Samsonite file is
 * black artwork on white meant for the white header -- unreadable as-is on this
 * black panel. Inverting it lands both halves where this footer needs them: the
 * mark turns white and the white ground turns #000, the footer's own background,
 * so a JPEG with no transparency still sits flush. It holds for a transparent
 * PNG too, since the mark is monochrome and has no hue to flip.
 */
/*
 * A height cap rather than the header's --logo-height: the footer wants the mark
 * smaller than the masthead does, whatever that setting says. The link above caps
 * the width, so a squarer upload stays inside the column too.
 */
.footer__col--brand .wordmark__image {
	max-height: 68px;
	margin-inline: 0;
	filter: invert(1);
}

.footer__col--brand .wordmark {
	font-size: 32px;
}

.footer__group + .footer__group {
	margin-top: 26px;
}

.footer__group-title {
	margin-bottom: 8px;
	font-size: 16px;
	font-weight: 700;
	letter-spacing: 0.01em;
}

.footer__group-row {
	color: var(--muted-light);
	font-size: 16px;
	line-height: 1.55;
}

.footer__group-row + .footer__group-row {
	margin-top: 2px;
}

.footer__group-row a:hover {
	color: var(--white);
}

.ig-card {
	display: inline-flex;
	align-items: center;
	gap: 14px;
	padding: 10px 18px 10px 12px;
	border-radius: 6px;
	background: linear-gradient(70deg, #f9ce34 0%, #ee2a7b 48%, #6228d7 100%);
}

.ig-card__badge {
	display: flex;
	color: var(--white);
}

.ig-card__text {
	display: flex;
	flex-direction: column;
	line-height: 1.1;
}

.ig-card__lead {
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.13em;
	text-transform: uppercase;
}

.ig-card__brand {
	font-size: 26px;
	font-weight: 600;
	font-style: italic;
	letter-spacing: -0.01em;
}

.footer__handle {
	margin-top: 20px;
	font-size: 26px;
	letter-spacing: 0.01em;
}

.social {
	display: flex;
	align-items: center;
	gap: 38px;
	margin-top: 22px;
}

.social a:hover {
	opacity: 0.65;
}

.payments {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 14px 18px;
	max-width: 380px;
}

.payments__item svg {
	height: 34px;
	width: auto;
}

/* ---------------------------------------------------------- 18. Legal --- */

.legal {
	background: var(--white);
	color: var(--ink);
	padding: 34px 0 40px;
	text-align: center;
}

.legal__line {
	font-size: 15px;
	line-height: 1.7;
}

.legal__line a {
	color: var(--link);
}

.legal__line a:hover {
	text-decoration: underline;
}

/* --------------------------------------------------- 19. Inner pages ---- */

.site-main:not(.home) {
	padding: 56px 0 90px;
}

.page-title {
	font-size: clamp(26px, 3vw, 42px);
	font-weight: 700;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	margin-bottom: 34px;
}

.entry + .entry {
	margin-top: 56px;
	padding-top: 56px;
	border-top: 1px solid var(--line);
}

.entry__title {
	font-size: 24px;
	font-weight: 700;
	margin-bottom: 12px;
}

.entry__meta {
	color: var(--muted);
	font-size: 14px;
	margin-bottom: 18px;
}

.entry__content > * + * {
	margin-top: 18px;
}

.entry__content a {
	color: var(--link);
	text-decoration: underline;
}

/*
 * Long-form page copy: the policy and terms pages are numbered clauses and one
 * wide cookie table, and section 2 strips markers and padding from every list on
 * the site. These put both back, scoped to page and post content so nothing in
 * the store's own lists is affected. Nested ordered lists step through the usual
 * decimal / lower-alpha / lower-roman sequence, which is what a clause like
 * "1.2 (a)" needs to stay readable.
 */
.entry__content ul,
.entry__content ol {
	padding-left: 26px;
	line-height: 1.7;
}

.entry__content ul {
	list-style: disc;
}

.entry__content ol {
	list-style: decimal;
}

.entry__content ol ol {
	list-style: lower-alpha;
}

.entry__content ol ol ol {
	list-style: lower-roman;
}

.entry__content li + li,
.entry__content li > ul,
.entry__content li > ol {
	margin-top: 10px;
}

.entry__content p,
.entry__content li {
	line-height: 1.7;
}

.entry__content h2,
.entry__content h3,
.entry__content h4 {
	font-weight: 700;
	line-height: 1.3;
}

.entry__content h2 {
	font-size: 22px;
}

.entry__content h3 {
	font-size: 19px;
}

.entry__content h4 {
	font-size: 17px;
}

.entry__content img {
	max-width: 100%;
	height: auto;
}

/* The cookie table is wider than the column on anything but a desktop, so it
   scrolls inside its own wrapper rather than widening the page. */
.entry__content > table,
.entry__content .wp-block-table {
	display: block;
	max-width: 100%;
	overflow-x: auto;
}

.entry__content table {
	border-collapse: collapse;
	font-size: 14px;
}

.entry__content th,
.entry__content td {
	padding: 12px 14px;
	border: 1px solid var(--line);
	text-align: left;
	vertical-align: top;
}

.entry__content th {
	font-weight: 700;
	background: var(--off);
}

.pagination {
	margin-top: 48px;
	display: flex;
	gap: 10px;
	flex-wrap: wrap;
}

.pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 42px;
	height: 42px;
	padding: 0 12px;
	border: 1px solid var(--line);
	font-size: 14px;
}

.pagination .current {
	background: var(--black);
	color: var(--white);
	border-color: var(--black);
}

.widget + .widget {
	margin-top: 36px;
}

.widget__title {
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	margin-bottom: 14px;
}

/* WooCommerce pages inherit the theme's type; the store's own layout CSS is
   dequeued in inc/woocommerce.php. */
.shop ul.products {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 40px 23px;
	margin-top: 30px;
}

/* The store's clearfix pseudo-elements would each claim a grid cell. */
.shop ul.products::before,
.shop ul.products::after {
	display: none;
}

.shop ul.products li.product {
	position: relative;
}

.shop ul.products li.product a img {
	width: 100%;
	height: auto;
	margin-bottom: 18px;
}

.shop ul.products li.product .woocommerce-loop-product__title {
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	margin-bottom: 10px;
}

.shop ul.products li.product .price {
	display: block;
	font-size: 17px;
	font-weight: 700;
}

.shop ul.products li.product .price del {
	color: var(--muted);
	font-size: 15px;
	font-weight: 400;
	margin-right: 8px;
}

.shop ul.products li.product .price ins {
	text-decoration: none;
}

/*
 * woocommerce-general.css is enqueued after the theme stylesheet, so its
 * button and helper rules need to be out-specified rather than just restated.
 */
.site-main.shop .button,
.site-main.shop button.button,
.site-main.shop a.button,
.site-main.shop input[type="submit"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 48px;
	padding: 0 28px;
	margin-top: 14px;
	background: var(--black);
	color: var(--white);
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	border: 0;
	cursor: pointer;
}

.site-main.shop .button:hover,
.site-main.shop button.button:hover,
.site-main.shop a.button:hover,
.site-main.shop input[type="submit"]:hover {
	background: #333;
	color: var(--white);
}

.site-main.shop .woocommerce-result-count,
.site-main.shop .woocommerce-ordering {
	color: var(--muted);
}

.site-main.shop ul.products li.product .woocommerce-loop-product__title {
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	padding: 0;
}

.site-main.shop ul.products li.product .price {
	color: var(--ink);
	font-size: 17px;
	font-weight: 700;
}

.site-main.shop ul.products li.product .price del {
	color: var(--muted);
	font-size: 15px;
	font-weight: 400;
	opacity: 1;
}

/* Account, cart and checkout forms. woocommerce-layout.css is dequeued, so the
   two-column arrangements it used to provide are rebuilt here. */
.shop .woocommerce-form,
.shop form.checkout_coupon,
.shop form.login,
.shop form.register {
	max-width: 620px;
	margin-top: 24px;
	padding: 30px;
	border: 1px solid var(--line);
}

.shop .form-row {
	display: flex;
	flex-direction: column;
	gap: 7px;
	margin-bottom: 20px;
}

.shop .form-row label {
	font-size: 14px;
	font-weight: 600;
	letter-spacing: 0.02em;
}

.shop .input-text,
.shop input[type="text"],
.shop input[type="email"],
.shop input[type="tel"],
.shop input[type="password"],
.shop select,
.shop textarea {
	width: 100%;
	min-height: 48px;
	padding: 10px 14px;
	border: 1px solid var(--line-strong);
	background: var(--white);
	font-size: 15px;
}

.shop .form-row.form-row-first,
.shop .form-row.form-row-last {
	display: inline-flex;
	width: calc(50% - 8px);
	vertical-align: top;
}

.shop .form-row.form-row-first {
	margin-right: 12px;
}

.shop .woocommerce-form__label-for-checkbox {
	flex-direction: row;
	align-items: center;
	gap: 9px;
	font-weight: 400;
}

.shop .woocommerce-form__label-for-checkbox input {
	min-height: 0;
	width: auto;
}

.shop .lost_password {
	margin-top: 14px;
	font-size: 14px;
}

.shop .woocommerce-error,
.shop .woocommerce-info,
.shop .woocommerce-message {
	margin-bottom: 26px;
	padding: 16px 20px;
	border-left: 3px solid var(--ink);
	background: var(--off);
	list-style: none;
	font-size: 15px;
}

.shop .woocommerce-error {
	border-left-color: var(--sale);
}

/*
 * Every store notice carries a glyph from WooCommerce's own icon font, absolutely
 * placed at top 1em / left 1.5em. The padding above does not reserve room for it,
 * and the theme never loads that font, so it lands on top of the wording as an
 * empty light-blue box. The wording says everything the mark would.
 *
 * Unscoped on purpose: section 26 suppresses the same three for .cart-page, but
 * the account and checkout screens were still showing it.
 */
.woocommerce-info::before,
.woocommerce-message::before,
.woocommerce-error::before {
	display: none;
}

.shop .woocommerce-MyAccount-navigation ul {
	display: flex;
	flex-wrap: wrap;
	gap: 8px 24px;
	margin-bottom: 30px;
	padding-bottom: 18px;
	border-bottom: 1px solid var(--line);
}

.shop .woocommerce-MyAccount-navigation a {
	font-size: 14px;
	font-weight: 600;
	letter-spacing: 0.05em;
	text-transform: uppercase;
}

.shop .woocommerce-MyAccount-navigation .is-active a {
	text-decoration: underline;
	text-underline-offset: 5px;
}

.shop table.shop_table {
	width: 100%;
	margin-top: 20px;
	border-collapse: collapse;
}

.shop table.shop_table th,
.shop table.shop_table td {
	padding: 14px 12px;
	border-bottom: 1px solid var(--line);
	text-align: left;
	font-size: 15px;
}

.shop table.shop_table th {
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.shop .woocommerce-breadcrumb {
	margin-bottom: 18px;
	color: var(--muted);
	font-size: 14px;
}

.shop .woocommerce-result-count,
.shop .woocommerce-ordering {
	display: inline-block;
	margin-right: 18px;
	font-size: 14px;
	color: var(--muted);
}

/* -------------------------------------------------- 20. Shop archive --- */

/*
 * The catalogue is a two-column page: a product grid and, beside it, the
 * attribute filters. The toolbar above shares the same column template so the
 * "Filters" heading sits exactly over the column it opens and closes.
 *
 * The class is doubled and the :not() repeated to out-specify section 19's
 * `.site-main:not(.home)`, which pads every non-homepage main element 56px
 * from the top. The catalogue is the one page whose first element is
 * furniture rather than content: the toolbar sticks under the header, so it
 * has to start there too, and 56px of nothing above it reads as a gap in the
 * page. Written plainly as `.shop-archive` this rule loses that fight -- one
 * class against two -- however far down the stylesheet it sits.
 */
.site-main.shop-archive:not(.home) {
	padding: 0 0 90px;
}

.shop-bar {
	position: sticky;
	top: calc(var(--header-h) + var(--admin-bar-height));
	z-index: 30;
	background: var(--white);
	border-bottom: 1px solid var(--line);
}

.shop-bar__inner {
	display: grid;
	grid-template-columns: 1fr minmax(240px, 456px) var(--shop-side);
	min-height: 78px;
}

/* ---- Breadcrumb ---- */

.shop-bar__crumbs {
	display: flex;
	align-items: center;
	gap: 8px;
	padding-inline: var(--gutter) 20px;
	color: var(--muted);
	font-size: 13px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.shop-bar__crumb:hover {
	color: var(--ink);
}

.shop-bar__sep {
	color: var(--line-strong);
}

/* The trail ends on a separator, as in the reference; the last one only shows
   when there is a category after "Home". */
.shop-bar__crumbs .shop-bar__sep:last-child {
	color: var(--muted);
}

/* ---- Sort select ---- */

/* The store's own five orders, in a native select so the option list is the
   platform's: the cell only supplies the chrome around it. */
.shop-bar__sort {
	position: relative;
	display: flex;
	align-items: center;
	border-inline: 1px solid var(--line);
}

/* Element-qualified: section 19's `.shop select` is (0,1,1) and would otherwise
   draw its own 48px bordered field inside the cell. */
.shop-bar__sort select.shop-sort__select {
	appearance: none;
	width: 100%;
	min-height: 78px;
	padding: 0 66px 0 30px;
	border: 0;
	border-radius: 0;
	background: transparent;
	color: var(--ink);
	font-family: inherit;
	font-size: 15px;
	font-weight: 600;
	line-height: 1.3;
	cursor: pointer;
}

.shop-bar__sort select.shop-sort__select:focus-visible {
	outline: 2px solid var(--ink);
	outline-offset: -4px;
}

/* Sits over the select, which has room reserved for it on the right. */
.shop-sort__chevron {
	position: absolute;
	right: 30px;
	pointer-events: none;
}

/* Only reachable without JavaScript, where the select cannot submit itself. */
.shop-sort__go {
	margin-right: 30px;
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-decoration: underline;
	text-transform: uppercase;
}

/* ---- Filter column heading ---- */

.shop-bar__filters {
	display: flex;
	align-items: center;
	padding-inline: 26px 46px;
}

.shop-filters__toggle {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 18px;
	width: 100%;
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
}

.shop-filters__label {
	display: inline-flex;
	align-items: center;
	gap: 10px;
}

.shop-filters__count,
.shop-filter__count {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 20px;
	height: 20px;
	padding: 0 6px;
	border-radius: 10px;
	background: var(--black);
	color: var(--white);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0;
}

.shop-filters__chevron {
	transition: transform 0.22s var(--ease);
}

.shop-filters__toggle[aria-expanded="false"] .shop-filters__chevron {
	transform: rotate(180deg);
}

/* ---- Two-column body ---- */

.shop-layout {
	display: grid;
	grid-template-columns: 1fr var(--shop-side);
	align-items: start;
}

.shop-layout__main {
	min-width: 0;
	padding-inline: var(--gutter) 0;
}

/* Closing the filters -- or having no attributes to filter on -- gives the grid
   the whole width back. */
.shop-archive--wide,
.shop-archive.is-filters-closed {
	--shop-side: 0px;
}

.shop-archive--wide .shop-layout__main,
.shop-archive.is-filters-closed .shop-layout__main {
	padding-inline: var(--gutter);
}

.shop-archive.is-filters-closed .shop-layout__side,
.shop-archive.is-filters-closed .shop-bar__filters .shop-filters__label {
	visibility: visible;
}

.shop-archive.is-filters-closed .shop-filters {
	display: none;
}

/* The heading cell keeps its width so the toolbar does not jump when the column
   underneath it closes. */
.shop-archive.is-filters-closed .shop-bar__inner {
	grid-template-columns: 1fr minmax(240px, 456px) clamp(300px, 24.8vw, 476px);
}

/* ---- Category shortcuts ---- */

.shop-chips {
	padding: 44px 0 6px;
}

.shop-chips__list {
	display: flex;
	flex-wrap: wrap;
	gap: 14px;
}

.shop-chip {
	display: inline-flex;
	align-items: center;
	min-height: 52px;
	padding: 0 26px;
	border: 1px solid var(--line-strong);
	border-radius: 2px;
	font-size: 15px;
	transition: border-color 0.2s var(--ease), background-color 0.2s var(--ease), color 0.2s var(--ease);
}

.shop-chip:hover {
	border-color: var(--ink);
}

.shop-chip.is-active {
	background: var(--black);
	border-color: var(--black);
	color: var(--white);
}

/* ---- Grid ---- */

.shop-grid {
	display: grid;
	grid-template-columns: repeat(var(--shop-columns, 4), minmax(0, 1fr));
	gap: 26px 24px;
	padding-top: 30px;
}

.shop-grid__item {
	display: flex;
	min-width: 0;
}

.shop-grid__item > .card {
	width: 100%;
}

.shop-empty {
	padding: 60px 0 20px;
	color: var(--ink-soft);
	font-size: 17px;
}

.shop-empty__reset {
	margin-bottom: 40px;
}

/* ---- Load more ---- */

.shop-more {
	display: flex;
	justify-content: center;
	padding: 64px 0 24px;
}

.shop-more__btn {
	gap: 12px;
	min-width: min(348px, 100%);
}

.shop-more__plus {
	font-size: 17px;
	line-height: 1;
}

.shop-more__btn.is-busy {
	pointer-events: none;
	opacity: 0.6;
}

/* ---- Filter column ---- */

/* The rows run the full width of the column -- the padding sits inside them, so
   the dividing lines reach both edges as they do in the reference. */
.shop-filters__clear {
	padding: 18px 46px 0 26px;
	font-size: 13px;
	letter-spacing: 0.04em;
	text-align: right;
}

.shop-filters__clear a {
	color: var(--sale);
	text-decoration: underline;
	text-underline-offset: 4px;
}

.shop-filter {
	border-bottom: 1px solid var(--line);
}

.shop-filter__title {
	font: inherit;
}

.shop-filter__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 14px;
	width: 100%;
	min-height: 78px;
	padding-inline: 26px 46px;
	text-align: left;
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

.shop-filter__name {
	display: inline-flex;
	align-items: center;
	gap: 10px;
}

.shop-filter__chevron {
	flex: none;
	transition: transform 0.22s var(--ease);
}

.shop-filter__head[aria-expanded="true"] .shop-filter__chevron {
	transform: rotate(180deg);
}

.shop-filter__body {
	padding: 0 46px 28px 26px;
}

.shop-filter__body[hidden] {
	display: none;
}

.shop-filter__options {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 14px;
}

.shop-filter__option.is-folded {
	display: none;
}

.shop-tile {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 12px;
	height: 100%;
	min-height: 62px;
	padding: 14px 10px;
	border: 1px solid var(--line);
	border-radius: 2px;
	font-size: 13px;
	letter-spacing: 0.06em;
	line-height: 1.25;
	text-align: center;
	text-transform: uppercase;
	transition: border-color 0.18s var(--ease), box-shadow 0.18s var(--ease);
}

.shop-tile--swatch {
	min-height: 108px;
}

.shop-tile:hover {
	border-color: var(--ink);
}

.shop-tile.is-active {
	border-color: var(--ink);
	box-shadow: inset 0 0 0 1px var(--ink);
	font-weight: 700;
}

.shop-tile__dot {
	width: 26px;
	height: 26px;
	border-radius: 50%;
	background: var(--swatch, #d5d5d5);
	box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.14);
}

/* Stands in for a colour term with no swatch set, and for "multicolour". */
.shop-tile__dot--multi {
	background: conic-gradient(#e2001a, #f2a71b, #0e6b45, #1b6cb5, #a99bc4, #e2001a);
}

.shop-filter__more {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-top: 18px;
	color: var(--ink-soft);
	font-size: 14px;
}

.shop-filter__more:hover {
	color: var(--ink);
}

.shop-filter__more[aria-expanded="true"] .icon {
	transform: rotate(180deg);
}

.shop-filter__more .icon {
	transition: transform 0.22s var(--ease);
}

/* The drawer's own head only exists below the desktop breakpoint. */
.shop-filters__head {
	display: none;
}

/* --------------------------------------------------- 21. Product page --- */

/*
 * Out-specifies the generic `.site-main:not(.home)` inner-page padding, which
 * would otherwise push the breadcrumb 56px down and leave a white strip between
 * the newsletter and the footer.
 */
.site-main.product-page {
	padding: 20px 0 0;

	/*
	 * The two fixed tracks of the layout below. They live here rather than in
	 * .product-layout because the panels further down the page inset themselves
	 * to the same tracks, and the accordion has to keep sitting under the
	 * artwork when these narrow -- see .product-info.
	 */
	--product-summary-w: 560px;
	--product-rail-w: 76px;
}

/*
 * Three tracks: the fixed-width summary, the gallery, and the thumbnail rail
 * hugging the container edge. The summary carries the page gutter itself so its
 * dividing rule can run to the very edge of the column. Capped at the site's
 * 1920px container, as the reference PDP is.
 */
.product-layout {
	display: grid;
	max-width: var(--container);
	margin-inline: auto;
	grid-template-columns: var(--product-summary-w) minmax(0, 1fr) var(--product-rail-w);
	align-items: start;
}

/* ---- Summary column ---- */

/* No right padding: the rules inside run flush to the dividing border, as in
   the reference design. */
.product-summary {
	padding: 22px 0 64px var(--gutter);
	border-right: 1px solid var(--line);
}

.crumbs__list {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0 6px;
	color: var(--ink-soft);
	font-size: 18px;
	line-height: 1.8;
}

.crumbs__item + .crumbs__item::before {
	content: "/";
	margin-right: 6px;
	color: var(--muted);
}

.crumbs__item--home a {
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

.crumbs a:hover {
	text-decoration: underline;
	text-underline-offset: 4px;
}

.product-title {
	margin-top: 48px;
	font-size: clamp(29px, 2.4vw, 40px);
	font-weight: 700;
	letter-spacing: 0.01em;
	line-height: 1.1;
	text-transform: uppercase;
}

.product-subtitle {
	margin-top: 6px;
	font-size: clamp(22px, 1.8vw, 31px);
	font-weight: 400;
	line-height: 1.25;
}

/* Outlined, unlike the filled pill used on cards. */
.product-discount {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 84px;
	height: 46px;
	margin-top: 32px;
	padding: 0 14px;
	border: 1.5px solid var(--sale);
	color: var(--sale);
	font-size: 19px;
	font-weight: 700;
	line-height: 1;
}

/*
 * The stock line reads as a note on the price, so it sits beside it rather than
 * out at the column's far edge -- space-between put the width of the column
 * between the two, which read as two unrelated things and landed the label on
 * the dividing border. It still wraps under the price when there is no room: the
 * label cannot break, and a four-figure price leaves it none.
 */
.product-pricing {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: flex-start;
	gap: 8px 20px;
	margin-top: 30px;
}

.product-price {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.product-price del {
	color: var(--muted);
	font-size: 23px;
	text-decoration-thickness: 1px;
}

.product-price ins {
	color: var(--ink);
	font-size: clamp(30px, 2.5vw, 38px);
	font-weight: 700;
	text-decoration: none;
}

.product-stock {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	font-size: 17px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	white-space: nowrap;
}

.product-stock__dot {
	width: 9px;
	height: 9px;
	border-radius: 50%;
	background: #00a89b;
}

.product-stock.is-out {
	color: var(--muted);
}

.product-stock.is-out .product-stock__dot {
	background: var(--muted);
}

.product-links {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 34px;
	margin-top: 34px;
	padding: 19px 0;
	border-top: 1px solid var(--line);
	border-bottom: 1px solid var(--line);
}

.product-link {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	color: var(--ink-soft);
	font-size: 18px;
}

.product-link span {
	text-decoration: underline;
	text-underline-offset: 5px;
	text-decoration-color: var(--line-strong);
}

.product-link:hover {
	color: var(--ink);
}

/* The compare button once chosen -- same red the cards use. */
.product-link.is-active {
	color: var(--sale);
}

.product-option {
	margin-top: 28px;
}

.product-option__label {
	font-size: 19px;
	font-weight: 600;
	letter-spacing: 0.02em;
}

.product-option__value {
	margin-left: 8px;
	color: var(--muted);
	font-weight: 400;
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

.sizes {
	display: flex;
	flex-wrap: wrap;
	gap: 14px;
	margin-top: 16px;
}

/*
 * A button centres its own label; these are <span>s and <a>s as well now -- the
 * derived rows are links to a sibling product rather than pickers -- so the
 * centring is stated rather than inherited from the element.
 */
.sizes__item {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 66px;
	height: 52px;
	padding: 0 16px;
	border: 1px solid var(--line-strong);
	background: var(--white);
	font-size: 18px;
	letter-spacing: 0.02em;
	transition: border-color 0.18s var(--ease), color 0.18s var(--ease);
}

.sizes__item:hover:not(.is-unavailable) {
	border-color: var(--ink);
}

.sizes__item.is-selected {
	border-color: var(--ink);
	border-width: 1.5px;
	font-weight: 600;
}

.sizes__item.is-unavailable {
	border-color: #ededed;
	color: #c2c2c2;
	cursor: not-allowed;
}

.colours {
	display: flex;
	flex-wrap: wrap;
	gap: 22px;
	margin-top: 18px;
}

.colours__item {
	position: relative;
	display: block;
	width: 32px;
	height: 32px;
	border-radius: 50%;
	background: var(--swatch, #c9c9c9);
	box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.16);
}

/* Selection ring sits outside the dot so the colour stays true. */
.colours__item.is-selected::after {
	content: "";
	position: absolute;
	inset: -6px;
	border: 1.5px solid var(--ink);
	border-radius: 50%;
}

.colours__item.is-unavailable {
	cursor: not-allowed;
	opacity: 0.35;
}

/* The current size and colour are <span>s, so the hover state has to be kept off
   them -- they are where you already are. */
a.sizes__item:hover {
	border-color: var(--ink);
}

a.colours__item:hover {
	box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.16), 0 0 0 3px rgba(0, 0, 0, 0.08);
}

.product-buy {
	display: flex;
	align-items: center;
	gap: 28px;
	margin-top: 40px;
}

/* div.product qualifier: WooCommerce's `.woocommerce div.product form.cart`
   (0,2,2) puts 2em under the form, which centres the heart against a taller
   row than the button. (0,3,2) here keeps the margin at zero. */
div.product .product-buy form.cart,
div.product .product-buy .variations_form {
	flex: 0 1 406px;
	min-width: 0;
	margin: 0;
}

.product-buy .single_add_to_cart_button,
.site-main.shop .product-buy .single_add_to_cart_button {
	display: flex;
	width: 100%;
	min-height: 64px;
	margin: 0;
	padding: 0 24px;
	background: var(--black);
	color: var(--white);
	font-size: 19px;
	font-weight: 600;
	letter-spacing: 0.11em;
	text-transform: uppercase;
}

.product-buy .single_add_to_cart_button:hover {
	background: #333;
}

.product-buy .single_add_to_cart_button.disabled,
.product-buy .single_add_to_cart_button:disabled {
	background: var(--line-strong);
	color: var(--white);
	cursor: not-allowed;
}

/* WooCommerce's own attribute selects. JS hides them once the swatch and size
   pickers above are wired to them; without JS they stay usable. */
.product-buy .variations {
	width: 100%;
	margin-bottom: 18px;
	border: 0;
}

.product-buy .variations th,
.product-buy .variations td {
	padding: 6px 0;
	text-align: left;
	border: 0;
}

.product-buy .variations.is-proxied,
.product-buy .woocommerce-variation-price {
	display: none;
}

.product-buy .reset_variations {
	display: inline-block;
	margin-top: 8px;
	font-size: 13px;
	color: var(--muted);
}

.product-unavailable {
	flex: 1;
	color: var(--muted);
	font-size: 16px;
}

.wishlist {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: none;
	width: 40px;
	height: 40px;
	color: var(--ink);
	transition: transform 0.18s var(--ease), color 0.18s var(--ease);
}

.wishlist:hover {
	transform: scale(1.08);
}

.wishlist[aria-pressed="true"] {
	color: var(--sale);
}

/* ---- Gallery ---- */

.product-gallery {
	padding: 0 0 0 18px;
}

.product-gallery__grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 24px;
}

/*
 * 2/3 is the shape the catalogue's photography is served in (800x1200), so the
 * shot fills its tile edge to edge. A tile of any other ratio letterboxes the
 * photo and renders it smaller than the space allows.
 */
.product-shot {
	position: relative;
	margin: 0;
	aspect-ratio: 2 / 3;
	overflow: hidden;
	background: #fafafa;
	border: 1px solid #efefef;
	scroll-margin-top: calc(var(--header-h) + var(--admin-bar-height) + 20px);
}

.product-shot img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: contain;
}

/* Stands in for the product shot while no photography is attached. */
.product-shot:not(:has(img))::after {
	content: "";
	position: absolute;
	inset: 14% 20%;
	border-radius: 16px;
	background: var(--accent, #9aa4ab);
	opacity: 0.13;
}

/*
 * The track has to span the full row for the rail to have anywhere to travel:
 * the grid sets align-items:start so the summary's divider stops at its own
 * content, so this column opts back into stretching.
 */
.product-rail {
	align-self: stretch;
	padding-right: 12px;
}

.product-rail__list {
	position: sticky;
	top: calc(var(--header-h) + var(--admin-bar-height) + 20px);
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.product-rail__item {
	position: relative;
	display: block;
	width: 100%;
	aspect-ratio: 5 / 8;
	overflow: hidden;
	background: #fafafa;
	border: 1px solid #efefef;
	transition: border-color 0.18s var(--ease);
}

.product-rail__item img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: contain;
}

.product-rail__item:not(:has(img))::after {
	content: "";
	position: absolute;
	inset: 16% 24%;
	border-radius: 4px;
	background: var(--accent, #9aa4ab);
	opacity: 0.16;
}

.product-rail__item:hover,
.product-rail__item.is-active {
	border-color: var(--ink);
}

/* ---- Description and panels ---- */

/*
 * Capped like .product-layout: .product-info's percentage padding resolves
 * against this box, so it has to be the same width as the artwork's grid or
 * the accordion drifts off the gallery's left edge on wide screens.
 */
.section--product-info {
	max-width: var(--container);
	margin-inline: auto;
	padding-top: 72px;
}

/*
 * The description used to hold a 560px column to the left of the panels; it is
 * inside the first panel now, so the accordion is the only thing here and the
 * measure that keeps the copy readable moved onto the panel body below.
 *
 * This element is the .container, so these paddings replace its gutter rather
 * than adding to it: the accordion starts where the artwork starts (the summary
 * track plus the gallery's own 18px) and stops where the artwork stops (the
 * thumbnail rail). Written as one `padding-inline` so it cleanly out-cascades
 * the container's, which is the same property on the same element.
 */
.product-info {
	display: block;
	padding-inline: calc(var(--product-summary-w) + 18px) var(--product-rail-w);
}

.prose {
	color: var(--ink-soft);
	font-size: 16px;
	line-height: 1.75;
}

.prose > * + * {
	margin-top: 16px;
}

.prose a {
	color: var(--link);
	text-decoration: underline;
}

.accordion__item {
	border-bottom: 1px solid var(--line);
}

.accordion__trigger {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
	width: 100%;
	min-height: 72px;
	padding: 14px 0;
	font-size: 17px;
	font-weight: 700;
	letter-spacing: 0.07em;
	text-align: left;
	text-transform: uppercase;
}

.accordion__heading {
	margin: 0;
	font-size: inherit;
	font-weight: inherit;
}

.accordion__chevron {
	flex: none;
	color: var(--ink-soft);
	transition: transform 0.25s var(--ease);
}

.accordion__trigger[aria-expanded="true"] .accordion__chevron {
	transform: rotate(180deg);
}

.accordion__panel[hidden] {
	display: none;
}

/* One step up from .prose's site-wide size: the panel is the product's own
   copy and reads at the product page's scale, not an inner page's. */
.accordion__body {
	max-width: 920px;
	padding: 4px 0 30px;
	font-size: 17px;
}

/* The description's own heading inside the specifications panel. */
.accordion__subtitle {
	margin: 0;
	color: var(--ink);
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.09em;
	text-transform: uppercase;
}

.accordion__body > * + .spec {
	margin-top: 26px;
}

.spec {
	margin: 0;
}

.spec__row {
	display: grid;
	grid-template-columns: 220px minmax(0, 1fr);
	gap: 16px;
	padding: 11px 0;
	border-bottom: 1px solid var(--line);
}

.spec__row:last-child {
	border-bottom: 0;
}

.spec__key {
	color: var(--muted);
	font-size: 16px;
}

.spec__value {
	margin: 0;
	font-size: 16px;
}

.section--related {
	padding-top: 72px;
}

/* ------------------------------------------------- 22. Account pages --- */

/*
 * Pages carrying a single centred form -- the password reset page today. The
 * breadcrumb band runs the full width directly under the header, so the page's
 * own top padding starts below it rather than on <main>: this takes the
 * inner-page padding from section 19 back off, doubling the class and repeating
 * the :not() to out-specify it.
 */
.site-main.site-main--flush:not(.home) {
	padding: 0;
}

.page-crumbs {
	border-bottom: 1px solid var(--line);
}

.page-crumbs__inner {
	display: flex;
	align-items: center;
	gap: 9px;
	min-height: 62px;
	color: var(--muted);
	font-size: 15px;
}

.page-crumbs__home {
	display: inline-flex;
	align-items: center;
	gap: 7px;
}

/* The chevron sits a little into the gutter, as in the reference design. */
.page-crumbs__chevron {
	margin-left: -3px;
}

.page-crumbs__home:hover {
	color: var(--ink);
}

/* Both crumbs read at the same weight in the reference; only the link darkens
   on hover. */
.page-crumbs__current {
	color: inherit;
}

.account {
	padding: 96px 0 64px;
}

.account__inner {
	max-width: 880px;
	margin-inline: auto;
	text-align: center;
}

.account__title {
	font-size: clamp(23px, 2vw, 27px);
	font-weight: 500;
	letter-spacing: 0.01em;
	line-height: 1.3;
}

.account__lead {
	margin-top: 38px;
	color: var(--ink-soft);
	font-size: 17px;
	line-height: 1.6;
}

.account__lead > * + * {
	margin-top: 12px;
}

.account__note {
	margin-top: 14px;
	color: var(--muted);
	font-size: 15px;
}

/* The one place the form answers back: a bad address, or an expired form. */
.account__error {
	margin-top: 30px;
	padding: 15px 20px;
	border-left: 3px solid var(--sale);
	background: var(--off);
	font-size: 15px;
	text-align: left;
}

.account__actions {
	margin-top: 46px;
}

.account-form {
	margin-top: 26px;
}

.account-form__input {
	width: min(500px, 100%);
	min-height: 62px;
	padding: 0 24px;
	border: 1px solid var(--line-strong);
	border-radius: 3px;
	background: var(--white);
	font-size: 16px;
}

.account-form__input::placeholder {
	color: var(--muted);
	opacity: 1;
}

.account-form__input:focus {
	border-color: var(--ink);
	outline: none;
}

.account-form__submit,
.account__submit {
	min-width: 200px;
	min-height: 66px;
}

.account-form__submit {
	margin-top: 52px;
}

/* ----------------------------------------------------- 23. Responsive --- */

@media (max-width: 1440px) {
	/* Five cards get too narrow to read here, so the row steps down to four. */
	.carousel__track--products > .carousel__item {
		width: calc((100% - (3 * 18px)) / 4);
	}

	.nav__list {
		gap: 20px;
	}

	.nav__list > li > a {
		font-size: 14px;
	}

	.carousel__track--tiles > .carousel__item {
		width: 420px;
	}

	.hero__slide {
		padding: 32px 18px 18px;
	}

	.site-main.product-page {
		--product-summary-w: 470px;
		--product-rail-w: 72px;
	}

	.shop-bar__inner {
		grid-template-columns: 1fr minmax(220px, 380px) var(--shop-side);
	}

	.shop-grid {
		gap: 24px 18px;
	}
}

@media (max-width: 1200px) {
	.header__bottom-inner {
		grid-template-columns: auto 1fr auto;
	}

	.header__search {
		max-width: 170px;
	}

	.nav__list {
		gap: 14px;
	}

	/* Too narrow for five tracks: the artwork tile goes, the products stay. */
	.mega__promo {
		display: none;
	}

	.mega__inner {
		grid-template-columns: repeat(3, minmax(0, 1fr)) repeat(2, minmax(0, 210px));
	}

	.hero__grid {
		grid-template-columns: 2.4fr 1fr;
		gap: 26px;
	}

	.split {
		min-height: 420px;
	}

	.site-main.product-page {
		--product-summary-w: 420px;
		--product-rail-w: 68px;
	}

	.product-summary {
		padding-right: 28px;
	}

	.product-gallery {
		padding-left: 18px;
	}

	.product-gallery__grid {
		gap: 20px;
	}

	.spec__row {
		grid-template-columns: 170px minmax(0, 1fr);
	}

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

	.shop-filter__head,
	.shop-bar__inner {
		min-height: 66px;
	}

	.shop-bar__sort select.shop-sort__select {
		min-height: 66px;
	}
}

@media (max-width: 1024px) {
	.promo-bar__item {
		font-size: 11px;
		letter-spacing: 0.06em;
		gap: 9px;
	}

	.promo-bar__item .icon {
		width: 17px;
		height: 17px;
	}

	.header__bottom {
		display: none;
	}

	/* Last visible row: .header's own border closes the header off. */
	.header__top {
		border-bottom: 0;
	}

	.header__action--search {
		display: inline-flex;
	}

	/* Absolute centring can collide with the icon row on narrow screens, so
	   the three groups become grid tracks that cannot overlap. */
	.header__top-inner {
		display: grid;
		grid-template-columns: auto minmax(0, 1fr) auto;
		align-items: center;
		gap: 10px;
		min-height: 62px;
	}

	.header__burger {
		position: static;
		display: inline-flex;
	}

	.header__logo {
		grid-column: 2;
		justify-self: center;
	}

	.wordmark {
		font-size: 30px;
	}

	.header__actions {
		position: static;
		grid-column: 3;
		gap: 18px;
	}

	.header__mobile-search:not([hidden]) {
		display: block;
	}

	.hero__grid {
		grid-template-columns: 1fr;
		gap: 22px;
	}

	/* Four cards get too narrow to read here, so the row steps down to three. */
	.carousel__track--products > .carousel__item {
		width: calc((100% - (2 * 18px)) / 3);
	}

	.hero__main {
		aspect-ratio: 16 / 10;
	}

	.hero__side {
		min-height: 420px;
	}

	.split {
		grid-template-columns: 1fr;
		min-height: 0;
	}

	.split__copy {
		gap: 26px;
		padding: 48px var(--gutter);
	}

	.split__media {
		aspect-ratio: 16 / 9;
		padding: 26px;
	}

	.usp {
		grid-template-columns: 1fr;
	}

	.usp__item {
		gap: 28px;
		padding: 38px var(--gutter);
	}

	.usp__item:nth-child(odd) {
		border-right: 0;
	}

	.usp__icon svg {
		width: 44px;
		height: 44px;
	}

	.footer__grid {
		grid-template-columns: repeat(2, 1fr);
		gap: 44px 30px;
	}

	.shop ul.products {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}

	/* The nav row is hidden at this width, so the sticky offset shrinks. */
	:root {
		--header-h: 63px;
	}

	/* Artwork first, then the buying column; the rail has no room left. */
	.product-layout {
		display: block;
	}

	.product-summary {
		padding: 30px var(--gutter) 54px;
		border-right: 0;
	}

	.product-gallery {
		padding: 0;
	}

	.product-gallery__grid {
		display: flex;
		gap: 12px;
		padding-inline: var(--gutter);
		overflow-x: auto;
		scroll-snap-type: x mandatory;
		scroll-padding-inline-start: var(--gutter);
		scrollbar-width: none;
		-ms-overflow-style: none;
	}

	.product-gallery__grid::-webkit-scrollbar {
		display: none;
	}

	.product-shot {
		flex: none;
		width: min(78%, 460px);
		scroll-snap-align: start;
	}

	.product-rail {
		display: none;
	}

	.section--product-info,
	.section--related {
		padding-top: 48px;
	}

	/* No gallery track to line up with at this width. */
	.product-info {
		padding-inline: var(--gutter);
	}

	/* The filter column becomes a drawer, so the toolbar drops to two rows: the
	   trail on top, the two controls beneath it. */
	.shop-bar__inner {
		grid-template-columns: 1fr auto;
		min-height: 0;
	}

	.shop-bar__crumbs {
		grid-column: 1 / -1;
		padding: 13px var(--gutter);
		border-bottom: 1px solid var(--line);
	}

	.shop-bar__sort {
		border-inline: 0;
	}

	.shop-bar__sort select.shop-sort__select {
		min-height: 58px;
		padding: 0 46px 0 var(--gutter);
	}

	.shop-sort__chevron {
		right: 20px;
	}

	.shop-bar__filters {
		padding-inline: 20px var(--gutter);
	}

	.shop-filters__toggle {
		gap: 10px;
	}

	.shop-filters__toggle[aria-expanded="false"] .shop-filters__chevron,
	.shop-filters__toggle[aria-expanded="true"] .shop-filters__chevron {
		transform: none;
	}

	.shop-layout {
		grid-template-columns: minmax(0, 1fr);
	}

	.shop-layout__main,
	.shop-archive.is-filters-closed .shop-layout__main {
		padding-inline: var(--gutter);
	}

	.shop-layout__side {
		position: fixed;
		top: 0;
		right: 0;
		bottom: 0;
		z-index: 80;
		width: min(430px, 92vw);
		background: var(--white);
		box-shadow: -10px 0 36px rgba(0, 0, 0, 0.14);
		transform: translateX(101%);
		transition: transform 0.3s var(--ease);
		overflow-y: auto;
		overscroll-behavior: contain;
	}

	.shop-archive.is-filters-open .shop-layout__side {
		transform: none;
	}

	/* The desktop collapse has no meaning once the column is a drawer. */
	.shop-archive.is-filters-closed .shop-filters {
		display: block;
	}

	.shop-filter__head,
	.shop-filter__body,
	.shop-filters__head,
	.shop-filters__clear {
		padding-inline: var(--gutter);
	}

	.shop-filter__body {
		padding-bottom: 26px;
	}

	.shop-filters__head {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 16px;
		min-height: 71px;
		border-bottom: 1px solid var(--line);
	}

	.shop-filters__head-title {
		font-size: 14px;
		font-weight: 700;
		letter-spacing: 0.12em;
		text-transform: uppercase;
	}

	.shop-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.shop-chips {
		padding-top: 30px;
	}
}

@media (max-width: 767px) {
	.promo-bar__inner {
		justify-content: flex-start;
		gap: 34px;
		overflow-x: auto;
		scrollbar-width: none;
		min-height: 44px;
	}

	.promo-bar__inner::-webkit-scrollbar {
		display: none;
	}

	.contact-bar__text {
		min-height: 40px;
		font-size: 14px;
	}

	.wordmark {
		font-size: 26px;
	}

	.header__actions {
		gap: 15px;
	}

	/* Too narrow to hang off the icon: the panel spans the gutters instead. */
	.cart-menu {
		left: var(--gutter);
	}

	.mini-cart {
		width: auto;
		padding: 16px 18px 20px;
	}

	.mini-cart__item {
		grid-template-columns: 46px minmax(0, 1fr) auto;
		gap: 0 14px;
	}

	.hero {
		padding-top: 20px;
	}

	.hero__main {
		aspect-ratio: 4 / 5;
	}

	.hero__panel {
		width: 88%;
		height: 72%;
	}

	.hero__side {
		min-height: 360px;
	}

	.section {
		padding-top: 40px;
	}

	.section--usp {
		padding-top: 34px;
	}

	.carousel__track--products {
		gap: 14px;
	}

	.carousel__track--products > .carousel__item {
		width: 72vw;
	}

	.carousel__track--tiles {
		gap: 18px;
	}

	.carousel__track--tiles > .carousel__item {
		width: 82vw;
	}

	.carousel__nav {
		display: none;
	}

	.carousel__progress {
		width: calc(100% - (var(--gutter) * 2));
		margin-top: 28px;
	}

	.card__cta {
		opacity: 1;
	}

	.material {
		width: calc(100% - (var(--gutter) * 2));
		aspect-ratio: 3 / 4;
	}

	.material .brackets {
		inset: 24px;
	}

	.footer {
		padding: 44px 0 54px;
	}

	.footer__grid {
		grid-template-columns: 1fr;
		gap: 38px;
	}

	.shop ul.products {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 30px 16px;
	}

	.product-summary {
		padding-bottom: 40px;
	}

	.product-title {
		margin-top: 28px;
	}

	.product-shot {
		width: 84%;
	}

	.product-buy {
		gap: 18px;
		margin-top: 30px;
	}

	.product-links {
		gap: 20px 24px;
	}

	.spec__row {
		grid-template-columns: 1fr;
		gap: 4px;
	}

	.shop-grid {
		gap: 18px 12px;
		padding-top: 22px;
	}

	.shop-chip {
		min-height: 44px;
		padding: 0 18px;
		font-size: 14px;
	}

	.shop-more {
		padding-top: 44px;
	}

	.shop-more__btn {
		width: 100%;
	}

	.page-crumbs__inner {
		min-height: 52px;
		font-size: 14px;
	}

	.account {
		padding: 52px 0 40px;
	}

	.account__lead {
		margin-top: 26px;
		font-size: 16px;
	}

	.account-form__submit,
	.account__submit {
		width: 100%;
	}

	.account-form__submit {
		margin-top: 34px;
	}
}

@media (max-width: 480px) {
	.wordmark {
		font-size: 23px;
	}
}

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	.carousel__viewport {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		transition-duration: 0.01ms !important;
	}
}

/* ------------------------------------------------------ 24. Login page --- */

/*
 * Signed out, the account page is this: the sign-in form on one half, campaign
 * artwork on the other with the guest order-tracking card floated over it. Both
 * halves run to the edge of the viewport, so the page carries no gutter of its
 * own and the service promises below start flush against the artwork.
 */
.site-main.login {
	padding: 0;
}

.site-main.login .section--usp {
	padding-top: 0;
}

.site-main.login .woocommerce-error,
.site-main.login .woocommerce-info,
.site-main.login .woocommerce-message {
	margin-bottom: 30px;
}

.auth {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	min-height: clamp(560px, 38vw, 736px);
}

.auth__panel {
	display: flex;
	flex-direction: column;
	justify-content: center;
	padding: 64px clamp(24px, 7.9vw, 152px);
}

.auth__title {
	font-size: clamp(26px, 2.5vw, 46px);
	font-weight: 700;
	letter-spacing: 0.02em;
	line-height: 1.1;
	text-transform: uppercase;
}

.auth__switch {
	margin-top: 32px;
	font-size: 17px;
}

.auth__switch a {
	color: var(--teal);
}

.auth__switch a:hover,
.auth__switch a:focus-visible {
	text-decoration: underline;
	text-underline-offset: 4px;
}

/*
 * Section 19 frames account forms in a bordered box of their own. On this page
 * the panel and the card are the frame, so that box is taken back off -- by the
 * same selector shapes, since some of them are element-qualified.
 */
.auth .auth-form,
.auth form.login,
.auth form.register {
	max-width: none;
	margin-top: 0;
	padding: 0;
	border: 0;
}

.auth .auth__fields {
	display: grid;
	gap: 24px;
	margin-top: 32px;
}

/*
 * Section 19's field rules are attribute-qualified -- .shop input[type="text"]
 * carries as much weight as a two-class selector -- so the fields here have to
 * be element-qualified too, and the card override below heavier again.
 */
.auth .auth-form input.auth__field {
	width: 100%;
	min-height: 66px;
	padding: 0 24px;
	border: 1px solid var(--line-strong);
	background: var(--white);
	font-size: 17px;
}

.auth .auth-form input.auth__field::placeholder {
	color: var(--muted);
	opacity: 1;
}

.auth .auth-form input.auth__field:focus {
	border-color: var(--ink);
	outline: none;
}

.auth__note,
/* The privacy notice the store hooks into the sign-up form. */
.auth .woocommerce-privacy-policy-text {
	margin-top: 16px;
	color: var(--muted);
	font-size: 15px;
	line-height: 1.6;
}

.auth__lost {
	margin-top: 20px;
	color: var(--ink-soft);
	font-size: 16px;
	text-align: right;
}

.auth__lost a:hover,
.auth__lost a:focus-visible {
	color: var(--ink);
	text-decoration: underline;
	text-underline-offset: 4px;
}

.auth .auth__submit {
	min-height: 66px;
	margin-top: 32px;
	letter-spacing: 0.14em;
}

/*
 * Grey until every field it submits holds something, as in the reference. The
 * class is maintained by initAuthForm() in assets/js/main.js; with no script the
 * button keeps its filled look rather than reading as unavailable.
 */
.auth .auth-form.is-incomplete .auth__submit {
	background: #c8c8c8;
}

/* ---- Artwork, and the guest tracking card over it ---- */

/* .media supplies the artwork and the tone wash; the grid centres the card. */
.auth__aside {
	display: grid;
	place-items: center;
	padding: clamp(28px, 4vw, 76px) clamp(20px, 8vw, 152px);
}

.auth-card {
	position: relative;
	width: min(650px, 100%);
	padding: clamp(28px, 3.9vw, 74px);
	background: var(--white);
}

.auth-card__title {
	font-size: clamp(19px, 1.45vw, 27px);
	font-weight: 700;
	letter-spacing: 0.03em;
	line-height: 1.25;
	text-transform: uppercase;
}

.auth-card__text {
	margin-top: 22px;
	color: var(--ink-soft);
	font-size: 17px;
	line-height: 1.65;
}

.auth .auth-card .auth__fields {
	gap: 22px;
	margin-top: 28px;
}

.auth .auth-card .auth-form input.auth__field {
	min-height: 58px;
}

.auth .auth-card .auth__submit {
	min-height: 60px;
	margin-top: 28px;
}

@media (max-width: 1024px) {
	/* Artwork first would bury the form, so the halves stack form-first. */
	.auth {
		grid-template-columns: minmax(0, 1fr);
		min-height: 0;
	}

	.auth__panel {
		padding: 48px var(--gutter) 56px;
	}

	.auth__aside {
		padding: 48px var(--gutter);
	}
}

@media (max-width: 767px) {
	.auth .auth-form input.auth__field,
	.auth .auth-card .auth-form input.auth__field,
	.auth .auth__submit,
	.auth .auth-card .auth__submit {
		min-height: 56px;
	}

	.auth__lost {
		text-align: left;
	}
}

/* ------------------------------------------------------- 25. Checkout --- */

/*
 * The checkout is a two-column page: the form on the left, the order summary
 * in a grey panel on the right. Both columns sit inside one <form>, so the
 * consent box and the order button can live under the totals where the design
 * puts them and still post with everything else.
 */
.site-main.checkout-page {
	padding: 46px 0 0;
}

.checkout-layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 0.86fr);
	gap: clamp(32px, 3.4vw, 62px);
	align-items: start;
	padding-bottom: 96px;
}

.checkout__title,
.checkout-summary__title {
	font-size: clamp(22px, 1.9vw, 34px);
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	text-align: center;
	line-height: 1.2;
}

.checkout__title {
	margin-bottom: 46px;
}

/* ---- Sign in, or carry on as a guest ---- */

.checkout-access {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

.checkout-access__panel {
	padding-right: clamp(20px, 2.4vw, 44px);
}

/* The rule runs down between the panels and on under the sign-in half only,
   which is what closes that half off from the address form below it. */
.checkout-access__panel:first-child {
	border-right: 1px solid var(--line);
	border-bottom: 1px solid var(--line);
	padding-bottom: 32px;
}

.checkout-access__panel--guest {
	padding-right: 0;
	padding-left: clamp(20px, 2.4vw, 44px);
}

.checkout-access__title {
	margin-bottom: 22px;
	font-size: 18px;
	font-weight: 700;
	letter-spacing: 0.01em;
}

.checkout-access__row {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: end;
	gap: 14px;
}

.checkout-access__submit {
	min-width: 168px;
	min-height: 54px;
	padding: 0 28px;
}

.checkout-access__lost {
	margin-top: 16px;
	font-size: 15px;
	font-style: italic;
}

.checkout-access__lost a {
	text-decoration: underline;
	text-underline-offset: 4px;
}

.checkout-access__lead {
	margin-bottom: 22px;
	font-size: 16px;
	color: var(--ink-soft);
}

/* Deliberately quiet: the guest path is already open below, and this only
   scrolls the shopper to it. */
.checkout-access__guest {
	width: 100%;
	min-height: 54px;
	background: #c6c6c6;
	color: var(--white);
}

.checkout-access__guest:hover,
.checkout-access__guest:focus-visible {
	background: var(--ink);
}

/* ---- Blocks ---- */

/* Not an adjacent-sibling rule: the store drops a <wc-order-attribution-inputs>
   element between two of these, which would break the chain. */
.checkout-layout__main .checkout-block {
	margin-top: 42px;
}

.checkout-layout__main .checkout-block--doc {
	margin-top: 30px;
}

.checkout-block__title {
	margin-bottom: 22px;
	font-size: 18px;
	font-weight: 700;
	letter-spacing: 0.01em;
}

.checkout-block__heading {
	margin-bottom: 24px;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

.checkout-block--payment,
.checkout-block--shipping {
	margin-top: 46px;
}

.checkout-block__empty {
	font-size: 15px;
	color: var(--ink-soft);
}

/* A label, then the two answers in the same two columns the fields use. */
.checkout-choice {
	display: grid;
	grid-template-columns: minmax(0, 0.72fr) repeat(2, minmax(0, 1fr));
	align-items: center;
	gap: 14px 26px;
}

.checkout-choice__label {
	font-size: 17px;
	font-weight: 700;
}

/* ---- Fields ---- */

.checkout-fields {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 20px 26px;
}

.checkout-field {
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	gap: 6px;
	margin: 0;
	min-width: 0;
}

.checkout-field--full,
.checkout-fields > .checkout-field--full {
	grid-column: 1 / -1;
}

.checkout-field__label {
	font-size: 12px;
	font-weight: 400;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--muted);
}

.checkout-field .required {
	color: var(--sale);
	text-decoration: none;
	border: 0;
}

.checkout-field .woocommerce-input-wrapper {
	display: block;
	width: 100%;
}

/*
 * Both woocommerce-general.css and section 19 style these by element and by
 * attribute -- `.woocommerce form .form-row input.input-text` and
 * `.shop input[type="text"]` -- which outweighs a plain class however late it
 * comes in the file. Matching their shape is what makes the sizes stick.
 */
.checkout-page .checkout-form .checkout-field input.checkout-field__input,
.checkout-page .checkout-form .checkout-field select.checkout-field__input,
.checkout-page .checkout-form .checkout-field textarea.checkout-field__input,
.checkout-page .checkout-form .checkout-coupon__row input.checkout-field__input,
.checkout-field__input {
	width: 100%;
	min-height: 54px;
	padding: 0 18px;
	border: 1px solid var(--line-strong);
	border-radius: 0;
	background: var(--white);
	color: var(--ink);
	font-size: 15px;
	line-height: 1.4;
}

.checkout-page .checkout-form .checkout-field textarea.checkout-field__input,
.checkout-page textarea {
	min-height: 152px;
	padding: 16px 18px;
	resize: vertical;
}

.checkout-page .checkout-form .checkout-field select.checkout-field__input,
.checkout-page select {
	appearance: none;
	-webkit-appearance: none;
	padding-right: 46px;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231a1a1a' stroke-width='1.6'%3E%3Cpath d='M3.5 8 12 16.5 20.5 8'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 16px center;
	background-size: 15px;
	cursor: pointer;
}

.checkout-page .checkout-field__input::placeholder,
.checkout-page textarea::placeholder {
	color: var(--muted);
	font-size: 13px;
	letter-spacing: 0.06em;
	opacity: 1;
}

.checkout-page .checkout-form .checkout-field .checkout-field__input:focus,
.checkout-field__input:focus,
.checkout-page select:focus,
.checkout-page textarea:focus {
	outline: none;
	border-color: var(--ink);
}

.checkout-page .woocommerce-invalid .checkout-field__input,
.checkout-page .woocommerce-invalid select {
	border-color: var(--sale);
}

.checkout-invalid-note,
.checkout-page .woocommerce-error {
	margin-bottom: 26px;
}

/* ---- Radios and checkboxes ---- */

.checkout-radio {
	display: inline-flex;
	align-items: center;
	gap: 14px;
	cursor: pointer;
	font-size: 16px;
	line-height: 1.3;
}

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

.checkout-radio__mark {
	position: relative;
	flex: none;
	width: 22px;
	height: 22px;
	border: 1px solid #a8a8a8;
	border-radius: 50%;
	background: var(--white);
	transition: border-color 0.18s var(--ease);
}

.checkout-radio__mark::after {
	content: "";
	position: absolute;
	inset: 4px;
	border-radius: 50%;
	background: var(--black);
	opacity: 0;
	transform: scale(0.4);
	transition: opacity 0.18s var(--ease), transform 0.18s var(--ease);
}

.checkout-radio:hover .checkout-radio__mark,
.checkout-radio__input:checked + .checkout-radio__mark {
	border-color: var(--ink);
}

.checkout-radio__input:checked + .checkout-radio__mark::after {
	opacity: 1;
	transform: scale(1);
}

.checkout-radio__input:focus-visible + .checkout-radio__mark {
	outline: 2px solid var(--ink);
	outline-offset: 3px;
}

.checkout-radio__text {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
}

.checkout-checkbox {
	display: inline-flex;
	align-items: center;
	gap: 14px;
	cursor: pointer;
	font-size: 15px;
}

.checkout-checkbox__input {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
}

.checkout-checkbox__mark {
	position: relative;
	flex: none;
	width: 20px;
	height: 20px;
	border: 1px solid #999;
	background: var(--white);
}

.checkout-checkbox__input:checked + .checkout-checkbox__mark::after {
	content: "";
	position: absolute;
	inset: 3px 4px 5px;
	border-right: 2px solid var(--ink);
	border-bottom: 2px solid var(--ink);
	transform: rotate(40deg);
}

.checkout-options__item + .checkout-options__item {
	margin-top: 28px;
}

.checkout-payment__box {
	margin: 14px 0 0 36px;
	padding: 14px 18px;
	border-left: 2px solid var(--line-strong);
	color: var(--ink-soft);
	font-size: 14px;
	line-height: 1.6;
}

.checkout-payment__box p {
	margin: 0;
}

.checkout-block--notes {
	display: grid;
	gap: 22px;
	margin-top: 46px;
}

.checkout-block--notes .checkout-fields {
	display: block;
}

/* ---- Order summary ---- */

.checkout-layout__aside {
	padding: 42px clamp(24px, 2.4vw, 46px) 48px;
	background: var(--off);
}

.checkout-summary__title {
	margin-bottom: 38px;
}

.checkout-summary__item {
	display: grid;
	grid-template-columns: clamp(96px, 8vw, 150px) minmax(0, 1fr) auto;
	align-items: start;
	gap: 0 26px;
}

.checkout-summary__item + .checkout-summary__item {
	margin-top: 40px;
}

.checkout-summary__media {
	aspect-ratio: 1;
	background: var(--white);
}

.checkout-summary__img {
	object-fit: contain;
}

/* Stands in for the shot while no photography is attached. */
.checkout-summary__media[class*="media--"] {
	background-image: none;
	background-color: var(--white);
}

.checkout-summary__media::after {
	content: "";
	position: absolute;
	inset: 12%;
	border-radius: 8px;
	background: currentColor;
	opacity: 0.1;
}

.checkout-summary__media:has(img)::after {
	display: none;
}

.checkout-summary__media.media--forest   { color: #12563a; }
.checkout-summary__media.media--yellow   { color: #eda31d; }
.checkout-summary__media.media--graphite { color: #3a3c3f; }
.checkout-summary__media.media--silver   { color: #a9b1af; }
.checkout-summary__media.media--navy     { color: #123a6b; }
.checkout-summary__media.media--petrol   { color: #0f5f66; }
.checkout-summary__media.media--mist     { color: #7d94a4; }
.checkout-summary__media.media--sand     { color: #b99e70; }
.checkout-summary__media.media--pale     { color: #9aa4ab; }
.checkout-summary__media.media--peach    { color: #dd9670; }
.checkout-summary__media.media--stone    { color: #2f3841; }
.checkout-summary__media.media--sage     { color: #9dab96; }
.checkout-summary__media.media--deep     { color: #16303f; }
.checkout-summary__media.media--ice      { color: #3d7fb0; }
.checkout-summary__media.media--jungle   { color: #3d4a31; }

.checkout-summary__name {
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	line-height: 1.3;
}

.checkout-summary__meta {
	margin-top: 8px;
	color: var(--ink-soft);
	font-size: 14px;
}

.checkout-summary__qty {
	margin-top: 14px;
	color: var(--ink-soft);
	font-size: 15px;
}

.checkout-summary__price {
	display: flex;
	align-items: baseline;
	gap: 12px;
	white-space: nowrap;
}

.checkout-summary__price del {
	color: var(--muted);
	font-size: 15px;
	text-decoration-thickness: 1px;
}

.checkout-summary__price ins {
	font-size: 17px;
	font-weight: 700;
	text-decoration: none;
}

/* ---- Coupon ---- */

.checkout-coupon {
	margin-top: 44px;
	padding-top: 38px;
	border-top: 1px solid var(--line-strong);
}

.checkout-coupon__title {
	margin-bottom: 18px;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.checkout-coupon__row {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	gap: 14px;
}

.checkout-coupon__apply {
	min-width: 160px;
	min-height: 54px;
	padding: 0 26px;
}

.checkout-coupon__notice:empty {
	display: none;
}

.checkout-coupon__notice {
	margin-top: 14px;
	font-size: 14px;
}

.checkout-coupon__notice ul,
.checkout-coupon__notice .woocommerce-error,
.checkout-coupon__notice .woocommerce-message {
	margin: 0;
	padding: 0;
	list-style: none;
}

.checkout-coupon__notice .woocommerce-error {
	color: var(--sale);
}

/* ---- Totals ---- */

.checkout-totals {
	margin: 34px 0 0;
}

.checkout-totals__row {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 20px;
	padding: 14px 0;
}

.checkout-totals__label {
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.checkout-totals__value {
	margin: 0;
	font-size: 17px;
	white-space: nowrap;
}

.checkout-totals__row--coupon .checkout-totals__label {
	font-weight: 400;
	letter-spacing: 0.02em;
	text-transform: none;
}

.checkout-totals__row--coupon a {
	margin-left: 10px;
	color: var(--sale);
	font-size: 13px;
	text-decoration: underline;
	text-underline-offset: 3px;
}

.checkout-totals__row--total {
	margin-top: 12px;
	padding-top: 26px;
	border-top: 1px solid var(--line-strong);
}

.checkout-totals__row--total .checkout-totals__label {
	font-size: 19px;
	letter-spacing: 0.08em;
}

.checkout-totals__row--total .checkout-totals__value {
	font-size: 24px;
	font-weight: 700;
}

/* ---- Consent and the order button ---- */

.checkout-submit {
	margin-top: 34px;
}

/*
 * The row above the order button is a link to the privacy policy, not a consent
 * checkbox -- nothing has to be ticked to place an order -- so it is typed like
 * the store's other small print rather than like a form control.
 */
.checkout-privacy {
	margin: 0 0 30px;
	font-size: 13px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.checkout-privacy__link {
	text-decoration: none;
	font-weight: 700;
}

.checkout-privacy__link:hover,
.checkout-privacy__link:focus-visible {
	text-decoration: underline;
	text-underline-offset: 4px;
}

.checkout-submit__button {
	min-height: 64px;
}

/* The store blocks the form while it refreshes; keep that legible rather than
   letting its overlay wash the panel out. */
.checkout-page .blockUI.blockOverlay {
	opacity: 0.35 !important;
	background: var(--white) !important;
}

/* ---- Narrower screens ---- */

@media (max-width: 1200px) {
	.checkout-layout {
		grid-template-columns: minmax(0, 1fr);
		gap: 44px;
	}

	/* One column runs title, form, summary, order button -- the summary is not
	   pulled above the heading, which would read as the top of the page. */
}

@media (max-width: 860px) {
	.checkout-access {
		grid-template-columns: minmax(0, 1fr);
	}

	.checkout-access__panel {
		padding-right: 0;
	}

	.checkout-access__panel:first-child {
		border-right: 0;
		margin-bottom: 28px;
		padding-bottom: 28px;
	}

	.checkout-access__panel--guest {
		padding-left: 0;
	}

	.checkout-choice {
		grid-template-columns: minmax(0, 1fr);
		gap: 16px;
	}

	.checkout-fields {
		grid-template-columns: minmax(0, 1fr);
	}

	.checkout-summary__item {
		grid-template-columns: 84px minmax(0, 1fr);
	}

	.checkout-summary__price {
		grid-column: 2;
		margin-top: 10px;
	}
}

@media (max-width: 560px) {
	.checkout-access__row {
		grid-template-columns: minmax(0, 1fr);
		align-items: stretch;
	}

	.checkout-coupon__row {
		grid-template-columns: minmax(0, 1fr);
	}

	.checkout-access__submit,
	.checkout-coupon__apply {
		width: 100%;
	}
}

/* ---- Checkout: out-specifying the store's own stylesheet ---- */

/*
 * woocommerce-general.css loads after this file, so its checkout rules have to
 * be answered rather than just restated: it paints the payment list lilac,
 * gives the description box a speech-bubble tail, and sets a 4em textarea.
 */
.checkout-page .checkout-fields > [hidden],
.checkout-page [hidden] {
	display: none;
}

/* Neither marker is drawn in the form itself -- the placeholder carries the
   field's name, and the two selects are plain. The sign-in panel keeps its
   asterisk, and lives outside this wrapper. */
.checkout-fields .required,
.checkout-fields .optional,
.checkout-field--stacked .required,
.checkout-field--stacked .optional {
	display: none;
}

.checkout-access .required {
	color: var(--sale);
	text-decoration: none;
}

.woocommerce-checkout .checkout-payment,
.woocommerce-checkout #payment {
	background: transparent;
	border-radius: 0;
}

.woocommerce-checkout #payment ul.payment_methods {
	padding: 0;
	border: 0;
}

.woocommerce-checkout #payment div.payment_box {
	width: auto;
	margin: 14px 0 0 36px;
	padding: 14px 18px;
	background: transparent;
	border-left: 2px solid var(--line-strong);
	border-radius: 0;
	color: var(--ink-soft);
	font-size: 14px;
	line-height: 1.6;
}

.woocommerce-checkout #payment div.payment_box::before,
.woocommerce-checkout #payment div.payment_box::after {
	display: none;
}

.woocommerce-checkout #payment div.form-row {
	padding: 0;
}

.woocommerce-checkout #payment ul.payment_methods li {
	line-height: inherit;
}

.woocommerce-checkout #payment ul.payment_methods li + li {
	margin-top: 28px;
}

.site-main.checkout-page form .form-row textarea,
.checkout-page textarea {
	height: auto;
	min-height: 152px;
}

.site-main.checkout-page form .form-row {
	margin: 0;
	padding: 0;
}

.site-main.checkout-page form .form-row label {
	line-height: inherit;
}

/* The store's own field styling is written against .shop, which the checkout
   also carries. */
.site-main.checkout-page .checkout-field input.input-text,
.site-main.checkout-page .checkout-field select,
.site-main.checkout-page .checkout-field textarea,
.site-main.checkout-page .input-text,
.site-main.checkout-page select,
.site-main.checkout-page textarea {
	border-color: var(--line-strong);
}

.checkout-page .woocommerce-notices-wrapper .woocommerce-message,
.checkout-page .woocommerce-notices-wrapper .woocommerce-error,
.checkout-page .woocommerce-notices-wrapper .woocommerce-info {
	margin-bottom: 22px;
}

/* ---------------------------------------------------------- 26. Cart --- */

/*
 * The cart is two columns divided by a rule: the lines and the help block on
 * the left, the shipping choice, promotional code and totals on the right. The
 * summary is the wider of the two -- its rows run the full width of the column
 * and price against the right edge of the page.
 *
 * The store's cart script replaces .woocommerce-cart-form and .cart_totals
 * wholesale as things change, so every rule below hangs off a class inside one
 * of them rather than off their position in the layout.
 */
.site-main.cart-page {
	padding: 48px 0 0;
}

/* No align-items here on purpose: both columns stretch to the row height, which
   is what carries the dividing rule the full way down the taller of the two. */
.cart-layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
	padding-bottom: 96px;
}

.cart-layout__main {
	min-width: 0;
	padding-right: clamp(20px, 2.6vw, 48px);
}

.cart-layout__aside {
	min-width: 0;
	border-left: 1px solid var(--line);
	padding-left: clamp(24px, 4vw, 76px);
}

.cart__title {
	margin-bottom: clamp(30px, 3.2vw, 62px);
	font-size: clamp(22px, 1.9vw, 34px);
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	line-height: 1.2;
}

/* ---- Lines ---- */

/*
 * Name, choice and remove link above a rule; quantity and price below it, with
 * the thumbnail spanning both. The rule is the body's own bottom border, so it
 * starts at the name and ends at the price -- never under the thumbnail.
 */
.cart-item {
	display: grid;
	grid-template-columns: clamp(120px, 12vw, 190px) minmax(0, 1fr) auto;
	align-items: start;
	column-gap: clamp(16px, 1.6vw, 28px);
}

.cart-item + .cart-item {
	margin-top: clamp(30px, 4.7vw, 90px);
}

/* Product shots sit on white at their full silhouette, as they do everywhere
   else in the theme, so the tone the line carries is left to the stand-in. */
.cart-item__media {
	grid-row: 1 / 3;
	aspect-ratio: 1;
	background: var(--white);
}

.cart-item__img {
	object-fit: contain;
}

.cart-item__media::after {
	content: "";
	position: absolute;
	inset: 14%;
	border-radius: 8px;
	background: #e4e4e4;
}

.cart-item__media:has(img)::after {
	display: none;
}

.cart-item__body {
	grid-column: 2 / -1;
	padding-bottom: clamp(18px, 1.6vw, 28px);
	border-bottom: 1px solid var(--line);
}

.cart-item__name {
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	line-height: 1.3;
}

.cart-item__meta {
	margin-top: 9px;
	color: var(--ink-soft);
	font-size: 15px;
}

.cart-item__remove {
	margin-top: 18px;
}

.cart-item__remove-link {
	display: inline-flex;
	align-items: center;
	gap: 11px;
	font-size: 15px;
}

.cart-item__remove-link:hover,
.cart-item__remove-link:focus-visible {
	color: var(--muted);
}

.cart-item__remove-link .icon {
	flex: none;
}

.cart-item__qty {
	grid-column: 2;
	grid-row: 2;
	display: flex;
	align-items: center;
	gap: 16px;
	padding-top: clamp(18px, 1.9vw, 36px);
}

.cart-item__qty-label {
	color: var(--muted);
	font-size: 15px;
}

/* Element-qualified: .shop select would otherwise stretch this to the full
   column and give it the store's own box. */
.shop select.cart-qty {
	width: auto;
	min-width: 64px;
	min-height: 34px;
	padding: 0 30px 0 12px;
	appearance: none;
	-webkit-appearance: none;
	border: 1px solid var(--line-strong);
	border-radius: 0;
	background-color: var(--white);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231a1a1a' stroke-width='1.6'%3E%3Cpath d='M3.5 8 12 16.5 20.5 8'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 9px center;
	background-size: 12px;
	font-size: 15px;
	cursor: pointer;
}

.shop select.cart-qty:focus {
	outline: none;
	border-color: var(--ink);
}

.cart-item__price {
	grid-column: 3;
	grid-row: 2;
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 5px;
	padding-top: clamp(18px, 1.9vw, 36px);
	white-space: nowrap;
}

.cart-item__price del {
	color: var(--muted);
	font-size: 15px;
	text-decoration-thickness: 1px;
}

.cart-item__price ins {
	font-size: 18px;
	font-weight: 700;
	text-decoration: none;
}

/* The quantity select is the instruction, so the script hides this. It is what
   posts the change when no script is running -- see woocommerce/cart/cart.php. */
.cart-form__update {
	margin-top: 26px;
	font-size: 14px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	text-decoration: underline;
	text-underline-offset: 4px;
}

.cart-form__update[hidden] {
	display: none;
}

.cart-form__update:disabled {
	color: var(--muted-light);
	cursor: default;
	text-decoration: none;
}

/* ---- Need help ---- */

.cart-help {
	margin-top: clamp(36px, 3.4vw, 60px);
	padding: clamp(26px, 2.2vw, 36px) 0;
	border-top: 1px solid var(--line);
	border-bottom: 1px solid var(--line);
}

.cart-help__title {
	margin-bottom: 26px;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

.cart-help__item + .cart-help__item {
	margin-top: 22px;
}

.cart-help__label {
	display: inline-block;
	font-size: 17px;
	font-weight: 700;
}

a.cart-help__label:hover,
a.cart-help__label:focus-visible {
	text-decoration: underline;
	text-underline-offset: 5px;
}

.cart-help__value {
	margin-top: 6px;
	color: var(--muted);
	font-size: 16px;
}

.cart-help__value a:hover,
.cart-help__value a:focus-visible {
	color: var(--ink);
	text-decoration: underline;
	text-underline-offset: 4px;
}

/* ---- Summary column ---- */

.cart-summary__title {
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

/* ---- How the order travels ---- */

.cart-shipping {
	margin-bottom: clamp(24px, 2vw, 36px);
}

.cart-shipping .cart-summary__title {
	margin-bottom: 32px;
}

.cart-shipping__empty {
	color: var(--ink-soft);
	font-size: 15px;
}

.cart-shipping__item + .cart-shipping__item {
	margin-top: 14px;
}

/* Flex rather than a grid: the radio mark is absent when there is only one rate
   to offer, and the name and price should not move when it is. */
.cart-option {
	display: flex;
	align-items: flex-start;
	gap: 18px;
	padding: clamp(22px, 1.8vw, 32px) clamp(18px, 1.6vw, 26px);
	border: 1px solid var(--line);
	cursor: pointer;
	transition: border-color 0.18s var(--ease);
}

.cart-shipping__item.is-chosen .cart-option {
	border-color: var(--line-strong);
}

/* One rate is a statement, not a choice: nothing here is clickable. */
.cart-option--fixed {
	cursor: default;
}

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

.cart-option__mark {
	position: relative;
	flex: none;
	width: 22px;
	height: 22px;
	border: 1px solid #a8a8a8;
	border-radius: 50%;
	background: var(--white);
	transition: border-color 0.18s var(--ease);
}

.cart-option__mark::after {
	content: "";
	position: absolute;
	inset: 4px;
	border-radius: 50%;
	background: var(--black);
	opacity: 0;
	transform: scale(0.4);
	transition: opacity 0.18s var(--ease), transform 0.18s var(--ease);
}

.cart-option:hover .cart-option__mark,
.cart-option__input:checked + .cart-option__mark {
	border-color: var(--ink);
}

.cart-option__input:checked + .cart-option__mark::after {
	opacity: 1;
	transform: scale(1);
}

.cart-option__input:focus-visible + .cart-option__mark {
	outline: 2px solid var(--ink);
	outline-offset: 3px;
}

.cart-option__text {
	flex: 1 1 auto;
	min-width: 0;
}

.cart-option__name {
	display: block;
	font-size: 17px;
	line-height: 1.3;
}

.cart-option__note {
	display: block;
	margin-top: 7px;
	color: var(--muted);
	font-size: 15px;
	line-height: 1.4;
}

.cart-option__price {
	flex: none;
	font-size: 17px;
	line-height: 1.3;
	white-space: nowrap;
}

/* ---- Promotional code ---- */

.cart-coupon {
	margin-bottom: clamp(24px, 2vw, 36px);
	padding: clamp(18px, 1.5vw, 24px) 0;
	border-top: 1px solid var(--line);
	border-bottom: 1px solid var(--line);
}

/* A <summary>: the marker is dropped in both of the ways browsers ask for, and
   the row keeps the icon the design gives it instead. */
.cart-coupon__toggle {
	display: flex;
	align-items: center;
	gap: 12px;
	width: fit-content;
	list-style: none;
	cursor: pointer;
	font-size: 17px;
	text-align: left;
}

.cart-coupon__toggle::-webkit-details-marker {
	display: none;
}

.cart-coupon__toggle:hover,
.cart-coupon__toggle:focus-visible {
	color: var(--muted);
}

.cart-coupon__panel {
	margin-top: 22px;
}

.cart-coupon__form {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	gap: 12px;
	max-width: 540px;
}

.shop input[type="text"].cart-coupon__input {
	min-height: 54px;
	padding: 0 18px;
	border: 1px solid var(--line-strong);
	border-radius: 0;
	background: var(--white);
	font-size: 15px;
}

.shop input[type="text"].cart-coupon__input:focus {
	outline: none;
	border-color: var(--ink);
}

.cart-coupon__apply {
	min-width: 148px;
	min-height: 54px;
	padding: 0 26px;
}

.cart-coupon__notice {
	margin-top: 14px;
	font-size: 14px;
}

.cart-coupon__notice:empty {
	display: none;
}

/* Answered as plain text beside the field, not as one of the store's banners --
   .shop .woocommerce-error would otherwise box and tint it. */
.cart-coupon__notice ul,
.cart-coupon__notice .woocommerce-error,
.cart-coupon__notice .woocommerce-message,
.cart-coupon__notice .woocommerce-info {
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	list-style: none;
}

.cart-coupon__notice .woocommerce-error {
	color: var(--sale);
}

/* ---- Totals ---- */

.cart-summary .cart-totals {
	margin: 0;
}

.cart-summary > .cart-summary__title {
	margin-bottom: 28px;
}

.cart-totals__row {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 20px;
	padding: 16px 0;
}

.cart-totals__label {
	font-size: 17px;
}

.cart-totals__value {
	margin: 0;
	font-size: 17px;
	white-space: nowrap;
}

.cart-totals__row--coupon .cart-totals__label {
	color: var(--ink-soft);
}

.cart-totals__row--coupon a {
	margin-left: 10px;
	color: var(--sale);
	font-size: 13px;
	text-decoration: underline;
	text-underline-offset: 3px;
}

.cart-totals__row--total {
	margin-top: 4px;
	padding-top: 26px;
	border-top: 1px solid var(--line);
}

.cart-totals__row--total .cart-totals__label {
	font-weight: 700;
}

.cart-totals__row--total .cart-totals__value {
	font-size: 22px;
	font-weight: 700;
}

/* ---- On to the checkout ---- */

.cart-summary__actions {
	margin-top: 30px;
}

/* Wide columns do not want a button their own width; the design gives it one. */
.cart-summary__checkout {
	display: flex;
	width: 100%;
	max-width: 374px;
	min-height: 64px;
}

/* ---- Nothing in it yet ---- */

.cart-blank {
	max-width: 620px;
	padding-bottom: 96px;
}

.cart-blank__title {
	margin-bottom: 24px;
}

/* The store says this in an information banner; here it is simply the answer to
   the heading above it. Not tied to the wrapper it arrives in: emptying the cart
   over AJAX moves the line out into the notices wrapper beside it. */
.cart-blank .woocommerce-info {
	margin: 0 0 32px;
	padding: 0;
	border: 0;
	background: none;
	color: var(--ink-soft);
	font-size: 17px;
}

.cart-blank__cta {
	min-width: 300px;
}

/* ---- The store's own notices ---- */

/*
 * Every store notice carries a glyph from WooCommerce's icon font, absolutely
 * placed 1.5em in -- which lands on top of the words as soon as the notice is
 * not wearing the store's own padding. The wording says everything the mark
 * would, so it goes.
 */
.cart-page .woocommerce-info::before,
.cart-page .woocommerce-message::before,
.cart-page .woocommerce-error::before {
	display: none;
}

/* The store blocks the page while it refreshes; keep that legible rather than
   letting its overlay wash the column out. */
.cart-page .blockUI.blockOverlay {
	opacity: 0.35 !important;
	background: var(--white) !important;
}

/* ---- Narrower screens ---- */

@media (max-width: 1200px) {
	.cart-layout {
		grid-template-columns: minmax(0, 1fr);
	}

	.cart-layout__main {
		padding-right: 0;
	}

	.cart-layout__aside {
		margin-top: clamp(36px, 4vw, 52px);
		padding-top: clamp(30px, 3vw, 44px);
		padding-left: 0;
		border-left: 0;
		border-top: 1px solid var(--line);
	}

	.cart-summary__checkout {
		max-width: none;
	}
}

@media (max-width: 560px) {
	.cart-item {
		grid-template-columns: 84px minmax(0, 1fr);
		column-gap: 16px;
	}

	.cart-item__media {
		grid-row: 1 / 4;
	}

	.cart-item__qty {
		grid-column: 2;
	}

	.cart-item__price {
		grid-column: 2;
		grid-row: 3;
		align-items: flex-start;
		padding-top: 12px;
	}

	.cart-coupon__form {
		grid-template-columns: minmax(0, 1fr);
	}

	.cart-coupon__apply {
		width: 100%;
	}

	.cart-blank__cta {
		width: 100%;
		min-width: 0;
	}
}

/* ------------------------------------------------------- 27. Compare --- */

/*
 * The comparison is one grid: a label column, then a column per chosen product.
 * The head row, the "Specification" band and every specification row share the
 * same column template, so a value always sits under the product it describes
 * however many products are being compared.
 *
 * --compare-cols is written onto the wrapper by the template.
 */

.compare__head,
.compare__spec-title,
.compare__row,
.compare__pin-inner {
	display: grid;
	grid-template-columns: 1.45fr repeat(var(--compare-cols, 3), minmax(0, 1fr));
	align-items: start;
}

.compare__title {
	display: flex;
	align-items: center;
	gap: 14px;
	padding-right: 24px;
	font-size: clamp(16px, 1.1vw, 19px);
	font-weight: 700;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	line-height: 1.3;
}

/* ---- Head row: artwork, name, price ---- */

.compare__media {
	aspect-ratio: 5 / 6;
	margin-bottom: 26px;
	background: var(--white);
}

/* Product shots keep their whole silhouette rather than filling the cell. */
.compare__img {
	object-fit: contain;
	padding: 4%;
}

/* Stands in for the shot while no photography is attached. */
.compare__media[class*="media--"] {
	background-image: none;
	background-color: var(--white);
}

.compare__media::after {
	content: "";
	position: absolute;
	inset: 8% 16%;
	border-radius: 10px;
	background: #ededed;
}

.compare__media:has(img)::after {
	display: none;
}

.compare__name {
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	line-height: 1.3;
}

.compare__subtitle {
	margin-top: 9px;
	font-size: 15px;
	line-height: 1.4;
}

.compare__price {
	display: flex;
	flex-direction: column;
	gap: 7px;
	margin-top: 11px;
}

.compare__price del {
	color: var(--muted);
	font-size: 15px;
	text-decoration-thickness: 1px;
}

.compare__price ins {
	font-size: 18px;
	font-weight: 700;
	text-decoration: none;
}

.compare__price .woocommerce-Price-amount {
	white-space: nowrap;
}

/* ---- Specification ---- */

/*
 * The band and the row rules bleed 16px past the container so their background
 * and their dividers start outside the first label, while the padding puts the
 * text back on the container's edge -- which is what keeps the columns lined up
 * with the artwork above.
 */
.compare__spec {
	margin: clamp(38px, 4.6vw, 84px) -16px 0;
}

.compare__spec-title,
.compare__row {
	padding: 18px 16px;
}

.compare__spec-title {
	background: var(--off);
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.09em;
	text-transform: uppercase;
}

.compare__row {
	border-bottom: 1px solid var(--line);
}

.compare__row-key,
.compare__row-value {
	margin: 0;
	font-size: 15px;
	line-height: 1.5;
}

.compare__row-key {
	padding-right: 24px;
}

/* ---- The bar that pins under the header ---- */

/*
 * Position-fixed rather than sticky: it replaces the head row once that has
 * scrolled behind the site header, and a sticky head that collapsed instead
 * would drop its own height out of the flow mid-scroll and jump the table.
 * Below the header's z-index, so the header still covers it.
 */
.compare__pin {
	position: fixed;
	top: calc(var(--header-h) + var(--admin-bar-height));
	right: 0;
	left: 0;
	z-index: 40;
	padding: 26px 0 30px;
	background: var(--white);
	box-shadow: 0 16px 26px -20px rgba(0, 0, 0, 0.35);
	opacity: 0;
	visibility: hidden;
	transform: translateY(-10px);
	transition: opacity 0.22s var(--ease), transform 0.22s var(--ease), visibility 0.22s;
}

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

.compare__title--pin {
	font-size: clamp(15px, 1vw, 17px);
}

/* ---- Nothing chosen, and the wait for the browser's list ---- */

.compare-empty {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 26px;
	padding: clamp(30px, 5vw, 80px) 0;
	text-align: center;
}

.compare-empty__text {
	color: var(--ink-soft);
	font-size: 17px;
}

.compare-page__body.is-busy {
	opacity: 0.35;
	transition: opacity 0.2s var(--ease);
}

.compare-page__intro {
	margin-bottom: clamp(24px, 3vw, 44px);
}

/* ---- The floating tray ---- */

/*
 * Collapsed the tray is one round button; open, the button grows into the
 * labelled bar and the panel of chosen products rises above it. The panel is
 * taken out of flow so the wrapper is only ever as wide as the button, and the
 * page behind it stays clickable while the tray is shut.
 */
.compare-tray {
	/* Brighter than --teal, which the theme keeps for links. */
	--tray-teal: #17bfae;
	--tray-teal-dark: #12a696;

	position: fixed;
	right: var(--gutter);
	bottom: clamp(20px, 3.4vw, 64px);
	z-index: 55;
}

.compare-tray[hidden] {
	display: none;
}

/* Dims the page the tray is sitting over, and swallows clicks on it. */
.compare-tray::before {
	content: "";
	position: fixed;
	inset: 0;
	z-index: -1;
	background: rgba(0, 0, 0, 0.45);
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.25s var(--ease), visibility 0.25s;
}

.compare-tray.is-open::before {
	opacity: 1;
	visibility: visible;
}

.compare-tray__toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 14px;
	width: 62px;
	min-height: 62px;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background: var(--tray-teal);
	color: var(--white);
	cursor: pointer;
	box-shadow: 0 14px 26px rgba(0, 0, 0, 0.22);
	transition: background-color 0.2s var(--ease);
}

.compare-tray__toggle:hover,
.compare-tray__toggle:focus-visible {
	background: var(--tray-teal-dark);
}

.compare-tray.is-open .compare-tray__toggle {
	width: min(470px, calc(100vw - 2 * var(--gutter)));
	justify-content: flex-start;
	padding: 0 24px;
}

.compare-tray__label,
.compare-tray__chevron {
	display: none;
}

.compare-tray.is-open .compare-tray__label {
	display: block;
	flex: 1 1 auto;
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	text-align: left;
	line-height: 1.2;
}

.compare-tray.is-open .compare-tray__chevron {
	display: block;
}

.compare-tray__count {
	font-weight: 400;
	letter-spacing: 0.04em;
}

.compare-tray__panel {
	position: absolute;
	right: 0;
	bottom: calc(100% + 12px);
	display: flex;
	flex-direction: column;
	width: min(470px, calc(100vw - 2 * var(--gutter)));
	padding: 14px 20px 22px;
	border-radius: 18px;
	background: var(--white);
	box-shadow: 0 26px 46px rgba(0, 0, 0, 0.22);
	opacity: 0;
	visibility: hidden;
	transform: translateY(14px);
	transition: opacity 0.24s var(--ease), transform 0.24s var(--ease), visibility 0.24s;
}

.compare-tray.is-open .compare-tray__panel {
	opacity: 1;
	visibility: visible;
	transform: none;
}

.compare-tray__panel:focus {
	outline: none;
}

/* A long list scrolls; the button below it stays put. */
.compare-tray__items {
	max-height: min(46vh, 420px);
	overflow-y: auto;
	overscroll-behavior: contain;
}

.compare-tray__empty {
	padding: 12px 0;
	color: var(--ink-soft);
	font-size: 15px;
}

.compare-tray__item {
	display: grid;
	grid-template-columns: 70px minmax(0, 1fr) 26px;
	align-items: start;
	gap: 0 18px;
	padding: 16px 0;
}

.compare-tray__media {
	aspect-ratio: 4 / 5;
	background: var(--white);
}

.compare-tray__media[class*="media--"] {
	background-image: none;
	background-color: var(--white);
}

.compare-tray__media .compare__img {
	object-fit: contain;
}

.compare-tray__media::after {
	content: "";
	position: absolute;
	inset: 7% 12%;
	border-radius: 8px;
	background: #ededed;
}

.compare-tray__media:has(img)::after {
	display: none;
}

.compare-tray__name {
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	line-height: 1.3;
}

.compare-tray__subtitle {
	margin-top: 7px;
	font-size: 15px;
	line-height: 1.4;
}

.compare-tray__price {
	display: flex;
	flex-direction: column;
	gap: 5px;
	margin-top: 9px;
}

.compare-tray__price del {
	color: var(--muted);
	font-size: 15px;
	text-decoration-thickness: 1px;
}

.compare-tray__price ins {
	font-size: 17px;
	font-weight: 700;
	text-decoration: none;
}

.compare-tray__remove {
	padding: 0;
	border: 0;
	background: none;
	color: var(--black);
	cursor: pointer;
	line-height: 0;
}

.compare-tray__remove:hover {
	color: var(--ink-soft);
}

.compare-tray__cta {
	margin-top: 14px;
}

/* ---- Narrower screens ---- */

@media (max-width: 1024px) {
	/*
	 * The table scrolls sideways below this width, so a bar fixed to the
	 * viewport could no longer stay above the column it labels.
	 */
	.compare__pin {
		display: none;
	}

	.compare__body {
		overflow-x: auto;
		overscroll-behavior-x: contain;
		padding-bottom: 10px;
	}

	/*
	 * Sized tracks rather than proportions: the label only needs room for its
	 * word, and what is left goes to the products, so the least scrolling is
	 * needed to read one. The floor grows with the number of columns.
	 */
	.compare__head,
	.compare__spec-title,
	.compare__row {
		grid-template-columns: 140px repeat(var(--compare-cols, 3), minmax(200px, 1fr));
		column-gap: 20px;
	}

	.compare__head,
	.compare__spec {
		min-width: calc(140px + var(--compare-cols, 3) * 220px);
	}

	/* Trimmed to fit "Product comparison" inside the narrower label column. */
	.compare__title {
		gap: 10px;
		padding-right: 10px;
		font-size: 15px;
		letter-spacing: 0.04em;
	}

	.compare__title .icon {
		width: 20px;
		height: 20px;
	}

	.compare__spec {
		margin-inline: 0;
	}

	.compare__spec-title,
	.compare__row {
		padding-inline: 0;
	}
}

@media (max-width: 560px) {
	.compare-tray {
		right: var(--gutter);
		left: var(--gutter);
		bottom: 18px;
	}

	.compare-tray__toggle,
	.compare-tray.is-open .compare-tray__toggle {
		width: 100%;
		justify-content: flex-start;
		padding: 0 20px;
	}

	/*
	 * Room is too short for the round-button state to be worth keeping, so the
	 * bar is always labelled. Written at the same weight as the .is-open rules
	 * above so it wins whichever state the tray is in.
	 */
	.compare-tray .compare-tray__label,
	.compare-tray .compare-tray__chevron {
		display: block;
	}

	.compare-tray .compare-tray__label,
	.compare-tray.is-open .compare-tray__label {
		flex: 1 1 auto;
		font-size: 13px;
		font-weight: 700;
		letter-spacing: 0.08em;
		text-transform: uppercase;
		text-align: left;
		line-height: 1.2;
	}

	.compare-tray__panel {
		width: 100%;
		max-height: min(70vh, 520px);
	}

	.compare-tray__item {
		grid-template-columns: 58px minmax(0, 1fr) 26px;
		gap: 0 14px;
	}
}

/* --------------------------------------------- 28. Registration page --- */

/*
 * The account-creation page: a help sidebar on the left, the sign-up form on a
 * tinted panel on the right. The panel runs to the right edge of the viewport
 * rather than stopping at the container gutter, so the grid is full-bleed and
 * each column pays for its own gutter -- the same arrangement the catalogue
 * uses in section 20.
 *
 * <main> already carries site-main--flush, which section 22 zeroes the
 * inner-page padding for, so the breadcrumb band sits straight under the header.
 */

.reg {
	--reg-side: clamp(300px, 24.8vw, 476px);

	display: grid;
	grid-template-columns: var(--reg-side) minmax(0, 1fr);
	align-items: start;
}

/* ---- Sidebar ---- */

.reg__side {
	padding: 58px 40px 90px var(--gutter);
	border-right: 1px solid var(--line);
}

.reg-side__title {
	font-size: clamp(27px, 2.4vw, 38px);
	font-weight: 700;
	letter-spacing: 0.01em;
	line-height: 1.15;
	text-transform: uppercase;
}

.reg-side__block {
	margin-top: 62px;
}

.reg-side__heading {
	margin-bottom: 26px;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

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

.reg-nav__item {
	display: flex;
	align-items: center;
	gap: 24px;
}

/* The ring is the design's; the glyph inside it is the header's account icon. */
.reg-nav__disc {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: 54px;
	height: 54px;
	border: 1px solid var(--line-strong);
	border-radius: 50%;
}

.reg-nav__label {
	font-size: 15px;
	font-weight: 600;
	letter-spacing: 0.05em;
	text-transform: uppercase;
}

/* ---- Need help? ---- */

.reg-help__list {
	display: grid;
	gap: 28px;
}

.reg-help__item {
	display: grid;
	grid-template-columns: 32px minmax(0, 1fr);
	gap: 20px;
	align-items: start;
}

.reg-help__icon {
	display: inline-flex;
	padding-top: 2px;
}

.reg-help__label {
	display: block;
	font-size: 15px;
	font-weight: 700;
	line-height: 1.4;
}

a.reg-help__label:hover {
	text-decoration: underline;
	text-underline-offset: 3px;
}

.reg-help__value {
	margin-top: 6px;
	font-size: 15px;
}

.reg-help__value a {
	color: var(--link);
}

.reg-help__value a:hover {
	text-decoration: underline;
}

.reg-help__line {
	margin-top: 5px;
	color: var(--ink-soft);
	font-size: 15px;
}

/* ---- Form column ---- */

.reg__main {
	min-width: 0;
}

.reg-main__title {
	padding: 44px 40px 26px var(--gutter);
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.reg-panel {
	padding: 58px 40px 90px var(--gutter);
	background: var(--off);
}

.reg-form__grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 29px 37px;
}

/* Holds the field and, under the password, its length hint. */
.reg-form__row {
	display: flex;
	flex-direction: column;
	margin: 0;
}

/*
 * Element-qualified on purpose. This page is not a WooCommerce page, so it does
 * not pick up section 19's `.shop input[type="text"]` block today -- but that
 * block is (0,2,1) and would silently win the moment anything adds the class,
 * so the field is stated at (0,2,1) too.
 */
.reg-form input.reg-form__input {
	width: 100%;
	min-height: 60px;
	padding: 0 26px;
	border: 1px solid var(--line);
	border-radius: 0;
	background: var(--white);
	color: var(--ink);
	font-size: 16px;
}

.reg-form input.reg-form__input::placeholder {
	color: var(--muted);
	opacity: 1;
}

.reg-form input.reg-form__input:focus {
	border-color: var(--ink);
	outline: none;
}

.reg-form input.reg-form__input.is-invalid {
	border-color: var(--sale);
}

.reg-form__hint {
	display: block;
	margin-top: 13px;
	font-size: 15px;
	color: var(--ink);
}

/* ---- Consent rows ---- */

.reg-consent {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	gap: 13px;
	align-items: start;
	margin: 0;
}

.reg-form__grid + .reg-consent {
	margin-top: 34px;
}

.reg-consent + .reg-consent {
	margin-top: 20px;
}

/* Sized rather than restyled, so it keeps the platform's own tick. */
.reg-form input.reg-consent__box {
	width: 15px;
	height: 15px;
	min-height: 0;
	margin-top: 3px;
	accent-color: var(--black);
}

.reg-consent__label {
	font-size: 15px;
	line-height: 1.5;
}

.reg-consent__link {
	color: var(--link);
	font-weight: 700;
}

a.reg-consent__link:hover {
	text-decoration: underline;
}

.reg-consent.is-invalid .reg-consent__label {
	color: var(--sale);
}

/* ---- Submit ---- */

/*
 * As wide as the left field column: half the panel's inner width, less half the
 * column gap.
 */
.reg-form__submit {
	width: calc(50% - 18.5px);
	min-width: 0;
	min-height: 58px;
	margin-top: 32px;
	padding: 0;
	border: 0;
	cursor: pointer;
}

/*
 * The design shows the button greyed out until the terms are accepted.
 * assets/js/main.js disables it on load and releases it with the checkbox; with
 * no JavaScript it is never disabled and the server does the refusing.
 */
.reg-form__submit:disabled,
.reg-form__submit:disabled:hover {
	background: #c9c9c9;
	color: var(--white);
	cursor: not-allowed;
}

/* ---- Errors ---- */

/* White on the tinted panel, so it reads as a card rather than a shaded band. */
.reg-form__error {
	margin-bottom: 30px;
	padding: 15px 20px;
	border-left: 3px solid var(--sale);
	background: var(--white);
	font-size: 15px;
}

.reg-form__error > * + * {
	margin-top: 8px;
}

/* ---- Narrower screens ---- */

@media (max-width: 1024px) {
	.reg {
		grid-template-columns: minmax(0, 1fr);
	}

	.reg__side {
		padding: 44px var(--gutter) 40px;
		border-right: 0;
		border-bottom: 1px solid var(--line);
	}

	.reg-main__title {
		padding: 38px var(--gutter) 22px;
	}

	.reg-panel {
		padding: 40px var(--gutter) 60px;
	}
}

@media (max-width: 767px) {
	.reg-form__grid {
		grid-template-columns: minmax(0, 1fr);
		gap: 20px;
	}

	.reg-form__submit {
		width: 100%;
	}
}


/* -------------------------------------------- 29. Account dashboard --- */

/*
 * The screen a signed-in customer lands on: the account nav and "need help"
 * rows in a sidebar on the left, the endpoint's own content on a tinted panel
 * on the right. Same full-bleed two-column arrangement as the sign-up page in
 * section 28 -- each column pays for its own gutter -- but the columns stretch
 * to a shared height here, because the sidebar is usually the taller of the two
 * and the tint has to reach the bottom of it.
 *
 * <main> carries site-main--flush, which section 22 zeroes the inner-page
 * padding for, so the breadcrumb band sits straight under the header.
 */

.acct {
	--acct-side: clamp(300px, 24.8vw, 476px);
	--acct-pad: clamp(24px, 4vw, 76px);

	display: grid;
	grid-template-columns: var(--acct-side) minmax(0, 1fr);
}

/* ---- Sidebar ---- */

.acct__side {
	padding: 54px 40px 84px var(--gutter);
	border-right: 1px solid var(--line);
}

.acct-side__greet {
	font-size: 19px;
	line-height: 1.45;
}

.acct-side__name {
	display: block;
	font-weight: 700;
}

.acct-side__block {
	margin-top: 58px;
}

.acct-side__heading {
	margin-bottom: 26px;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

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

.acct-nav__item + .acct-nav__item {
	margin-top: 19px;
}

.acct-nav__link {
	display: flex;
	align-items: center;
	gap: 14px;
	font-size: 14px;
	letter-spacing: 0.05em;
	text-transform: uppercase;
}

/*
 * A row with nowhere to point -- favourites, until the wishlist has a page of
 * its own -- keeps its place in the list and stops behaving like a link.
 */
.acct-nav__link--plain {
	cursor: default;
}

.acct-nav__icon {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: 24px;
	color: var(--ink);
}

.acct-nav__link:hover .acct-nav__label {
	text-decoration: underline;
	text-underline-offset: 4px;
}

.acct-nav__link--plain:hover .acct-nav__label {
	text-decoration: none;
}

/* The row you are on reads heavier rather than coloured, as in the design. */
.acct-nav__item.is-current .acct-nav__label {
	font-weight: 700;
}

/* ---- Need help? ---- */

.acct-help__item {
	display: flex;
	align-items: flex-start;
	gap: 16px;
}

.acct-help__item + .acct-help__item {
	margin-top: 28px;
}

.acct-help__icon {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: var(--off);
	color: var(--ink);
}

.acct-help__body {
	padding-top: 8px;
}

.acct-help__label {
	font-size: 15px;
	font-weight: 700;
}

.acct-help__value,
.acct-help__line {
	margin-top: 4px;
	color: var(--muted);
	font-size: 15px;
}

.acct-help__value a:hover {
	color: var(--ink);
}

/* ---- Content column ---- */

/*
 * A column rather than a plain block, so the tinted body can take up whatever
 * height the sidebar leaves it.
 */
.acct__main {
	display: flex;
	min-width: 0;
	flex-direction: column;
}

.acct-head {
	padding: 36px var(--acct-pad) 34px;
	border-bottom: 1px solid var(--line);
}

.acct-head__title {
	font-size: 16px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.acct-body {
	flex: 1 1 auto;
	padding: 84px var(--acct-pad) 90px;
	background: var(--off);
}

/* ---- Dashboard blocks ---- */

.acct-block + .acct-block {
	margin-top: 92px;
}

.acct-block__title {
	margin-bottom: 26px;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.acct-block__row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
}

.acct-block__row--address + .acct-block__row--address {
	margin-top: 34px;
}

.acct-block__line,
.acct-block__address,
.acct-block__empty {
	font-size: 16px;
	font-style: normal;
	line-height: 1.7;
}

.acct-block__label {
	margin-bottom: 4px;
	font-size: 14px;
	font-weight: 600;
	letter-spacing: 0.02em;
}

.acct-block__empty {
	color: var(--muted);
}

.acct-edit {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	gap: 9px;
	font-size: 15px;
}

.acct-edit:hover {
	text-decoration: underline;
	text-underline-offset: 4px;
}

/*
 * WooCommerce's endpoint screens -- orders, addresses, the account form -- land
 * in the same tinted body. Section 19 already styles the store's tables and
 * fields; these only give its headings and its own buttons room to breathe.
 */
.acct-body > h2,
.acct-body > h3 {
	margin-bottom: 20px;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.acct-body > p {
	font-size: 16px;
	line-height: 1.7;
}

.acct-body > p + p,
.acct-body > form,
.acct-body > .woocommerce-Addresses,
.acct-body > .woocommerce-orders-table,
.acct-body > .woocommerce-message,
.acct-body > .woocommerce-info {
	margin-top: 20px;
}

@media (max-width: 1024px) {
	.acct {
		grid-template-columns: minmax(0, 1fr);
	}

	.acct__side {
		padding: 40px var(--gutter) 44px;
		border-right: 0;
		border-bottom: 1px solid var(--line);
	}

	.acct-head {
		padding: 30px var(--gutter) 26px;
	}

	.acct-body {
		padding: 46px var(--gutter) 64px;
	}

	.acct-block + .acct-block {
		margin-top: 56px;
	}
}

@media (max-width: 767px) {
	/* The edit link drops under the detail it belongs to rather than squeezing
	   into the same row as it. */
	.acct-block__row {
		flex-direction: column;
		align-items: flex-start;
		gap: 10px;
	}
}

/* -------------------------------------------------- 30. Order received --- */

/*
 * The confirmation, the four facts about the order, then what was ordered and
 * where it goes.
 *
 * Only the banner and the strip are the theme's own markup. Everything under
 * them is the store's, arriving on woocommerce_thankyou, so those rules hang
 * off the store's own classes -- every one of them scoped to .order-received,
 * because the account area's view-order screen renders the same classes from
 * the same templates and must keep its own look.
 */
.site-main.order-received-page {
	padding: clamp(28px, 3vw, 48px) 0 clamp(56px, 6vw, 96px);
}

/* The store's pages run to the full container; a receipt reads better held in. */
.order-received {
	max-width: 1180px;
	margin: 0 auto;
}

/* ---- Confirmation ---- */

/*
 * A dashed rule rather than a filled panel: the checkout has been black on
 * white the whole way, and a solid block of colour at the end of it reads as an
 * alert rather than as a result.
 */
.order-received__banner {
	padding: clamp(24px, 3vw, 42px) clamp(20px, 3vw, 40px);
	border: 1px dashed var(--line-strong);
	text-align: center;
}

.order-received__banner p {
	margin: 0;
	color: var(--teal);
	font-size: clamp(17px, 1.5vw, 26px);
	font-weight: 700;
	letter-spacing: 0.04em;
	line-height: 1.3;
	text-transform: uppercase;
}

/*
 * The failed-payment wording is a full sentence of explanation, so it keeps
 * sentence case and a readable size -- uppercasing it would shout the apology.
 */
.order-received__banner--failed {
	border-color: var(--sale);
}

.order-received__banner--failed p {
	color: var(--sale);
	font-size: clamp(15px, 1.1vw, 18px);
	font-weight: 400;
	letter-spacing: 0;
	text-transform: none;
}

.order-received__actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 12px;
	margin: clamp(18px, 2vw, 26px) 0 0;
}

/* ---- The four facts ---- */

/*
 * Equal columns however many there are: the payment method drops out when the
 * gateway that took the order is gone, leaving three. grid-auto-flow with
 * grid-auto-columns sizes whatever arrives rather than naming a count.
 *
 * The dividers are each cell's own left border with the first suppressed, so
 * they stay correct at three cells as well as four.
 */
.order-received__overview {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: 1fr;
	margin: clamp(28px, 3vw, 48px) 0 0;
	padding: 0;
}

.order-received__cell {
	padding: 6px clamp(12px, 1.4vw, 24px);
	border-left: 1px solid var(--line);
	text-align: center;
}

.order-received__cell:first-child {
	border-left: 0;
}

.order-received__label {
	color: var(--muted);
	font-size: 13px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

/* Resets the browser's own indent on a dd as well as setting the gap. */
.order-received__value {
	margin: 8px 0 0;
	font-size: clamp(15px, 1.2vw, 19px);
	font-weight: 700;
	line-height: 1.3;
}

/*
 * A gateway prints its payment instructions as a bare paragraph straight into
 * the confirmation -- no class of its own to aim at -- so it is addressed by
 * the one thing that is reliable about it: it comes immediately after the strip.
 */
.order-received__overview + p {
	margin: clamp(22px, 2.4vw, 34px) 0 0;
	color: var(--ink-soft);
	font-size: 16px;
}

/* ---- What was ordered ---- */

.order-received .woocommerce-order-details,
.order-received .woocommerce-customer-details {
	margin-top: clamp(34px, 4vw, 60px);
}

.order-received .woocommerce-order-details__title,
.order-received .woocommerce-column__title {
	margin: 0;
	font-size: clamp(17px, 1.5vw, 22px);
	font-weight: 700;
	letter-spacing: 0.05em;
	line-height: 1.3;
	text-transform: uppercase;
}

/*
 * Section 19 already gives the store's tables their rule, padding and uppercase
 * head, so only what the receipt adds is here: money against the right edge and
 * a heavier product name.
 *
 * Element-qualified on purpose. Section 19's rules are .shop table.shop_table
 * (0,2,1), and .shop is on this page too -- a two-class selector would lose to
 * them with nothing logged. The :last-child pair below is (0,3,1) and wins
 * outright rather than on source order.
 */
.order-received table.shop_table th:last-child,
.order-received table.shop_table td:last-child {
	text-align: right;
}

.order-received table.shop_table td.woocommerce-table__product-name {
	font-weight: 700;
}

.order-received table.shop_table td.woocommerce-table__product-name a {
	color: inherit;
	text-decoration: none;
}

.order-received table.shop_table td.woocommerce-table__product-name a:hover,
.order-received table.shop_table td.woocommerce-table__product-name a:focus-visible {
	text-decoration: underline;
	text-underline-offset: 4px;
}

/*
 * The totals rows are labels rather than column heads, so they drop section
 * 19's uppercase treatment and sit at the size of the rows they summarise.
 */
.order-received table.shop_table tfoot th {
	font-size: 15px;
	letter-spacing: 0;
	text-transform: none;
}

.order-received .order-again {
	margin: clamp(18px, 2vw, 26px) 0 0;
}

/* ---- Where it goes ---- */

/*
 * The store floats these two columns and gives each a percentage width. Grid
 * ignores the float on a grid item but not the width, so the width is reset
 * here -- and both selectors are element-qualified to clear the store's own
 * .woocommerce .col2-set .col-1, which is (0,3,0).
 */
.order-received .woocommerce-columns--addresses {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
	gap: clamp(24px, 3vw, 56px);
	margin-top: clamp(20px, 2vw, 30px);
}

.order-received .woocommerce-columns--addresses > div.woocommerce-column {
	width: auto;
	float: none;
}

/*
 * Not italic: the slant is only the browser's default for an address element,
 * and nothing else in the theme leans.
 */
.order-received .woocommerce-customer-details address {
	margin: 12px 0 0;
	border: 0;
	padding: 0;
	color: var(--ink-soft);
	font-size: 15px;
	font-style: normal;
	line-height: 1.9;
}

/*
 * The store marks the phone and email lines with an icon-font glyph and
 * reserves 1.5em of indent for it. The theme never loads that font, so the
 * glyph draws as an empty box and the line sits indented behind it -- the same
 * cause as the notice mark section 19 suppresses, and the reason the indent has
 * to go with the mark rather than the mark alone.
 *
 * The selectors are long because the store's are: it sets both the indent and
 * the mark from a three-class selector of its own, (0,3,0) and (0,3,1). Adding
 * .woocommerce and qualifying the p puts these at (0,4,0) and (0,4,1), so they
 * win outright rather than on main.css happening to be enqueued last.
 *
 * Scoped to this section on purpose: the account area's view-order screen
 * renders these same two classes from the same template, and it is not this
 * section's to restyle.
 */
.woocommerce .order-received .woocommerce-customer-details p.woocommerce-customer-details--phone,
.woocommerce .order-received .woocommerce-customer-details p.woocommerce-customer-details--email {
	margin: 0;
	padding-left: 0;
}

.woocommerce .order-received .woocommerce-customer-details p.woocommerce-customer-details--phone::before,
.woocommerce .order-received .woocommerce-customer-details p.woocommerce-customer-details--email::before {
	display: none;
}

@media (max-width: 900px) {
	/* Two per row, so the dividers move to every second cell. */
	.order-received__overview {
		grid-auto-flow: row;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		row-gap: clamp(18px, 3vw, 26px);
	}

	.order-received__cell:nth-child(odd) {
		border-left: 0;
	}
}

@media (max-width: 520px) {
	/*
	 * One per row: a vertical divider between stacked cells would draw a line
	 * down the side of the strip, so it becomes a rule between them instead.
	 */
	.order-received__overview {
		grid-template-columns: minmax(0, 1fr);
		row-gap: 0;
	}

	.order-received__cell {
		border-left: 0;
		border-top: 1px solid var(--line);
		padding: 16px 0;
		text-align: left;
	}

	.order-received__cell:first-child {
		border-top: 0;
		padding-top: 0;
	}

	.order-received__value {
		margin-top: 4px;
	}
}

/* ------------------------------------------- 31. Account edit form --- */

/*
 * The edit-account endpoint, on the same tinted panel section 29 gives every
 * other account screen: labelled fields two to a row, the date of birth as three
 * selects sharing one cell, the password change folded away behind a checkbox,
 * and one black button under the middle of the panel.
 *
 * Nearly everything here is element-qualified and scoped to .acct-body on
 * purpose. This is a WooCommerce page, so it carries `shop`, and section 19's
 * `.shop input[type="text"]` block is (0,2,1) -- it sets 48px-tall fields with
 * 14px padding and would silently win against any plain-class rule however late
 * it came in the file. `.acct-body .acct-form input.acct-form__input` is (0,3,1)
 * and states the design's measurements loudly enough to keep them.
 */

/* Section 29 gives every direct child of the panel a 20px top margin; the panel
   already pays for the space above the form. */
.acct-body > form.acct-form {
	margin-top: 0;
}

.acct-form__grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 34px 37px;
}

/* Holds the label and the field it names. */
.acct-form__row {
	display: flex;
	min-width: 0;
	flex-direction: column;
	margin: 0;
}

/*
 * Starts a fresh row rather than filling the cell beside whatever came before,
 * so "new password" and "confirm new password" sit next to each other instead of
 * being split across two rows by the current-password field ahead of them.
 */
.acct-form__row--break {
	grid-column-start: 1;
}

.acct-form__label {
	display: block;
	margin-bottom: 11px;
	font-size: 15px;
	font-weight: 700;
	line-height: 1.4;
}

.acct-body .acct-form input.acct-form__input,
.acct-body .acct-form select.acct-form__input {
	width: 100%;
	min-height: 57px;
	padding: 0 20px;
	border: 1px solid var(--line);
	border-radius: 0;
	background: var(--white);
	color: var(--ink);
	font-size: 16px;
	line-height: 1.4;
}

.acct-body .acct-form input.acct-form__input::placeholder {
	color: var(--muted);
	opacity: 1;
}

.acct-body .acct-form .acct-form__input:focus {
	border-color: var(--ink);
	outline: none;
}

.acct-body .acct-form .acct-form__input.is-invalid {
	border-color: var(--sale);
}

/* The platform arrow is replaced with the design's, the same chevron the
   checkout's selects carry in section 25. */
.acct-body .acct-form select.acct-form__select {
	appearance: none;
	-webkit-appearance: none;
	padding-right: 46px;
	background-color: var(--white);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231a1a1a' stroke-width='1.6'%3E%3Cpath d='M3.5 8 12 16.5 20.5 8'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 16px center;
	background-size: 15px;
	cursor: pointer;
}

/* ---- Date of birth ---- */

/*
 * Day, month and year share the cell the other fields fill on their own, in the
 * design's proportions -- the month name is the longest of the three, the day
 * never needs more than two digits.
 */
.acct-form__dates {
	display: grid;
	grid-template-columns: 0.67fr 1.5fr 1fr;
	gap: 16px;
}

/* ---- Password change ---- */

/*
 * A pure-CSS disclosure: the checkbox is the toggle, so the fields open with
 * JavaScript blocked, and the box is a sibling of the panel rather than wrapped
 * in a label with it, which is what makes the :checked selector below reach it.
 */
.acct-pass {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	gap: 0 14px;
	align-items: center;
	margin-top: 42px;
}

/* Sized rather than restyled, so it keeps the platform's own tick. */
.acct-form input.acct-pass__box {
	width: 22px;
	height: 22px;
	min-height: 0;
	margin: 0;
	accent-color: var(--black);
	cursor: pointer;
}

.acct-pass__label {
	font-size: 16px;
	line-height: 1.4;
	cursor: pointer;
}

/*
 * After .acct-form__grid on purpose: the panel carries both classes, and this is
 * the one that has to win until the box is ticked.
 */
.acct-pass__fields {
	display: none;
	grid-column: 1 / -1;
	margin-top: 34px;
}

.acct-pass__box:checked ~ .acct-pass__fields {
	display: grid;
}

/* WooCommerce's own strength meter, which its script appends beside the new
   password once anything is typed into it. */
.acct-form .woocommerce-password-strength,
.acct-form .woocommerce-password-hint {
	display: block;
	margin-top: 10px;
	font-size: 14px;
	line-height: 1.5;
}

/* ---- Submit ---- */

/* Centred under the panel rather than under the first column, as in the design. */
.acct-form__actions {
	display: flex;
	justify-content: center;
	margin: 48px 0 0;
}

.acct-form__submit {
	min-width: 375px;
	border: 0;
	cursor: pointer;
}

@media (max-width: 1024px) {
	.acct-form__grid {
		gap: 26px 24px;
	}

	.acct-form__submit {
		min-width: 300px;
	}
}

@media (max-width: 767px) {
	.acct-form__grid {
		grid-template-columns: minmax(0, 1fr);
	}

	/* One column, so there is no row for the break to start. */
	.acct-form__row--break {
		grid-column-start: auto;
	}

	.acct-form__dates {
		grid-template-columns: 0.8fr 1.6fr 1fr;
		gap: 10px;
	}

	.acct-body .acct-form select.acct-form__select {
		padding-right: 34px;
		background-position: right 12px center;
	}

	.acct-form__actions {
		margin-top: 36px;
	}

	.acct-form__submit {
		width: 100%;
		min-width: 0;
		padding: 0 20px;
	}
}

/* ----------------------------------------------- 32. Account orders --- */

/*
 * The orders endpoint, on the same tinted panel section 29 hands every account
 * screen: one white card per order -- its number and status on the top line, the
 * three facts under that, what it holds, then whatever can be done with it -- and,
 * for an account that has not ordered yet, a single panel saying so.
 *
 * Two things to know before editing. Section 2's margin reset covers headings and
 * p but not dl/dt/dd, so the facts list zeroes its own margins. And this is a
 * WooCommerce page, so <main> carries `shop` and section 19's store rules are
 * element- and attribute-qualified -- .site-main.shop a.button is (0,2,2), which
 * beats any plain pair of classes. The cards use the theme's own .btn, a class the
 * store never prints, so they stay out of that fight; keep it that way rather than
 * reaching for .button here.
 */

.acct-orders {
	display: grid;
	gap: clamp(16px, 1.6vw, 22px);
}

.acct-order {
	padding: clamp(22px, 2.4vw, 34px);
	border: 1px solid var(--line);
	background: var(--white);
}

/* ---- Number and status ---- */

.acct-order__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding-bottom: 18px;
	border-bottom: 1px solid var(--line);
}

.acct-order__number {
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

/*
 * Outlined rather than filled: the cards sit on a tint already, and a block of
 * colour per row would read as the loudest thing on the page. The colour comes
 * from the card's status modifier below -- currentColor gives the border the same
 * one without repeating it.
 */
.acct-order__status {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	min-height: 28px;
	padding: 0 14px;
	border: 1px solid currentColor;
	color: var(--ink-soft);
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

/*
 * Only the statuses that mean something different to a customer are coloured:
 * done, on its way, needs them to act, stopped. Any other status a plugin
 * registers keeps the neutral pill above rather than picking up a wrong colour.
 */
.acct-order--completed .acct-order__status {
	color: var(--teal);
}

.acct-order--processing .acct-order__status {
	color: var(--link);
}

.acct-order--pending .acct-order__status,
.acct-order--failed .acct-order__status {
	color: var(--sale);
}

.acct-order--cancelled .acct-order__status,
.acct-order--refunded .acct-order__status {
	color: var(--muted);
}

/* ---- The three facts ---- */

/*
 * Wrapping rather than columns: the date drops out of an order that has lost it,
 * and a narrow panel has to be able to fold the row rather than crush three cells
 * into it. dl and dd carry browser margins that section 2 never zeroed.
 */
.acct-order__facts {
	display: flex;
	flex-wrap: wrap;
	gap: 18px clamp(28px, 3vw, 54px);
	margin: 22px 0 0;
}

.acct-order__fact {
	min-width: 110px;
}

.acct-order__label {
	font-size: 13px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--muted);
}

.acct-order__value {
	margin: 6px 0 0;
	font-size: 16px;
	font-weight: 700;
	line-height: 1.4;
}

/* ---- What it holds ---- */

.acct-order__items {
	margin-top: 20px;
	color: var(--muted);
	font-size: 15px;
	line-height: 1.6;
}

/* ---- Buttons ---- */

.acct-order__actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: flex-end;
	gap: 12px;
	margin-top: clamp(20px, 2vw, 28px);
}

/*
 * Shorter and tighter than a page's own buttons: section 5 sizes .btn for the
 * bottom of a form, and at 58px tall it would out-weigh the card it sits in.
 */
.acct-order__action {
	min-height: 48px;
	padding: 0 30px;
	font-size: 13px;
}

/* The light button is white on white here, so it needs its own edge. */
.acct-order__action.btn--light {
	border: 1px solid var(--line-strong);
}

/* ---- Nothing ordered yet ---- */

.acct-empty {
	display: flex;
	align-items: flex-start;
	gap: 18px;
	padding: clamp(24px, 2.8vw, 38px);
	border: 1px solid var(--line);
	background: var(--white);
}

/* The same disc the sidebar's help rows wear in section 29. */
.acct-empty__icon {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: 52px;
	height: 52px;
	border-radius: 50%;
	background: var(--off);
	color: var(--ink);
}

.acct-empty__body {
	padding-top: 4px;
}

.acct-empty__title {
	font-size: 17px;
	font-weight: 700;
	line-height: 1.45;
}

.acct-empty__text {
	margin-top: 8px;
	max-width: 62ch;
	color: var(--muted);
	font-size: 15px;
	line-height: 1.7;
}

@media (max-width: 767px) {
	/* The status drops under the order number rather than squeezing beside it. */
	.acct-order__head {
		flex-direction: column;
		align-items: flex-start;
		gap: 12px;
	}

	.acct-order__actions {
		justify-content: stretch;
	}

	.acct-order__action {
		flex: 1 1 100%;
	}

	.acct-empty {
		flex-direction: column;
		gap: 14px;
	}
}

/* ------------------------------------------- 33. Account addresses --- */

/*
 * The edit-address endpoint, on the same tinted panel section 29 gives every
 * other account screen. Two shapes share it: a saved address reads as a block
 * with the dashboard's pencil link beside its heading, and a slot with nothing
 * on file carries the form instead, so an address can be added without leaving
 * the screen.
 *
 * The form is section 31's -- .acct-form, .acct-form__grid, .acct-form__row and
 * .acct-form__input are all its classes, and its field, select and button rules
 * apply here unchanged. What this section adds is only what comes of the fields
 * being drawn by woocommerce_form_field() rather than by hand: every row is also
 * a .form-row, which section 19 styles at (0,2,0) with a bottom margin and a gap
 * of its own, and every control sits inside a .woocommerce-input-wrapper. The
 * selectors below are (0,3,0) and up for that reason.
 */

.acct-address__intro {
	margin-bottom: 34px;
	font-size: 16px;
	line-height: 1.7;
	color: var(--muted);
}

.acct-address__slot + .acct-address__slot {
	margin-top: 92px;
}

/* The heading and its edit link share a row; section 29 already lays that row
   out, and the title's own bottom margin would push the link off centre. */
.acct-address__head .acct-block__title {
	margin-bottom: 0;
}

.acct-address__head {
	margin-bottom: 26px;
}

.acct-address__slot .acct-block__empty {
	margin-bottom: 30px;
}

/* Section 29 spaces the panel's direct children; the form is nested inside a
   block here, and pays for its own space above. */
.acct-body .acct-address-form {
	margin-top: 0;
}

/* ---- Rows ---- */

/*
 * Section 19's `.shop .form-row` is (0,2,0) and sets a column layout with a 7px
 * gap and a 20px bottom margin -- the grid pays for the gaps here, so the row
 * only has to hold its label and its field.
 */
.acct-body .acct-form p.acct-form__row {
	display: flex;
	min-width: 0;
	flex-direction: column;
	gap: 0;
	margin: 0;
}

.acct-form__row--full {
	grid-column: 1 / -1;
}

/* Also (0,2,1) in section 19, where it is 14px and semibold. */
.acct-body .acct-form .acct-form__label {
	display: block;
	margin-bottom: 11px;
	font-size: 15px;
	font-weight: 700;
	line-height: 1.4;
}

/* The plugin appends both of these inside the label: a red asterisk on a
   required field, "(optional)" on the rest. */
.acct-form__label .required {
	border: 0;
	color: var(--sale);
	text-decoration: none;
}

.acct-form__label .optional {
	font-weight: 400;
	color: var(--muted);
}

/* woocommerce_form_field() wraps every control in this. */
.acct-address-form .woocommerce-input-wrapper {
	display: block;
	width: 100%;
}

/* ---- Selects ---- */

/*
 * The country and county selects are the plugin's, so they carry no class of
 * the design's own beyond .acct-form__input -- which section 31 sizes but only
 * gives the design's chevron to .acct-form__select. Qualified by element, so a
 * county that is a plain text field in some country does not get an arrow.
 */
.acct-body .acct-address-form select.acct-form__input {
	appearance: none;
	-webkit-appearance: none;
	padding-right: 46px;
	background-color: var(--white);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231a1a1a' stroke-width='1.6'%3E%3Cpath d='M3.5 8 12 16.5 20.5 8'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 16px center;
	background-size: 15px;
	cursor: pointer;
}

/* The store's own script marks a field it has rejected on the way to the
   server; section 31 marks the same state with .is-invalid on the account form. */
.acct-body .acct-form .woocommerce-invalid .acct-form__input {
	border-color: var(--sale);
}

@media (max-width: 1024px) {
	.acct-address__slot + .acct-address__slot {
		margin-top: 56px;
	}
}

@media (max-width: 767px) {
	/* One column, so nothing is full width in particular. */
	.acct-form__row--full {
		grid-column: auto;
	}

	.acct-body .acct-address-form select.acct-form__input {
		padding-right: 34px;
		background-position: right 12px center;
	}
}

/* --------------------------------------- 34. Account company addresses --- */

/*
 * The company-addresses screen: the list of saved invoicing addresses, and the
 * form for one of them. It is a page template rather than a WooCommerce
 * endpoint -- the store keeps only two address slots -- but it is an account
 * screen, so it sits in section 29's two columns on section 29's tinted panel
 * and reads as one.
 *
 * Two things this deliberately does not restate. The form is section 31's:
 * .acct-form, .acct-form__grid, .acct-form__row, .acct-form__label and
 * .acct-form__input carry every measurement. And section 33 already generalises
 * what comes of fields being drawn by woocommerce_form_field() rather than by
 * hand -- p.acct-form__row at (0,3,1), the label at (0,3,0),
 * .acct-form__row--full, and the invalid state. Those rules are written for any
 * `.acct-body .acct-form`, not for the addresses screen alone, so this form is
 * held by them unchanged; what follows is only what they leave out.
 *
 * Section 19's field block cannot reach this screen at all: `shop` is added by
 * samsonite_main_class() only on WooCommerce's own pages and this is a plain
 * page, so `.shop input[type="text"]` and `.shop .form-row` never match here.
 * The selectors below are element-qualified regardless -- that class comes from
 * a helper the template does not control, and the screen could later be moved
 * behind a WooCommerce page.
 */

/* ---- Messages ---- */

/*
 * Saving and removing redirect, and say so on the way back through the query
 * string. Qualified past section 29's `.acct-body > p`, which is (0,1,1).
 */
.acct-body > p.acct-company__notice {
	margin: 0 0 34px;
	padding: 15px 20px;
	border-left: 3px solid var(--teal);
	background: var(--white);
	font-size: 16px;
	line-height: 1.6;
}

.acct-body > p.acct-company__notice--error {
	border-left-color: var(--sale);
}

/* ---- Adding ---- */

/*
 * The design leads with this button whether or not anything is saved yet, on the
 * same 375px measure as the form's own submit in section 31.
 */
.acct-company__actions {
	display: flex;
	justify-content: center;
	margin-bottom: 44px;
}

.acct-company__add {
	min-width: 375px;
}

/* Section 29 colours and sizes .acct-block__empty; only the space above it is
   this screen's, since the button rather than a paragraph comes before it. */
.acct-body > p.acct-company__empty {
	margin: 0;
}

/* ---- Saved addresses ---- */

/* Section 29 spaces .acct-block + .acct-block; the heading row it lays out puts
   the title's own bottom margin off centre against the edit link beside it. */
.acct-company__head {
	margin-bottom: 22px;
}

.acct-company__head .acct-block__title {
	margin-bottom: 0;
}

/* The pill rides beside the title rather than under it, so the title is a flex
   line of its own. */
.acct-company__name {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 12px;
}

.acct-company__pill {
	display: inline-block;
	padding: 4px 11px;
	background: var(--black);
	color: var(--white);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.08em;
	line-height: 1.5;
	text-transform: uppercase;
}

/* One line per fact, rather than a wrapped paragraph, so a long company name
   cannot run into the street beneath it. */
.acct-company__address {
	display: flex;
	flex-direction: column;
	gap: 3px;
}

.acct-company__remove-form {
	margin-top: 20px;
}

/* A text button, because removing is the quiet action on the card and the black
   button belongs to adding. */
.acct-company__remove {
	padding: 0;
	border: 0;
	background: none;
	color: var(--muted);
	font-family: inherit;
	font-size: 15px;
	line-height: 1.4;
	text-decoration: underline;
	text-underline-offset: 3px;
	cursor: pointer;
}

.acct-company__remove:hover,
.acct-company__remove:focus-visible {
	color: var(--sale);
}

/* ---- The form ---- */

/* woocommerce_form_field() wraps every control in this span. */
.acct-company-form .woocommerce-input-wrapper {
	display: block;
	width: 100%;
}

/*
 * The plugin appends a red asterisk to every required label and "(optional)" to
 * every other one, with no argument that asks for neither. The design shows
 * neither: it writes optionality into the field's name instead, which is why the
 * landline reads "Landline phone (optional)". Only the markers go -- the
 * aria-required attribute the plugin sets alongside them stays, so the required
 * fields are still announced as required.
 *
 * Delete these two lines to show the plugin's markers.
 */
.acct-company-form .required,
.acct-company-form .optional {
	display: none;
}

/*
 * Country and county are the plugin's selects, so they carry no class of the
 * design's beyond .acct-form__input -- which section 31 sizes but only gives the
 * chevron to .acct-form__select. Qualified by element, so a county that is a
 * plain text field in some country does not get an arrow.
 */
.acct-body .acct-company-form select.acct-form__input {
	appearance: none;
	-webkit-appearance: none;
	padding-right: 46px;
	background-color: var(--white);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231a1a1a' stroke-width='1.6'%3E%3Cpath d='M3.5 8 12 16.5 20.5 8'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 16px center;
	background-size: 15px;
	cursor: pointer;
}

/* Section 31 sizes inputs and selects; the comments box is this screen's only
   textarea, so its measurements are here. */
.acct-body .acct-company-form textarea.acct-form__input {
	display: block;
	width: 100%;
	min-height: 132px;
	padding: 16px 20px;
	border: 1px solid var(--line);
	border-radius: 0;
	background: var(--white);
	color: var(--ink);
	font-family: inherit;
	font-size: 16px;
	line-height: 1.5;
	resize: vertical;
}

.acct-body .acct-company-form textarea.acct-form__input:focus {
	border-color: var(--ink);
	outline: none;
}

/*
 * Street and number share one full-width row in the design's proportions -- the
 * street takes what is left, the number never needs much. .acct-form__row--full
 * (section 33) is what spans it; this is the split inside.
 */
.acct-form__split {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 210px;
	gap: 0 37px;
}

/* ---- Default address ---- */

.acct-company__tick {
	display: flex;
	align-items: center;
	gap: 14px;
	font-size: 16px;
	line-height: 1.4;
	cursor: pointer;
}

/* Sized rather than restyled, so it keeps the platform's own tick -- the same
   trade section 31 makes for the password disclosure. */
.acct-company-form input.acct-company__box {
	flex: 0 0 auto;
	width: 22px;
	height: 22px;
	min-height: 0;
	margin: 0;
	accent-color: var(--black);
	cursor: pointer;
}

@media (max-width: 1024px) {
	.acct-company__add,
	.acct-company__actions .btn {
		min-width: 300px;
	}

	.acct-form__split {
		gap: 0 24px;
	}
}

@media (max-width: 767px) {
	.acct-company__actions {
		margin-bottom: 32px;
	}

	.acct-company__add,
	.acct-company__actions .btn {
		width: 100%;
		min-width: 0;
	}

	/* One column, so the number sits under the street rather than beside it. */
	.acct-form__split {
		grid-template-columns: minmax(0, 1fr);
		gap: 26px 0;
	}

	.acct-body .acct-company-form select.acct-form__input {
		padding-right: 34px;
		background-position: right 12px center;
	}
}
/* -------------------------------------------------- 35. Account favourites - */

/*
 * Two halves of one feature: the heart that sits on every product card, and the
 * account screen that lists what has been hearted.
 *
 * The screen reuses the shell (.acct, .acct-head, .acct-body) and the empty
 * state (.acct-empty) the WooCommerce account screens are built from, all of
 * which are unscoped -- so they reach this page even though a plain page
 * template never picks up the .shop class. Nothing here overrides them.
 */

/*
 * The card is left static by section 12, so it is made a positioning context
 * here rather than there: changing .card in its own section would move every
 * absolutely positioned thing another card feature has hung off the media.
 */
.card {
	position: relative;
}

/*
 * .card__fav and .wishlist are both (0,1,0) on the same element, so this would
 * come down to source order. Qualified with .card instead, because a size and a
 * shape losing silently to section 21's 40px square is exactly the trap this
 * stylesheet is full of.
 */
.card .card__fav {
	position: absolute;
	top: 12px;
	right: 12px;
	z-index: 2;
	width: 36px;
	height: 36px;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.88);
	box-shadow: 0 1px 6px rgba(0, 0, 0, 0.08);
}

.card .card__fav:hover {
	background: var(--white);
}

/* An outline heart until it is chosen, a filled one after -- section 21 already
   turns .wishlist[aria-pressed="true"] the sale red, which is the fill. */
.card__fav-icon {
	display: inline-flex;
}

.card__fav-icon--on,
.card__fav[aria-pressed="true"] .card__fav-icon--off {
	display: none;
}

.card__fav[aria-pressed="true"] .card__fav-icon--on {
	display: inline-flex;
}

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

/*
 * Held back until the script has read the browser's list: the empty state is
 * rendered server-side so a scriptless browser still says something, and
 * without this a full list would flash "no favourites" for the length of the
 * AJAX round trip. page-wishlist.php carries a <noscript> that reverts it.
 */
.fav-page.is-loading > * {
	display: none;
}

/*
 * Auto-fill rather than the fixed count .shop-grid uses: the same cards sit in
 * the account panel here, which is narrower than the archive and has no filter
 * column to step around, so the column width is matched to the shop's (~250px
 * at 4 across) and the count is left to follow the panel.
 */
.fav-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
	gap: 26px 24px;
	padding-top: 30px;
}

/* The card sets height: 100%, so the item has to be the thing that stretches. */
.fav-grid__item {
	display: flex;
}

@media (max-width: 600px) {
	.fav-grid {
		grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
		gap: 20px 12px;
		padding-top: 18px;
	}

	.card .card__fav {
		top: 8px;
		right: 8px;
	}
}

/* ---------------------------------- 36. Account newsletter preferences --- */

/*
 * One consent row, the cookie link under it and the button under that, on a
 * single grid: the box in the first column and everything the shopper reads in
 * the second, so the button's left edge lines up with the label rather than with
 * the box. The link spans both columns because the design hangs it on the
 * panel's own left edge.
 */
.acct-news {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	gap: 0 14px;
	align-items: center;
	margin: 0;
}

/* Sized rather than restyled, so it keeps the platform's own tick -- the same
   treatment the sign-up form's consent row gets. */
.acct-body .acct-news input.acct-news__box {
	width: 22px;
	height: 22px;
	min-height: 0;
	margin: 0;
	padding: 0;
	accent-color: var(--black);
	cursor: pointer;
}

.acct-news__label {
	font-size: 16px;
	line-height: 1.4;
	cursor: pointer;
}

.acct-news__cookies {
	grid-column: 1 / -1;
	margin: 48px 0 0;
	font-size: 16px;
	line-height: 1.5;
}

.acct-news__link {
	color: var(--link);
	font-weight: 700;
}

a.acct-news__link:hover {
	text-decoration: underline;
}

/* Second column, so it starts under the label. */
.acct-news__actions {
	grid-column: 2;
	margin: 30px 0 0;
}

.acct-news__submit {
	min-width: 375px;
	border: 0;
	cursor: pointer;
}

@media (max-width: 1024px) {
	.acct-news__submit {
		min-width: 300px;
	}
}

/*
 * Narrow: the button drops to the panel's own left edge and fills it, so it is
 * no longer hanging off the label column on a screen that has no room for the
 * indent.
 */
@media (max-width: 767px) {
	.acct-news__actions {
		grid-column: 1 / -1;
	}

	.acct-news__submit {
		width: 100%;
		min-width: 0;
	}
}

/* -------------------------------------------------- 37. Hero main slider - */

/*
 * The main hero is now a slider: .hero__main keeps the aspect ratio and the
 * positioning context (sections 10 and 23), each slide stacks inside it.
 */
.hero__main-slides {
	position: absolute;
	inset: 0;
}

.hero__main-slide {
	position: absolute;
	inset: 0;
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.5s var(--ease);
}

.hero__main-slide.is-active {
	opacity: 1;
	visibility: visible;
}

/* Dots sit on the artwork rather than under it, so the grid row keeps its height. */
.dots--overlay {
	position: absolute;
	right: 0;
	bottom: 16px;
	left: 0;
	z-index: 2;
	padding: 0;
}

.dots--overlay .dots__dot {
	background: rgba(255, 255, 255, 0.6);
}

.dots--overlay .dots__dot.is-active {
	background: var(--white);
}

@media (max-width: 600px) {
	.dots--overlay {
		bottom: 10px;
	}
}

/*
 * An uploaded image is absolutely positioned (section 4), so it paints above the
 * side slide's static text and button and hides them. Lift them into the
 * positioned layer, and lay a scrim under them so white copy survives a photo.
 */
.hero__slide--photo::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(
		180deg,
		rgba(0, 0, 0, 0.5) 0%,
		rgba(0, 0, 0, 0.15) 40%,
		rgba(0, 0, 0, 0.55) 100%
	);
}

.hero__slide-body,
.hero__slide .btn {
	position: relative;
	z-index: 1;
}

/*
 * An uploaded logo replaces the drawn wordmark. Its height comes from Site
 * Identity -> Logo height, because how much empty space a logo file carries
 * around its artwork varies per file and no fixed cap suits every upload.
 * Centring is inherited from .header__top-inner; margin-inline keeps it centred
 * even if the block is ever given a width.
 */
.wordmark__image {
	display: block;
	width: auto;
	max-width: 100%;
	height: auto;
	max-height: var(--logo-height, 52px);
	margin-inline: auto;
	object-fit: contain;
}

/* The material banner overlays the logo on artwork, where it reads smaller. */
.material__logo .wordmark__image {
	max-height: calc(var(--logo-height, 52px) * 0.8);
}

@media (max-width: 900px) {
	.wordmark__image {
		max-height: calc(var(--logo-height, 52px) * 0.75);
	}
}

/* ------------------------------ 38. Hero side alignment & wide banner --- */

/*
 * The side slider used to end a dots-row short of the main slider, because its
 * dots sat under the artwork while the main slider's dots overlay it (section
 * 37). Overlaying both puts the whole grid row's height into the artwork, so
 * the two panels finish on the same line.
 */
.hero__side .dots--overlay {
	bottom: 14px;
}

/* Room under a slide's button so the overlaid dots do not land on top of it. */
.hero__slide {
	padding-bottom: 46px;
}

/* The side artwork runs light at the bottom, where white dots would vanish. */
.hero__side .dots--overlay .dots__dot {
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}

/*
 * A campaign file that already carries its own headline and button is shown
 * whole, at its own aspect ratio -- not cropped into a .media box (section 4).
 */
.banner-wide {
	display: block;
}

.banner-wide img {
	width: 100%;
	height: auto;
}

/* ----------------------------------------------- 39. Shop filter panel --- */

/*
 * How many products sit behind an option, counted over the products the page is
 * showing. An option with no tally is one that only stays on screen so it can be
 * unchosen again.
 */
.shop-tile__tally {
	flex: none;
	min-width: 30px;
	padding: 2px 8px;
	border: 1px solid var(--line);
	border-radius: 999px;
	color: var(--muted);
	font-size: 11px;
	font-weight: 400;
	letter-spacing: 0.04em;
	text-align: center;
}

.shop-tile.is-active .shop-tile__tally {
	border-color: var(--ink);
	color: var(--ink);
}

/*
 * A group holding more options than the eye can scan -- sub-categories, models
 * -- reads as rows rather than tiles: one per line, left-aligned, in the
 * catalogue's own capitalisation, with the count against the right edge. The
 * list is capped in height so an unfolded sixty-model group cannot run the whole
 * panel off the page.
 */
.shop-filter__options--list {
	grid-template-columns: minmax(0, 1fr);
	gap: 2px;
	max-height: 320px;
	padding-right: 6px;
	overflow-y: auto;
	overscroll-behavior: contain;
	scrollbar-width: thin;
}

.shop-filter__options--list::-webkit-scrollbar {
	width: 4px;
}

.shop-filter__options--list::-webkit-scrollbar-thumb {
	border-radius: 4px;
	background: var(--line-strong);
}

.shop-filter__options--list .shop-tile {
	flex-direction: row;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	min-height: 0;
	padding: 9px 2px;
	border: 0;
	border-radius: 0;
	color: var(--ink-soft);
	letter-spacing: 0.01em;
	text-align: left;
	text-transform: none;
}

.shop-filter__options--list .shop-tile:hover {
	color: var(--ink);
}

.shop-filter__options--list .shop-tile.is-active {
	box-shadow: none;
	color: var(--ink);
}

/*
 * A colour row: dot, then the name, then the count pushed to the right edge.
 * The import stores colour names in whatever case the feed had ("Black",
 * "BLUE NIGHTS"), so these rows keep the uppercase the tiles used to draw.
 */
.shop-filter__options--list .shop-tile--swatch {
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

.shop-filter__options--list .shop-tile__dot {
	flex: none;
	width: 18px;
	height: 18px;
}

.shop-filter__options--list .shop-tile__label {
	flex: 1 1 auto;
	min-width: 0;
}

/* --- Finding one option among many --- */

.shop-filter__find {
	position: relative;
	margin-bottom: 16px;
}

/*
 * Element-qualified: section 19's `.shop input[type="…"]` block is (0,2,1) and
 * would out-specify a plain class if `search` were ever added to its list.
 */
.shop-filter__find input.shop-filter__find-input {
	width: 100%;
	min-height: 44px;
	padding: 0 42px 0 14px;
	border: 1px solid var(--line);
	border-radius: 2px;
	background: var(--white);
	color: var(--ink);
	font-size: 13px;
	letter-spacing: 0.02em;
}

.shop-filter__find input.shop-filter__find-input:focus {
	border-color: var(--ink);
	outline: none;
}

.shop-filter__find-icon {
	position: absolute;
	top: 50%;
	right: 14px;
	transform: translateY(-50%);
	color: var(--muted);
	pointer-events: none;
}

/*
 * A search shows what matched but was folded away behind "Show more", and hides
 * what did not match. Both have to out-specify `.shop-filter__option.is-folded`,
 * and the hiding rule has to out-specify the unfolding one -- which is why it
 * repeats the same four-class shape rather than relying on source order alone.
 */
.shop-filter__options.is-searching .shop-filter__option.is-folded {
	display: block;
}

.shop-filter__options.is-searching .shop-filter__option.is-hidden,
.shop-filter__options .shop-filter__option.is-hidden {
	display: none;
}

.shop-filter__empty {
	margin-top: 4px;
	color: var(--muted);
	font-size: 13px;
}

/* --- The price group --- */

/*
 * Two range inputs stacked over one track. The inputs themselves take no
 * pointer events, so a click lands on whichever thumb is under it rather than on
 * the input that happens to be on top.
 */
.shop-price__slider {
	position: relative;
	display: flex;
	align-items: center;
	height: 30px;
}

.shop-price__track {
	position: absolute;
	left: 0;
	right: 0;
	height: 3px;
	border-radius: 3px;
	background: var(--line);
}

.shop-price__fill {
	position: absolute;
	top: 0;
	bottom: 0;
	left: var(--from, 0%);
	width: calc(var(--to, 100%) - var(--from, 0%));
	border-radius: 3px;
	background: var(--sky);
}

.shop-price__handle {
	position: absolute;
	left: 0;
	width: 100%;
	height: 30px;
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	pointer-events: none;
	-webkit-appearance: none;
	appearance: none;
}

.shop-price__handle:focus {
	outline: none;
}

/*
 * WebKit pins an `appearance: none` thumb to the top edge of the runnable track,
 * not its centre, so the track is the thumb's own height: the 30px input still
 * centres the track, and the thumb lands on the 3px line behind it.
 */
.shop-price__handle::-webkit-slider-runnable-track {
	height: 18px;
	border: 0;
	background: none;
}

.shop-price__handle::-webkit-slider-thumb {
	width: 18px;
	height: 18px;
	border: 0;
	border-radius: 50%;
	background: var(--sky);
	box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
	cursor: pointer;
	pointer-events: auto;
	-webkit-appearance: none;
	appearance: none;
}

.shop-price__handle::-moz-range-track {
	height: 30px;
	border: 0;
	background: none;
}

.shop-price__handle::-moz-range-progress {
	background: none;
}

.shop-price__handle::-moz-range-thumb {
	width: 18px;
	height: 18px;
	border: 0;
	border-radius: 50%;
	background: var(--sky);
	box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
	cursor: pointer;
	pointer-events: auto;
}

.shop-price__handle:focus-visible::-webkit-slider-thumb {
	box-shadow: 0 0 0 2px var(--ink);
}

.shop-price__handle:focus-visible::-moz-range-thumb {
	box-shadow: 0 0 0 2px var(--ink);
}

.shop-price__foot {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 14px;
	margin-top: 16px;
}

.shop-price__readout {
	color: var(--muted);
	font-size: 13px;
	letter-spacing: 0.03em;
}

.shop-price__amount {
	color: var(--ink);
	font-weight: 700;
}

.shop-price__dash {
	margin: 0 2px;
}

/* Sized for the panel: .btn's own 58px would fill the column. */
.btn.shop-price__apply {
	min-height: 40px;
	padding: 0 18px;
	font-size: 11px;
	letter-spacing: 0.12em;
}

/* ------------------------------------------------- 40. Mobile refinements - */

/*
 * What the design does differently on a phone, gathered in one place.
 *
 * Sections 23 and each feature's own "narrower screens" block already bring the
 * desktop layout down to a single column. This section is the step after that:
 * the places where the small screen is not a narrower version of the wide one
 * but a different arrangement -- the header's icon row reordered around the
 * logo, the promo bar reduced to one message at a time, the catalogue's sort
 * moved into a drawer, the product page's buying controls pinned to the bottom
 * edge, the card stripped back to the three things it is read for.
 *
 * Two mechanisms recur and are worth naming once:
 *
 *  - `display: contents` on a wrapper, so its children join the grid or flex
 *    row above it and can be re-ordered against their aunts. It is how the
 *    header puts the search glyph before the logo without moving any markup,
 *    how the product page lifts the gallery in between the title and the size
 *    picker, and how the cart drops "need help" below the totals. The wrapper's
 *    own padding goes with it, so each child that needed it is given its own.
 *
 *  - `order`, once the parent is a column flex box. Source order stays the
 *    reading order for a screen reader and for the wide layout; only the visual
 *    sequence changes.
 *
 * Everything here is inside a max-width query, except a handful of rules for
 * furniture that exists only at these widths -- the off-canvas drawers, the two
 * glyphs on the search button, the sticky buying bar -- which are cheaper to
 * write once than to duplicate per breakpoint.
 */

/* ---- Furniture that only appears below the desktop breakpoint ---- */

/*
 * The bar's arrows and its track. `display: contents` keeps section 6's row
 * intact on a wide screen: the items stay direct children of the flex line as
 * far as the layout is concerned, and the track only becomes a box of its own
 * once there is one message on show.
 */
.promo-bar__track {
	display: contents;
}

.promo-bar__arrow {
	display: none;
}

/*
 * The button that opens the sort drawer, and the drawer's own footer button on
 * the filter column: both belong to the narrow layout only. A button's default
 * display is not none, so each has to be switched off here rather than merely
 * switched on inside the query.
 */
.shop-sort__toggle {
	display: none;
}

/*
 * The sign-in panel's required marker, restored.
 *
 * Section 25 states the intent -- the checkout's own fields carry their name in
 * the placeholder and are drawn without markers, "the sign-in panel keeps its
 * asterisk" -- but the e-mail field there is a .checkout-field--stacked as well,
 * which is one of the selectors doing the hiding, so the asterisk went with
 * them. Restoring display here rather than editing that rule leaves the fields
 * it is actually aimed at alone. Not a narrow-screen matter: it applies at every
 * width, and is here because this is the section that noticed.
 */
.checkout-access .checkout-field--stacked .required {
	display: inline;
}

/* The glyph swaps to a cross while the field it opened is on show. */
.header__glyph {
	display: inline-flex;
}

.header__glyph--shut,
.js-search-toggle[aria-expanded="true"] .header__glyph--open {
	display: none;
}

.js-search-toggle[aria-expanded="true"] .header__glyph--shut {
	display: inline-flex;
}

/* ---- The off-canvas menu ---- */

/*
 * The panel hangs below the header rather than over it: the burger that opened
 * it stays visible and stays the way out, which is what the design shows.
 *
 * --drawer-top is the header's real bottom edge, written by markDrawerTop() as
 * the panel opens. It cannot be a fixed number: the header is sticky above a
 * promo bar that scrolls away, so its bottom sits ~44px lower at the top of the
 * page than it does anywhere else. The fallback is the scrolled case, which is
 * also the value on any page without a promo bar.
 */
.mobile-nav {
	top: calc(var(--drawer-top, var(--header-h)) + var(--admin-bar-height));
	height: auto;
	bottom: 0;
	width: min(88vw, 400px);
}

/*
 * The dim is at z-index 60 and the header at 50, so without this the row holding
 * the control that opened the drawer would be washed out along with the page it
 * covers -- and every one of these panels is dismissed from that row. 61 keeps
 * the header under the panels themselves, which sit at 70 and 80.
 */
body:has(.mobile-nav.is-open) .header,
body:has(.shop-sort-menu:not([hidden])) .header,
body:has(.shop-archive.is-filters-open) .header,
body.is-searching .header {
	z-index: 61;
}

/* The cross now sits alone on this row. */
.mobile-nav__head {
	justify-content: flex-start;
	padding: 14px var(--gutter);
	border-bottom: 0;
}

.mobile-nav__close {
	display: inline-flex;
	align-items: center;
	color: var(--ink);
}

/* The word, centred on a tinted strip under it. */
.mobile-nav__title {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 46px;
	padding: 0 var(--gutter);
	background: var(--off);
	letter-spacing: 0.14em;
}

.mobile-nav__body {
	flex: 1 1 auto;
	padding-top: 0;
	padding-bottom: 20px;
}

/*
 * The rows read as the sections they are: upper case, and with the chevron the
 * design puts on the ones that open something. A section with nothing under it
 * -- an outlet link, a single landing page -- is left without one, which is the
 * distinction the reference draws.
 */
.mobile-nav__body .nav__list > li > a,
.mobile-nav__brand {
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	padding: 17px 0;
}

.mobile-nav__body .nav__list > li:is(.has-mega, .menu-item-has-children) > a {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 14px;
}

.mobile-nav__body .nav__list > li:is(.has-mega, .menu-item-has-children) > a::after {
	content: "";
	flex: none;
	width: 8px;
	height: 8px;
	border-top: 1.5px solid currentColor;
	border-right: 1.5px solid currentColor;
	transform: rotate(45deg);
}

/* The account row, held to the foot of the panel. */
.mobile-nav__foot {
	margin-top: auto;
	border-top: 1px solid var(--line);
}

.mobile-nav__account {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 20px var(--gutter);
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.mobile-nav__account .icon {
	flex: none;
	color: var(--ink-soft);
}

/* ---- The catalogue's sort drawer ---- */

.shop-sort-menu {
	position: fixed;
	top: calc(var(--drawer-top, var(--header-h)) + var(--admin-bar-height));
	right: 0;
	bottom: 0;
	left: 0;
	z-index: 80;
	display: flex;
	flex-direction: column;
	background: var(--white);
	overflow-y: auto;
	overscroll-behavior: contain;
}

.shop-sort-menu[hidden] {
	display: none;
}

.shop-sort-menu__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	min-height: 58px;
	padding: 0 var(--gutter);
	border-bottom: 1px solid var(--line);
}

.shop-sort-menu__title {
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
}

.shop-sort-menu__close {
	display: inline-flex;
	align-items: center;
	color: var(--ink);
}

.shop-sort-menu__item {
	display: flex;
	align-items: center;
	gap: 16px;
	padding: 15px var(--gutter);
	border-bottom: 1px solid var(--line);
	color: var(--ink);
	font-size: 15px;
}

.shop-sort-menu__item .icon {
	flex: none;
	color: var(--ink-soft);
}

.shop-sort-menu__item.is-current {
	font-weight: 700;
}

.shop-sort-menu__item.is-current .icon {
	color: var(--ink);
}

/* ---- The filter drawer's footer ---- */

/*
 * Sticky rather than fixed: the drawer is the scroll container, so the bar rides
 * its bottom edge without having to know how wide the drawer is. It is hidden
 * above the breakpoint, where the column is not a drawer and has nothing to
 * dismiss.
 */
.shop-filters__foot {
	display: none;
}

/* ---- The product page's buying bar ---- */

.product-sticky {
	display: none;
}

/* ============================ Below 1024px ============================= */

@media (max-width: 1024px) {

	/* ---- Promo bar: one message, stepped ---- */

	.promo-bar__inner {
		display: grid;
		grid-template-columns: 24px minmax(0, 1fr) 24px;
		align-items: center;
		justify-content: initial;
		gap: 8px;
		min-height: 44px;
		overflow: hidden;
	}

	.promo-bar__track {
		display: block;
		min-width: 0;
	}

	.promo-bar__item {
		display: none;
		justify-content: center;
		gap: 10px;
	}

	.promo-bar__item.is-active {
		display: flex;
	}

	/*
	 * Nothing marked current -- the script has not run, or a message was removed
	 * from under it -- shows the first rather than an empty bar.
	 */
	.promo-bar__track:not(:has(.is-active)) > .promo-bar__item:first-child {
		display: flex;
	}

	.promo-bar__arrow {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		width: 24px;
		height: 24px;
		color: var(--white);
	}

	/* ---- Header: search, logo, cart, menu ---- */

	/*
	 * The icon row is split around the logo. `display: contents` promotes its
	 * children into the header grid so the search glyph can take the first
	 * column and the burger the last, without the markup moving -- which keeps
	 * the wide layout, where the whole row sits right of the logo, untouched.
	 */
	.header__actions {
		display: contents;
	}

	.header__top-inner {
		grid-template-columns: 24px minmax(0, 1fr) auto auto;
		gap: 14px;
	}

	.header__action--search {
		grid-column: 1;
		grid-row: 1;
		justify-self: start;
	}

	.header__logo {
		grid-column: 2;
		grid-row: 1;
	}

	.header__action--cart {
		grid-column: 3;
		grid-row: 1;
	}

	.header__burger {
		grid-column: 4;
		grid-row: 1;
	}

	/* The account and store links are in the off-canvas menu at this width. */
	.header__action--account,
	.header__action--stores {
		display: none;
	}

	/* Black rather than the sale red, which is what the design uses here. */
	.header__count {
		background: var(--black);
	}

	/* ---- The catalogue toolbar ---- */

	/*
	 * The toolbar starting flush under the header rather than 56px down used to
	 * be arranged here, for this width alone. It is section 20's own rule now --
	 * the gap was there at every width, not only on a phone.
	 */

	/*
	 * Two cells of equal width with a rule between them: the sort on the left,
	 * the filters on the right. The select gives way to a button that opens the
	 * drawer -- a native select cannot carry the label the design asks for, and
	 * its option list is not the nine orders the drawer offers.
	 */
	.shop-bar__inner {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.shop-bar__sort select.shop-sort__select,
	.shop-sort__chevron {
		display: none;
	}

	.shop-bar__sort {
		display: flex;
		align-items: stretch;
		border-right: 1px solid var(--line);
	}

	.shop-sort__toggle {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 12px;
		width: 100%;
		min-height: 58px;
		padding: 0 18px 0 var(--gutter);
		color: var(--ink);
		font-size: 13px;
		font-weight: 700;
		letter-spacing: 0.1em;
		text-transform: uppercase;
	}

	.shop-sort__toggle .icon {
		flex: none;
		color: var(--ink);
	}

	.shop-bar__filters {
		display: flex;
		align-items: stretch;
		padding: 0;
	}

	.shop-filters__toggle {
		justify-content: space-between;
		width: 100%;
		min-height: 58px;
		padding: 0 18px 0 20px;
		font-size: 13px;
		font-weight: 700;
		letter-spacing: 0.1em;
		text-transform: uppercase;
	}

	/* ---- The filter drawer ---- */

	.shop-layout__side {
		/* Below the header, like every other drawer -- see --drawer-top above. */
		top: calc(var(--drawer-top, var(--header-h)) + var(--admin-bar-height));
		display: flex;
		flex-direction: column;

		/*
		 * Section 23 gives the drawer a shadow it casts whether it is open or
		 * shut, and shut it is parked just off the right edge -- so the shadow
		 * greys a 40px band down the side of every catalogue page. It belongs to
		 * the open state only.
		 */
		box-shadow: none;
	}

	.shop-archive.is-filters-open .shop-layout__side {
		box-shadow: -10px 0 36px rgba(0, 0, 0, 0.14);
	}

	.shop-filters {
		flex: 1 1 auto;
	}

	.shop-filters__foot {
		position: sticky;
		bottom: 0;
		z-index: 2;
		display: flex;
		align-items: center;
		gap: 14px;
		padding: 12px var(--gutter);
		border-top: 1px solid var(--line);
		background: var(--white);
	}

	.shop-filters__reset {
		flex: 1 1 auto;
		color: var(--ink-soft);
		font-size: 14px;
	}

	.shop-filters__reset.is-empty {
		color: var(--muted-light);
	}

	a.shop-filters__reset:hover {
		color: var(--ink);
		text-decoration: underline;
		text-underline-offset: 4px;
	}

	.shop-filters__apply {
		flex: none;
		min-height: 50px;
		padding: 0 20px;
		font-size: 12px;
		letter-spacing: 0.08em;
	}

	/* The head's own clear link is the footer's job now. */
	.shop-filters__clear {
		display: none;
	}

	/* ---- Product page ---- */

	/*
	 * The wide layout reads down the summary column and across to the artwork.
	 * There is no across at this width, so the page is re-cut into the order the
	 * design uses: what the product is, then what it looks like, then the
	 * choices to make about it. `display: contents` on the summary is what lets
	 * the gallery land in the middle of its children.
	 */
	.product-layout {
		display: flex;
		flex-direction: column;

		/*
		 * Section 21 sets `align-items: start` so the summary column does not
		 * stretch to the artwork's height. In a column flex box that same value
		 * shrink-wraps every row to its content instead -- the gallery to one
		 * thumbnail's width, a centred link to the width of its own text -- so
		 * the rows are stretched back across the screen here.
		 */
		align-items: stretch;
	}

	.product-summary {
		display: contents;
	}

	.product-summary > * {
		padding-inline: var(--gutter);
	}

	.product-title {
		order: 1;
		margin-top: 26px;
	}

	.product-subtitle {
		order: 2;
	}

	.product-discount {
		order: 3;
		align-self: flex-start;
		margin-inline: var(--gutter);
		padding-inline: 12px;
	}

	.product-links {
		order: 4;
		justify-content: center;
		margin-top: 26px;
	}

	.product-gallery {
		order: 5;
	}

	.product-rail {
		order: 6;
	}

	.product-option {
		order: 7;
		padding-block: 22px;
		border-bottom: 1px solid var(--line);
	}

	.product-option + .product-option {
		margin-top: 0;
	}

	/*
	 * Both are repeated in the bar pinned to the bottom edge, which is where the
	 * design keeps them, so the copies in the flow would only be read twice.
	 */
	.product-pricing,
	.product-buy {
		display: none;
	}

	/* The trail is the header's job at this width. */
	.product-summary > .crumbs {
		display: none;
	}

	/*
	 * The thumbnails, as a strip under the artwork rather than a rail beside it.
	 * The behaviour is already written: initGalleryRail() scrolls the gallery
	 * horizontally when it is a scroller, which it is at this width.
	 */
	.product-rail {
		display: block;
		padding: 14px var(--gutter) 0;
	}

	.product-rail__list {
		position: static;
		flex-direction: row;
		gap: 8px;
		overflow-x: auto;
		scrollbar-width: none;
		-ms-overflow-style: none;
	}

	.product-rail__list::-webkit-scrollbar {
		display: none;
	}

	.product-rail__list > li {
		flex: none;
		width: 64px;
	}

	.product-rail__item {
		aspect-ratio: 1 / 1;
	}

	/* ---- The buying bar ---- */

	.product-sticky {
		position: fixed;
		right: 0;
		bottom: 0;
		left: 0;
		z-index: 45;
		display: grid;
		grid-template-columns: minmax(0, 1fr) auto auto;
		align-items: center;
		gap: 12px;
		padding: 10px var(--gutter);
		border-top: 1px solid var(--line);
		background: var(--white);
		box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.08);
	}

	.product-sticky__price {
		display: flex;
		flex-direction: column;
		min-width: 0;
		line-height: 1.25;
	}

	.product-sticky__price del {
		color: var(--muted);
		font-size: 15px;
		text-decoration-thickness: 1px;
	}

	.product-sticky__price ins {
		color: var(--ink);
		font-size: 18px;
		font-weight: 700;
		text-decoration: none;
	}

	/* A price range, or "from", arrives as its own markup. */
	.product-sticky__price ins .woocommerce-Price-amount {
		white-space: nowrap;
	}

	.product-sticky__fav {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		width: 44px;
		height: 44px;
		color: var(--ink);
	}

	.product-sticky__note {
		color: var(--muted);
		font-size: 14px;
		text-align: right;
	}

	.product-sticky__add {
		min-height: 54px;
		padding: 0 18px;
		font-size: 13px;
		letter-spacing: 0.08em;
		white-space: normal;
	}

	/*
	 * Room under the page for the bar that now covers its bottom edge. The bar is
	 * fixed, so what it sits over once the page is scrolled to the end is the
	 * footer -- padding on the main element would leave the footer's last row
	 * underneath it.
	 */
	body:has(.product-sticky) .footer {
		padding-bottom: 96px;
	}

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

	/*
	 * "Need help" belongs under the totals here, not under the lines: the aside
	 * is no longer a column beside them but the next thing on the page, and the
	 * order button has to be the end of it. Lifting the main column's children
	 * into the layout is what lets the two swap.
	 */
	.cart-layout {
		display: flex;
		flex-direction: column;
	}

	.cart-layout__main {
		display: contents;
	}

	.cart-layout__aside {
		order: 3;
	}

	.cart-help {
		order: 4;
		margin-top: clamp(30px, 3vw, 44px);
	}

	/* ---- Campaign artwork: edge to edge ---- */

	/*
	 * Below the desktop breakpoint every full-width campaign file runs to both
	 * edges of the screen, as the reference store does -- it drops the hero
	 * wrapper's padding, the gutter between its two panels and the space above
	 * the pair at the same width the pair stops being two columns.
	 *
	 * The gutter is `clamp(16px, 4vw, 76px)`, so on a phone this is only 16px a
	 * side. That is the problem, not a small version of it: 16px of white down
	 * both sides of a photograph reads as a card sitting on the page rather than
	 * as the page's own artwork, and the frame is too thin to read as a deliberate
	 * margin. At 1440px the same 76px is wide enough to be one.
	 *
	 * Only the artwork moves. The carousels, the category tiles and the newsletter
	 * keep their gutter -- they are content laid out inside the page, and the
	 * reference store keeps a margin on those too.
	 */
	.hero {
		padding-top: 0;
	}

	.hero__grid {
		padding-inline: 0;
		gap: 0;
	}

	.section--banner > .container {
		padding-inline: 0;
	}

	.material {
		width: 100%;
	}
}

/* ============================= Below 768px ============================= */

@media (max-width: 767px) {

	/* ---- Hero ---- */

	/*
	 * The campaign slider's dots move off the artwork and onto the white under
	 * it. Overlaid, they land on whatever the bottom of the photograph happens to
	 * be -- which at this size is often the model or the product -- and the row
	 * is small enough that a shadow is all that keeps them visible. As a flex
	 * item below the track they are simply legible.
	 */
	.hero__side .dots--overlay {
		position: static;
		padding: 14px 0 2px;
	}

	.hero__side .dots--overlay .dots__dot {
		background: var(--line-strong);
		box-shadow: none;
	}

	.hero__side .dots--overlay .dots__dot.is-active {
		background: var(--ink);
	}

	/* ---- Carousels ---- */

	/*
	 * Two cards to a screen rather than one and a sliver: the row is read as a
	 * row, and the card beside the first one is what says the rest scroll.
	 */
	.carousel__track--products > .carousel__item {
		width: 62vw;
	}

	/* ---- Product cards ---- */

	/*
	 * A card is read for three things at this width -- what it is, what colours
	 * it comes in, what it costs -- and tapped to open the product. The heart,
	 * the compare toggle and the add-to-cart button are all taken off it: two of
	 * them are hover affordances with no hover to hang off, and all three put a
	 * second and third tap target inside a card whose whole face is already a
	 * link to the page where those actions live.
	 */
	.card__fav,
	.card .compare,
	.card__cta {
		display: none;
	}

	.card {
		padding: 10px 8px 22px;
	}

	.card .badge--sale {
		top: 10px;
		left: 10px;
		min-width: 40px;
		height: 24px;
		font-size: 12px;
	}

	.card__head {
		margin-top: 18px;
	}

	.card__name {
		font-size: 14px;
		letter-spacing: 0.04em;
	}

	.card__summary {
		margin-top: 6px;
		font-size: 13px;
		line-height: 1.45;
	}

	.card__price {
		gap: 3px;
		margin-top: 10px;
	}

	.card__price del {
		font-size: 14px;
	}

	.card__price ins {
		font-size: 16px;
	}

	.swatches {
		margin-top: 16px;
	}

	.card .swatches {
		gap: 9px;
	}

	/* ---- Catalogue ---- */

	/* The trail is a wide-screen affordance; the chips row is the way back. */
	.shop-bar__crumbs {
		display: none;
	}

	/* One line, scrolled sideways, rather than a block of wrapped pills. */
	.shop-chips__list {
		flex-wrap: nowrap;
		overflow-x: auto;
		scrollbar-width: none;
		-ms-overflow-style: none;
		padding-bottom: 2px;
	}

	.shop-chips__list::-webkit-scrollbar {
		display: none;
	}

	.shop-chips__list > li {
		flex: none;
	}

	/* ---- Product page ---- */

	.product-title {
		font-size: 29px;
	}

	.product-subtitle {
		font-size: 21px;
	}

	.product-links {
		margin-top: 20px;
		padding-block: 15px;
	}

	.product-shot {
		width: 100%;
	}

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

	/*
	 * The ways to reach the shop, as the pair of bordered boxes the design uses
	 * rather than a stacked list. An odd one out takes the full width instead of
	 * leaving a gap beside it.
	 */
	.cart-help__list {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 12px;
	}

	.cart-help__item {
		display: flex;
		flex-direction: column;
		justify-content: center;
		gap: 4px;
		min-height: 82px;
		padding: 14px 16px;
		border: 1px solid var(--line);
	}

	.cart-help__item + .cart-help__item {
		margin-top: 0;
	}

	.cart-help__item:last-child:nth-child(odd) {
		grid-column: 1 / -1;
	}

	.cart-help__label {
		font-size: 15px;
	}

	.cart-help__value {
		margin-top: 0;
		font-size: 14px;
	}

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

	/*
	 * The heading sits at the gutter, like every other page's does -- section 25
	 * centres it, which only reads as centred while the form beside it is a
	 * second column.
	 */
	.checkout-page .checkout__title {
		text-align: left;
	}

	/*
	 * The password and the button it belongs to stay on one row. Section 25
	 * stacks them below 560px, which gives a full-width black button the same
	 * weight as the order button at the end of the page -- signing in is not that
	 * decision, and the design keeps it as a control beside its field.
	 */
	.checkout-access__row {
		grid-template-columns: minmax(0, 1fr) auto;
		align-items: end;
	}

	.checkout-access__submit {
		width: auto;
		min-width: 0;
		padding: 0 20px;
		font-size: 12px;
		letter-spacing: 0.08em;
	}

	/* ---- Service promises: the promise, without the paragraph ---- */

	/*
	 * Four rows of icon-and-title and nothing else, which is what the reference
	 * store shows at this width. The paragraph under each title is the same
	 * reassurance the title already gives; at 390px it is four lines of it, and
	 * the four promises stop being a band that can be read at a glance and
	 * become a screen of body copy between the last banner and the newsletter.
	 *
	 * With the paragraph gone the row is one line tall, so the icon is centred
	 * against the title rather than aligned to the top of a two-part block --
	 * section 15's `flex-start` leaves a 44px glyph hanging above a 17px line --
	 * and the generous padding a paragraph needed comes down with it.
	 */
	.usp__text {
		display: none;
	}

	.usp__item {
		align-items: center;
		gap: 22px;
		padding: 22px var(--gutter);
	}

	.usp__icon svg {
		width: 38px;
		height: 38px;
	}
}

/* ------------------------------------------------------ 41. Contact page - */

/*
 * The contact page: the store's own details beside a Contact Form 7 form.
 *
 * Two halves with two different jobs. The layout, the panels and the details
 * list are the theme's own and are written like the rest of the file. The form
 * inside the left panel is CF7's markup, so a second set of rules re-states the
 * design's measurements over the plugin's stylesheet -- which is loaded on this
 * page, and only on this page, because its spinner and its validation tips are
 * worth keeping.
 *
 * The plugin's rules are beaten on specificity rather than by source order or by
 * !important: `.wpcf7 form .wpcf7-response-output` is (0,2,1) and
 * `.wpcf7 form.sent .wpcf7-response-output` likewise, so every override of one of
 * those carries `.contact-page` in front of it to reach (0,3,0). Fields are
 * element-qualified for the reason section 31 gives: this is a page template
 * today and section 19's `.shop input[type="text"]` cannot reach it, but the
 * class is added by a helper the template does not control.
 */

/*
 * padding-block, not padding: the element is also the page's .container, which
 * carries the site gutter as padding-inline. A four-value padding here is the
 * same specificity and later in the file, so it silently zeroes that gutter and
 * the title, the intro and the panels all run to the edge of the window.
 */
.contact {
	padding-block: 44px 90px;
}

.contact__title {
	margin-bottom: 18px;
}

.contact__intro {
	max-width: 760px;
	margin-bottom: 46px;
	color: var(--ink-soft);
	font-size: 16px;
	line-height: 1.7;
}

/* The form leads, and the details sit in a column the width of the catalogue's
   filter rail so the page lines up with the rest of the site. */
.contact__grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr) clamp(300px, 26vw, 440px);
	gap: clamp(28px, 3vw, 60px);
	align-items: start;
}

.contact__panel--form {
	background: var(--off);
	padding: clamp(24px, 3vw, 48px);
}

.contact__panel--details {
	border: 1px solid var(--line);
	padding: clamp(24px, 3vw, 40px);
}

.contact__panel-title {
	font-size: 20px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	margin-bottom: 12px;
}

.contact__note {
	color: var(--muted);
	font-size: 14px;
	line-height: 1.6;
}

/* Shown in place of the form when CF7 is inactive, so the panel is never empty. */
.contact__fallback {
	color: var(--ink-soft);
	font-size: 16px;
	line-height: 1.7;
}

.contact__fallback a {
	color: var(--link);
	text-decoration: underline;
}

/* ---- The form ---- */

/*
 * Two fields to a row, with the subject and the message across both. The gap
 * above comes from the panel title's own margin plus this, so the note between
 * them can be cleared from the Customizer without the form riding up.
 */
.contact-form__grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 26px 28px;
	margin-top: 30px;
}

.contact-form__row {
	display: flex;
	min-width: 0;
	flex-direction: column;
	margin: 0;
}

.contact-form__row--wide {
	grid-column: 1 / -1;
}

.contact-form__label {
	display: block;
	margin-bottom: 10px;
	font-size: 15px;
	font-weight: 700;
	line-height: 1.4;
}

.contact-form__req {
	color: var(--sale);
}

/*
 * CF7 wraps every control in a span, which is inline -- so a field inside one
 * ignores the width below until the wrapper is told to fill the row.
 */
.contact-page .contact-form__form .wpcf7-form-control-wrap {
	display: block;
}

.contact-page .contact-form__form input.contact-form__field,
.contact-page .contact-form__form textarea.contact-form__field {
	width: 100%;
	min-height: 57px;
	padding: 0 20px;
	border: 1px solid var(--line);
	border-radius: 0;
	background: var(--white);
	color: var(--ink);
	font-family: inherit;
	font-size: 16px;
	line-height: 1.4;
}

.contact-page .contact-form__form textarea.contact-form__field {
	min-height: 178px;
	padding: 16px 20px;
	line-height: 1.6;
	resize: vertical;
}

.contact-page .contact-form__form .contact-form__field:focus {
	border-color: var(--ink);
	outline: none;
}

/* The class CF7's own validation adds, so the field it names is marked in the
   same red as the message under it. */
.contact-page .contact-form__form .contact-form__field.wpcf7-not-valid {
	border-color: var(--sale);
}

.contact-page .contact-form__form .wpcf7-not-valid-tip {
	margin-top: 8px;
	color: var(--sale);
	font-size: 14px;
	font-weight: 400;
	line-height: 1.5;
}

/* ---- Consent ---- */

.contact-form__consent {
	margin-top: 30px;
}

/*
 * The plugin lays checkbox items out inline with a 1em indent, which on a single
 * full-width consent line reads as a stray gap before the box.
 */
.contact-page .contact-form__form .contact-form__consent .wpcf7-list-item {
	display: block;
	margin: 0;
}

.contact-form__consent label {
	display: flex;
	align-items: flex-start;
	gap: 12px;
	cursor: pointer;
}

/* Sized rather than restyled, so it keeps the platform's own tick -- the same
   choice section 31 makes for the password disclosure. */
.contact-page .contact-form__form input.contact-form__box {
	flex: 0 0 auto;
	width: 22px;
	height: 22px;
	min-height: 0;
	margin: 2px 0 0;
	padding: 0;
	accent-color: var(--black);
	cursor: pointer;
}

.contact-form__consent .wpcf7-list-item-label {
	color: var(--ink-soft);
	font-size: 15px;
	line-height: 1.6;
}

.contact-form__consent a {
	color: var(--link);
	text-decoration: underline;
}

/* ---- Send ---- */

.contact-form__actions {
	display: flex;
	align-items: center;
	margin-top: 34px;
}

.contact-page .contact-form__form input.contact-form__submit {
	min-height: 57px;
	padding: 0 46px;
	border: 0;
	border-radius: 0;
	background: var(--black);
	color: var(--white);
	font-family: inherit;
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	cursor: pointer;
}

.contact-page .contact-form__form input.contact-form__submit:hover {
	background: #333;
}

/*
 * CF7 keeps the button disabled until the consent box above it is ticked, which
 * is the same gate section 28 puts on the registration form -- so it is greyed
 * the same way rather than dimmed, which at 60% opacity read as a muddy black
 * button rather than an unavailable one.
 */
.contact-page .contact-form__form input.contact-form__submit:disabled,
.contact-page .contact-form__form input.contact-form__submit:disabled:hover {
	background: #c9c9c9;
	color: var(--white);
	cursor: not-allowed;
}

/* The plugin's spinner, in the theme's ink and close enough to the button to
   read as belonging to it rather than floating in the panel. */
.contact-page .contact-form__form .wpcf7-spinner {
	margin: 0 0 0 14px;
	background-color: var(--ink);
}

/* ---- The answer ---- */

/*
 * One bordered strip under the button, in place of the plugin's blue-bordered
 * box. The border carries the outcome: green for sent, red for a failure, amber
 * for something the visitor can fix.
 */
.contact-page .contact-form__form .wpcf7-response-output {
	margin: 28px 0 0;
	padding: 15px 20px;
	border: 1px solid var(--line-strong);
	background: var(--white);
	color: var(--ink);
	font-size: 15px;
	line-height: 1.6;
}

.contact-page .contact-form__form.sent .wpcf7-response-output {
	border-color: var(--teal);
}

.contact-page .contact-form__form.failed .wpcf7-response-output,
.contact-page .contact-form__form.aborted .wpcf7-response-output {
	border-color: var(--sale);
}

.contact-page .contact-form__form.invalid .wpcf7-response-output,
.contact-page .contact-form__form.unaccepted .wpcf7-response-output,
.contact-page .contact-form__form.spam .wpcf7-response-output,
.contact-page .contact-form__form.payment-required .wpcf7-response-output {
	border-color: #d68000;
}

/* ---- Store details ---- */

.contact-details {
	display: grid;
	gap: 26px;
	margin-top: 28px;
}

.contact-details__item {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	gap: 14px;
	align-items: start;
}

.contact-details__icon {
	display: inline-flex;
	margin-top: 2px;
	color: var(--ink);
}

.contact-details__label {
	display: block;
	margin-bottom: 6px;
	color: var(--muted);
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.contact-details__row {
	display: block;
	font-size: 16px;
	line-height: 1.6;
}

.contact-details__row a:hover {
	text-decoration: underline;
}

/* ---- Narrower ---- */

/* The details column runs out of room before the form does, so it drops under
   the form rather than being squeezed beside it. */
@media (max-width: 1023px) {
	.contact__grid {
		grid-template-columns: minmax(0, 1fr);
	}

	.contact {
		padding-block: 32px 70px;
	}
}

@media (max-width: 640px) {
	/* Two fields to a row stops being two fields and starts being two half
	   fields. */
	.contact-form__grid {
		grid-template-columns: minmax(0, 1fr);
		gap: 22px;
	}

	.contact__intro {
		margin-bottom: 32px;
	}

	.contact-form__actions {
		display: block;
	}

	.contact-page .contact-form__form input.contact-form__submit {
		width: 100%;
		padding: 0 20px;
	}

	/* Centred under a full-width button, where it has nothing to sit beside. */
	.contact-page .contact-form__form .wpcf7-spinner {
		display: block;
		margin: 16px auto 0;
	}
}

/* ---------------------------------------------- 42. Compact product row --- */

/*
 * The homepage row and the "related products" row show five cards where they
 * used to show four (section 11), so every measurement inside a card that was
 * set for a 425px card is a size too large at 339px. Scoped to the carousel: a
 * card in the catalogue grid or the favourites grid has its own column count
 * and is left alone.
 */

.carousel__track--products .card {
	padding: 12px;
}

.carousel__track--products .card .badge--sale {
	top: 16px;
	left: 16px;
}

.carousel__track--products .swatches {
	margin-top: 16px;
	gap: 9px;
}

.carousel__track--products .swatches__dot {
	width: 15px;
	height: 15px;
}

.carousel__track--products .swatches--none {
	height: 15px;
}

.carousel__track--products .card__head {
	margin-top: 20px;
	gap: 10px;
}

.carousel__track--products .card__name {
	font-size: 13px;
}

.carousel__track--products .compare {
	gap: 5px;
	font-size: 12px;
}

.carousel__track--products .card__summary {
	margin-top: 8px;
	font-size: 13px;
	line-height: 1.45;
}

.carousel__track--products .card__price {
	margin-top: 12px;
	gap: 4px;
}

.carousel__track--products .card__price del {
	font-size: 13px;
}

.carousel__track--products .card__price ins {
	font-size: 15px;
}

.carousel__track--products .card__cta {
	margin-top: 14px;
	min-height: 42px;
	font-size: 12px;
}

/*
 * The row is shallower than it was, so the arrows -- which are placed against
 * the whole carousel, progress track included -- sit a little higher to stay
 * centred on the artwork.
 */
.section--products .carousel__nav,
.section--related .carousel__nav {
	top: 30%;
}

/* Below 1024px the row scrolls a card and a bit at a time and the cards are
   wide again, so the compact sizing stops applying. */
@media (max-width: 1024px) {
	.carousel__track--products .card {
		padding: 17px;
	}

	.carousel__track--products .card__name {
		font-size: 15px;
	}

	.carousel__track--products .card__summary {
		font-size: 14px;
	}

	.carousel__track--products .card__price ins {
		font-size: 17px;
	}
}

/* ------------------------------------------------- 43. Editorial pages --- */

/*
 * The brand page and the personalisation page: two long editorial pages built
 * from the same pieces -- an opening band, and blocks of copy each beside a
 * photograph. They share this section because they share the furniture; what
 * differs is only what the blocks hold.
 *
 * The opening band of each is in section 45, which is also where these blocks
 * become the reference's flush two-panel layout. Neither page carries a
 * breadcrumb or a titled hero any more; <main> still carries site-main--flush so
 * the first band sits tight under the header.
 */

/* ---- Anything typed into the page's own editor ---- */

.editorial-intro,
.editorial-head {
	padding-block: clamp(28px, 3vw, 50px) 0;
}

/* The measure is the readable one, not the container's full 1768px. */
.editorial-intro__body,
.editorial-head__body {
	max-width: 74ch;
}

/* ---- A block: copy beside a photograph ---- */

.editorial-block__inner {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	align-items: center;
	gap: clamp(28px, 4vw, 84px);
}

.editorial-block__media {
	aspect-ratio: 4 / 3;
}

/*
 * The artwork side is a stored choice per block, so the reference layout --
 * artwork right, right, then left -- needs no per-block rule. Only the "left"
 * case reorders; the grid's own order is the "right" one.
 */
.editorial-block--left .editorial-block__body {
	order: 2;
}

.editorial-block__title {
	font-size: clamp(22px, 2vw, 34px);
	font-weight: 700;
	letter-spacing: 0.02em;
	line-height: 1.15;
	text-transform: uppercase;
}

.editorial-block__quote {
	margin-top: 22px;
	font-size: clamp(17px, 1.3vw, 22px);
	font-style: italic;
	line-height: 1.45;
}

.editorial-block__text {
	margin-top: 18px;
	color: var(--ink-soft);
	font-size: 16px;
	line-height: 1.7;
}

.editorial-block__cta {
	margin-top: 28px;
	min-height: 48px;
	padding-inline: 34px;
}

/* ---- Personalisation: the four kinds ---- */

.personalise-types__list {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: clamp(16px, 1.6vw, 30px);
}

.personalise-type__link {
	display: block;
	color: var(--ink);
}

.personalise-type__media {
	aspect-ratio: 3 / 4;
}

.personalise-type__title {
	display: block;
	margin-top: 20px;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
}

.personalise-type__note {
	display: block;
	margin-top: 8px;
	color: var(--ink-soft);
	font-size: 14px;
	line-height: 1.5;
}

a.personalise-type__link:hover .personalise-type__title {
	text-decoration: underline;
	text-underline-offset: 5px;
}

/* ---- Personalisation: the category shortcuts ---- */

.personalise-more__list {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
}

.personalise-more__chip {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	padding: 0 26px;
	border: 1px solid var(--line-strong);
	border-radius: 999px;
	color: var(--ink);
	font-size: 14px;
	font-weight: 600;
	letter-spacing: 0.03em;
	text-transform: uppercase;
	transition: background-color 0.2s var(--ease), color 0.2s var(--ease);
}

.personalise-more__chip:hover {
	background: var(--ink);
	border-color: var(--ink);
	color: var(--white);
}

/* ---- Narrower screens ---- */

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

}

@media (max-width: 767px) {
	.editorial-block__inner {
		grid-template-columns: 1fr;
	}

	/*
	 * One column: the photograph follows its copy on every block, so a page
	 * reads title, text, picture, title, text, picture rather than alternating
	 * -- which at this width looks like a mistake rather than a rhythm.
	 */
	.editorial-block--left .editorial-block__body {
		order: 0;
	}

}

/* --------------------------------------------- 44. Footer refinements --- */

/*
 * The footer as the reference design builds it: a centred newsletter band
 * opening it, an Instagram grid closing the column row, the payment marks moved
 * down into the legal strip, and a floating WhatsApp button over the lot.
 *
 * The pieces themselves are sections 16 (newsletter), 17 (footer) and 18
 * (legal); what is here is only what those three now need to differ on, so a
 * shared rule stays in one place.
 */

/* ---- The newsletter band, opening the footer ---- */

/*
 * Rebuilt 2026-08-20 from samsonite.gr's own `.newletter-outr` rules, which are
 * the design the store asked for band for band: a #f8f8f8 strip 60px deep, one
 * centred column a third of the page wide, the wordmark at 1.375rem bold on 2px
 * of tracking, a 0.875rem lead under it, and the email on a single 1px rule with
 * the arrow at its right end. It was a two-column left-ranged block before this,
 * so most of what follows undoes one of those overrides.
 */
.section--newsletter {
	background: #f8f8f8;
}

.newsletter {
	display: block;
	padding: 60px var(--gutter);
	text-align: center;
}

.newsletter__title {
	font-size: 22px;
	font-weight: 700;
	letter-spacing: 2px;
}

.newsletter__lead {
	margin-top: 16px;
	max-width: none;
	color: var(--ink);
	font-size: 14px;
	line-height: 1.5;
}

/*
 * 570px is their column: a third of the 1800px inside `.container-fluid`'s 60px
 * margins, less its own 15px gutters. Narrower than that and it is the screen.
 */
.newsletter__form {
	display: block;
	width: min(570px, 100%);
	margin: 8px auto 0;
	padding-bottom: 0;
	border-bottom: 0;
}

/*
 * The placeholder is the only label the reference shows, so the real one is
 * hidden rather than dropped -- a bare input on a rule has nothing to announce.
 */
.newsletter__label {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* The field is the rule, and the submit shares it -- see the template part. */
.newsletter__field {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	margin-bottom: 0;
	border-bottom: 1px solid #000;
}

.newsletter__input {
	flex: 1;
	min-width: 0;
	min-height: 38px;
	padding: 6px 0;
	border: 0;
	background: none;
	font-size: 16px;
	text-align: left;
}

.newsletter__input:focus {
	outline: none;
}

/*
 * Kept, though the reference carries no tick box: it is the store's consent
 * record, not decoration. Centred and quiet under the rule so it reads as a
 * footnote to the field. Emptying the consent line in the Customizer removes
 * both the box and the check behind it (inc/ajax.php) and leaves the reference's
 * exact form.
 */
.newsletter__consent {
	display: flex;
	align-items: flex-start;
	justify-content: center;
	gap: 10px;
	margin-top: 16px;
	margin-bottom: 0;
	color: var(--muted);
	font-size: 13px;
	line-height: 1.45;
	text-align: left;
}

.newsletter__box {
	flex: none;
	width: 15px;
	height: 15px;
	margin-top: 2px;
	accent-color: var(--ink);
}

.newsletter__consent label {
	cursor: pointer;
}

/* Only if the store sets a submit label; with none, the bare arrow is used. */
.newsletter__button {
	flex: none;
	min-height: 38px;
	padding-inline: 26px;
	font-size: 12px;
}

.newsletter__submit {
	flex: none;
}

.newsletter__message {
	margin-top: 14px;
	text-align: center;
}

/* ---- Footer column 4: the Instagram grid ---- */

.insta-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 8px;
}

.insta-grid__link {
	display: block;
	aspect-ratio: 1 / 1;
	background: rgba(255, 255, 255, 0.08);
}

/*
 * Instagram posts are square in the grid whatever shape they were posted in, so
 * these are cropped rather than fitted -- the opposite of the product shots in
 * section 12, and for the opposite reason: here the crop is the design.
 */
.insta-grid__link img {
	object-fit: cover;
}

.insta-grid__glyph {
	position: absolute;
	inset: 0;
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba(0, 0, 0, 0.45);
	color: var(--white);
	opacity: 0;
	transition: opacity 0.2s var(--ease);
}

.insta-grid__link:hover .insta-grid__glyph,
.insta-grid__link:focus-visible .insta-grid__glyph {
	opacity: 1;
}

/* ---- The legal strip: line left, payment marks right ---- */

.legal__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px 40px;
	flex-wrap: wrap;
}

/* Section 18 centres the strip; with two cells in it, each ranges to its edge. */
.legal__inner .legal__line {
	text-align: left;
}

.legal__inner .payments {
	max-width: none;
	gap: 10px 14px;
}

.legal__inner .payments__item svg {
	height: 26px;
}

/* ---- The floating WhatsApp button ---- */

/*
 * Fixed in the bottom corner of every page, at the same 20px inset as the
 * reference. The z-index sits under the mobile drawer and its overlay (section 9
 * runs at 60 and above) so the button cannot be tapped through an open drawer,
 * and above everything else on the page.
 */
.whatsapp {
	position: fixed;
	right: 20px;
	bottom: 20px;
	z-index: 46;
	display: flex;
	align-items: center;
	justify-content: center;
	color: #444;
	line-height: 0;
	transition: transform 0.2s var(--ease), color 0.2s var(--ease);
}

.whatsapp:hover,
.whatsapp:focus-visible {
	color: var(--ink);
	transform: scale(1.06);
}

/*
 * The compare tray (section 27) is fixed to the same corner and is the taller of
 * the two, so the button climbs above it while the tray is on screen. The tray
 * carries the `hidden` attribute until something is in it, which is what this
 * keys off -- no script has to know about the button.
 */
body:has(.compare-tray:not([hidden])) .whatsapp {
	bottom: calc(clamp(20px, 3.4vw, 64px) + 76px);
}

/* ---- Narrower screens ---- */

/* Their own phone values for the band: 40px over it, 50px under. */
@media (max-width: 767px) {
	.newsletter {
		padding: 40px var(--gutter) 50px;
	}
}

@media (max-width: 1024px) {
	/*
	 * Clear of the product page's buying bar, which is fixed to the same corner
	 * and only exists at this width -- above it the bar is display:none, so
	 * `:has` on its own would lift the button over nothing.
	 */
	body:has(.product-sticky) .whatsapp {
		bottom: 82px;
	}
}

@media (max-width: 767px) {
	.legal__inner {
		justify-content: center;
	}

	.legal__inner .legal__line {
		text-align: center;
	}

	.legal__inner .payments {
		justify-content: center;
	}

	.whatsapp {
		right: 14px;
		bottom: 14px;
	}

	.whatsapp .icon {
		width: 40px;
		height: 40px;
	}
}

/* ------------------------------------------ 45. Reference parity pass --- */

/*
 * Six things measured against samsonite.al and brought into line: the store's
 * own notices, the two editorial pages, the legal strip's typography, the
 * Instagram tiles' hover, the pair of floating controls in the bottom corner,
 * and campaign artwork on a phone.
 *
 * They share a section because they are one pass rather than one feature; each
 * block below says which screen it belongs to.
 */

/* ---- Store notices ---- */

/*
 * "Added to your cart" is the only confirmation the button gives, so it is a
 * card rather than a tinted strip: white, ruled, lifted, with the tick from
 * inc/cart.php in front of the wording and the link to the cart as a compact
 * button against the right edge.
 *
 * On the product page the notice is a direct child of .product-single, which
 * runs the full width of the screen -- so the strip used to run edge to edge
 * while everything under it sat inside the gutter. It gets the gutter here; the
 * cart, checkout and account screens print their notices inside a .container
 * already and are left alone.
 */
.product-single > .woocommerce-notices-wrapper:not(:empty) {
	padding: clamp(18px, 2vw, 30px) var(--gutter) 0;
}

.site-main.shop .woocommerce-message,
.site-main.shop .woocommerce-info,
.site-main.shop .woocommerce-error {
	display: flex;
	align-items: center;
	gap: 14px;
	margin: 0 0 clamp(20px, 2vw, 32px);
	padding: 16px 18px;
	border: 1px solid var(--line);
	border-left: 3px solid var(--ink);
	background: var(--white);
	box-shadow: 0 10px 28px rgba(0, 0, 0, 0.07);
	color: var(--ink);
	font-size: 15px;
	line-height: 1.45;
	list-style: none;
}

/*
 * WooCommerce's own sheet gives every notice a 3px lime top border. The theme
 * only ever replaced the left one, so the lime line was still there above the
 * wording -- the single most out-of-place colour on the page. The `border`
 * shorthand above resets it; these two only re-colour the left edge.
 */
.site-main.shop .woocommerce-error {
	border-left-color: var(--sale);
}

.site-main.shop .woocommerce-info {
	border-left-color: var(--link);
}

/*
 * No focus ring on the notice itself.
 *
 * WooCommerce makes the notice focusable and moves focus to it so a screen
 * reader announces it, and Chromium counts that programmatic focus as
 * focus-visible -- so section 2's ring drew a second 2px box 3px outside the
 * card, which is the thin dark outline around the whole strip in the reference
 * screenshots. There is nothing to operate here: the ring marks a live region,
 * not a control. The link inside is a real control and keeps its own.
 */
.site-main.shop .woocommerce-message:focus-visible,
.site-main.shop .woocommerce-info:focus-visible,
.site-main.shop .woocommerce-error:focus-visible {
	outline: none;
}

/*
 * WooCommerce's own ::after is a float clearfix (`display: table`). In a flex
 * row it becomes a third item and opens a gap between the wording and the
 * button; there is nothing left to clear here anyway.
 */
.site-main.shop .woocommerce-message::after,
.site-main.shop .woocommerce-info::after,
.site-main.shop .woocommerce-error::after {
	display: none;
}

/*
 * The tick, as a background rather than as markup.
 *
 * It cannot be inline SVG: WooCommerce runs every notice through
 * wc_kses_notice(), which keeps <path d> and throws away the <circle>, the
 * classes and every fill and stroke attribute -- so an icon from inc/icons.php
 * arrives as an unstyled outline. Section 19 switches every notice's own
 * ::before off because the icon font behind it is never loaded; this turns it
 * back on for our own mark, and only on the success notice.
 *
 * The two tones are baked in rather than inherited for the same reason
 * close-disc is in inc/icons.php: this only ever paints on the white card above.
 */
.site-main.shop .woocommerce-message::before {
	content: "";
	position: static;
	display: block;
	flex: none;
	width: 20px;
	height: 20px;
	background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='10' fill='%231a1a1a'/%3E%3Cpath d='m7.6 12.3 3 3 5.8-6.2' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* A row of one line of copy: the 14px top margin every other store button
   carries would push this one off centre. */
.site-main.shop .woocommerce-message .button,
.site-main.shop .woocommerce-info .button,
.site-main.shop .woocommerce-error .button {
	flex: none;
	min-height: 42px;
	margin: 0 0 0 auto;
	padding: 0 22px;
	font-size: 12px;
}

/* ---- Editorial pages: the flush two-panel band ---- */

/*
 * The reference build sets each block as one band: the copy on a filled panel,
 * the photograph hard against it, both the same height, the pair inside the
 * page's own gutter so a band lines up with the tiles above it. Section 43 laid
 * the same two cells out as a centred grid with a wide gap and no panel, which
 * reads as two unrelated things that happen to be side by side.
 *
 * Measured off samsonite.al at a 1600px viewport: the bands sit in the page
 * container, 70px apart, 50px under the shortcut strip, and carry no height of
 * their own -- a band is as tall as the taller of its two halves. The
 * min-height is only a floor for a block whose copy is one line and a button.
 */
.editorial-block + .editorial-block {
	margin-top: clamp(28px, 4.4vw, 70px);
}

.personalise-more + .editorial-block,
.editorial-lead + .editorial-block {
	margin-top: clamp(24px, 3.1vw, 50px);
}

.editorial-block__inner {
	align-items: stretch;
	gap: 0;
	min-height: clamp(220px, 20vw, 320px);
}

.editorial-block__body {
	display: flex;
	flex-direction: column;
	justify-content: center;
	padding: clamp(28px, 3.2vw, 50px);
}

/*
 * Height comes from the copy beside it, so a fixed ratio would fight it.
 */
.editorial-block__media {
	aspect-ratio: auto;
}

/*
 * The two fits the reference uses, per block, set in the Customizer.
 *
 * Default is fill: a photograph is cropped to its half of the band and runs to
 * the edges, which is what the brand page's first two bands and all three of the
 * personalisation page's do.
 *
 * `contain` is for a *product still* -- the row of cases under the 110-year
 * lock-up, say. Cropping one of those cuts a case in half, so it is shown whole
 * and centred; the band's own panel colour becomes the ground behind it (see
 * template-parts/editorial-block.php) rather than a second near-white, which
 * would put a visible seam down the middle of the band.
 */
.editorial-block--fit-contain .editorial-block__media {
	display: flex;
	align-items: center;
	justify-content: center;
	background: none;
}

.editorial-block--fit-contain .editorial-block__media img {
	position: relative;
	inset: auto;
	width: 100%;
	height: auto;
	max-height: 100%;
	object-fit: contain;
}

/*
 * The personalisation page's own splits, measured band by band off the
 * reference: a cropped band gives 60% of the width to the artwork and 40% to
 * the copy, and only the band whose artwork is shown whole is an even pair --
 * with 50px of page between the two halves rather than none, because that
 * artwork is a black card and the copy's cream would otherwise butt into it.
 * The brand page keeps the even flush pair on every band, so both are scoped.
 */
.personalise .editorial-block--fit-cover .editorial-block__inner {
	grid-template-columns: 4fr 6fr;
}

.personalise .editorial-block--left.editorial-block--fit-cover .editorial-block__inner {
	grid-template-columns: 6fr 4fr;
}

/*
 * That gap is page, not panel, so this band's inner keeps no ground of its own:
 * the copy's half carries the colour and the artwork's half is the artwork. The
 * brand page's contained band still letterboxes on the panel colour, which is
 * why this override is here rather than in the shared rule above.
 */
.personalise .editorial-block--fit-contain .editorial-block__inner {
	background: none;
	column-gap: clamp(20px, 3.1vw, 50px);
}

/*
 * The opening band's artwork is the exception: it is a photograph chosen to be
 * the top of the page rather than a campaign file with wording in it, so it
 * fills its half and takes the crop, which is what the reference does with it.
 */
.editorial-lead__media {
	aspect-ratio: auto;
}

/*
 * Sentence case, at the reference's size. Uppercase was the theme's own house
 * style for section headings; on a page whose headings are full sentences it
 * turns each one into a banner.
 */
.editorial-block__title {
	font-size: clamp(20px, 1.5vw, 24px);
	font-weight: 600;
	letter-spacing: 0;
	line-height: 1.2;
	text-transform: none;
}

/*
 * The first line of a block reads as its opening sentence, not as a pull quote.
 * Set larger and in italics it announced itself over the paragraphs it was
 * introducing.
 */
.editorial-block__quote {
	margin-top: 20px;
	color: var(--ink-soft);
	font-size: 16px;
	font-style: normal;
	line-height: 1.6;
}

/* One rhythm down the panel: 20px between the heading, the copy and the button. */
.editorial-block__text,
.editorial-block__quote + .editorial-block__text {
	margin-top: 20px;
	line-height: 1.6;
}

/*
 * The reference sets these buttons at 15px with no tracking and a 4px corner --
 * shorter and less spaced than the theme's own 14px/0.11em button. It is the one
 * place on the site that departs from it, because a band's button sits at the
 * foot of a paragraph rather than under a section heading.
 */
.editorial-block__cta {
	align-self: flex-start;
	margin-top: 20px;
	min-height: 39px;
	padding-inline: 24px;
	border-radius: 4px;
	font-size: 15px;
	letter-spacing: normal;
}

/* ---- Editorial pages: the panel palette ---- */

/*
 * Sampled off the reference pages. Four grounds, repeated down a page, are what
 * make it read as a set.
 *
 * Held as custom properties rather than as a background per class, because the
 * same colour has to be reachable from two different elements: the copy's half
 * on a fill block, and the whole band on a contained one. One declaration each,
 * and the "none" case needs no rule at all.
 */
/*
 * #f6f6f6 rather than the #efefef sampled off the reference's second band,
 * because the reference's *third* band -- the one with a contained still on it --
 * uses #f6f6f6, and that is not a coincidence: it is the ground the artwork file
 * itself is cut on. Matching it is what stops a faint lighter rectangle showing
 * around a contained image. Seven values lighter is invisible on the bands that
 * fill; a visible seam on the one that does not is not.
 */
/* The heading and body greys are the reference's own, sampled with the panels. */
.editorial-block {
	--panel: #f6f6f6;
	--panel-ink: #242424;
	--panel-soft: #767676;
}

.editorial-block--panel-cream {
	--panel: #f8ecdc;
}

.editorial-block--panel-sky {
	--panel: #bfd7ef;
}

.editorial-block--panel-dark {
	--panel: #778288;
	--panel-ink: var(--white);
	--panel-soft: rgba(255, 255, 255, 0.92);
}

.editorial-block--panel-none {
	--panel: transparent;
}

.personalise-more__inner {
	background: #efefef;
}

.editorial-block__body {
	background: var(--panel);
	color: var(--panel-ink);
}

/* A contained still is letterboxed on the same ground as the copy beside it. */
.editorial-block--fit-contain .editorial-block__inner {
	background: var(--panel);
}

.editorial-block__quote,
.editorial-block__text {
	color: var(--panel-soft);
}

/* On the dark panel a black button disappears into it; this one inverts. */
.editorial-block--panel-dark .editorial-block__cta {
	background: var(--white);
	color: var(--ink);
}

.editorial-block--panel-dark .editorial-block__cta:hover,
.editorial-block--panel-dark .editorial-block__cta:focus-visible {
	background: var(--ink);
	color: var(--white);
}

/* ---- Personalisation: the opening band ---- */

/*
 * Artwork on one side, the title and the intro on the panel beside it -- the
 * reference's own opening, and the reason the page needs no separate title band
 * or breadcrumb above it.
 */
.editorial-lead__inner {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	align-items: stretch;
	min-height: clamp(280px, 34vw, 500px);
}

.editorial-lead--single .editorial-lead__inner {
	grid-template-columns: minmax(0, 1fr);
}

.editorial-lead__body {
	display: flex;
	flex-direction: column;
	justify-content: center;
	padding: clamp(30px, 3.4vw, 62px) clamp(24px, 3.2vw, 58px);
}

.editorial-lead__title {
	font-size: clamp(30px, 3.2vw, 46px);
	font-weight: 400;
	letter-spacing: 0;
	line-height: 1.1;
}

.editorial-lead__text,
.editorial-lead__note {
	margin-top: 22px;
	max-width: 62ch;
	font-size: 15px;
	line-height: 1.75;
}

.editorial-lead--panel-grey .editorial-lead__body {
	background: #efefef;
}

.editorial-lead--panel-cream .editorial-lead__body {
	background: #f8ecdc;
}

/*
 * White on the sky panel is the reference's own treatment and the store can
 * step off it in one click -- the panel colour is a Customizer choice, and every
 * other value in the list carries dark copy at full contrast.
 */
.editorial-lead--panel-sky .editorial-lead__body {
	background: #bfd7ef;
	color: var(--white);
}

.editorial-lead--panel-dark .editorial-lead__body {
	background: #778288;
	color: var(--white);
}

/* ---- Personalisation: the four kinds ---- */

/* Landscape stills, as the reference crops them, and titles in the case they
   were typed in -- these are category names, not headings. */
.personalise-type__media {
	aspect-ratio: 14 / 9;
}

.personalise-type__title {
	margin-top: 16px;
	font-size: 18px;
	letter-spacing: 0;
	text-transform: none;
}

/* ---- Personalisation: the category shortcuts ---- */

/*
 * A band with the heading centred over the names, rather than a left-aligned
 * heading over a row of pills. Four pills the same width as the four tiles above
 * them read as a second set of choices; plain links read as what they are, a way
 * back into the catalogue.
 */
.personalise-more {
	margin-top: clamp(30px, 4.4vw, 70px);
	padding-inline: var(--gutter);
}

/*
 * The grey is a panel the width of the bands under it, not a strip across the
 * screen -- so the section carries the gutter and the panel's own padding
 * replaces the container's.
 */
.personalise-more__inner {
	padding: clamp(26px, 2.5vw, 40px);
	text-align: center;
}

.personalise-more__title {
	font-size: clamp(19px, 1.5vw, 24px);
	font-weight: 600;
	letter-spacing: 0;
	text-transform: uppercase;
}

.personalise-more__list {
	justify-content: center;
	gap: 8px 26px;
	margin-top: 20px;
}

.personalise-more__chip {
	min-height: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	font-size: 17px;
	font-weight: 400;
	letter-spacing: 0;
	text-transform: none;
}

.personalise-more__chip:hover,
.personalise-more__chip:focus-visible {
	background: none;
	color: var(--ink);
	text-decoration: underline;
	text-underline-offset: 5px;
}

/* ---- The legal strip's typography ---- */

/*
 * "© 2026" muted, the store's name and the credit after it in bold, the domain
 * as a quiet link -- three weights in one line, as the reference sets it. The
 * link was the theme's own blue, which on a grey strip was the loudest thing in
 * the footer.
 */
.legal {
	background: var(--off);
}

.legal__date {
	color: var(--muted);
}

.legal__name {
	font-weight: 700;
}

.legal__line .legal__by {
	color: #5c6b78;
	font-weight: 600;
}

.legal__line .legal__by:hover,
.legal__line .legal__by:focus-visible {
	color: var(--ink);
	text-decoration: underline;
}

/* ---- The Instagram tiles' hover ---- */

/*
 * Likes and comments over a dimmed still, which is what the reference shows and
 * what a live feed can actually supply. The glyph-only state is still there for
 * uploads and for accounts the API gives no counts for -- see footer.php.
 */
.insta-grid__glyph {
	gap: 14px;
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.02em;
}

.insta-grid__stat {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	line-height: 1;
}

/* ---- The two floating controls, side by side ---- */

/*
 * The chat button used to climb above the compare tray, so the corner held one
 * control stacked on another. They sit on one line now: the tray keeps the
 * corner and the chat button steps to its left, centred against the taller of
 * the two.
 *
 * Only while the tray is *collapsed*. Open, it grows to a 470px bar and there is
 * no room beside it, so the button goes back over the top -- which is the rule
 * section 44 already had, kept below.
 */
body:has(.compare-tray:not([hidden])) .whatsapp {
	right: calc(var(--gutter) + 78px);
	bottom: calc(clamp(20px, 3.4vw, 64px) + 8px);
}

body:has(.compare-tray.is-open) .whatsapp {
	right: 20px;
	bottom: calc(clamp(20px, 3.4vw, 64px) + 76px);
}

/* ---- Campaign artwork on a phone ---- */

/*
 * A hero slide that is finished artwork carries its headline and its button
 * inside the image file. Cropped to the panel's ratio -- 16/9 on a desktop,
 * 4/5 on a phone -- that is exactly the part that goes: at 390px the homepage
 * banner showed the model and lost "FOR EVERY JOURNEY" and "BLI VALIXHE" off the
 * right-hand side.
 *
 * So an art slide sets its own height from its own image: the panel drops its
 * aspect ratio, the track comes back into flow, and the active slide's image
 * lays out at its natural proportions. Slides the theme composes itself -- a
 * title, a subtitle and a button over a photograph -- still crop, because there
 * the crop is what makes room for the copy.
 */
@media (max-width: 1024px) {
	.hero__main:has(.hero__main-slide--art):not(.hero__main--phone) {
		aspect-ratio: auto;
	}

	.hero__main:has(.hero__main-slide--art):not(.hero__main--phone) .hero__main-slides {
		position: relative;
		inset: auto;
	}

	.hero__main:not(.hero__main--phone) .hero__main-slide--art.is-active {
		position: relative;
	}

	.hero__main:not(.hero__main--phone) .hero__main-slide--art img {
		position: relative;
		inset: auto;
		height: auto;
	}

	/* Same for the side panel, which is a second finished banner. */
	.hero__side:has(.hero__slide--art):not(.hero__side--phone) {
		min-height: 0;
	}

	.hero__side:has(.hero__slide--art):not(.hero__side--phone) .hero__slides {
		position: relative;
	}

	.hero__side:not(.hero__side--phone) .hero__slide--art.is-active {
		position: relative;
		padding: 0;
	}

	.hero__side:not(.hero__side--phone) .hero__slide--art img {
		position: relative;
		inset: auto;
		height: auto;
	}
}

/*
 * The scrim exists so white copy survives a photograph. A slide with no copy on
 * it has nothing to protect, and the scrim just darkens finished artwork -- which
 * is what was washing out "PACKING, PERFECTED" on the homepage's side banner.
 */
.hero__slide--art.hero__slide--photo::after {
	display: none;
}

/*
 * Finished artwork with a link set in the Customizer: the whole panel is the
 * link, laid over the image. z-index 1 sits under the overlaid dots (z-index 2).
 */
.hero__slide-link {
	position: absolute;
	inset: 0;
	z-index: 1;
}

/* ---- Narrower screens ---- */

@media (max-width: 767px) {
	/*
	 * One column. No aspect ratio is put back on either artwork cell: the image
	 * is in flow and shown whole, so its own proportions give the cell its
	 * height -- which is the point of the fit above, and a 4/3 box here would
	 * put grey bands above and below every one of these wide campaign files.
	 */
	.editorial-lead__inner {
		grid-template-columns: minmax(0, 1fr);
		min-height: 0;
	}

	.editorial-block__inner {
		min-height: 0;
	}

	/*
	 * The per-band splits above are three classes deep, so section 43's
	 * single-column rule cannot reach them here -- these repeat those exact
	 * selectors so one column still wins on a phone.
	 */
	.personalise .editorial-block--fit-cover .editorial-block__inner,
	.personalise .editorial-block--left.editorial-block--fit-cover .editorial-block__inner,
	.personalise .editorial-block--fit-contain .editorial-block__inner {
		grid-template-columns: minmax(0, 1fr);
	}

	/*
	 * In one column every artwork cell comes into flow, contained and cropped
	 * alike. A cropped one keeps section 4's absolute image, and with the band's
	 * min-height gone and no taller sibling left to stretch against, its cell
	 * measured nothing and the photograph disappeared -- which is what the
	 * comment above about proportions giving the cell its height assumed was
	 * already true of both fits, and was only true of the contained one.
	 */
	.editorial-block__media img {
		position: relative;
		inset: auto;
		width: 100%;
		height: auto;
	}

	/* The film cell keeps its 3:2 above, so its poster stays cropped to it. */
	.editorial-block--film .editorial-block__media img {
		position: absolute;
		inset: 0;
		height: 100%;
	}

	/*
	 * The one cell that does need a ratio back. Its artwork fills rather than
	 * fits, so the image is still out of flow (section 4) -- in one column there
	 * is no taller sibling to stretch against and the cell would collapse to
	 * nothing, taking the photograph with it.
	 */
	.editorial-lead__media {
		aspect-ratio: 4 / 3;
	}

	.personalise-more__list {
		gap: 6px 18px;
	}

	/*
	 * Still side by side: the tray is a 62px disc down to 560px, and 40 + 62
	 * plus the gaps clears the screen with room to spare. The offset is measured
	 * off the gutter, which is what the tray is positioned from, rather than off
	 * the 14px the button uses when it is alone in the corner.
	 */
	body:has(.compare-tray:not([hidden])) .whatsapp {
		right: calc(var(--gutter) + 78px);
		bottom: calc(clamp(20px, 3.4vw, 64px) + 11px);
	}

	.site-main.shop .woocommerce-message,
	.site-main.shop .woocommerce-info,
	.site-main.shop .woocommerce-error {
		flex-wrap: wrap;
	}

	.site-main.shop .woocommerce-message .button,
	.site-main.shop .woocommerce-info .button,
	.site-main.shop .woocommerce-error .button {
		margin-left: 34px;
	}
}

/*
 * Below 560px section 27 turns the tray into a labelled bar the full width of
 * the screen, so there is nothing to sit beside: the chat button goes back over
 * the top of it. Its own corner inset is 14px (section 44) and the bar is 18px
 * from the bottom, so the clearance is measured from there rather than from the
 * clamp the wider layout uses.
 */
@media (max-width: 560px) {
	body:has(.compare-tray:not([hidden])) .whatsapp,
	body:has(.compare-tray.is-open) .whatsapp {
		right: 14px;
		bottom: 82px;
	}
}

/* ---- The footer, tighter ---- */

/*
 * Measured against the reference: its column row is ~390px tall and its legal
 * strip ~70px; this one was 490 and 100. The extra came from generous padding
 * and from 48px between link rows, which on a five-item list is most of the
 * difference on its own. Nothing here changes what the footer holds -- only how
 * much air is around it.
 */
.footer {
	padding: 48px 0 52px;
}

.footer__title {
	margin-bottom: 18px;
}

.footer__links li + li {
	margin-top: 10px;
}

.footer__links a {
	font-size: 15px;
}

.footer__brand-link {
	margin-bottom: 24px;
}

.footer__group + .footer__group {
	margin-top: 18px;
}

.footer__group-title,
.footer__group-row {
	font-size: 15px;
}

.legal {
	padding: 20px 0 22px;
}

.legal__line {
	font-size: 14px;
}

/* ---- A background film on a hero side slide, the material banner or an editorial block ---- */

/*
 * The film sits over the still and under the slide's copy: section 4 puts the
 * artwork at the bottom of the positioned layer, section 37 lifts the copy and
 * the button to z-index 1, so 0 here is exactly between them.
 *
 * The iframe is scaled to *cover* the panel, which the two providers will not do
 * for you: given a tall narrow frame, Vimeo's background player sizes itself
 * `height: 56.25vw` and centres, so a 320x700 panel gets a 320x180 strip
 * floating in the middle of it. Measured, not assumed.
 *
 * Covering needs the panel's own proportions, and the panel has none to give --
 * it is a tall column on a desktop and a wide band on a phone. Container query
 * units supply them: `cqw`/`cqh` are to this box what `vw`/`vh` are to the
 * viewport, so `max(100cqw, 177.78cqh)` is "as wide as the box, or as wide as
 * 16:9 of its height, whichever is more" -- which is exactly cover, in two
 * declarations and no script.
 */
.hero__film,
.material__film,
.editorial-block__film {
	position: absolute;
	inset: 0;
	z-index: 0;
	display: block;
	container-type: size;
	overflow: hidden;
	pointer-events: none;
}

.hero__film iframe,
.material__film iframe,
.editorial-block__film iframe {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	width: max(100cqw, 177.7778cqh);
	height: max(56.25cqw, 100cqh);
	border: 0;
}

/*
 * The personalisation page's film band. Its artwork cell takes the clip's own
 * 3:2 rather than the height of the copy beside it: Vimeo letterboxes a 3:2
 * film inside its 16:9 frame, and the cover maths above only closes the gap at
 * the sides when the cell is at least as tall as 3:2. A taller cell (long copy,
 * or one column on a phone) still covers -- it crops the sides instead.
 */
.editorial-block--film .editorial-block__media {
	aspect-ratio: 3 / 2;
}

/*
 * Measured off samsonite.co.uk/personalisation at 1920px: an even pair, the
 * film left, the copy on the page's own white with 60px either side, a bold
 * uppercase heading at 36px, 20px body in black, and the black "Shop now".
 */
.personalise .editorial-block--fit-cover.editorial-block--film .editorial-block__inner {
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* Same specificity as the one-column rule in section 45's phone query, and
   later in the file, so it has to be said again here. */
@media (max-width: 767px) {
	.personalise .editorial-block--fit-cover.editorial-block--film .editorial-block__inner {
		grid-template-columns: minmax(0, 1fr);
	}
}

.editorial-block--film {
	--panel-ink: var(--black);
	--panel-soft: var(--black);
}

.editorial-block--film .editorial-block__body {
	padding-inline: clamp(24px, 3.2vw, 60px);
}

.editorial-block--film .editorial-block__title {
	font-size: clamp(22px, 1.9vw, 36px);
	font-weight: 700;
	text-transform: uppercase;
}

.editorial-block--film .editorial-block__text {
	font-size: clamp(15px, 1.05vw, 20px);
	line-height: 1.3;
}

.editorial-block--film .editorial-block__cta {
	margin-top: 24px;
	min-height: 57px;
	padding-inline: 28px;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.06em;
}

/* ---- Campaign artwork with a phone-shaped file ---- */

/*
 * A slide given its own phone crop takes its shape from that file: the panel
 * drops its ratio and the picture lays out in flow at its natural proportions.
 * That is the whole mechanism -- how tall the banner is on a phone becomes the
 * store's choice of crop rather than a number in this stylesheet, which is how
 * the reference builds vary the two banners' heights.
 *
 * Without a phone file nothing here applies and the rules above hold: composed
 * slides crop to the panel's ratio, finished artwork shows whole.
 */
@media (max-width: 1024px) {
	/*
	 * `--phone-ar` is the uploaded file's own width/height, written onto the
	 * panel by the template. The panel keeps working exactly as it does
	 * everywhere else in the theme -- a ratio box with absolutely positioned
	 * artwork covering it -- and only the number changes.
	 *
	 * Taking the shape from the *image* instead was tried first and does not
	 * work: an `<img>` inside a `<picture>` keeps the `width`/`height` attributes
	 * of the desktop file, `<picture>` and the slider's own stacking put the
	 * image out of flow, and the panel came out at 1:2.3 with the correct square
	 * file loaded -- which reads as the `<source>` having been ignored when it
	 * had not. A declared ratio has none of that to go wrong.
	 */
	.hero__main--phone,
	.hero__side--phone {
		aspect-ratio: var(--phone-ar);
	}

	/* The side panel's floor would otherwise out-argue a short ratio. */
	.hero__side--phone {
		min-height: 0;
	}

	/* `<picture>` is a wrapper the artwork rules do not know about. */
	.hero__main-slide picture,
	.hero__slide picture {
		display: contents;
	}
}

/* --------------------------------------- 46. Homepage phone parity --- */

/*
 * The reference build's phone header is a shorter row with a smaller mark and
 * lighter glyphs (measured: 56.6px against our 62). The icons are drawn at 24
 * in the markup for every width, so the phone size is taken here in CSS.
 */
@media (max-width: 767px) {
	.header__top-inner {
		min-height: 56px;
	}

	.wordmark__image {
		max-height: 22px;
	}

	.wordmark {
		font-size: 22px;
	}

	.header__burger svg,
	.header__action svg {
		width: 20px;
		height: 20px;
	}

	/* The sticky offset follows the shorter row (56 + the 1px rule). */
	:root {
		--header-h: 57px;
	}

	/* Daylight between the two campaign banners, which section 40 butts
	   together for the full-bleed look. */
	.hero__grid {
		gap: 18px;
	}

	/*
	 * A material banner that is a film keeps the film's own 16:9 instead of
	 * the portrait crop -- the embed covers the box, so a 3/4 box shows a
	 * third of the picture.
	 */
	.material--film {
		aspect-ratio: 16 / 9;
	}
}

/* --------------------------- 47. Product summary reference parity --- */

/*
 * The reference's single product page, measured element by element on
 * samsonite.gr (ecodiver-958909, DevTools, 2026-08-24). Their type is set in
 * Commissioner and every size below is fixed px at any width above their
 * 767px phone band; the theme's own phone band (sections 23/40) is left
 * alone, so the metric overrides only apply where the desktop summary
 * layout does.
 *
 * The font ships from Google Fonts only on the product page (inc/setup.php)
 * and is scoped to the page's main, so the header and footer keep the site
 * stack.
 */

.site-main.product-page {
	font-family: "Commissioner", var(--font);
}

@media (min-width: 1025px) {

	/*
	 * The reference's summary column is proportional, not fixed: their
	 * col-md-6 (50%) up to 1200, col-xl-4 (33.333%) above it. The theme's
	 * fixed 420/470/560px tracks are narrower than that at nearly every
	 * width, which squeezes the whole data column.
	 */
	.site-main.product-page {
		--product-summary-w: 50%;
	}

	/* 14px / #757575, as their .breadcamp li a. */
	.crumbs__list {
		color: #757575;
		font-size: 14px;
		line-height: 1.6;
	}

	/* h1.common: 30 / 700, line-height 1.2. */
	.product-title {
		font-size: 30px;
		letter-spacing: normal;
		line-height: 1.2;
	}

	/* #ProductTitle h2: 22 / 400. */
	.product-subtitle {
		margin-top: 4px;
		font-size: 22px;
		line-height: 1.2;
	}

	/* .product-promo-flag__content: 12 / 800 #c91010, padding 10px 15px,
	   margin 20px 0. */
	.product-discount {
		min-width: 0;
		height: auto;
		margin-top: 20px;
		padding: 10px 15px;
		border: 1px solid currentColor;
		color: #c91010;
		font-size: 12px;
		font-weight: 800;
		line-height: 1.5;
	}

	/* Their price h3 carries margin 20px above (the flag's bottom margin)
	   and 30px below, to the details row. */
	.product-pricing {
		margin-top: 20px;
	}

	/* Struck price stacked right on top of the current one: 16.5 / 400
	   #575757 over 22 / 700, no gap between the two lines. */
	.product-price {
		gap: 0;
	}

	.product-price del {
		color: #575757;
		font-size: 16.5px;
		line-height: 1.2;
	}

	.product-price ins {
		font-size: 22px;
		line-height: 1.5;
	}

	/* #ProductStockTxt: 12px, text and dot both #00c3a8. */
	.product-stock {
		color: #00c3a8;
		font-size: 12px;
		letter-spacing: normal;
	}

	.product-stock__dot {
		background: #00c3a8;
	}

	/* .pro-inr-details: a plain 14px / #757575 row, no rules and no
	   underline. */
	.product-links {
		margin-top: 30px;
		padding: 0;
		border: 0;
	}

	.product-link {
		color: #757575;
		font-size: 14px;
	}

	.product-link span {
		text-decoration: none;
	}

	/* Size / colour labels: 14 / 700 (their .font16 class is dead and the
	   labels fall back to the global 14px h3). Each block sits under a rule
	   that runs the full column width -- from the viewport edge, through the
	   summary's gutter, to the dividing border -- as the reference's
	   .top-product-cat-details rows do. */
	.product-option {
		margin-top: 18px;
		margin-left: calc(-1 * var(--gutter));
		padding: 18px 0 0 var(--gutter);
		border-top: 1px solid var(--line);
	}

	.product-option__label {
		font-size: 14px;
		font-weight: 700;
		letter-spacing: normal;
	}

	/* .size-outr li a: 14 / 400, padding 0.6rem 1rem, 5px between chips'
	   margins = 10px apart, no fixed box. */
	.sizes {
		gap: 10px;
		margin-top: 8px;
	}

	.sizes__item {
		min-width: 0;
		height: auto;
		padding: 9.6px 16px;
		font-size: 14px;
		line-height: 1.6;
	}

	/* .color-outr a: 24px dots, 10px apart; the active ring hugs the dot
	   (li is 33.6px over a 24px swatch). */
	.colours {
		gap: 10px;
		margin-top: 8px;
	}

	.colours__item {
		width: 24px;
		height: 24px;
	}

	.colours__item.is-selected::after {
		inset: -5px;
		border-width: 1px;
	}

	/* #add-to-cart-btn: 16 / 700 white on black, padding 16px 32px,
	   line-height 1.6 puts the box at their 57.6px. */
	/* The buy row sits under the same full-width rule. */
	.product-buy {
		gap: 16px;
		margin-top: 18px;
		margin-left: calc(-1 * var(--gutter));
		padding: 14px 0 0 var(--gutter);
		border-top: 1px solid var(--line);
	}

	.product-buy .single_add_to_cart_button,
	.site-main.shop .product-buy .single_add_to_cart_button {
		min-height: 0;
		padding: 16px 32px;
		font-size: 16px;
		font-weight: 700;
		letter-spacing: normal;
		line-height: 1.6;
	}

	/* Their heart sits in a 53.6 x 41.6 box around the same ~30px icon. */
	.wishlist {
		width: 54px;
		height: 42px;
	}
}

/* Their col-xl-4 band: a third of the 1920px-capped layout from 1200 up. */
@media (min-width: 1200px) {
	.site-main.product-page {
		--product-summary-w: 33.333%;
	}
}

/* ------------------------------------------- 48. Sticky shop filters --- */

/*
 * The filter column follows the catalogue down the page. Only above the
 * drawer breakpoint: below 1025px the column is a fixed drawer and
 * position:sticky must not override that. The offset clears the sticky
 * header plus the 78px shop toolbar pinned under it (section 20), and the
 * column scrolls its own overflow so a group list taller than the viewport
 * stays reachable while pinned.
 */
@media (min-width: 1025px) {
	.shop-layout__side {
		position: sticky;
		top: calc(var(--header-h) + var(--admin-bar-height) + 78px);
		max-height: calc(100vh - var(--header-h) - var(--admin-bar-height) - 78px);
		overflow-y: auto;
		overscroll-behavior: contain;
	}
}

/* --------------------------------------- 49. Filter column overflow --- */

/*
 * When the closed groups alone are taller than section 48's viewport cap,
 * the pinned column hides its tail behind an inner scrollbar that page
 * scrolling never reaches -- the last group (Zbritje) simply never shows.
 * main.js marks that state (initShopFilterFit), and the column gives up
 * the pin to flow with the page, where scrolling reaches everything.
 */
@media (min-width: 1025px) {
	.shop-layout__side.is-overtall {
		position: static;
		max-height: none;
		overflow-y: visible;
	}
}
