/* IKARIS — sitewide stylesheet. Cool editorial theme, mobile-first.
   --paper/--paper-2/--paper-3/--charcoal are the site's primary surface —
   gallery-white/ash/stone backgrounds, near-black neutral text, brass-gold
   as the one warm accent against them. --ink/--ink-2/--ink-3/--bone stay
   their original dark values on purpose: they're reserved for the two
   deliberate dark beats in an otherwise light page (the Icarus hero and
   the full-screen mobile nav overlay), not repurposed, so those two
   sections never need special-casing against the rest of this file. */

:root {
  --paper: #f1f0ee;
  --paper-2: #e3e1dc;
  --paper-3: #d2cfc8;
  --charcoal: #1e1d1b;
  --gold: #96702a;
  --gold-soft: #b9903f;
  --muted: #6d6a64;
  --line: rgba(30, 29, 27, 0.15);
  --danger: #a8483a;
  --success: #4f7a5c;

  --ink: #0b0b0d;
  --ink-2: #141418;
  --ink-3: #1b1b20;
  --bone: #f3efe7;

  --font-serif: 'Bodoni Moda', Didot, 'Times New Roman', serif;
  --font-sans: 'Jost', Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --container: 1200px;
  --radius: 2px;
  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2.5rem;
  --space-5: 4rem;
  --space-6: 6rem;
}

*, *::before, *::after { box-sizing: border-box; }
/* overflow-x must NOT be set here: giving <html> an explicit overflow value
   forces its overflow-y to 'auto' too (per spec), which turns it into a
   scroll container and breaks position:sticky for every descendant
   (confirmed — this exact rule silently un-stuck the sticky header and the
   Icarus pinned stage). Horizontal overflow is instead prevented on body
   below, and at the actual source (see .grain). */
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--charcoal);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.6;
  overflow-x: hidden;
}

img { max-width: 100%; height: auto; display: block; }
a { color: var(--gold-soft); text-decoration: none; }
a:hover { color: var(--gold); }
button { font-family: inherit; }

h1, h2, h3, h4 {
  font-family: var(--font-serif);
  font-weight: 600;
  line-height: 1.15;
  color: var(--charcoal);
  margin: 0 0 var(--space-2);
}
h1 { font-size: clamp(2.2rem, 5vw, 3.6rem); font-weight: 500; }
h2 { font-size: clamp(1.5rem, 3vw, 2.2rem); font-weight: 500; }
h3 { font-size: 1.25rem; }
p { margin: 0 0 var(--space-2); color: var(--charcoal); }

.eyebrow {
  display: block;
  font-family: var(--font-sans);
  font-size: 0.72rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: var(--space-1);
}

.container { max-width: var(--container); margin: 0 auto; padding: 0 var(--space-2); }
@media (min-width: 640px) { .container { padding: 0 var(--space-3); } }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* Skip link */
.skip-link {
  position: absolute; left: 0; top: -60px; z-index: 1000;
  background: var(--gold); color: var(--paper); padding: 0.75em 1.25em;
  font-weight: 600; transition: top 0.15s ease;
}
.skip-link:focus { top: 0; }

/* Focus states */
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--gold-soft);
  outline-offset: 2px;
}

/* ---------- Header ---------- */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(241,240,238,0.92);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--line);
}
.site-header__bar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.9rem 0;
  gap: var(--space-2);
}
.brand-mark { display: flex; align-items: center; gap: 0.6rem; }
.brand-mark img { height: 34px; width: auto; }
.brand-mark__word {
  font-family: var(--font-serif);
  font-size: 1.4rem;
  letter-spacing: 0.18em;
  color: var(--charcoal);
}
.main-nav { display: none; }
.main-nav ul {
  display: flex;
  gap: var(--space-3);
  list-style: none; margin: 0; padding: 0;
}
.main-nav a {
  color: var(--charcoal);
  font-size: 0.85rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  position: relative;
  padding-bottom: 0.3em;
}
.main-nav a:hover { color: var(--gold); }
/* Same underline-draw mechanism already used by .gallery__switcher-dot —
   reused here rather than inventing a new pattern, now doing double duty:
   drawn in on hover, and left permanently drawn for whichever section the
   visitor is actually on (previously there was no "you are here" signal
   in the nav at all). */
.main-nav__underline {
  position: absolute; left: 0; bottom: 0; height: 1px; width: 100%;
  background: var(--gold);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.4s cubic-bezier(.16,1,.3,1);
}
.main-nav a:hover .main-nav__underline { transform: scaleX(1); }
.main-nav a.is-current { color: var(--gold); }
.main-nav a.is-current .main-nav__underline { transform: scaleX(1); }
@media (min-width: 900px) { .main-nav { display: block; } }

.header-actions { display: flex; align-items: center; gap: var(--space-2); }
.icon-btn {
  background: none; border: none; color: var(--charcoal); cursor: pointer;
  min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center;
  position: relative;
}
.cart-badge {
  position: absolute; top: 2px; right: 2px;
  background: var(--gold); color: var(--paper);
  font-size: 0.65rem; font-weight: 700;
  min-width: 16px; height: 16px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  line-height: 1;
}
.cart-badge[hidden] { display: none; }
.cart-badge.is-pulsing { animation: cart-badge-pulse 0.4s ease-out; }
@keyframes cart-badge-pulse {
  0% { transform: scale(1); }
  40% { transform: scale(1.45); }
  100% { transform: scale(1); }
}

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

