/* Heraldic Studio - shared styles. Tokens and specs: DESIGN.md. */

/* ---------- Fonts: self-hosted, latin (Fontsource, OFL) ---------- */
@font-face { font-family: "Poppins"; font-style: normal; font-weight: 200; font-display: swap; src: url("../fonts/poppins-latin-200-normal.woff2") format("woff2"); }
@font-face { font-family: "Poppins"; font-style: normal; font-weight: 300; font-display: swap; src: url("../fonts/poppins-latin-300-normal.woff2") format("woff2"); }
@font-face { font-family: "Poppins"; font-style: normal; font-weight: 500; font-display: swap; src: url("../fonts/poppins-latin-500-normal.woff2") format("woff2"); }
@font-face { font-family: "Poppins"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/poppins-latin-700-normal.woff2") format("woff2"); }
/* Lora's lightest weight is 400; the boards' "Lora 300" is drawn with it. */
@font-face { font-family: "Lora"; font-style: normal; font-weight: 300 400; font-display: swap; src: url("../fonts/lora-latin-400-normal.woff2") format("woff2"); }
@font-face { font-family: "Lora"; font-style: italic; font-weight: 300 400; font-display: swap; src: url("../fonts/lora-latin-400-italic.woff2") format("woff2"); }
@font-face { font-family: "Lora"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/lora-latin-700-normal.woff2") format("woff2"); }
@font-face { font-family: "DM Mono"; font-style: normal; font-weight: 300; font-display: swap; src: url("../fonts/dm-mono-latin-300-normal.woff2") format("woff2"); }
@font-face { font-family: "DM Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/dm-mono-latin-400-normal.woff2") format("woff2"); }
/* The first paint uses a fallback until Poppins arrives (swap). Arial sized to Poppins' width (measured 1.09-1.14 by weight,
   session 44) with Poppins' ascent 1050 / descent 350 / gap 100, so the swap keeps the line breaks: no layout shift. */
@font-face { font-family: "Poppins Fallback"; src: local("Arial"); size-adjust: 111%; ascent-override: 94.6%; descent-override: 31.5%; line-gap-override: 9%; }

/* ---------- Tokens (DESIGN.md section 2, 3, 4) ---------- */
:root {
	color-scheme: light;

	--ground: #FCF5EB; /* the toned cream, Warmth 70 % (owner, session 38) */
	--ground-alt: #F5EEE1;
	--ink: #292929;
	--quiet: #666666;
	--line: #D4CAB8;
	--sage: #587364;
	--sage-deep: #496253;
	--band: #8AA79F;
	--forest: #37483F;
	--on-forest: #9EB6AF;
	--line-forest: #62766E;
	--error: #9A4A33;
	--well-foot: #E6DDCC;
	--well: linear-gradient(to bottom, var(--ground), var(--well-foot));

	--font-sans: "Poppins", "Poppins Fallback", ui-sans-serif, system-ui, "Segoe UI", sans-serif;
	--font-serif: "Lora", Georgia, "Times New Roman", serif;
	/* Labels and data (DESIGN.md section 3; Fontsource 5.3.0, OFL). The fallbacks have DM Mono's own advance (0.6 em:
	   Courier New on Windows and macOS, Droid Sans Mono on Android), so nothing re-wraps when DM Mono arrives. */
	--font-mono: "DM Mono", "Courier New", "Droid Sans Mono", ui-monospace, monospace;

	/* Display sizes, linear from the 375 to the 1440 board value. */
	--fs-display-mark: clamp(5rem, 3.239rem + 7.512vw, 10rem);
	--fs-display-numeral: clamp(4rem, 3.296rem + 3.005vw, 6rem);
	--fs-display-closing: clamp(2.5rem, 1.796rem + 3.005vw, 4.5rem);
	--fs-display-h1: clamp(2.75rem, 2.31rem + 1.878vw, 4rem); /* page titles 44 -> 64 */
	--fs-display-h2: clamp(2rem, 1.736rem + 1.127vw, 2.75rem);
	--fs-display-quote: clamp(1.375rem, 1.067rem + 1.315vw, 2.25rem);
	--fs-display-quote-sm: clamp(1rem, 0.978rem + 0.094vw, 1.0625rem);

	/* Side gutter 20 -> 56, section padding 72 -> 96. Spacing steps (owner, session 18): section head ->
	   content 56 -> 80; between groups inside a section 40 -> 48; image -> its text 24 -> 32. */
	--gutter: clamp(1.25rem, 0.458rem + 3.38vw, 3.5rem);
	--section-y: clamp(4.5rem, 3.972rem + 2.254vw, 6rem);
	--head-gap: clamp(3.5rem, 2.972rem + 2.254vw, 5rem);
	--group-gap: clamp(2.5rem, 2.324rem + 0.751vw, 3rem);
	--media-gap: clamp(1.5rem, 1.324rem + 0.751vw, 2rem);
	--content-max: 83rem; /* 1328 */
	--col-gap: 2.5rem;
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
	margin: 0;
	background: var(--ground);
	color: var(--ink);
	font-family: var(--font-sans);
	font-weight: 300;
	font-size: 1rem;
	line-height: 1.6;
	-webkit-font-smoothing: antialiased;
}
img { display: block; max-width: 100%; height: auto; }
h1, h2, h3, p, dl, dd, ul, figure, blockquote { margin: 0; }
/* A phone: headings even out their lines, so none ends on one word where it can be helped (session 55, owner). */
@media (max-width: 767.98px) { h1, h2, h3 { text-wrap: balance; } }
ul { padding: 0; list-style: none; }
a { color: inherit; }
address { font-style: normal; }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
[tabindex="-1"]:focus { outline: none; } /* focused by script only (WooCommerce's notices), never by Tab */

.screen-reader-text {
	position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
	overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

.skip-link {
	position: absolute; left: var(--gutter); top: -100px; z-index: 100;
	background: var(--ink); color: var(--ground); padding: 12px 16px; font-size: 13px; font-weight: 500;
}
.skip-link:focus { top: 8px; }

.wrap { width: 100%; max-width: calc(var(--content-max) + 2 * var(--gutter)); margin-inline: auto; padding-inline: var(--gutter); }

/* ---------- Section head (DESIGN.md section 4) ---------- */
.label-row { display: flex; align-items: center; gap: 12px; }
.label {
	font-family: var(--font-mono); font-size: 11px; font-weight: 400; letter-spacing: 0.06em;
	line-height: 1.4; text-transform: uppercase;
	color: var(--quiet); flex: none;
}
.label-rule { flex: 1; height: 1px; background: var(--line); }
.label:empty { display: none; } /* a row that keeps only its rule (hst_label_row( '' )) */
.h2 { font-family: var(--font-sans); font-weight: 300; letter-spacing: -0.02em; font-size: var(--fs-display-h2); line-height: 1.15; }
.section-head { display: grid; gap: clamp(20px, 18.592px + 0.376vw, 24px); margin-bottom: var(--head-gap); }

/* ---------- Application steps: homepage learn and the product page (DESIGN.md section 11) ---------- */
.steps { margin: 0; padding: 0; list-style: none; display: grid; gap: 32px; }
.step { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; padding-top: 16px; box-shadow: inset 0 1px 0 var(--line); }
.step-num { font-family: var(--font-mono); font-weight: 300; letter-spacing: -0.04em; font-size: var(--fs-display-numeral); line-height: 1; color: var(--sage); }
.step-title { font-family: var(--font-sans); font-weight: 300; letter-spacing: -0.02em; font-size: 22px; line-height: 1.2; } /* the h3 (DESIGN.md section 3) */
.step-desc { color: var(--quiet); }
@media (min-width: 768px) {
	/* The steps share three row lines (numeral, title, description) through subgrid, so every description starts on
	   one line however the titles wrap (at 800 two of the three take two lines). */
	.steps { grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-rows: auto auto auto; column-gap: 40px; row-gap: 0; }
	.step { display: grid; grid-row: span 3; grid-template-rows: subgrid; row-gap: 12px; justify-items: start; padding-top: 24px; }
	.step-title { font-size: 26px; }
}

/* ---------- Page head: label, h1, sub (cart; board pageHead 56 56 40 56, mobile 40 20 28 20) ---------- */
.page-head { padding: 40px 0 28px; }
.page-title-col { display: grid; gap: 14px; margin-top: 24px; }
.page-h1 { font-size: var(--fs-display-h1); font-weight: 200; line-height: 1.05; }
.page-sub { max-width: 700px; font-size: 13px; line-height: 1.6; color: var(--quiet); }
@media (min-width: 768px) {
	.page-head { padding: 56px 0 40px; }
	.page-title-col { gap: 16px; margin-top: 32px; }
}

/* ---------- 404 and search heads (404.php, search.php; no board, session 24): the page head + the ways back ---------- */
.notfound-text, .search-text { max-width: 700px; font-family: var(--font-sans); font-weight: 300; font-size: 16px; line-height: 1.7; }
.notfound-links { margin-top: 16px; display: flex; flex-wrap: wrap; align-items: center; gap: 24px 40px; }
.notfound-head { padding-bottom: var(--section-y); }
/* Head -> first group on the same ground is the head -> content gap (56 / 80), not a head plus a section's padding. */
.search-head:has(+ .search-group:not(.blog-more)) { padding-bottom: 0; }
.search-head + .search-group:not(.blog-more) { padding-top: var(--head-gap); }
.search-pages { margin: 32px 0 0; padding: 0; list-style: none; display: grid; gap: 12px; font-size: 16px; line-height: 1.5; }
.search-pages a { color: var(--sage-deep); font-weight: 500; text-decoration-color: var(--sage); text-underline-offset: 3px; }
@media (min-width: 768px) {
	.notfound-links { margin-top: 24px; }
}
@media (min-width: 1024px) {
	.product-grid.search-products { grid-template-columns: repeat(4, minmax(0, 1fr)); } /* full width here, not beside the shop's rail */
}

/* ---------- Quantity stepper (woocommerce/global/quantity-input.php, qty.js; DESIGN.md section 6) ---------- */
.qty-box { flex: none; display: flex; align-items: center; box-shadow: inset 0 0 0 1px var(--sage); }
.qty-box input {
	width: 30px; padding: 0; border: 0; background: none; text-align: center; -moz-appearance: textfield; appearance: textfield;
	font-family: var(--font-sans); font-size: 16px; font-weight: 500; line-height: 1.5; color: var(--ink);
}
.qty-box input::-webkit-outer-spin-button, .qty-box input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.qty-box:not(.is-ready) input { width: 64px; } /* no JavaScript: the bare number field */
.qty-btn {
	width: 32px; align-self: stretch; padding: 0; border: 0; background: none; cursor: pointer;
	font-family: var(--font-sans); font-size: 16px; font-weight: 300; line-height: 1.5; color: var(--sage-deep);
}
@media (max-width: 767.98px) { .qty-btn { width: 44px; } } /* a 44 px target on a phone (session 55, owner) */
.qty-btn:disabled { color: var(--quiet); cursor: default; }
.qty-btn:focus-visible, .qty-box input:focus-visible { outline-offset: -4px; }

/* ---------- Text link (DESIGN.md section 4) ---------- */
.text-link {
	/* Drawn 19-21 px tall as on the boards; the padding and negative margin give a 44 px hit area
	   without adding height to the row. The underline is a 1.5 px border 4 px under the text. */
	flex: none; display: inline-block; padding-block: 12px; margin-block: -12px;
	font-size: 12px; font-weight: 500; letter-spacing: 0.14px; text-transform: uppercase; line-height: 1.4;
	color: var(--sage-deep); text-decoration: none;
}
.text-link > span { display: inline-block; padding-bottom: 4px; border-bottom: 1.5px solid var(--sage); }
@media (min-width: 768px) { .text-link { font-size: 11px; } }

/* ---------- Buttons (DESIGN.md section 5, states section 7) ---------- */
.btn {
	display: inline-flex; align-items: center; justify-content: center; gap: 8px;
	min-height: 45px; padding: 10px 24px; border: 0; border-radius: 0;
	font-family: var(--font-sans); font-size: 13px; font-weight: 500; line-height: 1.6;
	text-decoration: none; cursor: pointer; transition: background-color 150ms, color 150ms;
}
.btn-lg { min-height: 51px; padding-inline: 32px; }
.btn-primary { background: var(--sage); color: var(--ground); }
.btn-primary:hover { background: var(--sage-deep); }
.btn-outline { background: transparent; color: var(--sage-deep); box-shadow: inset 0 0 0 1.5px var(--sage); }
.btn-outline:hover { background: var(--sage); color: var(--ground); }
/* The one CTA on forest (session 37: the greens carry the interface): cream with a forest label, 9.02:1. */
.btn-accent { background: var(--ground); color: var(--forest); }
.btn-accent:hover { background: var(--on-forest); }
.btn-outline-forest { background: transparent; color: var(--ground); box-shadow: inset 0 0 0 1.5px var(--on-forest); }
.btn-outline-forest:hover { background: var(--ground); color: var(--forest); }

/* ---------- Store notice (WooCommerce's own; DESIGN.md section 11) ---------- */
.woocommerce-store-notice, p.demo_store {
	position: static; margin: 0; display: flex; align-items: center; justify-content: center; gap: 16px;
	min-height: 40px; padding: 10px var(--gutter);
	background: var(--forest); color: var(--ground); font-size: 13px; font-weight: 300; line-height: 1.5; text-align: center;
	box-shadow: none;
}
.woocommerce-store-notice a { color: var(--ground); }
.woocommerce-store-notice__dismiss-link { margin-left: auto; font-size: 0; text-decoration: none; }
.woocommerce-store-notice__dismiss-link::after { content: "\00d7"; font-size: 16px; }

/* ---------- WooCommerce notices (DESIGN.md section 7): --ground-alt, errors in --error ---------- */
.woocommerce-notices-wrapper:empty { display: none; }
.woocommerce-message, .woocommerce-info, .woocommerce-error {
	margin: 0 0 24px; padding: 14px 16px; list-style: none;
	background: var(--ground-alt); box-shadow: inset 0 0 0 1px var(--line);
	font-size: 13px; line-height: 1.5; color: var(--ink);
}
.woocommerce-error { box-shadow: inset 0 0 0 1.5px var(--error); color: var(--error); }
/* A notice with a WooCommerce action button ("View cart"): text left, button right. */
.woocommerce-message:has(> .button), .woocommerce-info:has(> .button) { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 24px; }
/* Links inside notice text, including the live Code Snippet's reseller link (its own CSS is !important blue). */
.woocommerce-message a:not(.button), .woocommerce-info a:not(.button), .woocommerce-error a:not(.button),
.woocommerce-info .hs-reseller-link, .woocommerce-info .hs-reseller-link:hover {
	color: var(--sage-deep) !important; font-weight: 500; text-decoration: underline !important; text-decoration-color: var(--sage) !important; text-underline-offset: 3px;
}
.woocommerce-message .button, .woocommerce-info .button, .woocommerce-error .button {
	order: 2; padding-block: 12px; margin-block: -12px;
	font-size: 12px; font-weight: 500; letter-spacing: 0.14px; text-transform: uppercase; color: var(--sage-deep);
	text-decoration: underline; text-decoration-color: var(--sage); text-decoration-thickness: 1.5px; text-underline-offset: 5px;
}

/* ---------- Nav (64 px, DESIGN.md section 4) ---------- */
.site-nav {
	position: sticky; top: 0; z-index: 60; background: var(--ground); box-shadow: inset 0 -1px 0 var(--line);
	transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.2s;
}
/* Smart sticky (js/nav.js): a rule and soft shadow once the page has moved; away while scrolling down past 160 px. */
.site-nav.is-raised { box-shadow: inset 0 -1px 0 var(--line), 0 12px 32px rgba(41, 41, 41, 0.07); }
.site-nav.is-away { transform: translateY(-102%); transition-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
@media (prefers-reduced-motion: reduce) { .site-nav { transition: none; } }
/* A focused element is scrolled into view clear of the sticky nav (64 + 16). */
html { scroll-padding-top: 80px; }
.nav-inner {
	display: flex; align-items: center; justify-content: space-between; gap: 24px;
	min-height: 64px; padding-inline: var(--gutter); max-width: calc(var(--content-max) + 2 * var(--gutter)); margin-inline: auto;
}
.brand { display: flex; align-items: center; gap: 8px; text-decoration: none; }
.brand img { width: 32px; height: 36px; }
.brand-name, .nav-list a, .nav-account, .nav-menu-btn {
	font-size: 11px; line-height: 1.4; letter-spacing: 0.14px; text-transform: uppercase; text-decoration: none;
}
.brand-name { font-weight: 500; color: var(--ink); white-space: nowrap; }
.nav-cart { white-space: nowrap; }
.nav-list a, .nav-account, .nav-menu-btn { font-weight: 300; color: var(--quiet); }
.nav-list a:hover, .nav-account:hover { color: var(--ink); }
/* Active page (board: ink, 500, a 1 px --sage line under the text). */
.nav-list a[aria-current="page"], .nav-list .current-menu-item > a {
	color: var(--ink); font-weight: 500;
	text-decoration: underline; text-decoration-color: var(--sage); text-decoration-thickness: 1px; text-underline-offset: 3px;
}
.nav-right { display: flex; align-items: center; gap: 12px; }
.nav-sep { width: 1px; height: 16px; background: var(--line); }
.nav-cart {
	display: inline-flex; align-items: center; min-height: 50px; padding: 12px 16px;
	background: var(--sage); color: var(--ground); font-size: 16px; font-weight: 300; text-decoration: none;
	transition: background-color 150ms;
}
.nav-cart:hover { background: var(--sage-deep); }
.nav-menu-btn {
	min-width: 45px; min-height: 45px; padding: 0 6px; background: none; border: 0; font-family: inherit; font-size: 12px; cursor: pointer;
}
.nav-account { display: none; }

/* Mobile: a panel under the nav, opened by Menu. */
.nav-main { display: none; }
.nav-main.is-open {
	display: block; position: absolute; left: 0; right: 0; top: 100%; z-index: 20;
	background: var(--ground); padding: 8px var(--gutter) 24px; box-shadow: inset 0 -1px 0 var(--line);
}
.nav-main.is-open .nav-list a, .nav-main.is-open .nav-account--menu {
	display: flex; align-items: center; min-height: 48px; font-size: 12px; box-shadow: inset 0 -1px 0 var(--line);
}

/* The nav keeps the Menu button to 1023: below that the centred links crowd My account. */
@media (min-width: 1024px) {
	.brand { gap: 12px; }
	.nav-main, .nav-main.is-open {
		display: block; position: static; padding: 0; box-shadow: none; background: none;
		position: absolute; left: 50%; transform: translateX(-50%); top: 0; bottom: 0;
	}
	.nav-main .nav-list { display: flex; gap: 40px; height: 100%; align-items: center; }
	.nav-main .nav-list a { display: inline-flex; align-items: center; min-height: 44px; }
	.nav-account { display: inline-flex; align-items: center; min-height: 44px; }
	.nav-main .nav-account--menu { display: none; }
	.nav-menu-btn { display: none; }
	.nav-right { gap: 16px; }
	.nav-cart { min-height: 42px; padding: 8px 20px; }
}

/* ---------- Footer (DESIGN.md section 4) ---------- */
.site-footer { background: var(--ground); color: var(--quiet); font-size: 13px; }
.footer-top {
	display: flex; flex-direction: column; gap: 32px;
	padding: 56px var(--gutter) 40px; max-width: calc(var(--content-max) + 2 * var(--gutter)); margin-inline: auto;
}
.footer-brand { display: flex; flex-direction: column; gap: 16px; }
.footer-brand img { width: 104px; height: 116px; }
.footer-desc { max-width: 22rem; }
.footer-contact { display: grid; gap: 2px; }
.footer-contact a, .footer-social a, .footer-list a { text-decoration: none; }
.footer-contact a:hover, .footer-social a:hover, .footer-list a:hover { color: var(--ink); text-decoration: underline; }
.footer-social { display: flex; gap: 20px; }
.footer-links { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
.footer-head { font-family: var(--font-mono); font-size: 11px; font-weight: 400; letter-spacing: 0.06em; line-height: 1.4; text-transform: uppercase; color: var(--ink); margin-bottom: 16px; }
.footer-list { display: grid; gap: 16px; }
/* A phone: every footer link a 44 px target (session 55, owner), the lists 44 apart; the -12 keeps the text's distance
   to the column head and the wordmark. */
@media (max-width: 767.98px) {
	.footer-list { gap: 0; margin-block: -12px; }
	.footer-contact { gap: 0; }
	.footer-social a, .footer-contact a { display: inline-flex; align-items: center; min-height: 44px; }
	/* The email's text back in the address's rhythm, 2 px under it as from 768 (session 56, owner): (20.8 - 44) / 2 + 2.
	   Its target overlaps only the address text above, which is not a link. */
	.footer-contact a { margin-top: -10px; }
	.footer-list a { display: flex; align-items: center; min-height: 44px; } /* as wide as its column */
}
.footer-right { container-type: inline-size; display: flex; flex-direction: column; gap: 32px; }

/* The wordmark fills its box: 13.8cqi of the box, capped at 121 px (DESIGN.md section 3). */
.wordmark-box { container-type: inline-size; width: 100%; }
.wordmark {
	display: flex; justify-content: flex-end; gap: 0.165em; white-space: nowrap;
	font-size: min(13.8cqi, 7.5625rem); line-height: 1; letter-spacing: -0.022em; color: var(--ink);
}
.wm-a { font-weight: 200; }
/* "Studio" filled sage, drawn round in forest under the fill (4.81:1; DESIGN.md section 2). */
.wm-b { font-weight: 700; color: var(--sage); -webkit-text-stroke: max(1.5px, 0.012em) var(--forest); paint-order: stroke fill; }

.footer-bottom { position: relative; } /* its rule is the printed .rule (drawn on the homepage) */
.footer-bottom-inner {
	display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 24px;
	padding: 24px var(--gutter); max-width: calc(var(--content-max) + 2 * var(--gutter)); margin-inline: auto;
}
.consent-open {
	padding: 12px 0; margin-block: -12px; border: 0; background: none; cursor: pointer;
	font: inherit; color: var(--quiet); text-decoration: none;
}
.consent-open:hover { color: var(--ink); text-decoration: underline; }

@media (min-width: 768px) {
	.footer-top { flex-direction: row; gap: 40px; padding-top: 72px; padding-bottom: 44px; }
	.footer-brand { flex: none; width: 280px; gap: 20px; }
	.footer-brand img { width: 107px; height: 120px; }
	.footer-desc { max-width: 220px; }
	.footer-right { flex: 1; justify-content: space-between; align-items: flex-end; }
	.footer-links { grid-template-columns: repeat(3, 140px); gap: 40px; }
	/* Grid columns 5-12 of the content width W: 8 columns + 7 gutters = 2W/3 - 13.33 px.
	   footer-right is W - 320 wide, so that is 2/3 of it + 200 px (872 at W = 1328). */
	.wordmark-box { width: calc(66.667cqi + 200px); }
}

/* ---------- Sections and image wells (DESIGN.md sections 4, 8) ---------- */
.section { padding-block: var(--section-y); }
.well { display: flex; align-items: center; justify-content: center; background: var(--well); overflow: hidden; }
.well img { width: 100%; height: 100%; object-fit: contain; }
.sku-line { font-family: var(--font-mono); font-size: 11px; font-weight: 400; letter-spacing: 0.06em; line-height: 16px; text-transform: uppercase; color: var(--quiet); }
.woocommerce-Price-amount bdi, .price bdi { white-space: nowrap; }
/* Middle dots between items as short rules (hst_sep_text): the dot stays in the text, hidden inside the 1 px span. */
.sep {
	display: inline-block; width: 1px; height: 0.9em; margin-inline: 0.7em; vertical-align: -0.1em;
	background: currentColor; opacity: 0.45; overflow: hidden; text-indent: 4px; white-space: nowrap;
}
/* A wrapping line (session 55, owner): each item (.sep-i) moves to the next line whole, its rule hung in its own left
   padding by a negative indent (a longer item wraps inside itself, its later lines under its text). The line is shifted
   left by one rule and its margins and clipped there, so a rule that starts a line is never seen. */
.seps { display: block; margin-left: calc(-1.4em - 1px); clip-path: inset(-0.5em 0 -0.5em calc(1.4em + 1px)); }
.sep-i { display: inline-block; padding-left: calc(1.4em + 1px); text-indent: calc(-1.4em - 1px); }
.sep-i:first-child { text-indent: 0; }
/* WooCommerce appends a "View cart" link after an AJAX add; the nav's Cart (n) already says it. */
a.added_to_cart { display: none; }

/* Text link colour variants by ground (DESIGN.md section 4). */
.text-link--band { color: var(--ink); }
.text-link--band > span { border-bottom-color: var(--ink); }
.text-link--forest { color: var(--ground); }
.text-link--forest > span { border-bottom-color: var(--on-forest); }

/* Tablet: the footer's link columns share what is left beside the brand column. */
@media (min-width: 768px) and (max-width: 1023.98px) {
	.footer-brand { width: 220px; }
	.footer-links { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; width: 100%; }
	.wordmark-box { width: 100%; }
}

/* ---------- Cookie consent (inc/consent.php): minimal, the page's own box - square, 1 px --line, no shadow ---------- */
.consent {
	position: fixed; z-index: 70; /* above the sticky nav */ right: 20px; bottom: 20px; width: min(360px, calc(100% - 40px));
	display: grid; gap: 12px; padding: 20px; background: var(--ground); box-shadow: inset 0 0 0 1px var(--line);
}
.consent[hidden] { display: none; }
.consent-title { font-family: var(--font-mono); font-size: 11px; font-weight: 400; letter-spacing: 0.06em; line-height: 1.4; text-transform: uppercase; color: var(--ink); }
.consent-text { font-size: 12px; line-height: 1.5; color: var(--quiet); }
.consent-text a { color: var(--sage-deep); text-decoration-color: var(--sage); text-underline-offset: 3px; }
.consent-actions { display: flex; gap: 12px; }
.consent .btn { flex: 1; min-height: 44px; padding: 8px 16px; }
/* Mobile: a full-width sheet on the bottom edge with one rule on top, like the page's rows. */
@media (max-width: 767.98px) {
	.consent { right: 0; bottom: 0; width: 100%; padding: 16px var(--gutter) 20px; box-shadow: inset 0 1px 0 var(--line); }
}

/* ---------- A password-protected post or product: WordPress's own form (get_the_password_form), in the field and button styles ---------- */
.pd-password { padding-block: 56px 96px; }
.post-password-form { display: grid; gap: 16px; max-width: 480px; }
.post-password-form p { margin: 0; font-size: 16px; font-weight: 300; line-height: 1.6; color: var(--ink); }
.post-password-form p:has(input) { display: flex; flex-wrap: wrap; align-items: end; gap: 12px; }
.post-password-form label { /* the field label style (checkout.css) */
	display: grid; flex: 1; gap: 8px; font-family: var(--font-sans); font-size: 12px; font-weight: 500; line-height: 1.5; letter-spacing: 0.14px; text-transform: uppercase; color: var(--sage-deep);
}
.post-password-form input[type="password"] {
	width: 100%; min-height: 50px; padding: 13px 16px; border: 0; border-radius: 0; background: var(--ground);
	box-shadow: inset 0 0 0 1px var(--sage); color: var(--ink); font: 300 16px/1.4 var(--font-sans);
}
.post-password-form input[type="submit"] {
	min-height: 50px; padding: 10px 24px; border: 0; border-radius: 0; background: var(--sage); color: var(--ground);
	font: 500 13px/1.6 var(--font-sans); cursor: pointer; transition: background-color 150ms;
}
.post-password-form input[type="submit"]:hover { background: var(--sage-deep); }
.post-password-form input:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* ---------- Sold out on a card or featured row (hst_card_stock): the product page's stock line, small (product.css .pd-stock) ---------- */
.card-stock {
	display: flex; align-items: center; gap: 8px; margin-top: 6px;
	font-family: var(--font-sans); font-size: 12px; font-weight: 400; line-height: 1.4; color: var(--quiet);
}
.card-stock-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--error); }

/* ---------- The line system (DESIGN.md section 4; owner's "Technical" pick, other pages decided 2026-10-18) ----------
   A decal sheet on a cutting mat: 1 px rules in the ground's own line colour where content splits into columns. */

/* Nav as cells: a rule after the brand (from 768), round the links (from 1024, 40 px out), before account / cart. */
.brand, .nav-right { position: relative; align-self: stretch; }
.brand::after, .nav-right::before {
	content: ""; position: absolute; top: 0; bottom: 0; width: 1px; background: var(--line); pointer-events: none;
}
.brand::after { right: 0; display: none; } /* on a phone it touched the name */
.nav-right { padding-left: 12px; }
.nav-right::before { left: 0; }
/* Below 360 the cells tighten so the Cart button keeps the 20 px gutter (at 320 it reached the screen's edge). */
@media (max-width: 359.98px) {
	.nav-inner { gap: 12px; }
	.nav-right { gap: 8px; padding-left: 8px; }
	.nav-cart { padding-inline: 12px; }
}
@media (min-width: 768px) {
	.brand { padding-right: 24px; }
	.brand::after { display: block; }
	.nav-right { padding-left: 24px; }
}
@media (min-width: 1024px) {
	.nav-main::before, .nav-main::after {
		content: ""; position: absolute; top: 0; bottom: 0; width: 1px; background: var(--line); pointer-events: none;
	}
	.nav-main::before { left: -40px; }
	.nav-main::after { right: -40px; }
}

/* Footer columns: a rule in the middle of each gap (16 / 24 at 768-1023 / 40), as tall as the longest column. */
.footer-links .footer-col { position: relative; align-self: stretch; --vr-gap: 16px; }
.footer-col + .footer-col::before {
	content: ""; position: absolute; top: 0; bottom: 0; left: calc(var(--vr-gap) / -2); width: 1px; background: var(--line); pointer-events: none;
}
@media (min-width: 768px) { .footer-links .footer-col { --vr-gap: 40px; } }
@media (min-width: 768px) and (max-width: 1023.98px) { .footer-links .footer-col { --vr-gap: 24px; } }

/* Page columns (shop rail | grid, product gallery | buy box, cart and checkout main | summary, account nav | panel):
   the rule is the grid's own ::before, placed by each page at the start of its right-hand column and stretched over the
   rows, so it is as tall as the taller column whatever the content. Shown only where the columns sit side by side. */
:is(.browse, .pd-grid, .cart-body, .co-grid, .acc-grid)::before {
	content: ""; display: none; justify-self: start; align-self: stretch; width: 1px;
	margin-left: calc(var(--col-gap) / -2 - 0.5px); background: var(--line); pointer-events: none;
}

/* Crop marks round a page's one lead image (DESIGN.md section 4: the product's main image, Featured's lead sheet): 14 px
   marks 20 px out, --quiet at 55 %. Drawn on a frame round the well, which clips its image. */
.crop-frame { position: relative; width: 100%; }
.crop-frame::before {
	content: ""; position: absolute; inset: -20px; pointer-events: none; opacity: 0.55;
	--m: linear-gradient(var(--quiet), var(--quiet));
	background:
		var(--m) left 0 top 20px / 14px 1px, var(--m) right 0 top 20px / 14px 1px,
		var(--m) left 0 bottom 20px / 14px 1px, var(--m) right 0 bottom 20px / 14px 1px,
		var(--m) left 20px top 0 / 1px 14px, var(--m) right 20px top 0 / 1px 14px,
		var(--m) left 20px bottom 0 / 1px 14px, var(--m) right 20px bottom 0 / 1px 14px;
	background-repeat: no-repeat;
}

/* ---------- Printed rules (the line system, DESIGN.md section 4): 1 px elements where rules were inset shadows, so the
   homepage can draw them (js/motion/lines.js); whole and static without JS and on every other page. ---------- */
.rule { position: absolute; left: 0; right: 0; height: 1px; background: var(--line); transform-origin: 0 50%; pointer-events: none; z-index: 1; }
.rule--top { top: 0; }
.rule--bottom { bottom: 0; }

/* ---------- Page to page (owner, session 45; the motion lab's "ease" variant, lab-vt.css): the browser's own
   cross-document view transition - the old page eases out and up a little, the new one settles in. The nav stays still;
   a nav hidden by the smart-sticky scroll has its name taken away as the page is swapped (js/transition.js), so it fades
   with the page. No transition after a form submit (js/transition.js) or under reduced motion; Firefox just switches. */
@media (prefers-reduced-motion: no-preference) {
	@view-transition { navigation: auto; }
	::view-transition-old(root) { animation: 320ms cubic-bezier(0.4, 0, 1, 1) both vt-out; }
	::view-transition-new(root) { animation: 520ms cubic-bezier(0.16, 1, 0.3, 1) 60ms both vt-in; }
	@keyframes vt-out { to { opacity: 0; transform: translateY(-10px); } }
	@keyframes vt-in { from { opacity: 0; transform: translateY(14px); } }
	.site-nav { view-transition-name: site-nav; }
	::view-transition-group(site-nav) { animation-duration: 0s; }
}

/* ---------- Lines draw (owner, session 45; js/motion/site-lines.js off the homepage, lines.js on it): each rule draws
   from a variable, 1 when no script runs - --lnh across (a rule's scaleX, a row divider's width, the crop marks' fade),
   --lnv down (a column rule's scaleY). Off the homepage the head script sets lines-in before the first paint when motion
   is allowed, holding every rule at 0 until site-lines.js writes each rule's own value; a 3 s fail-safe drops it. ---------- */
html.lines-in { --lnh: 0; --lnv: 0; }
.label-rule, .toolbar-rule, .rule { transform: scaleX(var(--lnh, 1)); transform-origin: 0 50%; }
:is(.browse, .pd-grid, .cart-body, .co-grid, .acc-grid)::before, .footer-col + .footer-col::before { transform: scaleY(var(--lnv, 1)); transform-origin: 50% 0; }
/* Row dividers: the inset shadow becomes a 1 px line whose width draws (paint only, no layout). :root outranks the page
   stylesheets, which load after this one. */
:root :is(body:not(.home) .steps > .step, .about-make li, .post-toc-list a, .cm-body) {
	box-shadow: none; background-image: linear-gradient(var(--line), var(--line)); background-repeat: no-repeat;
	background-position: 0 0; background-size: calc(100% * var(--lnh, 1)) 1px;
}
/* A reply has no top rule (blog.css); body matches the list's weight above, so this later rule wins. */
:root body .cm-list .children .cm-body { background-image: none; }
/* Its own rule: in the list above, :is() takes its most specific selector's weight and would keep the line on top. */
:root .pd-spec {
	box-shadow: none; background-image: linear-gradient(var(--line), var(--line)); background-repeat: no-repeat;
	background-position: 0 100%; background-size: calc(100% * var(--lnh, 1)) 1px;
}
.crop-frame::before { opacity: calc(0.55 * var(--lnh, 1)); }
/* The footer's wordmark slides in from the right (js/motion/footer.js): no sideways scroll while it is out. */
.site-footer { overflow-x: clip; }
/* Smooth scroll (js/motion/smooth.js, Lenis, session 53): an embed under the pointer must not catch the wheel mid-glide (lenis.css). */
.lenis.lenis-smooth iframe { pointer-events: none; }
