/* ==========================================================================
   Heritage Thangka Gallery — design tokens + base
   Tokens lifted from the approved design comps in /Heritage Thangka website/
   ========================================================================== */

:root {
	/* Surfaces */
	--ht-cream:        #faf7f1;
	--ht-cream-warm:   #f4eee3;
	--ht-cream-light:  #fdf9f2;
	--ht-surface:      #fffdf8;  /* control fills: unticked boxes, sort select */
	--ht-line:         #c9bda9;  /* outline of an unticked control */
	--ht-track:        #e0d6c6;  /* slider track, chip border */
	--ht-faint:        #a79a88;  /* option counts, slider end labels */
	--ht-cream-rose:   #f7ebe3;

	/* Ink */
	--ht-ink:          #241e17;
	--ht-body:         #4a4238;
	--ht-muted:        #6e6257;

	/* Accents */
	--ht-crimson:      #8a2323;
	--ht-crimson-dark: #6e1b1b;
	--ht-crimson-deep: #5e1717;
	--ht-gold:         #e9c87e;

	/* Footer */
	--ht-footer-text:  #b9ae9f;

	/* Catalog */
	--ht-canvas:       #eee6d8;  /* image well behind product art */
	--ht-stone:        #8b7d6b;  /* muted label above product names */

	/* Lines */
	--ht-border:       #e8e0d4;

	/* Breakpoint mirrored in assets/js/navigation.js via toggle visibility */
	--ht-bp-nav:       900px;

	/* Type */
	--ht-font-display: "Outfit", ui-sans-serif, system-ui, sans-serif;
	--ht-font-body:    "Manrope", ui-sans-serif, system-ui, sans-serif;

	/* Rhythm */
	/*
	 * 1304, not 1240: the comps are content-box, so their max-width:1240 plus
	 * 32px gutters is 1240px of *content*. This sheet is border-box, so the
	 * same content width means naming the outer measurement.
	 */
	--ht-container:    1304px;
	--ht-gutter:       32px;
	--ht-radius:       4px;
	--ht-card-pad:     12px;  /* product card frame inset */
}

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

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

h1, h2, h3, h4 {
	font-family: var(--ht-font-display);
	font-weight: 500;
	line-height: 1.15;
	text-wrap: balance;
}

a { color: var(--ht-crimson); text-decoration: none; }
a:hover { color: var(--ht-crimson-deep); }

img, svg, video { max-width: 100%; height: auto; }

/* --------------------------------------------------------------------------
   Container
   -------------------------------------------------------------------------- */

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

/* --------------------------------------------------------------------------
   Announcement bar
   -------------------------------------------------------------------------- */

/*
 * Deliberately the deeper crimson, not --ht-crimson: the nav bar below uses
 * #8a2323, and two identical bands separated only by the logo row competed.
 * The darker announcement recedes and lets the nav read as the dominant tier.
 */
.ht-announcement {
	background: var(--ht-crimson-dark);
	color: var(--ht-cream-rose);
	text-align: center;
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	padding: 9px 16px;
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

/*
 * The header itself no longer sticks — only .ht-header-nav does. The logo row
 * scrolls away, giving the viewport back (124px of sticky chrome -> ~51px).
 *
 * Note the backgrounds below are all SOLID. backdrop-filter would make the nav
 * bar a containing block for its position:fixed descendants, which would trap
 * the mobile drawer inside the bar instead of letting it fill the viewport.
 */
.ht-site-header {
	background: var(--ht-cream);
	border-bottom: 1px solid var(--ht-border);
}

/* Zero-height probe for the IntersectionObserver in navigation.js. */
.ht-nav-sentinel {
	height: 0;
}

/* Row 1 — brand left, actions right */
.ht-header-top__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	min-height: 72px;
}

/*
 * Row 2 — navigation on its own centred bar.
 * Deliberate divergence from the comps, which run the nav inline in row 1.
 */
.ht-header-nav {
	position: sticky;
	top: 0;
	z-index: 50;
	background: var(--ht-crimson);
	border-bottom: 1px solid var(--ht-crimson);
	transition: background-color 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
}

/*
 * Pinned state, toggled by navigation.js: the bar lightens to cream so it sits
 * quietly over the content. The shadow does the separating work here — cream on
 * cream has no edge of its own, and backdrop-filter is not an option because it
 * would make the bar a containing block for the fixed mobile drawer.
 */
.ht-header-nav.is-stuck {
	background: var(--ht-cream);
	border-bottom-color: var(--ht-border);
	box-shadow: 0 2px 14px rgba(36, 30, 23, 0.10);
}

.ht-header-nav__inner {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
}

/*
 * Compact logo, revealed only while pinned. Absolutely positioned so the nav
 * stays optically centred and nothing shifts sideways when it appears.
 * visibility (not just opacity) keeps it out of the tab order when hidden.
 */
.ht-nav-brand {
	position: absolute;
	left: var(--ht-gutter);
	display: flex;
	align-items: center;
	opacity: 0;
	visibility: hidden;
	transform: translateX(-10px);
	transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s;
}
.ht-header-nav.is-stuck .ht-nav-brand {
	opacity: 1;
	visibility: visible;
	transform: none;
}

/*
 * No colour filter: the pinned bar is cream, so the logo shows in its own
 * colours exactly as it does in the header above.
 */
.ht-nav-brand .ht-nav-brand__img {
	display: block;
	width: auto;
	height: 30px;
}

/*
 * Cart mirrors .ht-nav-brand on the right: absolutely positioned so the nav
 * stays optically centred, and revealed on the same transition when pinned.
 *
 * Inset by the gutter rather than sitting flush at 0. Absolute positioning
 * resolves against the containing block's PADDING box, so `right: 0` put the
 * cart outside the 32px the container gives every other child -- including the
 * brand and actions in the header row above, which this bar is meant to echo.
 *
 * That was also a real horizontal scrollbar. Below the container's max-width
 * its edge IS the viewport's edge, so two things spilled past it: the count
 * badge, which hangs 6px out by design, and the 10px this element slides
 * outward while hidden (visibility:hidden keeps its box, and a transform still
 * contributes to scroll width). Measured at 1024px: 15px of overflow on every
 * page of the site. The gutter leaves both comfortably inside.
 */
.ht-nav-cart {
	position: absolute;
	right: var(--ht-gutter);
	display: flex;
	align-items: center;
	opacity: 0;
	visibility: hidden;
	transform: translateX(10px);
	transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s;
}
.ht-header-nav.is-stuck .ht-nav-cart {
	opacity: 1;
	visibility: visible;
	transform: none;
}

/* Slightly smaller than the header's, to sit inside the 52px bar. */
.ht-nav-cart .ht-cart {
	width: 36px;
	height: 36px;
}

.ht-brand { display: flex; flex-direction: column; color: var(--ht-ink); line-height: 1.1; }
.ht-brand__logo { display: block; }

/*
 * .ht-brand's own `color: var(--ht-ink)` above never reaches the wordmark:
 * `a { color: var(--ht-crimson) }` (near the top of this file) matches the
 * <a class="ht-brand__text"> element directly, and a rule that matches an
 * element directly always wins over a value it would otherwise only
 * inherit from its .ht-brand parent — that's not a specificity contest,
 * .ht-brand and `a` simply never compete because they match different
 * elements. .ht-brand__name (the inner span) declares no colour of its
 * own, so it was inheriting the anchor's crimson too. This rule is what
 * actually stops that — remove it and the whole wordmark reverts to
 * crimson, with .ht-brand's colour rule still sitting right there looking
 * like it should have been enough.
 */
.ht-brand__text { color: var(--ht-ink); }
.ht-brand__text:hover,
.ht-brand__text:focus-visible { color: var(--ht-crimson); }

/*
 * Two classes, not one. WooCommerce ships `.woocommerce-page img { height:auto }`
 * — class + element, specificity (0,1,1) — which outranks a lone
 * `.ht-brand__logo-img` (0,1,0) and let the logo balloon to its natural size on
 * every shop, cart, checkout and product page. Same reason for the pinned logo.
 */
.ht-brand .ht-brand__logo-img {
	display: block;
	width: auto;
	height: 46px;
}
.ht-brand__name { font-family: var(--ht-font-display); font-size: 21px; font-weight: 600; letter-spacing: 0.01em; }
.ht-brand__tagline {
	font-size: 10.5px;
	font-weight: 700;
	letter-spacing: 0.22em;
	color: var(--ht-crimson);
	margin-top: 3px;
	text-transform: uppercase;
}

/* Primary nav */
.ht-nav__list {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 32px;
	margin: 0;
	padding-block: 14px;
	padding-inline: 0;
	list-style: none;
	font-size: 14.5px;
	font-weight: 600;
}
/* At rest on crimson: cream at 8.5:1, gold current at 5.6:1 — both clear AA. */
.ht-nav__list a { color: var(--ht-cream-light); }
.ht-nav__list a:hover,
.ht-nav__list .current-menu-item > a,
.ht-nav__list .menu-item-has-children.is-open > a { color: var(--ht-gold); }

/* Pinned on cream: ink at 15.4:1, crimson current at 8.4:1. */
.ht-header-nav.is-stuck .ht-nav__list a { color: var(--ht-ink); }
.ht-header-nav.is-stuck .ht-nav__list a:hover,
.ht-header-nav.is-stuck .ht-nav__list .current-menu-item > a,
.ht-header-nav.is-stuck .ht-nav__list .menu-item-has-children.is-open > a { color: var(--ht-crimson); }

/* --- Dropdowns --- */

/*
 * "Deities Thangka" carries seventeen children. Left unstyled they rendered
 * as a bulleted list inside the bar, which grew it to 440px tall and pushed
 * the rest of the menu sideways.
 */
.ht-nav__list .menu-item-has-children { position: relative; }

.ht-nav__more {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 20px;
	height: 20px;
	margin-left: 4px;
	padding: 0;
	border: 0;
	background: transparent;
	cursor: pointer;
	vertical-align: middle;
	transition: color 0.2s ease;
}

/*
 * The chevron lives in a button BESIDE the link, not inside it, so it never
 * inherits the link's colour — it was picking up the body's ink and reading
 * dark against the crimson bar. It has to be given each bar state itself.
 */
.ht-nav__list .ht-nav__more { color: var(--ht-cream-light); }

.ht-nav__list .menu-item-has-children:hover > .ht-nav__more,
.ht-nav__list .menu-item-has-children:focus-within > .ht-nav__more,
.ht-nav__list .menu-item-has-children.is-open > .ht-nav__more,
.ht-nav__list .current-menu-ancestor > .ht-nav__more,
.ht-nav__list .current-menu-item > .ht-nav__more { color: var(--ht-gold); }

.ht-header-nav.is-stuck .ht-nav__list .ht-nav__more { color: var(--ht-ink); }

.ht-header-nav.is-stuck .ht-nav__list .menu-item-has-children:hover > .ht-nav__more,
.ht-header-nav.is-stuck .ht-nav__list .menu-item-has-children:focus-within > .ht-nav__more,
.ht-header-nav.is-stuck .ht-nav__list .menu-item-has-children.is-open > .ht-nav__more,
.ht-header-nav.is-stuck .ht-nav__list .current-menu-ancestor > .ht-nav__more,
.ht-header-nav.is-stuck .ht-nav__list .current-menu-item > .ht-nav__more { color: var(--ht-crimson); }

.ht-nav__chev {
	width: 7px;
	height: 7px;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: translateY(-2px) rotate(45deg);
	transition: transform 0.2s ease;
}

/*
 * Flipped for every way the panel can open, not just the button — on hover it
 * used to point down at an open menu.
 */
.ht-nav__list .menu-item-has-children:hover > .ht-nav__more .ht-nav__chev,
.ht-nav__list .menu-item-has-children:focus-within > .ht-nav__more .ht-nav__chev,
.ht-nav__list .menu-item-has-children.is-open > .ht-nav__more .ht-nav__chev {
	transform: translateY(1px) rotate(225deg);
}

.ht-nav__list .sub-menu {
	position: absolute;
	top: calc(100% + 14px);
	left: 50%;
	z-index: 5;
	margin: 0;
	padding: 16px 18px;
	list-style: none;
	background: var(--ht-cream-light);
	border: 1px solid var(--ht-border);
	border-radius: 10px;
	box-shadow: 0 18px 42px rgba(20, 12, 6, 0.16);
	/* Seventeen items in one column would run past the fold. */
	columns: 2;
	column-gap: 26px;
	min-width: 420px;
	max-width: min(560px, calc(100vw - 32px));
	font-size: 14px;
	font-weight: 600;
	text-align: left;
	opacity: 0;
	visibility: hidden;
	transform: translateX(-50%) translateY(-6px);
	transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s;
}

/*
 * The 14px gap above the panel would drop the hover on the way down to it,
 * so the panel reaches back up and covers it.
 */
.ht-nav__list .sub-menu::before {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	top: -14px;
	height: 14px;
}

.ht-nav__list .menu-item-has-children:hover > .sub-menu,
.ht-nav__list .menu-item-has-children:focus-within > .sub-menu,
.ht-nav__list .menu-item-has-children.is-open > .sub-menu {
	opacity: 1;
	visibility: visible;
	transform: translateX(-50%) translateY(0);
}

.ht-nav__list .sub-menu li { break-inside: avoid; }

/*
 * Four classes deep so it beats `.ht-header-nav.is-stuck .ht-nav__list a`,
 * which is 0,3,1 — the panel is cream in both bar states, so its links must
 * not follow the bar's colour.
 */
.ht-header-nav .ht-nav__list .sub-menu a,
.ht-header-nav.is-stuck .ht-nav__list .sub-menu a {
	display: block;
	padding: 7px 9px;
	border-radius: 6px;
	color: var(--ht-body);
	white-space: nowrap;
}
.ht-header-nav .ht-nav__list .sub-menu a:hover,
.ht-header-nav .ht-nav__list .sub-menu .current-menu-item > a,
.ht-header-nav.is-stuck .ht-nav__list .sub-menu a:hover,
.ht-header-nav.is-stuck .ht-nav__list .sub-menu .current-menu-item > a {
	background: var(--ht-cream-warm);
	color: var(--ht-crimson);
}

.ht-nav__more:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
	border-radius: 3px;
}

/* Actions */
.ht-header__actions {
	display: flex;
	align-items: center;
	gap: 20px;
	font-size: 14px;
	font-weight: 600;
}

/* Search — collapsed to an icon until hover or focus */
.ht-search {
	position: relative;
	display: flex;
	align-items: center;
	height: 42px;
	border: 1.5px solid transparent;
	border-radius: 99px;
	color: var(--ht-ink);
}
/*
 * This outer ring is the ONLY visible border searchform.php's plain,
 * always-on instance gets (its input carries no .ht-search__input class, so
 * none of the rules below ever touch it — see that template's own comment
 * for why). The header instance below, though, gives its OWN pill halves
 * (.ht-search__input / .ht-search__submit) a complete border once open, at
 * the exact same box edge this ring would draw — so :has() switches this
 * one off there specifically, rather than drawing a second, 1.5px-offset
 * ring right outside the first.
 */
.ht-search:hover,
.ht-search:focus-within { border-color: var(--ht-ink); }
.ht-search:has(.ht-search__input):hover,
.ht-search:has(.ht-search__input):focus-within { border-color: transparent; }

/*
 * Out of flow, at a CONSTANT 170px, so the expand never touches width or
 * padding — those are layout properties and force a reflow on every frame of
 * the transition. Only opacity and transform change, both compositor-only.
 *
 * Anchored with `right: 42px` — the submit button's own width — against
 * .ht-search's padding box, so the field's right edge sits flush at the
 * button's left edge and it grows LEFTWARD, into the open gap between the
 * logo and the actions row. Deliberately not anchored from .ht-search's own
 * right edge outward, or from a container edge at all: that is exactly the
 * shape that caused the sticky nav cart's overflow (see .ht-nav-cart above,
 * and tests/test-header-overflow.php) — an absolutely positioned box whose
 * offset resolves against a containing block whose edge, below the
 * container's max-width, IS the viewport's edge. This box's containing
 * block is the small search pill itself, never flush with any container or
 * viewport edge, so it has nowhere to spill past. Verified at 1440/1024/390
 * (below 900px the field is display:none regardless — see the breakpoint
 * below — so there is nothing to overflow there either).
 *
 * No `visibility: hidden` on the closed state, deliberately, even though it
 * would read as the obvious pair to opacity:0 here: a visibility:hidden
 * element cannot RECEIVE focus at all (confirmed in a real browser — even a
 * direct .focus() call on it is a no-op), which would silently break "must
 * open on focus, not only hover" below — a keyboard user tabbing forward
 * would skip straight over a hidden field and land on the submit button
 * instead, never reaching the input by the natural forward-tab path.
 * opacity:0 + pointer-events:none already keeps it invisible and un-clickable
 * while closed without taking away its focusability, exactly like the width:0
 * input this replaces (a zero-size box is still a legitimate focus target).
 */
.ht-search__input {
	position: absolute;
	top: 0;
	right: 42px;
	width: 170px;
	height: 100%;
	margin: 0;
	padding: 0 14px;
	/*
	 * --ht-line, not --ht-ink: every other field on the site (.ht-field-row
	 * .input-text, .ht-auth__input) rests at a light line weight and only
	 * darkens on interaction — --ht-ink here read as a near-black, out-of-
	 * family rectangle. It still darkens to --ht-ink, just scoped to
	 * :focus-within below, mirroring the escalation .ht-search itself
	 * already did before :has() switched that ring off for this instance.
	 */
	border: 1.5px solid var(--ht-line);
	border-right: none;
	border-radius: 99px 0 0 99px;
	background: var(--ht-surface);
	outline: none;
	font-family: var(--ht-font-body);
	font-size: 14px;
	color: var(--ht-ink);
	opacity: 0;
	transform: translateX(10px);
	transition: opacity 0.25s ease, transform 0.25s ease;
	/* pointer-events restored only once open — see the open state below. */
	pointer-events: none;
}
.ht-search:hover .ht-search__input,
.ht-search:focus-within .ht-search__input {
	opacity: 1;
	pointer-events: auto;
	transform: none;
}
.ht-search:focus-within .ht-search__input { border-color: var(--ht-ink); }

/*
 * outline:none above removes the browser's native focus ring, and
 * :focus-within darkening the border is a subtle cue against this cream
 * background — not enough on its own for a keyboard user to be sure where
 * they are. :focus-visible restores a real indicator, the same
 * outline:2px solid var(--ht-gold) treatment .ht-newsletter__input already
 * uses for the identical reason (a borderless-at-rest, pill-shaped field).
 */
.ht-search__input:focus-visible {
	outline: 2px solid var(--ht-gold);
	outline-offset: 2px;
}

/* Chrome/Safari's own '×' clear button renders in native chrome, unstyled
   and foreign to the pill it would sit inside — suppressed on every
   type="search" field under .ht-search, header pill and the plain
   searchform.php instance alike. */
.ht-search input[type="search"]::-webkit-search-cancel-button,
.ht-search input[type="search"]::-webkit-search-decoration {
	-webkit-appearance: none;
	appearance: none;
}

/*
 * Borderless/transparent at rest — identical to before this pass, so the
 * closed icon (the only state searchform.php's plain button ever shows,
 * and the header's own before hover/focus) is completely unchanged.
 * :has(.ht-search__input) scopes everything below to the header instance
 * only: searchform.php's button sits next to a default, unstyled input, and
 * giving it a half-pill border there would make that pairing look MORE
 * mismatched, not less.
 */
.ht-search__submit {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 42px;
	height: 42px;
	padding: 0;
	border: 1.5px solid transparent;
	border-radius: 0 99px 99px 0;
	background: none;
	color: inherit;
	cursor: pointer;
}
/*
 * The pill's right half once open — matching border, matching background,
 * mirrored radius, border-left removed so it butts seamlessly against the
 * input's own border-right:none above. Two adjoining halves read as one
 * continuous control instead of a rectangle sitting next to a bare icon.
 */
.ht-search:has(.ht-search__input):hover .ht-search__submit,
.ht-search:has(.ht-search__input):focus-within .ht-search__submit {
	border-color: var(--ht-line);
	border-left: none;
	background: var(--ht-surface);
}
.ht-search:has(.ht-search__input):focus-within .ht-search__submit { border-color: var(--ht-ink); }

/*
 * Live search results — a combobox listbox anchored under the control.
 * Same anchor reasoning as .ht-search__input above: right:0 against
 * .ht-search's own padding box, never a container/viewport edge, plus a
 * belt-and-braces max-width clamp to the viewport minus both gutters.
 */
.ht-search__panel {
	position: absolute;
	top: calc(100% + 8px);
	right: 0;
	z-index: 60;
	width: 340px;
	max-width: min(340px, calc(100vw - 2 * var(--ht-gutter)));
	max-height: 70vh;
	overflow-y: auto;
	margin: 0;
	background: var(--ht-cream-light);
	border: 1px solid var(--ht-border);
	border-radius: 10px;
	box-shadow: 0 18px 42px rgba(20, 12, 6, 0.16);
}
.ht-search__panel[hidden] { display: none; }

.ht-search__list {
	list-style: none;
	margin: 0;
	padding: 6px;
}

.ht-search__option {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 8px;
	border-radius: 6px;
	cursor: pointer;
}
.ht-search__option[aria-selected="true"] { background: var(--ht-cream-warm); }

.ht-search__thumb {
	flex: none;
	width: 44px;
	height: 44px;
	border-radius: var(--ht-radius);
	object-fit: cover;
	background: var(--ht-canvas);
}

.ht-search__body {
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.ht-search__name {
	font-size: 13px;
	font-weight: 600;
	color: var(--ht-ink);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.ht-search__meta {
	display: flex;
	align-items: baseline;
	gap: 8px;
	font-size: 12px;
	color: var(--ht-muted);
}

.ht-search__price {
	font-weight: 600;
	color: var(--ht-crimson);
}

.ht-search__option--seeall {
	justify-content: center;
	font-size: 13px;
	font-weight: 600;
	color: var(--ht-crimson);
}

.ht-search__empty {
	padding: 20px 14px;
	font-size: 13px;
	color: var(--ht-muted);
	text-align: center;
}

.ht-header__account { color: var(--ht-muted); }
.ht-header__account:hover { color: var(--ht-ink); }

/* Cart */
.ht-cart {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 42px;
	height: 42px;
	border: 1.5px solid var(--ht-ink);
	border-radius: 99px;
	color: var(--ht-ink);
	transition: background-color 0.2s, color 0.2s;
}
.ht-cart:hover { background: var(--ht-ink); color: var(--ht-cream-light); }

.ht-cart__count {
	position: absolute;
	top: -6px;
	right: -6px;
	display: flex;
	align-items: center;
	justify-content: center;
	min-width: 19px;
	height: 19px;
	padding: 0 4px;
	border-radius: 99px;
	background: var(--ht-crimson);
	color: var(--ht-cream-light);
	font-size: 11px;
	font-weight: 800;
	line-height: 1;
}
.ht-cart__count[hidden] { display: none; }

/* Drawer toggle — hidden above the breakpoint; JS keys off this visibility */
.ht-nav-toggle {
	display: none;
	flex-direction: column;
	justify-content: center;
	gap: 5px;
	width: 42px;
	height: 42px;
	padding: 0;
	border: 1.5px solid var(--ht-ink);
	border-radius: 99px;
	background: none;
	cursor: pointer;
}
.ht-nav-toggle__bar {
	display: block;
	width: 16px;
	height: 1.5px;
	margin-inline: auto;
	background: var(--ht-ink);
	transition: transform 0.2s, opacity 0.2s;
}

/*
 * Sits BELOW the header (z-index 50). The header is a stacking context, so the
 * drawer nested inside it cannot outrank a scrim layered above the header no
 * matter how high its own z-index goes.
 */
.ht-nav-scrim {
	position: fixed;
	inset: 0;
	z-index: 40;
	background: rgba(20, 12, 6, 0.45);
}
.ht-nav-scrim[hidden] { display: none; }

/* --------------------------------------------------------------------------
   Main
   -------------------------------------------------------------------------- */

.ht-main { padding-block: 64px; min-height: 50vh; }

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.ht-site-footer {
	background: var(--ht-ink);
	color: var(--ht-footer-text);
	margin-top: 96px;
	padding-top: 72px;
}

/*
 * Flex rather than a fixed 4-column grid: columns hide themselves when they
 * have no data (no product_cat terms, an empty widget area), and a hardcoded
 * grid-template-columns would leave dead tracks behind. Flex redistributes
 * across however many actually render.
 */
.ht-footer__columns {
	display: flex;
	flex-wrap: wrap;
	gap: 48px;
}
.ht-footer__col { flex: 1 1 180px; }
.ht-footer__col--brand { flex: 1.4 1 280px; }

.ht-footer__brandname {
	font-family: var(--ht-font-display);
	font-size: 20px;
	font-weight: 600;
	color: var(--ht-cream-light);
	margin-bottom: 4px;
}
.ht-footer__tagline {
	font-size: 10.5px;
	font-weight: 700;
	letter-spacing: 0.22em;
	color: var(--ht-gold);
	margin-bottom: 18px;
	text-transform: uppercase;
}
.ht-footer__col--brand p {
	margin: 0;
	font-size: 14px;
	line-height: 1.7;
	max-width: 300px;
}

.ht-footer__heading {
	margin: 0 0 16px;
	font-family: var(--ht-font-body);
	font-size: 13px;
	font-weight: 800;
	letter-spacing: 0.14em;
	color: var(--ht-cream-light);
	text-transform: uppercase;
}

.ht-footer__list {
	display: flex;
	flex-direction: column;
	gap: 12px;
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: 14px;
}
.ht-footer__list a { color: var(--ht-footer-text); }
.ht-footer__list a:hover { color: var(--ht-gold); }

/*
 * Widget-driven footer columns. The comps hardcode this content; here it comes
 * from widget areas so the client can edit it in wp-admin, which means the
 * markup is whatever the widget outputs — styled generically rather than by
 * a fixed class per element.
 */
.ht-footer__widgets { font-size: 14px; }
.ht-footer__widgets .widget + .widget { margin-top: 16px; }
.ht-footer__widgets p {
	margin: 0 0 12px;
	line-height: 1.7;
}
.ht-footer__widgets p:last-child { margin-bottom: 0; }
.ht-footer__widgets a { color: var(--ht-footer-text); }
.ht-footer__widgets a:hover { color: var(--ht-gold); }

.ht-footer__contact {
	display: flex;
	flex-direction: column;
	gap: 12px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.ht-footer__social {
	display: flex;
	flex-wrap: wrap;
	gap: 14px;
	margin: 18px 0 0;
	padding: 0;
	list-style: none;
}

.ht-footer__colophon {
	display: flex;
	justify-content: space-between;
	gap: 16px;
	margin-top: 56px;
	padding-block: 28px;
	border-top: 1px solid rgba(253, 249, 242, 0.1);
	font-size: 13px;
}
.ht-footer__colophon a { color: var(--ht-footer-text); text-decoration: underline; text-underline-offset: 3px; }
.ht-footer__colophon a:hover { color: var(--ht-gold); }

/* --------------------------------------------------------------------------
   Entries
   -------------------------------------------------------------------------- */

.ht-entry + .ht-entry { margin-top: 56px; padding-top: 56px; border-top: 1px solid var(--ht-border); }
.ht-entry__title { margin: 0 0 12px; font-size: 34px; }
.ht-entry__meta { font-size: 13px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ht-muted); font-weight: 700; }
.ht-entry__content { color: var(--ht-body); }

/* --------------------------------------------------------------------------
   Below the nav breakpoint
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
	:root { --ht-gutter: 20px; }

	.ht-nav-toggle { display: flex; }

	/*
	 * On phones the nav row is empty (its contents become the drawer), so the
	 * TOP row sticks instead — otherwise the hamburger would scroll away and
	 * leave no way to reach the menu.
	 */
	.ht-site-header {
		position: sticky;
		top: 0;
		z-index: 50;
	}

	/*
	 * The drawer is position:fixed, so it leaves the flow entirely. Removing the
	 * bar's background, border and padding lets row 2 collapse to zero height
	 * rather than leaving an empty strip under the logo.
	 */
	.ht-header-nav {
		position: static;
		background: none;
		border-bottom: 0;
	}
	.ht-header-nav > .ht-container {
		padding-inline: 0;
	}

	/*
	 * No pinned logo or cart on mobile — the top row sticks there and already
	 * carries both.
	 */
	.ht-nav-brand,
	.ht-nav-cart { display: none; }

	.ht-brand .ht-brand__logo-img { height: 38px; }

	.ht-header__account,
	.ht-search__input { display: none; }

	/*
	 * The header's own results panel only — never searchform.php's plain
	 * instance (e.g. the 404 page's), whose input is never display:none at
	 * this width and whose panel already works here on its own (it has its
	 * own max-width clamp — see .ht-search__panel above). Scoped to
	 * .ht-header__actions rather than bare .ht-search__panel so it stops
	 * applying the instant the header's <form class="ht-search"> is
	 * relocated into the mobile search sheet (assets/js/search-sheet.js) —
	 * different ancestor, this rule no longer matches, no !important tug of
	 * war needed against the sheet's own display:block below.
	 */
	.ht-header__actions .ht-search__panel { display: none; }

	.ht-search:hover,
	.ht-search:focus-within { border-color: transparent; }

	/*
	 * Below this width search, cart and menu are the only actions left in the
	 * header (account is hidden above, search never expands past its icon —
	 * see .ht-search__input just above), so each is worth a full 44px tap
	 * target rather than the 42px it shares with its desktop, mouse-driven
	 * sizing.
	 */
	.ht-search { height: 44px; }
	.ht-search__submit,
	.ht-header__actions .ht-cart,
	.ht-nav-toggle { width: 44px; height: 44px; }

	/* Off-canvas drawer */
	.ht-nav {
		position: fixed;
		top: 0;
		right: 0;
		bottom: 0;
		z-index: 70;
		width: min(320px, 84vw);
		padding: 88px 28px 28px;
		background: var(--ht-cream);
		border-left: 1px solid var(--ht-border);
		transform: translateX(100%);
		transition: transform 0.28s ease;
		overflow-y: auto;
	}
	.ht-nav-open .ht-nav { transform: translateX(0); }

	/*
	 * The drawer sits on cream regardless of the bar's pinned state, so these
	 * must out-specify the .is-stuck rules above.
	 */
	.ht-header-nav .ht-nav__list a,
	.ht-header-nav.is-stuck .ht-nav__list a { color: var(--ht-ink); }
	.ht-header-nav .ht-nav__list a:hover,
	.ht-header-nav .ht-nav__list .current-menu-item > a,
	.ht-header-nav .ht-nav__list .menu-item-has-children.is-open > a,
	.ht-header-nav.is-stuck .ht-nav__list a:hover,
	.ht-header-nav.is-stuck .ht-nav__list .current-menu-item > a,
	.ht-header-nav.is-stuck .ht-nav__list .menu-item-has-children.is-open > a { color: var(--ht-crimson); }

	.ht-header-nav .ht-nav__list .ht-nav__more,
	.ht-header-nav.is-stuck .ht-nav__list .ht-nav__more { color: var(--ht-ink); }
	.ht-header-nav .ht-nav__list .menu-item-has-children.is-open > .ht-nav__more,
	.ht-header-nav.is-stuck .ht-nav__list .menu-item-has-children.is-open > .ht-nav__more { color: var(--ht-crimson); }

	/* No hover on a touch screen; only the button's own state should flip it. */
	.ht-nav__list .menu-item-has-children:hover > .ht-nav__more .ht-nav__chev,
	.ht-nav__list .menu-item-has-children:focus-within > .ht-nav__more .ht-nav__chev {
		transform: translateY(-2px) rotate(45deg);
	}
	.ht-nav__list .menu-item-has-children.is-open > .ht-nav__more .ht-nav__chev {
		transform: translateY(1px) rotate(225deg);
	}

	.ht-nav__list {
		flex-direction: column;
		align-items: flex-start;
		justify-content: flex-start;
		gap: 22px;
		padding-block: 0;
		font-size: 17px;
	}

	/*
	 * In the drawer there is no hover and no room to float a panel, so the
	 * children become an indented list the disclosure button opens. The
	 * hover and focus-within rules are undone or a stray focus would spring
	 * it open while someone is tabbing past.
	 */
	.ht-nav__list .menu-item-has-children { width: 100%; }

	.ht-nav__list .sub-menu,
	.ht-nav__list .menu-item-has-children:hover > .sub-menu,
	.ht-nav__list .menu-item-has-children:focus-within > .sub-menu {
		display: none;
		position: static;
		transform: none;
		opacity: 1;
		visibility: visible;
		columns: 1;
		min-width: 0;
		max-width: none;
		padding: 6px 0 0 14px;
		border: 0;
		border-radius: 0;
		background: none;
		box-shadow: none;
		font-size: 15px;
	}
	/*
	 * Four classes, matching the desktop show-rule exactly. The reset above is
	 * only two, so the desktop rule's translateX(-50%) was still winning and
	 * dragging the open panel outside the drawer.
	 */
	.ht-nav__list .menu-item-has-children.is-open > .sub-menu {
		display: block;
		transform: none;
		opacity: 1;
		visibility: visible;
	}

	.ht-nav__list .sub-menu::before { content: none; }

	.ht-header-nav .ht-nav__list .sub-menu a,
	.ht-header-nav.is-stuck .ht-nav__list .sub-menu a {
		padding: 8px 0;
		white-space: normal;
	}
	.ht-header-nav .ht-nav__list .sub-menu a:hover,
	.ht-header-nav.is-stuck .ht-nav__list .sub-menu a:hover {
		background: none;
	}

	/* A comfortable tap target beside the parent link. */
	.ht-nav__more {
		width: 40px;
		height: 40px;
		margin-left: 2px;
	}

	.ht-nav-open .ht-nav-toggle__bar:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
	.ht-nav-open .ht-nav-toggle__bar:nth-child(2) { opacity: 0; }
	.ht-nav-open .ht-nav-toggle__bar:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

	.ht-nav-open { overflow: hidden; }

	.ht-main { padding-block: 40px; }

	.ht-footer__columns { gap: 36px; }
	.ht-footer__col,
	.ht-footer__col--brand { flex: 1 1 40%; }
	.ht-footer__colophon { flex-direction: column; gap: 8px; }
}

@media (max-width: 560px) {
	.ht-footer__col,
	.ht-footer__col--brand { flex: 1 1 100%; }
	.ht-brand__name { font-size: 18px; }

	/*
	 * At this width the tagline was wrapping onto two lines of its own under
	 * an already-wrapped two-line wordmark — four lines of type squeezed
	 * beside the search/cart/menu buttons. It is set in small caps purely as
	 * decoration under the logo; the site name it qualifies stays, so nothing
	 * essential is lost by dropping it once there is no room to set it on one
	 * line.
	 */
	.ht-brand__tagline { display: none; }

	/* Three 44px targets at 20px apart start to crowd the wordmark on the
	   narrowest phones; the targets themselves stay full-size (set at the
	   900px breakpoint above), only the air between them tightens. */
	.ht-header__actions { gap: 14px; }
}

@media (prefers-reduced-motion: reduce) {
	.ht-nav,
	.ht-search__input,
	.ht-nav-toggle__bar,
	.ht-cart { transition: none; }
}

/* ==========================================================================
   Cart drawer — .ht-cartdrawer only. .ht-cart/.ht-cart__count already belong
   to the header bubble site-wide, and .ht-cartpage to the /cart/ page;
   neither is touched here.
   ========================================================================== */

.ht-cartdrawer-scrim {
	position: fixed;
	inset: 0;
	z-index: 80;
	background: rgba(20, 12, 6, 0.45);
}
.ht-cartdrawer-scrim[hidden] { display: none; }

.ht-cartdrawer__panel {
	position: fixed;
	top: 0;
	right: 0;
	bottom: 0;
	z-index: 90;
	display: flex;
	flex-direction: column;
	width: min(400px, 92vw);
	background: var(--ht-surface);
	border-left: 1px solid var(--ht-border);
	box-shadow: -12px 0 32px rgba(36, 30, 23, 0.14);
	transform: translateX(100%);
	transition: transform 0.28s ease;
}
.ht-cartdrawer__panel[hidden] { display: none; }
.ht-cartdrawer.is-open .ht-cartdrawer__panel { transform: translateX(0); }

.ht-cartdrawer__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 20px 24px;
	border-bottom: 1px solid var(--ht-border);
}
.ht-cartdrawer__title {
	font-family: var(--ht-font-display);
	font-size: 18px;
	font-weight: 600;
	color: var(--ht-ink);
}
.ht-cartdrawer__close {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	border: 1px solid var(--ht-border);
	border-radius: 99px;
	background: none;
	color: var(--ht-ink);
	cursor: pointer;
}
.ht-cartdrawer__close:hover { border-color: var(--ht-ink); }

