/**
 * Wandhaus — Design System V3 (cool white + neutral cool grey + deep teal-petrol).
 *
 * Source of truth for every color, type, spacing, radius, shadow, breakpoint
 * used in the theme + plugin chrome. Downstream CSS references these via
 * var(--name) — never raw hex / px / rem in rule values.
 *
 * Spec mirror: `Wandhaus V2 design system/project/tokens.css`.
 * Vault: `Vault/01 Brand & Design System/Tokens (V2).md` + `Design Tokens Policy.md`.
 */
:root {
	/* ── Palette (light surface) ────────────────────────────── */
	--bg:            #FAFBFC; /* Page background (V3: cool white) */
	--bg-alt:        #F1F4F6; /* Subtly differentiated bg / section tint */
	--surface:       #FFFFFF; /* Card surface (stays white, pops on cool white) */
	--surface-2:     #F1F4F6; /* Secondary surface */
	--ink:           #1A1F22; /* Primary text (cool near-black) */
	--ink-2:         #2B3034; /* Body text */
	--ink-muted:     #5A6063; /* Secondary text */
	--ink-faint:     #9AA1A4; /* Disabled / least-attention */
	--border:        #E4E8EA; /* Default borders / hairlines */
	--border-strong: #CED6DA; /* Stronger dividers */
	--accent:        #235C68; /* Deep teal-petrol, single brand accent */
	--accent-ink:    #1A4651; /* Hover / pressed accent */
	--accent-soft:   #E6EEEF; /* Accent surface tint */

	/* ── Palette (dark surface) ─────────────────────────────── */
	/* Use these whenever something renders ON TOP of var(--ink): footer dark
	   band, dark-variant topnav, stepper "done" circle interior, ink-fill
	   quantity badges. */
	--on-ink:         #FFFFFF; /* Primary text on dark */
	--on-ink-muted:   #C2CACE; /* Secondary text on dark */
	--on-ink-faint:   #828B8F; /* Least-attention on dark */
	--on-ink-border:  #2E363A; /* Divider / border on dark */
	--on-ink-surface: #12171A; /* "Page bg" feel against ink (footer body copy) */

	/* ── Palette (semantic state) ───────────────────────────── */
	--ok:             #2E7D55;
	--ok-soft:        #E8F3EC;
	--ok-soft-ink:    #1E6B45;
	--warn:           #C08A2E;
	--warn-soft:      #FAF1DF;
	--warn-soft-ink:  #8A6418;
	--err:            #C0453B;
	--err-soft:       #FBECEA;
	--err-soft-border:#F0CFC9;
	--err-soft-ink:   #A8362D;
	--info:           #2C6E9E; /* info fill (cool blue) */
	--info-soft:      #E9F1F8; /* info tint */
	--info-soft-ink:  #235C86; /* info message text */

	/* ── Phase 0 bridging tokens ────────────────────────────── */
	/* Added 2026-04-29 to retire raw hex found in account / product files. */
	--ink-overlay:               #14181B; /* dark account overlay (cool) */
	--ink-warm:                  #C7CDD0; /* legacy warm tan, neutralised to a cool neutral */
	--surface-product-fallback:  #C7CDD0; /* product-card hero fallback (cool grey) */
	--border-soft:               #DCE2E5; /* soft border (filter / soft dividers) */
	--accent-soft-cool:          #EFF4F5; /* cool tint of accent-soft (checkout bg variants) */

	/* ── Typography ─────────────────────────────────────────── */
	--font-display: 'Fraunces', 'Tiempos Headline', 'Cormorant Garamond', Georgia, serif;
	--font-body:    'Inter', -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', Arial, sans-serif;
	--font-mono:    'Inter', system-ui, sans-serif; /* uppercase + tracking via .mono */

	/* ── Spacing (8pt grid) ─────────────────────────────────── */
	--s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
	--s-5: 24px; --s-6: 32px; --s-7: 48px; --s-8: 64px; --s-9: 96px;
	/* Off-doubling steps the editorial layouts use heavily but the pure
	   8pt scale skips (the scale jumps 16→24 and 32→48). Value-named — not
	   index-named — so the --s-1..9 scale stays intact. --s-40 / --s-56 are
	   the gutter tier (they mirror the --page-pad ladder below). Added
	   2026-06-19, see Vault "Whitespace Audit (2026-06-19)". */
	--s-20: 20px; --s-40: 40px; --s-56: 56px;
	/* Optical sub-grid (2/6/10/14px) is intentionally NOT tokenized: these
	   are fine optical paddings inside chips, badges and pills. Left raw
	   pending a decision to bless a fine-grain token set. Same audit note. */

	/* ── Radius ─────────────────────────────────────────────── */
	/* V2 editorial: sharp default. Legacy rounded scale kept for components
	   that explicitly need rounding. */
	--radius-0:    0px;
	--radius-1:    4px;
	--radius-pill: 999px;

	/* Touch target floor — WCAG 2.5.5 / Apple HIG 44pt. Used by the
	 * builder's (pointer:coarse) density pass; see design preview §36. */
	--tap: 44px;
	/* NOTE — TWO radius scales coexist (consolidation pending, Whitespace
	   Audit 2026-06-19): the sharp editorial set --radius-0/1/pill above,
	   and this rounded --r-sm/md/lg/xl set (aliased by --radius-sm/md/lg
	   below). They disagree (--radius-1=4px vs --radius-sm=3px). Canonical
	   for new code = the --radius-* names; pick one scale before extending. */
	--r-sm: 3px; --r-md: 6px; --r-lg: 12px; --r-xl: 20px;

	/* ── Shadow (soft, neutral rgba based on V3 cool ink) ───── */
	--shadow-1: 0 1px 2px rgba(26, 31, 34, .04), 0 2px 14px rgba(26, 31, 34, .06);
	--shadow-2: 0 2px 6px rgba(26, 31, 34, .05), 0 12px 32px rgba(26, 31, 34, .07);
	--shadow-3: 0 8px 24px rgba(26, 31, 34, .09), 0 32px 64px rgba(26, 31, 34, .11);

	--ease:       cubic-bezier(.2, .7, .2, 1);
	--transition: 200ms var(--ease);

	/* ── Overlays / dialog ──────────────────────────────────── */
	/* Scrim sits behind a modal dialog, dimming the page. Tuned darker
	   than a soft wash so the modal card still feels weighty on a white
	   page. Editorial register — no blur. */
	--scrim:        rgba(26, 31, 34, .42);
	--shadow-modal: 0 24px 64px rgba(26, 31, 34, .18), 0 8px 24px rgba(26, 31, 34, .10);
	--z-modal:      1100; /* above blockUI (1001) and topnav (~50) */

	/* ── Layout ─────────────────────────────────────────────── */
	/* Three-tier content cap (V2.3, 2026-04-30):
	 *   --page-max          → none (full-bleed). Header + footer only.
	 *   --page-max-catalog  → 1680px. Catalog surfaces with photo-led
	 *                          grids that need width to breathe (homepage,
	 *                          shop archive, PDP, collection rails).
	 *   --page-max-content  → 1440px. Transactional / reading surfaces
	 *                          (cart, checkout, my-account, thank-you,
	 *                          generic pages — /over/, /inspiratie/).
	 *                          Aritzia / Mr Porter / NAP register.
	 * Header + footer stay full-bleed (use `--page-max: none`).
	 */
	--container-max:     1200px; /* Legacy */
	--page-max:          none;   /* Full-bleed — only header + footer */
	--page-max-catalog:  1680px; /* Catalog surfaces — grids, archive, PDP, homepage */
	--page-max-content:  1440px; /* Transactional surfaces — cart, checkout, account */
	--page-pad:          40px;   /* Desktop default (1280-1679) — responsive ladder below */
	--reading-max:       720px;  /* Editorial reading column for body prose (page.php) */
	--reading-max-wide:  960px;  /* Hero captions, press quote, single-column callouts */
	--editorial-max:     1200px; /* Wide/overview editorial pages — over, materialen, zakelijk, inspiratie, installatie. Matches the /collecties/ archive (--container-max) so content + shop pages share the same content edge. (Page Consistency Standard 2026-06-17) */

	/* ── Breakpoints ────────────────────────────────────────── */
	/* @media queries can't read custom props (CSS spec) — values are also
	   declared here so JS can read via getComputedStyle. Keep media queries
	   below in sync if changing. See Vault/Viewport Strategy.md. */
	--bp-sm:  640px;   /* phone → tablet portrait */
	--bp-md:  1024px;  /* tablet → laptop */
	--bp-lg:  1280px;  /* laptop → desktop */
	--bp-xl:  1680px;  /* desktop → wide (content cap) */
	--bp-2xl: 1920px;  /* wide → office monitor / 4K-scaled (gutter bump) */

	/*
	 * Legacy aliases — earlier v0.1.0 of this theme used `--color-*`,
	 * `--space-*`, `--type-*`, `--radius-*`, `--shadow-card/elevated`. Kept
	 * as aliases so existing stylesheets (shop.css, builder-chrome.css)
	 * don't regress while code migrates to the spec names.
	 */
	--color-bg:          var(--bg);
	--color-surface:     var(--surface);
	--color-ink:         var(--ink);
	--color-ink-muted:   var(--ink-muted);
	--color-accent:      var(--accent);
	--color-accent-soft: var(--accent-soft);
	--color-accent-dark: var(--accent-ink); /* builder bundle references this */
	--accent-dark:       var(--accent-ink); /* builder bundle references this */
	--color-border:      var(--border);
	--color-success:     var(--ok);
	--color-warning:     var(--warn);
	--color-danger:      var(--err);
	--color-info:        var(--info); /* Legacy alias, now the cool-blue info token */

	/* DEPRECATED — duplicate of the canonical --s-* scale. Do not use in
	   new code; consume --s-1..9 / --s-20 / --s-40 / --s-56 directly. Kept
	   only so legacy stylesheets don't regress. (Whitespace Audit 2026-06-19) */
	--space-1: var(--s-1);
	--space-2: var(--s-2);
	--space-3: var(--s-3);
	--space-4: var(--s-4);
	--space-5: var(--s-5);
	--space-6: var(--s-6);
	--space-7: var(--s-7);
	--space-8: var(--s-8);
	--space-9: var(--s-9);

	--type-xs:   .75rem;
	--type-sm:   .875rem;
	--type-base: 1rem;
	--type-md:   1.125rem;
	--type-lg:   1.375rem;
	--type-xl:   1.75rem;
	--type-2xl:  2.25rem;
	--type-3xl:  3rem;

	--radius-sm: var(--r-sm);
	--radius-md: var(--r-md);
	--radius-lg: var(--r-lg);

	--shadow-card:     var(--shadow-1);
	--shadow-elevated: var(--shadow-3);

	/* ── Spec aliases — wandhaus_design_tokens v1.0 (Teal-Petrol on Cool White) ──
	   The bare tokens above are canonical (every stylesheet consumes them);
	   these mirror the design-token file's --wh-* naming for spec fidelity. */
	--wh-primary:       var(--accent);       /* #235C68 */
	--wh-primary-dark:  var(--accent-ink);   /* #1A4651 */
	--wh-primary-tint:  var(--accent-soft);  /* #E6EEEF */
	--wh-ink:           var(--ink);          /* #1A1F22 */
	--wh-muted:         var(--ink-muted);    /* #5A6063 */
	--wh-base:          var(--bg);           /* #FAFBFC */
	--wh-surface:       var(--bg-alt);       /* #F1F4F6 */
	--wh-neutral:       #DCE2E5;             /* secondary fills, chips */
	--wh-rule:          var(--border);       /* #E4E8EA */
	--wh-success: var(--ok);   --wh-success-text: var(--ok-soft-ink);   --wh-success-tint: var(--ok-soft);
	--wh-warning: var(--warn); --wh-warning-text: var(--warn-soft-ink); --wh-warning-tint: var(--warn-soft);
	--wh-error:   var(--err);  --wh-error-text:   var(--err-soft-ink);  --wh-error-tint:   var(--err-soft);
	--wh-info:    var(--info); --wh-info-text:    var(--info-soft-ink); --wh-info-tint:    var(--info-soft);
	--wh-radius-sm:   6px;
	--wh-radius-md:   10px;
	--wh-radius-lg:   14px;
	--wh-shadow-card: var(--shadow-1);
}

