/* ==============================================================
   Criseea . Lumanare botanica - scroll-driven landing

   Palette is the Criseea brand book (.claude/brand book/). ONE token
   deliberately does NOT follow it: --studio. See below.

   --studio is the colour the frames actually decode to at their outer
   edge, measured off the baked WebPs (left/right/top all read exactly
   238,236,232 with zero spread). The ffmpeg plate is authored as
   #EFEDEA; the yuv420p round-trip lands it 2 levels lower on blue, so
   this token tracks the DELIVERED value, not the authored one.
   Mirrored by STUDIO in js/app.js - EDIT BOTH TOGETHER.

   The brand ground is Raw stone #EFEAE0, 8 levels warmer on blue. We do
   NOT use it: that value is baked into the outer edge pixels of all 305
   frames, and moving the token alone opens a visible gutter around the
   candle. Closing the gap means re-baking AND re-tuning the grade's blue
   curve - see the brand note in CLAUDE.md.

   Motion mode is driven by html[data-motion], resolved before first
   paint by the inline script in index.html. The OS preference is the
   default; the reader can override it either way.

   Layer stack: canvas 0 . marquees 1 . tone-veil 2 . light-wash 3 .
                grain 4 . sections 5 . header 6 . loader 9
   ============================================================== */

@property --wipe { syntax: '<percentage>'; inherits: false; initial-value: 0%; }

:root {
  --studio:    #EEECE8;   /* measured off the baked frames - NOT the brand ground */
  --bg-wash:   #F8F5EE;   /* Bisque - cards, raised surfaces */

  /* Ink ramp descends from Soot ink, mixed toward the ground, so the whole
     ramp keeps Soot's channel proportions (R-G=4, G-B=5). Ratios measured
     against --studio, which is the conservative floor: text actually sits
     inside the Bisque halo, where every ratio is ~8% higher. */
  --ink:       #211D18;   /* Soot ink        14.2:1 */
  --ink-body:  #46423D;   /*                  8.4:1 */
  --ink-muted: #585550;   /*                  6.3:1 */
  --ink-faint: #65615D;   /*                  5.2:1 - floor */

  /* The brand book gives TWO accents with different jobs, so the single
     --accent this page used to have splits three ways. Two hard rules:
       . --sage is 4.8:1 and may NOT carry small text - use --sage-ink
       . --ember is 4.3:1 and may NEVER carry text, only flame/heat cues
     Both are the book's own instructions, now enforced by the ratios. */
  --sage:      #5C6B54;   /* Sage glaze  4.8:1 - fills, rules, marks       */
  --sage-ink:  #4A5743;   /* darkened    6.5:1 - small text and links      */
  --ember:     #A85A2C;   /* Ember       4.3:1 - flame/heat cues ONLY      */

  --rule:      #CFD2C6;   /* Glaze tint -> ground */
  --rule-x:    #A9B39C;   /* Glaze tint */
  --on-accent: #FFFFFF;   /*  5.7:1 on --sage, 7.7:1 on --sage-ink */

  --font-display: 'Fraunces', Georgia, serif;
  --font-body:    'Karla', system-ui, sans-serif;

  --fs-hero:    clamp(2.9rem, 8.4vw, 8rem);
  --fs-marquee: clamp(4rem, 12vw, 12vw);
  --fs-h2:      clamp(2rem, 4vw, 3.5rem);
  --fs-list:    clamp(1.5rem, 2.5vw, 2.25rem);
  --fs-body:    clamp(1.0625rem, 1.02vw, 1.1875rem);
  --fs-label:   0.75rem;

  --track:  0.22em;
  --ease:   cubic-bezier(0.22, 1, 0.36, 1);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--studio);
  color: var(--ink-body);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 450;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

::selection { background: rgba(168, 90, 44, 0.15); }   /* --ember */

/* -- Shared type ------------------------------------------------ */

