/** Shopify CDN: Minification failed

Line 332:0 Expected "}" to go with "{"

**/
/* Header.

   The nav has NO band of its own. It floats over whatever the hero is showing —
   field today, image or video once one exists — which is why .hdr is
   transparent and the hero is pulled up underneath it.

   The ground on ::before only exists for AFTER you scroll past the hero, where
   the nav would otherwise sit unreadably over white content. It is driven by
   the document scroll natively, no JS, and it fails safe: the declared state is
   opaque, and the animation that makes it transparent at the top is gated
   behind @supports, so a browser without scroll-timelines simply gets a solid
   header rather than an invisible one.
*/

/* THE STICKY ELEMENT IS THE WRAPPER, NOT .hdr.
   Shopify wraps every section in <div class="shopify-section"> that is only as
   tall as the section itself, and `position: sticky` can only travel inside its
   PARENT's box. Sticky on .hdr therefore had 84px of room and scrolled away
   with the page — measured at top: -1562px after a 1600px scroll. Matching the
   wrapper by id suffix survives the section-group id being regenerated. */
[id$='__header'].shopify-section-group-header-group {
  position: sticky;
  top: 0;
  z-index: 40;
  transition: transform var(--dur-mid) var(--ease);
}

/* ── TUCK ON THE WAY DOWN, RETURN ON THE WAY UP ────────────────────────────
   A phone screen is 90% of this brand's traffic and the bar was holding a
   fixed slice of it for the whole scroll. Reading is downward, so on the way
   down the bar leaves; the moment the reader reverses — which is what wanting
   the nav looks like — it comes straight back, already in place, no scroll to
   the top required.

   The transform sits on the WRAPPER, the same element that carries the sticky,
   so the whole bar travels as one and nothing inside has to be re-laid out.
   The class is set by header-scroll.js, which holds it visible whenever the
   menu is open, the cart drawer is open, focus is inside it, or the page is
   still near the top. Without JS the class is never added and the header
   behaves exactly as it did before — the fail-safe direction. */
[id$='__header'].shopify-section-group-header-group.is-tucked {
  transform: translateY(-100%);
}

@media (prefers-reduced-motion: reduce) {
  [id$='__header'].shopify-section-group-header-group { transition: none; }
}

.hdr {
  position: relative;
  z-index: 40;
  background: transparent;
}

.hdr::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--pale-2);
  opacity: 1;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  
/* An open drawer always needs the ground, wherever the page is scrolled to.
   !important is deliberate: it is the one thing that outranks an animation. */
.hdr:has(.hdr__menu[open])::before { opacity: 1 !important; }

/* Transparent while the hero is behind it, solid once it is not. */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .hdr::before {
      animation: hdr-ground linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 140px;
    }
  }
}
@keyframes hdr-ground { from { opacity: 0; } to { opacity: 1; } }

/* ── The three-column row ──────────────────────────────────────────────────
   1fr / auto / 1fr keeps the logo optically centred whatever the nav or the
   icons measure. Column one holds the mobile toggle and the desktop links —
   only ever one of the two is visible. */

.hdr__inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--s2);
  min-height: var(--header-h);
}

.hdr__lead { display: flex; align-items: center; justify-self: start; }
.hdr__end  { display: flex; align-items: center; justify-self: end; }

.hdr__logo { display: flex; align-items: center; min-height: 44px; }
.hdr__logo-img { width: 122px; height: auto; }

/* ── Links ─────────────────────────────────────────────────────────────────
   Uppercase, widely tracked, teal. Mono stays reserved for measured values —
   a nav label is not an instrument reading. */

.hdr__row,
.hdr__stack {
  display: flex;
  margin: 0;
  padding: 0;
  list-style: none;
}
.hdr__row { gap: clamp(var(--s3), 2.6vw, var(--s4)); }

/* min-width holds the 44px floor for the short labels — "SHOP" measures 41px
   in Quicksand at this tracking. Centring keeps the hairline underline, which
   spans the box, optically balanced over the shorter word. */
.hdr__row a,
.hdr__stack a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  min-height: 44px;
  min-width: 44px;
  color: var(--teal);
  text-decoration: none;
  font: 600 0.8125rem/1 var(--font-body);
  text-transform: uppercase;
  letter-spacing: .12em;
}
.hdr__row a:hover { color: var(--green-ink); }

/* Hairline underline instead of a shadow or a border. */
.hdr__row a::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  bottom: 13px;
  height: 1px;
  background: var(--green-ink);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur) var(--ease);
}
.hdr__row a:hover::after,
.hdr__row a[aria-current='page']::after { transform: scaleX(1); }

.hdr__nav { display: none; }

/* ── Cart ─────────────────────────────────────────────────────────────────
   44px box, pulled out by half its own padding so the glyph — not its
   bounding box — lines up with the gutter. */

.hdr__cart {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-inline-end: -12px;
  color: var(--teal);
}
.hdr__cart:hover { color: var(--green-ink); }

.hdr__count {
  position: absolute;
  top: 3px;
  right: 3px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  display: grid;
  place-items: center;
  background: var(--teal);
  color: var(--white);
  border-radius: 999px;
  font-size: 11px;
  line-height: 1;
  letter-spacing: 0;
}
.hdr__count[hidden] { display: none; }

/* ── Mobile menu. <details>, so it costs zero JavaScript. ────────────────── */

.hdr__menu { flex: 0 0 auto; }
.hdr__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-inline-start: -12px;
  color: var(--teal);
  list-style: none;
}
.hdr__toggle::-webkit-details-marker { display: none; }