/* Responsive --page-pad ladder (V2.2 almost-full-width register).
   Targets ~94-96% effective content width at every desktop+ tier — Aritzia /
   Ssense / COS / NAP / Mr Porter convention (2026 fashion + photo-led
   editorial e-commerce). Earlier V2.1 register kept 120/160 gutters which
   read as "magazine spread" instead of premium retail. Mobile + tablet
   unchanged — those values are already industry standard.
   Keep in sync with --bp-* above + design preview §20. */
@media (min-width: 1920px) { :root { --page-pad: 56px; } } /* big screen — 1808 effective on 1920 (94%) */
@media (min-width: 1680px) and (max-width: 1919px) { :root { --page-pad: 48px; } } /* wide-cap */
@media (max-width: 1279px) { :root { --page-pad: 32px; } } /* laptop — was 40 */
@media (max-width: 1023px) { :root { --page-pad: 24px; } }
@media (max-width: 639px) { :root { --page-pad: 16px; } }

/* ---- Chrome heights ----
   USP top bar height. Consumed by `css/wh-topbar.css` and (potentially) by
   any future component that needs to know how much vertical chrome sits
   above the sticky topnav. Topnav itself sticks alone — the bar scrolls
   away with the page, so most layouts don't need to subtract this. */
:root { --wh-topbar-h: 32px; }
@media (max-width: 639px) { :root { --wh-topbar-h: 28px; } }

