/* LuxPeptides — shared component CSS (header, footer, age gate, cards) */

/* ---------- CLS GUARD ----------
   All vial / product PNGs are square by convention. Reserving the
   1:1 aspect ratio in CSS prevents the "browser doesn't know image
   dimensions until the bytes arrive → reflow once they do" CLS source
   that the SEO audit flagged. Cheaper than touching every <img> tag
   to add explicit width/height attributes. Applies to filmstrip cells,
   shop hero vials, PDP hero, floating-catalog vials, and search
   thumbnails. Override locally if a non-square image lives in any of
   these classes. */
.hero-film__cell img,
.shop-hero__vial,
.pdp__hero-img > img,
.cf-vial img,
.lp-search-result__thumb img {
  aspect-ratio: 1 / 1;
}

/* ---------- SITE-WIDE SEARCH OVERLAY ----------
   Triggered from the magnifier in the header, slides down from the top
   over a blurred dark backdrop. Brand voice: dark surface, gold border,
   serif type for product names, mono-uppercase for the eyebrow + category.
   Built in lp-chrome.js (`buildSearchOverlay`) and wired in `wireSearch`. */
.lp-search-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  /* Pure-black backdrop with high opacity so the panel's true-black fill
     reads as a continuous void rather than as a panel against a tinted
     surface. The slight transparency + saturate blur preserves the sense
     of "the page is still there behind this". */
  background: rgba(0, 0, 0, 0.86);
  backdrop-filter: blur(12px) saturate(140%);
  -webkit-backdrop-filter: blur(12px) saturate(140%);
  display: flex;
  justify-content: center;
  /* Center vertically so the panel sits in the middle of any viewport
     instead of anchored near the top. Padding gives breathing room from
     all four edges so the panel never butts up against them. */
  align-items: center;
  padding: 24px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 280ms var(--ease);
}
.lp-search-overlay.is-open {
  opacity: 1;
  pointer-events: auto;
}
body.lp-search-open { overflow: hidden; }

.lp-search-overlay__panel {
  /* True black to match catalog-float.html — the panel reads as a window
     cut into the void, not a tinted card on a tinted backdrop. */
  background: #000;
  border: 1px solid var(--gold-400);
  width: 100%;
  max-width: 680px;
  /* Always fits the viewport — `100% - 48px` so the panel is bounded by
     the overlay's 24px padding on top and bottom no matter the screen
     height. Inner results scroll within. */
  max-height: calc(100dvh - 48px);
  padding: 28px 32px 24px;
  position: relative;
  /* Slight scale instead of vertical drift now that the panel is
     centered — feels like the panel "snaps in" from the void rather
     than dropping from the top. */
  transform: scale(0.98);
  transition: transform 360ms var(--ease);
  box-shadow: 0 40px 80px rgba(0, 0, 0, 0.6);
  display: flex;
  flex-direction: column;
}
.lp-search-overlay.is-open .lp-search-overlay__panel { transform: scale(1); }

.lp-search-overlay__head {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 20px;
}
.lp-search-overlay__eyebrow {
  font-family: var(--font-sans);
  font-size: 11px;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: var(--gold-200);
}
.lp-search-overlay__close {
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--rule);
  background: transparent;
  color: var(--beige-200);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease);
}
.lp-search-overlay__close:hover {
  border-color: var(--gold-300);
  color: var(--gold-100);
}

/* Field — gold underline only, transparent bg, large serif type to feel
   like an editorial inquiry rather than a generic site search. */
.lp-search-overlay__field {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 14px;
  padding: 8px 0 14px;
  border-bottom: 1px solid var(--gold-300);
}
.lp-search-overlay__field-icon { color: var(--gold-200); flex-shrink: 0; }
.lp-search-overlay__input {
  background: transparent;
  border: 0;
  outline: 0;
  font-family: var(--font-serif);
  font-size: clamp(22px, 2.6vw, 30px);
  font-weight: 400;
  letter-spacing: -0.005em;
  color: var(--beige-50);
  padding: 4px 0;
  width: 100%;
}
.lp-search-overlay__input::placeholder {
  color: var(--fg-dim);
  font-style: italic;
}

.lp-search-overlay__hint {
  font-family: var(--font-sans);
  font-size: 11px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--fg-muted);
  padding: 14px 0 4px;
}

.lp-search-overlay__results {
  /* Flex inside the centered panel — the panel has `max-height: 100dvh -
     48px` and is a flex column, so the results section flexes to absorb
     all leftover space (after the head + field + hint) and scrolls
     internally. No fixed `vh` clamp here; the panel's height is the
     authoritative cap, regardless of browser size. */
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  margin-top: 4px;
  /* Small custom scrollbar to match the dark surface. */
  scrollbar-width: thin;
  scrollbar-color: var(--gold-400) transparent;
}
.lp-search-overlay__results::-webkit-scrollbar { width: 6px; }
.lp-search-overlay__results::-webkit-scrollbar-thumb {
  background: var(--gold-400);
}

.lp-search-overlay__empty {
  font-family: var(--font-serif);
  font-style: italic;
  color: var(--fg-muted);
  font-size: 16px;
  padding: 20px 0;
  text-align: center;
}

