/*
 * Brand layer — the green / cream / gold identity.
 *
 * ⚠️ THIS FILE IS PHASE ONE OF A TWO-PHASE MIGRATION.
 *
 * The store is moving from the cream / near-black / coral palette in style.css
 * to the green / cream / gold one below. Rather than rewrite style.css and
 * repaint every page at once, this layer:
 *
 *     1. declares the new palette as its own `--xg-*` token set, and
 *     2. restyles ONLY the sitewide chrome — ticker, header, footer.
 *
 * Shop, PDP, cart and checkout keep their existing `--x-*` tokens untouched and
 * are migrated in phase two. The interim state is deliberate and holds together:
 * the header is cream in both palettes, so only the footer and the ticker read
 * as new, which is how a rebrand normally rolls out anyway.
 *
 * ⚠️ LOADED AFTER mobile.css, ON PURPOSE. `wp_enqueue_style` dependencies order
 * handles, not cascade weight — and mobile.css is enqueued last at priority 30
 * specifically so its overrides win. This file has to come after it or the
 * mobile rules would repaint the header back. See xyvira_brand_css_last().
 *
 * ⚠️ SPECIFICITY IS KEPT DELIBERATELY LOW. Everything here targets the same
 * selectors style.css already uses, at the same weight, and wins on order
 * alone. No `!important`, no escalated selectors — so phase two can delete a
 * rule here and the original simply reappears.
 */

:root {
  /* ── The palette ───────────────────────────────────────────────────────── */
  --xg-green:      #123023;   /* primary ink and dark surfaces */
  --xg-green-mid:  #1c4632;   /* hover on dark */
  --xg-green-dark: #0e2a1e;   /* footer ground, ticker start */

  --xg-cream:      #f7f4ee;   /* page ground */
  --xg-cream-2:    #efe9dd;   /* hover fill on light */
  --xg-cream-ink:  #f4eddf;   /* text on dark */

  --xg-accent:     #b98f42;   /* gold */
  --xg-accent-hi:  #dcbb74;   /* gold, brightened — badges on dark */
  --xg-accent-soft:#e2c68a;   /* gold, softened — labels on dark */
  --xg-accent-ink: #7e5320;   /* gold, darkened — links on light */
  --xg-accent-deep:#4a4429;   /* gold, deepest — the darker half of a gradient
                                 carrying white text. Paired with --xg-accent-ink
                                 it holds a white label above 4.5:1; the brighter
                                 golds above measure about 2.4:1 and cannot. */

  /*
   * Alpha-derived, not separate hex values. Every rule below that needs a
   * hairline or a muted ink pulls from these three so the whole layer shifts
   * together if the green ever moves.
   */
  --xg-line:       rgba(18, 48, 35, .10);
  --xg-ink-60:     rgba(18, 48, 35, .60);
  --xg-ink-72:     rgba(18, 48, 35, .72);

  /* ── Type ──────────────────────────────────────────────────────────────── */
  --xg-serif: "Instrument Serif", Georgia, "Times New Roman", serif;
  --xg-sans:  "Jost", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
}

/* ────────────────────────────────────────────────────────────────────────────
 * The container
 *
 * ⚠️ ONE WIDTH FOR HEADER, CONTENT AND FOOTER — THAT IS WHY IT IS HERE.
 *
 * The theme's `.x-container` is 75rem (1200px) with a fixed 2rem of padding.
 * The design uses a single `.wrap` of 1240px with `clamp(12px, 4vw, 40px)`,
 * applied to the header bar, every section and the footer alike.
 *
 * Left alone, the header sat at 152px from the viewport edge while the ritual
 * page's own sections sat at 140px — a 12px step between the logo and
 * everything under it, visible the moment you look down the left edge.
 *
 * Changing it in one place keeps every row on the same line. Every other page
 * simply gains 40px of width, which is the design's measure anyway.
 * ──────────────────────────────────────────────────────────────────────────── */

.x-container {
  max-width: 77.5rem;
  padding-inline: clamp(12px, 4vw, 40px);
}

/* ────────────────────────────────────────────────────────────────────────────
 * Ticker  (the restyled promo bar)
 *
 * ⚠️ THE MESSAGES SCROLL; THE COUPON CODE DOES NOT.
 *
 * The mockup's ticker is a pure marquee. This bar also carries the copyable
 * coupon button, and a control that slides out from under the cursor is a
 * control nobody can click. So the track scrolls inside its own overflow box
 * and the code pill is pinned outside it, static and always hittable.
 * ──────────────────────────────────────────────────────────────────────────── */

.x-promo {
  background: linear-gradient(90deg, var(--xg-green-dark), var(--xg-green-mid) 45%, var(--xg-accent));
  color: var(--xg-cream-ink);
  border-bottom: 0;
}

.x-promo__inner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-block: 10px;

  /*
   * ⚠️ FULL BLEED. THE MESSAGES SWEEP THE VIEWPORT, NOT THE CONTAINER.
   *
   * This carries .x-container, which caps it at 1240px and indents it by the
   * page gutter — so on a wide screen the messages appeared to start and stop
   * 100px inside the coloured band they scroll through. The design runs them
   * the full width; the gradient always did, and only the text was boxed.
   */
  max-width: none;
  padding-inline: 0;

  /*
   * ⚠️ style.css SETS min-height: 2.5rem ABOVE 1024px. THAT IS THE LAST 4px.
   *
   * It dates from when this strip held wrapping centred messages rather than a
   * single scrolling line, and it kept the bar 40px tall against the design's
   * 36 no matter what the contents measured. Cleared here rather than edited
   * there, because style.css is the layer this file exists to override.
   */
  min-height: 0;
  /* The track needs somewhere to be clipped, and the pill needs to survive it. */
  overflow: hidden;
  /*
   * ⚠️ EXPLICIT nowrap, BECAUSE mobile.css SETS `flex-wrap: wrap` HERE.
   *
   * Inherited, it dropped the coupon pill onto its own centred second row under
   * the marquee — which reads as a stray button rather than part of the bar. The
   * track already shrinks (flex: 1 1 auto; min-width: 0), so there is nothing to
   * wrap for.
   */
  flex-wrap: nowrap;
}

.x-promo__msg {
  color: var(--xg-cream-ink);
  font-family: var(--xg-sans);
  font-size: 11px;
  /*
   * ⚠️ `normal`, NOT THE SITE'S 1.6.
   *
   * The design inherits the browser default here; the theme sets 1.6 globally
   * for readable body copy. On an 11px line that is 17.6px against the design's
   * 16px, and the ticker came out 40px tall instead of 36 — a 4px step at the
   * very top of every page, visible against the header below it.
   */
  line-height: normal;
  letter-spacing: .13em;
  text-transform: uppercase;
  white-space: nowrap;
  min-width: 0;
}