.ht-cartdrawer__body {
	display: flex;
	flex: 1;
	flex-direction: column;
	min-height: 0;
	padding: 20px 24px 24px;
	overflow-y: auto;
}
/* cart-drawer.js toggles this while a stepper/Remove request is in flight —
   same pattern as .ht-cartpage.is-busy above: a visual hold, not the actual
   guard (that is the `mutating` flag in cart-drawer.js; opacity alone can't
   stop Enter/Space on a focused control from firing a second click). */
.ht-cartdrawer__body.is-busy { opacity: 0.6; pointer-events: none; }

.ht-cartdrawer__items {
	display: flex;
	flex-direction: column;
	margin: 0 0 20px;
	padding: 0;
	list-style: none;
}

/* A thin rule between lines, not after the last one: padding carries the
   spacing (:first-child drops the top half so the list still starts flush
   with the panel padding), the `+` sibling combinator is what keeps the
   divider from ever trailing the final item. */
.ht-cartdrawer__item {
	display: grid;
	grid-template-columns: 56px 1fr auto;
	gap: 12px;
	align-items: flex-start;
	padding-block: 16px;
}
.ht-cartdrawer__item:first-child { padding-top: 0; }
.ht-cartdrawer__item + .ht-cartdrawer__item { border-top: 1px solid var(--ht-border); }

.ht-cartdrawer__media { display: block; }
.ht-cartdrawer__img {
	display: block;
	width: 56px;
	height: 56px;
	border-radius: var(--ht-radius);
	background: var(--ht-canvas);
	object-fit: cover;
}

.ht-cartdrawer__itembody {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}
.ht-cartdrawer__name {
	overflow: hidden;
	color: var(--ht-ink);
	font-size: 14px;
	font-weight: 600;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.ht-cartdrawer__size {
	color: var(--ht-muted);
	font-size: 12.5px;
}

/* Stepper and Remove share one row, sized to their content rather than
   stretched: .ht-qty (woocommerce/cart/cart.php's own stepper, reused as-is)
   has no width of its own, so as a flex item in a column-flex parent
   (.ht-cartdrawer__itembody, align-items: stretch by default) it used to
   fill the parent's full width — the owner's screenshot. A row flex
   container doesn't stretch its children along the row axis, so both the
   compact stepper and the icon size to content and sit side by side. */
.ht-cartdrawer__linetools {
	display: flex;
	align-items: center;
	gap: 4px;
	margin-top: 8px;
}

/* Icon-only Remove, drawer only — the cart page keeps its text link
   (.ht-linkbtn). 44x44 tap target around a 16px glyph: the box is what
   needs to be reachable on a phone, not the glyph, sitting right next to a
   quantity stepper where a cramped hit area means mis-taps — a compact
   stepper must not be allowed to shrink that target. Red (--ht-crimson) by
   default, matching the owner's request, rather than only on hover. */
.ht-cartdrawer__remove {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: 99px;
	color: var(--ht-crimson);
}
.ht-cartdrawer__remove:hover { color: var(--ht-crimson-dark); }
.ht-cartdrawer__remove:focus-visible {
	color: var(--ht-crimson-dark);
	outline: 2px solid var(--ht-crimson);
	outline-offset: 2px;
}

.ht-cartdrawer__price {
	color: var(--ht-ink);
	font-size: 14px;
	font-weight: 700;
	white-space: nowrap;
}

.ht-cartdrawer__subtotal {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-top: auto;
	padding-top: 16px;
	border-top: 1px solid var(--ht-border);
	color: var(--ht-ink);
	font-size: 15px;
	font-weight: 700;
}

.ht-cartdrawer__actions {
	display: flex;
	flex-direction: column;
	gap: 10px;
	margin-top: 16px;
}
.ht-cartdrawer__actions .ht-btn { text-align: center; }

.ht-cartdrawer__empty {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 14px;
	margin: auto 0;
	padding-block: 40px;
}
.ht-cartdrawer__emptytext {
	margin: 0;
	color: var(--ht-muted);
	font-size: 15px;
}

/* The drawer traps focus and sits over a scrim, so scrolling the page behind
   it while open would just be confusing. */
body.ht-cartdrawer-open { overflow: hidden; }

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

/* ==========================================================================
   Mobile search sheet — assets/js/search-sheet.js relocates the header's own
   <form class="ht-search"> here on open (see ht_searchsheet_render(),
   inc/search.php, for why it is printed inside .ht-site-header rather than
   in wp_footer like the cart drawer). Everything here only ever needs to
   exist below the 900px breakpoint: above it the trigger never opens the
   sheet in the first place.
   ========================================================================== */

@media (max-width: 900px) {
	/*
	 * top: 100% against .ht-site-header's OWN box (position: sticky at this
	 * width, see the breakpoint above — a valid containing block for an
	 * absolutely positioned descendant same as position: relative/fixed
	 * would be) — "right where the header's rendered bottom edge is",
	 * whatever that height actually turns out to be, with no JS
	 * measurement and no inline style ever written to express it.
	 */
	.ht-searchsheet-scrim {
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		z-index: 1;
		/*
		 * Body scroll is locked (body.ht-searchsheet-open below) whenever
		 * this is visible, so 100vh reaching slightly past the real
		 * viewport bottom on a short/unscrolled page never becomes visible,
		 * scrollable, or a source of its own horizontal/vertical overflow —
		 * an absolutely positioned box never enlarges its own parent.
		 */
		height: 100vh;
		background: rgba(20, 12, 6, 0.45);
	}
	.ht-searchsheet-scrim[hidden] { display: none; }

	.ht-searchsheet__panel {
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		z-index: 2;
		padding: 16px var(--ht-gutter) 22px;
		background: var(--ht-cream-light);
		border-bottom: 1px solid var(--ht-border);
		box-shadow: 0 18px 42px rgba(20, 12, 6, 0.16);
		opacity: 0;
		transform: translateY(-14px);
		transition: opacity 0.22s ease, transform 0.22s ease;
	}
	.ht-searchsheet__panel[hidden] { display: none; }
	.ht-searchsheet.is-open .ht-searchsheet__panel {
		opacity: 1;
		transform: none;
	}

	.ht-searchsheet__head {
		display: flex;
		align-items: center;
		justify-content: space-between;
		margin-bottom: 14px;
	}
	.ht-searchsheet__title {
		font-family: var(--ht-font-display);
		font-size: 16px;
		font-weight: 600;
		color: var(--ht-ink);
	}
	.ht-searchsheet__close {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 36px;
		height: 36px;
		border: 1px solid var(--ht-border);
		border-radius: 99px;
		background: none;
		color: var(--ht-ink);
		cursor: pointer;
	}
	.ht-searchsheet__close:hover { border-color: var(--ht-ink); }

	/*
	 * The relocated form's own layout, once it is inside the sheet: the
	 * 170px absolute pill makes no sense at full width, so this reverts
	 * .ht-search__input to a normal, full-width, always-visible field with
	 * the submit icon overlaid on top of it rather than beside it —
	 * .ht-search is already position: relative (see above), so that overlay
	 * needs nothing extra here to anchor against.
	 */
	/*
	 * flex-direction: column, not the desktop row: .ht-search__panel is now
	 * a normal in-flow sibling of .ht-search__input (position: static both,
	 * below), and the base .ht-search is display:flex with no direction of
	 * its own set (row, the flexbox default) — left as a row, the panel
	 * shared the SAME horizontal line as the input instead of sitting below
	 * it, and both fought over width via flex-shrink, crushing the panel to
	 * a sliver and wrapping every result's price/size text down to one
	 * character per line. Column stacks them; align-items: stretch (also
	 * the flexbox default, named here so this reads as deliberate) is what
	 * then gives each its own full-width row.
	 */
	.ht-searchsheet .ht-search {
		height: auto;
		border: none;
		flex-direction: column;
		align-items: stretch;
	}
	.ht-searchsheet .ht-search__input {
		display: block;
		position: static;
		width: 100%;
		height: 48px;
		opacity: 1;
		transform: none;
		pointer-events: auto;
		padding: 0 48px 0 18px;
		border: 1.5px solid var(--ht-line);
		border-radius: 99px;
	}
	/*
	 * .ht-search:focus-within .ht-search__input { border-color: var(--ht-ink); }
	 * (declared with the desktop pill above) already reaches this field too
	 * — it is not scoped away from .ht-searchsheet, and needs no separate
	 * copy here.
	 */

	/*
	 * An overlay icon now, not a pill half — the desktop rules that give it
	 * a matching border/background on hover/focus-within (also declared
	 * above, also not scoped away from .ht-searchsheet, since they key off
	 * :has(.ht-search__input) which is still true here) are explicitly
	 * cancelled for this context at equal specificity + later source order,
	 * rather than relying on their absence.
	 */
	.ht-searchsheet .ht-search__submit,
	.ht-searchsheet .ht-search:hover .ht-search__submit,
	.ht-searchsheet .ht-search:focus-within .ht-search__submit {
		position: absolute;
		top: 50%;
		right: 4px;
		transform: translateY(-50%);
		width: 40px;
		height: 40px;
		border: none;
		border-radius: 99px;
		background: none;
	}
	.ht-searchsheet .ht-search__panel {
		display: block;
		position: static;
		width: 100%;
		max-width: none;
		margin-top: 14px;
		border: none;
		box-shadow: none;
		background: none;
	}
	.ht-searchsheet .ht-search__panel[hidden] { display: none; }
}

/* The sheet traps focus and sits over a scrim, exactly like the cart drawer
   — scrolling the page behind it while open would just be confusing. */
body.ht-searchsheet-open { overflow: hidden; }

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

/* ==========================================================================
   Fly to cart — a decorative clone animated entirely through the Web
   Animations API (assets/js/fly-to-cart.js). This class supplies only the
   non-animated baseline: fixed positioning so it never affects layout, and
   no hit area. Every position/size value it takes on is set by
   element.animate(), never by this stylesheet or by JS touching .style.
   ========================================================================== */

.ht-flycart-ghost {
	position: fixed;
	top: 0;
	left: 0;
	z-index: 999;
	background: var(--ht-canvas);
	object-fit: cover;
	pointer-events: none;
}

/* ==========================================================================
   Buttons — shared across homepage sections
   ========================================================================== */

.ht-btn {
	display: inline-block;
	padding: 15px 32px;
	border-radius: 99px;
	font-size: 15px;
	font-weight: 700;
	line-height: 1;
	transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.ht-btn--primary {
	background: var(--ht-crimson);
	color: var(--ht-cream-light);
}
.ht-btn--primary:hover {
	background: var(--ht-crimson-dark);
	color: var(--ht-cream-light);
}

.ht-btn--ghost {
	border: 1.5px solid rgba(253, 249, 242, 0.7);
	background: rgba(24, 14, 8, 0.25);
	color: var(--ht-cream-light);
}
.ht-btn--ghost:hover {
	border-color: var(--ht-cream-light);
	background: rgba(24, 14, 8, 0.5);
	color: var(--ht-cream-light);
}

/* ==========================================================================
   Homepage hero
   ========================================================================== */

/*
 * On the homepage every section supplies its own vertical rhythm, and both the
 * first (hero) and last (newsletter) are full-bleed bands. So the wrapper adds
 * no padding of its own, and the footer drops its top margin — otherwise
 * .ht-main's 64px bottom padding plus the footer's 96px margin left a 160px
 * band of empty cream between the crimson newsletter and the dark footer.
 * Both stay in place on ordinary pages, where content does need the breathing room.
 */
.home .ht-main { padding-block: 0; }
.home .ht-site-footer { margin-top: 0; }

/*
 * Catalog pages open with a full-bleed dark header and close with the
 * full-bleed Commission band — same shape as the homepage, so the wrapper
 * contributes no padding and the footer drops its top margin. Otherwise the
 * 64px + 96px stack leaves a 160px strip of cream before the footer.
 */
.woocommerce-shop .ht-main,
.tax-product_cat .ht-main,
.tax-product_tag .ht-main { padding-block: 0; }

.woocommerce-shop .ht-site-footer,
.tax-product_cat .ht-site-footer,
.tax-product_tag .ht-site-footer { margin-top: 0; }

/*
 * The cart and checkout pages open with the same full-bleed dark hero as the
 * shop archive (ht_cart_hero() / ht_checkout_hero(), both .ht-shophead--cart),
 * so the wrapper's top padding has to drop out here too or the same 64px
 * band of cream reappears between the crimson bar and the hero. Unlike the
 * shop archive, neither page *closes* on a full-bleed band — the cart ends on
 * the ordinary cross-sell grid and checkout on the payment card, the same
 * shape as a single product page ending on its related-products strip — so
 * the bottom padding (and the footer's top margin) stay put; that 160px is
 * the normal breathing room every other content page ends on, not a bug.
 *
 * :not(.woocommerce-order-received) matters here: is_checkout() — and so
 * wc_body_class()'s "woocommerce-checkout" — is also true on the thank-you
 * page, since WooCommerce endpoints are query vars on the same page rather
 * than separate posts. Woo adds "woocommerce-order-received" as an extra
 * class on exactly that page, so it is what excludes it here.
 *
 * The exclusion is still correct, but it no longer means the thank-you page
 * keeps the wrapper's padding — it means that page is not shaped like the
 * checkout and takes its own rule below instead.
 *
 * Both selectors are live today. wc_body_class() (wc-template-functions.php)
 * branches is_woocommerce() / elseif is_checkout() / elseif is_cart() — the
 * cart page's content is [woocommerce_cart] alone (bin/configure-shop.php),
 * so is_checkout() is false there and the elseif is_cart() branch adds
 * "woocommerce-cart"; /checkout/ gets "woocommerce-checkout" the same way.
 * (An earlier task briefly composed [woocommerce_checkout] onto the cart
 * page too, which made is_checkout() match first there and left
 * .woocommerce-cart matching nothing in practice — kept anyway, as cheap
 * insurance against exactly the situation now current again.)
 */
.woocommerce-cart .ht-main,
.woocommerce-checkout:not(.woocommerce-order-received) .ht-main { padding-top: 0; }

/*
 * The order-received page is the third shape: it opens AND closes on a
 * full-bleed band — ht_confirmation_hero()'s dark header above, the
 * "while you wait" invite below, both hooked either side of the shortcode
 * from inc/confirmation.php. So it takes the shop archive's treatment rather
 * than the checkout's: no wrapper padding at either end, and no footer top
 * margin.
 *
 * Before the confirmation rebuild this page opened on a boxed head
 * (.ht-confirmhead) that did want the 64px, which is why the rule above
 * excludes it. Now that head is gone, keeping the padding left a 64px strip
 * of cream between the crimson nav and the dark hero, and 64px + the
 * footer's own 96px left a 160px strip between the invite band and the
 * footer — the exact stack the homepage and the catalog pages already
 * document above.
 */
.woocommerce-order-received .ht-main { padding-block: 0; }
.woocommerce-order-received .ht-site-footer { margin-top: 0; }

.ht-hero {
	position: relative;
	min-height: 600px;
	display: flex;
	align-items: center;
	overflow: hidden;
}

/*
 * minmax(0, 1fr), not 1fr. Plain 1fr means minmax(auto, 1fr), and that auto
 * floor is the track's min-content size — for an 800x800 image that is the
 * column width, which is taller than an even split, so the rows refused to
 * shrink and the collage overflowed the hero. Zeroing the minimum lets the
 * tracks divide the container exactly.
 */
.ht-hero__collage {
	position: absolute;
	inset: 0;
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	grid-template-rows: minmax(0, 1fr);
}

/* Editors may pick fewer than four; the grid follows rather than leaving holes. */
.ht-hero__collage--1 { grid-template-columns: minmax(0, 1fr); }
.ht-hero__collage--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ht-hero__collage--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.ht-hero__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/*
 * Left-weighted scrim: heaviest behind the text, lifting towards the right so
 * the artwork stays visible. Sized in one gradient rather than an overlay per
 * panel so it reads continuously across the collage seams.
 */
.ht-hero__scrim {
	position: absolute;
	inset: 0;
	background: linear-gradient(
		90deg,
		rgba(20, 12, 6, 0.88) 0%,
		rgba(20, 12, 6, 0.72) 45%,
		rgba(20, 12, 6, 0.35) 100%
	);
}

.ht-hero__inner {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 22px;
	padding-block: 64px;
	width: 100%;
}

.ht-hero__eyebrow {
	margin: 0;
	color: var(--ht-gold);
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.28em;
	text-transform: uppercase;
}

.ht-hero__title {
	margin: 0;
	max-width: 640px;
	font-size: clamp(2rem, 4.4vw, 3.625rem);
	line-height: 1.08;
	color: var(--ht-cream-light);
	text-shadow: 0 2px 18px rgba(20, 12, 6, 0.6);
}

.ht-hero__lede {
	margin: 0;
	max-width: 520px;
	font-size: 18px;
	line-height: 1.6;
	color: var(--ht-cream-light);
	text-shadow: 0 1px 12px rgba(20, 12, 6, 0.6);
}

.ht-hero__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 14px;
	margin: 8px 0 0;
}

.ht-hero--empty {
	min-height: 0;
	padding-block: 24px;
	background: var(--ht-cream-warm);
	border-bottom: 1px solid var(--ht-border);
}
.ht-hero--empty p { margin: 0; color: var(--ht-muted); }

@media (max-width: 900px) {
	.ht-hero { min-height: 460px; }

	/* Four panels at phone width would be slivers; 2x2 keeps each readable. */
	/*
	 * Every variant sets BOTH axes. The markup always carries the bare
	 * .ht-hero__collage class alongside its --n modifier, so a rule that only
	 * overrides rows leaves the bare rule's 2 columns in place — which left a
	 * dead column for a single image. Same failure the footer grid had.
	 */
	.ht-hero__collage,
	.ht-hero__collage--3,
	.ht-hero__collage--4 {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		grid-template-rows: repeat(2, minmax(0, 1fr));
	}

	/*
	 * These MUST follow the bare rule above. .ht-hero__collage--1 and
	 * .ht-hero__collage are both single-class selectors, so they carry equal
	 * specificity and source order decides the winner.
	 */
	.ht-hero__collage--1 {
		grid-template-columns: minmax(0, 1fr);
		grid-template-rows: minmax(0, 1fr);
	}
	.ht-hero__collage--2 {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		grid-template-rows: minmax(0, 1fr);
	}

	/* Three images in a 2x2 would leave the last cell empty; the first spans. */
	.ht-hero__collage--3 .ht-hero__img:first-child {
		grid-column: span 2;
	}

	.ht-hero__scrim {
		background: linear-gradient(
			180deg,
			rgba(20, 12, 6, 0.72) 0%,
			rgba(20, 12, 6, 0.86) 60%,
			rgba(20, 12, 6, 0.92) 100%
		);
	}

	.ht-hero__inner { padding-block: 48px; gap: 18px; }
	.ht-hero__lede { font-size: 16px; }
	.ht-btn { padding: 13px 26px; font-size: 14px; }
}

/* ==========================================================================
   Trust strip
   ========================================================================== */

.ht-trust {
	background: var(--ht-cream-warm);
	border-bottom: 1px solid var(--ht-border);
}

/*
 * auto-fit, not a fixed repeat(4): trust points are editable content, so there
 * may be three or five. Fixed tracks would leave a dead column — the same
 * failure the footer and hero collage both had.
 */
.ht-trust__inner {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
	gap: 24px;
	padding-block: 22px;
	text-align: center;
}

.ht-trust__item { display: flex; flex-direction: column; gap: 3px; }
.ht-trust__title { font-size: 14px; font-weight: 800; color: var(--ht-ink); }
.ht-trust__sub { font-size: 12.5px; color: var(--ht-muted); }

/* ==========================================================================
   Editorial section (image + copy)
   ========================================================================== */

.ht-section__inner {
	display: grid;
	grid-template-columns: 1fr 1.1fr;
	gap: 72px;
	align-items: center;
	padding-block: 96px;
}

/*
 * Source order is media-then-body. For the image-right variant the columns are
 * swapped with grid-column rather than reordering the markup, so the heading
 * still precedes its image for screen readers and keyboard order.
 */
.ht-section--image-right .ht-section__media { grid-column: 2; grid-row: 1; }
.ht-section--image-right .ht-section__body  { grid-column: 1; grid-row: 1; }
.ht-section--image-right .ht-section__inner { grid-template-columns: 1.1fr 1fr; }

/*
 * A grid, not a single image slot: one picture renders as the tall portrait the
 * comp uses, two to four tile. minmax(0,1fr) throughout for the same reason as
 * the hero collage — plain 1fr floors at the image's min-content size.
 */
.ht-section__media {
	position: relative;
	display: grid;
	gap: 16px;
	grid-template-columns: minmax(0, 1fr);
}

.ht-section--images-2 .ht-section__media,
.ht-section--images-3 .ht-section__media,
.ht-section--images-4 .ht-section__media {
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

.ht-section__img {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 5;
	object-fit: cover;
	border-radius: var(--ht-radius);
}

/* Tiled pictures read better square than as stretched portraits. */
.ht-section--images-2 .ht-section__img,
.ht-section--images-3 .ht-section__img,
.ht-section--images-4 .ht-section__img {
	aspect-ratio: 1 / 1;
}

/* An odd one out spans the row rather than leaving a gap. */
.ht-section--images-3 .ht-section__img:first-child { grid-column: span 2; }

.ht-section__badge {
	position: absolute;
	left: -18px;
	bottom: -18px;
	margin: 0;
	padding: 16px 22px;
	border-radius: var(--ht-radius);
	background: var(--ht-crimson);
	color: var(--ht-cream-rose);
	font-family: var(--ht-font-display);
	font-size: 15px;
	line-height: 1.4;
	max-width: 60%;
}

.ht-section__eyebrow {
	margin: 0 0 14px;
	color: var(--ht-crimson);
	font-size: 13px;
	font-weight: 800;
	letter-spacing: 0.24em;
	text-transform: uppercase;
}

.ht-section__title {
	margin: 0 0 22px;
	font-size: clamp(1.75rem, 3vw, 2.5rem);
	line-height: 1.15;
}

.ht-section__text { color: var(--ht-body); }
.ht-section__text p { margin: 0 0 16px; font-size: 16.5px; line-height: 1.75; }
.ht-section__text p:last-child { margin-bottom: 0; }

.ht-section__cta { margin: 28px 0 0; }

.ht-textlink {
	font-size: 15px;
	font-weight: 800;
	border-bottom: 2px solid var(--ht-crimson);
	padding-bottom: 3px;
}

.ht-section--empty { background: var(--ht-cream-warm); border-block: 1px solid var(--ht-border); }
.ht-section--empty p { margin: 0; padding-block: 24px; color: var(--ht-muted); }

@media (max-width: 900px) {
	.ht-section__inner,
	.ht-section--image-right .ht-section__inner {
		grid-template-columns: minmax(0, 1fr);
		gap: 40px;
		padding-block: 56px;
	}

	/*
	 * Stacked, the swap must be undone or the image would jump below the copy
	 * on one variant and above it on the other.
	 */
	.ht-section--image-right .ht-section__media,
	.ht-section--image-right .ht-section__body {
		grid-column: 1;
		grid-row: auto;
	}

	.ht-section__badge { left: 0; bottom: -14px; font-size: 14px; padding: 13px 18px; }
	.ht-section__text p { font-size: 16px; }
}

/* --------------------------------------------------------------------------
   Section variants
   -------------------------------------------------------------------------- */

/* Panel — warm background, hairlines top and bottom. */
.ht-section--panel {
	background: var(--ht-cream-warm);
	border-block: 1px solid var(--ht-border);
}
.ht-section--panel .ht-section__inner { grid-template-columns: 1.1fr 1fr; }

/*
 * Card — a dark rounded block inset from the page rather than a full-bleed
 * band, so the section reads as a self-contained offer.
 */
.ht-section--card .ht-section__inner {
	display: block;
	padding-block: 96px 0;
}

.ht-section--card .ht-section__card {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	align-items: stretch;
	background: var(--ht-ink);
	border-radius: 6px;
	overflow: hidden;
}

/*
 * The body is a stretched grid item, so without this its content stacks from
 * the top while the image fills the full card height. Centring the column
 * optically balances the copy against the artwork beside it.
 */
.ht-section--card .ht-section__body {
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: flex-start;
	padding: 64px 56px;
	color: var(--ht-cream-light);
}
.ht-section--card .ht-section__eyebrow { color: var(--ht-gold); }
.ht-section--card .ht-section__title { color: var(--ht-cream-light); }
.ht-section--card .ht-section__text { color: rgba(253, 249, 242, 0.8); }
.ht-section--card .ht-section__text p { font-size: 15.5px; }

/*
 * The image half carries the same ink ground as the copy half, so the two read
 * as one card. The artwork is a trimmed portrait on a near-square panel, so it
 * is CONTAINed rather than cropped — covering would slice a third off the top
 * and bottom of the painting, and these are devotional images where the full
 * composition matters.
 */
.ht-section--card .ht-section__media {
	gap: 0;
	background: var(--ht-ink);
	padding: 32px;
	display: flex;
	align-items: center;
	justify-content: center;
}

.ht-section--card .ht-section__img {
	width: 100%;
	height: 100%;
	max-height: 100%;
	min-height: 380px;
	aspect-ratio: auto;
	object-fit: contain;
	border-radius: 0;
}

/*
 * The card lays out on .ht-section__card, not .ht-section__inner, so the
 * image-side swap needs its own rules rather than inheriting the ones above.
 */
.ht-section--card.ht-section--image-right .ht-section__media { grid-column: 2; grid-row: 1; }
.ht-section--card.ht-section--image-right .ht-section__body  { grid-column: 1; grid-row: 1; }

/* Outline button for light backgrounds; --ghost already covers dark ones. */
.ht-btn--outline {
	border: 1.5px solid var(--ht-ink);
	color: var(--ht-ink);
}
.ht-btn--outline:hover {
	background: var(--ht-ink);
	color: var(--ht-cream-light);
}

.ht-section__cta--buttons {
	display: flex;
	flex-wrap: wrap;
	gap: 14px;
}

@media (max-width: 900px) {
	.ht-section--panel .ht-section__inner { grid-template-columns: minmax(0, 1fr); }

	.ht-section--card .ht-section__inner { padding-block: 56px 0; }
	.ht-section--card .ht-section__card { grid-template-columns: minmax(0, 1fr); }
	.ht-section--card.ht-section--image-right .ht-section__media,
	.ht-section--card.ht-section--image-right .ht-section__body {
		grid-column: 1;
		grid-row: auto;
	}
	.ht-section--card .ht-section__body { padding: 40px 28px; }
	.ht-section--card .ht-section__media { padding: 24px; }
	.ht-section--card .ht-section__img { min-height: 260px; }
}

/* ==========================================================================
   Gallery strip
   ========================================================================== */

/*
 * The strip owns its top spacing rather than borrowing the previous
 * section's. It used to be `0 96px`, tuned to sit under the Journal — but
 * every section on this page renders nothing until its content exists, so
 * relying on a neighbour meant that on a site with no journal posts and no
 * reviews the strip butted straight against the Consecration block.
 *
 * The two sections that DO supply their own bottom space zero it again, so
 * nothing is spaced twice when they are present.
 */
.ht-section--strip { padding-block: 96px; }
.ht-journal + .ht-section--strip,
.ht-reviews + .ht-section--strip { padding-top: 0; }

/* Same reasoning: the Journal follows Reviews, which may equally be absent. */
.ht-reviews + .ht-journal { padding-top: 0; }

.ht-strip__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 24px;
	padding-bottom: 36px;
}

.ht-strip__title {
	margin: 0;
	font-size: clamp(1.5rem, 2.4vw, 1.875rem);
}

.ht-strip__link { font-size: 15px; font-weight: 700; white-space: nowrap; }

/*
 * auto-fit with a floor, not repeat(6): the picker allows six to eight images,
 * and a fixed six-column track would leave dead cells at seven. minmax(0,…)
 * for the usual min-content reason.
 */
.ht-strip__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr));
	gap: 4px;
}

