/* White Moon — header/mega styles ported verbatim from the whitemoonjewels.com
   theme export (sections/wm-header.liquid + wm-mega-*). Tokens are SCOPED to the
   header subtree so the rest of the theme keeps its own design tokens. */
/* These were originally scoped to `.announce, .header, .mega` so the rest of the
   theme kept its own tokens. That scoping does not work and cannot be made to:
   custom properties are set ON the matched elements, so only their DESCENDANTS
   inherit them. Every sibling that used them silently resolved to nothing —
   `.footer` (fixed by adding it to the list), then `.section` / `.cat__*` /
   `.media`, which rendered with `max-width: none`, `padding: 0`, Jost instead of
   Cormorant and ink instead of silver. Each newly ported section would repeat it.

   Hoisted to :root. Verified safe — this theme's own tokens are all `--wm-`
   prefixed (96 of them, zero unprefixed), so nothing collides. The one shared
   name is `--page-width`, read by `.page-width` in base.css with a `1400px`
   fallback; `--maxw` is 1400px, so that resolves to the value it already used. */
:root {
  /* Cold-luxury neutrals (cool, not warm-cream) */
  --paper:    #ffffff;
  --bone:     #f4f3f0;   /* cool off-white page base */
  --mist:     #e9e8e3;   /* slightly deeper surface */
  --ink:      #16171b;   /* cool near-black */
  --ink-soft: #4c4e56;
  --silver:   #9a9ca3;   /* cool mid grey */
  --hair:     rgba(22, 23, 27, 0.12);
  --hair-soft:rgba(22, 23, 27, 0.07);

  /* The single locked accent: a restrained champagne whisper */
  --accent:   #9c8559;
  --accent-soft: rgba(156, 133, 89, 0.16);

  /* Dark band tokens */
  --night:    #121317;
  --night-2:  #1b1d22;

  --font-display: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --font-sans:    "Jost", system-ui, -apple-system, sans-serif;

  --radius: 0px;                 /* SHAPE LOCK: all-sharp, editorial luxury */
  --maxw: 1400px;
  --gutter: clamp(22px, 6vw, 88px);
  --page-width: var(--maxw);     /* align Eurus base-theme container to the WM site width */
  /* Emil's exact easing curves — built-in eases are too weak. */
  --ease-out:    cubic-bezier(0.23, 1, 0.32, 1);     /* strong UI ease-out */
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);    /* on-screen movement */
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);     /* iOS-like drawer curve */
  --ease: var(--ease-out);                            /* alias: existing rules keep reading --ease */
  --nav-h: 76px;
  /* The announcement strip's height, as a token because the drawer has to
     subtract it — see the note on body[data-menu-open] .nav--left. */
  --announce-h: 40px;
}

/* WM chrome (announce / header / footer) carries its own typography globally,
   so it looks right on every page even when body is styled by Eurus. */
.announce, .header, .footer {
  font-family: var(--font-sans); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}

/* =========================================================
   SHARED PAGE PRIMITIVES
   The reference's content sections (cat / gems / trust / manifesto / journal)
   all build on these three. They live here rather than in a single section so
   the next ported section reuses them instead of redeclaring them. Values read
   off the live site, not estimated.
   ========================================================= */

/* Section shell — the reference declares .section twice and the later, tighter
   pair wins; only the winning values are kept here. */
.section {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: clamp(3rem, 6.5vw, 6.5rem) var(--gutter);
}
.section__head { margin-bottom: clamp(1.7rem, 3.4vw, 2.8rem); }
.section__head--row { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
/* 300 matters: the theme's own heading weight is 400, which reads noticeably
   heavier at this size. */
.section h2 { font-size: clamp(2.4rem, 5.2vw, 4.4rem); font-weight: 300; }

/* Media box. The gradient plus the data-label caption mean an image that is
   missing or still loading reads as intentional space with a name on it,
   rather than a grey hole. */
.media { position: relative; background: linear-gradient(135deg, var(--mist), var(--bone)); overflow: hidden; }
.media::after {
  content: attr(data-label);
  position: absolute; inset: 0; z-index: 0;
  display: flex; align-items: center; justify-content: center;
  padding: 1.4rem; text-align: center;
  font-family: var(--font-sans); font-size: 0.64rem; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--silver);
}
.media > img { position: relative; z-index: 1; }

/* Scroll reveal. Hidden state is gated on .wm-ref-js, which wm-header-ref.js
   adds to <html> as its first act — so a script that never loads leaves the
   content visible. The reference hides .reveal unconditionally; this is the one
   deliberate difference, and it is invisible when the script works. */