.x-promo__msg:hover { color: #fff; }

/*
 * The marquee itself. Duplicated content plus a -50% translation is what makes
 * the loop seamless — the second copy is in the same position the first started
 * in at the moment the animation resets, so there is no visible jump.
 */
/*
 * ⚠️ NO EDGE MASK. IT WAS EATING THE FIRST AND LAST WORD.
 *
 * A `mask-image` faded 24px at each end, which reads as a soft edge on a long
 * scrolling line and as a bug on a short one: the bar rendered "XTRA 5% OFF
 * YOUR FIRST ORDER" and "FREE DELIVERY O". It is not in the design, and the
 * first forty pixels of the page are the wrong place to be clever.
 */
.x-ticker {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  /*
   * ⚠️ 0, SO THE BOX HUGS THE TRACK INSIDE IT.
   *
   * The track is inline-flex, so this element still reserves a text line around
   * it — 19.2px of the theme's 1.6, against a track that is only 16px tall. That
   * 3px went straight into the height of the bar. Zero removes the strut; the
   * messages set their own line-height.
   */
  line-height: 0;
}

.x-ticker__track {
  display: inline-flex;
  gap: 44px;
  padding-left: 44px;
  white-space: nowrap;
  animation: xg-marquee 30s linear infinite;
  will-change: transform;
}

@keyframes xg-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/*
 * ⚠️ NOT DECORATION — VESTIBULAR SAFETY. Continuous horizontal motion is a
 * migraine and nausea trigger, and it is one of the few effects WCAG names
 * outright. Stopped, the first messages are still readable.
 */
@media (prefers-reduced-motion: reduce) {
  .x-ticker__track { animation: none; }
}

/* The copyable code chip was removed from the header — see header.php. */

/* ────────────────────────────────────────────────────────────────────────────
 * Header
 * ──────────────────────────────────────────────────────────────────────────── */

.x-header {
  background: rgba(247, 244, 238, .9);
  border-bottom: 1px solid var(--xg-line);
}

/*
 * ⚠️ FEATURE-QUERIED, NOT ASSUMED. Without backdrop-filter support the
 * translucent ground turns the nav into unreadable text over scrolling
 * product images, so the fallback is simply opaque.
 */
@supports (backdrop-filter: blur(14px)) or (-webkit-backdrop-filter: blur(14px)) {
  .x-header {
    -webkit-backdrop-filter: blur(14px);
            backdrop-filter: blur(14px);
  }
}

/*
 * ⚠️ NO BACKDROP BLUR BELOW 1024px, AND THE BACKGROUND MUST GO FULLY OPAQUE
 *    IN THE SAME BREATH.
 *
 * Reported symptom: on iOS Safari the sticky header intermittently paints
 * mid-screen and flickers, most often while scrolling past the horizontal rails
 * (`.ing__rail`, `.rr__rail`, `.x-bs__rail`).
 *
 * What was ruled out by measurement: the header's layout position is `top: 0` at
 * every scroll offset, its ancestry contains nothing that traps a sticky element,
 * its height never changes, there is exactly one header in the DOM, and CLS is
 * zero. The element is never *positioned* mid-screen — it is *painted* there,
 * which makes this a compositing fault rather than a layout one.
 *
 * A sticky element with `backdrop-filter` must re-sample and re-blur everything
 * behind it on every frame of a scroll. Next to a nested horizontal scroller,
 * WebKit is simultaneously disambiguating a horizontal pan from a vertical one
 * and running snap calculations on a second compositing layer. The header's
 * blurred layer is then liable to present a stale frame — which is precisely
 * "stuck in the middle of the screen, flickering".
 *
 * ⚠️ THE OPACITY IS NOT COSMETIC HOUSEKEEPING.
 *
 * The base rule is `rgba(247, 244, 238, .9)`. Dropping the blur while leaving it
 * at 90% leaves the nav legible over cream but unreadable over the scrolling
 * product photography beneath it — the exact failure the @supports block above
 * exists to prevent. Blur and translucency are one decision, so they are removed
 * together, landing on the same opaque fallback that block already sanctions.
 *
 * Desktop keeps the frosted treatment: it is where the effect is actually
 * legible, and no compositing fault has been observed there.
 *
 * ⚠️ THIS IS A HYPOTHESIS THAT WAS SHIPPED, NOT A CONFIRMED FIX.
 *
 * It could not be reproduced locally — headless Chrome has no mobile compositor,
 * and there is no iOS simulator on the build machine. If the flicker survives
 * this, the next levers are `scroll-snap-type: x mandatory` -> `x proximity` on
 * the three rails, and pausing the `xg-marquee` animation inside the header.
 * Change one at a time or the cause stays unknown.
 */
@media (max-width: 1023px) {
  .x-header {
    -webkit-backdrop-filter: none;
            backdrop-filter: none;
    background: #F7F4EE;
  }
}

/*
 * ⚠️ THE BAR IS A FLEX ROW, NOT space-between.
 *
 * style.css spaces three groups apart, which centres the nav. The design puts
 * the nav immediately beside the wordmark and pushes only the actions right, so
 * the gap has to be created by one `margin-left: auto` on the actions rather
 * than distributed between all three.
 */
.x-header__bar {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 10px;
  height: auto;
  padding-block: 12px;
}

.x-header__left { display: flex; align-items: center; gap: 0.375rem; }

/* The wordmark alone, at the design's height. */
.x-logo__word { display: block; height: clamp(15px, 2vw, 20px); width: auto; }

/*
 * ⚠️ THE NAV/BURGER SWITCH MOVES FROM 1024px TO 900px.
 *
 * style.css swaps them at 1024, the design specifies 900. Both rules have to
 * move together — changing one leaves a band of widths showing either two
 * navigations at once or none at all, and 900–1023px is a very common tablet
 * range to break.
 */
.x-nav { display: none; }
.x-burger { display: flex; }

@media (min-width: 900px) {
  .x-nav { display: flex; }
  .x-burger { display: none; }
}

.x-nav {
  gap: 24px;
  margin-left: 24px;
  white-space: nowrap;
}

.x-nav__list { display: flex; gap: 24px; margin: 0; padding: 0; list-style: none; }

/* Same strut, same fix — the list items inherited 1.6 and stood 24px tall
   around links that are 21. The nav is the tallest thing in the bar after the
   bag, so it decided the bar's height. */
.x-nav__list,
.x-nav__list li { line-height: normal; }

.x-nav a,
.x-mobile-menu a,
.x-logo { color: var(--xg-green); }

.x-nav a {
  font-family: var(--xg-sans);
  font-size: 14.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.x-nav a:hover { color: var(--xg-accent-ink); }

.x-header__actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
  flex: 0 0 auto;
}

/* ── Header search ───────────────────────────────────────────────────────── */

/*
 * ⚠️ HIDDEN BELOW 900px, NOT REMOVED FROM THE MARKUP.
 *
 * Below that width the bar is burger + wordmark + account + bag, and a field
 * would have nowhere to go. Keeping the form in the DOM and hiding it with CSS
 * means the search landmark exists at every width — and there is no second
 * markup path to keep in sync.
 */
.x-hsearch {
  display: none;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 0 14px;
  width: clamp(140px, 14vw, 200px);
  border: 1px solid rgba(18, 48, 35, .12);
  border-radius: 999px;
  background: rgba(18, 48, 35, .06);
  color: var(--xg-green);
}

.x-hsearch svg { opacity: .5; flex: 0 0 auto; }

.x-hsearch input {
  width: 100%;
  min-width: 0;
  border: 0;
  background: none;
  outline: none;
  font: inherit;
  font-size: 14px;
  color: var(--xg-green);
}

/* The focus ring belongs on the pill, not the bare input inside it. */
.x-hsearch:focus-within {
  border-color: var(--xg-accent-ink);
  background: #fff;
}

/* Safari draws its own clear button, which sits oddly in a pill this size. */
.x-hsearch input::-webkit-search-decoration,
.x-hsearch input::-webkit-search-cancel-button { -webkit-appearance: none; }

@media (min-width: 900px) {
  .x-hsearch { display: flex; }
}

/* ── Bag pill ────────────────────────────────────────────────────────────── */

.x-bag {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 40px;
  padding: 10px 14px;
  border-radius: 999px;
  background: var(--xg-green);
  color: var(--xg-cream-ink);
  font-size: 13.5px;
  /* Same reason as .x-promo__msg — 1.6 made the pill 41.6px, not 40, and that
     1.6px propagated to the whole header bar because it is the tallest item. */
  line-height: normal;
  white-space: nowrap;
}

.x-bag:hover { background: var(--xg-green-mid); color: var(--xg-cream-ink); }

/*
 * ⚠️ STATIC, OVERRIDING style.css's ABSOLUTE POSITIONING.
 *
 * The old count was a badge pinned to the corner of an icon button. Inside a
 * pill it is an inline chip sitting after the word "Bag", so the absolute
 * positioning has to be undone explicitly or it anchors to the wrong box and
 * floats off the header.
 */
.x-bag .x-cart-count {
  position: static;
  top: auto;
  right: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 19px;
  height: 19px;
  padding-inline: 5px;
  border-radius: 999px;
  background: var(--xg-accent-hi);
  color: var(--xg-green);
  font-size: 11.5px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

/* The current page is marked structurally, not by colour alone. */
.x-nav .current-menu-item > a,
.x-nav a[aria-current] {
  border-bottom: 1px solid var(--xg-green);
  padding-bottom: 2px;
}

.x-icon-btn {
  width: 40px;
  height: 40px;
  color: var(--xg-green);
  border: 1px solid rgba(18, 48, 35, .15);
}

/*
 * ⚠️ THE MENU BUTTON IS BARE IN THE DESIGN, NOT A CIRCLED ICON.
 *
 * It carries `.x-icon-btn` for its flex centring, which also gave it the ring
 * and the 40px box the account button wants. The design has neither: a plain
 * glyph, flush to the left edge of the bar.
 *
 * The mark stays an SVG rather than becoming the design's `&#8801;` character.
 * That glyph renders at a different weight and baseline in every font it falls
 * back to, and a header is the last place to accept that — the shape is the
 * same, the reliability is better.
 */
.x-burger {
  width: auto;
  height: auto;
  padding: 10px 4px 10px 0;
  border: 0;
  background: none;
}

.x-burger:hover { background: none; color: var(--xg-accent-ink); }

.x-icon-btn:hover { background: var(--xg-cream-2); color: var(--xg-green); }

.x-cart-count {
  background: var(--xg-accent-hi);
  color: var(--xg-green);
}

.x-burger { color: var(--xg-green); }
.x-mobile-menu { border-top: 1px solid var(--xg-line); }
.x-mobile-menu a { border-bottom-color: var(--xg-line); }

/* ────────────────────────────────────────────────────────────────────────────
 * Footer
 * ──────────────────────────────────────────────────────────────────────────── */

.x-footer {
  background: var(--xg-green-dark);
  color: rgba(244, 237, 223, .75);
}

.x-footer__brand p,
.x-footer__bottom p { color: rgba(244, 237, 223, .75); }

.x-footer__cols h2 {
  color: var(--xg-accent-soft);
  font-family: var(--xg-sans);
  letter-spacing: .18em;
  text-transform: uppercase;
  font-weight: 400;
}

.x-footer__cols a,
.x-footer__legal a { color: rgba(244, 237, 223, .75); }

.x-footer__cols a:hover,
.x-footer__legal a:hover { color: #fff; }

.x-footer__bottom { border-top: 1px solid rgba(244, 237, 223, .14); }

/*
 * ⚠️ AN OUTLINED PILL — AND IT MUST SAY SO IN FULL.
 *
 * This block used to set only `color` and `border-color`, which was the whole
 * bug. `border-color` paints nothing without a width and a style, so no outline
 * ever appeared; and style.css's `background: #e0d9cc` was never overridden, so
 * the beige disc from the old light footer survived underneath. The result was
 * a cream glyph at .75 alpha sitting on a cream disc — the icon was there and
 * effectively invisible, which is why it read as a blob rather than an icon.
 *
 * So: background and border are both stated outright. Do not trim either back
 * to a `-color` shorthand; that is exactly how this broke.
 */
.x-social a {
  background: transparent;
  border: 1px solid rgba(244, 237, 223, .22);
  color: rgba(244, 237, 223, .75);
}

/*
 * The hover had the same hole: it recoloured but left style.css's
 * `background: var(--x-dark)` in force, which on this ground turns the pill
 * near-black. A faint cream wash is the version that reads as "lit up".
 */
.x-social a:hover {
  background: rgba(244, 237, 223, .10);
  border-color: rgba(244, 237, 223, .5);
  color: #fff;
}

/* 16px in a 36px pill is 44% and reads as a dot. Sized here rather than in
   footer.php so the markup's width/height stay as the SVG's own intrinsic box. */
.x-social a svg { width: 18px; height: 18px; }

/*
 * ⚠️ THE FOOTER WORDMARK HAS TO SWAP FILES, NOT INVERT.
 *
 * The footer ground is now dark, and logo-dark.svg is dark ink — it would
 * disappear. A CSS `filter: invert()` would also recolour the gold in the mark.
 * footer.php therefore picks the light wordmark; this rule only guards the case
 * where a customiser logo (always the dark one) is set instead.
 */
.x-footer__brand img { max-width: 190px; height: auto; }

/* ────────────────────────────────────────────────────────────────────────────
 * Breadcrumbs
 *
 * ⚠️ `.x-crumbs` HAD NO STYLES ANYWHERE. Not in style.css, woocommerce.css or
 * mobile.css — the markup has been rendering with browser defaults on every
 * page that shows a trail, which is why it sat flush against the header with an
 * <ol>'s own margin and no separators.
 *
 * The separator is a CSS `::before` rather than markup, so it is decorative and
 * a screen reader reads "Home, Rituals, Glow Ritual" instead of
 * "Home slash Rituals slash Glow Ritual".
 * ──────────────────────────────────────────────────────────────────────────── */

.x-crumbs {
  padding-block: 14px 0;
  font-size: 12px;
  /* .55, matching the design exactly — not the shared --xg-ink-60, which is .60
     and reads a shade heavier next to it. */
  color: rgba(18, 48, 35, .55);
}

.x-crumbs__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.x-crumbs__item { display: flex; align-items: center; gap: 7px; }

/* The separator inherits rather than being dimmed — the design draws it at the
   same weight as the links either side of it. */
.x-crumbs__item + .x-crumbs__item::before { content: "/"; color: inherit; }

.x-crumbs a { color: inherit; }
.x-crumbs a:hover { color: var(--xg-accent-ink); }

/* The current page is the one you are on — stated, not a link. */
.x-crumbs [aria-current="page"] { color: var(--xg-green); }

/* ────────────────────────────────────────────────────────────────────────────
 * Home hero — aligned to hero-export/
 *
 * ⚠️ THE MARKUP AND THE CAROUSEL ARE UNTOUCHED. THIS IS PRESENTATION ONLY.
 *
 * `.x-hero2` is CMS-driven and supports several slides with arrows, dots and a
 * pause control. The design shows one static slide, but removing the carousel to
 * match a static export would delete a feature to match a screenshot. Only one
 * slide is configured today, so the two look identical; add a second and the
 * controls come back styled as they already are.
 *
 * ⚠️ THIS REVERSES A DELIBERATE EARLIER DECISION. SEE style.css.
 *
 * The slide image was pinned to `aspect-ratio: 4/3` with a comment explaining the
 * reasoning: 4:5 "took 625px — almost the whole first screen", and "a banner that
 * fills the phone entirely means the visitor's first scroll reveals more banner".
 *
 * The design asks for `clamp(560px, 92svh, 780px)`, which is that full-screen
 * banner. It is the more striking hero and it is what was asked for, but the
 * trade named in that comment is real: the trust row below no longer peeks above
 * the fold on a phone. If that matters more than the impact, the fix is one line
 * — drop the min-height here and the 4/3 ratio returns.
 * ──────────────────────────────────────────────────────────────────────────── */

.x-hero2__slide {
  /* svh, not vh: mobile browser chrome must not crop the buttons. */
  min-height: clamp(560px, 92svh, 780px);
}

/*
 * ⚠️ THE IMAGE FILLS THE SLIDE ABSOLUTELY, AND THE SCRIM IS LIFTED OVER IT.
 *
 * Two dead ends worth recording, because both look like fixes:
 *
 * 1. Leaving the image in flow with `height: 100%`. Its parent .x-hero2__link
 *    has `min-height: 100%` and no height, and a minimum is not definite — so
 *    the percentage had nothing to resolve against and the image fell back to
 *    its intrinsic size, 480px inside a 780px hero.
 *
 * 2. Giving that link `height: 100%` instead. The link then sizes from the
 *    slide, the slide sizes from its content, and the content is the link — a
 *    circular chain the browser breaks by using the image's intrinsic height.
 *    The hero became 1800px tall.
 *
 * Absolute with `inset: 0` resolves against the slide, which has a real
 * min-height, so neither problem arises. The cost is paint order: a positioned
 * element paints above a non-positioned one, so the image covered the ::after
 * gradient and left the headline on a bare photograph. The scrim and the copy
 * are given their own layers above it rather than relying on document order.
 */
.x-hero2__slide img {
  position: absolute;
  inset: 0;
  z-index: 0;
  aspect-ratio: auto;
  width: 100%;
  height: 100%;
  /* style.css caps this at `max-height: 30rem` above its desktop breakpoint —
     480px exactly, which was the real source of the missing height. */
  max-height: none;
  object-fit: cover;

  /*
   * ⚠️ NOT CENTRED. A CENTRED CROP DECAPITATES A PORTRAIT.
   *
   * `cover` defaults to `object-position: 50% 50%`, which keeps the middle of
   * the image. A square photograph in a 1440x780 hero is scaled to 1440x1440 and
   * then trimmed to the middle 54% — from 23% to 77% down. A head that starts at
   * the top of its frame is simply gone, and what survives is a chin and a neck.
   *
   * Biasing upward keeps the face and drops the empty ground below it, which is
   * where the scrim is densest and nothing is visible anyway.
   *
   * ⚠️ THIS ONLY AFFECTS DESKTOP. At phone width a square scaled to cover
   * 390x736 fits the height exactly, so there is no vertical crop to position.
   */
  object-position: 50% 22%;
}

.x-hero2__slide::after { position: relative; z-index: 1; }
.x-hero2__overlay { z-index: 2; }

/*
 * The copy sits at the FOOT of the image. style.css centres it above its desktop
 * breakpoint, which is the older design where the hero was a shorter band.
 */
.x-hero2__overlay { align-items: end; }

/*
 * ⚠️ THE BOTTOM STOP CARRIES THE HEADLINE. DO NOT LIGHTEN IT BELOW ~.85.
 *
 * The copy sits at the foot of the image, so that is where the scrim has to be
 * darkest. These are the design's stops, over the design's green rather than the
 * near-black the previous gradient used — the hero now reads as part of the same
 * palette as the header above it instead of a grey wash.
 */
.x-hero2__slide::after {
  background: linear-gradient(180deg,
    rgba(14, 42, 30, .15) 0%,
    rgba(14, 42, 30, .55) 45%,
    rgba(14, 42, 30, .92) 100%);
}

.x-hero2__text {
  max-width: none;
  padding: 0 0 40px;
  color: var(--xg-cream-ink);
}

@media (min-width: 900px) {
  .x-hero2__text { padding-bottom: 56px; }
}

.x-hero2__eyebrow {
  /* 14, not 12: the design's kicker is an inline span with no margin of its own,
     so the gap comes from the headline's 12px top margin plus the span's
     descender. Matching the measured gap rather than the declared number. */
  margin: 0 0 14px;
  font-family: var(--xg-sans);
  font-size: 11px;
  line-height: normal;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--xg-accent-soft);
  text-shadow: none;
}

.x-hero2__title {
  margin: 0 0 14px;
  font-family: var(--xg-serif);
  font-weight: 400;
  font-size: clamp(40px, 11vw, 74px);
  line-height: 1;
  letter-spacing: 0;
  max-width: 16ch;
  color: var(--xg-cream-ink);
  text-shadow: none;
  text-wrap: balance;
}

@media (min-width: 900px) {
  .x-hero2__title { font-size: clamp(46px, 6vw, 78px); }
}

.x-hero2__lead {
  margin: 0 0 22px;
  max-width: 42ch;
  font-family: var(--xg-sans);
  font-size: 16px;
  line-height: 1.6;
  font-weight: 300;
  color: rgba(244, 237, 223, .86);
  text-shadow: none;
}

/* ── The two buttons ──────────────────────────────────────────────────────── */

.x-hero2__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  pointer-events: auto;
}

.x-hero2__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 54px;
  padding: 16px 26px;
  border-radius: 999px;
  font-family: var(--xg-sans);
  font-size: 14.5px;
  line-height: normal;
  letter-spacing: .07em;
  text-transform: uppercase;
  transition: background .25s ease, filter .25s ease, color .25s ease;
}