/* ---- Base ---- */

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

body {
	font-family: var(--font-body);
	color: var(--ink);
	background: var(--bg);
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
	font-feature-settings: "ss01", "ss02", "cv11";
}

/* ---- Page container utility ----
 * `:not(body)` guard: WordPress adds `class="page"` to `<body>` on
 * every WP-Page render (Materialen, Inspiratie, Over, …). Without
 * this guard, the utility's `padding-inline: var(--page-pad)` would
 * land on the body and push the topnav inward — visible on every
 * inner page but not the homepage (which gets `home blog` instead). */
.page:not(body) {
	max-width: var(--page-max);
	margin-inline: auto;
	padding-inline: var(--page-pad);
}

/* ---- Typographic primitives ---- */

.display {
	font-family: var(--font-display);
	font-weight: 400;
	letter-spacing: -0.01em;
	line-height: 1.02;
}

/* V2 fluid display scale */
.display-xxl { font-family: var(--font-display); font-size: clamp(80px, 13vw, 220px); line-height: 0.88; letter-spacing: -0.045em; font-weight: 400; }
.display-xl  { font-family: var(--font-display); font-size: clamp(56px,  7vw,  96px); line-height: 0.96; letter-spacing: -0.035em; font-weight: 400; }
.display-l   { font-family: var(--font-display); font-size: clamp(40px,  5vw,  72px); line-height: 1.00; letter-spacing: -0.030em; font-weight: 400; }