.ht-strip__cell {
	display: block;
	aspect-ratio: 1 / 1;
	overflow: hidden;
}

.ht-strip__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.4s ease;
}
.ht-strip__cell:hover .ht-strip__img { transform: scale(1.06); }

/* ==========================================================================
   Newsletter
   ========================================================================== */

.ht-newsletter {
	background: var(--ht-crimson);
	color: var(--ht-cream-light);
}

.ht-newsletter__inner {
	max-width: 760px;
	margin-inline: auto;
	padding: 76px var(--ht-gutter);
	text-align: center;
}

.ht-newsletter__title {
	margin: 0 0 14px;
	font-size: clamp(1.625rem, 3vw, 2.125rem);
	color: var(--ht-cream-light);
}

.ht-newsletter__blurb {
	margin: 0 0 30px;
	font-size: 15.5px;
	line-height: 1.6;
	color: rgba(253, 249, 242, 0.85);
}

.ht-newsletter__form {
	display: flex;
	gap: 12px;
	max-width: 480px;
	margin-inline: auto;
}

.ht-newsletter__input {
	flex: 1;
	min-width: 0;
	border: none;
	border-radius: 99px;
	padding: 15px 22px;
	font-family: var(--ht-font-body);
	font-size: 15px;
	color: var(--ht-ink);
	background: var(--ht-cream-light);
}
.ht-newsletter__input:focus-visible {
	outline: 2px solid var(--ht-gold);
	outline-offset: 2px;
}

.ht-newsletter__submit {
	border: none;
	border-radius: 99px;
	padding: 15px 30px;
	background: var(--ht-ink);
	color: var(--ht-cream-light);
	font-family: var(--ht-font-body);
	font-size: 15px;
	font-weight: 700;
	cursor: pointer;
	transition: background-color 0.2s ease;
}
.ht-newsletter__submit:hover:not(:disabled) { background: #100b06; }
.ht-newsletter__submit:disabled { opacity: 0.6; cursor: default; }

/* Honeypot: off-screen rather than display:none, which some bots detect. */
.ht-newsletter__trap {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* Sits under the field, quieter than the blurb but still legible on crimson. */
.ht-newsletter__consent {
	margin: 16px auto 0;
	max-width: 480px;
	font-size: 12.5px;
	line-height: 1.5;
	color: rgba(253, 249, 242, 0.75);
}
.ht-newsletter__consent a {
	color: var(--ht-cream-light);
	text-decoration: underline;
}
.ht-newsletter__consent a:hover { color: var(--ht-gold); }

.ht-newsletter__message {
	margin: 18px 0 0;
	min-height: 1.4em;
	font-size: 15px;
	font-weight: 700;
	color: var(--ht-cream-light);
}
.ht-newsletter__message.is-error { color: var(--ht-gold); }

@media (max-width: 900px) {
	.ht-section--strip { padding-block: 56px; }
	.ht-journal + .ht-section--strip,
	.ht-reviews + .ht-section--strip { padding-top: 0; }
	.ht-strip__head { padding-bottom: 24px; }
	.ht-newsletter__inner { padding-block: 56px; }
	.ht-newsletter__form { flex-direction: column; }
}

@media (prefers-reduced-motion: reduce) {
	.ht-strip__img { transition: none; }
	.ht-strip__cell:hover .ht-strip__img { transform: none; }
}

/* ==========================================================================
   Shared section header
   ========================================================================== */

.ht-sechead {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 24px;
	margin-bottom: 40px;
}

.ht-sechead__eyebrow {
	margin: 0 0 12px;
	color: var(--ht-crimson);
	font-size: 13px;
	font-weight: 800;
	letter-spacing: 0.24em;
	text-transform: uppercase;
}

.ht-sechead__title {
	margin: 0;
	font-size: clamp(1.75rem, 3vw, 2.375rem);
}

.ht-sechead__link { font-size: 15px; font-weight: 700; white-space: nowrap; }

/* On dark grounds the accent flips to gold for contrast. */
.ht-sechead--dark .ht-sechead__eyebrow,
.ht-sechead--dark .ht-sechead__link { color: var(--ht-gold); }
.ht-sechead--dark .ht-sechead__title { color: var(--ht-cream-light); }

/* ==========================================================================
   Meet the Artists
   ========================================================================== */

.ht-artists { padding-block: 96px 0; }

/*
 * auto-FIT, not auto-fill. Both create as many tracks as fit, but auto-fill
 * keeps the empty ones — with three artists in a four-track row that left a
 * 300px hole on the right. auto-fit collapses empties so the items stretch.
 */
.ht-artists__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
	gap: 26px;
}

.ht-artist { display: flex; flex-direction: column; gap: 14px; }

.ht-artist__media {
	position: relative;
	aspect-ratio: 4 / 5;
	border-radius: var(--ht-radius);
	overflow: hidden;
	background: var(--ht-cream-warm);
}

.ht-artist__img { width: 100%; height: 100%; object-fit: cover; }

.ht-artist__placeholder {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 12.5px;
	letter-spacing: 0.08em;
	color: var(--ht-muted);
	text-transform: uppercase;
}

.ht-artist__meta { display: flex; flex-direction: column; gap: 3px; }

.ht-artist__name {
	margin: 0;
	font-family: var(--ht-font-display);
	font-size: 19px;
	font-weight: 500;
	color: var(--ht-ink);
}

.ht-artist__role {
	margin: 0;
	font-size: 13.5px;
	font-weight: 700;
	color: var(--ht-crimson);
}

.ht-artist__bio { margin-top: 4px; }
.ht-artist__bio p { margin: 0; font-size: 14px; line-height: 1.6; color: var(--ht-muted); }

/* ==========================================================================
   Reviews
   ========================================================================== */

.ht-reviews { padding-block: 96px; }

.ht-reviews__inner {
	display: grid;
	grid-template-columns: 0.9fr 2fr;
	gap: 64px;
	align-items: start;
}

.ht-reviews__title {
	margin: 0 0 18px;
	font-size: clamp(1.75rem, 3vw, 2.375rem);
	line-height: 1.15;
}

.ht-reviews__score {
	display: flex;
	align-items: baseline;
	gap: 10px;
	margin: 0;
	flex-wrap: wrap;
}

.ht-reviews__average {
	font-family: var(--ht-font-display);
	font-size: clamp(2.5rem, 5vw, 3.5rem);
	font-weight: 500;
	color: var(--ht-crimson);
	line-height: 1;
}

.ht-reviews__scorelabel { font-size: 15px; font-weight: 600; color: var(--ht-muted); }

/* auto-fit for the same reason as the artists grid above. */
.ht-reviews__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
	gap: 22px;
}

.ht-review {
	display: flex;
	flex-direction: column;
	gap: 12px;
	margin: 0;
	padding: 26px;
	background: var(--ht-cream-warm);
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
}

.ht-review__stars {
	margin: 0;
	font-size: 15px;
	letter-spacing: 2px;
	color: #e9a93e;
}

.ht-review__quote { margin: 0; }
.ht-review__quote p { margin: 0; font-size: 15px; line-height: 1.7; color: var(--ht-body); }

.ht-review__by { display: flex; flex-direction: column; gap: 2px; margin-top: auto; }
.ht-review__name { font-size: 14px; font-weight: 800; color: var(--ht-ink); }
.ht-review__where { font-size: 12.5px; color: var(--ht-muted); }

@media (max-width: 900px) {
	.ht-sechead { flex-direction: column; align-items: flex-start; gap: 12px; margin-bottom: 28px; }
	.ht-artists { padding-block: 56px 0; }
	.ht-reviews { padding-block: 56px; }
	.ht-reviews__inner { grid-template-columns: minmax(0, 1fr); gap: 36px; }
}

/* ==========================================================================
   Our Collections
   ========================================================================== */

.ht-collections {
	background: var(--ht-ink);
	color: var(--ht-cream-light);
}

.ht-collections__inner { padding-block: 88px; }

.ht-collections__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr));
	gap: 18px;
}

.ht-collection {
	position: relative;
	display: block;
	aspect-ratio: 3 / 4;
	border-radius: var(--ht-radius);
	overflow: hidden;
	background: #322a21;
	color: var(--ht-cream-light);
}

.ht-collection__img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.4s ease;
}
.ht-collection:hover .ht-collection__img { transform: scale(1.05); }

/* Bottom-weighted so the label stays legible over any artwork. */
.ht-collection__scrim {
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(20, 12, 6, 0) 40%, rgba(20, 12, 6, 0.85) 100%);
}

.ht-collection__name {
	position: absolute;
	left: 16px;
	right: 16px;
	bottom: 16px;
	font-family: var(--ht-font-display);
	font-size: 17px;
	font-weight: 500;
	line-height: 1.3;
}
.ht-collection:hover .ht-collection__name { color: var(--ht-gold); }

/* ==========================================================================
   New Arrivals
   ========================================================================== */

.ht-arrivals { padding-block: 96px 80px; }

/*
 * Three fixed tracks rather than auto-fit: at this width auto-fit would give
 * four, and the point is a bigger card, so the count is the thing being
 * chosen here and the breakpoints below step it down.
 */
.ht-arrivals__grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 26px 22px;
}

/*
 * One card, shared by the homepage arrivals grid, the catalog grid and the
 * related-products strip — all three render .ht-product, so the frame lives
 * here rather than being scoped to any one of them.
 *
 * The outer radius is the image's plus the padding, so the two curves stay
 * concentric instead of the frame looking tighter at the corners than the
 * art inside it.
 */
.ht-product {
	display: flex;
	flex-direction: column;
	gap: 12px;
	border: 1px solid var(--ht-border);
	border-radius: calc(var(--ht-radius) + var(--ht-card-pad));
	padding: var(--ht-card-pad);
	background: var(--ht-surface);
	transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.ht-product:hover {
	border-color: var(--ht-line);
	box-shadow: 0 6px 20px rgba(20, 12, 6, 0.07);
}

.ht-product__link {
	display: flex;
	flex-direction: column;
	gap: 3px;
	color: var(--ht-ink);
}

/*
 * The positioning context for both the badge and the add button, so each
 * anchors to a corner of the IMAGE rather than of the whole card.
 */
.ht-product__media {
	position: relative;
	display: block;
	aspect-ratio: 1 / 1;
	border-radius: var(--ht-radius);
	overflow: hidden;
	background: var(--ht-cream-warm);
}

.ht-product__imglink { display: block; width: 100%; height: 100%; }

.ht-product__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.4s ease;
}
.ht-product:hover .ht-product__img { transform: scale(1.04); }

.ht-product__badge {
	position: absolute;
	top: 12px;
	left: 12px;
	background: rgba(253, 249, 242, 0.95);
	color: var(--ht-crimson);
	font-size: 11px;
	font-weight: 800;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	padding: 5px 10px;
	border-radius: 99px;
}

.ht-product__name { font-size: 16px; font-weight: 800; color: var(--ht-ink); }

/* The price is the card's second read, so it carries the accent colour and
   the heaviest weight rather than sitting muted under the name. */
.ht-product__price {
	margin-top: 2px;
	font-size: 15px;
	font-weight: 800;
	color: var(--ht-crimson);
}
.ht-product__price del {
	color: var(--ht-muted);
	font-weight: 600;
	opacity: 0.7;
	margin-right: 6px;
}
.ht-product__price ins { text-decoration: none; color: var(--ht-crimson); font-weight: 800; }

/*
 * Quick add: hidden until hover, but ALWAYS revealed on keyboard focus —
 * a hover-only control is unreachable by keyboard and invisible to a screen
 * reader user tabbing through the grid.
 */
.ht-product__add {
	position: absolute;
	left: 12px;
	right: 12px;
	bottom: 12px;
	transform: translateY(8px);
	opacity: 0;
	visibility: hidden;
	background: var(--ht-crimson);
	color: var(--ht-cream-light);
	text-align: center;
	font-size: 13.5px;
	font-weight: 700;
	padding: 11px 14px;
	border-radius: 99px;
	transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s;
}
.ht-product__add:hover { background: var(--ht-crimson-dark); color: var(--ht-cream-light); }

.ht-product:hover .ht-product__add,
.ht-product__add:focus-visible {
	opacity: 1;
	visibility: visible;
	transform: translateY(0);
}

/* WooCommerce toggles these while its AJAX request is in flight. */
.ht-product__add.loading { opacity: 0.7; }
.ht-product__add.added::after { content: " ✓"; }

/*
 * WooCommerce injects its own "View cart" link after a successful add. It is
 * not ours to suppress — it is the confirmation affordance — but it arrives
 * unstyled, so it gets the theme's small-link treatment.
 */
.ht-product .added_to_cart {
	margin-top: 6px;
	font-size: 13px;
	font-weight: 700;
	color: var(--ht-crimson);
}
.ht-product .added_to_cart:hover { color: var(--ht-crimson-dark); }

@media (max-width: 900px) {
	.ht-collections__inner { padding-block: 56px; }

	/*
	 * Drop the tile floor so the grid keeps wrapping instead of collapsing to
	 * a single column. This band shows every leaf category -- all eighteen --
	 * and at the 180px floor a 390px phone fits exactly one per row:
	 * eighteen rows, 8,346px, very nearly ten screens of scrolling past one
	 * section. 140px gives two columns on a phone and four on a tablet.
	 *
	 * The floor moves; the auto-fit rule does not. Column COUNT stays the
	 * grid's own business at every width, rather than becoming a list of
	 * breakpoints someone has to keep in step with the number of categories
	 * -- which changes whenever the owner adds a subject.
	 *
	 * Here rather than in the "Below the nav breakpoint" block near the top of
	 * this file, for the reason the .ht-arrivals__grid rule below records:
	 * media queries add no specificity, so an override written before
	 * .ht-collections__grid's own declaration loses to it on source order and
	 * silently does nothing. Measured, not assumed -- it was written up there
	 * first and the phone stayed one column.
	 */
	.ht-collections__grid {
		grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr));
	}
	.ht-arrivals { padding-block: 56px 48px; }
	.ht-arrivals__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

	/*
	 * No hover on touch, so the button is permanently visible — but it stays
	 * anchored to the image rather than going static, which would push it below
	 * the price and away from the product it belongs to.
	 */
	.ht-product__add {
		opacity: 1;
		visibility: visible;
		transform: none;
	}
}
/* After the 900px block, not before it: same specificity, so at phone widths
   whichever comes last in the file wins. */
@media (max-width: 560px) {
	.ht-arrivals__grid { grid-template-columns: minmax(0, 1fr); }
}
/* One per row on a phone, after the 900px block so the cascade runs narrow-last. */
@media (max-width: 560px) {
	.ht-related ul.products.ht-grid,
	.woocommerce .ht-related ul.products.ht-grid {
		grid-template-columns: minmax(0, 1fr);
	}
}



@media (prefers-reduced-motion: reduce) {
	.ht-collection__img,
	.ht-product__img,
	.ht-product__add { transition: none; }
	.ht-collection:hover .ht-collection__img,
	.ht-product:hover .ht-product__img { transform: none; }
}

/* ==========================================================================
   Journal
   ========================================================================== */

.ht-journal { padding-block: 96px; }

.ht-journal__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
	gap: 26px;
}

.ht-article {
	display: flex;
	flex-direction: column;
	gap: 14px;
	color: var(--ht-ink);
}
.ht-article:hover { color: var(--ht-crimson); }

.ht-article__media {
	position: relative;
	display: block;
	aspect-ratio: 16 / 10;
	border-radius: var(--ht-radius);
	overflow: hidden;
	background: var(--ht-cream-warm);
}

/*
 * Portrait artwork in a 16:10 frame keeps only ~44% of its height, so where
 * that band falls matters. A thangka's principal deity sits in the upper
 * middle of the composition, and a dead-centre crop clips the head; biasing
 * upward keeps the face in frame.
 */
.ht-article__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center 34%;
	transition: transform 0.4s ease;
}
.ht-article:hover .ht-article__img { transform: scale(1.04); }

.ht-article__placeholder {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 12.5px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--ht-muted);
}

.ht-article__date {
	font-size: 12px;
	font-weight: 800;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--ht-muted);
}

.ht-article__title {
	font-family: var(--ht-font-display);
	font-size: 20px;
	font-weight: 500;
	line-height: 1.35;
	text-wrap: pretty;
}

@media (max-width: 900px) {
	.ht-journal { padding-block: 56px; }
	.ht-reviews + .ht-journal { padding-top: 0; }
}

@media (prefers-reduced-motion: reduce) {
	.ht-article__img { transition: none; }
	.ht-article:hover .ht-article__img { transform: none; }
}

/* ==========================================================================
   Collection page — values taken directly from Collection.dc.html
   ========================================================================== */

/* --- Dark page header --- */

.ht-shophead {
	background: var(--ht-ink);
	color: var(--ht-cream-light);
}

.ht-shophead__inner {
	display: flex;
	flex-direction: column;
	gap: 14px;
	padding-block: 64px;
}

.ht-crumbs {
	display: flex;
	gap: 8px;
	font-size: 13px;
	font-weight: 600;
	color: var(--ht-footer-text);
}
.ht-crumbs a { color: var(--ht-footer-text); }
.ht-crumbs a:hover { color: var(--ht-gold); }
.ht-crumbs__current { color: var(--ht-cream-light); }

.ht-shophead__title {
	margin: 0;
	font-size: clamp(2rem, 4vw, 2.875rem);
	line-height: 1.1;
	color: var(--ht-cream-light);
}

.ht-shophead__intro {
	margin: 0;
	max-width: 560px;
	font-size: 16px;
	line-height: 1.6;
	color: rgba(253, 249, 242, 0.75);
}

/* --------------------------------------------------------------------------
   Catalog: filter rail beside the grid
   -------------------------------------------------------------------------- */

.ht-shop-layout {
	display: grid;
	/* minmax(0,…) so a wide card can never push the grid past its column. */
	grid-template-columns: 262px minmax(0, 1fr);
	gap: 44px;
	align-items: start;
	padding-block: 44px 40px;
}

.ht-shop-rail {
	position: sticky;
	/* Clears the site header; the rail is what stays in view, not the toolbar. */
	top: 96px;
	max-height: calc(100vh - 120px);
	overflow-y: auto;
	background: #fff;
	padding: 20px;
	/* A hairline that stays out of the way of a column this narrow. */
	scrollbar-width: thin;
	scrollbar-color: var(--ht-track) transparent;
}
.ht-shop-rail::-webkit-scrollbar { width: 5px; }
.ht-shop-rail::-webkit-scrollbar-track { background: transparent; }
.ht-shop-rail::-webkit-scrollbar-thumb { background: var(--ht-track); border-radius: 99px; }
.ht-shop-rail::-webkit-scrollbar-thumb:hover { background: var(--ht-stone); }

.ht-filters {
	display: flex;
	flex-direction: column;
	gap: 26px;
	padding-bottom: 12px;
}

.ht-filters__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
	padding-bottom: 16px;
	/* Heavier than the group rules below, so the header reads as the header. */
	border-bottom: 1.5px solid var(--ht-ink);
}

.ht-filters__heading {
	flex: 1;
	font-family: var(--ht-font-display);
	font-size: 19px;
	font-weight: 600;
	color: var(--ht-ink);
}

.ht-filters__clear {
	font-size: 12.5px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--ht-crimson);
	white-space: nowrap;
}
.ht-filters__clear:hover { color: var(--ht-ink); }
.ht-filters__clear.is-hidden { visibility: hidden; }

/* Only reachable once the rail is a drawer, which happens on narrow screens. */
.ht-filters__close,
.ht-filters__toggle { display: none; }

/* ---- a group ---- */

.ht-filter {
	display: flex;
	flex-direction: column;
	gap: 12px;
	padding-bottom: 24px;
	border-bottom: 1px solid var(--ht-border);
}

.ht-filter__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 8px;
}

.ht-filter__title {
	margin: 0;
	font-size: 11.5px;
	font-weight: 800;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--ht-stone);
}

.ht-filter__value {
	font-size: 13.5px;
	font-weight: 800;
	color: var(--ht-crimson);
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.ht-filter__body {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

/* ---- a row ---- */

.ht-row {
	display: flex;
	align-items: center;
	gap: 11px;
	padding-block: 6px;
	font-size: 14.5px;
	font-weight: 600;
	color: var(--ht-ink);
	cursor: pointer;
}
.ht-row:hover .ht-row__label { color: var(--ht-crimson); }

/* Nothing down this path given the other filters; dimmed rather than removed,
   so the list does not reshuffle under the pointer as choices are made. */
.ht-row.is-empty { opacity: 0.4; }

.ht-row--child {
	padding-left: 15px;
	font-size: 13.5px;
}

/*
 * The real control is hidden but still focusable and still the thing that
 * carries the value; the box beside it is only a picture of its state, drawn
 * from :checked in CSS so nothing has to redraw a tick from script.
 */
.ht-row__input {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
	pointer-events: none;
}

.ht-row__box {
	flex: none;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	height: 18px;
	border: 1.5px solid var(--ht-line);
	border-radius: 99px;
	background: var(--ht-surface);
	color: var(--ht-cream-light);
	font-size: 11px;
	font-weight: 800;
	line-height: 1;
	transition: background-color 0.15s ease, border-color 0.15s ease;
}
.ht-row__box--square { border-radius: 3px; }

.ht-row__input:checked + .ht-row__box {
	border-color: var(--ht-crimson);
	background: var(--ht-crimson);
}
.ht-row__input:checked + .ht-row__box::after { content: "\2713"; }

.ht-row__input:focus-visible + .ht-row__box {
	outline: 2px solid var(--ht-ink);
	outline-offset: 2px;
}

.ht-row__label {
	flex: 1;
	transition: color 0.15s ease;
}
.ht-row__input:checked ~ .ht-row__label { color: var(--ht-crimson); }

.ht-row__count {
	font-size: 12.5px;
	font-weight: 700;
	color: var(--ht-faint);
	font-variant-numeric: tabular-nums;
}

/* ---- price ---- */

.ht-price__dash { color: var(--ht-stone); margin-inline: 2px; }

/*
 * Two ranges stacked on one track. The track is a real element rather than a
 * filled bar, so the selected span never needs a width written from script.
 */
.ht-price__slider {
	position: relative;
	height: 20px;
}

.ht-price__track {
	position: absolute;
	left: 0;
	right: 0;
	top: 8px;
	height: 3px;
	border-radius: 99px;
	background: var(--ht-track);
}

.ht-range {
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	height: 20px;
	margin: 0;
	background: transparent;
	-webkit-appearance: none;
	appearance: none;
	outline: none;
	/* The inputs overlap, so only the handles may take the pointer. */
	pointer-events: none;
}

.ht-range::-webkit-slider-runnable-track { background: transparent; height: 20px; }
.ht-range::-moz-range-track { background: transparent; height: 20px; }

.ht-range::-webkit-slider-thumb {
	-webkit-appearance: none;
	appearance: none;
	pointer-events: auto;
	width: 18px;
	height: 18px;
	margin-top: 1px;
	border-radius: 99px;
	border: 3px solid var(--ht-cream);
	background: var(--ht-crimson);
	box-shadow: 0 1px 4px rgba(20, 12, 6, 0.3);
	cursor: pointer;
}

.ht-range::-moz-range-thumb {
	pointer-events: auto;
	width: 14px;
	height: 14px;
	border-radius: 99px;
	border: 3px solid var(--ht-cream);
	background: var(--ht-crimson);
	box-shadow: 0 1px 4px rgba(20, 12, 6, 0.3);
	cursor: pointer;
}

.ht-range:focus-visible::-webkit-slider-thumb { outline: 2px solid var(--ht-ink); outline-offset: 2px; }
.ht-range:focus-visible::-moz-range-thumb { outline: 2px solid var(--ht-ink); outline-offset: 2px; }

.ht-price__ends {
	display: flex;
	justify-content: space-between;
	font-size: 12px;
	font-weight: 700;
	color: var(--ht-faint);
}

/* ---- new arrivals switch ---- */

.ht-switch { padding-block: 0; }

.ht-switch__input {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
	pointer-events: none;
}

.ht-switch__track {
	flex: none;
	display: flex;
	align-items: center;
	width: 38px;
	height: 22px;
	padding: 2px;
	border-radius: 99px;
	background: var(--ht-track);
	transition: background-color 0.2s ease;
}

.ht-switch__knob {
	width: 18px;
	height: 18px;
	border-radius: 99px;
	background: var(--ht-cream-light);
	box-shadow: 0 1px 3px rgba(20, 12, 6, 0.3);
	transition: transform 0.2s ease;
}

.ht-switch__input:checked + .ht-switch__track { background: var(--ht-crimson); }
.ht-switch__input:checked + .ht-switch__track .ht-switch__knob { transform: translateX(16px); }
.ht-switch__input:focus-visible + .ht-switch__track { outline: 2px solid var(--ht-ink); outline-offset: 2px; }

.ht-filters__apply {
	border: 0;
	border-radius: 99px;
	background: var(--ht-crimson);
	color: var(--ht-cream-light);
	padding: 11px 18px;
	width: 100%;
	font-family: var(--ht-font-body);
	font-size: 13.5px;
	font-weight: 700;
	cursor: pointer;
}

/* --------------------------------------------------------------------------
   Catalog: products column
   -------------------------------------------------------------------------- */

.ht-shop-main {
	display: flex;
	flex-direction: column;
	gap: 24px;
	min-width: 0;
}

.ht-shop-toolbar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
	flex-wrap: wrap;
	padding-bottom: 16px;
	border-bottom: 1px solid var(--ht-border);
}

.ht-shop-toolbar__count {
	flex: 1;
	font-size: 14px;
	font-weight: 700;
	color: var(--ht-body);
}
.ht-shop-toolbar__count strong { color: var(--ht-ink); }

.ht-sort__select {
	border: 1.5px solid var(--ht-border);
	border-radius: 99px;
	background: var(--ht-surface);
	color: var(--ht-ink);
	padding: 10px 16px;
	font-family: var(--ht-font-body);
	font-size: 13.5px;
	font-weight: 700;
	cursor: pointer;
	outline: none;
}

.ht-sort__go {
	border: 1.5px solid var(--ht-ink);
	border-radius: 99px;
	background: transparent;
	color: var(--ht-ink);
	padding: 9px 16px;
	font-family: var(--ht-font-body);
	font-size: 13px;
	font-weight: 700;
	cursor: pointer;
}

/* ---- active filter chips ---- */

.ht-chips {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
}
/* Rendered without stray whitespace so this actually matches when unfiltered. */
.ht-chips:empty { display: none; }

.ht-chip {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	border: 1.5px solid var(--ht-track);
	border-radius: 99px;
	background: var(--ht-cream-warm);
	color: var(--ht-ink);
	padding: 7px 14px;
	font-size: 13px;
	font-weight: 700;
}
.ht-chip:hover { border-color: var(--ht-crimson); color: var(--ht-crimson); }
.ht-chip__remove { color: var(--ht-stone); font-size: 14px; line-height: 1; }

/* ---- refreshing ---- */

[data-ht-results][aria-busy="true"] {
	opacity: 0.45;
	pointer-events: none;
	transition: opacity 0.15s ease;
}

.ht-shop-scrim {
	position: fixed;
	inset: 0;
	z-index: 60;
	background: rgba(20, 12, 6, 0.45);
}
.ht-shop-scrim[hidden] { display: none; }

/*
 * auto-FILL here, unlike the homepage grids. Filtering can leave a single
 * result, and auto-fit would collapse the empty tracks and stretch that one
 * card across the full width of the column — a lone thangka rendered a metre
 * wide. auto-fill keeps the tracks, so a card is always card-sized.
 */
.woocommerce ul.products.ht-grid,
ul.products.ht-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
	gap: 34px 22px;
	margin: 0;
	/* The products column supplies the spacing above; only the tail is ours. */
	padding: 0 0 8px;
	list-style: none;
}