/*
 * ⚠️ THEY GROW TO FILL THE ROW ON A PHONE, AND STOP ON DESKTOP.
 *
 * Two buttons side by side at 320px leaves each too narrow to read; stacked full
 * width they are thumb-sized. Above 900px a button as wide as the column reads as
 * a banner rather than a control.
 */
.x-hero2__btn.is-gold {
  flex: 1 1 180px;
  background: linear-gradient(135deg, var(--xg-accent-hi), var(--xg-accent));
  color: var(--xg-green);
  border: 0;
}

.x-hero2__btn.is-gold:hover { filter: brightness(1.08); color: var(--xg-green); }

.x-hero2__btn.is-ghost {
  flex: 1 1 140px;
  border: 1px solid rgba(244, 237, 223, .45);
  color: var(--xg-cream-ink);
  background: none;
}

.x-hero2__btn.is-ghost:hover { background: rgba(244, 237, 223, .14); color: var(--xg-cream-ink); }

/*
 * ⚠️ ONE BUTTON PER ROW BELOW 480px.
 *
 * The two share a row by way of `flex: 1 1 180px` and `1 1 140px`, which at
 * 390px still just fits — 180 + 140 + 10 against about 358px of usable width —
 * so they stayed side by side and each ended up narrower than its own label
 * wanted. "Shop all products" wrapped to two lines inside a button while "See
 * offers" sat on one, which reads as two different-sized controls.
 *
 * A 100% basis forces the wrap that the flex line was only just avoiding.
 * Deliberately 479px rather than the 640px used elsewhere: between 480 and 640
 * there is room for both, and a full-width pair of buttons at that size looks
 * like a form rather than a hero.
 *
 * ⚠️ THE SELECTOR NAMES `.is-gold` AND `.is-ghost` ON PURPOSE.
 *
 * `flex` is set on those two classes, at specificity (0,2,0). Writing this rule
 * against `.x-hero2__btn` alone would be (0,1,0) and would lose — a media query
 * adds no specificity, so being inside one wins nothing. The `min-width: 900px`
 * rule below has exactly that shape and is, in fact, already inert for this
 * reason: the buttons stretch on a desktop instead of hugging their labels.
 *
 * That is left alone deliberately. The design export has the identical selector
 * pair and therefore the identical behaviour, so the page matches what was
 * signed off. It is recorded here so the next person knows it is a known
 * inherited quirk rather than something to "fix" into a difference.
 */