.section-label {
  display: block;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
  margin-bottom: 1.6rem;
}
/* Recurring editorial hairline - the one ornament the page repeats. */
.section-label::before {
  content: "";
  display: block;
  width: 32px;
  height: 1px;
  margin-bottom: 1.15rem;
  background: var(--sage);
}

.section-heading {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: -0.018em;
  color: var(--ink);
  margin: 0 0 1.6rem;
  text-wrap: balance;
}

.section-body {
  max-width: 33ch;
  margin: 0;
  color: var(--ink-body);
}

/* Soft light halo - guarantees a local background without being a card:
   no border, no radius edge, no backdrop-filter, nothing to perceive. */
.section-inner { position: relative; }
.section-inner::before {
  content: "";
  position: absolute;
  inset: -3rem -4.5rem;
  background: radial-gradient(ellipse at center,
    rgba(248, 245, 238, 0.92) 0%,
    rgba(248, 245, 238, 0.7) 46%,
    rgba(248, 245, 238, 0) 78%);
  filter: blur(20px);
  z-index: -1;
  pointer-events: none;
}

.section-heading,
.section-body,
.section-label,
.plant {
  /* Large blur, low opacity. A tight high-opacity halo reads as a sticker. */
  text-shadow: 0 1px 12px rgba(248, 245, 238, 0.9), 0 0 2px rgba(248, 245, 238, 0.7);
}

/* -- Loader ----------------------------------------------------- */

#loader {
  position: fixed;
  inset: 0;
  z-index: 9;
  background: var(--studio);
  display: grid;
  place-items: center;
  transition: opacity 0.9s var(--ease);
}
#loader.done { opacity: 0; pointer-events: none; }

.loader-inner { width: min(80vw, 300px); }

/* Full lockup: the loader is the one place with room for it, and the brand
   book's 120px minimum lockup width is comfortably cleared at 240px. */
.loader-brand {
  display: block;
  width: 100%;
  max-width: 240px;
  height: auto;
  margin: 0 auto 2.1rem;
}

#loader-bar { height: 1px; background: var(--rule); overflow: hidden; }
/* Ember, not sage: the loader is literally an ignition - it reads "Se aprinde". */
#loader-bar i {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--ember);
  transition: width 0.3s linear;
}

.loader-meta {
  display: flex;
  justify-content: space-between;
  margin-top: 0.85rem;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

/* -- Header ----------------------------------------------------- */

.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 6;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.9rem 5vw;
  mix-blend-mode: multiply;
}

/* The mark ships black on a light ground - the brand book's primary ink
   version. Never recolour, stretch or rotate it. Clear space on every side
   must be at least the flame's height (~39% of the mark box); the header's
   1.9rem / 5vw padding already exceeds that.
   The header's mix-blend-mode: multiply is harmless here - the mark is black,
   and multiplying black over anything stays black. */
.logo {
  display: block;
  line-height: 0;
}
.logo img {
  display: block;
  width: 52px;
  height: 52px;
}

.site-header nav { display: flex; gap: 2.2rem; }

.site-header nav a {
  position: relative;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink-muted);
  text-decoration: none;
  transition: color 0.4s var(--ease);
}
.site-header nav a::after {
  content: "";
  position: absolute;
  left: 0; bottom: -5px;
  width: 100%; height: 1px;
  background: var(--sage);
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform 0.45s var(--ease);
}
.site-header nav a:hover { color: var(--sage-ink); }
.site-header nav a:hover::after { transform: scaleX(1); transform-origin: left center; }

/* -- Hero ------------------------------------------------------- */

.hero-standalone {
  position: relative;
  z-index: 5;
  height: 100vh;
  height: 100svh;
  display: grid;
  place-items: center;
  text-align: center;
  background: var(--studio);
  padding: 0 6vw;
}

.hero-inner .section-label { margin-bottom: 2.1rem; }
.hero-inner .section-label::before { margin-inline: auto; }

