:root {
  /* Light theme: Paper & Ember. */
  color-scheme: light;
  --bg: #f7f5f0;
  --ink: #111111;
  --muted: #55514b;
  --glow: #ece5d8;
  --echo: #e7e0d3;
  --accent: #ff5a1f;
  --on-accent: #ffffff; /* text/icons sitting on the accent colour */
  --grain-blend: multiply;
  --grain-opacity: 0.35;
  --grain-filter: none;
  /* Contrast panel (automation): inverted in light mode, a raised surface in dark. */
  --panel-bg: #111111;
  --panel-ink: #f7f5f0;
  --panel-muted: #b9b5ad;
  --panel-line: rgba(247, 245, 240, 0.15);
  --shot-glow: 0.55; /* strength of the accent glow behind product shots */
  --display: "Anton", "Impact", "Arial Narrow", sans-serif;
  --body: "Space Grotesk", system-ui, sans-serif;
  /* How much scrolling the hero spans, in viewport heights. */
  --hero-scroll: 560;
  /* Extra scroll for the lens dive into About (viewport heights). */
  --dive-scroll: 170;
}

/* Dark theme: Midnight & Lime. Follows the system setting unless the visitor
   picked a theme with the toggle (stored as data-theme on <html>). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #0f1012;
    --ink: #f2f0ea;
    --muted: #a8a59e;
    --glow: #1d1f23;
    --echo: #1c1e21;
    --accent: #c8ff3d;
    --on-accent: #0f1012;
    --grain-blend: screen;
    --grain-opacity: 0.14;
    --grain-filter: invert(1);
    --panel-bg: #1a1c1f;
    --panel-ink: #f2f0ea;
    --panel-muted: #a8a59e;
    --panel-line: rgba(242, 240, 234, 0.12);
    --shot-glow: 1;
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0f1012;
  --ink: #f2f0ea;
  --muted: #a8a59e;
  --glow: #1d1f23;
  --echo: #1c1e21;
  --accent: #c8ff3d;
  --on-accent: #0f1012;
  --grain-blend: screen;
  --grain-opacity: 0.14;
  --grain-filter: invert(1);
  --panel-bg: #1a1c1f;
  --panel-ink: #f2f0ea;
  --panel-muted: #a8a59e;
  --panel-line: rgba(242, 240, 234, 0.12);
  --shot-glow: 1;
}

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

html,
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--body);
}

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

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

/* ---------- Pills ---------- */

.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.7em 1.25em;
  border: 1.5px solid var(--ink);
  border-radius: 999px;
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1;
  transition: background-color 0.2s, color 0.2s;
}

.pill:hover {
  background: var(--ink);
  color: var(--bg);
}

.pill--solid {
  background: var(--ink);
  color: var(--bg);
}

.pill--solid:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}