.lp-search-result {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: 16px;
  align-items: center;
  padding: 14px 0;
  border-bottom: 1px solid var(--rule);
  text-decoration: none;
  color: inherit;
  transition: background var(--dur-fast) var(--ease);
}
.lp-search-result:hover {
  background: rgba(212, 178, 102, 0.06);
}
.lp-search-result:last-child { border-bottom: 0; }
.lp-search-result__thumb {
  width: 56px; height: 56px;
  background: var(--ink-2);
  border: 1px solid var(--rule);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  position: relative;
  overflow: hidden;
}
.lp-search-result__thumb img {
  max-width: 80%; max-height: 80%;
  object-fit: contain;
}
.lp-search-result__meta { min-width: 0; }
.lp-search-result__cat {
  font-family: var(--font-sans);
  font-size: 10px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--gold-300);
  margin-bottom: 4px;
}
.lp-search-result__name {
  font-family: var(--font-serif);
  font-size: 18px;
  line-height: 1.15;
  color: var(--beige-50);
}
.lp-search-result__sub {
  font-size: 12px;
  color: var(--fg-muted);
  margin-top: 4px;
  /* Truncate long subtitles so the row height stays consistent. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lp-search-result__price {
  font-family: var(--font-sans);
  font-size: 13px;
  letter-spacing: 0.04em;
  color: var(--beige-100);
  white-space: nowrap;
}
.lp-search-result--more {
  grid-template-columns: 1fr;
  text-align: center;
  font-family: var(--font-sans);
  font-size: 11px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--gold-100);
  padding: 18px 0 6px;
}
.lp-search-result--more:hover { color: var(--gold-200); }

/* Group headers inside the search overlay — separates "Solo Compounds"
   from "Blends" so the result list reads as a categorised menu instead
   of a flat ordered-by-array list. */
.lp-search-group__head {
  display: flex; align-items: center; gap: 16px;
  padding: 16px 0 8px;
  font-family: var(--font-sans);
  font-size: 11px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--gold-100);
}
.lp-search-group__head:first-child { padding-top: 4px; }
/* The trailing space inside the label is significant — combined with
   gap:16px on the parent it gives the label a breathing zone before
   the divider rule. Same on the count side. */
.lp-search-group__label { padding-right: 4px; white-space: pre; }
.lp-search-group__count { padding-left: 4px; white-space: pre; color: var(--gold-200); }
.lp-search-group__rule {
  flex: 1 1 auto;
  height: 1px;
  background: var(--rule);
}

/* Mobile — tighten overlay padding and panel padding so the centered
   panel uses the available viewport efficiently. The desktop max-height
   formula (`100dvh - 48px`) becomes `100dvh - 24px` here since the
   overlay's outer padding shrinks accordingly. */
@media (max-width: 600px) {
  .lp-search-overlay { padding: 12px; }
  .lp-search-overlay__panel {
    padding: 20px 18px 18px;
    max-height: calc(100dvh - 24px);
  }
  .lp-search-result { grid-template-columns: 48px 1fr auto; gap: 12px; padding: 12px 0; }
  .lp-search-result__thumb { width: 48px; height: 48px; }
  .lp-search-result__name { font-size: 16px; }
  .lp-search-result__sub { font-size: 11px; }
}

/* ---------- HEADER ---------- */
.lp-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(7, 6, 10, 0.84);
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  border-bottom: 1px solid var(--rule);
  /* iPhone notch / Android cutout — extend the header background up
     into the safe area so the blur reads as a solid bar to the very
     top of the viewport. Without this, the notch appears as a black
     gap above a "floating" pill. */
  padding-top: env(safe-area-inset-top, 0);
}
.lp-header__inner {
  display: grid;
  /* 1fr auto 1fr keeps the X logo centred when the side columns have room (the
     common desktop case); the shortened "Calculator" label keeps the nav narrow
     enough to stay centred without ever overlapping the logo. (minmax(0,1fr)
     forces dead-centre but lets a too-wide nav collide with the logo — avoided.) */
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  /* Was 84px — trimmed to 72px so the header takes a touch less vertical
     real estate without resizing the logo (44px), nav (11px), or icons
     (32px) inside. The logo now has 14px of vertical breathing room on
     each side instead of 20px — still clean, just tighter. */
  height: 72px;
  padding: 0 var(--gutter);
  max-width: var(--max-w);
  margin: 0 auto;
}
.lp-nav { display: flex; gap: 36px; }
.lp-nav a {
  font-size: 12px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--beige-100);
  position: relative;
  padding: 6px 0;
  /* Keep every nav label on a SINGLE line. Without this, a two-word label
     ("Reconstruction Calculator") wraps to two lines while the single-word
     links stay on one, making the row look vertically uneven. */
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease);
}
/* The nav is a single non-wrapping row; align every item on one baseline so a
   mix of plain links + the Shop dropdown item never sit at different heights. */
.lp-nav { align-items: center; }
.lp-nav a:hover { color: var(--gold-100); }
.lp-nav a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: var(--gold-200);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur) var(--ease);
}
.lp-nav a:hover::after, .lp-nav a.is-active::after { transform: scaleX(1); }
.lp-nav a.is-active { color: var(--gold-100); }

.lp-header__logo {
  display: flex; align-items: center; justify-content: center;
}
.lp-header__logo svg,
.lp-header__logo img { height: 44px; width: auto; display: block; }

.lp-header__right {
  display: flex; align-items: center; justify-content: flex-end; gap: 24px;
}
.lp-header__icon-btn {
  /* Tap target: 44px square so finger taps land reliably on phones.
     The icon glyph still renders at its design size — the extra space
     is hit area, not visual chrome. */
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 0;
  color: var(--beige-100);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease);
}
.lp-header__icon-btn:hover { color: var(--gold-100); }
.lp-header__cart {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 18px;
  border: 1px solid var(--gold-400);
  font-size: 12px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--beige-100);
  transition: border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.lp-header__cart:hover { border-color: var(--gold-200); color: var(--gold-100); }
.lp-header__cart .count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
  background: var(--gold-200); color: var(--ink-0);
  font-size: 11px; font-weight: 600; letter-spacing: 0;
}

/* ----- 900px breakpoint — small-laptop tier -----
   Logo moves to the top-left of the header, but nav stays visible
   inline next to it. Right-cluster compacts (icon-only cart) but the
   hamburger is NOT shown — the primary nav links must remain reachable
   without a click at any desktop / small-laptop width. Hamburger only
   appears at the true tablet/mobile tier below (640px). */