.hero-heading {
  font-family: var(--font-display);
  font-size: var(--fs-hero);
  font-weight: 300;
  line-height: 1.04;
  letter-spacing: -0.032em;
  color: var(--ink);
  margin: 0;
}
.hero-heading span { display: inline-block; }

.hero-tagline {
  margin: 2.2rem auto 0;
  max-width: 30ch;
  font-size: clamp(1.0625rem, 1.5vw, 1.3125rem);
  color: var(--ink-body);
}

.scroll-cue {
  position: absolute;
  bottom: 3rem;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column-reverse;
  align-items: center;
  gap: 0.9rem;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink-faint);
}
.scroll-cue i {
  width: 1px;
  height: 46px;
  background: linear-gradient(to bottom, var(--rule-x), transparent);
}

/* -- Fixed visual layers ---------------------------------------- */

/* Soft-edged wipe rather than clip-path: circle(). The wipe is centred on
   the candle, so a hard 1px edge would cut a visible arc across the flame's
   glow. In the gutters both sides are --studio, so softness costs nothing. */
.canvas-wrap {
  position: fixed;
  inset: 0;
  z-index: 0;
  background: var(--studio);
  --wipe: 0%;
  -webkit-mask-image: radial-gradient(circle at 50% 46%, #000 0%, #000 var(--wipe), transparent calc(var(--wipe) + 13%));
          mask-image: radial-gradient(circle at 50% 46%, #000 0%, #000 var(--wipe), transparent calc(var(--wipe) + 13%));
}
#canvas { display: block; width: 100%; height: 100%; }

#tone-veil {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  /* Derived from --ember (the book reserves it for flame/heat, which is
     exactly what this bloom is). The transparent stop stays in the Ember
     family so the ramp does not drift through grey on the way out. */
  background: radial-gradient(ellipse 60% 55% at 50% 42%,
    rgba(214, 114, 56, 0.5) 0%,
    rgba(196, 101, 46, 0.26) 45%,
    rgba(168, 90, 44, 0) 78%);
  mix-blend-mode: soft-light;
}

/* Inverted vignette: fully transparent over the candle, lightening only
   outward. It must never fog the product - a scrim across the hero is
   what makes pages like this look like a stock template. */
#light-wash {
  position: fixed;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: radial-gradient(ellipse 46% 70% at 50% 52%,
    rgba(248, 245, 238, 0) 0%,
    rgba(248, 245, 238, 0) 55%,
    rgba(248, 245, 238, 0.55) 78%,
    rgba(248, 245, 238, 0.86) 100%);
}

/* Post-decode dither. Identical texture on both sides of every join, and it
   breaks up #light-wash's own banding - that gradient traverses ~8 levels
   over half a viewport, and Safari does not dither CSS gradients. Plain
   opacity, no blend mode: a blend mode would force a compositor backdrop
   readback on every canvas repaint. */
#grain {
  position: fixed;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  opacity: 0.036;
  background-size: 128px 128px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='128' height='128'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='128' height='128' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* -- Marquees --------------------------------------------------- */

.marquee-wrap {
  position: fixed;
  left: 0;
  z-index: 1;
  width: 100%;
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  white-space: nowrap;
}
#marquee-1 { top: 74%; }
#marquee-2 { top: 16%; }

.marquee-text {
  display: inline-block;
  font-family: var(--font-display);
  font-size: var(--fs-marquee);
  font-weight: 300;
  line-height: 1;
  letter-spacing: -0.025em;
  color: #D6D8CD;                                /* Glaze tint -> ground */
  will-change: transform;
}
#marquee-2 .marquee-text { color: #DCDDD4; }

/* -- Scroll container & sections -------------------------------- */

#scroll-container {
  position: relative;
  height: 780vh;
  z-index: 5;
  pointer-events: none;
}