/* Round sun/moon button in the nav. */
.theme-toggle {
  display: inline-grid;
  place-items: center;
  width: 2.6rem;
  height: 2.6rem;
  padding: 0;
  border: 1.5px solid var(--ink);
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 0.2s, color 0.2s, transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.theme-toggle:hover {
  background: var(--ink);
  color: var(--bg);
}

.theme-toggle:active {
  transform: rotate(-30deg) scale(0.92);
}

.theme-toggle:focus-visible,
.pill:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.theme-toggle svg {
  width: 1.1rem;
  height: 1.1rem;
}

/* Show the moon in light mode (switch to dark) and the sun in dark mode. */
.theme-toggle .icon-sun {
  display: none;
}

:root[data-theme="dark"] .theme-toggle .icon-sun {
  display: block;
}

:root[data-theme="dark"] .theme-toggle .icon-moon {
  display: none;
}

/* ---------- Stage ---------- */

/* The section is tall; the stage sticks to the viewport while it scrolls past. */
.hero {
  position: relative;
  z-index: 1;
  height: calc(var(--hero-scroll) * 1svh);
}

.hero__stage {
  --pad: max(20px, 5.5vw);
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
}

/* ---------- Background ---------- */

/* Rows of giant type, a shade darker than the page and out of focus, so they
   read as depth without competing with the real text. JS sets each row's
   horizontal drift. */
.hero__echo {
  position: absolute;
  z-index: 0;
  inset: 0;
  pointer-events: none;
  user-select: none;
  /* Warm glow where the character ends up. */
  background: radial-gradient(ellipse 50% 75% at 76% 55%, var(--glow), transparent 75%);
  /* Fade the background out at the bottom so the hero dissolves into the
     next chapter instead of ending on a hard edge. */
  -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
}

.hero__echo-row {
  position: absolute;
  left: 0;
  margin: 0;
  font-family: var(--display);
  font-size: 33.3svh;
  line-height: 0.86;
  white-space: nowrap;
  color: var(--echo);
  filter: blur(0.02em);
  will-change: transform;
}

.hero__echo-row:nth-child(1) { top: 7%; }
.hero__echo-row:nth-child(2) { top: 40.5%; }
.hero__echo-row:nth-child(3) { top: 74%; }

/* Fine film grain behind the whole page. Content sits above it (z-index 1),
   so the texture runs continuously from the hero through every chapter. */
/* On top of everything (it's a texture, and pointer-events: none), so it
   also covers the opaque layers used by the lens dive and the About stage. */
.grain {
  position: fixed;
  z-index: 90;
  inset: 0;
  pointer-events: none;
  opacity: var(--grain-opacity);
  mix-blend-mode: var(--grain-blend);
  filter: var(--grain-filter);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.45  0 0 0 0 0.42  0 0 0 0 0.38  0 0 0 0.55 0'/></filter><rect width='200' height='200' filter='url(%23n)'/></svg>");
}

/* ---------- Lens dive (hero → About) ---------- */

.has-dive .hero {
  height: calc((var(--hero-scroll) + var(--dive-scroll)) * 1svh);
}

.dive {
  position: absolute;
  z-index: 5;
  inset: 0;
  visibility: hidden;
  pointer-events: none;
}

/* Inside the lens: dark glass with a soft sheen, a diagonal glare and a
   darker rim. */
.dive__glass {
  position: absolute;
  inset: 0;
  opacity: 0;
  background:
    linear-gradient(115deg, transparent 38%, rgba(255, 255, 255, 0.1) 44%, rgba(255, 255, 255, 0.04) 50%, transparent 56%),
    radial-gradient(ellipse 80% 70% at 30% 25%, #2a2b30, #0b0b0d 70%);
  box-shadow: inset 0 0 160px 60px #000;
}

/* The glass clears into the page with a diagonal sheen: JS moves the mask's
   edge across along the glare's angle (--sweep from 0 to 1). */
.dive__page {
  --sweep: 0;
  position: absolute;
  inset: 0;
  background: var(--bg);
  -webkit-mask-image: linear-gradient(115deg, #000 calc(var(--sweep) * 150% - 30%), transparent calc(var(--sweep) * 150% - 10%));
  mask-image: linear-gradient(115deg, #000 calc(var(--sweep) * 150% - 30%), transparent calc(var(--sweep) * 150% - 10%));
}

/* The greeting shared by the dive and About: both use this class, so the
   About section can take over at exactly the same spot. */
.greet {
  --greet-y: 50%;
  position: absolute;
  top: var(--greet-y);
  left: var(--pad);
  margin: 0;
  color: var(--ink);
  font-family: var(--display);
  font-size: clamp(3.5rem, 12.5vw, 14rem);
  font-weight: 400;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
  transform: translateY(-50%);
  transform-origin: 0 50%;
}

@media (max-width: 759px), (max-aspect-ratio: 1/1) {
  .greet {
    --greet-y: 32%;
    font-size: 19vw;
  }
}

/* On the glass the greeting is light; the copy inside .dive__page is in
   page ink and arrives with the sweep. */
.dive__greet {
  opacity: 0;
  color: #f2f0ea;
}



/* ---------- Words ---------- */

/* JS sets font-size (end size) and a transform that carries the line from its
   start position to the intro slot. line-height matches Anton's cap height,
   so the box is exactly the letters. */
.hero__words {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 0;
  height: 0.86em;
  font-family: var(--display);
  font-size: 160px;
  line-height: 0.86;
  letter-spacing: -0.005em;
  transform-origin: 0 0;
  visibility: hidden;
  user-select: none;
  pointer-events: none;
}

.hero__words.is-ready {
  visibility: visible;
}

/* All words share one line; each is clipped to it so letters roll in and out. */
.hero__word {
  position: absolute;
  top: 0;
  left: 0;
  width: max-content;
  margin: 0;
  white-space: nowrap;
  clip-path: inset(-0.03em -0.1em);
}

.hero__char {
  display: inline-block;
  transform: translateY(0);
}

.hero__word.is-before .hero__char {
  transform: translateY(-110%);
}

.hero__word.is-after .hero__char {
  transform: translateY(110%);
}

/* Letters follow each other in, slightly staggered. */
.hero__word.is-moving .hero__char {
  transition: transform 0.7s cubic-bezier(0.65, 0, 0.15, 1);
  transition-delay: calc(var(--i) * 30ms);
}

/* ---------- Character ---------- */

.hero__canvas {
  position: absolute;
  z-index: 2;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
  /* Soften the bottom edge of the figure for the same reason. */
  -webkit-mask-image: linear-gradient(to bottom, #000 86%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 86%, transparent 100%);
}

/* ---------- Intro column ---------- */

/* JS positions the column and sizes the slot the giant word lands in. */
.hero__intro {
  position: absolute;
  z-index: 3;
  top: 0;
  left: var(--pad);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.hero__intro [data-reveal] {
  opacity: 0;
}

.hero__slot {
  width: 100%;
}

.hero__rule {
  display: block;
  width: 48px;
  height: 5px;
  margin: max(16px, calc(var(--word-size, 150px) * 0.2)) 0 max(12px, calc(var(--word-size, 150px) * 0.14));
  background: var(--accent);
}

/* As wide as the big word, so the block has one clean right edge. */
.hero__lede {
  max-width: 100%;
  margin: 0;
  color: var(--muted);
  font-size: clamp(1.0625rem, 1.55vw, 1.5rem);
  line-height: 1.5;
  /* Even line lengths, no single word left on the last line. */
  text-wrap: balance;
}

@media (prefers-reduced-motion: reduce) {
  .hero {
    height: 100svh;
  }

  .hero__word.is-moving .hero__char {
    transition: none;
  }
}

/* ---------- Steady scrolling on phones ----------
   Pinned stages get their own compositing layer, so redrawing what's inside
   them doesn't disturb the page around them; and scroll anchoring is off
   (nothing here needs it, and it can nudge the page mid-scroll). */
html {
  overflow-anchor: none;
}

.has-dive .about__stage,
.has-motion .teach.is-pinned .teach__stage,
.has-motion .voice.is-pinned .voice__stage,
.has-motion .callend__stage,
.has-motion .exp__stage,
.has-motion .contact.is-pinned .ct__stage,
.has-motion .handoff__stage {
  will-change: transform;
}