@media (max-width: 900px) {
  .lp-header__inner {
    display: flex;
    align-items: center;
    gap: 16px;
    height: 64px;
  }
  .lp-header__logo { order: 1; flex: 0 0 auto; justify-content: flex-start; }
  .lp-header__logo svg,
  .lp-header__logo img { height: 32px; }

  .lp-nav {
    order: 2;
    flex: 1 1 auto;
    min-width: 0;
    gap: 20px;          /* was 36px — fit five items next to the logo */
  }
  .lp-nav a {
    font-size: 11px;
    letter-spacing: 0.22em;
    white-space: nowrap;
  }

  .lp-header__right { order: 3; margin-left: auto; gap: 8px; }

  /* Compact cart: icon-only square button with count overlaid as a
     badge. The "$0.00" price was eating ~40% of the header on a 375px
     viewport — keeping this compact form across small-desktop too so
     the inline nav has room to breathe. */
  .lp-header__cart {
    width: 36px; height: 36px;
    padding: 0;
    position: relative;
    justify-content: center;
    gap: 0;
  }
  .lp-header__cart [data-cart-total] { display: none; }
  .lp-header__cart .count {
    position: absolute;
    top: -6px; right: -6px;
    border: 1px solid var(--ink-0);
  }
  /* Keep the 44px tap target at the mobile tier too — the visual icon
     is still 24px, the hit area just stays generous. */
  .lp-header__icon-btn { width: 44px; height: 44px; }
}

/* ----- 720px breakpoint — true tablet/mobile -----
   Inline nav no longer fits beside the logo + right cluster (5 nav
   items at 10px font with 0.22em letter-spacing run ~430px, plus
   ~150px of logo + right cluster, leaves no headroom below ~720px).
   Hide it and reveal the hamburger; clicking the hamburger opens the
   drawer with all primary nav links. */
@media (max-width: 720px) {
  .lp-header__inner { gap: 8px; }
  .lp-nav { display: none; }
  .lp-mobile-toggle { display: inline-flex !important; }
}
/* Hamburger button — 44×44 tap target meets iOS HIG even though the
   visible icon is 24×24. Display switched on by the 720px media query. */
.lp-mobile-toggle {
  display: none;
  width: 44px; height: 44px;
  align-items: center; justify-content: center;
  color: var(--beige-100);
  transition: color 160ms var(--ease), background 160ms var(--ease);
}
.lp-mobile-toggle:active { background: rgba(212,178,102,0.10); color: var(--gold-100); }

/* Mobile drawer — slide-in animation, backdrop, body-scroll-lock applied
   by lp-chrome.js when toggled. The drawer itself is the panel; the body
   gets `.lp-drawer-open` to freeze the page beneath. */
.lp-mobile-drawer {
  position: fixed;
  inset: 0;
  background: rgba(7, 6, 10, 0.96);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  z-index: 100;
  padding: calc(env(safe-area-inset-top, 0) + 56px) var(--gutter) calc(env(safe-area-inset-bottom, 0) + 24px);
  display: flex;
  flex-direction: column;
  gap: 4px;
  /* Pre-animation state: off-screen + hidden from a11y / hit-testing. */
  visibility: hidden;
  transform: translateY(-12px);
  opacity: 0;
  transition: opacity 220ms var(--ease),
              transform 280ms cubic-bezier(0.32, 0.72, 0, 1),
              visibility 0s linear 280ms;
}
.lp-mobile-drawer.is-open {
  visibility: visible;
  transform: translateY(0);
  opacity: 1;
  transition: opacity 200ms var(--ease),
              transform 320ms cubic-bezier(0.32, 0.72, 0, 1);
}
/* Drawer-open body lock — `overflow: hidden` on body prevents the
   page beneath the drawer from being scrollable. We deliberately do
   NOT set `touch-action: none` here because that would also block the
   drawer itself from accepting touch gestures (a child element
   inherits the ancestor's touch-action unless it sets its own). The
   small iOS rubber-band that overflow:hidden allows is a fair trade
   for keeping the drawer fully interactive. */
body.lp-drawer-open { overflow: hidden; }
.lp-mobile-drawer a {
  font-family: var(--font-serif);
  font-size: clamp(30px, 7vw, 43px);
  color: var(--beige-50);
  border-bottom: 1px solid var(--rule);
  padding: clamp(14px, 3vw, 20px) 0;
  min-height: 44px;
  display: flex; align-items: center;
}
.lp-mobile-drawer a:hover { color: var(--gold-100); }
.lp-mobile-drawer a:active { color: var(--gold-200); }
@media (prefers-reduced-motion: reduce) {
  .lp-mobile-drawer { transition: none; }
}
.lp-mobile-drawer__close {
  position: absolute; top: 16px; right: calc(var(--gutter) - 10px);
  /* Tap target ≥ 44px so the X is easy to hit one-handed on a phone.
     Visual icon stays small; the rest is hit area. */
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 0;
  color: var(--beige-100);
  cursor: pointer;
}

/* ---------- FOOTER ---------- */
.lp-footer {
  background: var(--ink-0);
  border-top: 1px solid var(--rule);
  padding: var(--s-9) var(--gutter) var(--s-6);
  margin-top: var(--s-10);
}
.lp-footer__inner {
  max-width: var(--max-w);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: var(--s-7);
}
.lp-footer__mark { display: flex; flex-direction: column; gap: 24px; }
.lp-footer__mark svg { height: 56px; width: auto; }
.lp-footer__mark p {
  color: var(--fg-muted);
  font-size: 14px;
  max-width: 32ch;
  line-height: 1.7;
}
.lp-footer__col h4 {
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--gold-100);
  margin-bottom: 20px;
}
.lp-footer__col ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 4px; }
.lp-footer__col a {
  color: var(--beige-100);
  font-size: 15px;
  transition: color var(--dur-fast) var(--ease);
  display: inline-block;
  padding: 8px 0;
}
.lp-footer__col a:hover { color: var(--gold-100); }

.lp-footer__bottom {
  max-width: var(--max-w); margin: var(--s-7) auto 0;
  padding-top: var(--s-5);
  border-top: 1px solid var(--rule);
  display: flex; justify-content: space-between; align-items: center;
  gap: 24px;
  flex-wrap: wrap;
}
.lp-footer__legal {
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--fg-dim); max-width: 60ch; line-height: 1.6;
}
.lp-footer__copy { font-size: 12px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--fg-dim); }

@media (max-width: 900px) {
  .lp-footer__inner { grid-template-columns: 1fr 1fr; gap: var(--s-6); }
  .lp-footer__mark { grid-column: span 2; }
}
@media (max-width: 520px) {
  .lp-footer__inner { grid-template-columns: 1fr; }
  .lp-footer__mark { grid-column: span 1; }
}

