/* ==========================================================================
   Boombangh — layout, components, animation states
   Depends on tokens.css.

   Animation contract (mirrors the reference so the markup reads the same):
     .animated                     element observed by Reveal
     .animated.active              added when it crosses the 50% line
     .animated--reverse            re-hides on scroll-up, so it replays
     .fade-in / .fade-up-in /
     .fade-left-in / .fade-right-in    which way it travels
     .animated-item-delay          nth-child stagger inside a group
     .js-parallax[data-parallax=N] wrapper; child is .js-parallax-child
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Reset & base
   -------------------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Backstop against sideways scroll. Decorative layers all over this site
     bleed past their section on purpose; any one of them escaping its
     clipping ancestor would otherwise let the whole page pan. `clip` rather
     than `hidden` so the root does not become a scroll container. */
  overflow-x: clip;
}
/* An animated jump is motion too — anchors land instantly for anyone who
   asked for less of it. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}
/* Lenis drives the scroll; native smooth would fight it. */
html.lenis, html.lenis body { height: auto; }
html.lenis { scroll-behavior: auto; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--bone);
  font-family: var(--font-sans);
  font-size: var(--t-body);
  font-weight: 350;
  line-height: var(--leading-body);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img, svg, video { display: block; max-width: 100%; }
img { height: auto; }

a { color: inherit; text-decoration: none; }

button {
  font: inherit; color: inherit;
  background: none; border: 0; padding: 0;
  cursor: pointer;
}

h1, h2, h3, h4, p, figure, blockquote { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }

::selection { background: var(--gold); color: var(--ink); }

:focus-visible {
  outline: 2px solid var(--gold-lt);
  outline-offset: 3px;
  border-radius: 2px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* Skip link — visible only when focused. */
.skip-link {
  position: fixed; top: 0; left: 50%;
  transform: translate(-50%, -110%);
  z-index: calc(var(--z-gate) + 10);
  padding: .75rem 1.5rem;
  background: var(--gold-lt); color: var(--ink);
  font-size: var(--t-eyebrow); letter-spacing: var(--track-ui);
  text-transform: uppercase;
  transition: transform var(--dur-ui) var(--ease-out);
}
.skip-link:focus { transform: translate(-50%, 0); }

/* --------------------------------------------------------------------------
   2. Typography
   -------------------------------------------------------------------------- */

.d-hero, .d1, .d2, .d3 {
  font-family: var(--font-display);
  font-weight: 300;
  line-height: var(--leading-display);
  letter-spacing: -.015em;
  text-wrap: balance;
}
/* opsz tracks the rendered size: the bigger the type, the thinner and more
   dramatic the cut. This is the whole reason for choosing a variable serif. */
.d-hero { font-size: var(--t-hero); font-variation-settings: 'opsz' 144, 'SOFT' 0, 'WONK' 0; }
.d1     { font-size: var(--t-d1);   font-variation-settings: 'opsz' 120, 'SOFT' 0, 'WONK' 0; }
.d2     { font-size: var(--t-d2);   font-variation-settings: 'opsz' 84,  'SOFT' 0, 'WONK' 0; }
.d3     { font-size: var(--t-d3);   font-variation-settings: 'opsz' 48,  'SOFT' 0, 'WONK' 0; }

/* Italic emphasis inside a display line — the reference's signature move. */
.d1 em, .d2 em, .d3 em, .d-hero em {
  font-style: italic;
  font-weight: 300;
  color: var(--gold-lt);
}

.eyebrow {
  font-size: var(--t-eyebrow);
  font-weight: var(--ui-weight);
  font-stretch: var(--ui-width);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--ash);
  line-height: 1.4;
}
.eyebrow--metal {
  background: var(--metal);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
}

.lead {
  font-size: var(--t-lead);
  line-height: 1.6;
  color: color-mix(in srgb, var(--bone) 88%, transparent);
}
.prose p + p { margin-top: 1.1em; }
.prose { color: color-mix(in srgb, var(--bone) 80%, transparent); max-width: 44ch; }

.rule {
  height: 1px; border: 0; width: 100%;
  background: var(--metal); opacity: .5;
}

/* --------------------------------------------------------------------------
   3. Layout
   -------------------------------------------------------------------------- */

.container { width: 100%; margin-inline: auto; padding-inline: var(--gutter); }
.container--xs { max-width: var(--w-xs); }
.container--sm { max-width: var(--w-sm); }
.container--md { max-width: var(--w-md); }
.container--lg { max-width: var(--w-lg); }
.container--xl { max-width: var(--w-xl); }

.section { position: relative; padding-block: var(--section-y); }
.section--flush { padding-block: 0; }
.section--full { min-height: 100svh; display: flex; align-items: center; }
.section--void { background: var(--ink-void); }
.section--raised { background: var(--ink-2); }

.split {
  display: grid;
  gap: clamp(2.5rem, 1rem + 6vw, 7rem);
  align-items: center;
}
@media (min-width: 900px) {
  .split { grid-template-columns: 1fr 1fr; }
  .split--wide-left  { grid-template-columns: 1.15fr .85fr; }
  .split--wide-right { grid-template-columns: .85fr 1.15fr; }
  /* Put the text first in the DOM (for reading order) but second visually. */
  .split__media--last { order: 2; }
}

.stack > * + * { margin-top: var(--stack); }
.stack-sm > * + * { margin-top: .85rem; }

/* --------------------------------------------------------------------------
   4. Buttons & links
   -------------------------------------------------------------------------- */

/* The reference's primary CTA: label between two metal rules, arrow slides. */
.btn {
  font-weight: var(--ui-weight);
  font-stretch: var(--ui-width);
  display: inline-flex; align-items: center; gap: 1.25rem;
  padding-block: 1.05rem;
  font-size: var(--t-eyebrow);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--bone);
  border-top: 1px solid transparent;
  border-bottom: 1px solid transparent;
  border-image: var(--metal) 1;
  transition: color var(--dur-ui) var(--ease-out);
}
.btn__arrow {
  position: relative;
  display: block; width: 2.75rem; height: 1px;
  background: var(--gold-lt);
  transition: width var(--dur-ui) var(--ease-out);
}
.btn__arrow::after {
  content: ''; position: absolute; right: 0; top: 50%;
  width: .5rem; height: .5rem;
  border-top: 1px solid var(--gold-lt);
  border-right: 1px solid var(--gold-lt);
  transform: translateY(-50%) rotate(45deg);
}
.btn:hover { color: var(--gold-lt); }
.btn:hover .btn__arrow { width: 4rem; }

/* Secondary: underline that wipes in from the left. */
.link-u {
  font-weight: var(--ui-weight);
  font-stretch: var(--ui-width);
  position: relative;
  font-size: var(--t-eyebrow);
  letter-spacing: var(--track-ui);
  text-transform: uppercase;
}
.link-u::after {
  content: ''; position: absolute; left: 0; bottom: -.35em;
  width: 100%; height: 1px;
  background: var(--gold-lt);
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--dur-ui) var(--ease-out);
}
.link-u:hover::after, .link-u:focus-visible::after { transform: scaleX(1); }