/* Mobile nav drawer */
.mobile-nav {
  position: fixed; inset: 0; z-index: 200;
  background: var(--ink); /* deliberately dark — an editorial overlay moment, not the light page */
  display: none;
  flex-direction: column;
  padding: var(--space-2);
}
.mobile-nav.is-open { display: flex; }
.mobile-nav__top { display: flex; justify-content: flex-end; margin-bottom: var(--space-4); }
.mobile-nav ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.mobile-nav a { font-family: var(--font-serif); font-size: 1.8rem; color: var(--bone); }
.mobile-nav .icon-btn { color: var(--bone); }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0.75em 1.75em;
  border: 1px solid var(--charcoal); background: transparent; color: var(--charcoal);
  font-size: 0.78rem; letter-spacing: 0.14em; text-transform: uppercase;
  cursor: pointer; border-radius: 0;
  transition: border-color 0.25s ease, color 0.25s ease, letter-spacing 0.25s ease;
}
.btn:hover { border-color: var(--gold); color: var(--gold); letter-spacing: 0.18em; }
.btn-primary { background: var(--charcoal); color: var(--paper); border-color: var(--charcoal); }
.btn-primary:hover { background: var(--charcoal); color: var(--gold-soft); border-color: var(--charcoal); letter-spacing: 0.18em; }
.btn-ghost { border-color: var(--line); }
.btn-ghost:hover { border-color: var(--charcoal); color: var(--charcoal); }
.btn-block { width: 100%; }
.btn[disabled] { opacity: 0.5; cursor: not-allowed; }

/* ---------- Breadcrumbs ---------- */
.breadcrumbs { padding: var(--space-2) 0; font-size: 0.8rem; color: var(--muted); }
.breadcrumbs ol { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.4em; }
.breadcrumbs li::after { content: '/'; margin-left: 0.4em; color: var(--line); }
.breadcrumbs li:last-child::after { content: ''; }
.breadcrumbs a { color: var(--muted); }
.breadcrumbs a:hover { color: var(--gold); }
.breadcrumbs [aria-current] { color: var(--charcoal); }

/* ---------- Hero ---------- */
.hero {
  position: relative;
  padding: var(--space-5) 0;
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
.hero .container { position: relative; z-index: 1; }
.hero__grid { display: grid; gap: var(--space-4); align-items: center; }
@media (min-width: 900px) { .hero__grid { grid-template-columns: 1.1fr 0.9fr; } }
.hero__copy p { color: var(--muted); max-width: 46ch; }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }
.hero__media img { border-radius: var(--radius); width: 100%; }

.section { padding: var(--space-5) 0; }
.section-head { margin-bottom: var(--space-4); text-align: center; }
.section-head p { color: var(--muted); max-width: 60ch; margin: 0 auto; }

/* ---------- Grid utility (guides listing) ---------- */
.grid {
  display: grid; gap: var(--space-3);
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 700px) { .grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1000px) { .grid.grid-5 { grid-template-columns: repeat(5, 1fr); } }

/* ---------- Product page ---------- */
.product-page__grid { display: grid; gap: var(--space-4); }
@media (min-width: 900px) { .product-page__grid { grid-template-columns: 1fr 1fr; align-items: start; } }
/* Product pages currently carry zero atmosphere beyond the sitewide film
   grain — a soft wash tinted per-fragrance (from that product's own
   render3d.capColor, set inline as --wash-color) ties this back to the
   hero's ink-and-watercolor language without competing with the product
   shot itself: low opacity, blurred, sits behind the photo/3D viewer. */
.product-page__media { position: relative; z-index: 0; aspect-ratio: 586 / 996; }
.product-page__media::before {
  content: '';
  position: absolute; inset: -45%; z-index: -1; border-radius: 50%;
  background: radial-gradient(ellipse 45% 40% at 50% 42%, var(--wash-color, transparent) 0%, transparent 70%);
  opacity: 0.4;
  filter: blur(28px);
  pointer-events: none;
}
.product-page__media img { border-radius: var(--radius); width: 100%; }

.bottle-3d {
  position: absolute; inset: 0; z-index: 2;
  border-radius: var(--radius);
  opacity: 0;
  transition: opacity 0.6s ease;
}
.bottle-3d.is-ready { opacity: 1; }
.bottle-3d canvas { width: 100% !important; height: 100% !important; display: block; cursor: grab; touch-action: none; }
.bottle-3d:active canvas { cursor: grabbing; }
.bottle-3d__hint {
  position: absolute; bottom: var(--space-2); left: 50%;
  font-size: 0.68rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--muted); display: flex; align-items: center; gap: 0.5em;
  pointer-events: none; opacity: 0.85; transition: opacity 0.5s ease;
  animation: hint-nudge 2.4s ease-in-out infinite;
}
/* Previously stayed on screen, static, for the whole visit — competing
   with the bottle for attention indefinitely instead of teaching the
   gesture once and getting out of the way. bottle-viewer.js adds
   .is-dismissed the first time OrbitControls reports real drag input. */
.bottle-3d__hint.is-dismissed { opacity: 0; }
.bottle-3d__hint::before, .bottle-3d__hint::after { content: ''; width: 18px; height: 1px; background: var(--muted); }
@keyframes hint-nudge {
  0%, 100% { transform: translateX(-50%); }
  50% { transform: translateX(calc(-50% + 5px)); }
}
.product-page__meta { position: relative; display: flex; flex-direction: column; gap: var(--space-2); }
.product-page__meta > :not(.ghost-word) { position: relative; z-index: 1; }
.ghost-word--meta { top: 0.2em; left: -0.03em; transform: none; font-size: clamp(2.8rem, 9vw, 5.5rem); white-space: normal; line-height: 1; max-width: 100%; }
.product-page__price { font-size: 1.6rem; color: var(--gold-soft); font-family: var(--font-serif); }
.product-page__facts { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-2); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: var(--space-2) 0; }
.product-page__facts dt { font-size: 0.68rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); margin-bottom: 0.25em; }
.product-page__facts dd { margin: 0; font-size: 0.92rem; }