/* ---------- AGE GATE ---------- */
/* ===== Age gate =====
   Goal: render legibly on EVERY screen — phones in portrait, 1366×768
   laptops, 4K desktops, kiosks, you name it. Strategy:
     1. Container scrolls vertically if content overflows (`overflow-y: auto`)
        — no more silently clipped buttons on a 720p laptop.
     2. Container is flex column with a centered inner block. `min-height:
        100dvh` ensures the inner always reaches viewport-bottom even when
        content is short; `dvh` (dynamic viewport units) tracks the actual
        visible area on mobile after the URL bar collapses.
     3. Every gap, font size, and pad uses clamp() so the layout fluidly
        scales from a tiny phone (320 wide × ~568 tall) up to a 4K desktop.
        Worst-case still fits at 320×568 without needing scroll.
     4. Logo + title + warn shrink first on short viewports; body text
        stays readable.
*/
.age-gate {
  position: fixed; inset: 0;
  background: var(--ink-0);
  z-index: 1000;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  /* Vertical pad scales down on short screens so we don't waste 96px
     of empty space top + bottom on a 568px-tall iPhone in landscape. */
  padding: clamp(16px, 4vh, 48px) clamp(16px, 4vw, 48px);
  opacity: 1;
  transition: opacity 700ms var(--ease);
  overflow-y: auto;        /* if even the clamped sizes overflow, scroll */
  overflow-x: hidden;
  /* Lock body scroll while the gate is up — prevents the background
     page from scrolling behind a translucent edge of the gate. */
  overscroll-behavior: contain;
  /* Tap targets stay finger-friendly on touch */
  -webkit-tap-highlight-color: transparent;
}
.age-gate.is-leaving { opacity: 0; pointer-events: none; }
.age-gate__bg {
  position: fixed; inset: 0;      /* fixed (not absolute) so it doesn't scroll with content */
  background:
    radial-gradient(ellipse at 50% 30%, rgba(184,145,73,0.08), transparent 60%),
    radial-gradient(ellipse at 50% 70%, rgba(184,145,73,0.04), transparent 70%);
  pointer-events: none;
  z-index: 0;
}
.age-gate__inner {
  position: relative;
  z-index: 1;
  max-width: 640px;
  width: 100%;
  margin: auto;              /* center vertically when content fits, top-aligns when it doesn't */
  text-align: center;
  display: flex; flex-direction: column;
  align-items: center;
  /* Vertical rhythm scales 16 → 36 with viewport height. On a 568px-tall
     screen the inner shrinks tight; on a 1200px-tall screen it breathes. */
  gap: clamp(16px, 3.5vh, 36px);
}
.age-gate__logo {
  animation: fade-in 800ms var(--ease) both;
  /* Defensive: if some other style breaks the flex column alignment,
     keep the logo centered. */
  display: flex; justify-content: center;
}
/* Logo: 56 → 96 with viewport. */
.age-gate__logo img,
.age-gate__logo svg {
  height: clamp(56px, 10vh, 96px);
  width: auto;
  display: block;
}
.age-gate__rules {
  display: flex; align-items: center; gap: 16px;
  width: 100%;
  animation: fade-in 800ms var(--ease) both 200ms;
}
.age-gate__rules .line { flex: 1; height: 1px; background: var(--gold-400); opacity: .6; }
.age-gate__rules .label {
  font-size: 11px; letter-spacing: 0.42em; text-transform: uppercase; color: var(--gold-200);
}
.age-gate__title {
  font-family: var(--font-serif);
  /* Floor was 32; that's still big on a small phone or a 720p laptop.
     New floor 24 fits comfortably and the upper bound stays 56 for big
     desktops. */
  font-size: clamp(26px, 4.5vw, 60px);
  font-weight: 400;
  line-height: 1.15;
  color: var(--beige-50);
  animation: fade-in 800ms var(--ease) both 300ms;
  /* Long-form wrapping for "twenty-one" so a narrow column doesn't
     break the word awkwardly. */
  text-wrap: balance;
}
.age-gate__title em { color: var(--gold-100); font-style: italic; }
.age-gate__body {
  color: var(--beige-200);
  font-size: clamp(14px, 1.4vw, 16px);
  line-height: 1.6;          /* tighter than 1.75 — saves ~40px on a small viewport */
  max-width: 52ch;
  animation: fade-in 800ms var(--ease) both 400ms;
}
.age-gate__body a { color: var(--gold-100); text-decoration: underline; text-underline-offset: 4px; }
.age-gate__actions {
  display: flex; gap: 12px; flex-wrap: wrap; justify-content: center;
  width: 100%;
  animation: fade-in 800ms var(--ease) both 500ms;
}
.age-gate__warn {
  display: inline-block;
  margin-top: 4px;
  padding: 10px 18px;
  border: 1px solid var(--gold-400);
  font-size: 11px; letter-spacing: 0.28em; text-transform: uppercase;
  color: var(--gold-100);
  /* Allow the warn line to wrap on very narrow screens instead of
     forcing horizontal overflow. */
  max-width: 100%;
  white-space: normal;
  animation: fade-in 800ms var(--ease) both 600ms;
}

/* ----- Phone / tablet portrait ----- */
@media (max-width: 520px) {
  .age-gate__actions { flex-direction: column; width: 100%; }
  .age-gate__actions .btn { width: 100%; justify-content: center; }
  .age-gate__body { font-size: 14px; line-height: 1.55; }
}

/* ----- Short laptops (1366×768, 1280×720, MacBook in split-screen) -----
   Trigger when the viewport is shorter than ~720px regardless of width.
   Compress vertical rhythm further and demote the warn line so the
   primary CTA buttons are guaranteed visible above the fold. */
@media (max-height: 720px) {
  .age-gate__inner { gap: clamp(12px, 2.5vh, 24px); }
  .age-gate__logo img,
  .age-gate__logo svg { height: clamp(44px, 7vh, 72px) !important; }
  .age-gate__title { font-size: clamp(24px, 3.8vw, 43px); }
  .age-gate__body { line-height: 1.5; }
  .age-gate__warn { padding: 8px 14px; font-size: 10px; letter-spacing: 0.24em; }
}