/* --------------------------------------------------------------------------
   5. The metal frame
   Two inset rectangles drawn with a gradient border-image, offset from each
   other by 10px on alternating axes. Reproduces the reference's hero frame.
   -------------------------------------------------------------------------- */

.frame {
  position: absolute; inset: 0;
  pointer-events: none;
  z-index: 2;
  /* Fades out towards the bottom so the frame dissolves with the rest of the
     hero, rather than ending on a hard line inside a soft transition. */
  -webkit-mask-image: linear-gradient(to bottom, #000 55%, transparent 94%);
          mask-image: linear-gradient(to bottom, #000 55%, transparent 94%);
}
.frame::before, .frame::after {
  content: '';
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  border: 1px solid var(--gold-dk);
  border-image: var(--metal) 1;
  border-image-slice: 1;
}
.frame::before { width: calc(100% - 40px); height: calc(100% - 30px); }
.frame::after  { width: calc(100% - 30px); height: calc(100% - 40px); }
@media (min-width: 768px) {
  .frame::before { width: calc(100% - 52px); height: calc(100% - 38px); }
  .frame::after  { width: calc(100% - 38px); height: calc(100% - 52px); }
}

/* --------------------------------------------------------------------------
   6. Media primitives
   -------------------------------------------------------------------------- */

.media { position: relative; overflow: hidden; }
.media > img { width: 100%; height: 100%; object-fit: cover; }
.media--tall  { aspect-ratio: 3 / 4; }
.media--square{ aspect-ratio: 1 / 1; }
.media--wide  { aspect-ratio: 4 / 3; }

.bleed {
  position: absolute; inset: 0;
  z-index: 0; overflow: hidden;
}
.bleed > img { width: 100%; height: 100%; object-fit: cover; }
.bleed::after { content: ''; position: absolute; inset: 0; background: var(--scrim-b); }
.bleed--right::after { background: var(--scrim-r); }
.bleed--left::after  { background: var(--scrim-l); }
.bleed--flat::after  { background: rgba(2,4,3,.55); }

/* Decorative botanicals that float over sections. Never interactive, never
   announced — they exist purely to give the parallax something to move. */
.leaf {
  position: absolute;
  pointer-events: none;
  user-select: none;
  z-index: 1;
  /* Shadow on the wrapper rather than the image, so it follows the cut-out
     alpha and leaves the image's own colour untouched. */
  filter: drop-shadow(0 20px 40px rgba(2,4,3,.6));
}

/* --------------------------------------------------------------------------
   7. Parallax
   The JS writes translate3d on .js-parallax-child. The wrapper clips nothing
   by default — layers are meant to overflow their section.
   -------------------------------------------------------------------------- */

/* No `position` here on purpose. Parallax wrappers are frequently also the
   positioned element (.leaf, .bleed, .hero__layer), and a base rule would win
   over their `position: absolute` by source order. The transform on the child
   needs no positioning context anyway. */
.js-parallax-child { will-change: transform; }

/* Parallax is desktop-only: on touch, the address-bar resize makes every
   scroll-linked transform stutter, and the reference's worst jank comes from
   running it anyway. Below 768px the layers just sit still. */
@media (max-width: 767px), (prefers-reduced-motion: reduce) {
  .js-parallax-child { transform: none !important; will-change: auto; }
}

/* --------------------------------------------------------------------------
   8. Reveal states
   -------------------------------------------------------------------------- */

.animated { }

.animated.fade-in,
.animated .fade-in {
  opacity: 0;
  transition: opacity var(--dur-reveal) var(--ease-cine);
}
.animated.fade-up-in,
.animated .fade-up-in {
  opacity: 0;
  transform: translate3d(0, 3.5rem, 0);
  transition: opacity var(--dur-reveal) var(--ease-cine),
              transform var(--dur-reveal) var(--ease-cine);
}
.animated.fade-left-in,
.animated .fade-left-in {
  opacity: 0;
  transform: translate3d(-4rem, 0, 0);
  transition: opacity var(--dur-reveal) var(--ease-cine),
              transform var(--dur-reveal) var(--ease-cine);
}
.animated.fade-right-in,
.animated .fade-right-in {
  opacity: 0;
  transform: translate3d(4rem, 0, 0);
  transition: opacity var(--dur-reveal) var(--ease-cine),
              transform var(--dur-reveal) var(--ease-cine);
}

.animated.active.fade-in,
.animated.active .fade-in,
.animated.active.fade-up-in,
.animated.active .fade-up-in,
.animated.active.fade-left-in,
.animated.active .fade-left-in,
.animated.active.fade-right-in,
.animated.active .fade-right-in {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

/* Stagger children of a revealed group. */
.animated-item-delay:nth-child(1) { transition-delay: calc(var(--stagger) * 1); }
.animated-item-delay:nth-child(2) { transition-delay: calc(var(--stagger) * 2); }
.animated-item-delay:nth-child(3) { transition-delay: calc(var(--stagger) * 3); }
.animated-item-delay:nth-child(4) { transition-delay: calc(var(--stagger) * 4); }
.animated-item-delay:nth-child(5) { transition-delay: calc(var(--stagger) * 5); }
.animated-item-delay:nth-child(6) { transition-delay: calc(var(--stagger) * 6); }
.animated-item-delay:nth-child(7) { transition-delay: calc(var(--stagger) * 7); }
.animated-item-delay:nth-child(8) { transition-delay: calc(var(--stagger) * 8); }

/* If JS never runs, nothing should stay invisible. */
.no-js .animated .fade-in,
.no-js .animated .fade-up-in,
.no-js .animated .fade-left-in,
.no-js .animated .fade-right-in,
.no-js .animated.fade-in,
.no-js .animated.fade-up-in,
.no-js .animated.fade-left-in,
.no-js .animated.fade-right-in {
  opacity: 1; transform: none;
}

/* --------------------------------------------------------------------------
   9. Wordmark
   -------------------------------------------------------------------------- */

/* Two self-contained variants live in assets/img/ — logo-metal.svg (gradient
   baked in) and logo-bone.svg. Both are used as <img>, so only the box needs
   sizing. Aspect ratio is 1000 x 203. Regenerate with
   `python3 scripts/make-wordmark.py`. */
.wordmark { display: block; width: 100%; height: auto; aspect-ratio: 1000 / 203; }
.brand-mark { display: block; width: 100%; height: auto; aspect-ratio: 1000 / 105.2; }

/* --------------------------------------------------------------------------
   10. Header
   -------------------------------------------------------------------------- */

.header {
  position: fixed; top: 0; left: 0; right: 0;
  z-index: var(--z-header);
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem;
  /* Top padding clears the hero's metal frame, which sits 19px in on desktop. */
  padding: clamp(1.5rem, 1rem + 1.4vw, 2.5rem) var(--gutter);
  will-change: transform;
  transition: transform calc(var(--dur-ui) * 1.15) var(--ease-io);
}
.header::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(to bottom, rgba(2,4,3,.75), rgba(2,4,3,0));
  opacity: 0;
  transition: opacity var(--dur-ui) var(--ease-out);
}
.header.is-scrolled::before { opacity: 1; }

.header__logo {
  width: clamp(7rem, 5rem + 5vw, 10.5rem);
  transition: opacity var(--dur-ui) var(--ease-out),
              visibility var(--dur-ui) var(--ease-out);
}
/* On the home page the wordmark lives in the hero, so the header one stays
   hidden until you have scrolled past it. */
.home .header__logo { opacity: 0; visibility: hidden; pointer-events: none; }
.home .header.header--showlogo .header__logo { opacity: 1; visibility: visible; pointer-events: auto; }
.nav-active .header__logo { opacity: 0 !important; visibility: hidden !important; }

.header__menu {
  font-weight: var(--ui-weight);
  font-stretch: var(--ui-width);
  display: inline-flex; align-items: center; gap: .85rem;
  font-size: var(--t-eyebrow);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--bone);
  position: relative;
}
.header__menu:hover { color: var(--gold-lt); }

/* The header sets a z-index, which makes it a stacking context — a z-index on
   the button inside it cannot lift the button above the overlay. The whole
   header has to move instead, or the toggle is unreachable once the nav is
   open and there is no way to close it. */
.nav-active .header { z-index: calc(var(--z-nav) + 1); }
/* Nothing behind the overlay should be clickable, but the toggle must stay so. */
.nav-active .header { pointer-events: none; }
.nav-active .header__menu { pointer-events: auto; }

.burger { position: relative; display: block; width: 26px; height: 12px; }
.burger span {
  position: absolute; left: 0; width: 100%; height: 1px;
  background: currentColor;
  transition: transform var(--dur-ui) var(--ease-io),
              opacity calc(var(--dur-ui) / 2) linear;
}
.burger span:nth-child(1) { top: 0; }
.burger span:nth-child(2) { top: 50%; }
.burger span:nth-child(3) { top: 100%; }
.header__menu[aria-expanded="true"] .burger span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.header__menu[aria-expanded="true"] .burger span:nth-child(2) { opacity: 0; }
.header__menu[aria-expanded="true"] .burger span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* --------------------------------------------------------------------------
   11. Nav overlay
   -------------------------------------------------------------------------- */

.nav {
  position: fixed; inset: 0;
  z-index: var(--z-nav);
  background: var(--ink-void);
  visibility: hidden; opacity: 0;
  transition: opacity var(--dur-ui) var(--ease-out),
              visibility var(--dur-ui) var(--ease-out);
}
.nav.is-open { visibility: visible; opacity: 1; }

.nav__media { position: absolute; inset: 0; overflow: hidden; }
.nav__media img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  opacity: 0;
  transform: scale(1.06);
  transition: opacity var(--dur-reveal) var(--ease-cine),
              transform calc(var(--dur-reveal) * 1.8) var(--ease-cine);
}
.nav__media img.is-active { opacity: .34; transform: scale(1); }
.nav__media::after {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(120% 90% at 50% 50%, rgba(2,4,3,.35) 0%, rgba(2,4,3,.9) 100%);
}