.serif {
	font-family: var(--font-display);
	font-weight: 400;
}

.mono {
	font-family: var(--font-mono);
	font-weight: 500;
	letter-spacing: .16em;
	text-transform: uppercase;
	font-feature-settings: "tnum";
}

.eyebrow {
	font-family: var(--font-mono);
	font-size: 11px;
	font-weight: 500;
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--ink-muted);
}

.label {
	font-size: 12px;
	letter-spacing: .02em;
	color: var(--ink-muted);
}

/* ---- Buttons (pill) ---- */

.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	height: 44px;
	padding: 0 20px;
	border-radius: var(--radius-pill);
	font: 500 14px/1 var(--font-body);
	letter-spacing: .01em;
	border: 1px solid transparent;
	cursor: pointer;
	transition: all .18s var(--ease);
	text-decoration: none;
	white-space: nowrap;
}

.btn-primary       { background: var(--ink);    color: var(--bg); }
.btn-primary:hover { background: var(--accent); color: var(--on-ink); }

.btn-accent        { background: var(--accent);     color: var(--on-ink); }
.btn-accent:hover  { background: var(--accent-ink); color: var(--on-ink); }

.btn-ghost         { background: transparent; color: var(--ink); border-color: var(--border-strong); }
.btn-ghost:hover   { background: var(--ink);  color: var(--bg);  border-color: var(--ink); }

.btn-sm { height: 34px; padding: 0 14px; font-size: 13px; }
.btn-lg { height: 52px; padding: 0 28px; font-size: 15px; }

.btn[disabled],
.btn[aria-disabled="true"] {
	opacity: .35;
	cursor: not-allowed;
	pointer-events: none;
}

/* ---- Scrollbars ---- */

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 10px; border: 2px solid var(--bg); }
::-webkit-scrollbar-track { background: transparent; }