/*
 * WooCommerce's stylesheet floats catalog items and gives them a percentage
 * width (`ul.products li.product { float:left; width:22.05% }`), which inside a
 * CSS grid collapses every card to a sliver. These undo that so the grid tracks
 * govern the layout. Specificity has to beat `.woocommerce ul.products li.product`.
 */
.woocommerce ul.products.ht-grid > li.product,
ul.products.ht-grid > li.product {
	float: none;
	width: auto;
	margin: 0;
	/* Not 0: this selector out-specifies .ht-product, so zeroing it here
	   would strip the frame's inset off every catalog card. */
	padding: var(--ht-card-pad);
	clear: none;
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.woocommerce ul.products.ht-grid > li.product::before,
.woocommerce ul.products.ht-grid > li.product::after { content: none; }

/*
 * WooCommerce clearfixes the list with ul.products::before/::after. Harmless
 * around floats, but in a grid container those pseudo-elements become real grid
 * items — the ::before was taking cell one and shunting every card a column to
 * the right, leaving an empty first column.
 */
.woocommerce ul.products.ht-grid::before,
.woocommerce ul.products.ht-grid::after,
ul.products.ht-grid::before,
ul.products.ht-grid::after { content: none; display: none; }

/*
 * The catalog card is PORTRAIT (4/5) per the comp, where the homepage's New
 * Arrivals card is square. Same component, deliberately different framing, so
 * the aspect is scoped to the catalog rather than changed globally.
 */
.ht-grid .ht-product__media {
	aspect-ratio: 4 / 5;
	background: var(--ht-canvas);
}

/*
 * The related strip borrows the catalog's grid class but the Product Detail
 * comp draws its cards square, like the homepage row. Three classes to beat
 * the catalog rule above.
 */
.ht-related .ht-grid .ht-product__media { aspect-ratio: 1 / 1; }

/*
 * WooCommerce ships `.woocommerce ul.products li.product a img { height:auto }`
 * — specificity (0,3,3), which beats a lone `.ht-product__img` (0,1,0) and left
 * the image short of its 4:5 well. This selector is (0,5,2) so it wins.
 *
 * Third time Woo's stylesheet has out-specified a single-class rule here (logo,
 * item float/width, now this): anything the catalog styles needs the long form.
 */
.woocommerce ul.products.ht-grid li.product .ht-product__img,
ul.products.ht-grid li.product .ht-product__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.ht-product__meta { display: flex; flex-direction: column; gap: 3px; }

.ht-product__cat {
	font-size: 11.5px;
	font-weight: 800;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--ht-stone);
}

.ht-product__size { font-size: 13px; color: var(--ht-muted); }

.ht-grid .ht-product__price {
	margin-top: 2px;
	font-size: 15px;
	font-weight: 800;
	color: var(--ht-crimson);
}

/* --- Empty state --- */

.ht-shop-empty {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 16px;
	text-align: center;
	padding: 72px 24px;
	background: var(--ht-cream-warm);
	border-radius: 6px;
}

.ht-shop-empty__text {
	margin: 0;
	max-width: 380px;
	color: var(--ht-body);
	font-size: 16px;
	font-weight: 600;
	line-height: 1.6;
}

.ht-shop-empty__clear {
	border-radius: 99px;
	background: var(--ht-crimson);
	color: var(--ht-cream-light);
	padding: 12px 24px;
	font-size: 14px;
	font-weight: 700;
}
.ht-shop-empty__clear:hover { background: var(--ht-ink); color: var(--ht-cream-light); }

/* --- Pagination --- */

.woocommerce-pagination { padding: 0 0 88px; }

/*
 * Long-form selectors on purpose. WooCommerce styles pagination as a floated,
 * inline list with a divider border on each item:
 *
 *   .woocommerce nav.woocommerce-pagination ul     (0,2,2)  display:inline-block
 *   .woocommerce nav.woocommerce-pagination ul li  (0,2,3)  display:inline; float:left; border-right
 *
 * A shorter `.woocommerce-pagination ul.page-numbers` is only (0,2,1) and loses,
 * which left the numbers stacked with a stray vertical divider. These are
 * (0,3,2) and (0,3,3) so they win.
 */
.woocommerce nav.woocommerce-pagination ul.page-numbers,
nav.woocommerce-pagination ul.page-numbers {
	display: flex;
	justify-content: center;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
	margin: 0;
	padding: 0;
	list-style: none;
	border: 0;
	width: 100%;
}

.woocommerce nav.woocommerce-pagination ul.page-numbers li,
nav.woocommerce-pagination ul.page-numbers li {
	display: block;
	float: none;
	border: 0;
	border-right: 0;
	margin: 0;
	padding: 0;
	overflow: visible;
}

.woocommerce-pagination .page-numbers {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: 99px;
	border: 1.5px solid var(--ht-border);
	color: var(--ht-ink);
	font-size: 14px;
	font-weight: 800;
	transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
.woocommerce-pagination .page-numbers:hover { border-color: var(--ht-ink); }

.woocommerce nav.woocommerce-pagination ul.page-numbers li a.page-numbers,
.woocommerce nav.woocommerce-pagination ul.page-numbers li span.page-numbers {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	border-radius: 99px;
	border: 1.5px solid var(--ht-border);
	color: var(--ht-ink);
	background: none;
}

.woocommerce nav.woocommerce-pagination ul.page-numbers li span.page-numbers.current,
.woocommerce-pagination .page-numbers.current {
	background: var(--ht-crimson);
	border-color: var(--ht-crimson);
	color: var(--ht-cream-light);
}

.woocommerce-pagination .page-numbers.dots { border-color: transparent; }

@media (max-width: 900px) {
	.ht-shophead__inner { padding-block: 40px; }

	/* Below the breakpoint the header's top row is what sticks, at 73px. */

	/*
	 * No room for a column alongside the grid, so the rail becomes a drawer —
	 * but only where script can open it again. Without script it stays in the
	 * flow above the products, where it still works as a plain form.
	 */
	.ht-shop-layout {
		grid-template-columns: minmax(0, 1fr);
		gap: 24px;
		padding-block: 28px 32px;
	}

	.ht-shop-rail {
		position: static;
		max-height: none;
		overflow: visible;
	}

	.ht-js .ht-filters::-webkit-scrollbar { width: 5px; }
	.ht-js .ht-filters::-webkit-scrollbar-track { background: transparent; }
	.ht-js .ht-filters::-webkit-scrollbar-thumb { background: var(--ht-border); border-radius: 99px; }

	.ht-js .ht-shop-rail { display: contents; }

	.ht-js .ht-filters {
		position: fixed;
		top: 0;
		bottom: 0;
		left: 0;
		z-index: 70;
		width: min(320px, 86vw);
		overflow-y: auto;
		background: #fff;
		border-right: 1px solid var(--ht-border);
		padding: 20px 22px 40px;
		scrollbar-width: thin;
		scrollbar-color: var(--ht-track) transparent;
		transform: translateX(-101%);
		transition: transform 0.25s ease;
	}
	.ht-js .ht-filters.is-open { transform: translateX(0); }

	.ht-js .ht-filters__close {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		width: 30px;
		height: 30px;
		border: 1px solid var(--ht-border);
		border-radius: 50%;
		background: transparent;
		color: var(--ht-ink);
		font-size: 18px;
		line-height: 1;
		cursor: pointer;
	}

	/*
	 * Three controls on one row leaves the count about a third of the width,
	 * which broke "Showing 70 of 80 pieces" over three lines. Refine and the
	 * sort share the first row; the count takes its own beneath them, where it
	 * reads as a caption for the grid that follows.
	 */
	.ht-shop-toolbar {
		gap: 12px 14px;
		padding-bottom: 14px;
	}

	.ht-filters__toggle { order: 1; }

	.ht-sort__select {
		order: 2;
		margin-left: auto;
		max-width: 100%;
	}

	.ht-shop-toolbar__count {
		order: 3;
		flex: 1 0 100%;
	}

	.ht-js .ht-filters__toggle {
		display: inline-flex;
		align-items: center;
		gap: 7px;
		border: 1.5px solid var(--ht-ink);
		border-radius: 99px;
		background: transparent;
		color: var(--ht-ink);
		padding: 8px 16px;
		font-family: var(--ht-font-body);
		font-size: 13px;
		font-weight: 700;
		cursor: pointer;
	}

	.ht-filters-open { overflow: hidden; }

	.woocommerce ul.products.ht-grid,
	ul.products.ht-grid { padding-block: 28px 24px; gap: 26px 16px; }

	.woocommerce-pagination { padding-bottom: 56px; }
}

/* --- Commission CTA (Collection page) --- */

.ht-commission {
	background: var(--ht-cream-warm);
	border-top: 1px solid var(--ht-border);
}

.ht-commission__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 40px;
	flex-wrap: wrap;
	padding-block: 72px;
}

.ht-commission__copy { max-width: 620px; }

.ht-commission__eyebrow {
	margin: 0 0 12px;
	color: var(--ht-crimson);
	font-size: 13px;
	font-weight: 800;
	letter-spacing: 0.24em;
	text-transform: uppercase;
}

.ht-commission__title {
	margin: 0 0 12px;
	font-size: clamp(1.5rem, 2.6vw, 2rem);
	line-height: 1.2;
}

.ht-commission__text {
	margin: 0;
	font-size: 15.5px;
	line-height: 1.7;
	color: var(--ht-body);
}

.ht-commission__cta { white-space: nowrap; }

@media (max-width: 900px) {
	.ht-commission__inner { padding-block: 48px; gap: 28px; }
}

/* ==========================================================================
   Product detail
   ========================================================================== */

.ht-crumbs--light {
	padding-top: 22px;
	font-size: 13.5px;
	font-weight: 600;
	color: var(--ht-muted);
}
.ht-crumbs--light a { color: var(--ht-muted); }
.ht-crumbs--light a:hover { color: var(--ht-crimson); }
.ht-crumbs--light .ht-crumbs__current { color: var(--ht-ink); }

/* Woo's own shell already sets the images beside .summary; this is the comp's
   two-column grid, so no template copy is needed to produce it. */
.woocommerce div.product,
.woocommerce-page div.product {
	display: grid;
	grid-template-columns: 1.05fr minmax(0, 1fr);
	gap: 64px;
	align-items: start;
	padding-block: 34px 88px;
}

/*
 * div.summary, not .summary: WooCommerce ships
 * `.woocommerce div.product div.summary { float: right; width: 48% }`, which
 * out-specifies a bare class and was leaving this column 260px wide inside a
 * 542px grid track.
 */
.woocommerce div.product div.summary,
.woocommerce-page div.product div.summary {
	display: flex;
	flex-direction: column;
	margin: 0;
	float: none;
	width: auto;
}

/* --- gallery --- */

.ht-pgallery {
	display: flex;
	flex-direction: column;
	gap: 14px;
}

.ht-pgallery__stage { position: relative; }

/*
 * No fixed ratio. The comp crops to 4:5, which suited its mock photo, but the
 * real paintings are square and cropping cut the outer ring off a mandala.
 * The frame takes the painting's own shape instead.
 */
.ht-pgallery__frame {
	position: relative;
	border-radius: var(--ht-radius);
	overflow: hidden;
	background: var(--ht-canvas);
	cursor: crosshair;
}

/*
 * Two classes, not one: WooCommerce's layout stylesheet carries
 * `.woocommerce img { height: auto }`, which out-specifies a single class and
 * left the image at its natural height inside a 4:5 frame.
 */
/* Two classes, not one: WooCommerce's layout stylesheet carries
   `.woocommerce img { height: auto }`, which out-specifies a single class. */
.ht-pgallery .ht-pgallery__img {
	width: 100%;
	height: auto;
	object-fit: contain;
	display: block;
}

.ht-pgallery__badge {
	position: absolute;
	top: 14px;
	left: 14px;
	background: rgba(253, 249, 242, 0.95);
	color: var(--ht-crimson);
	font-size: 11px;
	font-weight: 800;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	padding: 5px 10px;
	border-radius: 99px;
}

.ht-pgallery__hint {
	position: absolute;
	bottom: 14px;
	right: 14px;
	display: flex;
	align-items: center;
	gap: 6px;
	background: rgba(36, 30, 23, 0.72);
	color: var(--ht-cream-light);
	font-size: 12px;
	font-weight: 700;
	padding: 6px 12px;
	border-radius: 99px;
	pointer-events: none;
}
.ht-pgallery.is-zooming .ht-pgallery__hint { display: none; }

/*
 * The lens and the pane are placed from custom properties the script sets as
 * the pointer moves. Everything about how they look lives here.
 */
.ht-pgallery__lens {
	position: absolute;
	left: var(--ht-lens-x, 0);
	top: var(--ht-lens-y, 0);
	width: var(--ht-lens-w, 45%);
	height: var(--ht-lens-h, 36%);
	border: 1.5px solid rgba(36, 30, 23, 0.7);
	background: rgba(253, 249, 242, 0.25);
	box-shadow: 0 0 0 9999px rgba(36, 30, 23, 0.18);
	pointer-events: none;
	display: none;
}
.ht-pgallery.is-zooming .ht-pgallery__lens { display: block; }

.ht-pgallery__pane {
	position: absolute;
	left: calc(100% + 18px);
	top: 0;
	width: 540px;
	height: 540px;
	z-index: 45;
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
	box-shadow: 0 16px 48px rgba(20, 12, 6, 0.22);
	background-color: var(--ht-canvas);
	background-image: var(--ht-zoom-image);
	background-repeat: no-repeat;
	background-size: var(--ht-zoom-size, 220%);
	background-position: var(--ht-zoom-pos, 50% 50%);
	pointer-events: none;
	display: none;
}
.ht-pgallery.is-zooming .ht-pgallery__pane { display: block; }

.ht-pgallery__thumbs {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 12px;
}

.ht-pgallery__thumb {
	padding: 0;
	border: 2px solid var(--ht-border);
	border-radius: var(--ht-radius);
	overflow: hidden;
	background: var(--ht-canvas);
	aspect-ratio: 1 / 1;
	cursor: pointer;
}
.ht-pgallery .ht-pgallery__thumb img { width: 100%; height: 100%; object-fit: contain; display: block; }
.ht-pgallery__thumb:hover { border-color: var(--ht-crimson); }
.ht-pgallery__thumb.is-active { border-color: var(--ht-crimson); }

.ht-pgallery__note {
	margin: 0;
	font-size: 12.5px;
	color: var(--ht-stone);
}

/* --- summary --- */

.ht-psummary__eyebrow {
	margin: 0 0 12px;
	color: var(--ht-crimson);
	font-size: 12.5px;
	font-weight: 800;
	letter-spacing: 0.24em;
	text-transform: uppercase;
}

.woocommerce div.product .product_title {
	margin: 0 0 12px;
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: clamp(30px, 3vw, 40px);
	line-height: 1.1;
	text-wrap: balance;
}

.ht-rating {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 0 0 18px;
}

.ht-rating__stars { display: inline-flex; gap: 2px; }

