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

:root{
  --bg:#000000;
  --off:#f5f5ed;
  --mint:#63b89b;
  --accent:#72cfb1;
  --muted:#8a8f8c;
  --dim:#4d524f;
  --line:#1a1d1b;
  --panel:#080a09;
  --ease:cubic-bezier(.22,1,.36,1);
  --mono:'JetBrains Mono',ui-monospace,monospace;
  --sans:'Inter',system-ui,sans-serif;
  --disp:'Space Grotesk','Inter',sans-serif;
}

html{ scroll-behavior:smooth; }

body{
  background:var(--bg);
  color:var(--off);
  font-family:var(--sans);
  line-height:1.6;
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
}

/* Pure black like the banner, lifted so it never reads flat. */
body::before{
  content:''; position:fixed; inset:0; z-index:0; pointer-events:none;
  background:
    radial-gradient(60% 50% at 75% 30%, rgba(114,207,177,.10), transparent 70%),
    radial-gradient(50% 40% at 15% 85%, rgba(99,184,155,.06), transparent 70%);
}

/* Fine grain: kills gradient banding, must never read as noise. */
.grain{
  position:fixed; inset:0; z-index:1; pointer-events:none; opacity:.035;
  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='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E");
}

a{ color:inherit; text-decoration:none; }
::selection{ background:rgba(114,207,177,.25); color:#fff; }

.wrap{ max-width:1180px; margin:0 auto; padding:0 clamp(1.1rem,4vw,2.2rem); position:relative; z-index:2; }

.nav{
  position:fixed; inset:0 0 auto 0; z-index:50;
  display:flex; align-items:center; justify-content:space-between;
  padding:.85rem clamp(1.1rem,4vw,2.2rem);
  backdrop-filter:blur(12px); background:rgba(0,0,0,.55);
  border-bottom:1px solid transparent; transition:border-color .3s var(--ease), background .3s var(--ease);
}
.nav.scrolled{ border-color:var(--line); background:rgba(0,0,0,.85); }
.nav-mark{ display:flex; align-items:center; gap:.6rem; font-family:var(--disp); font-weight:700; }
.nav-mark img{ width:22px; height:22px; }
.nav-links{ display:flex; align-items:center; gap:.9rem; font-family:var(--mono); font-size:.72rem; }
.nav-links a{ color:var(--muted); transition:color .2s var(--ease); }
.nav-links a:hover{ color:var(--accent); }

/* Lit when the scene is on, so its state is readable at a glance. */
.mode-tog{
  font-family:var(--mono); font-size:.68rem; font-weight:600; letter-spacing:.08em;
  padding:.3rem .55rem; border-radius:6px; cursor:pointer;
  background:transparent; color:var(--dim);
  border:1px solid var(--line);
  transition:color .2s var(--ease), border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.mode-tog:hover{ color:var(--off); border-color:var(--muted); }
.mode-tog[data-on="true"]{ color:var(--accent); border-color:var(--accent); box-shadow:0 0 14px rgba(114,207,177,.28); }

/* A scroll track, not a screen. The stage pins while the choreography plays;
   a 100svh hero would carry the scene off-screen before the flow appears. */
.hero{ position:relative; height:300svh; }
.hero-stage{ position:sticky; top:0; height:100svh; overflow:hidden; }

/* With no choreography there is nothing to scroll through: a 300svh track
   would be two screens of dead air before the content starts. */
:root[data-hero="reduced"] .hero,
:root[data-hero="static"] .hero{ height:100svh; }
#hero-canvas{ position:absolute; inset:0; width:100%; height:100%; z-index:1; display:block; }

/* The static mark is the default; WebGL earns the right to replace it.
   favicon.svg already carries the brand colours, so it needs no filter.
   It holds the right, where the 3D mark sits — centring it drops the mark
   straight on top of the copy. */
.hero-static{
  position:absolute; inset:0; z-index:2; pointer-events:none;
  display:flex; align-items:center; justify-content:flex-end;
  padding-right:12vw;
}
.hero-static img{ width:clamp(160px,22vw,300px); height:auto; filter:drop-shadow(0 0 70px rgba(114,207,177,.4)); }
@media(max-width:900px){
  .hero-static{ justify-content:center; align-items:flex-end; padding:0 0 14vh; }
}
:root[data-hero="webgl"] .hero-static{ display:none; }
:root[data-hero="reduced"] #hero-canvas,
:root[data-hero="static"] #hero-canvas{ display:none; }

.btn{
  font-family:var(--mono); font-size:.76rem; font-weight:600;
  text-transform:uppercase; letter-spacing:.05em;
  padding:.85rem 1.4rem; border-radius:9px;
  display:inline-flex; align-items:center; gap:.5rem;
  transition:transform .18s var(--ease), box-shadow .25s var(--ease), border-color .2s var(--ease);
}
.btn-primary{ background:linear-gradient(120deg,var(--mint),var(--accent)); color:#04120c; box-shadow:0 8px 40px rgba(114,207,177,.25); }
.btn-primary:hover{ transform:translateY(-3px); box-shadow:0 14px 55px rgba(114,207,177,.4); }
.btn-ghost{ border:1px solid var(--line); color:var(--off); }
.btn-ghost:hover{ border-color:var(--accent); transform:translateY(-3px); }

.sec{ padding:clamp(4rem,8vw,7rem) 0; border-top:1px solid var(--line); position:relative; z-index:2; }
.sec-num{ font-family:var(--mono); font-size:.72rem; color:var(--accent); letter-spacing:.2em; }
.sec-title{ font-family:var(--disp); font-weight:700; font-size:clamp(1.7rem,3.2vw,2.5rem); letter-spacing:-.02em; margin:.5rem 0 0; }
.sec-lead{ color:var(--muted); max-width:62ch; margin-top:1rem; }

/* The copy is a story across the scroll track. The pitch sits left beside the
   mark; every later beat drops to the bottom, because once the mark walks to
   centre the flow spans the full width and left-aligned text would collide. */
.hero-copy{ position:absolute; inset:0; z-index:3; pointer-events:none; }
/* width:100% matters: as a flex item the wrap would shrink to its content and
   `margin:0 auto` would then centre the copy instead of leaving it on the left. */
.hero-copy .wrap{ position:relative; height:100%; width:100%; }
.beat{ opacity:0; transition:opacity .18s linear; }
.beat-pitch{ max-width:44ch; }
:root[data-hero="webgl"] .beat{ position:absolute; left:0; right:0; }
:root[data-hero="webgl"] .beat-pitch{ top:50%; transform:translateY(-50%); right:auto; opacity:1; }
:root[data-hero="webgl"] .beat-cap{ bottom:9vh; text-align:center; }
.cap-line{ color:var(--muted); font-size:1.02rem; max-width:60ch; margin:0 auto; }
.cap-line strong{ color:var(--off); font-weight:600; }
.beat-cap .cta-row{ justify-content:center; margin-top:1.4rem; }
.scroll-hint{ margin-top:1.8rem; font-family:var(--mono); font-size:.7rem; letter-spacing:.16em; text-transform:uppercase; color:var(--dim); }

/* No scroll story without the scene: show the pitch and the CTA, drop the
   narration beats that only make sense against the animation. */
:root[data-hero="reduced"] .hero-copy,
:root[data-hero="static"] .hero-copy{ display:flex; align-items:center; }
/* height:auto lets the flex centring actually bite — a full-height wrap has
   nothing left to centre. */
:root[data-hero="reduced"] .hero-copy .wrap,
:root[data-hero="static"] .hero-copy .wrap{ height:auto; }
:root[data-hero="reduced"] .beat,
:root[data-hero="static"] .beat{ position:relative; opacity:1; transform:none; pointer-events:auto; }
:root[data-hero="reduced"] .beat-cap,
:root[data-hero="static"] .beat-cap{ display:none; }
:root[data-hero="reduced"] .beat-cap:last-child,
:root[data-hero="static"] .beat-cap:last-child{ display:block; text-align:left; margin-top:1.5rem; }
:root[data-hero="reduced"] .beat-cap:last-child .cap-line,
:root[data-hero="static"] .beat-cap:last-child .cap-line{ display:none; }
:root[data-hero="reduced"] .beat-cap .cta-row,
:root[data-hero="static"] .beat-cap .cta-row{ justify-content:flex-start; margin-top:0; }
:root[data-hero="reduced"] .scroll-hint,
:root[data-hero="static"] .scroll-hint{ display:none; }
.eyebrow{ font-family:var(--mono); font-size:.72rem; letter-spacing:.24em; text-transform:uppercase; color:var(--accent); }
h1{ font-family:var(--disp); font-weight:700; font-size:clamp(2.2rem,4.6vw,3.9rem); line-height:1.02; letter-spacing:-.03em; margin:1.1rem 0 0; max-width:14ch; }
h1 .grad{ background:linear-gradient(100deg,var(--mint),var(--accent)); -webkit-background-clip:text; background-clip:text; color:transparent; }
.lead{ margin:1.3rem 0 0; color:var(--muted); font-size:1.02rem; max-width:44ch; }
.cta-row{ display:flex; gap:.8rem; margin-top:2rem; flex-wrap:wrap; }
@media(max-width:900px){
  .hero-copy{ align-items:flex-start; padding-top:22vh; }
  .hero-copy .wrap{ text-align:center; }
  h1, .lead{ max-width:none; }
  .hero-copy .cta-row{ justify-content:center; }
}
.code{
  margin-top:1.4rem; border:1px solid var(--line); border-radius:12px; background:var(--panel);
  padding:1.05rem 1.25rem; font-family:var(--mono); font-size:.9rem; color:var(--accent); overflow-x:auto;
}
.grid-3{ display:grid; grid-template-columns:repeat(3,1fr); gap:1.1rem; margin-top:2.4rem; }
.card{ border:1px solid var(--line); border-radius:16px; background:var(--panel); padding:1.6rem; }
.card h3{ font-family:var(--disp); font-weight:600; font-size:1.15rem; margin-bottom:.5rem; }
.card p{ color:var(--muted); font-size:.9rem; }
.fine{ margin-top:1.6rem; font-size:.86rem; color:var(--muted); }
.fine a{ color:var(--accent); }
code{ font-family:var(--mono); font-size:.9em; color:var(--accent); }
@media(max-width:760px){ .grid-3{ grid-template-columns:1fr; } }

.rv{ opacity:0; transform:translateY(22px); transition:opacity .7s var(--ease), transform .7s var(--ease); }
.rv.in{ opacity:1; transform:none; }

footer{ border-top:1px solid var(--line); padding:2.4rem 0; text-align:center; color:var(--dim); font-family:var(--mono); font-size:.72rem; position:relative; z-index:2; }

@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{ animation-duration:.001ms !important; transition-duration:.001ms !important; }
  .rv{ opacity:1; transform:none; }
}