/* ---- Placeholder image (striped) ----
   Decorative atom — gradient stops are an exception to the no-raw-hex policy
   per Vault/Design Tokens Policy.md. */

.ph {
	background-image:
		repeating-linear-gradient(45deg, rgba(26, 31, 34, .05) 0 2px, transparent 2px 14px),
		linear-gradient(180deg, #E4E8EA, #CED6DA);
	position: relative;
	overflow: hidden;
}
.ph::after {
	content: attr(data-label);
	position: absolute;
	inset: 0;
	display: grid;
	place-items: center;
	font: 400 10px/1 var(--font-mono);
	letter-spacing: .18em;
	text-transform: uppercase;
	color: #5A6063;
}
.ph-dark {
	background-image:
		repeating-linear-gradient(45deg, rgba(255, 255, 255, .04) 0 2px, transparent 2px 14px),
		linear-gradient(180deg, #12171A, #1A1F22);
	color: #9AA1A4;
}

/* ---- Generic chrome ---- */

.panel {
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--r-md);
}

.hr {
	height: 1px;
	background: var(--border);
	border: 0;
	margin: 0;
}

/* ================================================================== */
/* Layout reset — Storefront ships with a right sidebar. We suppress it */
/* everywhere so the editorial chrome can own the full viewport.         */
/* ================================================================== */

body #secondary,
body aside.widget-area,
body .storefront-handheld-footer-bar {
	display: none !important;
}

body.no-sidebar #primary,
body #primary.content-area,
body.no-sidebar .site-main,
body .site-main {
	width: 100% !important;
	max-width: none !important;
	float: none !important;
	margin: 0 !important;
}

/* Storefront wraps most pages in <div id="page" class="hfeed site"> with
   restrictive padding. Override so our editorial sections go edge-to-edge. */
body .site {
	max-width: none !important;
}
body .site-content,
body #content.site-content {
	padding: 0 !important;
}
body .content-area {
	padding-inline: 0 !important;
}

/* Default generic-page inset (Materialen / Inspiratie / etc.).
 * Horizontal gutter follows the canonical viewport ladder via
 * `--page-pad` (see §20 of the design system). Cart + checkout +
 * account override this back to 0 via their body-class rules. */
body .wh-main {
	max-width: 1400px;
	margin: 0 auto;
	padding: 48px var(--page-pad) 96px;
}
@media (max-width: 1023px) {
	body .wh-main { padding: 32px var(--page-pad) 64px; }
}

/* ─────────────────────────────────────────────────────────────────
 * Focus rings — Storefront ships a hard-coded purple (#7f54b3) outline
 * on every focused link/input/button. Override site-wide:
 *   • Mouse interactions: no outline (avoids the "purple border on
 *     anything I click" feeling the user reported).
 *   • Keyboard navigation: clean accent ring so a11y is preserved.
 * ───────────────────────────────────────────────────────────────── */