.qty-input {
  display: inline-flex; align-items: center; border: 1px solid var(--line); border-radius: var(--radius);
}
.qty-input button { min-width: 44px; min-height: 44px; background: none; border: none; color: var(--charcoal); font-size: 1.1rem; cursor: pointer; }
.qty-input input { width: 3rem; text-align: center; background: none; border: none; color: var(--charcoal); font-size: 16px; min-height: 44px; }

/* Note pyramid accordion */
.notes-accordion { border-top: 1px solid var(--line); }
.notes-accordion__toggle {
  width: 100%; display: flex; align-items: center; justify-content: space-between;
  background: none; border: none; border-bottom: 1px solid var(--line);
  color: var(--charcoal); font-family: var(--font-serif); font-size: 1.1rem;
  padding: var(--space-2) 0; cursor: pointer; min-height: 44px;
}
.notes-accordion__icon { display: inline-block; transition: transform 0.3s ease; font-size: 1.3rem; color: var(--gold); }
.notes-accordion__toggle[aria-expanded="true"] .notes-accordion__icon { transform: rotate(135deg); }
.notes-accordion__panel {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows 0.4s cubic-bezier(.16,1,.3,1), opacity 0.3s ease;
}
.notes-accordion__panel-inner { overflow: hidden; min-height: 0; }
.notes-accordion__panel.is-open { grid-template-rows: 1fr; opacity: 1; }
.notes-accordion__panel.is-open .notes-accordion__panel-inner { padding: var(--space-2) 0; }
@supports not (grid-template-rows: 1fr) {
  .notes-accordion__panel { display: none; }
  .notes-accordion__panel.is-open { display: block; }
}
.notes-tier { margin-bottom: var(--space-2); }
.notes-tier h4 { font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--gold); margin-bottom: 0.35em; }
.notes-tier p { margin: 0; color: var(--muted); }

/* ---------- Cart / Checkout ---------- */
.cart-table { width: 100%; border-collapse: collapse; }
.cart-table th, .cart-table td { text-align: left; padding: var(--space-2) 0.5rem; border-bottom: 1px solid var(--line); vertical-align: middle; }
.cart-table th { font-size: 0.7rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
.cart-line__product { display: flex; align-items: center; gap: var(--space-2); }
.cart-line__product img { width: 56px; height: 76px; object-fit: cover; border-radius: var(--radius); }
.cart-summary { background: var(--paper-2); border: 1px solid var(--line); padding: var(--space-3); }
.cart-summary__row { display: flex; justify-content: space-between; padding: 0.4em 0; }
.cart-summary__row--total { border-top: 1px solid var(--line); margin-top: 0.5em; padding-top: 0.75em; font-weight: 600; font-size: 1.1rem; }
.cart-empty { text-align: center; padding: var(--space-5) 0; color: var(--muted); }

.form-grid { display: grid; gap: var(--space-2); }
@media (min-width: 700px) { .form-grid.cols-2 { grid-template-columns: 1fr 1fr; } }
.form-field { display: flex; flex-direction: column; gap: 0.4em; }
.form-field label { font-size: 0.75rem; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); }
.form-field input, .form-field select, .form-field textarea {
  background: var(--paper-2); border: 1px solid var(--line); color: var(--charcoal);
  padding: 0.8em 0.9em; font-size: 16px; border-radius: var(--radius); min-height: 44px; font-family: inherit;
}
.form-field input:focus, .form-field select:focus, .form-field textarea:focus { border-color: var(--gold); }
fieldset { border: 1px solid var(--line); border-radius: var(--radius); padding: var(--space-2); margin: 0; }
legend { font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); padding: 0 0.5em; }
.radio-row { display: flex; align-items: center; gap: 0.6em; padding: 0.5em 0; min-height: 44px; }
.radio-row input { width: 20px; height: 20px; }
.checkout-layout { display: grid; gap: var(--space-4); }
@media (min-width: 900px) { .checkout-layout { grid-template-columns: 1.3fr 1fr; align-items: start; } }
.checkout-step { border: 1px solid var(--line); padding: var(--space-3); margin-bottom: var(--space-3); }

.confirm-panel { text-align: center; padding: var(--space-5) 0; max-width: 640px; margin: 0 auto; }
.confirm-ref { font-family: var(--font-serif); font-size: 1.6rem; color: var(--gold-soft); letter-spacing: 0.05em; }
.disclosure-box { border: 1px solid var(--gold); padding: var(--space-2); font-size: 0.88rem; margin: var(--space-3) 0; border-radius: var(--radius); text-align: left; }

/* ---------- Guides ---------- */
.guide-article { max-width: 72ch; margin: 0 auto; }
.guide-article h2 { margin-top: var(--space-4); }
.guide-article ul, .guide-article ol { color: var(--charcoal); padding-left: 1.2em; }
.guide-article li { margin-bottom: 0.5em; }
.guide-meta { color: var(--muted); font-size: 0.85rem; margin-bottom: var(--space-2); }
.faq-item { border-top: 1px solid var(--line); padding: var(--space-2) 0; }
.faq-item h3 { font-size: 1.05rem; }
.faq-item p { color: var(--muted); }
.guide-card { border: 1px solid var(--line); padding: var(--space-3); background: var(--paper-2); height: 100%; }
.guide-card h3 { margin-top: 0; }
.guide-card p { color: var(--muted); font-size: 0.9rem; }

