/*
Theme Name:      Kyrex Storefront
Theme URI:       https://kyrex.org
Description:     Storefront theme for the celebrations & gifting store. Built by Kyrex.
Author:          Kyrex
Author URI:      https://kyrex.org
Requires Plugins: kyrex-core
Version:         0.59.0
License:         GNU General Public License v2 or later
License URI:     https://www.gnu.org/licenses/gpl-2.0.html
Text Domain:     kyrex-storefront
*/

/* ── Self-hosted fonts ─────────────────────────────────────────────
   No Google Fonts CDN — all three files are served from this theme.
   See assets/fonts/OFL.txt for licensing (SIL OFL 1.1). Playfair Display
   ships as two static-weight-range files (upright + a separate italic
   face); Jost ships as one upright variable-weight file. ──────────── */

@font-face {
	font-family: 'Playfair Display';
	src: url('assets/fonts/playfair.woff2') format('woff2-variations'),
	     url('assets/fonts/playfair.woff2') format('woff2');
	font-weight: 400 900;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: 'Playfair Display';
	src: url('assets/fonts/playfair-italic.woff2') format('woff2-variations'),
	     url('assets/fonts/playfair-italic.woff2') format('woff2');
	font-weight: 400 900;
	font-style: italic;
	font-display: swap;
}

@font-face {
	font-family: 'Jost';
	src: url('assets/fonts/jost.woff2') format('woff2-variations'),
	     url('assets/fonts/jost.woff2') format('woff2');
	font-weight: 300 700;
	font-style: normal;
	font-display: swap;
}

/* ── Metrics-matched fallbacks ─────────────────────────────────────
   These are not extra fonts to download — they are the *system* fonts,
   re-declared with their metrics bent to match the web fonts.

   The problem they solve, measured rather than assumed: with plain
   `font-display: swap`, the homepage painted in Georgia/Helvetica and then
   reflowed when Playfair and Jost arrived, because the fallback sets different
   line heights and advance widths. Cold-load CLS was **0.3595** — the nav and
   chips jumping 19px to 23px and 34px to 37px, and the hero headline rewrapping
   and moving 80px. Anything above 0.1 is a poor score.

   size-adjust scales the fallback's advance widths to the web font's; the
   ascent/descent overrides pin its line box to the same height. The values come
   from measuring both faces at 100px in a real browser (canvas TextMetrics), not
   from a table — see the Task 7 notes in the Phase 4 plan.

   Ordered AFTER the real faces in the font stacks below, so they are only ever
   used during the swap window. */

@font-face {
	font-family: 'Playfair Fallback';
	src: local('Georgia'), local('Times New Roman');
	size-adjust: 99.49%;
	ascent-override: 108.55%;
	descent-override: 25.13%;
	line-gap-override: 0%;
}

@font-face {
	font-family: 'Jost Fallback';
	src: local('Helvetica Neue'), local('Helvetica'), local('Arial');
	size-adjust: 94.42%;
	ascent-override: 113.32%;
	descent-override: 40.25%;
	line-gap-override: 0%;
}

/* ── Client brand tokens ──────────────────────────────────────────
   Palette approved against the Framer prototype (2026-08). The accent
   is set per occasion category from term meta and is the only value
   that varies between pages. ───────────────────────────────────── */