.wm-ref-js .reveal {
  opacity: 0;
  transform: translateY(22px) scale(0.992);
  transition: opacity .7s var(--ease-out), transform .7s var(--ease-out);
}
.wm-ref-js .reveal[data-delay="1"] { transition-delay: .06s; }
.wm-ref-js .reveal[data-delay="2"] { transition-delay: .12s; }
.wm-ref-js .reveal[data-delay="3"] { transition-delay: .18s; }
.wm-ref-js .reveal[data-delay="4"] { transition-delay: .24s; }
.wm-ref-js .reveal.in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .wm-ref-js .reveal { opacity: 1; transform: none; transition: none; }
}
.announce *, .header *, .footer * { box-sizing: border-box; }
/* announcement */
.announce { background: var(--ink); color: var(--bone); text-align: center; height: var(--announce-h); overflow: hidden;
  font-size: 0.66rem; letter-spacing: 0.22em; text-transform: uppercase; font-weight: 300; }
.announce__track { display: flex; flex-direction: column; }
.announce__track span { height: var(--announce-h); line-height: var(--announce-h); }
/* header */
.header { position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--bone) 86%, transparent);
  backdrop-filter: blur(12px) saturate(130%);
  border-bottom: 1px solid var(--hair-soft);
  transition: box-shadow 0.5s var(--ease), transform 0.4s var(--ease); }
.header[data-scrolled] { box-shadow: 0 10px 40px rgba(22,23,27,0.05); }
/* smart sticky: slide out on scroll-down, return on scroll-up */
.header[data-hidden] { transform: none; }
.header__inner { max-width: var(--maxw); margin: 0 auto; height: var(--nav-h); padding: 0 var(--gutter);
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; }
.nav { display: flex; align-items: center; gap: 2rem; }
.nav--right { justify-content: flex-end; }
.nav a { font-size: 0.7rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-soft); position: relative; padding: 0.4rem 0; transition: color 0.3s var(--ease); }
.nav a::after { content: ""; position: absolute; left: 0; bottom: 0; width: 100%; height: 1px; background: var(--accent); transform: scaleX(0); transform-origin: left; transition: transform 0.4s var(--ease); }
.nav a:hover { color: var(--ink); }
.nav a:hover::after { transform: scaleX(1); }
/* ---- Engagement mega-menu ---- */
/* NB: keep .nav__item / wrapper UN-positioned so the panel's containing block
   is the sticky .header (full-width), not the narrow nav item. */
.nav__item--mega { align-self: stretch; display: flex; align-items: center; }
.mega {
  position: absolute; top: 100%;
  left: 50%; right: auto;
  width: min(var(--maxw), calc(100vw - 2 * var(--gutter)));
  margin-left: calc(min(var(--maxw), calc(100vw - 2 * var(--gutter))) * -0.5);
  background: var(--bone); border: 1px solid var(--hair-soft);
  box-shadow: 0 24px 50px rgba(22, 23, 27, 0.12);
  opacity: 0; visibility: hidden; transform: translateY(-8px);
  transition: opacity 0.35s var(--ease), transform 0.35s var(--ease), visibility 0.35s var(--ease);
  z-index: 40; pointer-events: none;
}
.nav__item--mega:focus-within .mega,
.nav__item--mega.is-open .mega { opacity: 1; visibility: visible; transform: none; pointer-events: auto; }
.mega__inner {
  max-width: none; margin: 0; padding: clamp(1.7rem, 2.6vw, 2.4rem) clamp(2rem, 3vw, 3rem);
  display: block;
}
.mega__shapeband { margin-bottom: clamp(1.4rem, 2.4vw, 2rem); }
.mega__shapeband .mega__shapes--band { grid-template-columns: repeat(auto-fit, minmax(84px, 1fr)); gap: 0.7rem; }
.mega__shapes--band .mega__shape { flex-direction: column; gap: 0.5rem; text-align: center; font-size: 0.62rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--silver); }
.mega__shapes--band .mega__shape:hover { color: var(--ink); }
.mega__shapes--band .mega__shape-ic { width: 48px; height: 48px; }

/* Photo variant — the shape band now shows the real diamond photograph (the
   same asset the ring builder uses) instead of a line glyph. The circular
   chrome is dropped for it: a ring around a 30px outline reads as an icon
   badge, but a ring around a photographed stone reads as a crop. object-fit:
   contain keeps the stone whole inside the square box whatever its aspect. */