/* Fixed rather than absolute-at-midpoint: keeps every section optically
   centred instead of drifting toward the viewport edge on late sections. */
.scroll-section {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  height: 100svh;
  display: flex;
  align-items: center;
  opacity: 0;
  visibility: hidden;
}
.scroll-section.is-active { visibility: visible; }
.scroll-section .section-inner > * { pointer-events: auto; }

.align-left  { padding-left: 6vw;  padding-right: 55vw; justify-content: flex-start; }
.align-right { padding-left: 55vw; padding-right: 6vw;  justify-content: flex-start; }
.align-left  .section-inner,
.align-right .section-inner { max-width: 39vw; }

/* -- 004 . botanical index -------------------------------------- */

.plant-list { list-style: none; margin: 2.6rem 0 0; padding: 0; }
.plant {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 1.1rem;
  font-family: var(--font-display);
  font-size: var(--fs-list);
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--ink);
  padding-bottom: 0.85rem;
  margin-bottom: 0.85rem;
}
.plant em {
  font-family: var(--font-body);
  font-style: normal;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--sage-ink);   /* 12px text - needs the ratio --sage cannot give */
  font-variant-numeric: tabular-nums;
}
.plant-rule {
  position: absolute;
  left: 0; bottom: 0;
  display: block;
  width: 100%;
  height: 1px;
  background: var(--rule-x);
  transform: scaleX(0);
  transform-origin: left center;
}

/* -- 005 . three-line heading ----------------------------------- */

.section-heading--lines span { display: block; }

/* -- CTA & colophon --------------------------------------------- */

.cta-button {
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  margin-top: 2.4rem;
  padding: 1.1rem 2.2rem;
  background: var(--sage);
  color: var(--on-accent);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track);
  text-transform: uppercase;
  text-decoration: none;
  transition: background 0.45s var(--ease), transform 0.45s var(--ease);
}
.cta-button span { transition: transform 0.45s var(--ease); }
.cta-button:hover { background: var(--sage-ink); transform: translateY(-2px); }
.cta-button:hover span { transform: translateX(4px); }
.cta-button:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

.colophon {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  margin: 3.5rem 0 0;
  padding-top: 1.3rem;
  border-top: 1px solid var(--rule);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* Mark at the brand book's 20px icon floor, paired with the name. */
.colophon-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
}
.colophon-brand img { display: block; width: 30px; height: 30px; }

.motion-toggle {
  margin-left: auto;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: var(--track);
  cursor: pointer;
  border-bottom: 1px solid var(--rule-x);
  transition: color 0.4s var(--ease), border-color 0.4s var(--ease);
}
.motion-toggle:hover { color: var(--sage-ink); border-color: var(--sage); }
.motion-toggle:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

/* -- Static imagery (reduced-motion only) ----------------------- */

.static-media { display: none; margin: 0; }
.static-media img { width: 100%; height: auto; display: block; }

/* == Narrow desktop ============================================= */

@media (max-width: 1200px) and (min-width: 901px) {
  .align-left  { padding-left: 5vw;  padding-right: 52vw; }
  .align-right { padding-left: 52vw; padding-right: 5vw; }
  .align-left .section-inner,
  .align-right .section-inner { max-width: 43vw; }
  #light-wash {
    background: radial-gradient(ellipse 38% 62% at 50% 52%,
      rgba(248, 245, 238, 0) 0%,
      rgba(248, 245, 238, 0) 50%,
      rgba(248, 245, 238, 0.6) 76%,
      rgba(248, 245, 238, 0.9) 100%);
  }
}

/* == Mobile ======================================================
   The frame's bottom edge is content (wax pool + shadow) and must never be
   shown, so the candle is bottom-anchored on every viewport. Text therefore
   takes the UPPER band and the candle rises into it from below - they never
   overlap, so no scrim is needed at all. */