:root {
	--kyrex-ivory:          #FAF6EF;
	--kyrex-surface:        #FFFDF9;
	--kyrex-charcoal:       #2A2622;
	--kyrex-charcoal-muted: #5C544C;
	--kyrex-gold:           #B08D3F;
	--kyrex-gold-soft:      #D9C08A;

	/* Gold, darkened along its own hue (41deg) until it clears WCAG AA as
	   TEXT. Plain --kyrex-gold is 2.90:1 on ivory — fine as a fill, a border
	   or an underline, and well short of the 4.5:1 that body-size text needs.
	   Use this one whenever gold is the colour of words. */
	--kyrex-gold-deep:      #876C30;
	--kyrex-border:         #E8DFD0;

	/* Occasion accents — one is promoted to --kyrex-accent per category */
	--kyrex-wine:      #6B1F2E;
	--kyrex-emerald:   #1B5E43;
	--kyrex-sapphire:  #22366B;

	--kyrex-accent: var(--kyrex-wine);

	/* Radius scale — the prototype uses restrained, consistent rounding on
	   cards, chips, and buttons. Kept as tokens so nothing hardcodes a px
	   value inline. */
	--kyrex-radius-sm:   8px;
	--kyrex-radius-lg:   10px;
	--kyrex-radius-pill: 999px;

	/* Elevation — charcoal at low alpha rather than a neutral grey, so the
	   shadow reads as part of the warm palette instead of muddying it. Kept
	   as a token so the sticky header is not the only thing that can use it. */
	--kyrex-shadow-sm: 0 2px 12px rgb(42 38 34 / 8%);

	/* Type — Playfair Display for headings, Jost for body. */
	--kyrex-font-display: 'Playfair Display', 'Playfair Fallback', ui-serif, Georgia, serif;
	--kyrex-font-body:    'Jost', 'Jost Fallback', ui-sans-serif, system-ui, sans-serif;
}

body {
	background-color: var(--kyrex-ivory);
	color: var(--kyrex-charcoal);
	font-family: var(--kyrex-font-body);
}

h1, h2, h3, h4, h5, h6 {
	font-family: var(--kyrex-font-display);
	letter-spacing: -0.02em;
	font-weight: 600;
}

/* ── Links ───────────────────────────────────────────────────────
   The parent theme leaves links at a magenta default (#CC3366) that
   appears nowhere in this brand — it was showing on the site title and
   every content link. The brand kit calls for plain text links with a
   thin gold underline on hover.

   POSITIVE SCOPE, not a blocklist: rather than styling every `a` on the
   page and then carving components back out with a growing chain of
   `:not()` exclusions, this rule targets only the containers where prose
   actually lives — page/post body copy (`.page-content`, rendered by the
   parent theme's template-parts for single/archive/search/404), comment
   text, and the two WooCommerce product description blocks. Components
   (chips, buttons, footer nav, primary nav, product-card links, the
   text-CTA) live outside these containers, so they style themselves via
   their own rules in homepage.css / catalogue.css / product.css without
   ever needing an exclusion here — a new link component added anywhere
   outside prose never has to touch this selector.

   No `:not(#wpadminbar a)` needed either: the admin bar is never inside
   these content containers, so it's naturally untouched — and no
   selector here carries ID-level specificity. */

.page-content a,
.comment-content a,
.kyrex-product__short-description a,
.kyrex-product__inclusions-body a {
	color: var(--kyrex-charcoal);
	text-decoration: none;
	border-bottom: 1px solid transparent;
	transition: color 200ms ease, border-color 200ms ease;
}

.page-content a:hover,
.page-content a:focus-visible,
.comment-content a:hover,
.comment-content a:focus-visible,
.kyrex-product__short-description a:hover,
.kyrex-product__short-description a:focus-visible,
.kyrex-product__inclusions-body a:hover,
.kyrex-product__inclusions-body a:focus-visible {
	color: var(--kyrex-charcoal);
	border-bottom-color: var(--kyrex-gold);
}

/*
 * The site title is a wordmark, not a link that should look clickable — and
 * it must render in the display serif (Playfair Display), not the body
 * sans (Jost) it was inheriting. The parent theme's own
 * `.site-header .site-title { font-size:2.5rem; font-weight:500; ... }`
 * (assets/css/header-footer.css) is two classes deep (0,2,0); `#site-header`
 * is an ID already present on the markup, so `#site-header .site-title`
 * (1,1,0) outranks it without touching parent files. Font-size is left
 * alone (the parent's 2.5rem already reads as a logotype at this weight).
 */
#site-header .site-title,
#site-header .site-title a {
	font-family: var(--kyrex-font-display);
	font-weight: 600;
	letter-spacing: -0.01em;
	color: var(--kyrex-charcoal);
	border-bottom-color: transparent;
}