.mega__shape-ic--photo { border: 0; border-radius: 0; }
.mega__shape-ic--photo .wm-shape-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  transition: transform 0.35s var(--ease);
}
.mega__shape:hover .mega__shape-ic--photo .wm-shape-img { transform: scale(1.08); }
@media (prefers-reduced-motion: reduce) {
  .mega__shape-ic--photo .wm-shape-img { transition: none; }
  .mega__shape:hover .mega__shape-ic--photo .wm-shape-img { transform: none; }
}
.mega__row { display: grid; grid-template-columns: 1fr 1.15fr 1fr 1.1fr; gap: clamp(1.5rem, 2.6vw, 3rem); border-top: 1px solid var(--hair-soft); padding-top: clamp(1.4rem, 2.4vw, 2rem); }
.mega__cols { display: grid; grid-template-columns: 1fr 1fr 1fr 1.1fr; gap: clamp(1.5rem, 2.6vw, 3rem); align-items: start; }
.mega__title { font-family: var(--font-sans); font-size: 0.64rem; letter-spacing: 0.22em; text-transform: uppercase; color: var(--ink); padding-bottom: 0.9rem; margin-bottom: 1rem; border-bottom: 1px solid var(--accent); display: inline-block; }
.mega__title--mt { margin-top: 1.8rem; }
.mega a { font-size: 0.78rem; letter-spacing: 0.02em; text-transform: none; color: var(--ink-soft); padding: 0; transition: color 0.25s var(--ease); }
.mega a::after { display: none; }
.mega a:hover { color: var(--accent); }
.mega__shapes { display: grid; grid-template-columns: 1fr 1fr; gap: 0.55rem 1rem; }
.mega__shape { display: flex; align-items: center; gap: 0.7rem; }
.mega__shape-ic { width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center; color: var(--silver); border: 1px solid var(--hair); border-radius: 50%; transition: color 0.25s var(--ease), border-color 0.25s var(--ease); flex: 0 0 auto; }
.mega__shape:hover .mega__shape-ic { color: var(--ink); border-color: var(--ink-soft); }
.mega__links { display: grid; gap: 0.62rem; }
.mega__links--2col { grid-template-columns: 1fr 1fr; gap: 0.62rem 1.4rem; }
.mega__swatches { display: grid; gap: 0.62rem; }
.mega__swatches--2col { grid-template-columns: 1fr 1fr; gap: 0.62rem 1.2rem; }
.mega__swatches a { display: flex; align-items: center; gap: 0.6rem; }
.gem-dot { width: 14px; height: 14px; border-radius: 50%; flex: 0 0 auto; box-shadow: inset 0 0 0 1px rgba(22, 23, 27, 0.14); }
/* 380px is deliberate, not a round number: the promo column is ~286px wide, so
   this makes the card exactly 3:4 — the same ratio as the art now shipped for
   it, which means object-fit: cover crops nothing. It also brings the four
   short category menus (Wedding Bands / Earrings / Necklace / Bracelets, which
   have fewer link rows) up to the height of the tall Engagement card, so the
   promo reads the same weight in every menu instead of looking stunted. */