.nav__inner {
  position: relative; z-index: 1;
  height: 100%;
  display: flex; flex-direction: column; justify-content: center;
  padding: 6rem var(--gutter) 3rem;
  overflow-y: auto;
}
.nav__brand {
  position: absolute;
  top: clamp(1.75rem, 1rem + 1.5vw, 2.75rem);
  left: var(--gutter);
  width: clamp(10rem, 7rem + 9vw, 16rem);
  opacity: 0;
  transform: translate3d(0, -1rem, 0);
  transition: opacity var(--dur-reveal) var(--ease-cine),
              transform var(--dur-reveal) var(--ease-cine);
}
.nav.is-open .nav__brand { opacity: 1; transform: none; }
.nav__list { display: flex; flex-direction: column; gap: clamp(.25rem, .1rem + .7vw, 1rem); }

.nav__link {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(2.25rem, 1rem + 6vw, 5.5rem);
  font-variation-settings: 'opsz' 120, 'SOFT' 0, 'WONK' 0;
  line-height: 1.08;
  letter-spacing: -.02em;
  color: var(--bone);
  transition: color var(--dur-reveal) var(--ease-out);
}
.nav__link:hover, .nav__link.is-current { color: var(--gold-lt); }
.nav__link.is-current { font-style: italic; }

/* Items rise in one after another once the overlay opens. */
.nav__item {
  opacity: 0;
  transform: translate3d(0, 1.5rem, 0);
  transition: opacity var(--dur-reveal) var(--ease-cine),
              transform var(--dur-reveal) var(--ease-cine);
}
.nav.is-open .nav__item { opacity: 1; transform: none; }
.nav.is-open .nav__item:nth-child(1) { transition-delay: calc(var(--stagger-nav) * 1); }
.nav.is-open .nav__item:nth-child(2) { transition-delay: calc(var(--stagger-nav) * 2); }
.nav.is-open .nav__item:nth-child(3) { transition-delay: calc(var(--stagger-nav) * 3); }
.nav.is-open .nav__item:nth-child(4) { transition-delay: calc(var(--stagger-nav) * 4); }
.nav.is-open .nav__item:nth-child(5) { transition-delay: calc(var(--stagger-nav) * 5); }

.nav__foot {
  margin-top: clamp(2rem, 1rem + 4vw, 4.5rem);
  display: flex; flex-wrap: wrap; gap: 1.5rem 2.5rem; align-items: center;
  opacity: 0; transform: translate3d(0, 1rem, 0);
  transition: opacity var(--dur-reveal) var(--ease-cine) calc(var(--stagger-nav) * 6),
              transform var(--dur-reveal) var(--ease-cine) calc(var(--stagger-nav) * 6);
}
.nav.is-open .nav__foot { opacity: 1; transform: none; }

/* --------------------------------------------------------------------------
   12. Age gate
   Rendered visible in the HTML and removed by JS once cleared, so it fails
   closed when scripting is unavailable.
   -------------------------------------------------------------------------- */

.gate {
  position: fixed; inset: 0;
  z-index: var(--z-gate);
  display: grid; place-items: center;
  padding: var(--gutter);
  background: var(--ink-void);
  overflow-y: auto;
}
.gate[hidden] { display: none; }
/* Set by the head script when clearance is still live, before first paint.
   Without JS the class is never added and the wall stands. */