/* ----- Very short (300-something px tall — bootcamps, kiosk overlays) -----
   At this point we drop the rules-line ornament and the warn box;
   only the title + body + buttons matter for the consent moment.
   Buttons also lose .btn--lg padding so the two CTAs comfortably fit. */
@media (max-height: 560px) {
  .age-gate__rules { display: none; }
  .age-gate__warn { display: none; }
  .age-gate__inner { gap: 12px; }
  .age-gate__actions .btn { padding: 12px 22px; }
}

/* ----- Landscape orientation on small heights -----
   Phones in landscape (e.g. iPhone 13 landscape = 844×390) — the height
   is the constraint. The same compressed sizing kicks in via @media
   (max-height) above; this block just enables the side-by-side button
   row that the narrow-portrait media query disabled. */
@media (orientation: landscape) and (max-height: 520px) {
  .age-gate__actions { flex-direction: row; }
  .age-gate__actions .btn { width: auto; flex: 1 1 0; min-width: 0; }
  /* And tighten the body further — landscape phone gets the strictest
     vertical budget of any mainstream form factor. */
  .age-gate__body {
    /* Collapse the inter-paragraph break (the body uses <br/><br/> for
       paragraphing) to a single line of space. Selecting `br + br`
       targets the second <br> in each pair and zeros its height. */
    line-height: 1.45;
  }
  .age-gate__body br + br { display: none; }
}

/* ---------- FLOATING VIAL (shared) ----------
   Reusable hover animation for transparent-background product PNGs. Applied
   to the methodology stage, shop hero, and PDP hero (when the product has a
   `cardImg` glow asset). Keep it centralised so all three stay in sync. */
@keyframes lpVialHover {
  0%, 100% { transform: translate(-50%, -50%)              rotate(-14deg); }
  50%      { transform: translate(-50%, calc(-50% - 14px)) rotate(-12deg); }
}
@media (prefers-reduced-motion: reduce) {
  .lp-vial-anim { animation: none !important; }
}

/* ---------- PRODUCT CARD ---------- */
.product-card {
  display: flex; flex-direction: column;
  background: var(--ink-2);
  border: 1px solid var(--rule);
  transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
  position: relative;
  overflow: hidden;
  /* Make the card a container so `cqi` units in its descendants
     (font-size, padding, gap) scale with the card's own inline-size
     instead of the viewport. One card definition then renders well in
     every grid context: 1-col phone, 2-col phone, 3-col tablet, 4-col
     desktop, and the wide spotlight tile on home. */
  container-type: inline-size;
}
.product-card:hover { border-color: var(--gold-400); }
/* Touch feedback. `:hover` is sticky on touch screens (state persists
   after tap until the user taps elsewhere), so :active is the honest
   "I'm pressing this right now" signal on phones. */
.product-card:active { border-color: var(--gold-200); transform: scale(0.995); }
.product-card:active .product-card__cta { color: var(--gold-100); }
.product-card__media {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--ink-3);
  isolation: isolate;
}
/* Champagne radial glow — same treatment as the filmstrip */
.product-card__media::before {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(
    ellipse 65% 55% at 50% 50%,
    color-mix(in oklch, var(--gold-300) 28%, transparent) 0%,
    color-mix(in oklch, var(--gold-400) 14%, transparent) 35%,
    transparent 70%
  );
  z-index: 0;
  opacity: 0.85;
  transition: opacity 600ms var(--ease);
  pointer-events: none;
}
.product-card:hover .product-card__media::before { opacity: 1; }
.product-card__media img {
  position: relative; z-index: 1;
  width: 100%; height: 100%; object-fit: contain;
  /* Padding around the vial inside the square media frame. Fluid so a
     tiny card on a 360px phone uses less of its surface for whitespace
     than a 320px desktop tile. */
  padding: clamp(10%, 4cqi, 18%);
  transition: transform 800ms var(--ease);
}
.product-card:hover .product-card__media img { transform: scale(1.04); }

/* Catalog hover-float — for cards whose product ships with a transparent
   `cardImg` glow asset (marker class `has-glow` applied at render time).
   The animation is gated by `.is-floating`, NOT `:hover`, so the shop's
   mouseleave handler can capture the live transform mid-loop and ease it
   back to rest instead of the browser snapping the image to identity the
   instant the hover state drops. Frame 0 of the keyframes matches the
   base `scale(1.04)` hover transform so the entry stays continuous. */