/*
 * FIX 4 — primary nav (Occasions · Packages · Gallery · Enquire), rendered
 * by the parent theme's dynamic-header.php via wp_nav_menu( 'menu-1' ):
 * plain text links, thin gold underline on hover/:focus-visible, no pills.
 * Deliberately carved out of the generic link rule above (:not(.site-navigation a))
 * rather than fought via specificity — this block is the sole source of
 * truth for nav link styling, so there is no ID-vs-class race to lose.
 * Scoped to `.site-navigation ul.menu li a` (not `.kyrex-chip`), so the
 * occasion chip row — pills by design — is untouched.
 */
.site-navigation ul.menu li a {
	font-family: var(--kyrex-font-body);
	font-size: 0.8125rem;
	font-weight: 500;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--kyrex-charcoal);
	text-decoration: none;
	background-color: transparent;
	border: none;
	border-bottom: 1px solid transparent;
	border-radius: 0;
	transition: color 150ms ease, border-color 150ms ease;
}

.site-navigation ul.menu li a:hover,
.site-navigation ul.menu li a:focus-visible {
	color: var(--kyrex-charcoal);
	border-bottom-color: var(--kyrex-gold);
}

/* Cards take a top border only — never a full accent fill. */
.kyrex-card {
	background-color: var(--kyrex-surface);
	border: 1px solid var(--kyrex-border);
	border-top: 3px solid var(--kyrex-accent);
}

/* ── Shared layout primitives ─────────────────────────────────────
   .kyrex-container, .kyrex-section, .kyrex-eyebrow, and the shared part
   of .kyrex-heading were duplicated verbatim in both assets/homepage.css
   and assets/product.css (a selector diff across all three page-scoped
   stylesheets confirmed these four are the only repeats). One copy had
   already drifted: assets/product.css's .kyrex-heading used
   margin-bottom: 1.5rem with no max-width, while assets/homepage.css used
   margin-bottom: 2.5rem and max-width: 36rem — despite product.css's own
   header comment claiming it "intentionally duplicates" homepage.css.
   That silent divergence is exactly the risk this move removes.

   This file is a declared `wp_enqueue_style()` dependency of every
   page-scoped stylesheet and loads on every request, so these primitives
   now live here ONCE. Page-scoped files (assets/homepage.css,
   assets/catalogue.css, assets/product.css) must NOT redefine
   .kyrex-container, .kyrex-section, .kyrex-eyebrow, or this shared part of
   .kyrex-heading — extend only via a more specific selector, the way
   .kyrex-catalogue__title / .kyrex-product__title already override
   margin-bottom. The .kyrex-heading spacing difference above was a real,
   page-specific need (not accidental), so it stays as two small, commented
   overrides in homepage.css and product.css rather than being collapsed
   into one guessed value. ──────────────────────────────────────────── */

.kyrex-container {
	max-width: 72rem;
	margin-inline: auto;
	padding-inline: 1.5rem;
}

.kyrex-section {
	padding-block: clamp(3rem, 6vw, 6rem);
}

.kyrex-eyebrow {
	font-family: var(--kyrex-font-body);
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--kyrex-gold-deep);
	margin: 0 0 1rem;
}

.kyrex-heading {
	font-family: var(--kyrex-font-display);
	font-weight: 600;
	letter-spacing: -0.02em;
	line-height: 1.15;
	font-size: clamp(1.75rem, 1.3rem + 2vw, 2.75rem);
	margin: 0;
}

/* ── Base layout ───────────────────────────────────────────────────
   The theme is standalone now — it no longer inherits hello-elementor's
   reset.css/theme.css, so the handful of resets those files provided move
   here. Deliberately minimal: only what real content on this site needs. */

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

body {
	margin: 0;
}

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

/*
 * The parent theme's reset.css used to strip the browser default blue,
 * underlined link style; every component in this theme (nav, chips,
 * buttons, footer, .page-content prose) already sets its own
 * text-decoration/color explicitly EXCEPT the site-title wordmark link,
 * which relied on that parent reset and was showing a stray underline
 * once it was gone. `color: inherit` (not a new hex) plus
 * `text-decoration: none` restores the same baseline everywhere else too.
 */
a {
	color: inherit;
	text-decoration: none;
}

/* ── Skip link ─────────────────────────────────────────────────────
   Visually hidden until focused, matching the standard WordPress
   `.screen-reader-text` treatment so header.php's skip-to-content link is
   reachable by keyboard but invisible otherwise. */