.gate-cleared .gate { display: none; }
.gate.is-closing { opacity: 0; transition: opacity var(--dur-reveal) var(--ease-cine); }

.gate__bg { position: absolute; inset: 0; overflow: hidden; }
.gate__bg img { width: 100%; height: 100%; object-fit: cover; opacity: .55; }
.gate__bg::after {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(100% 80% at 50% 45%, rgba(2,4,3,.35) 0%, rgba(2,4,3,.92) 100%);
}

.gate__inner {
  position: relative; z-index: 1;
  width: 100%; max-width: 34rem;
  text-align: center;
  padding-block: 3rem;
}
.gate__logo { width: clamp(11rem, 8rem + 14vw, 17rem); margin: 0 auto 3rem; }

.gate__choices {
  display: flex; justify-content: center; gap: 1rem;
  margin-top: 2.75rem;
}
.gate__choice {
  font-weight: var(--ui-weight);
  font-stretch: var(--ui-width);
  flex: 1 1 0; max-width: 11rem;
  padding-block: 1rem;
  font-size: var(--t-eyebrow);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--bone);
  border-top: 1px solid transparent; border-bottom: 1px solid transparent;
  border-image: var(--metal) 1;
  transition: color var(--dur-ui) var(--ease-out);
}
.gate__choice:hover, .gate__choice:focus-visible { color: var(--gold-lt); }
/* After "No" the wall stays up: the refusal reads as the answer, and Yes is
   still there for a mis-tap. */
.gate.is-denied [data-gate-no] { color: var(--ash); }

.gate__msg {
  margin-top: 1.5rem; min-height: 1.5em;
  font-size: var(--t-eyebrow);
  letter-spacing: var(--track-ui);
  text-transform: uppercase;
  color: var(--gold);
}
.gate__legal { margin-top: 3rem; font-size: var(--t-micro); color: var(--ash); line-height: 1.7; }

/* --------------------------------------------------------------------------
   13. Hero
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  min-height: 100svh;
  display: grid;
  align-items: center;
  justify-items: stretch;
  padding-block: 8rem 5rem;
  overflow: hidden;
  isolation: isolate;
}

/* Interior pages get a shorter hero — enough for the lockup and the leaves to
   frame it, without a full screen of nothing before the content starts. */
.hero--page {
  min-height: auto;
  padding-block: clamp(9rem, 6rem + 9vw, 16rem) clamp(3rem, 1rem + 6vw, 7rem);
}
.hero--page .hero__leaf--tl { top: -12%; left: -5%; }
.hero--page .hero__leaf--tr { top: -18%; right: -5%; }
.hero--page .hero__leaf img { max-height: clamp(13rem, 9rem + 26vw, 34rem); }

/* The lit ground: a warm key behind where the bottle stands, a cool fill in
   the opposite corner, over near-black. Painted rather than photographed so
   the bottle cut-out is the only bottle on screen. */
.hero__wash {
  position: absolute; inset: -6% -4%;
  z-index: 0;
  will-change: opacity;
  background:
    radial-gradient(circle at 72% 46%, rgba(230,174,55,.30), transparent 30%),
    radial-gradient(circle at 16% 74%, rgba(10,52,50,.85), transparent 40%),
    linear-gradient(125deg, #020403 2%, #08201D 48%, #23100A 100%);
}

/* Full-frame foliage planes.
   `cover`, never `fill`. The art is a 3:2 landscape cut-out; stretching it to
   an arbitrary viewport distorts every leaf, and on a portrait phone it is
   grotesque. Cropping costs a little framing at the sides — the mobile rule
   further down wins that back by treating the foliage as a bottom band. */
.hero__layer {
  position: absolute; inset: -6% -4%;
  pointer-events: none;
}
.hero__layer img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center 40%;
}
.hero__layer--back {
  z-index: 1;
  opacity: .72;
  filter: brightness(.68) blur(.5px);   /* pushed back, out of focus */
}
.hero__layer--front {
  z-index: 4;
  filter: drop-shadow(0 20px 30px rgba(2,4,3,.4));
}

/* Above the front foliage. The depth still reads because the bottle stays
   behind it — but legibility of the wordmark and copy is not negotiable. */
.hero__inner { position: relative; z-index: 5; width: 100%; }

/* The inline expression mark. Aspect is 1000 x 132.8 — regenerating the SVG
   at a different weight or tracking changes it, so keep the two in step. */
.title-inline {
  width: min(100%, 44rem);
  margin-inline: auto;
  aspect-ratio: 1000 / 133;
}
.home-hero-mark {
  width: 100%;
  margin-inline: 0;
  aspect-ratio: 1000 / 105.2;
}
.hero__copy { position: relative; width: min(46rem, 58%); }
.hero__copy::before {
  content: ''; position: absolute; z-index: -1;
  /* Oversize the scrim and fade it out well before its box ends. The blur
     removes the rectangular edge that otherwise shows over the hero wash. */
  inset: -65% -45% -70% -70%;
  background: radial-gradient(ellipse 68% 76% at 38% 50%,
    rgba(2,4,3,.82) 0%,
    rgba(2,4,3,.58) 30%,
    rgba(2,4,3,.28) 55%,
    rgba(2,4,3,.08) 72%,
    transparent 88%);
  filter: blur(24px);
}
.hero__logo { width: 100%; margin: 0; }

@media (max-width: 899px) {
  /* Phone: a clean vertical stack — wordmark up top, bottle centred and
     unobstructed below it, foliage framing only the bottom edge. Nothing
     overlaps the bottle, which is the thing worth looking at.

     The foliage becomes a bottom band at its natural aspect rather than a
     full-frame layer, so it frames without cropping to a sliver. */
  .hero { align-items: start; padding-block: 7.5rem 8rem; }

  .hero__copy { width: 100%; max-width: 17rem; }

  /* Centred with auto margins, not a transform — the intro timeline animates
     this element's transform, and the two would overwrite each other. */
  .hero__bottle {
    left: 0; right: 0;
    margin-inline: auto;
    width: max-content;
    bottom: 5vh;
    height: 50vh;
    opacity: 1;
  }

  .hero__layer { inset: auto -18% -2% -18%; height: 42%; }
  .hero__layer img { object-position: center bottom; }
  .hero__layer--back { height: 30%; opacity: .6; }
}
.hero__title { margin-inline: auto; }

/* The bottle sits behind the wordmark and above the background. */
.hero__bottle {
  /* Right of centre and bottom-anchored, the way the product shot is lit —
     the copy then owns the left half without anything overlapping it. */
  position: absolute; right: 15vw; bottom: 13vh;
  z-index: 2;
  height: min(78vh, 41rem);
}
.hero__bottle img { height: 100%; width: auto; filter: drop-shadow(0 34px 55px rgba(2,4,3,.55)); }