@keyframes lpVialCardHover {
  0%, 100% { transform: translateY(0)     rotate(-3deg) scale(1.04); }
  50%      { transform: translateY(-10px) rotate(2deg)  scale(1.04); }
}
.product-card.has-glow.is-floating .product-card__media img {
  animation: lpVialCardHover 4.5s ease-in-out infinite;
  filter: drop-shadow(0 18px 28px rgba(0,0,0,0.5));
}
@media (prefers-reduced-motion: reduce) {
  .product-card.has-glow.is-floating .product-card__media img { animation: none; }
}
.product-card__body {
  /* All paddings / gaps / typography fluid so the card visually shrinks
     in step with its column width. Without this, a one-column card on
     a 360px phone keeps its 24px desktop padding + 22px serif name and
     looks enormous relative to the viewport. */
  padding: clamp(12px, 4.5cqi, 24px);
  display: flex; flex-direction: column;
  gap: clamp(6px, 2.5cqi, 12px);
  border-top: 1px solid var(--rule);
}
.product-card__cat {
  font-size: clamp(10px, 2.4cqi, 11px);
  letter-spacing: 0.28em; text-transform: uppercase;
  color: var(--gold-300);
}
.product-card__name {
  font-family: var(--font-serif);
  /* Container-query font: scales with the card itself, so a 2-col phone
     card gets ~16px and a 4-col desktop card gets ~22px without media
     queries that have to know every layout context. */
  font-size: clamp(17px, 5.5cqi, 24px);
  line-height: 1.15;
  color: var(--beige-50);
}
.product-card__price-row { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.product-card__price {
  font-size: clamp(13px, 3.5cqi, 15px);
  color: var(--beige-100); letter-spacing: 0.04em;
}
.product-card__price .from { font-size: clamp(10px, 2.4cqi, 11px); color: var(--fg-dim); letter-spacing: 0.2em; text-transform: uppercase; margin-right: 6px; }
.product-card__cta {
  font-size: clamp(10px, 2.4cqi, 11px);
  letter-spacing: 0.28em; text-transform: uppercase; color: var(--gold-200);
  display: inline-flex; align-items: center; gap: 6px;
}
.product-card__cta::after {
  content: "→"; transition: transform var(--dur-fast) var(--ease);
}
.product-card:hover .product-card__cta::after { transform: translateX(4px); }

.product-card__badge {
  position: absolute; top: 16px; left: 16px;
  font-size: 10px; letter-spacing: 0.32em; text-transform: uppercase;
  color: var(--gold-100);
  padding: 6px 10px;
  border: 1px solid var(--gold-300);
  background: rgba(0,0,0,0.7);
}

/* Number index — used in editorial layouts */
.idx {
  font-family: var(--font-serif);
  font-style: italic;
  color: var(--gold-200);
  font-size: 15px;
  letter-spacing: 0.04em;
}

/* ---------- FORM CONTROLS (themed) ---------- */
.form-label {
  display: block;
  font-size: 11px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin-bottom: 10px;
  font-weight: 400;
}
.form-input {
  display: block;
  width: 100%;
  padding: 12px 0 14px;
  font: inherit;
  font-family: var(--font-sans);
  /* 16px floor so iOS Safari does not zoom the viewport on focus. The
     visual difference vs. the prior 15px is invisible at typical reading
     distance and the UX win on phones (no jarring zoom-then-zoom-back
     when tab-cycling through a 12-field shipping form) is significant. */
  font-size: max(17px, 1em);
  color: var(--beige-50);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule-strong);
  border-radius: 0;
  outline: none;
  transition: border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
  -webkit-appearance: none;
  appearance: none;
}
.form-input::placeholder {
  color: var(--fg-dim);
  font-style: italic;
}
.form-input:hover { border-bottom-color: var(--beige-300); }
.form-input:focus {
  border-bottom-color: var(--gold-200);
  color: var(--beige-50);
}
.form-input:focus::placeholder { color: var(--fg-muted); }
.form-input:-webkit-autofill,
.form-input:-webkit-autofill:hover,
.form-input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--beige-50);
  -webkit-box-shadow: 0 0 0 1000px var(--ink-2) inset;
  caret-color: var(--beige-50);
}

/* Larger fields: textarea + select adopt a softer outlined chamber */
textarea.form-input,
select.form-input {
  padding: 14px 16px;
  border: 1px solid var(--rule-strong);
  background: rgba(20, 16, 26, 0.4);
  min-height: 56px;
}
textarea.form-input:hover,
select.form-input:hover {
  border-color: var(--beige-300);
  border-bottom-color: var(--beige-300);
}
textarea.form-input:focus,
select.form-input:focus {
  border-color: var(--gold-200);
  border-bottom-color: var(--gold-200);
  background: rgba(20, 16, 26, 0.6);
}

/* Native select arrow → gold chevron */
select.form-input {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none' stroke='%23d4b266' stroke-width='1.4'><path d='M3 5l4 4 4-4'/></svg>");
  background-repeat: no-repeat;
  background-position: right 16px center;
  padding-right: 44px;
  cursor: pointer;
}
select.form-input option {
  background: var(--ink-1);
  color: var(--beige-50);
}

/* ---------- MINI CART POPUP ---------- */
/* Anchored top-right, just under the sticky header. Slides in on add-to-cart,
   auto-dismisses, pause on hover. Visual language matches .payment-card —
   dark surface, gold border, serif accents. */
.lp-mini-cart {
  position: fixed;
  top: 92px;                 /* clears 72px header + 20px gap */
  right: var(--gutter, 24px);
  width: min(380px, calc(100vw - 32px));
  /* Cap to the viewport so a growing cart can NEVER push Checkout off-screen:
     the panel is a flex column → lines scroll, totals + Checkout stay pinned. */
  max-height: calc(100dvh - 108px);
  z-index: 90;
  background: var(--ink-2);
  border: 1px solid var(--gold-400);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  pointer-events: none;
  opacity: 0;
  transform: translateY(-12px) translateX(8px);
  transition:
    opacity var(--dur, 320ms) var(--ease, ease),
    transform var(--dur, 320ms) var(--ease, ease);
  box-shadow: 0 24px 48px rgba(0,0,0,0.55), 0 2px 0 rgba(0,0,0,0.4);
}
.lp-mini-cart.is-open {
  opacity: 1;
  transform: translateY(0) translateX(0);
  pointer-events: auto;
}
@media (max-width: 900px) {
  /* 64px mobile header + 16px gap */
  .lp-mini-cart { top: 80px; right: 12px; max-height: calc(100dvh - 92px); }
}

.lp-mini-cart__head {
  display: flex; align-items: center; justify-content: space-between;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--rule);
  flex-shrink: 0;
}
.lp-mini-cart__eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: 11px; letter-spacing: 0.32em; text-transform: uppercase;
  color: var(--gold-200);
}
.lp-mini-cart__eyebrow .dot {
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--gold-200);
}
.lp-mini-cart__close {
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--beige-200);
  border: 1px solid transparent;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
  cursor: pointer;
  background: transparent;
}
.lp-mini-cart__close:hover { color: var(--gold-100); border-color: var(--rule); }

.lp-mini-cart__lines {
  display: flex; flex-direction: column; gap: 10px;
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
}
.lp-mini-cart__line {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: 14px;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid var(--rule);
}
.lp-mini-cart__line:last-child { border-bottom: 0; }
.lp-mini-cart__thumb {
  width: 56px; height: 56px;
  /* No background, no border — the thumb blends into the mini-cart
     panel and the only visible element is the vial (or white-bg
     studio shot) itself. Removes the "framed thumbnail" look the
     dark ink-1 + rule border gave each row. */
  background: transparent;
  border: 0;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  position: relative;
  isolation: isolate;
  flex-shrink: 0;
}
.lp-mini-cart__thumb img {
  max-width: 80%; max-height: 80%; object-fit: contain;
  display: block;
  position: relative;
  z-index: 1;
}
/* Transparent floating-vial variant — same champagne halo treatment as
   the home filmstrip / catalog-float cells. Slightly larger image scale
   since there's no white-bg bezel to fit around. The halo is static
   (no animation) — mini-cart isn't a hover surface, paint cost matters
   more than motion here. */