@media (max-width: 479px) {
  .x-hero2__btn.is-gold,
  .x-hero2__btn.is-ghost { flex: 1 1 100%; }
}

@media (min-width: 900px) {
  .x-hero2__btn { flex: 0 0 auto; }
}

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

/* ────────────────────────────────────────────────────────────────────────────
 * About page — aligned to about-export/
 *
 * ⚠️ THE LAYOUT IS FIXED AND THE CONTENT IS NOT. That split is xl-about.php's,
 * and it is the right one: this page is a composition in a deliberate rhythm,
 * not a stack of blocks. Everything below styles that composition; every word,
 * figure and photograph in it comes from Home page → About.
 *
 * ⚠️ TWO CONTRAST FLOORS ARE MARKED BELOW. Both fail WCAG if lightened, and
 * both are easy to lighten by eye because they look heavy against a placeholder
 * and correct against a real photograph.
 * ──────────────────────────────────────────────────────────────────────────── */

/*
 * ⚠️ THE EMPTY STATE IS DESIGNED, NOT ABSENT.
 *
 * Most of this page's photographs are not shot yet. A striped panel in the brand
 * colours holds the layout at its final height, so nothing on the page moves when
 * an image is finally added, and it reads as intentional rather than broken.
 */
.x-about__hero.is-empty,
.x-about__stepimg.is-empty,
.x-about__bannerimg.is-empty {
  background: repeating-linear-gradient(135deg,
    var(--xg-cream-2) 0 14px,
    #e6dfd0 14px 28px);
}

.x-about__hero img,
.x-about__stepimg img,
.x-about__bannerimg img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ── the wide hero ────────────────────────────────────────────────────────── */

.x-about__herowrap { margin-top: clamp(20px, 3vw, 32px); }

/*
 * 4/3 on a phone rather than the desktop letterbox: a 21/9 crop of a portrait
 * subject at 390px wide leaves a band of forehead and nothing else.
 */
.x-about__hero {
  border-radius: 20px;
  overflow: hidden;
  aspect-ratio: 4 / 3;
}

@media (min-width: 700px) {
  .x-about__hero { aspect-ratio: 21 / 9; }
}

/* ── the origin split ─────────────────────────────────────────────────────── */

.x-about__story { padding-top: clamp(32px, 5vw, 64px); gap: clamp(18px, 3vw, 40px); }
.x-about__storyimg { border-radius: 20px; overflow: hidden; aspect-ratio: 4 / 5; }
.x-about__storyimg img { width: 100%; height: 100%; object-fit: cover; }

.x-about__storytext h2 {
  font-family: var(--xg-serif);
  font-weight: 400;
  font-size: clamp(28px, 7vw, 44px);
  line-height: 1.04;
  margin: 0;
  max-width: 18ch;
}

.x-about__storytext p {
  margin: 0;
  font-size: 16px;
  line-height: 1.7;
  font-weight: 300;
  color: var(--xg-ink-72);
  max-width: 50ch;
}

.x-about__quote {
  margin: 8px 0 0;
  padding: 20px 22px;
  border-radius: 16px;
  background: linear-gradient(150deg, var(--xg-green), var(--xg-green-mid) 70%, #2c5c42);
  color: var(--xg-cream-ink);
  font-family: var(--xg-serif);
  font-style: italic;
  font-size: clamp(20px, 3vw, 26px);
  line-height: 1.32;
  max-width: none;
  /* A coral left rule from the palette this layer is migrating away from — the
     only coral left on the page, and it read as a stray stripe on the green. */
  border-left: 0;
}

/* ── values ───────────────────────────────────────────────────────────────── */

.x-about__values {
  margin-top: clamp(32px, 5vw, 64px);
  background: var(--xg-cream-2);
  padding-block: clamp(28px, 4.5vw, 56px);
}

.x-about__heading {
  font-family: var(--xg-serif);
  font-weight: 400;
  font-size: clamp(28px, 7vw, 44px);
  line-height: 1.04;
  margin: 8px 0 20px;
  max-width: 20ch;
}

.x-about__cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: 12px;
}

.x-about__card {
  background: #fff;
  border: 1px solid rgba(18, 48, 35, .08);
  border-radius: 18px;
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.x-about__card h3 {
  font-family: var(--xg-serif);
  font-weight: 400;
  font-size: clamp(21px, 5vw, 26px);
  line-height: 1.15;
  margin: 0;
}

.x-about__card p {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.6;
  font-weight: 300;
  color: var(--xg-ink-72);
}

/*
 * ⚠️ THE FOUR COLOURS CYCLE IN CSS, NOT INLINE ON EACH ITEM.
 *
 * The design writes them as inline styles per card, derived from each product
 * family's carton deepened toward the brand green. Inline they cannot survive a
 * fifth value being added — the fifth would render with no colour at all — and
 * they would put a colour picker in front of somebody in the admin. Cycling on
 * nth-child means any number of items is covered and none can be unreadable.
 */
.x-about__card .x-about__icon,
.x-about__card:nth-child(4n + 1) .x-about__icon { color: #6e6434; }
.x-about__card:nth-child(4n + 2) .x-about__icon { color: #4d6a46; }
.x-about__card:nth-child(4n + 3) .x-about__icon { color: #38677f; }
.x-about__card:nth-child(4n + 4) .x-about__icon { color: #604a65; }

/* ── stats ────────────────────────────────────────────────────────────────── */

.x-about__stats { padding-top: clamp(28px, 4.5vw, 56px); }

.x-about__statgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
  gap: 12px;
}

.x-about__statgrid > * {
  border-radius: 18px;
  border: 1px solid var(--xg-line);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.x-about__statvalue {
  font-family: var(--xg-serif);
  font-size: clamp(38px, 9vw, 54px);
  line-height: 1;
  color: var(--xg-accent-ink);
}

.x-about__statlabel {
  font-size: 14.5px;
  line-height: 1.5;
  font-weight: 300;
  color: var(--xg-ink-72);
}

/* ── process ──────────────────────────────────────────────────────────────── */

.x-about__process { padding-top: clamp(32px, 5vw, 64px); }

/*
 * Two across on a phone rather than one: four stacked cards is a long scroll for
 * four short sentences, and the steps read as a sequence when they sit in a grid.
 */
.x-about__steps {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 760px) {
  .x-about__steps { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.x-about__steps > li {
  background: #fff;
  border: 1px solid var(--xg-line);
  border-radius: 18px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.x-about__stepimg { position: relative; aspect-ratio: 4 / 3; }

.x-about__stepno {
  position: absolute;
  top: 9px;
  left: 9px;
  color: #fff;
  font-size: 11.5px;
  font-weight: 500;
  padding: 5px 10px;
  border-radius: 999px;
  pointer-events: none;
}

/* Same cycle as the value cards, for the same reason. */
.x-about__steps > li .x-about__stepno,
.x-about__steps > li:nth-child(4n + 1) .x-about__stepno { background: #6e6434; }
.x-about__steps > li:nth-child(4n + 2) .x-about__stepno { background: #4d6a46; }
.x-about__steps > li:nth-child(4n + 3) .x-about__stepno { background: #3b4e6c; }
.x-about__steps > li:nth-child(4n + 4) .x-about__stepno { background: #604a65; }

/* A wash of the badge colour behind an empty plate, so the four read as a set. */
.x-about__steps > li:nth-child(4n + 1) .x-about__stepimg.is-empty { background-color: rgba(185, 143, 66, .14); }
.x-about__steps > li:nth-child(4n + 2) .x-about__stepimg.is-empty { background-color: rgba(126, 154, 99, .14); }
.x-about__steps > li:nth-child(4n + 3) .x-about__stepimg.is-empty { background-color: rgba(92, 102, 168, .14); }
.x-about__steps > li:nth-child(4n + 4) .x-about__stepimg.is-empty { background-color: rgba(160, 96, 155, .14); }

.x-about__stepbody {
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  flex: 1;
}

.x-about__stepbody h3 { margin: 0; font-size: 16px; font-weight: 500; line-height: 1.25; }

.x-about__stepbody p {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.55;
  font-weight: 300;
  color: var(--xg-ink-72);
}

/* ── the closing banner ───────────────────────────────────────────────────── */

.x-about__banner {
  position: relative;
  overflow: hidden;
  margin-top: clamp(32px, 5vw, 64px);
}

.x-about__bannerimg { position: absolute; inset: 0; }

/*
 * ⚠️ CONTRAST FLOOR — DO NOT LIGHTEN THE LAST STOP BELOW ~.6.
 *
 * At phone width the copy spans almost the whole diagonal sweep, so the pale end
 * of the gradient ends up behind the headline rather than beside it. Against the
 * striped placeholder this looks far too heavy; against a real photograph it is
 * the difference between readable and not.
 */
.x-about__bannerscrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(105deg,
    rgba(14, 42, 30, .90) 0%,
    rgba(18, 48, 35, .78) 52%,
    rgba(120, 90, 40, .66) 100%);
}

.x-about__cta {
  position: relative;
  z-index: 2;
  padding-block: clamp(40px, 7vw, 84px);
  color: var(--xg-cream-ink);
  background: none;
  border: 0;
  border-radius: 0;
}

.x-about__cta h2 {
  font-family: var(--xg-serif);
  font-weight: 400;
  font-size: clamp(30px, 8.5vw, 52px);
  line-height: 1.04;
  margin: 12px 0;
  max-width: 18ch;
  color: var(--xg-cream-ink);
}

.x-about__ctatext {
  margin: 0 0 22px;
  max-width: 46ch;
  font-size: 15.5px;
  line-height: 1.65;
  font-weight: 300;
  color: rgba(244, 237, 223, .86);
}

/*
 * ⚠️ CONTRAST FLOOR — BOTH GRADIENT STOPS STAY DARK.
 *
 * White on the brighter gold (--xg-accent-hi) measures about 2.4:1. It looks
 * expensive and it is unreadable. These two stops keep it above 4.5:1.
 */
.x-about__cta .x-btn,
.x-about__cta .x-btn--light {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 50px;
  padding: 15px 28px;
  border-radius: 999px;
  border: 0;
  background: linear-gradient(135deg, var(--xg-accent-ink), var(--xg-accent-deep));
  color: #fff;
  font-size: 13.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  transition: filter .25s ease;
}

.x-about__cta .x-btn:hover,
.x-about__cta .x-btn--light:hover { filter: brightness(1.12); color: #fff; }

@media (prefers-reduced-motion: reduce) {
  .x-about__cta .x-btn { transition: none; }
}

/* ── the About opening, scoped so no other page that shares .x-hero moves ─── */

.x-hero--about .x-hero__title {
  font-family: var(--xg-serif);
  font-weight: 400;
  font-size: clamp(38px, 11vw, 68px);
  line-height: .98;
  margin: 12px 0 16px;
  max-width: 15ch;
  text-wrap: balance;
}

.x-hero--about .x-hero__intro {
  margin: 0;
  /* ⚠️ NAMED, NOT INHERITED. `ch` is measured in the element's own font, so a
     56ch measure in the theme's older sans is 80px wider than the same measure
     in the one this layer uses — the line breaks land somewhere else. */
  font-family: var(--xg-sans);
  font-size: clamp(16px, 2vw, 19px);
  line-height: 1.6;
  font-weight: 300;
  color: var(--xg-ink-72);
  max-width: 56ch;
}

.x-hero--about .x-hero__eyebrow {
  font-size: 11px;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--xg-accent-ink);
}

/*
 * ⚠️ LEFT, NOT CENTRED. The shared .x-hero centres its contents, which suits the
 * short titles on the pages that borrow it. The About opening is a headline over
 * a paragraph of prose, and centred prose is hard to read past two lines.
 */
.x-hero--about,
.x-hero--about .x-container { text-align: left; }
.x-hero--about .x-hero__title,
.x-hero--about .x-hero__intro,
.x-hero--about .x-hero__eyebrow { margin-inline: 0; }

/* The decorative mark belongs to the older centred composition; with the copy
   ranged left it floats in the middle of nothing. */
.x-hero--about .x-hero__mark { display: none; }

/* ── About: corrections found by looking at the page, not measuring it ────── */

/*
 * ⚠️ RANGED LEFT. The shared .x-about__eyebrow and .x-about__heading centre
 * themselves, which suited the older composition. Every heading in the design is
 * ranged left against the same gutter as the copy beneath it.
 */
.x-about__values .x-about__eyebrow,
.x-about__values .x-about__heading,
.x-about__process .x-about__eyebrow,
.x-about__process .x-about__heading { text-align: left; margin-inline: 0; }

/* The numbered marker that replaced the icons. */
.x-about__cardno {
  font-size: 11px;
  letter-spacing: .16em;
  font-weight: 500;
}

.x-about__card .x-about__cardno,
.x-about__card:nth-child(4n + 1) .x-about__cardno { color: #6e6434; }
.x-about__card:nth-child(4n + 2) .x-about__cardno { color: #4d6a46; }
.x-about__card:nth-child(4n + 3) .x-about__cardno { color: #38677f; }
.x-about__card:nth-child(4n + 4) .x-about__cardno { color: #604a65; }

/*
 * ⚠️ THE STATS BAND IS LIGHT, AND THE OLD DARK ONE WAS UNREADABLE ANYWAY.
 *
 * woocommerce.css paints this band near-black and sets the label colour from the
 * old palette. Against that ground the labels measured close to 2:1 — "Products,
 * each with a reason to exist" was legible only if you already knew what it said.
 *
 * The design has three bordered cards on the page's own cream, with the figure in
 * gold. Same information, and it can actually be read.
 */
.x-about__stats {
  background: none;
  color: inherit;
  padding-block: 0;
  padding-top: clamp(28px, 4.5vw, 56px);
}

/* The stat card ranges left with its label, as the rest of the page does. */
.x-about__statgrid > * { text-align: left; align-items: flex-start; }

/*
 * ⚠️ NO BAND, NO BORDER, NO CURSOR SHEEN ON THE ABOUT OPENING.
 *
 * `.x-hero` carries three things the design does not have:
 *
 *   1. `background: var(--x-bg-alt)` — a tinted band behind the copy.
 *   2. `border-bottom` — a rule under it.
 *   3. A `::before` radial sheen that tracks the pointer, described in
 *      woocommerce.css as "sheen on any hero, not just the contact page".
 *
 * The third is the one that reads as a fault rather than a choice. It is painted
 * in rgba(201,105,74,.10) — coral, from the palette this layer is migrating the
 * site away from — so on a cream page it appears as a pink smudge drifting under
 * the cursor, in a colour that exists nowhere else on the page any more.
 *
 * The design's opening is words on the page's own ground. All three go here.
 */
.x-hero--about {
  background: none;
  border-bottom: 0;
}

/*
 * ⚠️ REMOVED EVERYWHERE, NOT JUST HERE.
 *
 * woocommerce.css declares this twice — once under "Contact: interactions" and
 * again 560 lines later, generalised with the comment "sheen on any hero, not
 * just the contact page". Both paint the same coral wash, and the second is why
 * it turned up on About and Shop.
 *
 * It is `rgba(201, 105, 74, .10)` — a colour from the palette this file exists to
 * migrate away from. On cream it reads as a pink smudge sliding under the cursor,
 * in a hue that appears nowhere else on the site any more. It was not a design
 * decision that aged badly; it is a leftover the migration had not reached.
 *
 * The homepage hero is untouched — it is .x-hero2 and never had one.
 *
 * ⚠️ THE POINTER TRACKING STILL RUNS.
 *
 * motion.js and contact.js keep writing --x-mx and --x-my on every pointer move.
 * They are now writing to a property nothing reads, which is wasted work rather
 * than a bug — worth deleting when either file is next opened, not worth a patch
 * of its own.
 */
.x-hero::before { display: none; }

/* ── About: the rest of it ────────────────────────────────────────────────── */

/*
 * ⚠️ THE PAGE'S BASE TYPE, AND THE REASON EVERY SECTION LOOKED WRONG AT ONCE.
 *
 * Body copy across this page was still the theme's older stack — Outfit at 15px
 * on a 24px line, inked near-black. The design is Jost at 16px on a normal line,
 * inked in the brand green. That single inheritance was behind almost every
 * complaint about the page: paragraphs a shade too small, lines a shade too
 * tight, and a grey that reads cold against cream.
 *
 * Set once on the page rather than per element, so anything added later inherits
 * the right thing instead of the old thing.
 */
body.page-template-template-about,
.x-about__crumbs,
.x-about__story,
.x-about__values,
.x-about__stats,
.x-about__process,
.x-about__banner {
  font-family: var(--xg-sans);
  font-size: 16px;
  line-height: normal;
  color: var(--xg-green);
}

/* ── breadcrumb ───────────────────────────────────────────────────────────── */

.x-about__crumbs {
  display: flex;
  gap: 7px;
  flex-wrap: wrap;
  margin-bottom: 14px;
  font-size: 12px;
  color: var(--xg-ink-72);
}

.x-about__crumbs a { color: inherit; }
.x-about__crumbs a:hover { color: var(--xg-accent-ink); }

/* ── intro spacing ────────────────────────────────────────────────────────── */

/*
 * ⚠️ 32px ABOVE AND NOTHING BELOW.
 *
 * `.x-hero` pads itself generously — 72px above and 120px below — because on the
 * pages it was built for it is a standalone band. Here it is the opening of a
 * page that continues immediately into an image, and that 120px left a hole.
 */
.x-hero--about {
  padding-top: clamp(18px, 3vw, 32px);
  padding-bottom: 0;
}

/* ── the origin split ─────────────────────────────────────────────────────── */

@media (min-width: 860px) {
  .x-about__story {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: center;
  }
}

/* The copy is a column with an even rhythm, not a stack of default margins. */
.x-about__storytext {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* ── how we work ──────────────────────────────────────────────────────────── */

/*
 * ⚠️ NO BAND BEHIND THIS ONE.
 *
 * woocommerce.css tints the process section, which put two coloured bands —
 * values and process — either side of the stats with only a thin strip of page
 * between them. The design bands the values section alone; the process sits on
 * the page's own ground, and the contrast between the two is what makes the
 * banded one read as deliberate.
 */
.x-about__process {
  background: none;
  padding-bottom: 0;
}

/* ── start somewhere ──────────────────────────────────────────────────────── */

/*
 * ⚠️ RANGED LEFT, LIKE EVERY OTHER SECTION ON THE PAGE.
 *
 * The old CTA was a centred panel, which is why this inherited centre. Centred
 * over a full-bleed photograph it floats — there is no edge for it to sit
 * against, and the eye has nowhere to start.
 */
.x-about__cta,
.x-about__cta h2,
.x-about__ctatext { text-align: left; }

.x-about__cta h2 { margin-inline: 0; }
.x-about__ctatext { margin-inline: 0; max-width: 46ch; }

.x-about__cta .x-btn,
.x-about__cta .x-btn--light {
  font-weight: 400;
  gap: 0;
}

/* The split image was missing from the placeholder set, so an unset story image
   rendered an empty box rather than the striped panel the others show. */
.x-about__storyimg.is-empty {
  background: repeating-linear-gradient(135deg,
    var(--xg-cream-2) 0 14px,
    #e6dfd0 14px 28px);
}

.x-about__storyimg { aspect-ratio: 4 / 5; }

/*
 * ⚠️ EQUAL COLUMNS, AND THE GRID DECLARED HERE RATHER THAN INHERITED.
 *
 * woocommerce.css gives this section an uneven split sized to the older layout.
 * The design is two equal halves with the copy centred against the image beside
 * it, so both are declared outright rather than left to whichever rule wins.
 */
@media (min-width: 860px) {
  .x-about__story {
    grid-template-columns: 1fr 1fr !important;
    gap: clamp(18px, 3vw, 40px);
    align-items: center;
  }
}

/* The page runs straight on into the values band; the older layout closed itself
   off with padding and a rule that the design does not have. */
.x-about__process { border-top: 0; }
.x-about__story { padding-bottom: 0; }

/* The button was the last thing still set in the theme's older sans. */
.x-about__cta .x-btn,
.x-about__cta .x-btn--light { font-family: var(--xg-sans); line-height: normal; }

/*
 * The design's kicker sets no alignment at all — it inherits, and every section
 * it sits in is ranged left. Ours defaulted to centred, so each section opened
 * with a centred label above a left-ranged heading. Set on the base rather than
 * per-section so a new section cannot reintroduce it.
 */
.x-about__eyebrow { text-align: left; }

/* The kicker was still coral. The design's is --accent-ink, a deep brown-gold;
   only the banner's --is-light variant stays pale, because it sits on green. */
.x-about__eyebrow:not(.is-light) { color: var(--xg-accent-ink); }

/*
 * The design wraps its quote in an inner <p> and sizes that; ours is the
 * blockquote itself, so the type has to be set on the element rather than
 * inherited — otherwise it takes the body's 16px and the pull-quote reads as an
 * ordinary paragraph that happens to sit in a green box.
 */
.x-about__quote {
  font-family: var(--xg-serif);
  font-style: italic;
  font-size: clamp(20px, 3vw, 26px);
  line-height: 1.32;
  max-width: none;
  /* A coral left rule from the palette this layer is migrating away from — the
     only coral left on the page, and it read as a stray stripe on the green. */
  border-left: 0;
}