.hero__leaves { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.hero__leaf--tl { top: -4%;  left: -6%;  }
.hero__leaf--tr { top: -8%;  right: -6%; }
.hero__leaf--bl { bottom: -8%; left: -4%; }
.hero__leaf--br { bottom: -6%; right: -8%; }
.hero__leaf img { max-height: clamp(11rem, 8rem + 22vw, 30rem); width: auto; }

/* On a phone the botanicals and the bottle are competing with the type for a
   third of the width they have on desktop. Shrink them and let them sit back,
   so the headline stays the loudest thing on screen. */
@media (max-width: 767px) {
  .leaf { opacity: .5; }
  .hero__bottle { height: clamp(15rem, 11rem + 24vh, 26rem); }
  .hero--page .hero__leaf img { max-height: clamp(7rem, 5rem + 14vw, 11rem); }
  .hero--page { padding-block: 8rem 3rem; }
}

/* Scroll cue */
.scroll-cue {
  position: absolute; left: 50%; bottom: 2.25rem;
  transform: translateX(-50%);
  z-index: 4;
  display: flex; flex-direction: column; align-items: center; gap: .9rem;
  font-size: var(--t-micro);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--ash);
}
.scroll-cue__line { position: relative; width: 1px; height: 3.5rem; background: var(--ash-dim); overflow: hidden; }
.scroll-cue__line::after {
  content: ''; position: absolute; inset: 0;
  background: var(--gold-lt);
  animation: cue 2.4s var(--ease-io) infinite;
}
@keyframes cue {
  0%   { transform: translateY(-100%); }
  55%  { transform: translateY(0); }
  100% { transform: translateY(100%); }
}
@media (prefers-reduced-motion: reduce) {
  .scroll-cue__line::after { animation: none; opacity: .6; }
}

/* --------------------------------------------------------------------------
   13b. Soft edges & the video band

   A hard horizontal line between two sections is the quickest way to make a
   long scroll feel like a stack of slides. Anything that changes ground
   dissolves into what follows instead: a gradient the height of the
   transition, plus a negative margin so the next section starts underneath
   the tail of the previous one.
   -------------------------------------------------------------------------- */

.edge-fade {
  position: absolute; left: 0; right: 0;
  z-index: 5;
  pointer-events: none;
  height: clamp(6rem, 3rem + 14vh, 17rem);
}
/* `92%` rather than `100%`: the last few percent of a linear-gradient to a
   flat colour is where banding shows, so it lands on the colour early. */
.edge-fade--bottom { bottom: -1px; background: linear-gradient(to bottom, transparent 0%, var(--ink) 92%); }
.edge-fade--top    { top: -1px;    background: linear-gradient(to top,    transparent 0%, var(--ink) 92%); }
.edge-fade--void-bottom { bottom: -1px; background: linear-gradient(to bottom, transparent 0%, var(--ink-void) 92%); }
.edge-fade--void-top    { top: -1px;    background: linear-gradient(to top,    transparent 0%, var(--ink-void) 92%); }

/* Deliberately no negative-margin overlap. An overlapping section paints its
   own opaque ground over the tail of the fade above it, which puts the hard
   line straight back. Matching the fade's end colour to the next section's
   ground is what actually removes the seam.

   For two sections that simply differ in ground colour, the same idea in one
   class: paint the previous section's colour across the top of this one and
   fade it out. `isolation` keeps the z-index:-1 layer above this section's own
   background but below its content. Set --blend-from to whatever sits above. */
.section--blend { isolation: isolate; }
.section--blend::before {
  content: '';
  position: absolute; inset: 0 0 auto 0;
  z-index: -1;
  height: clamp(5rem, 3rem + 10vh, 13rem);
  background: linear-gradient(to bottom, var(--blend-from, var(--ink)) 0%, transparent 100%);
  pointer-events: none;
}

/* --- Video band ----------------------------------------------------------
   Full-bleed looping footage with the copy over it. The video is decorative:
   muted, no controls, and swapped for its own poster frame whenever motion is
   unwelcome or the file cannot play.
   ------------------------------------------------------------------------ */

.videoband {
  position: relative;
  display: grid;
  align-items: center;
  min-height: min(100svh, 54rem);
  padding-block: clamp(6rem, 4rem + 10vh, 12rem);
  overflow: hidden;
  background: var(--ink-void);
  isolation: isolate;
}

.videoband__media { position: absolute; inset: 0; z-index: 0; }
.videoband__media video,
.videoband__media img {
  width: 100%; height: 100%;
  object-fit: cover;
}
/* The poster is its own <img> underneath, not the video's poster attribute:
   the video starts transparent, so a poster attached to it would be invisible
   too. This way something is always on screen — on a slow connection, with
   autoplay refused, or under reduced motion where the video never loads. */
.videoband__poster { position: absolute; inset: 0; z-index: 0; }
.videoband__media video {
  position: absolute; inset: 0; z-index: 1;
  opacity: 0;
  transition: opacity var(--dur-hero) var(--ease-cine);
}
.videoband.is-playing .videoband__media video { opacity: 1; }

.videoband__scrim {
  position: absolute; inset: 0; z-index: 1;
  /* Weighted, not uniform. Heavy on the left where the copy sits, almost
     clear over the right third so the footage is actually visible — a flat
     scrim dark enough for text makes the video pointless. */
  background:
    linear-gradient(to right,
      rgba(2,4,3,.94) 0%, rgba(2,4,3,.7) 34%, rgba(2,4,3,.2) 66%, rgba(2,4,3,.42) 100%),
    linear-gradient(to bottom,
      rgba(2,4,3,.5) 0%, transparent 22%, transparent 78%, rgba(2,4,3,.5) 100%);
}

.videoband__inner { position: relative; z-index: 6; }


/* --------------------------------------------------------------------------
   13c. Hero intro — armed state

   An inline script in <head> puts `intro` on <html> before first paint, so
   these hidden states apply immediately and the timeline in main.js animates
   out of them. The default (unarmed) state below is the finished one, so a
   visitor with no JS — or one whose JS failed — sees a complete hero rather
   than an empty box. The same script removes the class after 3s as a
   failsafe if the timeline never runs.
   -------------------------------------------------------------------------- */

html.intro .hero__wash,
html.intro .hero__layer,
html.intro .hero__bottle,
html.intro .frame,
html.intro .scroll-cue,
html.intro .hero__copy > * { opacity: 0; }
html.intro .header { transform: translate3d(0, -100%, 0); }

/* Motion is unwelcome: nothing is hidden, so nothing needs revealing. */
@media (prefers-reduced-motion: reduce) {
  html.intro .hero__wash,
  html.intro .hero__layer,
  html.intro .hero__bottle,
  html.intro .frame,
  html.intro .scroll-cue,
  html.intro .hero__copy > * { opacity: 1; }
  html.intro .header { transform: none; }
}