.screen-reader-text {
	border: 0;
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
	word-wrap: normal !important;
}

.skip-link.screen-reader-text:focus {
	background-color: var(--kyrex-ivory);
	border-radius: var(--kyrex-radius-sm);
	box-shadow: 0 0 0 2px var(--kyrex-charcoal);
	clip: auto !important;
	clip-path: none;
	color: var(--kyrex-charcoal);
	display: block;
	font-family: var(--kyrex-font-body);
	font-size: 0.875rem;
	font-weight: 600;
	height: auto;
	left: 1rem;
	line-height: normal;
	padding: 0.75rem 1.25rem;
	text-decoration: none;
	top: 1rem;
	width: auto;
	z-index: 100000;
}

/* ── WooCommerce notices ───────────────────────────────────────────
   Global on purpose. These rules lived twice — scoped to
   `.kyrex-product` in product.css and to `.kyrex-catalogue__intro` in
   catalogue.css — which meant a notice on the cart, checkout, account,
   search, 404 or home page rendered completely unstyled. Same rules,
   one copy, no scope.

   THE ELEMENT SELECTOR MATTERS. Both old copies targeted
   `ul.woocommerce-message` and `ul.woocommerce-info`, and neither ever
   matched anything: WooCommerce renders only `error` as a `<ul>`
   (templates/notices/error.php). `success` and `notice` are `<div>`s.
   Verified against the running site — an add-to-cart success comes back
   as `<div class="woocommerce-message" role="alert">`. So success and
   info notices were unstyled for the whole of Phases 1–3. These
   selectors name no element for exactly that reason.

   Each type also gets its own edge colour. Previously all three shared a
   gold border, so "added to your cart" and "that slot is no longer
   available" were visually identical and a shopper had to read the text
   to tell whether something had gone wrong. */

.woocommerce-notices-wrapper:not(:empty) {
	margin-bottom: 2rem;
}

.woocommerce-message,
.woocommerce-error,
.woocommerce-info {
	list-style: none;
	margin: 0 0 1.5rem;
	padding: 0.875rem 1.25rem;
	background-color: var(--kyrex-surface);
	border: 1px solid var(--kyrex-border);
	border-left: 3px solid var(--kyrex-gold);
	font-family: var(--kyrex-font-body);
	font-size: 0.9375rem;
	color: var(--kyrex-charcoal);
}

/* Colour carries meaning, but never alone — the wording already says what
   happened, so this reinforces rather than replaces it. That matters for
   anyone who cannot distinguish the two edges. */
.woocommerce-message {
	border-left-color: var(--kyrex-emerald);
}

.woocommerce-error {
	border-left-color: var(--kyrex-wine);
}

.woocommerce-info {
	border-left-color: var(--kyrex-gold);
}

.woocommerce-message a,
.woocommerce-error a,
.woocommerce-info a {
	color: var(--kyrex-charcoal);
	font-weight: 600;
	border-bottom: 1px solid var(--kyrex-gold);
}

/*
 * Kill WooCommerce's icon glyph on notices.
 *
 * It sets `content` to a private-use codepoint in `font-family: WooCommerce`.
 * This theme does not load that icon font, so it rendered as an empty box —
 * visible on the checkout coupon notice as a stray glyph before "Have a
 * coupon?". The coloured left edge already carries the same signal, in the
 * brand palette rather than WooCommerce blue.
 */
.woocommerce-message::before,
.woocommerce-error::before,
.woocommerce-info::before {
	display: none;
	content: none;
}

/* Multi-error lists keep their bullets suppressed but stay readable. */
.woocommerce-error li + li {
	margin-top: 0.375rem;
}

/* ── Reduced motion ────────────────────────────────────────────────
   A single global switch rather than a per-component opt-out.

   Before this, only assets/header.css honoured the preference; the four
   other stylesheets carried eight transitions between them that ignored
   it entirely. A blanket rule also means anything added later is covered
   by default, which a per-component approach cannot promise.

   `!important` is deliberate and is the conventional form of this reset:
   the whole point is to beat component rules that set their own
   durations. */

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