.mega__promo { display: flex; flex-direction: column; justify-content: flex-end; gap: 0.35rem; padding: 1.4rem; min-height: 380px; color: var(--ink); background: linear-gradient(160deg, var(--mist), var(--bone)); border: 1px solid var(--hair-soft); }
.mega__promo-eyebrow { font-size: 0.6rem; letter-spacing: 0.22em; text-transform: uppercase; color: var(--accent); }
.mega__promo-title { font-family: var(--font-display); font-size: 1.5rem; line-height: 1.1; color: var(--ink); }
.mega__promo-lede { font-size: 0.76rem; color: var(--ink-soft); margin-bottom: 0.4rem; }
.mega__promo-cta { font-size: 0.66rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink); border-bottom: 1px solid var(--accent); align-self: flex-start; padding-bottom: 2px; }
.mega__promo:hover .mega__promo-cta { color: var(--accent); }
.mega__promo-body { display: flex; flex-direction: column; gap: 0.35rem; position: relative; z-index: 1; }
.mega__promo--img { padding: 0; overflow: hidden; justify-content: flex-end; }
.mega__promo-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform 0.6s var(--ease); }
.mega__promo--img:hover .mega__promo-img { transform: scale(1.04); }
.mega__promo--img .mega__promo-body { padding: 2.6rem 1.7rem 1.6rem; background: linear-gradient(to top, rgba(20, 20, 22, 0.92) 0%, rgba(20, 20, 22, 0.8) 45%, rgba(20, 20, 22, 0.55) 80%, rgba(20, 20, 22, 0.2) 100%); }
.mega__promo--img .mega__promo-eyebrow { color: #ecdcb6; }
.mega__promo--img .mega__promo-title,
.mega__promo--img .mega__promo-cta { color: #fff; }
.mega__promo--img .mega__promo-lede { color: rgba(255, 255, 255, 0.86); }
.mega__promo--img:hover .mega__promo-cta { color: #ecdcb6; }
/* Drawer (≤1024px): each mega becomes an expandable accordion inside the burger
   panel. This used to stop at 880, with a separate 881–1024 rule that killed the
   hover panel and left the trigger as a plain link — see the note in the
   RESPONSIVE section for why that band no longer exists. */
@media (max-width: 1024px) {
  /* --announce-h is subtracted as well, and it is not redundant. `.header` sets
     backdrop-filter, which makes IT the containing block for this fixed drawer
     instead of the viewport — so `top: var(--nav-h)` is measured from the header
     box, which itself starts below the announcement strip. Sizing against the
     viewport alone put the drawer's last 40px past the bottom of the screen:
     measured at 1024x800 with a mega expanded, "About" ended 39px below the fold
     and stayed there with the drawer scrolled fully to its end — unreachable.

     When the page is scrolled and the strip has gone, the header is at top: 0
     and this is 40px more conservative than it needs to be. That direction is
     the safe one: a slightly shorter scrollable drawer, never a clipped link. */
  body[data-menu-open] .nav--left {
    max-height: calc(100dvh - var(--nav-h) - var(--announce-h));
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .nav__item--mega { display: block; }
  .nav__mega-trigger { display: flex; align-items: center; justify-content: space-between; }
  .nav__mega-trigger::after {
    content: ""; display: inline-block; width: 7px; height: 7px;
    border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
    transform: rotate(45deg); transition: transform 0.3s var(--ease); margin-left: 0.6rem; opacity: 0.65;
  }
  .nav__item--mega.is-open .nav__mega-trigger::after { transform: rotate(-135deg); }
  .mega {
    position: static; left: auto; right: auto; width: auto; margin-left: 0;
    opacity: 1; visibility: visible; transform: none; pointer-events: auto;
    box-shadow: none; border: 0; background: transparent; z-index: auto;
    max-height: 0; overflow: hidden; transition: max-height 0.45s var(--ease);
  }
  .nav__item--mega.is-open .mega { max-height: 1800px; }
  .mega__inner { display: block; max-width: none; margin: 0; padding: 0.2rem 0 1.2rem; gap: 0; }
  .mega__col { margin-top: 1.4rem; }
  .mega__col:first-child { margin-top: 0.4rem; }
  .mega__title { font-size: 0.58rem; padding-bottom: 0.7rem; margin-bottom: 0.9rem; }
  .mega__shapeband .mega__shapes--band { grid-template-columns: repeat(4, 1fr); gap: 0.6rem; }
  .mega__shapes--band .mega__shape-ic { width: 40px; height: 40px; }
  .mega__row, .mega__cols { display: block; border-top: 0; padding-top: 0; }
  .mega__shapeband { margin-bottom: 0.2rem; }
  .nav--left .mega a { padding: 0; border-bottom: 0; font-size: 0.86rem; }
  .mega__shape { padding: 0.15rem 0; }
  .mega__promo { margin-top: 1.4rem; min-height: 150px; }
}
.brand { display: inline-flex; align-items: center; gap: 0.6rem; color: var(--ink); justify-self: center; }
/* HEIGHT leads, width follows. The other way round — a fixed width with
   `height: auto` — meant the rendered height depended entirely on the logo's
   aspect ratio, and this wordmark is 2155x512 (4.2:1). At the 200px default it
   came out 54.6px tall inside a 64px bar: about 4px of air above and below, so
   the mark read as jammed into the header rather than set in it.

   34px is the measured cap-height band a wordmark wants in a 64px nav — a
   little under half, leaving the logo clearly the largest thing in the bar
   without touching its edges. width:auto lets any aspect ratio size itself from
   that height, so a squarer logo simply comes out narrower instead of taller.

   max-width still honours the merchant's per-instance setting, so a very wide
   wordmark is bounded on both axes and can never push the nav apart. */
.brand__logo {
  height: 34px;
  width: auto;
  max-width: var(--wm-logo-w, 200px);
  object-fit: contain;
}
/* .brand__logo--footer lives in wm-footer.liquid's own {% stylesheet %} — see
   the ownership note at the top of that block. */
.brand__fallback { display: inline-flex; align-items: center; gap: 0.6rem; }
.brand__mark { color: var(--accent); display: inline-flex; }
.brand__word { font-family: var(--font-display); font-size: 1.4rem; letter-spacing: 0.3em; padding-left: 0.3em; font-weight: 400; }
.nav__icons { display: flex; align-items: center; gap: 0.2rem; margin-left: 0.8rem; }
.iconbtn { width: 38px; height: 38px; display: inline-flex; align-items: center; justify-content: center; color: var(--ink-soft); position: relative; transition: color 0.3s var(--ease); }
.iconbtn:hover { color: var(--accent); }
.iconbtn__count { position: absolute; top: 4px; right: 0; display: flex; align-items: center; justify-content: center; min-width: 16px; height: 16px; padding: 0 4px; box-sizing: border-box; background: var(--accent); color: #fff; font-family: var(--font-sans); font-size: 0.6rem; font-weight: 500; line-height: 16px; border-radius: 999px; font-variant-numeric: tabular-nums; }
.burger { display: none; flex-direction: column; gap: 5px; width: 40px; height: 40px; align-items: center; justify-content: center; }
.burger span { width: 22px; height: 1px; background: var(--ink); transition: transform 0.35s var(--ease), opacity 0.35s var(--ease); }
.nav__mobile-extra { display: none; }
/* desktop: hidden — only appears inside the mobile burger drawer */

/* hero */
.hero { position: relative; min-height: calc(100dvh - var(--nav-h) - var(--announce-h)); display: flex; align-items: flex-end; }
/* Container alignment: Eurus base-theme sections (.page-width) inherit the WM
   responsive gutter so left/right padding matches the brand pages site-wide.
   Full-bleed overrides (.full-width-mobile.page-width) keep higher specificity. */
.page-width { padding-left: var(--gutter); padding-right: var(--gutter); }
/* .brand--footer / .footer__brand rules moved into wm-footer.liquid. They and
   the section's own .footer__top / .footer__contact rules declared the same
   properties at the same specificity across two sheets, so the result depended
   on which sheet loaded last. The footer now owns all of them. */
.iconbtn:active, .burger:active { transform: scale(0.94); }
/* =========================================================
   RESPONSIVE
   ========================================================= */
/* The burger drawer starts at 1024, not 880.

   It used to start at 880, and a `@media (max-width: 1024px)` block above it did
   `.nav--left a:nth-child(3), .nav--right a { display: none }`. Two things went
   wrong in the 881–1024 band that rule created:

     1. `.nav--right a` also matches the account and cart links — they are
        <a class="iconbtn">, not buttons. The rule that puts them back
        (.nav__icons .iconbtn) lived inside the 880 block, so between 881 and
        1024 there was no cart, no account, AND no burger to reach them from.
        Measured at 1024 (iPad landscape): Search was the only control left.
     2. Necklace, Bracelets and About were hidden with nowhere to go for the
        same reason — 3 of the 6 top-level destinations simply unreachable.

   `.nav--left a:nth-child(3)` never hit what it was aiming at either: every
   top-level <a> is the FIRST child of its own .nav__item--mega wrapper, so the
   only :nth-child(3) anchor in .nav--left is About inside .nav__mobile-extra —
   which it hid at every width down to 320, taking About out of the drawer too.

   Measured at 1000px: the right nav needs 402px to show its categories, About
   and the icons, but the side track is only 366px — so they genuinely do not
   fit and the band needs the drawer rather than a wider bar. The icons alone
   are 120px and fit easily, which is why they come back below.

   Page-section collapses (.cat__grid, .manifesto__points, …) stay at 880 in
   their own block — only the CHROME moves to 1024. */
@media (max-width: 1024px) {
  :root { --nav-h: 64px; }
  .header__inner { grid-template-columns: auto 1fr auto; column-gap: 0.5rem; }
  .nav--left {
    flex-direction: column; gap: 0; align-items: stretch;
    position: fixed; top: var(--nav-h); left: 0; right: 0;
    background: var(--bone); border-bottom: 1px solid var(--hair);
    padding: 0 var(--gutter);
    transform: translateY(-12px); opacity: 0; pointer-events: none; visibility: hidden;
    /* Emil: drawer-specific easing (Ionic / iOS) */
    transform-origin: top center;
    transition: opacity 0.4s var(--ease-drawer), transform 0.4s var(--ease-drawer), visibility 0.4s; z-index: 49;
  }
  .nav--left a { padding: 1.1rem 0; border-bottom: 1px solid var(--hair-soft); font-size: 0.82rem; }
  .nav--left a:last-child { border-bottom: 0; }
  .nav__mobile-extra { display: block; }
  .nav__mobile-extra a { display: block; }
  body[data-menu-open] .nav--left { opacity: 1; transform: none; pointer-events: auto; visibility: visible; }
  /* Three 1px bars with a 5px gap sit at y = 0 / 6 / 12, so the centre line is
     6px from each outer one — that is the exact travel each outer bar needs to
     meet in the middle and form the X. The middle bar leaves on opacity rather
     than a transform, so it fades under the crossing bars instead of sliding. */
  body[data-menu-open] .burger span:first-child { transform: translateY(6px) rotate(45deg); }
  body[data-menu-open] .burger span:nth-child(2) { opacity: 0; }
  body[data-menu-open] .burger span:last-child { transform: translateY(-6px) rotate(-45deg); }
  /* Mobile chrome: menu icon far-left · logo centered · account+cart far-right.

     grid-row: 1 on all three is load-bearing, not tidiness. The burger is LAST
     in the markup but asks for column 1, and auto-placement walks the grid in
     DOM order — by the time it reaches the burger the cursor has already passed
     column 1 on row 1 (brand took column 2, nav--right column 3), so it opened a
     SECOND row and dropped the burger into it. Measured at 390px: grid rows
     computed to `38px 40px` and the button rendered at y 94–134 against a header
     that ends at 104 — 30px below the bar, off-centre from the logo, and
     overlapping the page beneath it. `.header__inner` has a fixed 64px height,
     so the overflow row had nowhere to go. Pinning every child to row 1 keeps
     the bar one row whatever order the markup happens to be in. */
  .burger { display: flex; grid-column: 1; grid-row: 1; justify-self: start; }
  .brand { grid-column: 2; grid-row: 1; justify-self: center; }
  .brand__word { font-size: 1.15rem; letter-spacing: 0.18em; }
  .nav--right { grid-column: 3; grid-row: 1; justify-self: end; gap: 0; }
  /* Right-nav categories + About collapse into the burger drawer on mobile.
     Hiding them also removes the off-screen mega panels that pushed the
     header to 466px (the 54px overflow → white strip + clipped grid). */
  .nav--right .nav__item--mega,
  .nav--right > a { display: none; }
  .nav__icons { display: flex; margin-left: 0; gap: 0; }
  .nav__icons .iconbtn { display: inline-flex; }
  /* Search stays in the header on phones and tablets. It used to be hidden at
     every width below the desktop breakpoint on the grounds that "search lives
     in-page" — but the in-page entry point is the collection toolbar, so on a
     product page, an article, the cart or the home page there was no way to
     search at all. Desktop had the icon; mobile had nothing.

     Measured at 390: burger 40 + wordmark 143 + three icons 114 + two 8px gaps
     = 313 against 344 of content width, so it fits with room to spare. */
  .nav__icons .iconbtn[aria-label="Search"] { display: inline-flex; }

  /* 44px tap rows without growing the buttons. The bar is genuinely tight at
     320px — burger + wordmark + two icons + gutters leaves about 1px of slack —
     so the hit area is extended with a pseudo-element instead of a bigger box.
     Vertical only: horizontally the icons already sit flush (gap: 0), so the
     whole strip is tappable and inflating them sideways would just overlap
     their neighbours' targets. */
  .burger::before,
  .nav__icons .iconbtn::before {
    content: "";
    position: absolute;
    left: 0; right: 0; top: -3px; bottom: -3px;
  }
  .burger { position: relative; }
}

/* Below ~357px the bar genuinely cannot hold a fourth control: at 320 the
   burger, wordmark and two icons already use 275 of 276px of content width —
   one pixel of headroom. Search is the one to drop there because it is the only
   icon with an alternative route (the collection toolbar), whereas cart and
   account have none. 360 rather than 357 so the smallest common phone widths
   sit clearly on one side of the line instead of on top of it. */
@media (max-width: 359px) {
  .nav__icons .iconbtn[aria-label="Search"] { display: none; }
}

@media (max-width: 880px) {
  .cat__grid { grid-template-columns: repeat(2, 1fr); }
  .cat__tile--feature { grid-column: span 2; grid-row: span 1; }
  .cat__tile--feature .cat__img { aspect-ratio: 16/10; min-height: 0; }
  .manifesto__points { grid-template-columns: 1fr; gap: 0; }
  .manifesto__points li { border-top: 1px solid rgba(244,243,240,0.16); padding: 1.4rem 0; }
  .bespoke { grid-template-columns: 1fr; gap: 2rem; }
  .quotes__grid { grid-template-columns: 1fr; }
  .journal__grid { grid-template-columns: 1fr; }
  .trust__row { grid-template-columns: repeat(2, 1fr); gap: 1.6rem 0; }
  .trust__row li + li::before { display: none; }
  /* .footer__top / .footer__brand collapses moved into wm-footer.liquid. */
}
@media (max-width: 520px) {
  .field { flex-direction: column; }
  .hero__cta { gap: 1.1rem; }
  .cat__grid { grid-template-columns: 1fr; }
}
@media (max-width: 880px) {
  .collection-body { grid-template-columns: 1fr; gap: 0; }
  .filters { display: none; }
  .prod-grid { grid-template-columns: repeat(2, 1fr); gap: 18px; }
  .toolbar { padding-bottom: 1rem; }
  .mobile-bar { display: flex; }
  .collection { padding-bottom: 88px; }
  .shape-tile { width: 80px; padding: 0.7rem 0.5rem; }
  .chero h1 { font-size: clamp(2.2rem, 9vw, 3.4rem); }
  /* sort menu becomes a bottom sheet (reachable from the sticky bar's Sort button) */
  .sort__menu {
    position: fixed; left: 14px; right: 14px; top: auto;
    bottom: calc(84px + env(safe-area-inset-bottom));
    min-width: 0; z-index: 96; transform-origin: bottom center;
    box-shadow: 0 -14px 50px rgba(22,23,27,0.14);
  }
  .sort__menu li { padding: 0.85rem 1rem; }
  /* comfortable touch targets in the filter drawer + chips */
  .filter-drawer .filter-list label, .filter-drawer .metal-row { padding-block: 0.65rem; }
  .filter-drawer .filter-group summary { padding-block: 0.7rem; }
  .active-filters__chip { padding-block: 0.6rem; }
  .drawer__head .iconbtn { width: 44px; height: 44px; }
}
body.wm-reels .wm-section--header,
body.wm-reels .wm-section--footer { display: none !important; }
.reel-brand {
  justify-self: center;
  display: inline-flex; align-items: center; gap: 0.55rem;
  font-family: var(--font-display); font-size: 0.92rem; letter-spacing: 0.32em;
  color: #fff;
}
/* Brand wordmark: shadowed for guaranteed contrast everywhere */
body.wm-reels .reel-brand {
  font-size: 0.84rem;
  letter-spacing: 0.28em;
  text-shadow: 0 1px 3px rgba(0,0,0,0.55), 0 0 12px rgba(0,0,0,0.35);
}
body.wm-reels .reel-brand svg { filter: drop-shadow(0 1px 2px rgba(0,0,0,0.55)); }
.opt__metal .vh:checked ~ .metal-pick, .opt__metal .vh:checked ~ .gem-dot { box-shadow: 0 0 0 2px var(--paper), 0 0 0 3px var(--accent); }
.opt__metal .vh:focus-visible ~ .metal-pick, .opt__metal .vh:focus-visible ~ .gem-dot { outline: 2px solid var(--accent); outline-offset: 2px; }
.gem-dot--lg { width: 26px; height: 26px; }
/* Sticky header fix — the header section wrapper is short (~117px), which
   breaks the inner .header's position:sticky (sticky only works within the
   parent's bounds). Pin the wrapper itself; its parent (.main-container) is
   full-page height, so the header bar now stays put on scroll. */
.wm-section--header { position: sticky; top: 0; z-index: 50; }

/* Search overlay — kept from the White Moon CLI header so the predictive-search
   panel still works behind the ported icon button. Hidden until opened: no visual change. */
/* ---- search overlay --------------------------------------------------- */
  .wm-search { background: var(--wm-paper); color: var(--wm-ink); border-top: 1px solid var(--wm-hair); }

.wm-search__inner { display: flex; align-items: center; gap: var(--wm-space-4); padding-block: var(--wm-space-4); }

.wm-search__form { display: flex; flex: 1 1 auto; gap: var(--wm-space-3); align-items: center; }

.wm-search__input { flex: 1 1 auto; min-width: 0; min-height: 44px; padding: 0 var(--wm-space-2); background: transparent; border: 0; border-bottom: 1px solid var(--wm-line); font: inherit; font-size: var(--wm-text-lg); color: var(--wm-ink); }

.wm-search__input:focus-visible { outline: none; border-color: var(--wm-accent); }

/* WHY THE NATIVE CLEAR BUTTON IS HIDDEN.
   `type="search"` makes Chrome/Safari draw their OWN ✕ inside the field. Next to
   our overlay-close ✕ that put two identical-looking crosses side by side with
   different jobs — one wipes the text, one shuts the panel — and the shopper
   cannot tell which is which. The native one is also unstyleable beyond this,
   so it never matched the rest of the row.

   `type="search"` is kept rather than swapped for `text`: it is the correct
   semantic, it gives the field the right role, and on iOS it puts a Search key
   on the keyboard. Only the decoration is removed. */
.wm-search__input::-webkit-search-cancel-button,
.wm-search__input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; }

/* 44px box, not just a 28px glyph. Measured 17x28 before this — the control a
   shopper reaches for the moment the overlay opens by accident was the smallest
   target on the bar. Same treatment as the facets drawer close. */
.wm-search__close {
  font-size: 28px;
  line-height: 1;
  color: var(--wm-ink);
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}

/* Predictive dropdown (populated by wm-search.js).

   These rules were lost when the header was ported: the comment survived but
   every .wm-suggest rule under it did not, so wm-search.js kept injecting the
   markup and nothing styled it. The visible symptom was a product thumbnail
   rendering at its natural size — a ~440px image filling the viewport with the
   title crushed underneath — because .wm-suggest__thumb's 44px box was gone.
   The dropdown is generated by JS, so there is no template whose {% stylesheet %}
   could own this; it lives here beside the overlay markup it decorates. */
  .wm-search__inner { position: relative; flex-wrap: wrap; }

.wm-suggest {
  position: absolute;
  left: 0; right: 0; top: 100%;
  background: var(--wm-paper);
  border: 1px solid var(--wm-hair);
  border-top: 0;
  box-shadow: var(--wm-shadow-pop);
  max-height: 70vh;
  overflow-y: auto;
  z-index: var(--wm-z-mega);
}
.wm-suggest__group { padding: var(--wm-space-3) 0; border-bottom: 1px solid var(--wm-hair-soft); }
.wm-suggest__label {
  margin: 0 var(--wm-space-4) var(--wm-space-2);
  font-size: var(--wm-text-xs);
  letter-spacing: var(--wm-tracking-wide);
  text-transform: uppercase;
  color: var(--wm-accent);
}
.wm-suggest ul { margin: 0; padding: 0; list-style: none; }

.wm-suggest__product {
  display: flex;
  align-items: center;
  gap: var(--wm-space-3);
  padding: var(--wm-space-2) var(--wm-space-4);
  color: var(--wm-ink);
}
.wm-suggest__product:hover,
.wm-suggest [role="option"].is-active { background: var(--wm-bone); }

/* The flex-basis AND the explicit box both matter: without them the injected
   <img> lays out at its intrinsic size, which is what broke this. */
.wm-suggest__thumb {
  flex: 0 0 44px;
  width: 44px; height: 44px;
  background: var(--wm-bone);
  overflow: hidden;
}
.wm-suggest__thumb img { width: 100%; height: 100%; object-fit: cover; }

.wm-suggest__pinfo { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.wm-suggest__ptitle { font-size: var(--wm-text-sm); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wm-suggest__pprice { font-size: var(--wm-text-xs); color: var(--wm-text-muted); }

.wm-suggest__link { display: block; padding: 8px var(--wm-space-4); font-size: var(--wm-text-sm); color: var(--wm-ink); }
.wm-suggest__link:hover { color: var(--wm-link); }

.wm-suggest__all {
  display: block;
  padding: var(--wm-space-4);
  font-size: var(--wm-text-sm);
  text-align: center;
  border-top: 1px solid var(--wm-hair);
  color: var(--wm-ink);
}
.wm-suggest__all:hover, .wm-suggest__all.is-active { background: var(--wm-ink); color: var(--wm-bone); }

.wm-suggest__none { padding: var(--wm-space-5) var(--wm-space-4); font-size: var(--wm-text-sm); color: var(--wm-text-muted); text-align: center; }

/* --------------------------------------------------------------------------
   Generic resets the reference relies on. wm-design.css carries a bare
   `ul { margin:0; padding:0; list-style:none; }`; the header CSS slice only
   kept header/mega-named rules, so that reset was dropped and every mega list
   rendered with bullets. Re-added SCOPED to the header subtree so the rest of
   the White Moon theme keeps its own list styling.
   -------------------------------------------------------------------------- */
:where(.announce, .header) ul { margin: 0; padding: 0; list-style: none; }
:where(.announce, .header) li { list-style: none; }

/* The reference wraps this section in its own `.wm-section`, which in OUR theme
   means "page section" and adds padding-block — that produced a large empty
   band above the announcement bar. The section tag now uses `.wm-header-section`
   (see the schema); pin it flush so the announce bar sits at the very top. */
.wm-header-section { padding-block: 0; margin: 0; }


/* bare-element resets — copied VERBATIM from the reference's wm-design.css and
   scoped to the header subtree. The header CSS slice only kept class-named rules,
   so these (like the ul reset above) were dropped and the header inherited our
   theme's defaults instead of the reference's. */
:where(.announce, .header) img { display: block; max-width: 100%; height: auto; }
:where(.announce, .header) a { color: inherit; text-decoration: none; }
:where(.announce, .header) button { font-family: inherit; cursor: pointer; border: 0; background: none; color: inherit; }
:where(.announce, .header) :is(h1, h2, h3, h4, h5) { margin: 0; font-family: var(--font-display); font-weight: 300; line-height: 1.04; letter-spacing: 0.004em; }