.ht-rating__star { font-size: 15px; line-height: 1; }
.ht-rating__star::before { content: "\2605"; }
.ht-rating__star.is-full { color: #e9a93e; }
.ht-rating__star.is-empty { color: var(--ht-border); }

/*
 * A half star: the same glyph filled from the left, painted through the text
 * itself rather than by stacking two elements.
 */
.ht-rating__star.is-half {
	background: linear-gradient(90deg, #e9a93e 50%, var(--ht-border) 50%);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}

.ht-rating__text {
	font-size: 13.5px;
	font-weight: 600;
	color: var(--ht-muted);
}

.woocommerce div.product p.price,
.woocommerce div.product span.price {
	margin: 0;
	font-family: var(--ht-font-display);
	font-size: 34px;
	font-weight: 500;
	/* 1.6 on 34px is 54px of box for 34px of type; the comp leaves it normal. */
	line-height: normal;
	color: var(--ht-crimson);
}
.woocommerce div.product p.price del { font-size: 22px; color: var(--ht-muted); }
.woocommerce div.product p.price ins { text-decoration: none; }

/* Baselines, not tops: the price is 34px and the note 13.5px, and the comp
   sets them on one line. */
.ht-priceline {
	display: flex;
	align-items: baseline;
	gap: 12px;
	flex-wrap: wrap;
	margin: 0 0 6px;
}

.ht-psummary__shipping {
	margin: 0;
	font-size: 13.5px;
	font-weight: 600;
	color: var(--ht-muted);
}

.woocommerce div.product .woocommerce-product-details__short-description {
	margin: 0;
	font-size: 15.5px;
	line-height: 1.7;
	color: var(--ht-body);
}
.woocommerce div.product .woocommerce-product-details__short-description p { margin: 0; }

/*
 * The comp leaves its small text at the browser default line-height; this
 * theme sets 1.6 on body, which is right for paragraphs and too loose for
 * labels. Each of these was running ~4px tall, and across three size cards,
 * three canvas cards and four reassurances it pushed the column 104px longer
 * than the comp's.
 */
.ht-psummary__eyebrow,
.ht-psummary__shipping,
.ht-rating__text,
.ht-field__label,
.ht-option__label,
.ht-option__note,
.ht-option__price,
.ht-assurances__item,
.ht-accordion__title,
.ht-pgallery__note {
	line-height: normal;
}

/* --- option cards --- */

.ht-field { margin-bottom: 24px; }

.ht-field__label {
	margin: 0 0 10px;
	font-size: 13px;
	font-weight: 800;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--ht-ink);
}
/* The label is set in capitals, the chosen value is not — inheriting the
   transform turned "Cotton Canvas" into "COTTON CANVAS". */
.ht-field__value {
	color: var(--ht-crimson);
	text-transform: none;
}

.ht-field__options { display: flex; flex-direction: column; gap: 9px; }
.ht-field__options--canvas {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 10px;
}

.ht-option {
	display: flex;
	align-items: center;
	gap: 12px;
	border: 1.5px solid var(--ht-border);
	background: var(--ht-surface);
	border-radius: var(--ht-radius);
	cursor: pointer;
	transition: border-color 0.15s ease, background-color 0.15s ease;
}
.ht-option:hover { border-color: var(--ht-crimson); }

.ht-option__input {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
	pointer-events: none;
}
.ht-option:has( .ht-option__input:checked ) {
	border-color: var(--ht-crimson);
	background: #f7ebe3;
}
.ht-option:has( .ht-option__input:focus-visible ) {
	outline: 2px solid var(--ht-ink);
	outline-offset: 2px;
}

.ht-option--size { padding: 14px 18px; }

.ht-option__dot {
	flex: none;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	height: 18px;
	border: 2px solid #b9ae9f;
	border-radius: 99px;
}
.ht-option__dot::after {
	content: "";
	width: 9px;
	height: 9px;
	border-radius: 99px;
	background: transparent;
}
.ht-option__input:checked ~ .ht-option__dot { border-color: var(--ht-crimson); }
.ht-option__input:checked ~ .ht-option__dot::after { background: var(--ht-crimson); }

.ht-option__text { display: flex; flex-direction: column; gap: 1px; flex: 1; }
.ht-option__label { font-weight: 800; font-size: 14.5px; color: var(--ht-ink); }
.ht-option__note { font-size: 12.5px; color: var(--ht-muted); }
.ht-option__price { font-weight: 800; font-size: 15px; color: var(--ht-crimson); white-space: nowrap; }

.ht-option--canvas {
	flex-direction: column;
	align-items: stretch;
	gap: 0;
	overflow: hidden;
}
.ht-option--canvas .ht-option__text { padding: 9px 11px; }
.ht-option--canvas .ht-option__label { font-size: 13px; }
.ht-option--canvas .ht-option__note { font-size: 11.5px; }

/* Stand-ins until the cloths are photographed. */
.ht-option__swatch {
	display: block;
	width: 100%;
	aspect-ratio: 5 / 3;
	background: repeating-linear-gradient(45deg, #eee6d8 0 10px, #e5daca 10px 20px);
}
.ht-option__swatch--fine-silk { background: repeating-linear-gradient(45deg, #f0e4d0 0 10px, #e9d6b8 10px 20px); }
.ht-option__swatch--brocade-mounted { background: repeating-linear-gradient(45deg, #e3cdb4 0 10px, #d9be9c 10px 20px); }

/* --- buy row --- */

/* The gap above the options belongs to the form, so a product with no short
   description does not run its price straight into the size cards. */
.woocommerce div.product form.cart { margin: 26px 0 0; }
.woocommerce div.product form.cart .variations,
.woocommerce div.product form.cart .reset_variations { display: none; }

/* The headline price above carries the chosen variation, so this would be the
   same figure twice. Woo still needs the element present and updated. */
.woocommerce div.product .woocommerce-variation-price { display: none; }

.woocommerce div.product .woocommerce-variation-availability { margin-bottom: 12px; }

.woocommerce div.product form.cart .woocommerce-variation-add-to-cart {
	display: flex;
	gap: 12px;
	margin-bottom: 14px;
}

.woocommerce div.product form.cart .quantity {
	display: flex;
	align-items: center;
	border: 1.5px solid var(--ht-ink);
	border-radius: 99px;
	overflow: hidden;
	margin: 0;
	float: none;
}
.woocommerce div.product form.cart .quantity input.qty {
	width: 34px;
	height: 50px;
	border: 0;
	background: transparent;
	text-align: center;
	font-family: var(--ht-font-body);
	font-weight: 800;
	font-size: 15px;
	color: var(--ht-ink);
	-moz-appearance: textfield;
	appearance: textfield;
}
/* The native spinners would sit beside our own stepper. */
.woocommerce div.product form.cart .quantity input.qty::-webkit-outer-spin-button,
.woocommerce div.product form.cart .quantity input.qty::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}

.ht-qty__step {
	width: 40px;
	height: 50px;
	border: 0;
	background: transparent;
	color: var(--ht-ink);
	font-family: var(--ht-font-body);
	font-size: 18px;
	line-height: 1;
	cursor: pointer;
}
.ht-qty__step:hover { color: var(--ht-crimson); }

/* Woo labels the field for assistive tech; the stepper makes it visible noise. */
.woocommerce div.product form.cart .quantity label { display: none; }

.woocommerce div.product form.cart .single_add_to_cart_button {
	flex: 1;
	height: 52px;
	border: 0;
	border-radius: 99px;
	background: var(--ht-crimson);
	color: var(--ht-cream-light);
	font-family: var(--ht-font-body);
	font-weight: 800;
	font-size: 15.5px;
	cursor: pointer;
	transition: background-color 0.2s ease;
}
.woocommerce div.product form.cart .single_add_to_cart_button:hover { background: var(--ht-ink); }
.woocommerce div.product form.cart .single_add_to_cart_button.disabled { opacity: 0.45; cursor: not-allowed; }

.ht-whatsapp {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 9px;
	height: 50px;
	border: 1.5px solid #1fa855;
	border-radius: 99px;
	color: #178a45;
	font-weight: 800;
	font-size: 14.5px;
	margin-bottom: 22px;
}
.ht-whatsapp:hover { background: #1fa855; color: #fff; }
.ht-whatsapp__dot { width: 8px; height: 8px; border-radius: 99px; background: currentColor; }

/* --- availability --- */

/* A hairline and a state dot rather than an accent bar down one side: this
   block is product information sitting in the buy column, not a notice, and
   nothing else in that column carries a bar. The dot reuses the idiom already
   established by .ht-whatsapp__dot above. */

.ht-availability {
	border-top: 1px solid var(--ht-border);
	padding-block: 14px 0;
	margin-block: 20px 0;
}

.ht-availability__title {
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: 0.75rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	font-weight: 600;
}

.ht-availability__title::before {
	content: "";
	flex: none;
	width: 7px;
	height: 7px;
	border-radius: 99px;
	background: var(--ht-gold);
}

.ht-availability--commission .ht-availability__title::before {
	background: var(--ht-stone);
}

.ht-availability__body {
	margin: 4px 0 0;
	font-size: 0.875rem;
	line-height: 1.5;
	color: var(--ht-body);
}

/* --- assurances --- */

.ht-assurances {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 10px 20px;
	margin: 0 0 28px;
	padding: 18px 20px;
	background: var(--ht-cream-warm);
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
	list-style: none;
}

.ht-assurances__item {
	font-size: 13px;
	font-weight: 700;
	color: var(--ht-body);
}
.ht-assurances__item::before { content: "\2713"; margin-right: 6px; }

/* --- accordions --- */

.ht-accordions { border-top: 1px solid var(--ht-border); }

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

.ht-accordion__title {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 18px 2px;
	font-weight: 800;
	font-size: 15px;
	color: var(--ht-ink);
	cursor: pointer;
	list-style: none;
}
.ht-accordion__title::-webkit-details-marker { display: none; }
.ht-accordion__title:hover { color: var(--ht-crimson); }
.ht-accordion__title::after {
	content: "+";
	font-family: var(--ht-font-display);
	font-size: 20px;
	font-weight: 300;
	color: var(--ht-crimson);
}
.ht-accordion[open] > .ht-accordion__title::after { content: "\2013"; }

.ht-accordion__body {
	margin: 0;
	padding: 0 2px 20px;
	font-size: 14.5px;
	line-height: 1.75;
	color: var(--ht-body);
}

/* --- symbolism --- */

.ht-symbolism {
	background: var(--ht-ink);
	color: var(--ht-cream-light);
}

.ht-symbolism__inner {
	display: grid;
	grid-template-columns: 1fr 1.2fr;
	gap: 72px;
	align-items: center;
	padding-block: 88px;
}

/*
 * The comp crops to 4:5 because its mock photo suited it. The real paintings
 * are square, so cropping cut the outer ring off a mandala — the part that
 * carries the iconography. Shown whole at its own ratio instead; the section
 * centres the shorter column, so nothing is left hanging.
 */
.ht-symbolism .ht-symbolism__img {
	width: 100%;
	height: auto;
	aspect-ratio: auto;
	object-fit: contain;
	border-radius: var(--ht-radius);
	display: block;
}

.ht-symbolism__eyebrow {
	margin: 0 0 14px;
	color: var(--ht-gold);
	font-size: 13px;
	font-weight: 800;
	letter-spacing: 0.24em;
	text-transform: uppercase;
}

.ht-symbolism__title {
	margin: 0 0 22px;
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: clamp(28px, 3vw, 38px);
	line-height: 1.15;
	text-wrap: balance;
}

.ht-symbolism__text p {
	margin: 0 0 16px;
	font-size: 16px;
	line-height: 1.8;
	color: rgba(253, 249, 242, 0.82);
}
.ht-symbolism__text p:last-child { margin-bottom: 0; }

/* --- related --- */

.ht-related { padding-block: 96px; }

/*
 * Fixed tracks, not the catalog grid's auto-fill: with three products a
 * four-column grid would leave a hole on the right.
 */
.ht-related ul.products.ht-grid,
.woocommerce .ht-related ul.products.ht-grid {
	grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media (max-width: 1100px) {
	.ht-pgallery__pane { display: none; }
	.ht-pgallery.is-zooming .ht-pgallery__pane { display: none; }
}

@media (max-width: 900px) {
	.woocommerce div.product,
	.woocommerce-page div.product {
		grid-template-columns: minmax(0, 1fr);
		gap: 32px;
		padding-block: 20px 56px;
	}

	.ht-symbolism__inner {
		grid-template-columns: minmax(0, 1fr);
		gap: 32px;
		padding-block: 56px;
	}

	.ht-related { padding-block: 56px; }

	.ht-related ul.products.ht-grid,
	.woocommerce .ht-related ul.products.ht-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

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

@media (max-width: 560px) {
	.ht-field__options--canvas { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --------------------------------------------------------------------------
   Floating WhatsApp button
   -------------------------------------------------------------------------- */

/*
 * z-index 35, not the comp's 60: the comp has no drawers, this build has two.
 * Below the nav scrim (40) and the filter scrim (60) so an open drawer covers
 * it, above ordinary content everywhere else.
 */
.ht-wa-float {
	position: fixed;
	right: 26px;
	bottom: 26px;
	z-index: 35;
	display: flex;
	align-items: center;
	gap: 9px;
	background: #1fa855;
	color: #fff;
	padding: 14px 24px;
	border-radius: 99px;
	font-family: var(--ht-font-body);
	font-size: 14.5px;
	font-weight: 800;
	line-height: normal;
	box-shadow: 0 8px 24px rgba(20, 12, 6, 0.25);
	transition: background-color 0.2s ease;
}
.ht-wa-float:hover { background: #178a45; color: #fff; }
.ht-wa-float:focus-visible { outline: 2px solid var(--ht-ink); outline-offset: 3px; }

.ht-wa-float__dot {
	width: 9px;
	height: 9px;
	border-radius: 99px;
	background: #fff;
}

@media (max-width: 560px) {
	.ht-wa-float {
		right: 16px;
		bottom: 16px;
		padding: 12px 18px;
		font-size: 13.5px;
	}
}

/* ==========================================================================
   Cart — values taken directly from Cart.dc.html
   ========================================================================== */

/* --- hero: row layout, steps on the right --- */

.ht-shophead--cart .ht-shophead__inner {
	flex-direction: row;
	align-items: flex-end;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 40px;
}

.ht-shophead__lead {
	display: flex;
	flex-direction: column;
	gap: 14px;
}

.ht-steps {
	display: flex;
	align-items: center;
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: 12px;
	font-weight: 800;
	letter-spacing: 0.14em;
	color: rgba(253, 249, 242, 0.5);
}

.ht-steps__item {
	display: flex;
	align-items: center;
	gap: 9px;
}
.ht-steps__item.is-current { color: var(--ht-gold); }

.ht-steps__item + .ht-steps__item::before {
	content: '';
	width: 52px;
	height: 1px;
	background: rgba(253, 249, 242, 0.22);
	margin: 0 16px;
}

.ht-steps__num {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 22px;
	height: 22px;
	border-radius: 99px;
	border: 1.5px solid rgba(253, 249, 242, 0.35);
	font-size: 11px;
}
.ht-steps__item.is-current .ht-steps__num {
	border-color: var(--ht-gold);
	background: var(--ht-gold);
	color: var(--ht-ink);
}

/* --- empty cart --- */

/*
 * padding-block only: this renders inside .ht-container (opened by
 * ht_woocommerce_wrapper_start()), which already supplies max-width and
 * padding-inline. Re-applying either here insets the card 32px further than
 * the items card above it.
 */
.ht-cartempty {
	padding-block: 88px 96px;
}

.ht-cartempty__card {
	max-width: 620px;
	margin-inline: auto;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 18px;
	text-align: center;
	background: var(--ht-surface);
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
	padding: 64px 48px;
}

.ht-cartempty__icon {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 72px;
	height: 72px;
	border-radius: 99px;
	border: 1.5px solid var(--ht-border);
	color: var(--ht-stone);
}

.ht-cartempty__title {
	margin: 0;
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: 30px;
	line-height: 1.2;
}

.ht-cartempty__body {
	margin: 0;
	max-width: 400px;
	font-size: 15.5px;
	line-height: 1.7;
	color: var(--ht-body);
}

.ht-cartempty__actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 12px;
	margin-top: 8px;
}

/*
 * "Saved for later" also renders here now (round-3 review, S1) — saving the
 * last cart line empties the cart, so this card is what that click lands on,
 * and without the saved list it looked exactly like a delete. The section is
 * shaped for the cart's wide main column, so it needs re-fitting for this
 * narrow centred card: full width, left-aligned inside a centred parent, and
 * the price/actions dropped onto their own row rather than squeezed into an
 * `auto` column that leaves the title wrapping every other word.
 */
.ht-cartempty .ht-saved {
	align-self: stretch;
	width: 100%;
	box-sizing: border-box;
	text-align: left;
}
.ht-cartempty .ht-saved__heading { text-align: center; }
.ht-cartempty .ht-saved__line { grid-template-columns: 56px minmax(0, 1fr); gap: 14px; }
.ht-cartempty .ht-saved__actions {
	grid-column: 1 / -1;
	justify-content: flex-start;
	flex-wrap: wrap;
}

/* --- two-column body --- */

.ht-cartpage {
	display: grid;
	grid-template-columns: 1.55fr 1fr;
	gap: 48px;
	align-items: start;
	padding-block: 52px 24px;
}

.ht-cartpage__main { display: flex; flex-direction: column; gap: 34px; }

/* cart.js toggles this while an AJAX mutation is in flight — no inline
   style, no layout shift, just a visual hold so a second click doesn't
   race the first request. */
.ht-cartpage.is-busy { opacity: 0.6; pointer-events: none; }
/* The same pending state for the saved list on the EMPTY cart page, where
   there is no .ht-cartpage for cart.js to mark (see assets/js/cart.js). */
.ht-saved.is-busy { opacity: 0.6; pointer-events: none; }

.ht-cartpage__aside { position: sticky; top: 96px; display: flex; flex-direction: column; gap: 18px; }

/* --- items card --- */

.ht-cartpage__items {
	background: var(--ht-surface);
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
}

.ht-cartpage__itemshead {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 18px 26px;
	border-bottom: 1px solid var(--ht-border);
}

.ht-cartpage__itemscount {
	font-size: 12px;
	font-weight: 800;
	letter-spacing: 0.16em;
	color: var(--ht-stone);
}

.ht-cartpage__continue { font-size: 13.5px; font-weight: 700; }

.ht-cartline {
	display: grid;
	grid-template-columns: 104px 1fr auto;
	gap: 22px;
	padding: 26px;
	border-bottom: 1px solid var(--ht-track);
	align-items: start;
}

.ht-cartline__media {
	display: block;
	aspect-ratio: 4 / 5;
	border-radius: var(--ht-radius);
	overflow: hidden;
	background: var(--ht-canvas);
}
/* Two classes, not one: WooCommerce's layout stylesheet carries
   `.woocommerce img { height: auto }`, which out-specifies a single class. */
.ht-cartline__media .ht-cartline__img { display: block; width: 100%; height: 100%; object-fit: cover; }

.ht-cartline__body { display: flex; flex-direction: column; gap: 5px; }

.ht-cartline__cat {
	font-size: 11.5px;
	font-weight: 800;
	letter-spacing: 0.12em;
	color: var(--ht-stone);
}

.ht-cartline__name {
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: 20px;
	line-height: 1.25;
	color: var(--ht-ink);
}
.ht-cartline__name:hover { color: var(--ht-crimson); }

.ht-cartline__size { font-size: 13.5px; color: var(--ht-muted); }

.ht-cartline__stock {
	display: flex;
	align-items: center;
	gap: 7px;
	margin-top: 3px;
	font-size: 13px;
	color: var(--ht-body);
}
.ht-cartline__stock::before {
	content: '';
	flex: none;
	width: 6px;
	height: 6px;
	border-radius: 99px;
	background: #1fa855;
}

.ht-cartline__actions {
	display: flex;
	align-items: center;
	gap: 18px;
	margin-top: 12px;
	flex-wrap: wrap;
}

.ht-qty {
	display: flex;
	align-items: center;
	border: 1.5px solid var(--ht-border);
	border-radius: 99px;
	overflow: hidden;
}
.ht-qty__btn {
	width: 38px;
	height: 38px;
	border: 0;
	background: none;
	color: var(--ht-ink);
	font-family: var(--ht-font-body);
	font-size: 17px;
	font-weight: 700;
	cursor: pointer;
}
.ht-qty__btn:hover { background: var(--ht-cream-warm); }
.ht-qty__input {
	width: 34px;
	border: 0;
	background: none;
	text-align: center;
	font-family: var(--ht-font-body);
	font-weight: 800;
	font-size: 14.5px;
	color: var(--ht-ink);
	-moz-appearance: textfield;
	appearance: textfield;
}
.ht-qty__input::-webkit-outer-spin-button,
.ht-qty__input::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}

.ht-linkbtn {
	border: 0;
	background: none;
	padding: 0;
	font-family: var(--ht-font-body);
	font-size: 13.5px;
	font-weight: 700;
	color: var(--ht-muted);
	cursor: pointer;
	text-decoration: underline;
	text-underline-offset: 3px;
}
.ht-linkbtn:hover { color: var(--ht-crimson); }

.ht-cartline__money {
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 4px;
}
.ht-cartline__total { font-weight: 800; font-size: 17px; color: var(--ht-ink); }
.ht-cartline__unit { font-size: 13px; color: var(--ht-stone); }

.ht-cartpage__shipnote {
	margin: 0;
	padding: 18px 26px;
	font-size: 13.5px;
	font-weight: 600;
	color: var(--ht-body);
}

/* --- saved for later --- */

.ht-saved {
	background: var(--ht-cream-warm);
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
	padding: 24px 26px;
}

.ht-saved[hidden] { display: none; }

.ht-saved__heading {
	display: block;
	margin-bottom: 18px;
	font-size: 12px;
	font-weight: 800;
	letter-spacing: 0.16em;
	color: var(--ht-stone);
}

.ht-saved__list { display: flex; flex-direction: column; gap: 16px; }

.ht-saved__line {
	display: grid;
	grid-template-columns: 64px 1fr auto;
	gap: 18px;
	align-items: center;
}

.ht-saved__media {
	display: block;
	aspect-ratio: 4 / 5;
	border-radius: var(--ht-radius);
	overflow: hidden;
	background: var(--ht-canvas);
}
/* Two classes, not one: WooCommerce's layout stylesheet carries
   `.woocommerce img { height: auto }`, which out-specifies a single class. */
.ht-saved__media .ht-saved__img { display: block; width: 100%; height: 100%; object-fit: cover; }

.ht-saved__body { display: flex; flex-direction: column; gap: 3px; }
.ht-saved__name { font-weight: 700; font-size: 15px; color: var(--ht-ink); }
.ht-saved__size { font-size: 13px; color: var(--ht-muted); }

.ht-saved__actions { display: flex; align-items: center; gap: 16px; }
.ht-saved__price { font-weight: 800; font-size: 15px; color: var(--ht-crimson); }
.ht-saved__move { padding: 9px 18px; font-size: 13px; }

/*
 * --- gift note ---
 *
 * .ht-giftnote* lived here, styling the cart page's own gift-note card.
 * Round-2 final review (C3) established that the card could never work —
 * its textarea had no `name` and sat outside the cart's <form> — so the
 * note moved to the checkout form as a real submitted `order_comments`
 * field (ht_checkout_order_note_field(), inc/checkout.php). Its styling is
 * .ht-checkout__notefield, down with the rest of the checkout's fields,
 * rather than a second card here; the rules that dressed the cart card left
 * with the card, instead of staying as CSS nothing selects.
 */

/*
 * --- payment method card ---
 *
 * The real, selectable payment card at checkout/payment.php
 * (woocommerce/checkout/payment.php — .ht-paymethods, .ht-paymethods__heading,
 * .ht-paymethods__list), which lives on the standalone /checkout/ page. A
 * second, read-only "coming soon" stand-in used to live in the cart's main
 * column with its own per-row classes (.ht-paymethods__row, __dot, __info,
 * __name, __desc, __tag) — removed along with its markup (inc/cart.php,
 * ht_cart_payment_methods_render()) when the real card briefly rendered
 * directly on the cart page too. That composition has since been reversed
 * (see cart/cart.php); the stand-in was not reinstated, so the cart page
 * carries no payment block of its own at all — its CTA links to /checkout/.
 */

.ht-paymethods {
	background: var(--ht-surface);
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
	padding: 26px;
}

.ht-paymethods__heading {
	display: block;
	margin-bottom: 18px;
	font-size: 12px;
	font-weight: 800;
	letter-spacing: 0.16em;
	color: var(--ht-stone);
}

.ht-paymethods__list { display: flex; flex-direction: column; gap: 12px; }

/* --- order summary (aside) --- */

.ht-summary {
	background: var(--ht-surface);
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
	padding: 26px;
}

.ht-summary__heading {
	display: block;
	margin-bottom: 20px;
	font-size: 12px;
	font-weight: 800;
	letter-spacing: 0.16em;
	color: var(--ht-stone);
}

.ht-summary__rows { display: flex; flex-direction: column; gap: 13px; font-size: 14.5px; }
.ht-summary__row { display: flex; justify-content: space-between; gap: 16px; }
.ht-summary__label { color: var(--ht-body); }
.ht-summary__value { font-weight: 700; }
.ht-summary__value--free { color: #1fa855; }
.ht-summary__value--muted { font-size: 13.5px; font-weight: 400; color: var(--ht-stone); }

.ht-summary__row--discount { color: var(--ht-crimson); }
.ht-summary__row--discount .ht-summary__label { font-weight: 700; color: var(--ht-crimson); }
.ht-summary__row--discount .ht-summary__value { font-weight: 800; color: var(--ht-crimson); }
.ht-summary__row--discount .woocommerce-remove-coupon {
	color: var(--ht-muted);
	font-weight: 700;
	text-decoration: underline;
	text-underline-offset: 3px;
}
.ht-summary__row--discount .woocommerce-remove-coupon:hover { color: var(--ht-crimson); }

.ht-summary__total {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 16px;
	margin-top: 20px;
	padding-top: 20px;
	border-top: 1px solid var(--ht-border);
}
.ht-summary__totallabel { font-family: var(--ht-font-display); font-weight: 500; font-size: 19px; }
.ht-summary__totalvalue { font-family: var(--ht-font-display); font-weight: 600; font-size: 28px; color: var(--ht-crimson); }

.ht-summary__coupon { display: flex; gap: 8px; margin-top: 22px; }
.ht-summary__couponinput {
	flex: 1;
	min-width: 0;
	border: 1.5px solid var(--ht-border);
	border-radius: 99px;
	background: var(--ht-cream);
	padding: 12px 18px;
	font-family: var(--ht-font-body);
	font-size: 14px;
	font-weight: 600;
	color: var(--ht-ink);
	outline: none;
}
.ht-summary__couponinput:focus { border-color: var(--ht-crimson); }
.ht-summary__couponbtn { flex: none; padding: 0 20px; height: 44px; }

.ht-summary__checkout {
	display: block;
	width: 100%;
	box-sizing: border-box;
	margin-top: 18px;
	text-align: center;
}
.ht-summary__note {
	margin: 12px 0 0;
	text-align: center;
	font-size: 12.5px;
	line-height: 1.6;
	color: var(--ht-stone);
}

/* --- trust badges & "ask us" (aside) --- */

.ht-badges {
	display: flex;
	flex-direction: column;
	gap: 14px;
	margin: 0;
	padding: 20px 22px;
	list-style: none;
	background: var(--ht-cream-warm);
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
}
.ht-badges__item { display: flex; flex-direction: column; gap: 2px; }
.ht-badges__title { font-weight: 800; font-size: 13.5px; color: var(--ht-ink); }
.ht-badges__body { font-size: 13px; line-height: 1.5; color: var(--ht-muted); }

.ht-askus {
	display: flex;
	flex-direction: column;
	gap: 8px;
	padding: 20px 22px;
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
}
.ht-askus__title { font-weight: 800; font-size: 13.5px; color: var(--ht-ink); }
.ht-askus__body { margin: 0; font-size: 13px; line-height: 1.6; color: var(--ht-muted); }
.ht-askus__link { font-size: 13.5px; font-weight: 700; }

/* --- cross-sell --- */

/* padding-block only — see the comment on .ht-cartempty above. */
.ht-crosssell { padding-block: 40px 88px; }

.ht-crosssell__head {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 24px;
	margin-bottom: 26px;
}
.ht-crosssell__eyebrow {
	display: block;
	margin-bottom: 10px;
	font-size: 12.5px;
	font-weight: 800;
	letter-spacing: 0.24em;
	color: var(--ht-crimson);
}
.ht-crosssell__title {
	margin: 0;
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: 30px;
	line-height: 1.2;
}
.ht-crosssell__viewall { font-size: 14px; font-weight: 700; white-space: nowrap; }

/*
 * Fixed tracks, not the catalog grid's auto-fill: three cross-sells should
 * always fill three columns, the same reasoning ht-related uses.
 *
 * Three, not the design comp's repeat(4, 1fr) — the owner made the same call
 * for .ht-related (product page) and wants this section to match. Deliberate
 * departure from the comp; keep in sync with ht_cart_cross_sells()'s default
 * (inc/cart.php) and the posts_per_page/columns args in
 * woocommerce/cart/cart.php. Do not "correct" this back to 4.
 */
.ht-crosssell ul.products.ht-grid,
.woocommerce .ht-crosssell ul.products.ht-grid {
	grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* ==========================================================================
   Checkout
   ========================================================================== */

/*
 * Standalone /checkout/: form-checkout.php wraps the <form> and the sticky
 * aside in .ht-cartpage's grid, exactly like cart/cart.php does for its own
 * items form and summary — align-items: start already comes from the base
 * .ht-cartpage rule above, shared by both pages.
 *
 * .ht-checkout__form is `display: contents` (round-2 review, I4): the
 * checkout <form> itself must stay the real ancestor of both
 * .ht-cartpage__main AND .ht-cartpage__aside — the aside carries the
 * review-order table's shipping-method radios, which must be inside SOME
 * real <form> to submit at all — but a form's own box would otherwise sit
 * between .ht-cartpage (the grid container) and its two column children,
 * breaking the two-column layout entirely (CSS Grid only distributes DIRECT
 * children into its columns). `display: contents` removes the form's own
 * generated box from the render tree without touching the DOM or its
 * behaviour as a form, so .ht-cartpage__main/__aside become direct grid
 * children for layout purposes while every field either contains is still
 * collected by the one real <form> that wraps them.
 *
 * The coupon field (round-2 review, further amendment) sits inside the
 * summary card itself now, directly below the Total row, exactly like
 * cart/cart-totals.php's own — no grid-row bookkeeping of its own needed
 * for the field itself. See woocommerce/checkout/form-checkout.php's own
 * docblock and ht_checkout_coupon_field()/ht_checkout_coupon_shell_form()
 * (inc/checkout.php) for how it still avoids a nested <form> (the HTML5
 * `form=""` attribute, not a separate grid-positioned element — an earlier
 * pass here did exactly that, and the grid-row bookkeeping it needed is
 * gone along with it).
 *
 * ht_checkout_coupon_shell_form()'s own real, empty <form> (holding only
 * the nonce) still IS a direct child of .ht-cartpage, though — a sibling
 * of .ht-checkout__form, not a descendant of it, so it never inherited that
 * form's display: contents. Left alone it is its own grid item with no
 * template column of its own to fall into, which auto-placed it into a new
 * row 48px tall (40px at <=900px) — dead space at the very bottom of the
 * page, empty but still occupying a track. `.ht-checkout__couponshell`
 * gets the same display: contents treatment for the same reason: it holds
 * nothing visual, only a hidden nonce field, so removing its own box from
 * the grid costs nothing and closes the gap.
 *
 * .ht-checkout__fields no longer draws its own card: the billing/shipping
 * fields it wraps render inside .ht-deposit's own STEP 2
 * (ht_checkout_deposit_section() in inc/checkout.php) — nested inside a card
 * that already has a border, so a second one here would draw a card inside a
 * card. Kept as a plain wrapper purely for its descendant h3/checkbox rules.
 */
.ht-checkout__form,
.ht-checkout__couponshell { display: contents; }

/*
 * "Returning customer?" banner (woocommerce/checkout/form-login.php) and the
 * login form it reveals (woocommerce/global/form-login.php). The banner
 * itself needs no rule here — it renders as a plain .woocommerce-info div,
 * styled globally above (see "notices"). The revealed form reuses
 * .ht-auth__panel and .ht-auth__form -- the same card shape and field
 * layout woocommerce/myaccount/form-login.php established -- rather than
 * a parallel set of checkout-only classes; .ht-checkout-login only adds the
 * bottom margin that separates it from the billing fields below, which
 * .ht-auth__panel doesn't carry on its own (on the account pages that
 * spacing comes from the surrounding .ht-auth grid's gap instead).
 */
.ht-checkout-login { margin: 0 0 32px; }
.ht-checkout-login[hidden] { display: none; }

.ht-checkout__fields h3 {
	margin: 0 0 20px;
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: 20px;
}
.ht-checkout__fields .woocommerce-shipping-fields > h3 {
	margin-top: 26px;
	margin-bottom: 12px;
	font-family: var(--ht-font-body);
	font-size: 13.5px;
	font-weight: 800;
	color: var(--ht-ink);
}
.ht-checkout__fields .woocommerce-form__label-for-checkbox {
	display: flex;
	align-items: center;
	gap: 8px;
	font-weight: 700;
	cursor: pointer;
}

/* --- field grid: name/email, phone/country, address (wide) --- */

.woocommerce-billing-fields__field-wrapper,
.woocommerce-shipping-fields__field-wrapper {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 20px 16px;
	margin: 0;
	padding: 0;
	list-style: none;
}

/*
 * The checkout page's readonly reference field (ht_checkout_deposit_extra_
 * fields(), inc/checkout.php) is NOT run through WooCommerce's checkout-
 * field system — see that function's own docblock for why — so it isn't
 * inside .woocommerce-billing-fields__field-wrapper above; this is just its
 * own spacing, placed immediately after that <ul> closes.
 *
 * Transfer date and amount transferred used to sit alongside it in a
 * two-column .ht-field-grid here (removed at the owner's request: both
 * describe a transfer that has already happened, and asking at checkout,
 * before most buyers have transferred, was confusing — they still exist,
 * unchanged, on the confirmation page's own upload form). Nothing else ever
 * used .ht-field-grid, so it and the now-pointless "— optional" suffix
 * style it needed left with them rather than staying as unreferenced CSS.
 */
.ht-checkout__depositfields { margin-top: 20px; }

/*
 * The account-password field (ht_checkout_account_fields(), inc/checkout.php)
 * — a single .ht-field-row sitting on its own directly under the billing
 * grid above, not a grid item within it, so it just needs the same top
 * spacing every other standalone block in this step uses.
 */
.ht-checkout__account { margin-top: 20px; }

.ht-field-row {
	margin: 0;
	display: flex;
	flex-direction: column;
	gap: 7px;
}
.ht-field-row--wide { grid-column: 1 / -1; }

.ht-field-row label {
	font-size: 12.5px;
	font-weight: 800;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--ht-body);
}
.ht-field-row .required { color: var(--ht-crimson); font-style: normal; }

.ht-field-row .woocommerce-input-wrapper { display: block; }

.ht-field-row .input-text,
.ht-field-row select,
.ht-field-row textarea {
	box-sizing: border-box;
	width: 100%;
	border: 1.5px solid var(--ht-border);
	border-radius: var(--ht-radius);
	background: var(--ht-cream);
	padding: 12px 14px;
	font-family: var(--ht-font-body);
	font-size: 14.5px;
	font-weight: 500;
	color: var(--ht-ink);
	outline: none;
}
.ht-field-row .input-text:focus,
.ht-field-row select:focus,
.ht-field-row textarea:focus { border-color: var(--ht-crimson); }

.ht-field-row textarea { resize: vertical; line-height: 1.6; min-height: 96px; }

/*
 * The gift/order note (ht_checkout_order_note_field(), inc/checkout.php).
 * A .ht-field-row like every other field on this form rather than the
 * standalone card the cart page used to draw, so it inherits the shared
 * label, textarea and focus rules above and needs only its own spacing and
 * the two pieces of supporting text the comp's copy carries.
 *
 * Placed AFTER `.ht-field-row { margin: 0 }` deliberately: both rules are
 * single-class (0,1,0), so source order decides, and a margin declared
 * above that reset is silently discarded. Recorded, not changed this round:
 * `.ht-checkout__depositfields { margin-top: 20px }` further up is dead for
 * exactly this reason — the readonly Reference field has never had the
 * 20px it asks for. Cosmetic only, and out of scope for a money-path fix
 * wave.
 *
 * 30px rather than the grid's own 20px: this block is two lines of
 * supporting text tall, and closer than that its heading reads as a caption
 * belonging to the Reference input above it.
 */
.ht-checkout__notefield { margin-top: 30px; }
.ht-checkout__noteoptional {
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: none;
	color: var(--ht-faint);
}
.ht-checkout__notehint {
	margin-top: -2px;
	font-size: 13.5px;
	font-weight: 500;
	line-height: 1.6;
	letter-spacing: 0;
	text-transform: none;
	color: var(--ht-muted);
}

/* The country select is enhanced into selectWoo/select2 by Woo's own script;
   its default chrome is themed just enough to match the plain fields around it. */
.ht-field-row .select2-container--default .select2-selection--single {
	height: 46px;
	border: 1.5px solid var(--ht-border);
	border-radius: var(--ht-radius);
	background: var(--ht-cream);
}
.ht-field-row .select2-selection__rendered {
	padding-left: 14px;
	line-height: 44px;
	font-size: 14.5px;
	color: var(--ht-ink);
}
.ht-field-row .select2-selection__arrow { height: 44px; }

/* --- payment methods card (main column) --- */

.ht-checkout__payment.ht-paymethods { margin-bottom: 0; }

.ht-paymethods__list.wc_payment_methods { margin: 0; padding: 0; list-style: none; }

.ht-paymethod {
	position: relative;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 16px;
	border: 1.5px solid var(--ht-border);
	background: var(--ht-cream);
	border-radius: var(--ht-radius);
	padding: 18px 20px;
}
.ht-paymethod + .ht-paymethod { margin-top: 12px; }
.ht-paymethod:not(.ht-paymethod--soon):hover { border-color: var(--ht-crimson); }
.ht-paymethod:has(.ht-paymethod__radio:checked) { border-color: var(--ht-crimson); }

/*
 * The comp's selection dot, as its own element in BOTH rows rather than as
 * the radio.
 *
 * WooCommerce core's checkout.js hides the payment radio with an inline
 * display:none the moment there is exactly one available gateway, and
 * bin/configure-shop.php makes exactly one a permanent design decision — so
 * the selected, real row had no dot while the un-selectable COMING SOON row
 * kept its decorative one, and the two rows' titles were 36px out of line.
 * Giving both rows the same span works WITH that instead of forcing the radio
 * back into view with !important: identical markup, identical geometry, and
 * the filled state read from the radio's real :checked, so it stays honest if
 * a second gateway is ever added -- which it now has been, since Cash on
 * Delivery is kept enabled for Kathmandu Valley orders. See the @supports
 * block below for why .is-chosen is NOT a second source of that answer.
 *
 * Not a ::before on the row: woocommerce.css already owns that pseudo-element
 * with `.woocommerce-checkout #payment ul.payment_methods
 * li:not(.woocommerce-notice)::before { display: table }` — a clearfix at a
 * specificity (0,4,2) no theme rule of this shape can outrank without an id or
 * !important, which meant a ::before dot could not control its own display.
 */
.ht-paymethod__dot {
	flex: none;
	width: 20px;
	height: 20px;
	box-sizing: border-box;
	border-radius: 99px;
	border: 1.5px solid var(--ht-line);
	background: var(--ht-surface);
}
.ht-paymethod:has(.ht-paymethod__radio:checked) .ht-paymethod__dot {
	border-color: var(--ht-crimson);
	background: var(--ht-crimson);
	box-shadow: inset 0 0 0 3.5px var(--ht-surface);
}
.ht-paymethod:has(.ht-paymethod__radio:focus-visible) .ht-paymethod__dot {
	outline: 2px solid var(--ht-gold);
	outline-offset: 2px;
}

/*
 * .is-chosen is WooCommerce's server-side answer, and it is only correct until
 * the buyer clicks. Between a click and the next AJAX refresh it still names
 * the PREVIOUS gateway, so while it was OR'd with :checked above, two rows
 * painted as selected at once -- one live, one stale. Only one was ever really
 * submitted, but the page said otherwise, which on a payment step is the worst
 * place to be ambiguous.
 *
 * It survives only as what it was meant to be: a fallback for engines without
 * :has(). Gated behind @supports so it can never contradict :checked in an
 * engine that has both.
 */
@supports not selector(:has(*)) {
	.ht-paymethod.is-chosen { border-color: var(--ht-crimson); }

	.ht-paymethod.is-chosen .ht-paymethod__dot {
		border-color: var(--ht-crimson);
		background: var(--ht-crimson);
		box-shadow: inset 0 0 0 3.5px var(--ht-surface);
	}
}

/*
 * The radio itself stays in the DOM and in the tab order — it is the control
 * WooCommerce submits — but is taken out of the visual flow, so core's own
 * inline display:none lands on something already invisible and nothing shifts
 * whether that script has run or not. .ht-paymethod is position: relative, so
 * this is contained by the row.
 */
.ht-paymethod__radio {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: 0;
	padding: 0;
	border: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* #payment/.ht-paymethods carries tabindex="-1" (checkout/payment.php) for
   programmatic focus; suppress the default ring since nothing currently
   focuses it visibly. */
.ht-paymethods:focus { outline: none; }

.ht-paymethod__body {
	display: flex;
	flex-direction: column;
	gap: 3px;
	flex: 1;
	cursor: pointer;
}
.ht-paymethod--soon .ht-paymethod__body,
.ht-paymethod--soon { cursor: not-allowed; }

.ht-paymethod__title { font-weight: 800; font-size: 15px; color: var(--ht-ink); }
.ht-paymethod__note { font-size: 13.5px; line-height: 1.5; color: var(--ht-muted); }

.ht-paymethod--soon {
	background: var(--ht-cream-warm);
	border-color: var(--ht-border);
	opacity: 0.62;
}
.ht-paymethod--soon .ht-paymethod__title { color: var(--ht-muted); }
.ht-paymethod--soon .ht-paymethod__note { color: var(--ht-stone); }

.ht-pill {
	flex: none;
	font-size: 11px;
	font-weight: 800;
	letter-spacing: 0.1em;
	padding: 6px 12px;
	border-radius: 99px;
}
.ht-pill--available { background: var(--ht-cream-warm); color: var(--ht-crimson); }
.ht-pill--muted {
	border: 1.5px solid var(--ht-line);
	padding: 5px 12px;
	color: var(--ht-stone);
}

.ht-paymethod__fields {
	flex-basis: 100%;
	margin-top: 16px;
	padding-top: 16px;
	border-top: 1px solid var(--ht-border);
	font-size: 13.5px;
	line-height: 1.6;
	color: var(--ht-body);
}
.ht-paymethod__fields[hidden] { display: none; }

.ht-paymethods .form-row.place-order { margin-top: 22px; }

#place_order {
	display: block;
	width: 100%;
	box-sizing: border-box;
	border: none;
	border-radius: 99px;
	background: var(--ht-crimson);
	color: var(--ht-cream-light);
	font-family: var(--ht-font-body);
	font-weight: 800;
	font-size: 15.5px;
	padding: 17px 0;
	cursor: pointer;
	transition: background-color 0.2s ease;
}
#place_order:hover { background: var(--ht-crimson-dark); }

.ht-paymethods .woocommerce-terms-and-conditions-wrapper { margin-bottom: 14px; font-size: 13.5px; color: var(--ht-muted); }

/* --- order review (sticky aside) --- */

.ht-checkout__summary .woocommerce-checkout-review-order-table {
	width: 100%;
	margin: 0;
	border-collapse: collapse;
	font-size: 14.5px;
}
.ht-checkout__summary .woocommerce-checkout-review-order-table thead { display: none; }
.ht-checkout__summary .woocommerce-checkout-review-order-table td,
.ht-checkout__summary .woocommerce-checkout-review-order-table th {
	padding: 10px 0;
	border: none;
	font-weight: 400;
	text-align: left;
	vertical-align: top;
}
.ht-checkout__summary .woocommerce-checkout-review-order-table tbody tr { border-bottom: 1px solid var(--ht-border); }
.ht-checkout__summary .woocommerce-checkout-review-order-table .product-total { text-align: right; font-weight: 700; }
.ht-checkout__summary .woocommerce-checkout-review-order-table .cart-subtotal th,
.ht-checkout__summary .woocommerce-checkout-review-order-table .cart-subtotal td { color: var(--ht-body); }
.ht-checkout__summary .woocommerce-checkout-review-order-table .order-total th,
.ht-checkout__summary .woocommerce-checkout-review-order-table .order-total td {
	border-top: 1px solid var(--ht-border);
	padding-top: 20px;
	font-family: var(--ht-font-display);
	font-size: 19px;
	font-weight: 500;
}
.ht-checkout__summary .woocommerce-checkout-review-order-table .order-total td {
	text-align: right;
	font-size: 22px;
	font-weight: 600;
	color: var(--ht-crimson);
}

/* ==========================================================================
   Order confirmation (checkout/thankyou.php) — deposit panel
   ========================================================================== */

/* --- order confirmation: hero --- */

.ht-confirmhero {
	background: var(--ht-ink);
	color: var(--ht-cream-light);
}
.ht-confirmhero__inner {
	padding-top: 56px;
	padding-bottom: 56px;
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 40px;
	flex-wrap: wrap;
}
.ht-confirmhero__lede {
	display: flex;
	flex-direction: column;
	gap: 16px;
	max-width: 640px;
}
.ht-confirmhero__eyebrow {
	display: flex;
	align-items: center;
	gap: 12px;
	margin: 0;
	font-size: 12.5px;
	font-weight: 800;
	letter-spacing: 0.22em;
	color: var(--ht-gold);
}
.ht-confirmhero__pip {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: none;
	width: 34px;
	height: 34px;
	border-radius: 99px;
	background: var(--ht-gold);
	color: var(--ht-ink);
	font-weight: 800;
}
.ht-confirmhero--blocked .ht-confirmhero__eyebrow { color: var(--ht-cream-rose); }
.ht-confirmhero--blocked .ht-confirmhero__pip {
	background: var(--ht-cream-rose);
	color: var(--ht-crimson);
}
.ht-confirmhero__title {
	margin: 0;
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: 46px;
	line-height: 1.1;
	text-wrap: balance;
}
.ht-confirmhero__body {
	margin: 0;
	font-size: 16.5px;
	line-height: 1.7;
	color: rgba(253, 249, 242, 0.78);
}
.ht-confirmhero__email {
	color: var(--ht-cream-light);
	font-weight: 700;
}

/*
 * The step bar is light-on-dark here, unlike the cart and checkout heroes
 * where it sits on cream. .ht-steps' own rules are left alone; only the
 * colours are restated inside the hero.
 */
.ht-confirmhero .ht-steps { color: rgba(253, 249, 242, 0.5); }
.ht-confirmhero .ht-steps__item.is-current { color: var(--ht-gold); }
.ht-confirmhero .ht-steps__num {
	background: rgba(233, 200, 126, 0.25);
	color: var(--ht-gold);
	border-color: transparent;
}
.ht-confirmhero .ht-steps__item.is-current .ht-steps__num {
	background: var(--ht-gold);
	color: var(--ht-ink);
}

/* --- order confirmation: the email-verification gate --- */

/*
 * Shown INSTEAD of the confirmation page when WooCommerce cannot tell that the
 * reader is the buyer — a guest order past its ten-minute grace period. There
 * is deliberately no hero in this state (see
 * ht_confirmation_viewer_may_see_order(), inc/confirmation.php), so this block
 * supplies the vertical rhythm the wrapper gives up on this page.
 */
.ht-verify {
	padding-block: 64px;
	display: flex;
	justify-content: center;
}
.ht-verify__card {
	width: 100%;
	max-width: 520px;
	padding: 32px;
}
.ht-verify__title {
	margin: 0 0 12px;
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: 26px;
	line-height: 1.2;
	color: var(--ht-ink);
}
.ht-verify__body {
	margin: 0 0 24px;
	font-size: 15px;
	line-height: 1.7;
	color: var(--ht-body);
}
.ht-verify__form { margin: 0; }
.ht-verify__field { margin: 0 0 18px; }
.ht-verify__submit { width: 100%; }
.ht-verify__alt {
	margin: 20px 0 0;
	padding-top: 18px;
	border-top: 1px solid var(--ht-border);
	font-size: 13.5px;
	color: var(--ht-muted);
}

/*
 * Core's own "Thank you. Your order has been received." line. It renders bare,
 * outside any container, above the verification card and above the empty-order
 * branch of checkout/thankyou.php — the only two places it still appears, now
 * that the confirmation page's hero says this itself. Give it the page's
 * measure and type rather than leaving it flush against the viewport edge.
 */
.woocommerce-thankyou-order-received {
	max-width: var(--ht-container);
	margin: 0 auto;
	padding: 48px var(--ht-gutter) 0;
	font-size: 15px;
	color: var(--ht-muted);
}
.ht-verify + .woocommerce-thankyou-order-received,
.woocommerce-thankyou-order-received + .ht-verify { padding-top: 0; }

@media (max-width: 520px) {
	.ht-verify { padding-block: 40px; }
	.ht-verify__card { padding: 24px; }
	.ht-verify__title { font-size: 22px; }
}

/* --- order confirmation: while you wait --- */

.ht-invite {
	background: var(--ht-cream-warm);
	border-top: 1px solid var(--ht-border);
	margin-top: 28px;
}
.ht-invite__inner {
	padding-top: 72px;
	padding-bottom: 72px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 40px;
	flex-wrap: wrap;
}
.ht-invite__lede { max-width: 620px; }
.ht-invite__eyebrow {
	margin: 0 0 12px;
	color: var(--ht-crimson);
	font-size: 13px;
	font-weight: 800;
	letter-spacing: 0.24em;
}
.ht-invite__title {
	margin: 0 0 12px;
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: 32px;
	line-height: 1.2;
}
.ht-invite__body {
	margin: 0;
	font-size: 15.5px;
	line-height: 1.7;
	color: var(--ht-body);
}
.ht-invite__actions {
	display: flex;
	gap: 12px;
	flex-wrap: wrap;
}

@media (max-width: 780px) {
	.ht-confirmhero__inner { padding-top: 40px; padding-bottom: 40px; }
	.ht-confirmhero__title { font-size: 34px; }
	.ht-invite__inner { padding-top: 48px; padding-bottom: 48px; }
	.ht-invite__title { font-size: 26px; }
}

/* --- deposit panel --- */

.ht-deposit {
	display: block;
	background: var(--ht-surface);
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
	padding: 30px;
}

.ht-deposit__step + .ht-deposit__step {
	margin-top: 30px;
	padding-top: 30px;
	border-top: 1px solid var(--ht-border);
}

.ht-deposit__steptitle {
	margin: 0 0 16px;
	font-family: var(--ht-font-body);
	font-size: 12px;
	font-weight: 800;
	letter-spacing: 0.16em;
	color: var(--ht-crimson);
}

.ht-bankrows {
	margin: 0;
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 18px 32px;
	padding: 22px;
	background: var(--ht-cream-warm);
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
}

.ht-bankrows__row { display: flex; flex-direction: column; gap: 4px; }

.ht-bankrows__label {
	font-size: 11.5px;
	font-weight: 800;
	letter-spacing: 0.12em;
	color: var(--ht-stone);
}

.ht-bankrows__value {
	margin: 0;
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 14.5px;
	font-weight: 600;
	color: var(--ht-ink);
	word-break: break-word;
}

.ht-deposit__hint { margin: 12px 0 0; font-size: 13px; line-height: 1.6; color: var(--ht-stone); }

/* --- notices --- */

.ht-notice {
	margin: 0 0 20px;
	padding: 14px 18px;
	border-radius: 2px;
	border-left: 3px solid var(--ht-crimson);
	background: var(--ht-cream-rose);
	font-size: 14px;
	line-height: 1.6;
	color: var(--ht-body);
}
.ht-notice--ok { border-left-color: #1fa855; background: #f3faf5; }

/*
 * WooCommerce's own notice markup (.woocommerce-error, .woocommerce-message,
 * .woocommerce-info) styled globally, wherever it appears -- checkout, cart,
 * the account area, anywhere a template calls wc_print_notice() or
 * wc_print_notices(). Previously declared locally inside .ht-auth and
 * .ht-account__content (identical values, three times over) which left every
 * other surface -- checkout's "Returning customer?" banner among them --
 * falling through to WooCommerce's own stylesheet. One declaration now
 * carries the values .ht-notice already defined above.
 *
 * WooCommerce renders .woocommerce-error as a <ul> and the other two as a
 * <div>; list-style: none keeps the <ul> from showing bullets.
 *
 * Severity: .woocommerce-error keeps the theme's crimson (it is one), and
 * .woocommerce-message keeps the existing green. .woocommerce-info gets its
 * own quieter accent -- var(--ht-stone), not var(--ht-gold) -- because gold
 * is already this theme's "look here, premium" accent (deposit-panel labels,
 * CTAs); using it for a routine notice like "Returning customer?" would
 * still shout, just in a different color. Stone is the muted, already-quiet
 * tone (product-card labels), which is what an informational nudge calls
 * for.
 *
 * WooCommerce's own woocommerce.css declares .woocommerce-error,
 * .woocommerce-info, .woocommerce-message together in one rule of its own
 * (padding, margin, position: relative, background-color, color, a 3px
 * border-TOP colored per type -- #720eec generic, overridden to green/blue/
 * red per type -- list-style, width, word-wrap), loaded before this
 * stylesheet at equal specificity (one plain class selector either way), so
 * ours only overrides the properties it actually redeclares -- everything
 * else still comes through from WooCommerce's rule. position: relative and
 * word-wrap: break-word are harmless leftovers, left alone. border-top is
 * not: left unset it draws WooCommerce's own blue/green/red rule ON TOP of
 * the border-left this rule sets, so it is explicitly cleared below.
 *
 * WooCommerce also draws a ::before icon glyph (font-family: WooCommerce;
 * content: "\e028", overridden to a check/warning glyph per type) absolutely
 * positioned at top: 1em; left: 1.5em -- squarely on top of a notice's first
 * word once WooCommerce's own 3.5em left padding is gone (replaced by this
 * rule's 18px). content: none below removes the glyph. ::after is WooCommerce's
 * clearfix for that same icon (content: " "; display: table; clear: both) --
 * genuinely harmless with no visible content, and left alone.
 */
.woocommerce-error,
.woocommerce-message,
.woocommerce-info {
	margin: 0 0 20px;
	padding: 14px 18px;
	border-radius: 2px;
	border-top: none;
	border-left: 3px solid var(--ht-crimson);
	background: var(--ht-cream-rose);
	font-size: 14px;
	line-height: 1.6;
	color: var(--ht-body);
	list-style: none;
}
.woocommerce-error::before,
.woocommerce-message::before,
.woocommerce-info::before { content: none; }
.woocommerce-message { border-left-color: #1fa855; background: #f3faf5; }
.woocommerce-info { border-left-color: var(--ht-stone); background: var(--ht-cream-warm); }

/* --- receipt upload form --- */

.ht-drop__fields {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 16px;
	margin-bottom: 20px;
}

.ht-deposit .ht-field-row {
	display: flex;
	flex-direction: column;
	gap: 7px;
}

.ht-deposit .ht-field-row__label {
	font-size: 12.5px;
	font-weight: 800;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--ht-body);
}

.ht-deposit .ht-field-row .ht-field {
	margin-bottom: 0;
	box-sizing: border-box;
	width: 100%;
	border: 1.5px solid var(--ht-border);
	border-radius: var(--ht-radius);
	background: var(--ht-cream);
	padding: 12px 14px;
	font-family: var(--ht-font-body);
	font-size: 14.5px;
	font-weight: 500;
	color: var(--ht-ink);
	outline: none;
}
.ht-deposit .ht-field-row .ht-field:focus { border-color: var(--ht-crimson); }

/* The checkout page's readonly transfer reference (ht_checkout_deposit_section(),
   inc/checkout.php) — minted server-side and never editable, styled to read
   as settled rather than as an ordinary input. */
.ht-deposit .ht-field-row .ht-field--mono {
	background: var(--ht-cream);
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-weight: 600;
	color: var(--ht-body);
	cursor: default;
}
.ht-deposit .ht-field-row .ht-field--mono:focus { border-color: var(--ht-border); }

/*
 * Nested inside .ht-paymethods' own card (woocommerce/checkout/payment.php),
 * the checkout page's deposit steps must not draw a second, inner card —
 * .ht-deposit's base rule above is a bordered box on its own (the shape the
 * confirmation page needs, sitting directly in .ht-confirm with nothing
 * around it). Here it is neutralised down to the comp's own divider
 * treatment: a rule above the first step, nothing else.
 */
.ht-paymethods .ht-deposit {
	background: none;
	border: none;
	border-radius: 0;
	padding: 26px 0 0;
	margin-top: 26px;
	border-top: 1px solid var(--ht-border);
}
[data-ht-checkout-droperror][hidden] { display: none; }

.ht-drop__zone {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 10px;
	text-align: center;
	padding: 38px 24px;
	border: 2px dashed var(--ht-line);
	border-radius: var(--ht-radius);
	background: var(--ht-cream);
	cursor: pointer;
	transition: border-color 0.2s ease, background-color 0.2s ease;
}
.ht-drop__zone:hover,
.ht-drop__zone.is-over {
	border-color: var(--ht-crimson);
	background: var(--ht-cream-rose);
}
/* assets/js/checkout-deposit.js toggles this while the eager, pre-order
   upload is in flight (see ht_checkout_deposit_section(), inc/checkout.php) —
   no inline style, just a visual hold matching .ht-cartpage.is-busy. */
.ht-drop__zone.is-uploading { opacity: 0.7; pointer-events: none; }

.ht-drop__icon {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 46px;
	height: 46px;
	border-radius: 99px;
	background: var(--ht-cream-warm);
	color: var(--ht-crimson);
}

.ht-drop__title { font-weight: 800; font-size: 15px; color: var(--ht-ink); }
.ht-drop__hint { font-size: 13.5px; line-height: 1.5; color: var(--ht-muted); }
.ht-drop__chosen:not(:empty) { font-size: 13.5px; font-weight: 700; color: var(--ht-crimson); }

/* Visually hidden, not display:none — still focusable and clickable via the
   wrapping <label>, so the form keeps working with JavaScript disabled. */
.ht-drop__input {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.ht-drop .ht-btn {
	display: block;
	width: 100%;
	margin-top: 22px;
	border: none;
	text-align: center;
	font-family: var(--ht-font-body);
	cursor: pointer;
}

/*
 * What the buyer told us, played back on the confirmation page once a receipt
 * exists (round-3 review, I4). The comp's two-column mono grid — DEPOSIT
 * RECORD's four rows — plus the file block that acknowledges the upload
 * itself. Kept in .ht-receiptrecap: tests/test-deposit-upload.php asserts
 * that exact class as the regression net for a receipt uploading and the
 * page not changing.
 */
.ht-receiptrecap {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 18px 32px;
	margin: 0 0 22px;
	padding: 0;
}
.ht-receiptrecap__row { display: flex; flex-direction: column; gap: 4px; }
.ht-receiptrecap__label {
	font-size: 11.5px;
	font-weight: 800;
	letter-spacing: 0.12em;
	color: var(--ht-stone);
}
.ht-receiptrecap__value {
	margin: 0;
	font-family: ui-monospace, Menlo, Consolas, monospace;
	font-size: 14.5px;
	font-weight: 600;
	color: var(--ht-ink);
	word-break: break-word;
}

.ht-receiptfile {
	display: flex;
	align-items: center;
	gap: 16px;
	background: var(--ht-surface);
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
	padding: 16px 18px;
}
.ht-receiptfile__icon {
	flex: none;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	border-radius: var(--ht-radius);
	background: #f3faf5;
	color: #1fa855;
}
.ht-receiptfile__detail { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ht-receiptfile__name {
	font-weight: 800;
	font-size: 14.5px;
	color: var(--ht-ink);
	word-break: break-word;
}
.ht-receiptfile__when { font-size: 13px; color: var(--ht-muted); }

.ht-receiptfile__fold { margin-top: 16px; }
.ht-receiptfile__summary {
	cursor: pointer;
	display: inline-block;
	border: 1.5px solid var(--ht-ink);
	border-radius: 99px;
	padding: 10px 20px;
	font-weight: 700;
	font-size: 13.5px;
	color: var(--ht-ink);
	list-style: none;
}
.ht-receiptfile__summary::-webkit-details-marker { display: none; }
.ht-receiptfile__summary:hover,
.ht-receiptfile__summary:focus-visible {
	background: var(--ht-ink);
	color: var(--ht-cream-light);
}
.ht-receiptfile__preview {
	display: block;
	max-width: 100%;
	height: auto;
	margin-top: 16px;
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
}
.ht-receiptfile__open {
	display: inline-block;
	margin-top: 16px;
	font-weight: 700;
	font-size: 13.5px;
}

.ht-depositcard { background: var(--ht-cream-warm); }
.ht-depositcard__reconcile {
	margin: 16px 0 0;
	font-size: 13.5px;
	line-height: 1.7;
	color: var(--ht-body);
}

/*
 * .ht-deposit is a bordered box of its own elsewhere (the checkout page's
 * payment method block). Inside the confirmation card it is already framed,
 * so it drops its own frame rather than nesting two.
 */
.ht-depositcard .ht-deposit {
	border: 0;
	background: none;
	padding: 0;
	border-radius: 0;
}

.ht-deposit__body {
	margin: 0 0 20px;
	font-size: 14.5px;
	line-height: 1.7;
	color: var(--ht-body);
}

/*
 * The two quiet disclosures the confirmation page uses once a receipt is in:
 * the account details, folded away because a live "STEP 1 — TRANSFER $x"
 * heading over "we have your receipt" is a stale instruction; and replacing
 * the receipt, demoted because leaving the upload form open is what made
 * re-uploading look like the obvious next move.
 */
.ht-deposit__fold { margin-top: 0; }
.ht-deposit__step + .ht-deposit__fold { margin-top: 30px; padding-top: 30px; }
.ht-deposit__replace { margin-top: 4px; }

.ht-deposit__foldsummary {
	display: flex;
	align-items: center;
	gap: 9px;
	width: fit-content;
	cursor: pointer;
	list-style: none;
	font-size: 13.5px;
	font-weight: 700;
	color: var(--ht-muted);
	padding: 4px 0;
}
.ht-deposit__foldsummary::-webkit-details-marker { display: none; }
.ht-deposit__foldsummary::before {
	content: '';
	flex: none;
	width: 7px;
	height: 7px;
	border-right: 1.6px solid currentColor;
	border-bottom: 1.6px solid currentColor;
	transform: rotate(-45deg);
	transition: transform 0.15s ease;
}
.ht-deposit__fold[open] > .ht-deposit__foldsummary::before { transform: rotate(45deg); }
.ht-deposit__foldsummary:hover { color: var(--ht-crimson); }
.ht-deposit__foldsummary:focus-visible { outline: 2px solid var(--ht-gold); outline-offset: 3px; }
.ht-deposit__fold > .ht-bankrows,
.ht-deposit__fold > .ht-drop { margin-top: 16px; }

.ht-deposit__contact {
	margin: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
}
.ht-deposit__contact .ht-btn { flex: none; }

.ht-deposit__next {
	margin: 0;
	padding: 18px 20px;
	background: var(--ht-cream-rose);
	border-left: 3px solid var(--ht-crimson);
	border-radius: 2px;
	font-size: 14px;
	line-height: 1.7;
	color: var(--ht-body);
}
.ht-deposit__step + .ht-deposit__next,
.ht-deposit__fold + .ht-deposit__next { margin-top: 30px; }

/* Narrow rules go after the wide ones: media queries add no specificity. */

@media (max-width: 900px) {
	.ht-cartpage { grid-template-columns: minmax(0, 1fr); gap: 40px; padding-block: 40px 16px; }
	.ht-cartpage__aside { position: static; top: auto; }

	.ht-shophead--cart .ht-shophead__inner { align-items: flex-start; }

	.ht-crosssell ul.products.ht-grid,
	.woocommerce .ht-crosssell ul.products.ht-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.ht-bankrows { grid-template-columns: minmax(0, 1fr); }
	.ht-drop__fields { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 560px) {
	.ht-cartline {
		grid-template-columns: 72px 1fr;
		gap: 14px;
		padding: 18px;
	}
	.ht-cartline__money {
		grid-column: 1 / -1;
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
		gap: 8px;
		margin-top: 4px;
	}

	.ht-cartline__actions { gap: 12px; }

	.ht-cartempty { padding-block: 56px 64px; }
	.ht-cartempty__card { padding: 40px 24px; }

	.ht-crosssell ul.products.ht-grid,
	.woocommerce .ht-crosssell ul.products.ht-grid {
		grid-template-columns: minmax(0, 1fr);
	}

	/*
	 * The row's description is long enough that squeezing it beside a
	 * fixed-width dot and AVAILABLE/COMING SOON tag leaves almost no room for
	 * text — every word wraps and the row balloons in height. Stacking the
	 * three pieces gives the description the full row width instead.
	 */
	/* .ht-paymethods__row / __dot (PLURAL "paymethods") are the removed Task 6
	   read-only stand-in's classes, kept as recorded dead CSS. Not to be
	   confused with the live .ht-paymethod__dot below — different element,
	   different rule, one letter apart. */
	.ht-paymethods__row { flex-direction: column; align-items: flex-start; gap: 10px; }
	.ht-paymethods__dot { display: none; }

	/* The comp's two-column field grid (full name/email, phone/country)
	   collapses to one column once there is no room for two. */
	.woocommerce-billing-fields__field-wrapper,
	.woocommerce-shipping-fields__field-wrapper {
		grid-template-columns: minmax(0, 1fr);
	}

	/* Same reasoning as .ht-paymethods__row above: at this width, dot +
	   title/note + pill in one row leaves the title too little room and
	   every word wraps. Stacking the four gives the note the full row. The
	   dot stays visible, in the same place on both rows — it is the thing
	   that says which method is selected, and dropping it at narrow widths
	   would leave only the AVAILABLE / COMING SOON pills to carry that. */
	.ht-paymethod { flex-direction: column; align-items: flex-start; gap: 10px; }
	.ht-paymethod__fields { margin-top: 0; }

	/*
	 * At its desktop size CART / PAYMENT / CONFIRMED runs ~470px wide — wider
	 * than the phones it needs to fit on. Left alone it doesn't wrap (the list
	 * has no wrap of its own to fall back to), so it just pushed the whole
	 * document wider than the viewport, which is also what made the off-canvas
	 * drawer look like it was the thing overflowing: a fixed element's `right:
	 * 0` is resolved against that same too-wide layout viewport, not the
	 * screen, so it drifted right along with it. Shrinking the indicator
	 * itself removes the overflow at its source.
	 */
	.ht-steps { font-size: 10px; letter-spacing: 0.08em; }
	.ht-steps__item { gap: 5px; }
	.ht-steps__num { width: 18px; height: 18px; font-size: 9.5px; }
	.ht-steps__item + .ht-steps__item::before { width: 18px; margin: 0 8px; }

	.ht-deposit { padding: 20px; }
	.ht-deposit__step + .ht-deposit__step,
	.ht-deposit__step + .ht-deposit__fold { margin-top: 24px; padding-top: 24px; }
	.ht-receiptrecap { grid-template-columns: minmax(0, 1fr); }
	.ht-drop__zone { padding: 28px 18px; }
}

/* ==========================================================================
   Toasts — #ht-toasts (ht_toasts_region(), inc/notices.php) is what every
   WooCommerce notice renders into now, in place of the framework's own
   full-width, blue-bordered banner. Printed once in the footer, same as the
   cart drawer, so it exists — and its markup is real, visible HTML with no
   JavaScript required — on every front-end page; see that file's own
   docblock for the reasoning. assets/js/toast.js only adds auto-dismiss,
   hover/focus pause and the manual close button on top.

   NOT .ht-notice: that class already belongs to the deposit page's inline
   message block (inc/checkout.php) and is a different component — a static
   block in normal flow, not a floating, stacking, dismissible toast.

   Placement: fixed, upper-right, clear of the sticky nav bar — 96px is the
   same offset .ht-cartpage__aside already uses to clear that same header
   (cart/cart-totals.php's aside), so a toast settles exactly where a shopper
   who has scrolled the cart page already expects fixed chrome to start.
   Narrow layout below switches to a full-width band instead of a right-hand
   stack, so it never sits over a control lower on a short viewport.
   ========================================================================== */

.ht-toasts {
	position: fixed;
	top: 96px;
	right: 24px;
	z-index: 100; /* above the cart drawer panel (90) and its scrim (80) */
	display: flex;
	flex-direction: column;
	gap: 10px;
	width: min(380px, calc(100vw - 48px));
	/* The stack itself has no hit area — only a toast lets its own controls
	   through — so an empty region, or the gaps between toasts, never blocks
	   a click on whatever is underneath it. */
	pointer-events: none;
}
.ht-toasts:empty { display: none; }

.ht-toast {
	display: flex;
	align-items: flex-start;
	gap: 12px;
	width: 100%;
	box-sizing: border-box;
	padding: 14px 16px;
	border-radius: var(--ht-radius);
	border: 1px solid var(--ht-border);
	border-left: 3px solid var(--ht-ink);
	background: var(--ht-cream-light);
	box-shadow: 0 10px 30px rgba(36, 30, 23, 0.14);
	font-family: var(--ht-font-body);
	pointer-events: auto;
}

/* Shape carries the type first (ht_toast_icon(), inc/notices.php — a check,
   a triangle, a circled "i"); colour is the second, reinforcing cue, not
   the only one. */
.ht-toast--success { border-left-color: #1fa855; background: #f3faf5; }
.ht-toast--error   { border-left-color: var(--ht-crimson); background: var(--ht-cream-rose); }

.ht-toast__icon { flex: none; margin-top: 1px; color: var(--ht-ink); }
.ht-toast--success .ht-toast__icon { color: #1fa855; }
.ht-toast--error   .ht-toast__icon { color: var(--ht-crimson); }

.ht-toast__text {
	flex: 1;
	margin: 0;
	font-size: 14px;
	line-height: 1.55;
	color: var(--ht-ink);
}
.ht-toast__text a { color: inherit; font-weight: 700; text-decoration: underline; text-underline-offset: 2px; }
.ht-toast__text a:hover { color: var(--ht-crimson); }

.ht-toast__close {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	margin: -4px -4px 0 0;
	border: none;
	border-radius: 99px;
	background: none;
	color: var(--ht-stone);
	cursor: pointer;
}
.ht-toast__close:hover,
.ht-toast__close:focus-visible { color: var(--ht-ink); background: var(--ht-border); }

@media (max-width: 560px) {
	.ht-toasts {
		/* Clears the announcement bar + logo row (~111px measured at 390px
		   wide — .ht-header-nav has not stuck yet on a fresh load, so the
		   full unstuck header is what a toast has to clear here). */
		top: 120px;
		right: 12px;
		left: 12px;
		width: auto;
	}
}

@media (prefers-reduced-motion: reduce) {
	/* assets/js/toast.js already skips element.animate() entirely under
	   this query — this is the belt-and-suspenders CSS half, in case a
	   toast is ever given a transition directly instead of a WAAPI
	   animation in the future. */
	.ht-toast { transition: none; }
}

/* --- order confirmation: body grid --- */

.ht-confirm {
	display: grid;
	grid-template-columns: 1.55fr 1fr;
	gap: 48px;
	align-items: start;
	padding-top: 52px;
	padding-bottom: 24px;
}
.ht-confirm__main {
	display: flex;
	flex-direction: column;
	gap: 34px;
	min-width: 0;
}
.ht-confirm__aside {
	position: sticky;
	top: 96px;
	display: flex;
	flex-direction: column;
	gap: 18px;
	min-width: 0;
}
.ht-confirm__extras:empty { display: none; }

/*
 * One card shape for every section on this page. The comp gives all of them
 * the same 1px border on all four sides — no side-tab accents anywhere.
 */
.ht-card {
	background: var(--ht-surface);
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
	padding: 26px;
}
.ht-card__heading {
	margin: 0 0 24px;
	font-family: var(--ht-font-body);
	font-size: 12px;
	font-weight: 800;
	letter-spacing: 0.16em;
	color: var(--ht-stone);
}

/* --- order confirmation: meta card --- */

.ht-metacard {
	background: var(--ht-surface);
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
	padding: 26px;
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 20px 24px;
}
.ht-metacard__cell { display: flex; flex-direction: column; gap: 5px; }
.ht-metacard__label {
	font-size: 11.5px;
	font-weight: 800;
	letter-spacing: 0.12em;
	color: var(--ht-stone);
}
.ht-metacard__value {
	font-size: 15px;
	font-weight: 700;
	color: var(--ht-ink);
}

/* --- order confirmation: status timeline --- */

.ht-track__list {
	list-style: none;
	margin: 0;
	padding: 0;
}
.ht-track__step {
	display: grid;
	grid-template-columns: 34px minmax(0, 1fr);
	gap: 18px;
	position: relative;
	padding-bottom: 22px;
}
.ht-track__step:last-child { padding-bottom: 0; }

/*
 * The connector. Drawn from the mark's own column so it stays aligned
 * whatever the row's height, and stopped on the last step so the track does
 * not trail off into nothing.
 */
.ht-track__step:not(:last-child)::before {
	content: "";
	position: absolute;
	left: 16px;
	top: 40px;
	bottom: 4px;
	width: 1.5px;
	background: var(--ht-border);
}
.ht-track__step--done:not(:last-child)::before { background: var(--ht-crimson); }

.ht-track__mark {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: none;
	width: 34px;
	height: 34px;
	border-radius: 99px;
	border: 1.5px solid var(--ht-border);
	background: var(--ht-cream);
	color: var(--ht-faint);
	font-size: 13px;
	font-weight: 800;
}
.ht-track__step--done .ht-track__mark {
	background: var(--ht-crimson);
	border-color: var(--ht-crimson);
	color: var(--ht-cream-light);
}
/*
 * `active` ("the studio is working, do nothing") and `blocked` ("the studio
 * is waiting on you, act") must not read the same at a glance — the fourth
 * mark exists precisely so a buyer can tell the two apart. Both stay in the
 * crimson family, but `blocked` reads as a demand rather than as progress: a
 * filled crimson mark with a light glyph, against `active`'s outlined one.
 */
.ht-track__step--active .ht-track__mark {
	background: var(--ht-cream-rose);
	border-color: var(--ht-crimson);
	color: var(--ht-crimson);
}
.ht-track__step--blocked .ht-track__mark {
	background: var(--ht-crimson);
	border-color: var(--ht-crimson);
	color: var(--ht-cream-light);
}

.ht-track__body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ht-track__head {
	display: flex;
	align-items: center;
	gap: 10px;
	flex-wrap: wrap;
}
.ht-track__title {
	font-weight: 800;
	font-size: 15.5px;
	color: var(--ht-stone);
}
.ht-track__step--done .ht-track__title,
.ht-track__step--active .ht-track__title,
.ht-track__step--blocked .ht-track__title { color: var(--ht-ink); }

.ht-track__tag {
	font-size: 11.5px;
	font-weight: 800;
	letter-spacing: 0.1em;
	padding: 4px 10px;
	border-radius: 99px;
	background: var(--ht-cream-warm);
	color: var(--ht-stone);
}
.ht-track__step--done .ht-track__tag { background: #f3faf5; color: #1b8a4b; }
.ht-track__step--active .ht-track__tag,
.ht-track__step--blocked .ht-track__tag {
	background: var(--ht-cream-rose);
	color: var(--ht-crimson);
}

.ht-track__copy {
	margin: 0;
	font-size: 14px;
	line-height: 1.6;
	color: var(--ht-muted);
	max-width: 560px;
}

@media (max-width: 980px) {
	.ht-confirm {
		grid-template-columns: minmax(0, 1fr);
		gap: 28px;
		padding-top: 36px;
	}
	.ht-confirm__aside { position: static; top: auto; }
	.ht-metacard { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 520px) {
	.ht-metacard { grid-template-columns: minmax(0, 1fr); }
}

/* --- order confirmation: pieces --- */

.ht-pieces { padding: 0; }
.ht-pieces > .ht-card__heading {
	margin: 0;
	padding: 18px 26px;
	border-bottom: 1px solid var(--ht-border);
}
.ht-pieces__list { list-style: none; margin: 0; padding: 0; }

.ht-piece {
	display: grid;
	grid-template-columns: 88px minmax(0, 1fr) auto;
	gap: 22px;
	align-items: center;
	padding: 24px 26px;
	border-bottom: 1px solid #f0e9dd;
}
.ht-piece__media {
	display: block;
	border-radius: var(--ht-radius);
	overflow: hidden;
	aspect-ratio: 4 / 5;
	background: var(--ht-canvas);
}
/*
 * Two classes, not one. WooCommerce's own `.woocommerce img { height: auto }`
 * (woocommerce-layout.css) is (0,1,1) and out-specifies a single-class rule —
 * the same trap the cart line and the product gallery both hit.
 */
.ht-piece__media .ht-piece__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.ht-piece__detail { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ht-piece__cat {
	font-size: 11.5px;
	font-weight: 800;
	letter-spacing: 0.12em;
	color: var(--ht-stone);
}
.ht-piece__name {
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: 19px;
	line-height: 1.25;
	color: var(--ht-ink);
}
a.ht-piece__name:hover, a.ht-piece__name:focus { color: var(--ht-crimson); }
.ht-piece__meta {
	display: flex;
	flex-wrap: wrap;
	gap: 4px 8px;
	font-size: 13.5px;
	color: var(--ht-muted);
}
/*
 * Load-bearing, not dead: wc_display_item_meta() (items.php) blanks its own
 * before/after wrapper, but WC_Order_Item::get_formatted_meta_data() already
 * ran display_value through wpautop() before that — the <p> is baked into
 * the value itself, before wc_display_item_meta() ever sees it. Without this
 * rule every variation line in the items card gets a 1em margin under it.
 */
.ht-piece__meta p { margin: 0; }
.ht-piece__total {
	font-weight: 800;
	font-size: 16.5px;
	color: var(--ht-ink);
	white-space: nowrap;
}

.ht-pieces__totals {
	padding: 22px 26px;
	display: flex;
	flex-direction: column;
	gap: 11px;
	font-size: 14.5px;
}
.ht-pieces__row { display: flex; justify-content: space-between; gap: 16px; }
.ht-pieces__label { color: var(--ht-body); }
.ht-pieces__value { font-weight: 700; }
.ht-pieces__row[class*="discount"] .ht-pieces__label,
.ht-pieces__row[class*="discount"] .ht-pieces__value { color: var(--ht-crimson); }

.ht-pieces__grand {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 16px;
	border-top: 1px solid var(--ht-border);
	margin-top: 9px;
	padding-top: 16px;
}
.ht-piece__grandlabel {
	font-family: var(--ht-font-display);
	font-size: 19px;
	font-weight: 500;
}
.ht-piece__grandvalue {
	font-family: var(--ht-font-display);
	font-size: 26px;
	font-weight: 600;
	color: var(--ht-crimson);
}

/* --- order confirmation: shipping and note --- */

.ht-shipcard {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 32px;
}
.ht-shipcard:has(> .ht-shipcard__col:only-child) { grid-template-columns: minmax(0, 1fr); }
.ht-shipcard__col > .ht-card__heading { margin-bottom: 14px; }
.ht-shipcard__address {
	margin: 0;
	font-size: 15px;
	line-height: 1.8;
	color: var(--ht-ink);
	font-weight: 600;
}
.ht-shipcard__phone {
	margin: 12px 0 0;
	font-size: 13.5px;
	color: var(--ht-muted);
}
.ht-shipcard__note {
	margin: 0;
	font-size: 15px;
	line-height: 1.7;
	color: var(--ht-body);
	font-style: italic;
}
.ht-shipcard__note::before { content: "\201C"; }
.ht-shipcard__note::after { content: "\201D"; }

@media (max-width: 680px) {
	.ht-piece { grid-template-columns: 64px minmax(0, 1fr); gap: 16px; }
	.ht-piece__total { grid-column: 2; }
	.ht-shipcard { grid-template-columns: minmax(0, 1fr); gap: 24px; }
}

/* --- order confirmation: aside --- */

.ht-next {
	background: var(--ht-ink);
	color: var(--ht-cream-light);
	border-radius: var(--ht-radius);
	padding: 26px;
}
.ht-next__heading {
	margin: 0 0 18px;
	font-family: var(--ht-font-body);
	font-size: 12px;
	font-weight: 800;
	letter-spacing: 0.16em;
	color: var(--ht-gold);
}
.ht-next__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 18px;
}
.ht-next__step { display: flex; gap: 14px; }
.ht-next__num {
	flex: none;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 26px;
	height: 26px;
	border-radius: 99px;
	border: 1.5px solid rgba(233, 200, 126, 0.55);
	color: var(--ht-gold);
	font-size: 12px;
	font-weight: 800;
}
.ht-next__body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ht-next__title { font-weight: 800; font-size: 14.5px; color: var(--ht-cream-light); }
.ht-next__copy { font-size: 13.5px; line-height: 1.6; color: rgba(253, 249, 242, 0.7); }
.ht-next__note {
	margin: 22px 0 0;
	padding-top: 18px;
	border-top: 1px solid rgba(253, 249, 242, 0.12);
	font-size: 13px;
	line-height: 1.6;
	color: rgba(253, 249, 242, 0.65);
}

.ht-keep { display: flex; flex-direction: column; gap: 10px; padding: 22px; }
.ht-keep__title { font-weight: 800; font-size: 14.5px; color: var(--ht-ink); }
.ht-keep__body { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--ht-muted); }
.ht-keep__actions {
	display: flex;
	flex-direction: column;
	gap: 9px;
	margin-top: 6px;
}
.ht-keep__actions .ht-btn { text-align: center; }

.ht-badges--aside {
	background: var(--ht-cream-warm);
	padding: 20px 22px;
	gap: 14px;
}

.ht-change { display: flex; flex-direction: column; gap: 8px; padding: 20px 22px; background: none; }
.ht-change__title { font-weight: 800; font-size: 13.5px; color: var(--ht-ink); }
.ht-change__body { margin: 0; font-size: 13px; line-height: 1.6; color: var(--ht-muted); }
.ht-change__link { font-size: 13.5px; font-weight: 700; }

/* ==========================================================================
   Our Story
   Built to Heritage Thangka website/About.dc.html. The comp's Numbers band is
   not implemented — see page-our-story.php for why.
   ========================================================================== */

/*
 * Our Story opens on a full-bleed dark hero and closes on the full-bleed Visit
 * band, the same shape as the homepage and the catalog pages — so the wrapper
 * contributes no padding and the footer drops its top margin. Without this the
 * 64px + 96px stack leaves a strip of cream above the hero and another below
 * the Visit band. Keyed on the page-template body class rather than the slug,
 * so renaming the page cannot break it.
 */
.page-template-page-our-story .ht-main { padding-block: 0; }
.page-template-page-our-story .ht-site-footer { margin-top: 0; }

.ht-storyhero {
	background: var(--ht-ink);
	color: var(--ht-cream-light);
}
.ht-storyhero__inner {
	padding-block: 80px;
	max-width: 780px;
}
.ht-storyhero__eyebrow {
	margin: 0 0 14px;
	font-size: 12.5px;
	font-weight: 800;
	letter-spacing: 0.24em;
	color: var(--ht-gold);
}
.ht-storyhero__title {
	margin: 0 0 18px;
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: 46px;
	line-height: 1.12;
	text-wrap: balance;
}
.ht-storyhero__lede {
	margin: 0;
	font-size: 17px;
	line-height: 1.7;
	color: rgba(253, 249, 242, 0.78);
	max-width: 60ch;
}

/*
 * One placeholder shape for every empty image slot on this page, following
 * .ht-artist__placeholder's convention so a page with some photos and some
 * gaps still reads as one thing.
 */
.ht-imgplaceholder {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--ht-canvas);
	font-size: 12.5px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--ht-muted);
	text-align: center;
	padding: 12px;
}

/* Hero photograph, when there is one: a dimmed bed for the type. */
.ht-storyhero--photo { position: relative; isolation: isolate; }
.ht-storyhero__media {
	position: absolute;
	inset: 0;
	z-index: -1;
	overflow: hidden;
}
.ht-storyhero__media::after {
	content: "";
	position: absolute;
	inset: 0;
	background: rgba(36, 30, 23, 0.72);
}
.ht-storyhero__media .ht-storyhero__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.ht-storybody__inner { padding-block: 72px; }
.ht-storybody__inner--split {
	display: grid;
	grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
	gap: 56px;
	align-items: start;
}
.ht-storybody__media {
	position: relative;
	margin: 0;
	aspect-ratio: 4 / 5;
	border-radius: var(--ht-radius);
	overflow: hidden;
	background: var(--ht-canvas);
}
.ht-storybody__media .ht-storybody__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/* --- our story: studio details --- */

.ht-storygrid__inner { padding-block: 0 72px; }
.ht-storygrid__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 16px;
}
.ht-storygrid__item {
	position: relative;
	aspect-ratio: 1 / 1;
	border-radius: var(--ht-radius);
	overflow: hidden;
	background: var(--ht-canvas);
}
.ht-storygrid__item .ht-storygrid__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.ht-storygrid__prompt {
	margin: 16px 0 0;
	font-size: 13.5px;
	color: var(--ht-muted);
}

/*
 * The story is the page's own content, written in WordPress. Measure is capped
 * in characters rather than pixels so it stays readable whatever the type
 * scale does.
 */
.ht-prose {
	max-width: 68ch;
	font-size: 17px;
	line-height: 1.8;
	color: var(--ht-body);
}
.ht-prose > * + * { margin-top: 1.4em; }
.ht-prose h2 {
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: 30px;
	line-height: 1.2;
	color: var(--ht-ink);
	margin-top: 2em;
}
.ht-prose h3 {
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: 22px;
	color: var(--ht-ink);
	margin-top: 1.8em;
}
.ht-prose strong { color: var(--ht-ink); }

/* --- our story: numbers --- */

.ht-numbers { background: var(--ht-cream-warm); border-bottom: 1px solid var(--ht-border); }
.ht-numbers__inner { padding-block: 56px; }
.ht-numbers__list {
	margin: 0;
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 32px 40px;
}
.ht-number { min-width: 0; }
.ht-number__value {
	margin: 0 0 6px;
	font-family: var(--ht-font-display);
	font-size: 42px;
	font-weight: 600;
	line-height: 1;
	color: var(--ht-crimson);
}
.ht-number__label {
	font-size: 12.5px;
	font-weight: 800;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--ht-ink);
}
.ht-number__note {
	margin: 6px 0 0;
	font-size: 13.5px;
	line-height: 1.6;
	color: var(--ht-muted);
}
.ht-number__note > :first-child { margin-top: 0; }
.ht-number__note > :last-child { margin-bottom: 0; }
.ht-numbers__prompt {
	margin: 0;
	font-size: 13.5px;
	line-height: 1.7;
	color: var(--ht-muted);
	max-width: 70ch;
}

/* --- our story: process --- */

.ht-process { background: var(--ht-cream-warm); border-block: 1px solid var(--ht-border); }
.ht-process__inner { padding-block: 72px; }
.ht-process__eyebrow {
	margin: 0 0 12px;
	font-size: 12.5px;
	font-weight: 800;
	letter-spacing: 0.24em;
	color: var(--ht-crimson);
}
.ht-process__title {
	margin: 0 0 40px;
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: 32px;
	line-height: 1.2;
}
.ht-process__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 36px 40px;
	counter-reset: none;
}
.ht-process__step { min-width: 0; }
.ht-process__num {
	display: block;
	margin-bottom: 10px;
	font-family: var(--ht-font-display);
	font-size: 26px;
	font-weight: 600;
	color: var(--ht-gold);
}
.ht-process__steptitle {
	margin: 0 0 8px;
	font-size: 17px;
	font-weight: 800;
	color: var(--ht-ink);
}
.ht-process__stepbody > :first-child { margin-top: 0; }
.ht-process__stepbody > :last-child { margin-bottom: 0; }
.ht-principle__body > :first-child,
.ht-storyhero__lede > :first-child,
.ht-visit__body > :first-child { margin-top: 0; }
.ht-principle__body > :last-child,
.ht-storyhero__lede > :last-child,
.ht-visit__body > :last-child { margin-bottom: 0; }

.ht-process__stepbody {
	margin: 0;
	font-size: 14.5px;
	line-height: 1.7;
	color: var(--ht-muted);
}

/* --- our story: how we work --- */

.ht-principles__inner {
	padding-block: 72px;
	display: grid;
	grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
	gap: 48px;
	align-items: start;
}
.ht-principles__eyebrow {
	margin: 0 0 12px;
	font-size: 12.5px;
	font-weight: 800;
	letter-spacing: 0.24em;
	color: var(--ht-crimson);
}
.ht-principles__title {
	margin: 0;
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: 32px;
	line-height: 1.2;
	text-wrap: balance;
}
.ht-principles__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 28px;
}
.ht-principle__title {
	margin: 0 0 8px;
	font-size: 17px;
	font-weight: 800;
	color: var(--ht-ink);
}
.ht-principle__body {
	margin: 0;
	font-size: 15px;
	line-height: 1.75;
	color: var(--ht-muted);
	max-width: 62ch;
}

/* --- our story: visit --- */

.ht-visit { background: var(--ht-ink); color: var(--ht-cream-light); }
.ht-visit__inner {
	padding-block: 72px;
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	gap: 48px;
	align-items: start;
}
.ht-visit__eyebrow {
	margin: 0 0 12px;
	font-size: 12.5px;
	font-weight: 800;
	letter-spacing: 0.24em;
	color: var(--ht-gold);
}
.ht-visit__title {
	margin: 0 0 16px;
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: 32px;
	line-height: 1.2;
}
.ht-visit__body {
	margin: 0;
	font-size: 15.5px;
	line-height: 1.75;
	color: rgba(253, 249, 242, 0.78);
	max-width: 52ch;
}
.ht-visit__rows { margin: 0; display: flex; flex-direction: column; gap: 22px; }
.ht-visit__row { display: flex; flex-direction: column; gap: 5px; }
.ht-visit__label {
	font-size: 11.5px;
	font-weight: 800;
	letter-spacing: 0.14em;
	color: var(--ht-gold);
}
.ht-visit__value {
	margin: 0;
	font-size: 15.5px;
	line-height: 1.6;
	color: var(--ht-cream-light);
}
.ht-visit__value a { color: var(--ht-cream-light); text-decoration: underline; }
.ht-visit__value a:hover, .ht-visit__value a:focus { color: var(--ht-gold); }

@media (max-width: 900px) {
	.ht-process__list,
	.ht-numbers__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.ht-principles__inner,
	.ht-visit__inner,
	.ht-storybody__inner--split { grid-template-columns: minmax(0, 1fr); gap: 32px; }
	.ht-storybody__media { max-width: 420px; }
	.ht-storygrid__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
	.ht-storyhero__inner { padding-block: 48px; }
	.ht-storyhero__title { font-size: 32px; }
	.ht-storybody__inner,
	.ht-process__inner,
	.ht-principles__inner,
	.ht-visit__inner { padding-block: 48px; }
	.ht-process__list { grid-template-columns: minmax(0, 1fr); gap: 28px; }
	.ht-numbers__inner { padding-block: 40px; }
	.ht-number__value { font-size: 34px; }
	.ht-storygrid__inner { padding-bottom: 48px; }
	.ht-process__title, .ht-principles__title, .ht-visit__title { font-size: 26px; }
	.ht-prose { font-size: 16px; }
}

/* ==========================================================================
   Sign In and Create Account (woocommerce/myaccount/form-login.php)

   The split screen itself (.ht-authscreen and its children) is its own
   block, further down. What's here is the field/form vocabulary shared with
   form-lost-password.php and form-reset-password.php's single-column
   .ht-auth card, which this file leaves untouched — .ht-auth__field,
   .ht-auth__input etc. Card shape borrowed from .ht-verify/.ht-card; field
   shape borrowed from .ht-field-row, renamed ht-auth__field because this
   form also carries the plain checkbox fields those don't.
   ========================================================================== */

.ht-auth {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 40px;
}

.ht-auth__panel {
	background: var(--ht-surface);
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
	padding: 40px;
}

.ht-auth__intro { margin-bottom: 28px; }
.ht-auth__title {
	margin: 0 0 8px;
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: 30px;
	line-height: 1.15;
	color: var(--ht-ink);
}
.ht-auth__subtitle { margin: 0; font-size: 15px; line-height: 1.7; color: var(--ht-body); }

.ht-auth__form { margin: 0; display: flex; flex-direction: column; gap: 20px; }

.ht-auth__grid2 {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 16px;
}
.ht-auth__grid2 .ht-auth__field { margin: 0; }

.ht-auth__field { margin: 0; display: flex; flex-direction: column; gap: 7px; }
.ht-auth__field label {
	font-size: 12.5px;
	font-weight: 800;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--ht-body);
}
.ht-auth__field .required { color: var(--ht-crimson); font-style: normal; }
.ht-auth__optional {
	text-transform: none;
	font-weight: 700;
	letter-spacing: 0.02em;
	color: var(--ht-faint);
}

.ht-auth__input,
.ht-auth__field .input-text {
	box-sizing: border-box;
	width: 100%;
	border: 1.5px solid var(--ht-border);
	border-radius: var(--ht-radius);
	background: var(--ht-cream-light);
	padding: 14px 16px;
	font-family: var(--ht-font-body);
	font-size: 15px;
	font-weight: 500;
	color: var(--ht-ink);
	outline: none;
}
.ht-auth__input:focus,
.ht-auth__field .input-text:focus { border-color: var(--ht-crimson); }

.ht-auth__hint { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--ht-muted); }

.ht-auth__row {
	margin: 0;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	flex-wrap: wrap;
}
.ht-auth__remember {
	display: flex;
	align-items: center;
	gap: 10px;
	font-size: 14px;
	font-weight: 600;
	color: var(--ht-body);
}
.ht-auth__forgot { font-size: 14px; font-weight: 700; color: var(--ht-crimson); }
.ht-auth__forgot:hover { color: var(--ht-crimson-dark); }

.ht-auth__field--check label {
	display: flex;
	align-items: flex-start;
	gap: 11px;
	font-size: 13.5px;
	font-weight: 600;
	text-transform: none;
	letter-spacing: 0;
	line-height: 1.6;
	color: var(--ht-body);
}
.ht-auth__field--check input[type="checkbox"] { flex: none; margin-top: 3px; }
.ht-auth__field--check a { font-weight: 700; color: var(--ht-crimson); }
.ht-auth__field--check a:hover { color: var(--ht-crimson-dark); }

.ht-auth__submit { width: 100%; text-align: center; border: none; cursor: pointer; }

.ht-auth__switch {
	margin: 0;
	font-size: 14px;
	line-height: 1.7;
	color: var(--ht-muted);
}
.ht-auth__switch a { font-weight: 700; color: var(--ht-crimson); }
.ht-auth__switch a:hover { color: var(--ht-crimson-dark); }

/*
 * The one-line pointer to /track-order/ (page-track-order.php), below both
 * sign-in and register tabs on the split screen (and, in the no-JS/no-tabs
 * single-panel state, below whichever form is unavailable). Replaces what
 * used to be the guest order lookup form itself, which lived here and has
 * moved to its own page; this keeps only the border-top divider that form's
 * own .ht-auth__lookup wrapper used, so the visual separation survives even
 * though the block it used to separate did not.
 */
.ht-auth__trackorder {
	padding-top: 26px;
	border-top: 1px solid var(--ht-border);
}

.ht-auth__input--mono { font-family: ui-monospace, Menlo, monospace; letter-spacing: 0.02em; }

/*
 * Password reset (woocommerce/myaccount/form-lost-password.php,
 * form-reset-password.php) and the Track your order page
 * (page-track-order.php). Same .ht-auth panel as sign in, single column
 * rather than split. .ht-auth__contact carries the lost-password page's and
 * the track-order page's WhatsApp-or-contact-page offer -- shape borrowed
 * from .ht-deposit__contact, the same pairing used on the deposit-mismatch
 * screen.
 *
 * .ht-auth__panel--track-order caps and centres the card rather than
 * leaving it to stretch across the full container the way the single-column
 * card otherwise would (see .ht-auth__panel--lost-password, which carries no
 * override at all) -- a form this short reads best at a card's width, not a
 * container's, and this page has no comp of its own to match instead.
 */
.ht-auth__contact {
	margin: 16px 0 0;
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
}
.ht-auth__contact .ht-btn { flex: none; }

.ht-auth__panel--track-order {
	max-width: 560px;
	margin-inline: auto;
}

@media (max-width: 520px) {
	.ht-auth__panel { padding: 28px; }
	.ht-auth__title { font-size: 25px; }
	.ht-auth__grid2 { grid-template-columns: minmax(0, 1fr); }
}

/* ==========================================================================
   Sign In split screen (woocommerce/myaccount/form-login.php)

   grid-template-columns: 1fr 1fr, full height, matching the comp exactly:
   a form column (max-width 440px, centred in its half) on the left, a dark
   full-bleed image panel on the right.

   FULL BLEED WITHOUT 100vw. .ht-authscreen used to break out of page.php's
   .ht-container with width:100vw + a negative margin (the same trick
   .ht-account__hero, further down, used too, until the identical bug
   turned up there and got the identical fix — see that block's own
   docblock). 100vw measures the whole viewport including the vertical
   scrollbar's own width, which the scrollbar then doesn't leave room for
   -- every page tall enough to
   scroll got a horizontal scrollbar too, permanently, confirmed by
   measuring documentElement.scrollWidth > clientWidth. Fixed instead by
   lifting the width constraint off the ancestor .ht-container itself, for
   this screen only (the ".ht-signin-screen .ht-main .ht-container" rule
   below): with nothing capping its width, .ht-authscreen's own 100% simply
   fills whatever the real, scrollbar-aware viewport leaves available, so
   there is no vw arithmetic left to get wrong.

   "Full height" is the .ht-signin-screen chain just below this block: a
   body class scoped to exactly the logged-out sign-in view
   (ht_is_signin_screen(), inc/account.php) turns <body> into a flex column
   and hands flex:1 down through every ancestor between it and
   #customer_login, so .ht-authscreen fills whatever space is left between
   the header and the footer instead of sizing to its own content. The same
   chain rule that hands down flex:1 also strips .ht-container's max-width,
   inline padding AND inline margin, which is what makes the full-bleed
   width above work -- the margin has to go too, not just the max-width:
   .ht-container's own base rule sets margin-inline: auto, and a flex item
   with an auto margin on its cross axis has that margin soak up all the
   free space instead of stretching (the same "auto margins win over
   align-items" behaviour flexbox uses to centre a lone item) -- confirmed
   in-browser: dropping max-width alone left .ht-container shrunk to its
   content's width and centred, not full width, until margin-inline: 0
   joined it.

   The chain deliberately reads ".ht-main .ht-container", not the bare
   ".ht-container" .ht-main sits inside on this page (page.php wraps
   the_content() in one). .ht-container is a site-wide layout utility, also
   used by header.php's two rows and footer.php's column wrap -- both are
   siblings of #ht-content.ht-main, not descendants of it, but are still
   descendants of body.ht-signin-screen. Scoping this chain to that bare
   utility class directly off .ht-signin-screen would reach them too and
   force the header's row-1 flex (brand left, actions right) into a column,
   stacking and centring it, AND strip their max-width, blowing both rows
   full-bleed. Every selector in this chain must stay provably confined to
   #ht-content's own subtree for that reason.

   .ht-auth__block replaces .ht-auth__panel for the two forms here — no card
   border/background, since the comp draws the form column on plain ground,
   not a boxed panel; .ht-auth__intro/__title/__subtitle/__form/__field/etc.
   (above) are reused unchanged inside it.

   TABS. .ht-authtabs__tab and every cross-link ("New here?" / "Already have
   an account?") are real <a href="#ht-auth-signin|register"> elements, not
   buttons — with JavaScript off or broken they just jump to an anchor that
   is already visible, because .ht-auth__block is never hidden by CSS: only
   assets/js/account-auth.js hides the inactive one, by setting its `hidden`
   IDL property once it has loaded and run. There is deliberately no rule
   here for `[hidden]` — the browser's own UA stylesheet already treats it
   as display:none, and adding one back in CSS would be one more place a
   panel could be hidden without JavaScript's involvement.
   ========================================================================== */

.ht-signin-screen {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
}
.ht-signin-screen .ht-main,
.ht-signin-screen .ht-main .ht-container,
.ht-signin-screen .ht-entry,
.ht-signin-screen .ht-entry__content,
.ht-signin-screen .woocommerce {
	display: flex;
	flex-direction: column;
	flex: 1;
}
.ht-signin-screen .ht-main { padding-block: 0; min-height: 0; }
.ht-signin-screen .ht-site-footer { margin-top: 0; }

/*
 * Lifts .ht-container's own max-width/gutter for this screen only, so
 * .ht-authscreen (its great-grandchild, through .ht-entry and
 * .ht-entry__content) can fill the real viewport width with no width:100vw
 * breakout needed at all -- see the block comment above.
 */
.ht-signin-screen .ht-main .ht-container {
	max-width: none;
	margin-inline: 0;
	padding-inline: 0;
}

.ht-authscreen {
	flex: 1;
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	align-items: stretch;
}

.ht-authscreen__form {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 72px var(--ht-gutter);
}

.ht-authscreen__inner {
	width: 100%;
	max-width: 440px;
	display: flex;
	flex-direction: column;
	gap: 40px;
}

.ht-auth__block { display: flex; flex-direction: column; }
/*
 * assets/js/account-auth.js hides the inactive panel by setting `hidden` —
 * never `.style` — trusting the browser's own UA stylesheet to turn that
 * into display:none. It doesn't: author rules always win over UA defaults
 * regardless of selector specificity, so .ht-auth__block's own
 * display:flex above silently overrode it, leaving a "hidden" panel fully
 * visible. This restates the browser's default explicitly, in the author
 * sheet, so it can no longer lose to anything declared above it.
 */
.ht-auth__block[hidden] { display: none; }

/*
 * WooCommerce's own core stylesheet (woocommerce.css) draws
 * "form.checkout_coupon, form.login, form.register" as a bordered card --
 * border, padding, margin, radius -- a leftover panel treatment from
 * before this template's fields sat bare on the comp's cream ground. Undo
 * it here, scoped to this screen: the checkout page's "Returning
 * customer?" login form (see .ht-checkout-login above) still wants that
 * card look, so this must not reach it. .ht-signin-screen .woocommerce
 * form.login/.register beats WooCommerce's own ".woocommerce form.login"
 * on class count (3 vs 2) regardless of stylesheet load order.
 */
.ht-signin-screen .woocommerce form.login,
.ht-signin-screen .woocommerce form.register {
	margin: 0;
	padding: 0;
	border: none;
	border-radius: 0;
}

/* --- tabs --- */

.ht-authtabs {
	display: flex;
	border-bottom: 1px solid var(--ht-border);
}
.ht-authtabs__tab {
	flex: 1;
	display: block;
	padding: 0 0 16px;
	font-family: var(--ht-font-display);
	font-size: 19px;
	font-weight: 500;
	color: var(--ht-stone);
	border-bottom: 2.5px solid transparent;
	margin-bottom: -1px;
}
.ht-authtabs__tab:hover { color: var(--ht-ink); }
.ht-authtabs__tab.is-active {
	color: var(--ht-ink);
	border-bottom-color: var(--ht-crimson);
}

/* --- password show/hide (sign-in field only, per the comp) --- */

.ht-pwfield {
	display: flex;
	align-items: center;
	border: 1.5px solid var(--ht-border);
	border-radius: var(--ht-radius);
	background: var(--ht-cream-light);
}
.ht-pwfield:focus-within { border-color: var(--ht-crimson); }
.ht-pwfield .ht-auth__input {
	flex: 1;
	min-width: 0;
	border: none;
	border-radius: 0;
	background: transparent;
}
.ht-pwfield__toggle {
	flex: none;
	border: none;
	background: none;
	padding: 0 16px;
	font-family: var(--ht-font-body);
	font-size: 13px;
	font-weight: 700;
	color: var(--ht-muted);
	cursor: pointer;
}
.ht-pwfield__toggle:hover { color: var(--ht-crimson); }

/*
 * WooCommerce's own frontend script (woocommerce.js -- the main 'woocommerce'
 * handle, the same bundle that also drives other behaviour this page and
 * others depend on, so it is never dequeued; see checkout/form-login.php's
 * own docblock for the same call made once already about checkout.js) wraps
 * EVERY ".woocommerce-Input[type=password]" on this form -- both the
 * sign-in password field and the register one -- in its own
 * <span class="password-input"> at runtime, and appends its own eye-icon
 * toggle (.show-password-input) inside it. Two consequences, both handled
 * here with CSS alone:
 *
 * 1. THE SIGN-IN FIELD'S WIDTH. Before that script runs, #password is a
 *    direct child of .ht-pwfield and ".ht-pwfield .ht-auth__input { flex: 1
 *    }" above sizes it correctly. Once the script wraps it, that rule no
 *    longer reaches anything: #password now sits inside .password-input,
 *    which is the actual flex child of .ht-pwfield, and which carries no
 *    flex value of its own -- so it renders at its intrinsic width (a bare
 *    <input>'s UA-default ~20-character size, ~240px) instead of
 *    stretching, and .ht-pwfield__toggle lands wherever that width happens
 *    to end rather than at .ht-pwfield's own right edge. Measured: a 440px
 *    field with the wrapper stopping at 240px and the toggle's right edge
 *    133px short of the border. Giving the WRAPPER the same flex: 1 fixes
 *    it whether or not the script ever runs -- with no script, .password-
 *    input simply never exists and the rule matches nothing.
 *
 * 2. TWO CONTROLS. WooCommerce's injected button duplicates the comp's own
 *    text toggle on the sign-in field ("Sign In.dc.html" draws one plain
 *    "Show"/"Hide" control, not an icon), and it also appears on the
 *    register field, which the comp gives no toggle at all. Adopting
 *    WooCommerce's icon instead of ours was considered and rejected:
 *    account-auth.js already drives ours with the exact aria-pressed state
 *    and Show/Hide strings this markup carries, and the comp's control is
 *    text, not an icon. Suppressing WooCommerce's is the smaller change,
 *    and it costs nothing -- the script that renders it keeps running (see
 *    above), the button just never becomes visible. display:none is safe
 *    here with no !important: WooCommerce's own click handler only ever
 *    toggles a class and an aria-label on this button, never an inline
 *    style, so there is no competing write to outrank the way
 *    .woocommerce-password-strength (below) has to sidestep one. A
 *    display:none button also drops out of the tab order, so it cannot be
 *    reached as a second control by keyboard either. The padding-right
 *    WooCommerce's own CSS reserves on the input for that icon is reset
 *    alongside it, on both fields, so removing the icon doesn't leave
 *    lopsided padding behind on the visible one.
 */
.ht-pwfield .password-input {
	flex: 1;
	min-width: 0;
}
.ht-signin-screen .show-password-input {
	display: none;
}
.ht-signin-screen .ht-authscreen .password-input input[type="password"] {
	padding-right: 16px;
}

/* --- password strength (register form only) --- */

.ht-strength { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.ht-strength__bars { display: flex; gap: 6px; }
.ht-strength__bar { flex: 1; height: 4px; border-radius: 99px; background: var(--ht-border); display: block; }
.ht-strength__bar.is-filled { background: var(--ht-crimson); }
.ht-strength.is-fair .ht-strength__bar.is-filled { background: var(--ht-muted); }
.ht-strength.is-good .ht-strength__bar.is-filled,
.ht-strength.is-strong .ht-strength__bar.is-filled { background: var(--ht-ink); }

.ht-strength__label { font-size: 12.5px; font-weight: 700; color: var(--ht-stone); }
.ht-strength.is-weak .ht-strength__label { color: var(--ht-crimson); }
.ht-strength.is-fair .ht-strength__label,
.ht-strength.is-good .ht-strength__label,
.ht-strength.is-strong .ht-strength__label { color: var(--ht-body); }

/*
 * WooCommerce enqueues its OWN password strength meter on this exact page,
 * independently of anything above (class-wc-frontend-scripts.php: any
 * account page, generated passwords off, logged out) — it is what disables
 * the "Create account" button below the minimum strength
 * (woocommerce_min_password_strength), not decoration, so it must keep
 * running. Its default UI (a plain green/red banner, #password_strength)
 * is what .ht-strength above replaces; left alone the two would stack.
 *
 * display:none won't do it: that script's own includeMeter() re-shows the
 * element with jQuery's show(), which (since the only thing hiding it would
 * be an external rule, not an inline style) writes a competing INLINE
 * display back on every keystroke once the field has been through an empty
 * state, and this stylesheet carries no !important anywhere to outrank
 * that (tests/test-checkout-templates.php enforces it site-wide). jQuery's
 * show()/hide() only ever touch `display`, never `visibility`, so keying
 * off visibility instead sidesteps the fight entirely — nothing here is
 * fighting WooCommerce's own script, it just never touches the property
 * this rule uses. checkPasswordStrength() (WooCommerce core) still reads
 * jQuery's `:hidden`, which visibility:hidden satisfies exactly like
 * display:none does, so the strength check and the submit-button gate stay
 * intact; position:absolute keeps the invisible box out of the layout flow
 * so it cannot open a gap next to the password field.
 */
.ht-authscreen .woocommerce-password-strength { position: absolute; visibility: hidden; }

/* --- the dark art panel --- */

/*
 * Base text colour + vertical centring for the panel's copy.
 *
 * COLOUR: this panel only ever set `background: var(--ht-ink)`, never a
 * `color`, so anything printed inside it without its own colour inherited
 * `--ht-body` -- dark brown, ~1.7:1 against near-black, invisible. Every
 * child here happened to set its own light colour already, which is
 * exactly the trap: the next paragraph or hook output dropped into this
 * panel with no colour of its own would silently vanish the same way.
 * Setting the base colour once, here, means every descendant is readable
 * by default instead of opting in one at a time. `.ht-authscreen__art-
 * eyebrow` (gold) and `.ht-authscreen__reason-text` (cream, same value as
 * this base) keep their own declarations unchanged.
 *
 * POSITION: `.ht-authscreen__art-copy` used to be `position: absolute`,
 * pinned to this panel's bottom, matching the comp. But this column's
 * height is driven by whichever sibling form is taller -- 1201px with
 * "Create account" open in a 900px-tall viewport -- so an absolute,
 * bottom-anchored block sat ~780px down and was never on screen; the
 * panel read as an empty dark slab. `position: sticky` was tried first
 * (tracking scroll while still reading as bottom-anchored, closer to the
 * comp's composition) but this element is a CSS Grid item in
 * `.ht-authscreen`, and confirmed by measuring in-browser -- scrolling
 * from 0 to 800px moved the copy block 1:1 with the page the entire way,
 * never once pinning -- so it was dropped rather than shipped unverified.
 * Centring the copy vertically in the flex column below is simple,
 * guaranteed correct at any column height, and keeps the top of the copy
 * on screen at any reasonable viewport height.
 */
.ht-authscreen__art {
	position: relative;
	overflow: hidden;
	background: var(--ht-ink);
	color: var(--ht-cream-light);
	min-height: 640px;
	display: flex;
	flex-direction: column;
	justify-content: center;
}
.ht-authscreen__art-img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.ht-authscreen__art-scrim {
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(20, 12, 6, 0.35) 0%, rgba(20, 12, 6, 0.88) 72%);
}
.ht-authscreen__art-copy {
	/*
	 * A relative position, not the default static, purely so this stacks
	 * above .ht-authscreen__art-img/-scrim: both are absolutely
	 * positioned, and per CSS2.1 painting order, positioned descendants
	 * paint after (on top of) non-positioned ones regardless of DOM order
	 * -- without this the two backdrop layers would paint over the copy.
	 */
	position: relative;
	padding: 48px;
	display: flex;
	flex-direction: column;
	gap: 22px;
}

.ht-authscreen__art-eyebrow {
	color: var(--ht-gold);
	font-size: 12.5px;
	font-weight: 800;
	letter-spacing: 0.24em;
	text-transform: uppercase;
}

.ht-authscreen__reasons {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 16px;
	max-width: 420px;
}
.ht-authscreen__reason { display: flex; gap: 14px; }
.ht-authscreen__reason-mark {
	flex: none;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 26px;
	height: 26px;
	border-radius: 99px;
	border: 1.5px solid rgba(233, 200, 126, 0.55);
	color: var(--ht-gold);
}
.ht-authscreen__reason-text {
	font-weight: 800;
	font-size: 15px;
	line-height: 1.5;
	color: var(--ht-cream-light);
}

.ht-authscreen__reassure {
	margin: 8px 0 0;
	padding-top: 18px;
	border-top: 1px solid rgba(253, 249, 242, 0.14);
	font-size: 13px;
	line-height: 1.7;
	/*
	 * 0.55 measured at 5.65:1 against the panel's --ht-ink ground -- just
	 * over the 4.5:1 AA floor for 13px text, with no margin for a slightly
	 * different render. Raised for headroom, not because the old value
	 * technically failed.
	 */
	color: rgba(253, 249, 242, 0.72);
	max-width: 420px;
}

.ht-authscreen__art-footer {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: 12px;
	font-size: 12px;
	/* 0.5 measured at 4.91:1 -- barely over the 4.5:1 AA floor at this
	   size. Raised for headroom, not because the old value technically
	   failed. */
	color: rgba(253, 249, 242, 0.68);
}
.ht-authscreen__art-footer-links { display: flex; gap: 16px; }
.ht-authscreen__art-footer-links a { color: rgba(253, 249, 242, 0.6); }
.ht-authscreen__art-footer-links a:hover { color: var(--ht-gold); }

/*
 * Below the nav breakpoint the right panel collapses away entirely so the
 * form owns the screen — same 900px this theme's nav already treats as its
 * breakpoint (--ht-bp-nav; custom properties cannot be read inside an
 * @media condition, so this is the literal value, same as every other
 * @media (max-width: 900px) in this file).
 */
@media (max-width: 900px) {
	.ht-authscreen { grid-template-columns: minmax(0, 1fr); }
	.ht-authscreen__art { display: none; }
	.ht-authscreen__form { padding: 48px var(--ht-gutter); }
	.ht-signin-screen .ht-main { padding-block: 0; }
}
@media (max-width: 520px) {
	.ht-authscreen__form { padding: 40px var(--ht-gutter); }
	.ht-authtabs__tab { font-size: 17px; }
}

/* ==========================================================================
   Account shell (woocommerce/myaccount/my-account.php, navigation.php,
   dashboard.php). Same family as .ht-auth above — card shape, radius and
   the crimson/gold/ink palette all carried over — but its own block, since
   this is a signed-in area rather than a form.

   Layout follows the comp exactly (Heritage Thangka website/My Orders.dc.
   html): a dark hero (breadcrumb, heading, tab strip) above a two-column
   body with the endpoint content on the left and the sidebar — identity
   card, "how deposits work" panel, contact card — on the right, rather than
   the woocommerce_before_main_content-hooked full-bleed band the shop/cart/
   checkout/confirmation pages use — see my-account.php's own docblock for
   why. Sidebar rhythm (sticky aside, 18px stack gap) borrowed from
   .ht-cartpage__aside; the dark "how deposits work" panel borrowed from
   .ht-next (template-parts/confirmation/aside.php) down to its exact
   spacing, so a buyer sees the same explainer worded and framed the same
   way on both the confirmation page and here.

   .ht-account__hero used to break out of page.php's .ht-container with
   width:100vw + a negative margin, the same bug the sign-in split screen
   had (see that block's own docblock, further up, for the full write-up):
   100vw counts the vertical scrollbar's own width, which the real,
   scrollbar-aware viewport then has no room for, so any tall enough page
   grew a permanent horizontal scrollbar. Fixed the same way: the width
   constraint is lifted off the ancestor .ht-container instead, scoped to
   the ".ht-account-screen" body class (ht_is_account_dashboard_screen(),
   inc/account.php) rather than ".ht-signin-screen" -- that class flags
   exactly is_account_page() && is_user_logged_in(), the signed-in shell
   this hero renders in on every endpoint (dashboard, My Orders, a single
   order, addresses, ...), where ".ht-signin-screen" flags the opposite,
   logged-out half of the same [woocommerce_my_account] shortcode.
   Neither is_account_page() alone nor WooCommerce's own 'woocommerce-
   account'/'woocommerce-dashboard' body classes narrow this correctly --
   see ht_is_account_dashboard_screen()'s own docblock for why.

   ".ht-account-screen .ht-main > .ht-container" is a CHILD combinator, not
   the descendant one the sign-in screen's equivalent chain uses -- and has
   to be. This hero carries its OWN nested ".ht-container.ht-account__hero-
   inner" (my-account.php) to centre the breadcrumb/heading/tab strip
   inside the full-bleed dark band, exactly like header.php's rows do
   inside the site header. A descendant selector would reach that inner
   .ht-container too and strip its max-width right along with the outer
   one, blowing the hero's own content full-bleed instead of just the
   band's background. .ht-container is a direct child of .ht-main only
   once, from page.php's own wrapper -- the hero's copy sits several
   elements deeper, inside .ht-entry, .ht-entry__content, .ht-account and
   .ht-account__hero itself -- so the child combinator reaches only the
   one this fix means to touch.
   ========================================================================== */

.ht-account { display: flex; flex-direction: column; }

/*
 * Lifts .ht-container's own max-width/gutter for the signed-in account
 * shell only, so .ht-account__hero below can fill the real viewport width
 * with no width:100vw breakout needed -- see the block comment above for
 * why this targets .ht-main's direct child specifically.
 */
.ht-account-screen .ht-main > .ht-container {
	max-width: none;
	margin-inline: 0;
	padding-inline: 0;
}

/* --- hero: breadcrumb, heading, tab strip --- */

.ht-account__hero {
	background: var(--ht-ink);
	color: var(--ht-cream-light);
}

.ht-account__hero-inner {
	display: flex;
	flex-direction: column;
	gap: 14px;
	padding-block: 40px 0;
}

.ht-account__hero-title {
	margin: 0;
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: clamp(1.75rem, 4vw, 2.75rem);
	line-height: 1.1;
	color: var(--ht-cream-light);
}

.ht-account__hero-intro {
	margin: 0 0 8px;
	max-width: 560px;
	font-size: 16px;
	line-height: 1.6;
	color: rgba(253, 249, 242, 0.75);
}

.ht-account__tabs { margin-top: 14px; }
.ht-account__tabs-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	gap: 0;
	overflow-x: auto;
}
.ht-account__tab-link {
	display: block;
	padding: 16px 22px;
	font-size: 14.5px;
	font-weight: 700;
	white-space: nowrap;
	color: rgba(253, 249, 242, 0.6);
	border-bottom: 2.5px solid transparent;
}
.ht-account__tab-link:hover { color: var(--ht-cream-light); }
.ht-account__tab.is-active .ht-account__tab-link {
	color: var(--ht-cream-light);
	border-bottom-color: var(--ht-gold);
}

/* --- two-column body --- */

.ht-account__body {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(240px, 300px);
	gap: 40px;
	align-items: start;
	padding-block: 40px 0;
}

.ht-account__sidebar {
	position: sticky;
	top: 96px;
	display: flex;
	flex-direction: column;
	gap: 18px;
}

/* --- identity card, with the stats block nested inside it (comp draws one
   card, not two — see my-account.php's own docblock) --- */

.ht-account__identity {
	display: flex;
	flex-direction: column;
	gap: 20px;
	background: var(--ht-surface);
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
	padding: 24px;
}
.ht-account__identity-row {
	display: flex;
	align-items: center;
	gap: 14px;
}
.ht-account__avatar {
	flex: none;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 46px;
	height: 46px;
	border-radius: 99px;
	background: var(--ht-ink);
	color: var(--ht-gold);
	font-family: var(--ht-font-display);
	font-size: 18px;
	font-weight: 600;
}
.ht-account__who { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ht-account__name { font-weight: 800; font-size: 15px; color: var(--ht-ink); }
.ht-account__email { font-size: 13px; color: var(--ht-muted); overflow-wrap: anywhere; }

.ht-account__stats {
	list-style: none;
	margin: 0;
	padding-top: 18px;
	border-top: 1px solid var(--ht-cream-warm);
	display: flex;
	flex-direction: column;
	gap: 12px;
}
.ht-account__stats-row { display: flex; justify-content: space-between; gap: 14px; font-size: 14px; }
.ht-account__stats-label { color: var(--ht-body); }
.ht-account__stats-value { font-weight: 800; color: var(--ht-ink); }

/* --- "something look wrong?" contact card --- */

.ht-account__help { display: flex; flex-direction: column; gap: 8px; padding: 20px 22px; }
.ht-account__help-title { font-weight: 800; font-size: 13.5px; color: var(--ht-ink); }
.ht-account__help-body { margin: 0; font-size: 13px; line-height: 1.6; color: var(--ht-muted); }
.ht-account__help-link { font-size: 13.5px; font-weight: 700; color: var(--ht-crimson); }
.ht-account__help-link:hover { color: var(--ht-crimson-dark); }

/* --- "how deposits work" panel --- */

.ht-account__deposits {
	background: var(--ht-ink);
	color: var(--ht-cream-light);
	border-radius: var(--ht-radius);
	padding: 24px;
}
.ht-account__deposits-title {
	display: block;
	margin-bottom: 12px;
	font-size: 12px;
	font-weight: 800;
	letter-spacing: 0.16em;
	color: var(--ht-gold);
}
.ht-account__deposits-text { margin: 0; font-size: 13.5px; line-height: 1.7; color: rgba(253, 249, 242, 0.75); }
.ht-account__deposits-note {
	margin: 14px 0 0;
	padding-top: 14px;
	border-top: 1px solid rgba(253, 249, 242, 0.12);
	font-size: 13px;
	line-height: 1.6;
	color: rgba(253, 249, 242, 0.6);
}

/* --- content card --- */

.ht-account__content {
	min-width: 0;
	background: var(--ht-surface);
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
	padding: 32px;
}

.ht-account__dashboard { display: flex; flex-direction: column; gap: 16px; }
.ht-account__dashboard-title {
	margin: 0;
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: 26px;
	line-height: 1.2;
	color: var(--ht-ink);
}
.ht-account__dashboard-line { margin: 0; font-size: 15px; line-height: 1.7; color: var(--ht-body); }
.ht-account__dashboard-line a { font-weight: 700; color: var(--ht-crimson); }
.ht-account__dashboard-line a:hover { color: var(--ht-crimson-dark); }

@media (max-width: 900px) {
	.ht-account__body { grid-template-columns: minmax(0, 1fr); gap: 28px; padding-block: 32px 0; }
	.ht-account__sidebar { position: static; top: auto; }
}
@media (max-width: 520px) {
	.ht-account__hero-inner { padding-block: 32px 0; }
	.ht-account__tab-link { padding: 14px 16px; font-size: 13.5px; }
	.ht-account__content { padding: 24px; }
}

/* ==========================================================================
   My Orders (woocommerce/myaccount/orders.php) — cards, the client-side
   status filter tabs (assets/js/account-orders.js) and each card's
   expandable panel. Renders inside .ht-account__content above, so it never
   needs its own outer card frame or page padding.

   The timeline inside a card's panel reuses .ht-track (the "order confirmation:
   status timeline" block above) rather than a second copy — same function
   (ht_confirmation_steps()) feeding both, same marks. The pieces list below
   it is its own, smaller block: .ht-pieces above is sized for the
   confirmation page's full-width column, and the comp draws these
   noticeably smaller.
   ========================================================================== */

.ht-orders { display: flex; flex-direction: column; gap: 22px; }

/* --- receipt banner --- */

.ht-orders__banner {
	display: flex;
	align-items: center;
	gap: 18px;
	background: var(--ht-cream-rose);
	border-left: 3px solid var(--ht-crimson);
	border-radius: 2px;
	padding: 20px 22px;
}
.ht-orders__banner-icon {
	flex: none;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	border-radius: 99px;
	background: var(--ht-cream-light);
	color: var(--ht-crimson);
}
.ht-orders__banner-copy { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 0; }
.ht-orders__banner-title { font-weight: 800; font-size: 15px; color: var(--ht-ink); }
.ht-orders__banner-text { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--ht-body); }
.ht-orders__banner-cta { flex: none; white-space: nowrap; }

/* --- toolbar: filter tabs + result count --- */

.ht-orders__toolbar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
	flex-wrap: wrap;
}
.ht-orders__filters { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ht-orders__filter {
	border: 1.5px solid var(--ht-border);
	background: var(--ht-surface);
	color: var(--ht-ink);
	border-radius: 99px;
	padding: 9px 18px;
	font-family: var(--ht-font-body);
	font-weight: 700;
	font-size: 13.5px;
	cursor: pointer;
}
.ht-orders__filter:hover { border-color: var(--ht-crimson); }
.ht-orders__filter.is-active {
	border-color: var(--ht-crimson);
	background: var(--ht-crimson);
	color: var(--ht-cream-light);
}
.ht-orders__count { font-size: 13px; color: var(--ht-muted); font-weight: 700; white-space: nowrap; }

/* --- order cards --- */

.ht-orders__list { display: flex; flex-direction: column; gap: 22px; }
.ht-orders__card {
	background: var(--ht-cream-light);
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
}
.ht-orders__card.is-hidden { display: none; }

.ht-orders__card-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
	padding: 20px 26px;
	border-bottom: 1px solid var(--ht-cream-warm);
	flex-wrap: wrap;
}
.ht-orders__card-meta { display: flex; align-items: center; gap: 26px; flex-wrap: wrap; }
.ht-orders__field { display: flex; flex-direction: column; gap: 3px; }
.ht-orders__field-label {
	font-size: 11.5px;
	font-weight: 800;
	letter-spacing: 0.12em;
	color: var(--ht-stone);
}
.ht-orders__field-value { font-size: 14.5px; font-weight: 700; color: var(--ht-ink); }
.ht-orders__ref { font-family: ui-monospace, Menlo, monospace; font-weight: 600; }

.ht-orders__pill {
	display: flex;
	align-items: center;
	gap: 8px;
	background: var(--ht-cream-warm);
	color: var(--ht-stone);
	font-size: 11.5px;
	font-weight: 800;
	letter-spacing: 0.1em;
	padding: 7px 14px;
	border-radius: 99px;
	white-space: nowrap;
}
.ht-orders__pill-dot { width: 7px; height: 7px; border-radius: 99px; background: currentColor; display: inline-block; }

/* Status colour, keyed to the real status_key values ht_account_order_card()
   returns (deposit workflow states, or the order's own WooCommerce status
   for anything paid another way). Anything not listed keeps the neutral
   default above rather than going unstyled. */
.ht-orders__pill--awaiting_transfer,
.ht-orders__pill--info_requested,
.ht-orders__pill--pending {
	background: var(--ht-cream-rose);
	color: var(--ht-crimson);
}
.ht-orders__pill--receipt_uploaded,
.ht-orders__pill--on-hold {
	background: var(--ht-cream-warm);
	color: var(--ht-crimson-dark);
}
/* Same success pair .ht-track__step--done .ht-track__tag already uses above. */
.ht-orders__pill--approved,
.ht-orders__pill--processing,
.ht-orders__pill--completed {
	background: #f3faf5;
	color: #1b8a4b;
}
.ht-orders__pill--rejected,
.ht-orders__pill--cancelled,
.ht-orders__pill--refunded,
.ht-orders__pill--failed {
	background: var(--ht-crimson);
	color: var(--ht-cream-light);
}

.ht-orders__card-body {
	padding: 22px 26px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 26px;
	flex-wrap: wrap;
}
.ht-orders__summary { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.ht-orders__items-line { font-weight: 700; font-size: 15px; color: var(--ht-ink); }
.ht-orders__detail-line { font-size: 13.5px; color: var(--ht-muted); line-height: 1.5; }
.ht-orders__actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ht-orders__actions .ht-btn { padding: 12px 22px; font-size: 14px; white-space: nowrap; }

/* --- expandable panel --- */

.ht-orders__panel {
	border-top: 1px solid var(--ht-cream-warm);
	padding: 26px;
	display: grid;
	grid-template-columns: 1.4fr 1fr;
	gap: 36px;
	background: var(--ht-cream);
}
.ht-orders__panel[hidden] { display: none; }

.ht-orders__panel-main,
.ht-orders__panel-aside { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
.ht-orders__panel-block + .ht-orders__panel-block { border-top: 1px solid var(--ht-border); padding-top: 16px; }
.ht-orders__panel-heading {
	margin: 0 0 14px;
	font-size: 11.5px;
	font-weight: 800;
	letter-spacing: 0.12em;
	color: var(--ht-stone);
	text-transform: uppercase;
}

.ht-orders__pieces { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.ht-orders__piece {
	display: grid;
	grid-template-columns: 56px minmax(0, 1fr) auto;
	gap: 16px;
	align-items: center;
}
.ht-orders__piece-media {
	display: block;
	border-radius: var(--ht-radius);
	overflow: hidden;
	aspect-ratio: 4 / 5;
	background: var(--ht-canvas);
}
/* Two classes, not one — see .ht-piece__media .ht-piece__img above for why:
   WooCommerce's own `.woocommerce img { height: auto }` otherwise wins. */
.ht-orders__piece-media .ht-orders__piece-img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.ht-orders__piece-detail { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ht-orders__piece-name { font-weight: 700; font-size: 14.5px; color: var(--ht-ink); }
a.ht-orders__piece-name:hover, a.ht-orders__piece-name:focus { color: var(--ht-crimson); }
.ht-orders__piece-meta {
	display: flex;
	flex-wrap: wrap;
	gap: 4px 8px;
	font-size: 13px;
	color: var(--ht-muted);
}
.ht-orders__piece-meta p { margin: 0; }
.ht-orders__piece-total { font-weight: 800; font-size: 14.5px; color: var(--ht-ink); white-space: nowrap; }

.ht-orders__panel-address,
.ht-orders__panel-payment { margin: 0; font-size: 14px; line-height: 1.7; }
.ht-orders__panel-address { color: var(--ht-ink); }
.ht-orders__panel-payment { color: var(--ht-body); }

.ht-orders__panel-links { display: flex; flex-direction: column; gap: 9px; }
.ht-orders__panel-link { text-align: center; padding: 11px 0; font-size: 13.5px; }
.ht-orders__panel-help { text-align: center; font-size: 13px; font-weight: 700; padding-top: 2px; color: var(--ht-crimson); }
.ht-orders__panel-help:hover { color: var(--ht-crimson-dark); }

/* --- empty states: no orders at all, and "nothing matches this filter" --- */

.ht-orders__empty {
	background: var(--ht-surface);
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
	padding: 64px 40px;
	text-align: center;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 14px;
}
.ht-orders__empty[hidden] { display: none; }
.ht-orders__empty-title {
	margin: 0;
	font-family: var(--ht-font-display);
	font-weight: 500;
	font-size: 26px;
	line-height: 1.2;
	color: var(--ht-ink);
}
.ht-orders__empty-text { margin: 0; font-size: 15px; line-height: 1.7; color: var(--ht-body); max-width: 380px; }

.ht-orders__pagination { display: flex; justify-content: center; gap: 12px; }

@media (max-width: 680px) {
	.ht-orders__panel { grid-template-columns: minmax(0, 1fr); }
	.ht-orders__piece { grid-template-columns: 64px minmax(0, 1fr); gap: 16px; }
	.ht-orders__piece-total { grid-column: 2; }
}
@media (max-width: 480px) {
	.ht-orders__card-head, .ht-orders__card-body { flex-direction: column; align-items: flex-start; }
	.ht-orders__actions { width: 100%; }
	.ht-orders__actions .ht-btn { flex: 1; text-align: center; }
}

/* --- the full order page (myaccount/view-order.php) ---
   Reuses .ht-orders__field, .ht-orders__pill, .ht-track__list and
   .ht-orders__panel-* rather than a parallel set — see that file's own
   header comment. Only the layout wrapping those pieces is new. */

.ht-orderdetail { display: flex; flex-direction: column; gap: 22px; }

.ht-orderdetail__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
	flex-wrap: wrap;
	background: var(--ht-cream-light);
	border: 1px solid var(--ht-border);
	border-radius: var(--ht-radius);
	padding: 20px 26px;
}
.ht-orderdetail__meta { display: flex; align-items: center; gap: 26px; flex-wrap: wrap; }

.ht-orderdetail__actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ht-orderdetail__actions .ht-btn { padding: 12px 22px; font-size: 14px; white-space: nowrap; }

.ht-orderdetail__body {
	display: grid;
	grid-template-columns: 1.4fr 1fr;
	gap: 36px;
	align-items: start;
}
.ht-orderdetail__main,
.ht-orderdetail__aside { display: flex; flex-direction: column; gap: 20px; min-width: 0; }

.ht-orderdetail__block { min-width: 0; }
.ht-orderdetail__delivery { margin: 0; font-size: 15px; font-weight: 700; color: var(--ht-ink); }

/* The order-updates list mirrors core's own woocommerce-OrderUpdates markup
   (kept verbatim in the template) so nothing here needs to duplicate its
   class names — only give it this page's spacing and colours instead of
   core's unstyled default. */
.ht-orderdetail__updates { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.ht-orderdetail__updates .woocommerce-OrderUpdate-meta {
	margin: 0 0 4px;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.02em;
	color: var(--ht-stone);
}
.ht-orderdetail__updates .woocommerce-OrderUpdate-description { font-size: 14px; line-height: 1.6; color: var(--ht-body); }
.ht-orderdetail__updates .woocommerce-OrderUpdate-description > p:last-child { margin-bottom: 0; }
.ht-orderdetail__updates > li:not(:last-child) {
	padding-bottom: 14px;
	border-bottom: 1px solid var(--ht-border);
}

/* woocommerce_view_order's own order-details table (core markup, kept
   unmodified) — this only gives it the page's card chrome. WooCommerce's
   own stylesheet (woocommerce-general.css, enqueued via
   add_theme_support('woocommerce')) styles the table itself. */
.ht-orderdetail__native :is(h2) {
	font-family: var(--ht-font-body);
	font-size: 12px;
	font-weight: 800;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--ht-stone);
}

@media (max-width: 980px) {
	.ht-orderdetail__body { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 480px) {
	.ht-orderdetail__head { flex-direction: column; align-items: flex-start; }
	.ht-orderdetail__actions { width: 100%; }
	.ht-orderdetail__actions .ht-btn { flex: 1; text-align: center; }
}

/* --------------------------------------------------------------------------
   Staff sign-in (/studio/) — template-parts/staff-auth/*.
   Borrows the whole .ht-authscreen split screen; only the art panel and the
   two message rows are its own. No tabs, so no .ht-authtabs rules here.
   -------------------------------------------------------------------------- */

.ht-authscreen--staff .ht-authscreen__art-lede {
	margin: 0.75rem 0 0;
	font-family: var(--ht-font-body);
	font-size: 1.05rem;
	letter-spacing: 0.01em;
	color: var(--ht-cream-warm);
}

.ht-auth__error,
.ht-auth__notice {
	margin: 0 0 1.5rem;
	padding: 0.85rem 1rem;
	border-left: 4px solid;
	font-size: 0.95rem;
	line-height: 1.5;
}

.ht-auth__error {
	border-left-color: var(--ht-crimson);
	background: var(--ht-cream-rose);
	color: var(--ht-ink);
}

.ht-auth__notice {
	border-left-color: var(--ht-line);
	background: var(--ht-cream-warm);
	color: var(--ht-body);
}