@media (max-width: 900px) {
  #scroll-container { height: 520vh; }

  .site-header { padding: 1.3rem 6vw; }
  .site-header nav { gap: 1.5rem; }
  /* Held back from the desktop 52px so the header does not eat a phone viewport. */
  .logo img { width: 42px; height: 42px; }
  .site-header nav a[data-target="004"] { display: none; }

  .hero-heading { font-size: 14.5vw; }

  .scroll-section {
    align-items: flex-start;
    padding: 15vh 7vw 0 !important;
    justify-content: flex-start;
    text-align: left;
  }
  .align-left .section-inner,
  .align-right .section-inner { max-width: 100%; }

  .section-heading { font-size: 2.6rem; }
  .plant { font-size: 1.7rem; }
  .section-body { max-width: 38ch; }
  .colophon { margin-top: 2.4rem; }

  /* Linear and inverted: bright field under the text at the top, fully
     transparent over the candle below. */
  #light-wash {
    background: linear-gradient(to bottom,
      rgba(248, 245, 238, 0.96) 0%,
      rgba(248, 245, 238, 0.9) 38%,
      rgba(248, 245, 238, 0) 58%,
      rgba(248, 245, 238, 0) 100%);
  }
  #tone-veil {
    background: radial-gradient(ellipse 75% 45% at 50% 72%,
      rgba(214, 114, 56, 0.5) 0%,
      rgba(196, 101, 46, 0.26) 45%,
      rgba(168, 90, 44, 0) 78%);
  }

  .marquee-text { font-size: 17vw; }
  #marquee-1 { top: 66%; }
  #marquee-2 { top: 5%; }

  .section-inner::before { inset: -1.6rem -2rem; }
}

/* == Reduced motion - a real static one-pager, not a broken one ==
   Driven by the attribute, not the media query, so the reader can opt in
   or out. The inline head script seeds it from the OS preference. */

html[data-motion="reduce"] #loader { display: none; }
html[data-motion="reduce"] .canvas-wrap,
html[data-motion="reduce"] #light-wash,
html[data-motion="reduce"] #tone-veil,
html[data-motion="reduce"] #grain { display: none !important; }

html[data-motion="reduce"] .site-header { position: static; mix-blend-mode: normal; }
html[data-motion="reduce"] .hero-standalone { height: auto; padding: 16vh 6vw 11vh; }
html[data-motion="reduce"] .scroll-cue { display: none; }

html[data-motion="reduce"] #scroll-container { height: auto !important; pointer-events: auto; }

html[data-motion="reduce"] .scroll-section {
  position: static !important;
  height: auto !important;
  opacity: 1 !important;
  visibility: visible !important;
  transform: none !important;
  clip-path: none !important;
  display: block;
  padding: 9vh 6vw !important;
  border-top: 1px solid var(--rule);
}
html[data-motion="reduce"] .align-left .section-inner,
html[data-motion="reduce"] .align-right .section-inner { max-width: 62ch; }
html[data-motion="reduce"] .section-inner::before { display: none; }
html[data-motion="reduce"] .section-heading,
html[data-motion="reduce"] .section-body,
html[data-motion="reduce"] .section-label,
html[data-motion="reduce"] .plant { text-shadow: none; }
html[data-motion="reduce"] .plant-rule { transform: scaleX(1); }

html[data-motion="reduce"] .marquee-wrap {
  position: static;
  opacity: 1;
  margin: 0;
  padding: 5vh 6vw;
}
html[data-motion="reduce"] .marquee-text {
  font-size: clamp(1.75rem, 6vw, 3.25rem);
  transform: none !important;
}

html[data-motion="reduce"] .static-media { display: block; padding: 0 6vw; }
html[data-motion="reduce"] .static-media img { max-width: 64rem; margin: 0 auto; }

html[data-motion="reduce"] *,
html[data-motion="reduce"] *::before,
html[data-motion="reduce"] *::after {
  animation: none !important;
  transition-duration: 200ms !important;
}