.hdr__drawer {
  position: absolute;
  inset-inline: 0;
  top: 100%;
  background: var(--pale-2);
  border-bottom: 1px solid var(--green-line);
  padding: var(--s1) var(--gutter) var(--s2);
}
.hdr__stack { flex-direction: column; }
.hdr__stack a {
  width: 100%;
  min-height: 52px;
  border-bottom: 1px solid var(--green-line);
}
.hdr__stack li:last-child a { border-bottom: 0; }

/* ── Desktop ──────────────────────────────────────────────────────────────
   The row grows to the reference's rhythm and the toggle steps aside. */

@media (min-width: 900px) {
  .hdr__menu { display: none; }
  .hdr__nav { display: block; }
  .hdr__inner { min-height: var(--header-h-lg); }
  .hdr__logo-img { width: 148px; }

  /* THE LOGO MOVES OUT OF THE CENTRE ON DESKTOP.
     The hero is a centred product that fills the frame — the bottle's top edge
     sits at 12.7% of the image and the crop pulls it up as the window gets
     shorter. Measured against the real asset, a centred 148px logo clears the
     bottle by at most 12px on any desktop size and OVERLAPS it by 29px at
     1512x750. No object-position value fixes that: even anchoring the crop to
     the image top still fails at 1100x700 and cuts 75px off the pack, taking
     the "NET VOL. 50 ml" line with it.

     So the geometry is conceded rather than fought — logo left, nav and cart
     right, centre left empty for the product. Clearance becomes permanent at
     every viewport and the photograph is untouched. Mobile keeps the centred
     logo: there the bottle sits ~9px lower than the (shorter) logo and the
     burger/logo/cart arrangement is the right pattern anyway.

     grid-row is explicit on all three: with only grid-column set, the
     auto-placement cursor has already passed column 2 by the time the logo
     asks for column 1, and it would be pushed onto a second row. */
  .hdr__logo { grid-column: 1; grid-row: 1; justify-self: start; }
  .hdr__lead { grid-column: 2; grid-row: 1; justify-self: end; }
  .hdr__end  { grid-column: 3; grid-row: 1; justify-self: end; }
  .hdr__inner { grid-template-columns: auto 1fr auto; }
  .hdr__nav { margin-inline-end: var(--s2); }
}

/* ══════════════════════════════════════════════════════════════════════════
   NAV INK OVER THE HERO — A WHITE VEIL, NOT A DARK SCRIM (10 Aug 2026)

   The header floats on the homepage photograph. Until today that meant WHITE
   links over a black scrim, re-derived three times because every new frame
   moved the numbers. On the 10 Aug frame it failed outright: measured on the
   render, 3.50:1 under the logo and 4.20:1 under ABOUT.

   Why it failed is the useful part. This frame is bright cream linen across
   its left half, black hair across the middle right, and pale wall behind the
   right-most link. WHITE ink cannot survive the cream; TEAL ink cannot survive
   the hair. A dark scrim strong enough to rescue white needs ~.50 alpha, and
   .50 of black over cream is a grey band across the brightest, airiest part of
   the picture.

   So the ink stays TEAL — the colour it already is everywhere else — and the
   scrim inverts. A white veil is invisible where the frame is already near
   white, and it only does work where the frame is dark, which is exactly where
   teal needs help. The picture keeps its character; the failure that remains
   is the one the veil is sized for.

   THE NUMBER, solved rather than tried:
     teal #31474D has relative luminance .0533, so AA 4.5:1 needs the ground at
     or above (4.5 x .1033) - .05 = .415 linear = 172 in sRGB. Over the darkest
     hair (~L20) a white overlay gives 20 + 235a, so a >= .647 at the height of
     the glyph band. The ramp below carries ~.72 there, which lands the worst
     hair pixel near 5.4:1 with room for a frame whose hair sits higher.

   It rides the same scroll timeline as the ground below it: veil while the
   photograph is behind the bar, gone by the time the solid pale ground has
   faded in. The veil lives ONLY inside the animation, never as a base rule —
   where animation-timeline is unsupported the ground is permanently solid, and
   a base veil would then sit on a pale bar forever.

   Two scopes, both load-bearing:
   · :has(.hero--has-content) — an inner page opens the header over white and
     has no photograph to veil.
   · min-width 900px — the header does not float on phones (see .hero in
     section-hero.css), so it is already on the pale ground there.
   ══════════════════════════════════════════════════════════════════════════ */

@media (min-width: 900px) {
  body:has(.hero--has-content) .hdr::after {
    content: '';
    position: absolute;
    inset: 0 0 auto;
    height: 215%;
    z-index: -1;
    opacity: 0;
    background: linear-gradient(to bottom,
      rgba(255, 255, 255, .90) 0%,
      rgba(255, 255, 255, .76) 46%,
      rgba(255, 255, 255, 0) 100%);
    pointer-events: none;
  }

  @supports (animation-timeline: scroll()) {
    @media (prefers-reduced-motion: no-preference) {
      body:has(.hero--has-content) .hdr::after {
        animation: hdr-veil linear both;
        animation-timeline: scroll(root block);
        animation-range: 0 140px;
      }
    }
  }
}

@keyframes hdr-veil { from { opacity: 1; } to { opacity: 0; } }

/* ── The two-lockup cross-fade — RETIRED with the scrim ────────────────────
   The white lockup existed to sit on the scrimmed photograph. With the header
   on its own pale ground there is nothing to cross-fade from, and a white logo
   is now only ever an invisible one. The markup keeps both lockups (the light
   one is still the right asset for any future dark bar), so this is a styling
   retirement, not a template change. */
.hdr__logo { position: relative; display: inline-flex; }
.hdr__logo-img--light { position: absolute; inset: 0; opacity: 0; }