/* ── Site header ───────────────────────────────────────────────────
   Structural layout for #site-header — the parent theme's
   header-footer.css used to provide this; now it's ours. */

#site-header {
	background-color: var(--kyrex-ivory);
	border-bottom: 1px solid var(--kyrex-border);
}

.site-header__inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding-block: 1.25rem;
}

.site-branding {
	display: flex;
	flex-direction: column;
}

.site-navigation ul.menu {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 1.75rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

/* ── Footer ────────────────────────────────────────────────────────
   Moved from assets/homepage.css: footer.php now renders the branded
   footer globally (every template calls get_footer()), so its styles need
   to load on every page, not just the homepage. */

.kyrex-footer {
	background-color: var(--kyrex-charcoal);
	color: var(--kyrex-ivory);
}

.kyrex-footer__inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding-block: 1.75rem;
}

.kyrex-footer__copyright {
	font-family: var(--kyrex-font-body);
	font-size: 0.75rem;
	font-weight: 500;
	letter-spacing: 0.08em;
	color: var(--kyrex-gold-soft);
	margin: 0;
}

.kyrex-footer__nav-list {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 1.5rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.kyrex-footer__nav a {
	font-family: var(--kyrex-font-body);
	font-size: 0.75rem;
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--kyrex-ivory);
	text-decoration: none;
	border-bottom: 1px solid transparent;
	padding-bottom: 0.125rem;
	transition: border-color 150ms ease, color 150ms ease;
}

.kyrex-footer__nav a:hover {
	color: var(--kyrex-gold-soft);
	border-bottom-color: var(--kyrex-gold-soft);
}

/* Policy row. Visually subordinate to the nav above it — sentence case and a
   hairline rule rather than a second row of uppercase tracking competing with
   the first — but the same ivory, because "small print" must not mean "low
   contrast" on the pages a customer reads before parting with money. */

.kyrex-footer__legal {
	border-top: 1px solid rgba(250, 247, 242, 0.16);
}

.kyrex-footer__legal-list {
	display: flex;
	flex-wrap: wrap;
	gap: 0.375rem 1.25rem;
	list-style: none;
	margin: 0;
	padding: 0;
	padding-block: 1rem;
}

.kyrex-footer__legal-list a {
	font-family: var(--kyrex-font-body);
	font-size: 0.75rem;
	color: var(--kyrex-ivory);
	text-decoration: none;
	border-bottom: 1px solid transparent;
	padding-bottom: 0.125rem;
	transition: border-color 150ms ease, color 150ms ease;
}

.kyrex-footer__legal-list a:hover {
	color: var(--kyrex-gold-soft);
	border-bottom-color: var(--kyrex-gold-soft);
}

.kyrex-footer__legal-list a:focus-visible {
	outline: 2px solid var(--kyrex-charcoal);
	outline-offset: 2px;
	box-shadow: 0 0 0 4px var(--kyrex-ivory);
	border-radius: var(--kyrex-radius-sm);
}

/* ── Buttons ───────────────────────────────────────────────────────
   Moved from assets/homepage.css so 404.php and search.php (neither of
   which loads homepage.css) can use the same component. Filled brass gold
   or outlined, uppercase wide-tracked. --outline assumes a dark surface
   (hero/closing overlays); --ghost is the light-surface equivalent used on
   404/search, which sit on the plain ivory page background. */

.kyrex-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-family: var(--kyrex-font-body);
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	text-decoration: none;
	border-radius: var(--kyrex-radius-sm);
	padding: 0.9375rem 1.875rem;
	border: 1px solid transparent;
	cursor: pointer;
	transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}

.kyrex-btn:focus-visible,
.kyrex-footer__nav a:focus-visible {
	outline: 2px solid var(--kyrex-charcoal);
	outline-offset: 2px;
	box-shadow: 0 0 0 4px var(--kyrex-ivory);
	border-radius: var(--kyrex-radius-sm);
}

.kyrex-btn--filled {
	background-color: var(--kyrex-gold);
	color: var(--kyrex-charcoal);
	border-color: var(--kyrex-gold);
}

.kyrex-btn--filled:hover {
	background-color: var(--kyrex-gold-soft);
	border-color: var(--kyrex-gold-soft);
	color: var(--kyrex-charcoal);
}