.lp-mini-cart__thumb--vial::before {
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  width: 80%; aspect-ratio: 1;
  transform: translate(-50%, -52%);
  background: radial-gradient(
    circle at 50% 50%,
    rgba(212, 175, 96, 0.42) 0%,
    rgba(212, 175, 96, 0.22) 30%,
    rgba(212, 175, 96, 0.08) 55%,
    rgba(212, 175, 96, 0)    74%
  );
  filter: blur(4px);
  pointer-events: none;
  z-index: 0;
}
.lp-mini-cart__thumb--vial img {
  max-width: 96%; max-height: 96%;
}
.lp-mini-cart__meta { min-width: 0; }
.lp-mini-cart__name {
  font-family: var(--font-serif);
  font-size: 17px;
  color: var(--beige-50);
  line-height: 1.2;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.lp-mini-cart__sub {
  margin-top: 4px;
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--fg-muted);
}
.lp-mini-cart__price {
  font-family: var(--font-mono, var(--font-sans));
  font-size: 14px;
  color: var(--gold-100);
}

.lp-mini-cart__totals {
  display: flex; justify-content: space-between; align-items: baseline;
  padding-top: 12px;
  border-top: 1px solid var(--rule);
  flex-shrink: 0;
  font-size: 12px; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--beige-200);
}
.lp-mini-cart__subtotal {
  font-family: var(--font-serif);
  font-style: normal;
  font-size: 24px;
  letter-spacing: 0;
  color: var(--gold-100);
  text-transform: none;
}

.lp-mini-cart__actions {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
  flex-shrink: 0;
}
.lp-mini-cart__actions .btn {
  width: 100%;
  text-align: center;
  justify-content: center;
}

/* ---------- "What this site is / isn't" — plain statement ---------- */
/* Cream surface against the dark site, deliberately the only beige-surface
   block so it lands as a printed insert. Used on about and home pages.
   Vertical rhythm trimmed twice now so the whole section fits inside a
   typical 720px-tall desktop window after the 84px header — every
   margin / padding / clamp below is part of that vertical budget. */
.about-truth {
  background: var(--beige-surface);
  color: var(--beige-surface-text);
  padding: var(--s-5) var(--gutter);
}
.about-truth__inner {
  max-width: 1080px;
  margin: 0 auto;
}
.about-truth__eyebrow {
  display: flex; align-items: center; justify-content: center;
  gap: 16px;
  font-size: 12px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--beige-surface-text);
  opacity: 0.65;
  margin-bottom: 14px;
}
.about-truth__eyebrow .line {
  width: 40px; height: 1px;
  background: var(--beige-surface-text);
  opacity: 0.4;
}
.about-truth__title {
  font-family: var(--font-serif);
  font-size: clamp(35px, 4.2vw, 65px);
  line-height: 1.05;
  letter-spacing: -0.015em;
  text-align: center;
  color: var(--beige-surface-text);
  text-wrap: pretty;
  margin: 0 0 22px;
}
.about-truth__title em {
  font-style: italic;
  /* Slightly desaturated gold so it reads warm rather than neon on cream. */
  color: #6b4f1a;
}
.about-truth__cols {
  display: grid;
  grid-template-columns: 1fr 1px 1fr;
  gap: 28px;
  align-items: stretch;
  margin-bottom: 22px;
}
.about-truth__divider {
  background: var(--beige-surface-text);
  opacity: 0.18;
  width: 1px;
}
.about-truth__col {
  display: flex; flex-direction: column; gap: 14px;
}
/* Column headings — large, declarative, the visual anchor of each side.
   Cap shrunk so the headline doesn't dominate the section's vertical
   budget on shorter laptop screens. */
.about-truth__col-label {
  display: flex; align-items: baseline; gap: 16px;
  padding-bottom: 12px;
  border-bottom: 2px solid #6b4f1a;
  line-height: 1;
}
.about-truth__col-label .it {
  font-family: var(--font-sans);
  font-size: clamp(14px, 1.4vw, 16px);
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: #6b4f1a;
  font-weight: 500;
}
.about-truth__col-label em {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(41px, 4.4vw, 65px);
  letter-spacing: -0.02em;
  text-transform: none;
  color: #6b4f1a;
  line-height: 0.9;
}
/* "isn't" gets a deeper, more saturated tone so it lands harder than "is". */
.about-truth__col--isnt .about-truth__col-label,
.about-truth__col--isnt .about-truth__col-label em,
.about-truth__col--isnt .about-truth__col-label .it {
  color: #4a2a0a;
}
.about-truth__col--isnt .about-truth__col-label {
  border-bottom-color: #4a2a0a;
}
.about-truth__col p {
  font-family: var(--font-serif);
  font-size: clamp(17px, 1.6vw, 22px);
  line-height: 1.45;
  color: var(--beige-surface-text);
  margin: 0;
  text-wrap: pretty;
}
.about-truth__col p strong {
  font-weight: 500;
  color: #3a2a0e;
}
/* Per-word emphasis (research / reference / take / never) — bold AND
   italic, regardless of whether the em sits inside a strong or alone. We
   override font-weight inside the strong block (which is otherwise 500
   medium) so the emphasized word reads heavier than the rest of the
   sentence; the bare em outside any strong gets the same treatment for
   visual parity with its siblings. */
.about-truth__col p em {
  font-weight: 700;
  font-style: italic;
  color: #3a2a0e;
}
.about-truth__close {
  text-align: center;
  padding-top: 18px;
  border-top: 1px solid rgba(26, 20, 16, 0.18);
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(19px, 2.2vw, 28px);
  line-height: 1.35;
  color: var(--beige-surface-text);
  margin: 0;
}
.about-truth__close-sub {
  display: block;
  margin-top: 8px;
  font-style: normal;
  font-family: var(--font-sans);
  font-size: 12px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: #6b4f1a;
  opacity: 0.85;
}
@media (max-width: 800px) {
  .about-truth__cols {
    grid-template-columns: 1fr;
    gap: 32px;
  }
  .about-truth__divider { display: none; }
}