/* ---------- About / policy pages ---------- */
.prose { max-width: 72ch; margin: 0 auto; }
.prose p { color: var(--muted); }
.stat-row { display: grid; grid-template-columns: repeat(2,1fr); gap: var(--space-3); margin: var(--space-4) 0; text-align: center; }
@media (min-width: 700px) { .stat-row { grid-template-columns: repeat(4,1fr); } }
.stat-row strong { display: block; font-family: var(--font-serif); font-size: 2rem; color: var(--gold-soft); }
.stat-row span { font-size: 0.78rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }

/* --ink-2/--ink-3 were defined for a genuine three-step dark elevation
   ladder alongside --ink, but nothing on the site actually used the two
   raised steps — every dark surface just sat flat on --ink. This is the
   first deliberate use of all three together: a subtle radial lift toward
   the top of the panel instead of a flat fill. */
.house-statement {
  background: radial-gradient(ellipse 70% 90% at 50% 0%, var(--ink-3) 0%, var(--ink-2) 45%, var(--ink) 100%);
  color: var(--bone);
  text-align: center;
}
.house-statement__quote {
  font-family: var(--font-serif);
  font-size: clamp(1.7rem, 1.1vw + 1.4rem, 2.6rem);
  line-height: 1.3;
  max-width: 20ch;
  margin: 0 auto var(--space-3);
  color: var(--bone);
}
.house-statement__label {
  display: block;
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold-soft);
}

/* ---------- Footer ---------- */
.site-footer { border-top: 1px solid var(--line); padding: var(--space-5) 0 var(--space-3); background: var(--paper-2); }
.footer-grid { display: grid; gap: var(--space-4); margin-bottom: var(--space-4); }
@media (min-width: 700px) { .footer-grid { grid-template-columns: 1.4fr 1fr 1fr; } }
.footer-grid h4 { font-size: 0.75rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); margin-bottom: var(--space-2); }
.footer-grid ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.6em; }
.footer-grid ul a { color: var(--charcoal); font-size: 0.9rem; }
.footer-bottom { border-top: 1px solid var(--line); padding-top: var(--space-2); display: flex; flex-wrap: wrap; gap: var(--space-2); justify-content: space-between; align-items: center; font-size: 0.78rem; color: var(--muted); }
.footer-disclosure { font-size: 0.76rem; color: var(--muted); border-top: 1px dashed var(--line); margin-top: var(--space-2); padding-top: var(--space-2); }

/* ---------- Consent banner ---------- */
.consent-banner {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 300;
  background: var(--paper-2); border-top: 1px solid var(--gold);
  padding: var(--space-2);
  display: none;
}
.consent-banner.is-visible { display: block; }
.consent-banner__inner { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; justify-content: space-between; max-width: var(--container); margin: 0 auto; }
.consent-banner p { margin: 0; font-size: 0.85rem; color: var(--muted); max-width: 60ch; }
.consent-banner__actions { display: flex; gap: var(--space-1); flex-wrap: wrap; }

/* ---------- Internal traffic badge ---------- */
.internal-badge {
  position: fixed; bottom: var(--space-2); left: var(--space-2); z-index: 400;
  background: var(--danger); color: #1a0d0a; font-size: 0.7rem; font-weight: 700;
  letter-spacing: 0.05em; text-transform: uppercase; padding: 0.4em 0.7em;
  border-radius: var(--radius);
}

/* ---------- 404 ---------- */
.error-page { text-align: center; padding: var(--space-6) 0; }
.error-page h1 { font-size: 5rem; color: var(--gold); }

/* ---------- Analytics debug ---------- */
.debug-grid { display: grid; gap: var(--space-3); }
@media (min-width: 900px) { .debug-grid { grid-template-columns: 1fr 1fr; } }
.debug-panel { border: 1px solid var(--line); padding: var(--space-2); background: var(--paper-2); }
.debug-panel h2 { font-size: 1rem; }
.debug-table { width: 100%; border-collapse: collapse; font-size: 0.78rem; }
.debug-table th, .debug-table td { border-bottom: 1px solid var(--line); padding: 0.4em; text-align: left; vertical-align: top; }
.debug-table pre { white-space: pre-wrap; word-break: break-word; margin: 0; font-size: 0.72rem; color: var(--muted); max-height: 120px; overflow: auto; }
.debug-actions { display: flex; flex-wrap: wrap; gap: 0.5em; }
.debug-actions button { font-size: 0.72rem; padding: 0.5em 0.8em; min-height: 36px; }
.status-pill { display: inline-block; padding: 0.2em 0.7em; border-radius: 999px; font-size: 0.72rem; border: 1px solid var(--line); }
.status-pill.ok { color: var(--success); border-color: var(--success); }
.status-pill.off { color: var(--muted); }

/* ---------- Utility ---------- */
.mt-0 { margin-top: 0; }
.text-center { text-align: center; }
.mb-0 { margin-bottom: 0; }

/* =====================================================================
   EXPERIENCE LAYER — preloader, grain, cursor, tilt/glass, kinetic type,
   marquee, scroll-reveal. Pure CSS + progressive-enhancement JS
   (src/js/experience.js). Every effect here degrades to plain, fully
   readable, keyboard- and crawler-accessible content with JS off or
   prefers-reduced-motion on — nothing here gates real content on animation.
   ===================================================================== */

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--paper); }
::-webkit-scrollbar-thumb { background: var(--line); border: 2px solid var(--paper); border-radius: 8px; }
::-webkit-scrollbar-thumb:hover { background: var(--gold); }
html { scrollbar-color: var(--line) var(--paper); }