/* --------------------------------------------------------------------------
   14. Product blocks (Our Rum)
   -------------------------------------------------------------------------- */

/* Four photographic chapters read as a vertical filmstrip without JavaScript.
   On a motion-capable desktop BottleStory layers them into one pinned scene:
   the environment changes while the product itself remains calm. */
.bottle-story {
  position: relative;
  overflow: hidden;
  background: var(--ink-void);
  isolation: isolate;
}

.bottle-story__mobile-film {
  position: relative;
  display: grid;
  min-height: 100svh;
  overflow: hidden;
  isolation: isolate;
  background: #020403;
}
.bottle-story__mobile-poster,
.bottle-story__mobile-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 52% center;
}
.bottle-story__mobile-poster { z-index: 0; }
.bottle-story__mobile-video {
  z-index: 1;
  opacity: 0;
  transition: opacity 800ms var(--ease-out);
}
.bottle-story__mobile-film.is-playing .bottle-story__mobile-video { opacity: 1; }
.bottle-story__mobile-shade {
  position: absolute;
  z-index: 2;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(180deg,
      #020403 0%,
      rgba(2,4,3,.62) 5%,
      rgba(2,4,3,.16) 17%,
      transparent 30%,
      transparent 67%,
      rgba(2,4,3,.22) 80%,
      #020403 100%),
    linear-gradient(90deg,
      rgba(2,4,3,.5) 0%,
      rgba(2,4,3,.12) 8%,
      transparent 18%,
      transparent 82%,
      rgba(2,4,3,.12) 92%,
      rgba(2,4,3,.5) 100%),
    radial-gradient(ellipse at center,
      transparent 52%,
      rgba(2,4,3,.08) 72%,
      rgba(2,4,3,.3) 100%);
}
.bottle-story__mobile-caption {
  position: absolute;
  z-index: 3;
  right: var(--gutter);
  bottom: clamp(2rem, 6svh, 4rem);
  left: var(--gutter);
  display: flex;
  gap: 1rem;
  align-items: flex-end;
  justify-content: space-between;
}
.bottle-story__mobile-caption .eyebrow {
  max-width: 10rem;
  color: rgba(255,255,255,.72);
}
.bottle-story__mobile-caption .btn { flex: 0 0 auto; }

.bottle-story__pin { position: relative; min-height: 100svh; }
.bottle-story__scenes {
  display: grid;
  gap: 1px;
  background: var(--ink);
}
.bottle-story__scene {
  position: relative;
  min-height: clamp(35rem, 88svh, 52rem);
  overflow: hidden;
  isolation: isolate;
  background: #020403;
}
.bottle-story__plate {
  position: absolute;
  inset: 0;
  z-index: -3;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
.bottle-story__scrim {
  position: absolute;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(1,3,2,.5), transparent 28%, transparent 65%, rgba(1,3,2,.76)),
    linear-gradient(to right, rgba(1,3,2,.74), transparent 68%);
}
.bottle-story__copy {
  position: absolute;
  z-index: 4;
  left: var(--gutter);
  right: var(--gutter);
  bottom: clamp(3rem, 7svh, 5rem);
  max-width: 30rem;
  text-shadow: 0 .18rem 1.5rem rgba(0,0,0,.72);
}
.bottle-story__copy > p:not(.eyebrow) {
  max-width: 34ch;
  color: color-mix(in srgb, var(--bone) 82%, transparent);
}
.bottle-story__scene--night .bottle-story__copy {
  top: clamp(6rem, 13svh, 9rem);
  bottom: auto;
  max-width: 23rem;
}
.bottle-story__scene--night .bottle-story__scrim {
  background:
    linear-gradient(to bottom, rgba(1,3,2,.42), transparent 44%, rgba(1,3,2,.7)),
    linear-gradient(to right, rgba(1,3,2,.7), transparent 80%);
}
.bottle-story__scene--highball .bottle-story__copy {
  left: auto;
  max-width: min(45vw, 18rem);
  text-align: right;
}
.bottle-story__scene--highball .bottle-story__copy > p { margin-left: auto; }
.bottle-story__scene--highball .bottle-story__scrim {
  background:
    linear-gradient(to bottom, rgba(1,3,2,.38), transparent 30%, rgba(1,3,2,.72)),
    linear-gradient(to left, rgba(1,3,2,.82), transparent 72%);
}
.bottle-story__scene--tableau .bottle-story__copy {
  top: clamp(5rem, 11svh, 8rem);
  bottom: auto;
  margin-inline: auto;
  text-align: center;
  max-width: 28rem;
}
.bottle-story__scene--tableau .bottle-story__copy > p,
.bottle-story__scene--tableau .bottle-story__copy .btn { margin-inline: auto; }
.bottle-story__number {
  display: block;
  font-size: var(--t-micro);
  font-weight: var(--ui-weight);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--gold);
}
.bottle-story__mobile-bottle {
  position: absolute;
  z-index: 2;
  left: 50%;
  bottom: -5%;
  height: min(57svh, 31rem);
  width: auto;
  transform: translateX(-50%);
  filter: drop-shadow(0 2.5rem 3rem rgba(0,0,0,.72));
}
.bottle-story__visual,
.bottle-story__foreground,
.bottle-story__progress { display: none; }

@media (max-width: 899px) {
  .bottle-story__pin { display: none; }
}

.bottle-story__bottle-wrap {
  position: relative;
  height: min(78svh, 44rem);
  aspect-ratio: 816 / 1926;
}
.bottle-story__bottle {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 3rem 4.5rem rgba(0,0,0,.72));
  transform-origin: 50% 58%;
}
.bottle-story__glint {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(100deg, transparent 35%, rgba(255,230,155,.78) 48%, transparent 61%);
  background-size: 38% 100%;
  background-repeat: no-repeat;
  background-position: -80% 50%;
  mix-blend-mode: screen;
  -webkit-mask: url('../img/brand/bottle-cutout.png') center / contain no-repeat;
          mask: url('../img/brand/bottle-cutout.png') center / contain no-repeat;
}