/* ============================================================
   SHOP NAV DROPDOWN  (appended — scoped to .lp-nav / drawer)
   The Shop primary-nav item carries a submenu of catalog views
   (All / Popular / Blends / Bundle & Save) that target the
   shop `?cat=` filter contract. Built in lp-chrome.js buildHeader.
   ============================================================ */

/* Wrapper sits as a flex child of .lp-nav alongside the plain <a>
   items. position:relative anchors the absolutely-positioned panel. */
.lp-nav__item--has-menu {
  position: relative;
  display: inline-flex;
  align-items: center;
}
/* The parent <a> inherits the standard .lp-nav a styles (color,
   letter-spacing, the animated ::after underline) — nothing to
   re-declare here. A small caret hints the submenu. */
.lp-nav__item--has-menu > a::before {
  content: "";
  position: absolute;
  right: -13px;
  top: 50%;
  width: 5px;
  height: 5px;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  transform: translateY(-65%) rotate(45deg);
  opacity: 0.7;
  transition: transform var(--dur-fast) var(--ease), opacity var(--dur-fast) var(--ease);
  pointer-events: none;
}
.lp-nav__item--has-menu:hover > a::before,
.lp-nav__item--has-menu:focus-within > a::before {
  opacity: 1;
  transform: translateY(-35%) rotate(225deg);
}

/* The dropdown panel. Hidden by default; revealed on hover OR
   keyboard focus anywhere inside the item (focus-within), so it is
   reachable by Tab without a pointer. A small invisible bridge
   (padding-top via translateY gap) keeps it from closing when the
   pointer travels from the trigger down into the panel. */
.lp-nav__menu {
  position: absolute;
  top: 100%;
  left: -18px;
  margin-top: 10px;
  min-width: 200px;
  display: flex;
  flex-direction: column;
  background: rgba(10, 8, 14, 0.97);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  backdrop-filter: blur(16px) saturate(140%);
  border: 1px solid var(--rule);
  border-top: 2px solid var(--gold-400);
  box-shadow: 0 18px 40px -18px rgba(0, 0, 0, 0.8);
  padding: 6px 0;
  z-index: 60;
  /* hidden state */
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease),
              visibility 0s linear var(--dur-fast);
}
/* A hover-bridge so the gap between trigger and panel doesn't drop
   the hover. Covers the 10px margin gap. */
.lp-nav__menu::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -12px;
  height: 12px;
}
.lp-nav__item--has-menu:hover .lp-nav__menu,
.lp-nav__item--has-menu:focus-within .lp-nav__menu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition: opacity var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease);
}
.lp-nav__menu a {
  display: block;
  padding: 11px 22px;
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--beige-100);
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
/* Override the inherited animated underline from .lp-nav a::after —
   inside the panel we use a background-fill hover instead. */
.lp-nav__menu a::after { display: none; }
.lp-nav__menu a:hover,
.lp-nav__menu a:focus-visible {
  color: var(--gold-100);
  background: rgba(212, 178, 102, 0.08);
  outline: none;
}

@media (prefers-reduced-motion: reduce) {
  .lp-nav__menu { transition: none; }
  .lp-nav__item--has-menu > a::before { transition: none; }
}

/* ----- 900px tier: keep the caret from colliding with the next item.
   At this width .lp-nav gap drops to 20px (see header rules above); the
   caret lives in that gutter, so nudge it in slightly. ----- */
@media (max-width: 900px) {
  .lp-nav__item--has-menu > a::before { right: -11px; }
}

/* ----- Mobile drawer Shop submenu (<=720px, hamburger tier) -----
   The desktop dropdown can't be hovered on touch, so the drawer lists
   the same catalog views as an indented sub-group beneath Shop. */
/* Shop accordion toggle — same big serif row as the drawer links, with a chevron
   pushed to the right that rotates 180° when the Shop sub-menu is expanded. */
.lp-mobile-drawer__acc {
  font-family: var(--font-serif);
  font-size: clamp(30px, 7vw, 43px);
  color: var(--beige-50);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule);
  padding: clamp(14px, 3vw, 20px) 0;
  min-height: 44px;
  width: 100%;
  display: flex; align-items: center; justify-content: space-between;
  cursor: pointer;
  text-align: left;
}
.lp-mobile-drawer__acc:hover { color: var(--gold-100); }
.lp-mobile-drawer__chev {
  color: var(--gold-200);
  flex-shrink: 0;
  transition: transform var(--dur) var(--ease);
}
.lp-mobile-drawer__acc[aria-expanded="true"] .lp-mobile-drawer__chev { transform: rotate(180deg); }
/* Shop sub-menu — COLLAPSED (display:none) by default; tapping Shop toggles
   `.is-open` to display:flex. A plain display toggle, NOT an animated max-height:
   the max-height version computed to 0 on some engines and left the options
   invisible even when present in the DOM. Reliability over animation. */
.lp-mobile-drawer__sub {
  display: none;
  flex-direction: column;
  padding-left: 18px;
  border-left: 1px solid var(--rule);
  margin: 4px 0 8px;
}
.lp-mobile-drawer__sub.is-open {
  display: flex;
}
.lp-mobile-drawer__sub a {
  font-family: var(--font-sans);
  font-size: 13px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--beige-200);
  border-bottom: 0;
  padding: 12px 0;
  min-height: 44px;
}
.lp-mobile-drawer__sub a:hover { color: var(--gold-100); }
.lp-mobile-drawer__sub a:active { color: var(--gold-200); }

/* ============================================================
   SHOP DENSITY SELECTOR — hide on mobile.
   At the mobile breakpoint the grid is capped to 2 columns
   (see shop.css), so the 2/3/4/5 density control is a no-op.
   Hidden purely in CSS so shop.html markup is untouched.
   720px matches the header's tablet/mobile tier (hamburger).
   ============================================================ */
@media (max-width: 720px) {
  .shop-density { display: none !important; }
}