/* Preloader */
.preloader {
  position: fixed; inset: 0; z-index: 900;
  background: var(--paper);
  display: flex; align-items: center; justify-content: center;
  transition: opacity 0.6s ease, visibility 0.6s ease;
}
.preloader img { width: 64px; height: 60px; opacity: 0; animation: preloader-in 1.1s ease forwards; }
.preloader.is-done { opacity: 0; visibility: hidden; pointer-events: none; }
@keyframes preloader-in {
  0% { opacity: 0; transform: scale(0.85); }
  60% { opacity: 1; transform: scale(1.03); }
  100% { opacity: 1; transform: scale(1); }
}
body.no-js-preload .preloader { display: none; }

/* Film grain, fixed and cheap: one animated SVG-noise layer over everything */
.grain {
  position: fixed; inset: 0; z-index: 2;
  width: 100%; height: 100%;
  pointer-events: none;
  opacity: 0.05;
  overflow: hidden;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 160px 160px;
  animation: grain-shift 1s steps(4) infinite;
}
@keyframes grain-shift {
  0% { background-position: 0 0; }
  25% { background-position: -8px 4px; }
  50% { background-position: 4px -8px; }
  75% { background-position: -4px 8px; }
  100% { background-position: 0 0; }
}

/* Ambient gold glow, used behind hero/product visuals */
.glow {
  position: absolute; z-index: 0; pointer-events: none;
  width: 60vw; height: 60vw; max-width: 700px; max-height: 700px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(201,162,39,0.22) 0%, rgba(201,162,39,0.06) 45%, transparent 70%);
  filter: blur(20px);
  animation: glow-pulse 8s ease-in-out infinite;
}
@keyframes glow-pulse {
  0%, 100% { opacity: 0.7; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.08); }
}

/* Custom cursor (desktop, fine-pointer only — see experience.js feature check) */
.cursor-dot, .cursor-ring {
  position: fixed; top: 0; left: 0; z-index: 950;
  pointer-events: none;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  will-change: transform;
}
.cursor-dot { width: 6px; height: 6px; background: var(--gold); }
.cursor-ring {
  width: 34px; height: 34px; border: 1px solid var(--gold-soft);
  transition: width 0.2s ease, height 0.2s ease, border-color 0.2s ease, opacity 0.2s ease;
  opacity: 0.7;
}
.cursor-ring.is-hover { width: 56px; height: 56px; border-color: var(--gold); opacity: 1; }
.cursor-ring.is-drag { width: 90px; height: 90px; }
body.has-custom-cursor, body.has-custom-cursor a, body.has-custom-cursor button { cursor: none; }

/* Kinetic hero type: each line clips in from below on load */
.kinetic-line { overflow: hidden; }
.kinetic-line span {
  display: inline-block;
  transform: translateY(110%);
  animation: kinetic-in 0.9s cubic-bezier(.16,1,.3,1) forwards;
  animation-delay: var(--d, 0s);
}
@keyframes kinetic-in { to { transform: translateY(0); } }

/* Scroll reveal */
.reveal { opacity: 0; transform: translateY(28px); transition: opacity 0.7s cubic-bezier(.16,1,.3,1), transform 0.7s cubic-bezier(.16,1,.3,1); transition-delay: var(--rd, 0s); }
.reveal.is-visible { opacity: 1; transform: translateY(0); }

/* Interactive tilt stage for product imagery — mouse-reactive glass highlight */
.tilt-stage {
  position: relative;
  perspective: 1200px;
}
.tilt-stage__inner {
  position: relative;
  transform-style: preserve-3d;
  transition: transform 0.25s cubic-bezier(.16,1,.3,1);
  will-change: transform;
}
.tilt-stage__inner picture, .tilt-stage__inner img { position: relative; z-index: 1; border-radius: var(--radius); }
.tilt-stage__sheen {
  position: absolute; inset: 0; z-index: 2;
  border-radius: var(--radius);
  background: radial-gradient(circle at var(--sx, 50%) var(--sy, 30%), rgba(255,255,255,0.30) 0%, rgba(255,255,255,0.08) 18%, transparent 42%);
  mix-blend-mode: screen;
  opacity: 0;
  transition: opacity 0.3s ease;
}
.tilt-stage:hover .tilt-stage__sheen, .tilt-stage.is-active .tilt-stage__sheen { opacity: 1; }
.tilt-stage__hint {
  position: absolute; bottom: var(--space-2); left: 50%; transform: translateX(-50%);
  z-index: 3;
  font-size: 0.68rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--muted);
  display: flex; align-items: center; gap: 0.5em;
  opacity: 0.8;
  pointer-events: none;
}
.tilt-stage__hint::before, .tilt-stage__hint::after { content: ''; width: 18px; height: 1px; background: var(--muted); }

/* Giant background wordmark behind product hero */
.ghost-word {
  position: absolute; z-index: 0; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  font-family: var(--font-serif); font-weight: 600;
  font-size: clamp(4rem, 16vw, 13rem);
  color: transparent;
  -webkit-text-stroke: 1px var(--line);
  white-space: nowrap;
  pointer-events: none;
  letter-spacing: 0.02em;
  user-select: none;
}

/* Magnetic buttons */
/* JS (experience.js initMagnetic) writes a translate() on every mousemove
   and resets to translate(0,0) on mouseleave — with no transition here,
   the release snapped back in a single frame instead of settling, which
   read as a glitch rather than a magnetic pull. The same short transition
   also smooths the tracking itself into a slight elastic lag, which is
   the actual effect real "magnetic button" implementations rely on. */
.btn-magnetic { position: relative; transition: transform 0.35s cubic-bezier(.16,1,.3,1); }

