/* Design tokens. All colors and shared layout constants are defined here —
   other stylesheets reference them via var(), never hardcoded hex. */

:root {
  /* fonts */
  --font-body: 'Satoshi', sans-serif;
  --font-script: 'Momo Signature', cursive;

  /* floating menu */
  --menu-bg: #21211e;
  --menu-border: rgba(255, 255, 255, 0.06);
  --menu-shadow: rgba(0, 0, 0, 0.4);
  --menu-text: #ffffff;
  --menu-text-muted: #9d9d9d;
  --menu-divider: rgba(255, 255, 255, 0.08);
  --menu-hover-bg: rgba(255, 255, 255, 0.02);
  --menu-accent: #8b98ff;
  --menu-current-bg: #ffffff;
  --menu-current-text: #211b1a;

  /* nav list item hover (highlight + label nudge) — Figma's "Gentle"
     is an actual damped spring, not an easing curve at all, which is
     why every cubic-bezier version of this ("ease", "ease-out", any
     bezier "gentle" approximation) still read as mechanical/jerky —
     a bezier is a fixed S-curve shape, a spring is a physical decay.
     This uses CSS's linear() easing to sample real critically-damped
     spring math (no bounce/overshoot, matching "Gentle" rather than
     "Bouncy") instead of approximating it with a bezier. */
  --menu-item-hover-duration: 600ms;
  --menu-item-hover-ease: linear(0, 0.1172 8.33%, 0.3277 16.67%, 0.5258 25%, 0.6818 33.33%, 0.7938 41.67%, 0.8705 50%, 0.9211 58.33%, 0.9537 66.67%, 0.9743 75%, 0.9872 83.33%, 0.9952 91.67%, 1);


  /* page grid — 12 columns, stretch (1fr) fill at every breakpoint;
     margin/gutter narrow at smaller breakpoints. Base values below are
     the XS tier; overridden upward by the media queries that follow.

     Four tiers (kept distinct even where token values coincide —
     S and M share margin/gutter but are not the same tier, e.g.
     component-level breakpoints should target the S/M boundary
     at 980px, not merge the two):
       XS  360–639px   margin 24px  gutter 16px
       S   640–979px   margin 40px  gutter 20px
       M   980–1199px  margin 40px  gutter 20px
       XL/L 1200px+    margin 80px  gutter 20px */
  --grid-columns: 12;
  --grid-margin: 24px;  /* xs: 360–639px */
  --grid-gutter: 16px;  /* xs: 360–639px */

  /* homepage background: gradient from the top, ending exactly at the
     bottom of the first work row's 16:9 image; the flat end color
     continues for the rest of the page no matter how tall it grows.
     --home-gradient-stop is measured live by js/app.js against
     #gradient-anchor (its edge shifts with viewport width and font
     loading) — 1590px below is only the no-JS/first-paint fallback. */
  --home-gradient-start: #dad1f9;
  --home-gradient-end: #f3f3f1;
  --home-gradient-stop: 1590px;

  /* shared text color */
  --color-body-text: #1e1c38;
  --color-surface: #ffffff;

  /* hero heading gets a thin same-color stroke on top of the fill
     (matches the Figma layer: fill + stroke, both "body-text") to
     read a touch bolder than the Medium weight alone */
  --hero-heading-stroke-width: 0.1px;

  /* hero — the layout itself lives in the site's real 12-col grid
     (see css/hero.css: XL-L is node 332:909, M is node 332:1055).
     Avatar sizing differs by tier (M's circle is smaller than XL-L's,
     not just scaled by the grid), hence the separate -m tokens. */
  --hero-avatar-width: 216px;
  --hero-avatar-height: 217px;
  --hero-avatar-width-m: 162px;
  --hero-avatar-height-m: 162px;
  --hero-avatar-width-s: 80px;
  --hero-avatar-height-s: 80px;
  --hero-avatar-bg: linear-gradient(135deg, #b9aee8, #6f63a8); /* placeholder until the real illustration is exported */
  --hero-click-color: #746ba4;

  /* avatar bubble-pop toggle (illustration <-> real photo) */
  --hero-pop-out-duration: 190ms;
  --hero-pop-out-ease: cubic-bezier(0.55, 0, 1, 0.45);
  --hero-pop-in-duration: 450ms;
  --hero-pop-in-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --hero-burst-duration: 380ms;
  --hero-burst-ease: ease-out;

  /* work / notes-&-talks card grid — Figma reuses one placeholder
     stock photo across every card; we do the same with a gradient
     stand-in until real project shots are supplied */
  --work-placeholder-bg: linear-gradient(160deg, #0d1b2a 0%, #1b4965 22%, #5fa8d3 42%, #cdeac0 58%, #f4a259 75%, #bc4749 100%);

  /* work card hover: tag pills (hidden until hover, matching the
     reference mockup's .proj-tag behavior) + a 20% image scale-up */
  --work-tag-bg: #f2efff;
  --work-hover-duration: 400ms;
  --work-hover-ease: ease;
  --work-hover-stagger: 100ms;
  --work-tag-leave-duration: 180ms;
  --work-tag-leave-ease: ease-out;
  --work-tag-leave-stagger: 50ms;
  --work-image-scale: 1.2;

  /* scroll-triggered reveal (cards, and anything else opted in via
     .reveal-item — see css/reveal.css) */
  --reveal-duration: 600ms;
  --reveal-stagger: 100ms;
  --reveal-offset: 32px;
  --reveal-ease: cubic-bezier(0.25, 0.46, 0.45, 0.94);

  /* footer (Figma node 191:472) — XL-L/1200+ only for now */
  --footer-border: rgba(0, 0, 0, 0.12);
  /* link hover nudge reuses --menu-item-hover-ease (the "Gentle"
     spring, linear()-sampled so it's valid at any duration) at its
     own 300ms */
  --footer-link-hover-duration: 300ms;
}

/* s: 640–979px */
@media (min-width: 640px) {
  :root {
    --grid-margin: 40px;
    --grid-gutter: 20px;
  }
}

/* m: 980–1199px — same margin/gutter as S today, but a distinct tier;
   this boundary is the reference point for component-level
   breakpoints that need to split at S/M (e.g. work.css card spans),
   independent of whether the token values ever diverge. */
@media (min-width: 980px) {
  :root {
    --grid-margin: 40px;
    --grid-gutter: 20px;
  }
}

/* xl–l: 1200px and up */
@media (min-width: 1200px) {
  :root {
    --grid-margin: 80px;
    --grid-gutter: 20px;
  }
}