a:focus,
input:focus,
textarea:focus,
button:focus,
select:focus,
[tabindex]:focus {
	outline: none;
}
a:focus-visible,
input:focus-visible,
textarea:focus-visible,
button:focus-visible,
select:focus-visible,
[tabindex]:focus-visible {
	outline: 2px solid var( --color-accent, #235C68 );
	outline-offset: 2px;
}

/* Storefront's customizer inline CSS (storefront-style-inline-css) sets
 * `outline-color: #7f54b3` (Woo purple) on TYPED selectors —
 * `input[type="email"]:focus`, `input[type="password"]:focus`, … — at
 * specificity (0,2,1), which out-ranks the (0,1,1) ring above. Its list
 * omits input[type="text"], so e.g. the login username field rang teal
 * while the register e-mail field rang purple. Mirror the same typed
 * selectors so the cascade (this file loads after the inline style)
 * re-asserts the brand accent everywhere. */
input[type="email"]:focus,
input[type="tel"]:focus,
input[type="url"]:focus,
input[type="password"]:focus,
input[type="search"]:focus,
input[type="button"]:focus,
input[type="reset"]:focus,
input[type="submit"]:focus,
.button.alt:focus {
	outline-color: var( --color-accent, #235C68 );
}

/* ─────────────────────────────────────────────────────────────────
 * WooCommerce notices — one consistent Wandhaus treatment.
 *
 * Storefront's parent CSS does a lot here: absolute-positioned icon
 * pseudo-elements with FontAwesome glyphs, hard-coded green/red bg
 * colors, generous left padding to clear the absolute icon, and
 * `:first-child { margin-top: 2.6em }`. We need to forcefully
 * neutralise all of that — `!important` is unfortunately required
 * because Storefront also uses `!important` on enough of those rules
 * that pure-specificity overrides aren't reliable here.
 * ───────────────────────────────────────────────────────────────── */
/* Wrapper: inherit Storefront's natural placement (inside the main content
 * column, after the page H1). No forced width/margin override — that was
 * making the notice float above the page header on cart/shop pages where
 * Storefront's parent theme positions the wrapper just under the header
 * region. We only normalise the empty-state collapse. */
body .woocommerce-notices-wrapper:empty {
	margin: 0 !important;
	padding: 0 !important;
}

/* ─────────────────────────────────────────────────────────────────
 * Global notices — bottom-center toast stack (replaces the V2 band).
 *
 * Toast styling lives in `css/wh-toasts.css` (scoped to .wh-toast,
 * .wh-toast-stack). The body-prefixed `body .woocommerce-message`
 * register below stays as a fallback for any notice that escapes the
 * toast pipeline (e.g. block-checkout edge cases, account dashboard
 * inline notices) — they'll render with the V2.3 inline styling rather
 * than as toasts.
 * ───────────────────────────────────────────────────────────────── */

/* V2.3 notice register — applies everywhere: account tabs,
 * empty-state inline notices, modern Woo block-class variants. Kept on
 * `body`-prefixed selectors so any place Woo emits a notice picks this
 * styling up automatically. */
body .woocommerce-message,
body .woocommerce-error,
body .woocommerce-info,
body .woocommerce-Message,
body .woocommerce-noreviews,
body .woocommerce-NoOrders,
body .wc-block-components-notice-banner {
	display: flex !important;
	align-items: flex-start;
	gap: 12px;
	background: var(--info-soft) !important;
	border: 1px solid var(--border, #E4E8EA) !important;
	border-left: 2px solid var(--ink-muted) !important;
	color: var(--ink, #1A1F22) !important;
	padding: 14px 18px !important;
	margin: 0 0 12px !important;
	border-radius: 0 !important;
	font: 400 14px/1.5 var(--font-body, 'Inter', sans-serif) !important;
	list-style: none !important;
	box-shadow: none !important;
	position: relative;
}
body .woocommerce-message:first-child,
body .woocommerce-error:first-child,
body .woocommerce-info:first-child,
body .woocommerce-Message:first-child,
body .woocommerce-noreviews:first-child,
body .woocommerce-NoOrders:first-child,
body .wc-block-components-notice-banner:first-child {
	margin-top: 0 !important;
}
/* State variants — modifier classes (.is-info, .is-success, .is-error)
 * cover the modern Gutenberg/block-based Woo notices. */
body .woocommerce-message,
body .woocommerce-Message,
body .wc-block-components-notice-banner.is-success {
	border-left-color: var(--ok, #2E7D55) !important;
	background: var(--ok-soft, #E8F3EC) !important;
}
body .woocommerce-error,
body .wc-block-components-notice-banner.is-error {
	border-left-color: var(--err, #C0453B) !important;
	background: var(--err-soft, #FBECEA) !important;
}
body .woocommerce-info,
body .woocommerce-noreviews,
body .woocommerce-NoOrders,
body .wc-block-components-notice-banner.is-info,
body .wc-block-components-notice-banner.is-warning {
	border-left-color: var(--ink-muted) !important;
	background: var(--info-soft) !important;
}

/* Inline SVG icon via `::before`. Static position so it joins the flex
 * flow at the left edge of the notice content. Each state gets its own
 * SVG via background-image. */
body .woocommerce-message::before,
body .woocommerce-error::before,
body .woocommerce-info::before,
body .woocommerce-Message::before,
body .woocommerce-noreviews::before,
body .woocommerce-NoOrders::before {
	content: "" !important;
	display: inline-block !important;
	position: static !important;
	top: auto !important;
	left: auto !important;
	font-family: inherit !important;
	color: inherit !important;
	width: 18px !important;
	height: 18px !important;
	flex-shrink: 0;
	margin: 2px 0 0 0 !important;
	background-repeat: no-repeat !important;
	background-position: center !important;
	background-size: contain !important;
}
body .woocommerce-message::before,
body .woocommerce-Message::before {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232E7D55' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") !important;
}
body .woocommerce-error::before {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23C0453B' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='12' y1='8' x2='12' y2='12'/%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'/%3E%3C/svg%3E") !important;
}
/* Info icon now uses neutral --ink-muted (#5A6063) stroke instead of
 * accent (terracotta) — matches the V2.3 info-pill register so info
 * notices don't read as errors. */
body .woocommerce-info::before,
body .woocommerce-noreviews::before,
body .woocommerce-NoOrders::before {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235A6063' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='12' y1='16' x2='12' y2='12'/%3E%3Cline x1='12' y1='8' x2='12.01' y2='8'/%3E%3C/svg%3E") !important;
}

/* Inline links inside notices */
body .woocommerce-message a,
body .woocommerce-error a,
body .woocommerce-info a,
body .woocommerce-Message a,
body .woocommerce-noreviews a,
body .woocommerce-NoOrders a,
body .wc-block-components-notice-banner a {
	color: var(--ink, #1A1F22) !important;
	font-weight: 500;
	text-decoration: underline;
	text-decoration-color: var(--ink-muted) !important;
	text-underline-offset: 3px;
	opacity: 1 !important;
	transition: color .15s var(--ease), text-decoration-color .15s var(--ease);
}
body .woocommerce-message a:hover,
body .woocommerce-error a:hover,
body .woocommerce-info a:hover,
body .woocommerce-Message a:hover,
body .woocommerce-noreviews a:hover,
body .woocommerce-NoOrders a:hover,
body .wc-block-components-notice-banner a:hover {
	color: var(--accent, #235C68) !important;
	text-decoration-color: var(--accent, #235C68) !important;
}

/* "Restore" / view-cart inline buttons — Storefront floats them right with
 * a left border. Strip that and let flexbox handle alignment via auto-margin. */
body .woocommerce-message .button,
body .woocommerce-error .button,
body .woocommerce-info .button {
	background: transparent !important;
	color: var(--ink, #1A1F22) !important;
	padding: 0 !important;
	border: 0 !important;
	border-bottom: 1px solid currentColor !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	font: inherit !important;
	font-weight: 500 !important;
	letter-spacing: 0 !important;
	text-transform: none !important;
	margin-left: auto !important;
	float: none !important;
	flex-shrink: 0;
}
body .woocommerce-message .button:hover,
body .woocommerce-error .button:hover,
body .woocommerce-info .button:hover {
	background: transparent !important;
	color: var(--accent, #235C68) !important;
	opacity: 1 !important;
}

/* Storefront uses ::after as a clearfix — kill it so it doesn't add an
 * empty box inside our flex container and push the button onto a new line. */
body .woocommerce-message::after,
body .woocommerce-error::after,
body .woocommerce-info::after {
	display: none !important;
	content: none !important;
}

/* ─────────────────────────────────────────────────────────────────
 * WooCommerce loaders — replace the default jQuery blockUI loader
 * GIF + harsh overlay with a Wandhaus-branded CSS spinner.
 *
 * blockUI is what WC uses to mask the cart / mini-cart / checkout
 * review-order area while qty updates, coupon-apply, AJAX fragment
 * refreshes, and Place-Order are in flight. Out of the box it
 * paints a black 60%-opacity overlay with a circular GIF — looks
 * generic and clashes with our V2 white/terracotta palette.
 *
 * Selectors are the canonical jQuery blockUI ones (cannot be
 * changed without forking WC's JS), so we override their inline
 * styles with !important. Same approach Storefront's parent uses.
 * ───────────────────────────────────────────────────────────────── */

/* The overlay: soft white wash, no GIF. */
.blockUI.blockOverlay,
body .blockUI.blockOverlay {
	background-image: none !important;
	background-color: var(--bg, #FFFFFF) !important;
	opacity: .78 !important;
	cursor: progress !important;
	transition: opacity .15s ease;
}
/* WC ships a `.blockUI.blockOverlay::before` pseudo with its own
 * loader.svg + spin animation. Suppress it — our `.processing::after`
 * pseudo on the parent already shows the Wandhaus spinner, and leaving
 * WC's pseudo active produces a double-spinner overlap. */
.blockUI.blockOverlay::before,
.blockUI.blockOverlay::after,
body .blockUI.blockOverlay::before,
body .blockUI.blockOverlay::after {
	display: none !important;
	content: none !important;
	background: none !important;
	animation: none !important;
}
/* WC's blockMsg is the centered "Loading…" text element; we don't use it. */
.blockUI.blockMsg {
	display: none !important;
}
/* The blockMsg (text shown alongside loader on some interactions) */
.blockUI.blockMsg {
	background: transparent !important;
	border: 0 !important;
	color: var(--ink, #1A1F22) !important;
	font-family: var(--font-body, 'Inter', sans-serif) !important;
	font-size: 13px !important;
	font-weight: 500 !important;
}

/* The branded spinner — overlaid on the SAME element that gets the
 * blockUI overlay (so it's centered over whatever zone is loading).
 * blockUI applies `position:relative` on the blocked element, so an
 * absolute pseudo on `.processing` reliably centers. WC adds the
 * `.processing` class to the form/section while AJAX is in flight,
 * which gives us a stable hook that doesn't depend on jQuery internals. */
.processing,
form.checkout.processing,
.woocommerce-cart-form.processing,
.woocommerce-cart .cart_totals.processing,
.cart_totals.processing,
.woocommerce-checkout-review-order.processing,
.cart-collaterals .cart_totals.processing,
form.woocommerce-cart-form.processing {
	position: relative;
}
.processing::after,
form.checkout.processing::after,
.woocommerce-cart-form.processing::after,
.woocommerce-cart .cart_totals.processing::after,
.cart_totals.processing::after,
.woocommerce-checkout-review-order.processing::after,
.cart-collaterals .cart_totals.processing::after,
form.woocommerce-cart-form.processing::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 36px;
	height: 36px;
	margin: -18px 0 0 -18px;
	border: 3px solid rgba(26, 31, 34, .12);
	border-top-color: var(--accent, #235C68);
	border-radius: 50%;
	animation: wh-loader-spin 700ms linear infinite;
	z-index: 1001; /* above blockUI's own ::before */
	box-sizing: border-box;
}
@keyframes wh-loader-spin {
	to { transform: rotate(360deg); }
}

/* WC's "Place order" / "Apply coupon" / "Update cart" buttons get a
 * `.loading` class while their request is in flight. Replace the
 * default trailing GIF with a small inline spinner inside the button. */
.button.loading,
.button.loading::after {
	background-image: none !important;
}
.button.loading {
	position: relative;
	color: transparent !important;
	pointer-events: none;
}
.button.loading::after {
	content: "" !important;
	position: absolute;
	top: 50%;
	left: 50%;
	width: 16px;
	height: 16px;
	margin: -8px 0 0 -8px;
	border: 2px solid rgba(255, 255, 255, .35);
	border-top-color: var(--on-ink, #FFFFFF);
	border-radius: 50%;
	animation: wh-loader-spin 600ms linear infinite;
	display: block !important;
}
/* Ghost buttons that might use ink color instead of white */
.btn-ghost.loading::after,
.button.alt:not(.checkout-button):not([style*="background"]).loading::after {
	border-color: rgba(26, 31, 34, .15);
	border-top-color: var(--ink, #1A1F22);
}

/* The cart-item row's "removing" state (when × is clicked) */
.woocommerce-cart-form__cart-item.removing,
tr.cart_item.removing {
	opacity: .45 !important;
	transition: opacity .2s ease;
}

/* Storefront's mini-cart shows a small loader during AJAX. Same treatment. */
.widget_shopping_cart .blockUI.blockOverlay {
	background-color: var(--surface, #FFFFFF) !important;
	opacity: .85 !important;
}

/* Generic processing badge that cart-totals area gets (some WC versions
 * apply `.is-loading` instead of `.processing`). Belt-and-suspenders. */
.is-loading,
.woocommerce-loading {
	position: relative;
}
.is-loading::after,
.woocommerce-loading::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 36px;
	height: 36px;
	margin: -18px 0 0 -18px;
	border: 3px solid rgba(26, 31, 34, .12);
	border-top-color: var(--accent, #235C68);
	border-radius: 50%;
	animation: wh-loader-spin 700ms linear infinite;
	z-index: 1001;
}