.kyrex-btn--outline {
	background-color: transparent;
	color: var(--kyrex-ivory);
	border-color: rgba(250, 246, 239, 0.6);
}

.kyrex-btn--outline:hover {
	background-color: rgba(250, 246, 239, 0.12);
	border-color: var(--kyrex-ivory);
	color: var(--kyrex-ivory);
}

.kyrex-btn--ghost {
	background-color: transparent;
	color: var(--kyrex-charcoal);
	border-color: var(--kyrex-border);
}

.kyrex-btn--ghost:hover {
	background-color: var(--kyrex-surface);
	border-color: var(--kyrex-gold);
	color: var(--kyrex-charcoal);
}

/* ── Prose content ─────────────────────────────────────────────────
   Basic content template (page.php, singular.php, index.php) typography:
   plain Pages, blog posts, and the fallback loop. */

/*
 * 48rem is a reading measure. Centred rather than flush left: at 1440px a
 * left-aligned 768px column leaves 500px of dead space on one side, and the
 * header, the occasion chips and every section below are centred — the policy
 * pages were the first prose on the site long enough to make the odd one out
 * obvious.
 */
.kyrex-entry {
	max-width: 48rem;
	margin-inline: auto;
}

/*
 * ...except on the WooCommerce app screens.
 *
 * 48rem is a reading measure, right for a Page of prose and actively wrong for
 * a cart: it squeezed the line-item table into 768px of a 1152px container, so
 * package names wrapped to three lines and the slot wrapped to five. These
 * screens are interfaces, not articles.
 */
body.woocommerce-cart .kyrex-entry,
body.woocommerce-checkout .kyrex-entry,
body.woocommerce-account .kyrex-entry {
	max-width: none;
}

.kyrex-entry__title {
	margin-bottom: 1.5rem;
}

.kyrex-entry__meta {
	font-family: var(--kyrex-font-body);
	font-size: 0.8125rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--kyrex-charcoal-muted);
	margin: -1rem 0 1.5rem;
}

.page-content {
	font-family: var(--kyrex-font-body);
	font-size: 1rem;
	line-height: 1.7;
	color: var(--kyrex-charcoal);
}

.page-content p,
.page-content ul,
.page-content ol {
	margin: 0 0 1.25rem;
}

.page-content h2,
.page-content h3,
.page-content h4 {
	margin: 2rem 0 1rem;
}

/* Opening paragraph of a content page — the brand type scale's step above
   body copy, in the display serif, so About and Contact start the way the
   homepage sections do rather than as an undifferentiated wall of Jost. */

.page-content .kyrex-lead {
	font-family: var(--kyrex-font-display);
	font-size: clamp(1.25rem, 1.05rem + 0.85vw, 1.625rem);
	line-height: 1.4;
	letter-spacing: -0.01em;
	margin-bottom: 2rem;
}

/* ── Disclosure (core/details) ─────────────────────────────────────
   The FAQ accordion. A real <details>/<summary>, not a div and a click
   handler: keyboard operable and announced as expandable with no
   JavaScript at all, and it still works if a script fails.

   The marker is drawn as a rotating chevron via a pseudo-element on the
   summary rather than styling ::marker, which Safari does not reliably
   support — the disclosure triangle is hidden and replaced instead. */

.page-content .wp-block-details {
	border-bottom: 1px solid var(--kyrex-border);
	padding: 0;
}

.page-content .wp-block-details:first-of-type {
	border-top: 1px solid var(--kyrex-border);
}

.page-content .wp-block-details summary {
	position: relative;
	display: block;
	cursor: pointer;
	list-style: none;
	font-family: var(--kyrex-font-body);
	font-size: 1.0625rem;
	font-weight: 500;
	color: var(--kyrex-charcoal);
	padding: 1.125rem 2.5rem 1.125rem 0;
}

/* Safari and Chrome each need one of these to drop the default triangle. */
.page-content .wp-block-details summary::-webkit-details-marker {
	display: none;
}

.page-content .wp-block-details summary::marker {
	content: '';
}