/* Reduced motion: strip every non-essential animation, keep content static */
@media (prefers-reduced-motion: reduce) {
  .grain, .glow, .preloader img, .bottle-3d__hint, .cart-badge { animation: none !important; }
  .kinetic-line span { animation: none !important; transform: none !important; }
  .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
  .tilt-stage__inner { transition: none !important; }
  html { scroll-behavior: auto; }
}

/* Coarse pointers / touch: no custom cursor, no tilt math, no grain flicker cost */
@media (hover: none), (pointer: coarse) {
  .cursor-dot, .cursor-ring { display: none !important; }
  .grain { animation: none; }
}

/* =====================================================================
   THE EPIC — a GSAP/ScrollTrigger-driven cinematic telling of the Icarus
   myth as the homepage hero: ascent toward the sun, the fall, the sea, and
   rebirth holding the bottle, which then grows to fill the screen as the
   transition into the product gallery. src/js/icarus-cinematic.js pins
   .epic and scrubs a GSAP timeline against scroll position — this file
   only sets base look; GSAP owns the animated properties directly.
   ===================================================================== */

.epic {
  position: relative;
  height: 100vh;
  min-height: 560px;
  overflow: hidden;
  /* The hero is an illustrated storybook plate, not a night sky — these
     tones are pulled straight from the ink-and-watercolor illustrations'
     own warm paper, so the scene reads as one continuous painting instead
     of artwork pasted onto a black box. */
  --epic-cream: #f5ead0;
  --epic-cream-deep: #e6d2a3;
  --epic-ink: #3c2c1a;
  --epic-ink-soft: #6b5439;
  --epic-sea: #1c6577;
  --epic-sea-deep: #0d3140;
  background: var(--epic-cream);
}
.epic__sky {
  position: absolute; inset: -2px; z-index: 0;
  /* Blotchy watercolor wash patches (matching the loose ink-and-watercolor
     bleed in the illustrations themselves) layered under the base warm
     gradient, instead of a flat, smoothly-printed backdrop. */
  background:
    radial-gradient(ellipse 30% 22% at 14% 28%, rgba(216,178,116,0.32) 0%, transparent 72%),
    radial-gradient(ellipse 26% 20% at 82% 58%, rgba(198,156,96,0.28) 0%, transparent 72%),
    radial-gradient(ellipse 36% 24% at 42% 84%, rgba(228,198,148,0.3) 0%, transparent 72%),
    radial-gradient(ellipse at 68% 20%, #fffaef 0%, var(--epic-cream) 46%, var(--epic-cream-deep) 100%);
  transition: background 1.4s ease;
}
/* The reference illustrations are built from linework — fine sketchy pen
   strokes under the wash, not a smooth printed gradient. A tiled diagonal
   hatch, multiplied over the blotches above, closes that gap without
   touching the gradient layer itself (mix-blend-mode applies per element,
   so this needs its own pseudo rather than a fifth background layer). */
.epic__sky::after {
  content: '';
  position: absolute; inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='46' height='46'%3E%3Cg stroke='rgba(60,44,26,0.16)' stroke-width='1' fill='none'%3E%3Cline x1='-8' y1='46' x2='38' y2='0'/%3E%3Cline x1='8' y1='58' x2='58' y2='8'/%3E%3Cline x1='-20' y1='30' x2='16' y2='-6'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 46px 46px;
  mix-blend-mode: multiply;
  opacity: 0.55;
  pointer-events: none;
}
/* Phase classes were already wired up by icarus-cinematic.js (one per
   scroll segment) but nothing consumed them — the backdrop stayed static
   the whole sequence. Cooling the wash once he starts falling ties the
   background to the story instead of just the ocean panel at the bottom. */
.epic__sky.phase-fall,
.epic__sky.phase-ocean,
.epic__sky.phase-rise {
  background:
    radial-gradient(ellipse 30% 22% at 18% 26%, rgba(150,190,178,0.3) 0%, transparent 72%),
    radial-gradient(ellipse 26% 20% at 78% 56%, rgba(128,170,164,0.26) 0%, transparent 72%),
    radial-gradient(ellipse 36% 24% at 42% 84%, rgba(180,214,206,0.28) 0%, transparent 72%),
    radial-gradient(ellipse at 68% 20%, #eef4ee 0%, #cfe2df 46%, #9fc4c2 100%);
}
.epic__vignette { position: absolute; inset: 0; z-index: 9; pointer-events: none; box-shadow: inset 0 0 16vw 3vw rgba(45,32,18,0.16); }

/* Soft, slow-drifting cloud smudges — an ambient CSS loop for constant
   motion, plus icarus-cinematic.js nudges the whole layer's transform from
   scroll progress so the sky itself parallaxes as you move through the
   sequence, not just the foreground elements. */
.epic__clouds { position: absolute; inset: 0; z-index: 1; overflow: hidden; pointer-events: none; transition: transform 0.4s linear; }
.epic__cloud {
  position: absolute; border-radius: 50%;
  background: radial-gradient(ellipse at center, rgba(255,252,240,0.6) 0%, rgba(255,252,240,0) 72%);
  filter: blur(3px);
}
.epic__cloud--1 { width: 38vw; height: 14vh; top: 10%; left: -15%; animation: epic-cloud-drift 75s linear infinite; }
.epic__cloud--2 { width: 26vw; height: 10vh; top: 26%; left: 35%; opacity: 0.75; animation: epic-cloud-drift 100s linear infinite; animation-delay: -30s; }
.epic__cloud--3 { width: 30vw; height: 11vh; top: 5%; left: 60%; opacity: 0.65; animation: epic-cloud-drift 88s linear infinite; animation-delay: -55s; }
@keyframes epic-cloud-drift { from { transform: translateX(0); } to { transform: translateX(135vw); } }


.epic__particles { position: absolute; inset: 0; z-index: 3; pointer-events: none; opacity: 0; }
.epic__particles span {
  position: absolute; border-radius: 50%; background: rgba(150,112,42,0.6);
  width: 3px; height: 3px;
}

/* Full-bleed: the artwork now fills the entire hero section edge to edge
   (previously a small floating plate, clamp(380px,42vw,640px), with a
   feathered radial mask fading its edges into the sky behind it) — object-
   fit: cover on the <video> itself (below) handles cropping whichever
   source (wide 16:9 desktop / tall 9:16 mobile, swapped by the breakpoint
   in icarus-figure.js) to fill the section's actual aspect ratio. */
.epic__icarus { position: absolute; z-index: 4; inset: 0; overflow: hidden; background: var(--epic-cream); }
/* Short desktop windows: the caption plaque wants less vertical room. */
@media (min-width: 700px) and (max-height: 720px) {
  .epic__caption { top: 96px; }
  .epic__line { font-size: clamp(1.3rem, 4vw, 2.1rem); }
  .epic__sub { font-size: 0.78rem; }
}
.epic__icarus video {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  display: block;
}

.epic__bottle {
  position: absolute; z-index: 5; left: 50%; top: 50%;
  width: clamp(160px, 22vw, 320px); height: 50vh; max-height: 480px;
  transform: translate(-50%, -50%) scale(0.001);
  opacity: 0;
  pointer-events: none;
}
.epic__bottle.is-live { pointer-events: auto; }
.epic__bottle canvas { width: 100% !important; height: 100% !important; display: block; }

/* Parked in the open sky above the video plate, clear of both the sun and
   the illustration/footage underneath it (top: 22vh, not a Y-centered
   46%) — plain text directly on the sky now that it has a clean patch of
   paper to sit on, with a soft light halo standing in for a boxed
   background so it still reads if a brighter patch of sky drifts behind it. */
.epic__caption {
  position: absolute; z-index: 7; left: 50%;
  /* A fixed-feeling top edge (not a Y-centered percentage) so this never
     drifts under the sticky header on short viewports — clamp() keeps it
     just below the header at any height instead of scaling down with it. */
  top: clamp(88px, 14vh, 150px);
  transform: translateX(-50%);
  text-align: center; width: min(80vw, 520px);
  pointer-events: none;
  /* All four lines (2 headlines + 2 subs) crossfade via opacity but only
     one is ever visible — without this they still stack in normal flow
     and their heights ADD UP (worst on mobile, where the narrower column
     wraps each one across more lines), pushing the whole block much
     taller than the single line actually on screen. Stacking every child
     into the same grid cell makes the container's height track just the
     tallest single line instead of the sum of all four. */
  display: grid;
}
.epic__caption > * { grid-area: 1 / 1; margin: 0; align-self: center; }
.epic__line {
  font-family: var(--font-serif); font-weight: 500;
  font-size: clamp(1.8rem, 5.4vw, 3.6rem);
  line-height: 1.1;
  color: var(--epic-ink);
  text-shadow: 0 1px 3px rgba(255,252,240,0.7), 0 0 24px rgba(255,252,240,0.6);
  opacity: 0;
}
.epic__sub {
  font-family: var(--font-sans); font-size: clamp(0.85rem, 1.5vw, 1.05rem);
  color: var(--epic-ink-soft);
  letter-spacing: 0.03em;
  text-shadow: 0 1px 3px rgba(255,252,240,0.7), 0 0 20px rgba(255,252,240,0.6);
  opacity: 0;
}
/* One word/phrase per caption carries the emotional weight of that line
   ("the sun", "to weep", "the sea", "kept") — picking it out in the
   brand's gold, rather than leaving every word the same weight, is what
   makes the line read as authored/art-directed rather than a plain
   caption. */
.epic__accent { color: var(--gold); font-style: italic; }

.epic__actions {
  position: absolute; z-index: 7; left: 50%; bottom: 8vh; transform: translateX(-50%);
  display: flex; gap: var(--space-2);
  opacity: 0; pointer-events: none;
}
.epic__actions.is-live { pointer-events: auto; }
/* .btn-ghost's near-invisible border (var(--line), 15% black) was tuned
   for the sitewide light --paper background. These actions only ever fade
   in past 90% scroll (see the tl.to(actions, ...) tween below), by which
   point the risen dark ocean fills the frame behind them — so this needs
   light, not ink-dark, to actually read: dark text/border on a dark teal
   sea was invisible, not just low-contrast. */
.epic__actions .btn-ghost { border-color: rgba(243,239,231,0.7); color: var(--bone); }
.epic__actions .btn-ghost:hover { border-color: var(--bone); color: var(--bone); }

.epic__cue {
  position: absolute; z-index: 7; left: 50%; bottom: 3vh; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 0.5em;
  font-size: 0.66rem; letter-spacing: 0.22em; text-transform: uppercase; color: var(--epic-ink-soft);
  opacity: 1; transition: opacity 0.6s ease;
}
.epic__cue.is-hidden { opacity: 0; }
.epic__cue::after { content: ''; width: 1px; height: 26px; background: var(--epic-ink-soft); animation: epic-cue-pulse 1.8s ease-in-out infinite; }
@keyframes epic-cue-pulse { 0%, 100% { opacity: 0.3; } 50% { opacity: 1; } }

/* Reduced motion / no-JS-timeline fallback: a plain static resting hero,
   no pin, no forced scroll length. Applied by icarus-cinematic.js adding
   .epic--static when it declines to build the GSAP timeline. */
.epic--static { height: auto; min-height: 82vh; display: flex; align-items: center; padding: var(--space-6) 0; }
.epic--static .epic__icarus,
.epic--static .epic__bottle,
.epic--static .epic__caption,
.epic--static .epic__actions { position: relative; inset: auto; transform: none; opacity: 1; pointer-events: auto; }
.epic--static .epic__line,
.epic--static .epic__sub { opacity: 1; }
.epic--static .epic__cue,
.epic--static .epic__particles { display: none; }
.epic--static .epic__caption { margin: 0 auto var(--space-4); }
/* .epic__icarus dropped its own width/aspect-ratio when it went full-bleed
   (inset: 0 fills whatever box it's in) — the static fallback still needs
   an explicit size since here it's back in normal document flow. */
.epic--static .epic__icarus { margin: 0 auto var(--space-3); width: clamp(380px, 42vw, 640px); aspect-ratio: 16 / 9; }
@media (max-width: 699px) {
  .epic--static .epic__icarus { width: clamp(240px, 62vw, 360px); aspect-ratio: 9 / 16; }
}
.epic--static .epic__bottle { margin: 0 auto var(--space-3); width: min(280px, 60vw); }
.epic--static .epic__actions { justify-content: center; margin: 0 auto; }

@media (max-width: 700px) {
  .epic__bottle { width: clamp(140px, 40vw, 220px); height: 40vh; }
}

/* =====================================================================
   THE GALLERY — the editorial product presentation replacing a plain
   grid: one large panel at a time per category, a small MEN · WOMEN
   corner switcher (not a nav bar), crossfaded via GSAP with no reload
   and no scroll-position jump. Falls back to a plain stacked list with
   both categories visible if JS never runs (real content either way).
   ===================================================================== */

.gallery { position: relative; padding: var(--space-6) 0; }
.gallery__head { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-5); flex-wrap: wrap; }
.gallery__title { margin: 0; font-size: clamp(2.6rem, 7vw, 5.5rem); line-height: 0.95; }

.gallery__switcher {
  display: inline-flex; align-items: center; gap: 0.6em;
  font-family: var(--font-sans); font-size: 0.78rem; letter-spacing: 0.14em; text-transform: uppercase;
}
.gallery__switcher button {
  background: none; border: none; color: var(--muted); cursor: pointer;
  padding: 0.4em 0.1em; min-height: 44px; position: relative;
}
.gallery__switcher button.is-active { color: var(--charcoal); }
.gallery__switcher-sep { color: var(--line); }
.gallery__switcher-dot {
  position: absolute; left: 0; bottom: 2px; height: 1px; width: 100%;
  background: var(--gold);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.4s cubic-bezier(.16,1,.3,1);
}
.gallery__switcher button.is-active .gallery__switcher-dot { transform: scaleX(1); }

.gallery__stage { position: relative; }
.gallery__set[hidden] { display: none; }

/* The showcase: one large centered 3D model (or photo) at a time, its name
   and a small detail line beneath it, a clicker either side to move to the
   next fragrance — no product grid anywhere, matching the reference site's
   single-model presentation. */
.showcase { max-width: 560px; margin: 0 auto; text-align: center; }
.showcase__stage {
  position: relative; aspect-ratio: 586 / 996; max-height: 68vh; margin: 0 auto;
  width: 100%;
}
.showcase__panel {
  position: absolute; inset: 0; z-index: 0; opacity: 0; pointer-events: none;
  transition: opacity 0.5s ease;
}
.showcase__panel::before {
  content: '';
  position: absolute; inset: -45%; z-index: -1; border-radius: 50%;
  background: radial-gradient(ellipse 45% 40% at 50% 42%, var(--wash-color, transparent) 0%, transparent 70%);
  opacity: 0.4;
  filter: blur(28px);
  pointer-events: none;
}
.showcase__panel.is-active { opacity: 1; pointer-events: auto; }
.showcase__panel .tilt-stage, .showcase__panel .tilt-stage__inner { position: absolute; inset: 0; }
.showcase__panel img { width: 100%; height: 100%; object-fit: contain; display: block; }
.showcase__panel .bottle-3d { position: absolute; inset: 0; }

.showcase__caption { display: flex; align-items: center; justify-content: center; gap: var(--space-3); margin-top: var(--space-3); }
.showcase__info { min-width: 0; }
.showcase__name { font-family: var(--font-serif); font-size: clamp(1.8rem, 3.4vw, 2.6rem); margin: 0 0 0.2em; color: var(--charcoal); }
.showcase__char { color: var(--muted); font-size: 0.85rem; letter-spacing: 0.02em; margin: 0 0 0.6em; }
.showcase__link { font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--charcoal); border-bottom: 1px solid var(--charcoal); padding-bottom: 0.15em; transition: color 0.2s ease, border-color 0.2s ease; }
.showcase__link:hover { color: var(--gold); border-color: var(--gold); }

.showcase__arrow {
  flex: none; background: none; border: 1px solid var(--line); color: var(--charcoal);
  width: 40px; height: 40px; border-radius: 50%; cursor: pointer;
  display: flex; align-items: center; justify-content: center; font-size: 1rem;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.showcase__arrow:hover { border-color: var(--gold); color: var(--gold); }
.showcase__dots { display: flex; align-items: center; justify-content: center; gap: 0.5em; margin-top: var(--space-2); }
.showcase__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--line); border: none; padding: 0; cursor: pointer; }
.showcase__dot.is-active { background: var(--gold); }

@media (max-width: 560px) {
  .showcase__stage { max-height: 52vh; }
  .showcase__caption { gap: var(--space-2); }
}