@media (min-width: 900px) {
  .bottle-story__mobile-film { display: none; }

  .bottle-story.is-enhanced .bottle-story__pin {
    display: block;
    height: 100svh;
    min-height: 46rem;
    overflow: hidden;
  }
  .bottle-story.is-enhanced .bottle-story__scenes,
  .bottle-story.is-enhanced .bottle-story__scene {
    position: absolute;
    inset: 0;
    min-height: 0;
    display: block;
  }
  .bottle-story.is-enhanced .bottle-story__scene { opacity: 0; }
  .bottle-story.is-enhanced .bottle-story__scene:first-child { opacity: 1; }
  .bottle-story.is-enhanced .bottle-story__plate {
    transform: scale(1.055);
    will-change: transform;
  }
  .bottle-story.is-enhanced .bottle-story__copy {
    top: 50%;
    bottom: auto;
    width: min(31rem, 34vw);
    transform: translateY(-50%);
  }
  .bottle-story.is-enhanced .bottle-story__scene--highball .bottle-story__copy {
    left: auto;
    right: var(--gutter);
  }
  .bottle-story.is-enhanced .bottle-story__scene--tableau .bottle-story__copy {
    top: 10%;
    left: var(--gutter);
    right: var(--gutter);
    width: auto;
    max-width: none;
    margin: 0;
    display: grid;
    grid-template-columns: minmax(24rem, .8fr) minmax(17rem, .42fr);
    grid-template-rows: auto auto;
    column-gap: clamp(14rem, 22vw, 24rem);
    align-items: end;
    text-align: left;
    transform: none;
  }
  .bottle-story.is-enhanced .bottle-story__scene--tableau .bottle-story__number {
    grid-column: 1;
    grid-row: 1;
  }
  .bottle-story.is-enhanced .bottle-story__scene--tableau .bottle-story__copy h3 {
    grid-column: 1;
    grid-row: 2;
    margin-top: .65rem;
  }
  .bottle-story.is-enhanced .bottle-story__scene--tableau .bottle-story__copy > p {
    grid-column: 2;
    grid-row: 1;
    margin: 0;
  }
  .bottle-story.is-enhanced .bottle-story__scene--tableau .bottle-story__copy .btn {
    grid-column: 2;
    grid-row: 2;
    justify-self: start;
    margin: 1.15rem 0 0;
  }
  .bottle-story.is-enhanced .bottle-story__mobile-bottle { display: none; }
  .bottle-story.is-enhanced .bottle-story__visual {
    position: absolute;
    inset: 7% 35% 3%;
    z-index: 5;
    display: grid;
    place-items: end center;
    pointer-events: none;
  }
  .bottle-story.is-enhanced .bottle-story__foreground {
    position: absolute;
    inset: 0;
    z-index: 6;
    display: block;
    pointer-events: none;
    opacity: .24;
    -webkit-mask-image: linear-gradient(to bottom, transparent 42%, #000 82%);
            mask-image: linear-gradient(to bottom, transparent 42%, #000 82%);
  }
  .bottle-story.is-enhanced .bottle-story__foreground img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center bottom;
    filter: brightness(.54) saturate(.84);
    transform: scale(1.08);
  }
  .bottle-story.is-enhanced .bottle-story__progress {
    position: absolute;
    z-index: 8;
    left: var(--gutter);
    bottom: 2rem;
    display: grid;
    grid-template-columns: auto minmax(6rem, 9vw) auto;
    align-items: center;
    gap: .85rem;
    font-size: var(--t-micro);
    letter-spacing: var(--track-ui);
    color: var(--ash);
  }
  .bottle-story.is-enhanced .bottle-story__progress::before {
    content: '';
    grid-column: 2;
    grid-row: 1;
    height: 1px;
    background: color-mix(in srgb, var(--ash-dim) 55%, transparent);
  }
  .bottle-story.is-enhanced .bottle-story__progress-fill {
    grid-column: 2;
    grid-row: 1;
    height: 1px;
    background: var(--gold-lt);
    transform: scaleX(0);
    transform-origin: left center;
  }
}

/* Clipped so the botanicals can bleed past the bottle without spilling over
   the divider into the next expression. */
.product { position: relative; overflow: hidden; padding-block: clamp(4rem, 2rem + 7vw, 8rem); }
.product + .product { border-top: 1px solid color-mix(in srgb, var(--ash-dim) 35%, transparent); }

.product__stage {
  position: relative;
  /* The botanicals inside bleed well past this box on purpose. The stage
     clips them itself rather than relying on .product, which only wraps it
     on rum.html — on the home page the stage sits bare in the grid, and the
     bleed escaped all the way out of the viewport. */
  overflow: hidden;
  display: grid; place-items: center;
  min-height: clamp(22rem, 18rem + 22vw, 38rem);
}
/* Bled past the stage and feathered at the edges. The source art is a
   rectangular cut-out, so without a mask its boundary shows as a hard seam
   wherever the layout does not happen to clip it. */
.product__botanicals { position: absolute; inset: -22% -14%; }
.product__botanicals img {
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: .8;
  /* farthest-side puts the gradient's end exactly on the left and right
     edges, so those reach full transparency; top and bottom are already
     clipped by .product's overflow. */
  -webkit-mask-image: radial-gradient(farthest-side at 50% 45%, #000 28%, transparent 100%);
          mask-image: radial-gradient(farthest-side at 50% 45%, #000 28%, transparent 100%);
}
.product__bottle { position: relative; z-index: 2; }
.product__bottle img {
  height: clamp(18rem, 14rem + 24vw, 32rem); width: auto;
  filter: drop-shadow(0 40px 60px rgba(0,0,0,.7));
}

.product__meta { display: flex; flex-wrap: wrap; gap: 1.75rem 3rem; }
.product__stat dt { font-weight: var(--ui-weight); font-stretch: var(--ui-width); font-size: var(--t-micro); letter-spacing: var(--track-eyebrow); text-transform: uppercase; color: var(--ash); }
.product__stat dd {
  margin: .45rem 0 0;
  font-family: var(--font-display); font-weight: 300;
  font-size: 1.5rem; font-variation-settings: 'opsz' 48;
  color: var(--gold-lt);
}

/* Tasting notes as a metal-ruled list. */
.notes { border-top: 1px solid color-mix(in srgb, var(--ash-dim) 45%, transparent); }
.notes li {
  display: flex; justify-content: space-between; gap: 2rem;
  padding-block: .9rem;
  border-bottom: 1px solid color-mix(in srgb, var(--ash-dim) 45%, transparent);
  font-size: var(--t-body);
}
.notes li span:first-child { color: var(--ash); font-weight: var(--ui-weight); font-stretch: var(--ui-width); font-size: var(--t-eyebrow); letter-spacing: var(--track-ui); text-transform: uppercase; }
.notes li span:last-child { text-align: right; color: var(--bone); }

/* --------------------------------------------------------------------------
   15. Cocktails — filter + grid
   -------------------------------------------------------------------------- */


.grid {
  display: grid;
  gap: clamp(1.25rem, .5rem + 2.5vw, 2.75rem);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
}
/* Three serves, three columns — but never a lonely orphan on the second row,
   so it goes straight from three to one. */
.grid--3 { grid-template-columns: 1fr; }
@media (min-width: 900px) { .grid--3 { grid-template-columns: repeat(3, 1fr); } }

/* The numeral above a serve's name: 01 / NEAT */
.card__index {
  margin-bottom: .6rem;
  font-weight: var(--ui-weight); font-stretch: var(--ui-width);
  font-size: var(--t-micro);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--gold);
}

.card {
  position: relative;
  transition: opacity var(--dur-reveal) var(--ease-cine),
              transform var(--dur-reveal) var(--ease-cine);
}


.card__media {
  position: relative; overflow: hidden;
  aspect-ratio: 4 / 5;
  background: var(--ink-2);
}
.card__media img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform calc(var(--dur-reveal) * 1.2) var(--ease-cine),
              filter var(--dur-ui) var(--ease-out);
}
.card__media::after {
  content: ''; position: absolute; inset: 0;
  background: var(--scrim-b); opacity: .85;
  transition: opacity var(--dur-ui) var(--ease-out);
}
.card:hover .card__media img { transform: scale(1.06); }
.card:hover .card__media::after { opacity: .6; }

.card__body {
  position: absolute; left: 0; right: 0; bottom: 0;
  z-index: 1;
  padding: 1.5rem;
}
.card__title {
  font-family: var(--font-display); font-weight: 300;
  font-size: 1.375rem; font-variation-settings: 'opsz' 48;
  line-height: 1.15;
}
.card__line { margin-top: .5rem; font-weight: var(--ui-weight); font-stretch: var(--ui-width); font-size: var(--t-micro); letter-spacing: var(--track-ui); text-transform: uppercase; color: var(--gold-lt); }
/* Whole card is clickable via a stretched pseudo-element on the title link. */
.card__link::after { content: ''; position: absolute; inset: 0; z-index: 2; }

.card--soon { opacity: .55; }
.card--soon .card__line { color: var(--ash); }

/* --------------------------------------------------------------------------
   16. Cocktail detail
   -------------------------------------------------------------------------- */

/* Two offset images: a bleed plate behind, the product shot in front.
   The shot is taller than the plate, so the container reserves the extra room
   with padding — otherwise it overflows onto whatever follows. */
.recipe__hero-media { position: relative; padding-bottom: 26%; }
.recipe__plate { width: 84%; }
.recipe__shot {
  position: absolute; right: 0; bottom: 0;
  width: 58%;
  box-shadow: 0 40px 80px rgba(2,4,3,.6);
}

.recipe__cols { display: grid; gap: clamp(2.5rem, 1rem + 5vw, 5rem); }
@media (min-width: 800px) { .recipe__cols { grid-template-columns: 1fr 1.2fr; } }

.ingredients li {
  display: flex; gap: 1.5rem; justify-content: space-between;
  padding-block: .85rem;
  border-bottom: 1px solid color-mix(in srgb, var(--ash-dim) 40%, transparent);
}
.ingredients li span:first-child { color: var(--bone); }
.ingredients li span:last-child { color: var(--gold-lt); white-space: nowrap; font-variant-numeric: tabular-nums; }

.method { counter-reset: step; }
.method li {
  position: relative;
  counter-increment: step;
  padding-left: 3.25rem;
  color: color-mix(in srgb, var(--bone) 82%, transparent);
}
.method li + li { margin-top: 1.5rem; }
.method li::before {
  content: counter(step, decimal-leading-zero);
  position: absolute; left: 0; top: .1em;
  font-family: var(--font-display); font-size: 1.125rem;
  font-variation-settings: 'opsz' 48;
  background: var(--metal);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* --------------------------------------------------------------------------
   17. Footer
   -------------------------------------------------------------------------- */

.footer {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: clamp(2.5rem, 1.5rem + 4vw, 5.5rem) 2.25rem;
  /* Its own ground rather than a photograph: a cool pool top-left and a warm
     one rising from the bottom centre, as if lit from below the fold. Echoes
     the hero's wash so the page closes the way it opened. */
  background:
    radial-gradient(85% 60% at 50% 118%, rgba(230,174,55,.22) 0%, transparent 58%),
    radial-gradient(70% 55% at 12% -10%, rgba(10,52,50,.55) 0%, transparent 62%),
    linear-gradient(to bottom, var(--ink-void) 0%, #04110D 55%, #030A08 100%);
}
/* The foliage is brightest exactly where the legal line sits. This puts the
   ground back under it without hiding the leaves further up. */
.footer::after {
  content: '';
  position: absolute; z-index: -1;
  inset: auto 0 0 0;
  height: 20%;
  background: linear-gradient(to top, rgba(3,10,8,.94) 0%, rgba(3,10,8,.55) 45%, transparent 100%);
  pointer-events: none;
}
/* Foliage rising from the base, masked so it has no edge of its own and
   fades out before it reaches the links. */
.footer__leaves {
  position: absolute; z-index: -1;
  left: -12%; right: -12%; bottom: -8%;
  height: clamp(11rem, 8rem + 22vw, 26rem);
  pointer-events: none;
}
.footer__leaves img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center bottom;
  opacity: .45;
  -webkit-mask-image: linear-gradient(to top, #000 8%, transparent 92%);
          mask-image: linear-gradient(to top, #000 8%, transparent 92%);
}

.footer__inner { position: relative; z-index: 1; }

/* The sign-off: the wordmark set as wide as the measure allows. */
.footer__logo {
  width: min(100%, 62rem);
  aspect-ratio: 1000 / 105.2;
  margin: clamp(3rem, 2rem + 4vw, 6rem) auto clamp(2.5rem, 1.5rem + 3vw, 4.5rem);
}

.footer__grid {
  display: grid; gap: 2.5rem clamp(2rem, 1rem + 4vw, 5rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
}
/* A metal hairline instead of a grey one — the same rule the buttons use. */
.footer__rule {
  height: 1px; border: 0; margin: 0;
  background: var(--metal);
  opacity: .45;
}
.footer__h {
  font-weight: var(--ui-weight); font-stretch: var(--ui-width);
  font-size: var(--t-micro); letter-spacing: var(--track-eyebrow);
  text-transform: uppercase; color: var(--ash); margin-bottom: 1.1rem;
}
.footer__links li + li { margin-top: .6rem; }
.footer__links a { color: color-mix(in srgb, var(--bone) 85%, transparent); transition: color var(--dur-ui) var(--ease-out); }
.footer__links a:hover { color: var(--gold-lt); }

.footer__base {
  display: flex; flex-wrap: wrap; gap: .75rem 2rem;
  justify-content: space-between; align-items: baseline;
  font-size: var(--t-micro); color: var(--ash);
  letter-spacing: .04em;
}
@media (max-width: 599px) {
  .footer__base { justify-content: center; text-align: center; }
}
.footer__responsibly {
  font-family: var(--font-display); font-style: italic; font-size: 1.125rem;
  font-variation-settings: 'opsz' 48;
  background: var(--metal); -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* --------------------------------------------------------------------------
   18. Utilities
   -------------------------------------------------------------------------- */

.text-center { text-align: center; }
.mx-auto { margin-inline: auto; }
.relative { position: relative; }
.z-2 { z-index: 2; }
@media (max-width: 767px) { .hide-sm { display: none; } }