.page-content .wp-block-details summary::after {
	content: '';
	position: absolute;
	right: 0.5rem;
	top: 50%;
	width: 0.5rem;
	height: 0.5rem;
	margin-top: -0.375rem;
	border-right: 1.5px solid var(--kyrex-gold-deep);
	border-bottom: 1.5px solid var(--kyrex-gold-deep);
	transform: rotate(45deg);
	transform-origin: center;
	transition: transform 180ms ease;
}

.page-content .wp-block-details[open] summary::after {
	transform: rotate(-135deg);
	margin-top: -0.125rem;
}

.page-content .wp-block-details summary:hover {
	color: var(--kyrex-gold-deep);
}

.page-content .wp-block-details summary:focus-visible {
	outline: 2px solid var(--kyrex-charcoal);
	outline-offset: -2px;
	border-radius: var(--kyrex-radius-sm);
}

.page-content .wp-block-details > *:not(summary) {
	margin-left: 0;
}

.page-content .wp-block-details p:last-child {
	padding-bottom: 1.125rem;
	margin-bottom: 0;
	color: var(--kyrex-charcoal-muted);
}

/* ── Designed empty/error states ──────────────────────────────────────
   Shared by 404.php and search.php's no-results state. */

.kyrex-state__inner {
	max-width: 34rem;
	text-align: center;
	margin-inline: auto;
}

.kyrex-state__heading {
	margin-bottom: 1rem;
}

.kyrex-state__copy {
	font-size: 1rem;
	line-height: 1.7;
	color: var(--kyrex-charcoal-muted);
	margin: 0 0 2rem;
}

.kyrex-state__actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 1rem;
}

/* ── Search results ────────────────────────────────────────────────
   Reuses the shared .kyrex-card shell (ivory surface, hairline border,
   top-border accent) rather than the WooCommerce-specific product card
   markup in assets/catalogue.css, which isn't enqueued on search pages. */

.kyrex-search__grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
	gap: 1.5rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.kyrex-search-card {
	padding: 1.5rem;
	border-radius: var(--kyrex-radius-lg);
}

.kyrex-search-card__link {
	display: block;
	text-decoration: none;
	color: inherit;
}

.kyrex-search-card__type {
	display: block;
	font-family: var(--kyrex-font-body);
	font-size: 0.6875rem;
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--kyrex-gold-deep);
	margin-bottom: 0.5rem;
}

.kyrex-search-card__title {
	font-size: 1.25rem;
	margin: 0 0 0.5rem;
}

.kyrex-search-card__excerpt {
	font-family: var(--kyrex-font-body);
	font-size: 0.9375rem;
	line-height: 1.6;
	color: var(--kyrex-charcoal-muted);
	margin: 0;
}

/* ── Pagination ────────────────────────────────────────────────────
   Global counterpart to assets/catalogue.css's .kyrex-catalogue__pagination
   (WooCommerce-specific, not enqueued on search pages) — same visual
   language, applied to core's the_posts_pagination() output. */

.kyrex-pagination {
	display: flex;
	justify-content: center;
	margin-top: 2.5rem;
}

.kyrex-pagination ul.page-numbers {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.kyrex-pagination .page-numbers li {
	display: block;
}

.kyrex-pagination .page-numbers a,
.kyrex-pagination .page-numbers span {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.25rem;
	height: 2.25rem;
	font-family: var(--kyrex-font-body);
	font-size: 0.875rem;
	color: var(--kyrex-charcoal-muted);
	text-decoration: none;
	border: 1px solid transparent;
	border-radius: var(--kyrex-radius-sm);
}

.kyrex-pagination .page-numbers a:hover,
.kyrex-pagination .page-numbers a:focus-visible {
	color: var(--kyrex-charcoal);
	border-color: var(--kyrex-border);
}

.kyrex-pagination .page-numbers .current {
	color: var(--kyrex-charcoal);
	border-color: var(--kyrex-gold);
	font-weight: 600;
}


/* ── WooCommerce buttons ───────────────────────────────────────────
   This theme styles its own buttons, so WooCommerce's are switched off at
   the source rather than overridden.

   WooCommerce guards its button rules with
   `:where(body:not(.woocommerce-block-theme-has-button-styles))`. `:where()`
   contributes no specificity, so the rules still land at (0,3,1) — enough to
   beat any plain class selector this theme writes, whatever the load order.
   Fighting that across cart, checkout and account would mean escalating
   selectors on every button in the store.

   Instead functions.php adds that body class, which is WooCommerce's own
   documented opt-out, and the rules below supply the replacement. That is why
   the class exists: it is the intended path for a theme with its own button
   styles, not a hack.

   Every WooCommerce button therefore inherits the brand look from one place —
   and Task 3's checkout and Phase 6's account screens get it for free. */

.woocommerce .button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce a.button,
.woocommerce #respond input#submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-family: var(--kyrex-font-body);
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	text-decoration: none;
	line-height: 1;
	padding: 0.9375rem 1.875rem;
	border: 1px solid var(--kyrex-charcoal);
	border-radius: var(--kyrex-radius-sm);
	background-color: transparent;
	color: var(--kyrex-charcoal);
	cursor: pointer;
	transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}

.woocommerce .button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce a.button:hover,
.woocommerce #respond input#submit:hover {
	background-color: var(--kyrex-charcoal);
	color: var(--kyrex-ivory);
}

/* `.alt` is WooCommerce's primary action — proceed to checkout, place order. */
.woocommerce .button.alt,
.woocommerce button.button.alt,
.woocommerce input.button.alt,
.woocommerce a.button.alt {
	background-color: var(--kyrex-gold);
	border-color: var(--kyrex-gold);
	color: var(--kyrex-charcoal);
}

.woocommerce .button.alt:hover,
.woocommerce button.button.alt:hover,
.woocommerce input.button.alt:hover,
.woocommerce a.button.alt:hover {
	background-color: var(--kyrex-gold-soft);
	border-color: var(--kyrex-gold-soft);
	color: var(--kyrex-charcoal);
}

.woocommerce .button:focus-visible,
.woocommerce button.button:focus-visible,
.woocommerce input.button:focus-visible,
.woocommerce a.button:focus-visible,
.woocommerce #respond input#submit:focus-visible {
	outline: 2px solid var(--kyrex-charcoal);
	outline-offset: 2px;
}

.woocommerce .button:disabled,
.woocommerce .button.disabled,
.woocommerce button.button:disabled {
	opacity: 0.5;
	cursor: not-allowed;
}

/*
 * The remove-line control.
 *
 * `!important` is not a preference here. WooCommerce sets
 * `.woocommerce a.remove { color: var(--wc-red) !important }`, and an
 * important declaration can only be beaten by another important one.
 */
.woocommerce a.remove {
	color: var(--kyrex-charcoal-muted) !important;
	font-weight: 400;
}

.woocommerce a.remove:hover {
	color: var(--kyrex-wine) !important;
	background: none;
}

/* ── Policy reassurance ───────────────────────────────────────────
   Audit baseline 10.10: the cancellation terms have to be visible before
   the customer commits, not only in the footer. Rendered on the package
   page and the cart by template-parts/policy-reassurance.php, so it lives
   in the global stylesheet rather than in product.css or cart.css — one
   component, two consumers.

   Gold-deep on the link, not plain gold: --kyrex-gold is 2.90:1 on this
   surface and fails as text. */

.kyrex-reassurance {
	display: grid;
	grid-template-columns: 1rem 1fr;
	gap: 0.5rem;
	align-items: start;
	margin: 1.25rem 0 0;
	font-family: var(--kyrex-font-body);
	font-size: 0.8125rem;
	line-height: 1.5;
	color: var(--kyrex-charcoal-muted);
}

.kyrex-reassurance__icon {
	color: var(--kyrex-gold-deep);
	margin-top: 0.125rem;
}

.kyrex-reassurance__link {
	color: var(--kyrex-gold-deep);
	text-decoration: underline;
	text-underline-offset: 0.15em;
	white-space: nowrap;
}

.kyrex-reassurance__link:hover {
	color: var(--kyrex-charcoal);
}

.kyrex-reassurance__link:focus-visible {
	outline: 2px solid var(--kyrex-charcoal);
	outline-offset: 2px;
	border-radius: var(--kyrex-radius-sm);
}
