@import url('./assets/fonts.css');

/* ==========================================================================
   Design tokens — warm, light, colourful
   ========================================================================== */

:root {
  color-scheme: light;

  /* Surfaces: warm paper rather than clinical white. */
  --paper: #fdf8f3;
  --paper-2: #f7efe6;
  --paper-3: #f1e5d8;
  --card: #ffffff;

  /* Ink */
  --ink: #211a15;
  --ink-2: #5b4f45;
  --ink-3: #8a7b6d;

  /* Accents — each project/section owns one. */
  --coral: #f2604a;
  --amber: #f2a03d;
  --leaf: #3fa87b;
  --sky: #3f8fd4;
  --violet: #7b62d9;
  --rose: #e0577f;
  --teal: #14968a;

  --accent: var(--coral);
  --accent-soft: #fde8e3;

  --line: #e7dacb;
  --line-2: #d6c4b1;

  --sans: 'DM Sans', system-ui, -apple-system, Segoe UI, sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, monospace;
  --serif: 'Instrument Serif', Georgia, 'Times New Roman', serif;

  --gutter: clamp(20px, 5vw, 88px);
  --radius: 18px;
  --radius-lg: 28px;
  --radius-pill: 999px;

  --shadow-sm: 0 1px 2px #4a352314, 0 2px 8px #4a352310;
  --shadow: 0 2px 6px #4a35231a, 0 12px 32px -8px #4a352324;
  --shadow-lg: 0 4px 12px #4a35231f, 0 28px 60px -14px #4a35232e;

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --spring: cubic-bezier(0.34, 1.4, 0.64, 1);

  --header-h: 68px;
}

/* ==========================================================================
   Reset & base
   ========================================================================== */

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

html {
  scroll-behavior: smooth;
  /* Anchor targets clear the sticky header. */
  scroll-padding-top: calc(var(--header-h) + 20px);
  -webkit-text-size-adjust: 100%;
}

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

body.modal-open { overflow: hidden; }

h1, h2, h3, h4, p, figure, blockquote { margin: 0; }

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

button {
  font: inherit;
  color: inherit;
  border: 0;
  background: none;
  cursor: pointer;
}

button, a {
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

:where(button, a, summary, [tabindex]):focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
  border-radius: 6px;
}

img, svg, canvas { max-width: 100%; display: block; }

::selection { background: var(--accent); color: #fff; }

.skip-link {
  position: fixed;
  top: -100px;
  left: var(--gutter);
  z-index: 300;
  padding: 12px 20px;
  background: var(--ink);
  color: var(--paper);
  border-radius: var(--radius-pill);
  font-weight: 600;
  font-size: 14px;
  transition: top 0.2s var(--ease);
}

.skip-link:focus { top: 14px; }

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

/* ==========================================================================
   Shared primitives
   ========================================================================== */

.wrap {
  width: 100%;
  max-width: 1240px;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  position: relative;
  padding-block: clamp(64px, 9vw, 132px);
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 18px;
  font: 600 12px var(--mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
}

.eyebrow::before {
  content: '';
  width: 22px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
}

.section-title {
  max-width: 20ch;
  font-size: clamp(30px, 4.4vw, 52px);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.033em;
  text-wrap: balance;
}

.section-lead {
  max-width: 56ch;
  margin-top: 16px;
  font-size: clamp(15px, 1.4vw, 18px);
  line-height: 1.7;
  color: var(--ink-2);
  text-wrap: pretty;
}

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 50px;
  padding: 13px 26px;
  border-radius: var(--radius-pill);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  transition: transform 0.22s var(--spring), box-shadow 0.22s var(--ease),
              background-color 0.22s var(--ease), color 0.22s var(--ease);
}

.btn svg { width: 17px; height: 17px; flex: none; }

.btn-primary {
  background: var(--ink);
  color: var(--paper);
  box-shadow: var(--shadow);
}

.btn-primary:hover,
.btn-primary:focus-visible {
  background: var(--accent);
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg);
}

.btn-ghost {
  background: transparent;
  color: var(--ink);
  border: 1.5px solid var(--line-2);
}

.btn-ghost:hover,
.btn-ghost:focus-visible {
  border-color: var(--ink);
  background: var(--card);
  transform: translateY(-2px);
  box-shadow: var(--shadow-sm);
}

/* Small pill used for tech tags. Long labels (certifications) must be able to
   wrap, or they force the page into horizontal overflow on narrow screens. */
.tag {
  display: inline-flex;
  align-items: center;
  max-width: 100%;
  padding: 5px 11px;
  border-radius: 14px;
  background: var(--paper-2);
  border: 1px solid var(--line);
  font: 500 12px var(--mono);
  line-height: 1.5;
  letter-spacing: -0.01em;
  color: var(--ink-2);
  overflow-wrap: anywhere;
}

/* ==========================================================================
   Scroll reveal
   ========================================================================== */

/* ==========================================================================
   Motion — choreography for the content

   motion.js only ever writes numbers into custom properties; every transform
   below is composed here. Each property falls back to its resting value, so
   with the script absent (or `prefers-reduced-motion`) this whole section
   evaluates to "no transform, fully opaque" and the page is the static site.

   Entrances are driven per frame and therefore carry no transition. Once an
   element finishes arriving it gets `.is-in`, which switches transitions on so
   that hover states animate without smearing the entrance.
   ========================================================================== */

.reveal {
  --e: var(--enter, 1);
  opacity: var(--e);
  transform: translate3d(0, calc((1 - var(--e)) * 34px), 0);
}

.reveal.is-in {
  transition: opacity 0.4s var(--ease), transform 0.45s var(--ease);
}

/* --- Headings: uncovered a word at a time ------------------------------- */

.w {
  display: inline-block;
  overflow: hidden;
  /* Room for descenders, taken back out of the layout. */
  padding-bottom: 0.14em;
  margin-bottom: -0.14em;
}

.wi {
  display: inline-block;
  /* Each word trails the one before it, then catches up. */
  --we: clamp(0, calc((var(--e, 1) - var(--wi, 0) * 0.055) * 2.6), 1);
  transform: translate3d(0, calc((1 - var(--we)) * 110%), 0);
}

/* --- Chips: each lands just after the one before it --------------------- */

.motion-on :is(.project-tags, .chapter-facts, .tool-tags, .certs) .tag {
  --te: clamp(0, calc((var(--e, 1) - 0.3 - var(--i, 0) * 0.05) * 3.4), 1);
  opacity: var(--te);
  transform:
    translate3d(0, calc((1 - var(--te)) * 12px), 0)
    scale(calc(0.88 + var(--te) * 0.12));
}

/* --- The figures in Proof rise inside their own mask -------------------- */

.stat-value {
  overflow: hidden;
  padding-bottom: 0.08em;
  margin-bottom: -0.08em;
}

.stat-value > span { display: block; }

.motion-on .stat-value > span {
  --ve: clamp(0, calc((var(--e, 1) - 0.25) * 3), 1);
  transform: translate3d(0, calc((1 - var(--ve)) * 118%), 0);
}

/* --- The rule before each eyebrow draws itself -------------------------- */

.motion-on .eyebrow::before {
  transform-origin: left center;
  transform: scaleX(clamp(0, calc((var(--e, 1) - 0.1) * 2.4), 1));
}

/* --- The project number drifts against its own row --------------------- */

.motion-on .project-index {
  display: inline-block;
  transform: translate3d(0, calc((var(--p, 0.5) - 0.5) * -14px), 0);
}

/* --- Project rows: rise, and grow into their own edges ------------------ */

.motion-on .project {
  transform: translate3d(0, calc((1 - var(--e)) * 62px + var(--lift, 0px)), 0);
}

/* The wipe only applies on the way in. Left on afterwards it would clip the
   card's own drop shadow away. */
.motion-on .project:not(.is-in) {
  clip-path: inset(0 0 calc((1 - var(--e)) * 36%) 0 round var(--radius-lg));
}

/* --- Toolbox and stats: gathered at one point, then spread -------------- */

.motion-on .tool-card,
.motion-on .stat {
  transform:
    translate3d(
      calc((1 - var(--e)) * var(--sx, 0) * 1px),
      calc((1 - var(--e)) * var(--sy, 0) * 1px + var(--lift, 0px)),
      0
    )
    rotate(calc((1 - var(--e)) * var(--rot, 0) * 1deg))
    scale(calc(0.84 + var(--e) * 0.16));
}

/* --- Journey: the spine draws itself, the dots land on it --------------- */

.motion-on .timeline::before {
  transform-origin: top center;
  transform: scaleY(var(--draw, 1));
}

/* The chapters travel sideways into place. A full-width card sliding in from
   the right widens the page while it moves, so the travel is clipped at the
   timeline — `clip` rather than `hidden`, which would make this a scroll
   container and trap the spine. */
.motion-on .timeline { overflow-x: clip; }

.motion-on .chapter {
  opacity: var(--e);
  transform: translate3d(calc((1 - var(--e)) * 40px), 0, 0);
}

.motion-on .chapter-dot {
  transform: scale(calc(0.34 + var(--e) * 0.66));
}

/* --- The diagram beside each project leans, and drifts ------------------ */

.motion-on .project-visual {
  transform: translate3d(0, calc((var(--p, 0.5) - 0.5) * -22px), 0);
}

.motion-on .project-visual svg {
  transform:
    perspective(700px)
    rotateX(calc(var(--tx, 0) * 1deg))
    rotateY(calc(var(--ty, 0) * 1deg));
  transition: transform 0.5s var(--ease);
}

/* --- Scroll velocity: the capability strip leans into the movement ------ */

.motion-on .marquee span {
  transform: skewX(calc(var(--vel, 0) * -2.4deg));
}

/* --- The opening sequence ----------------------------------------------- */

.hero h1 .line {
  display: block;
  overflow: hidden;
  padding-bottom: 0.12em;
  margin-bottom: -0.12em;
}

.hero h1 .line-i { display: block; }

.motion-on .hero h1 .line-i { transform: translate3d(0, 112%, 0); }

.motion-on .hero-copy > .status,
.motion-on .hero-copy > .hero-lead,
.motion-on .hero-copy > .hero-actions,
.motion-on .hero-copy > .hero-meta,
.motion-on .stage-badge {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
}

.intro-ready .hero h1 .line-i {
  animation: line-up 1s var(--ease) forwards;
  animation-delay: calc(var(--i, 0) * 120ms + 100ms);
}

.intro-ready .hero-copy > .status,
.intro-ready .hero-copy > .hero-lead,
.intro-ready .hero-copy > .hero-actions,
.intro-ready .hero-copy > .hero-meta,
.intro-ready .stage-badge {
  animation: intro-rise 0.85s var(--ease) forwards;
}

.intro-ready .hero-copy > .status      { animation-delay: 60ms; }
.intro-ready .hero-copy > .hero-lead   { animation-delay: 420ms; }
.intro-ready .hero-copy > .hero-actions{ animation-delay: 520ms; }
.intro-ready .hero-copy > .hero-meta   { animation-delay: 620ms; }
.intro-ready .stage-badge              { animation-delay: 760ms; }

@keyframes line-up {
  to { transform: translate3d(0, 0, 0); }
}

@keyframes intro-rise {
  to { opacity: 1; transform: translate3d(0, 0, 0); }
}

/* ==========================================================================
   Header
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  height: var(--header-h);
  display: flex;
  align-items: center;
  background: #fdf8f3d9;
  backdrop-filter: saturate(1.6) blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s var(--ease), background-color 0.3s var(--ease);
}

.site-header.stuck {
  border-bottom-color: var(--line);
  background: #fdf8f3f2;
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  width: 100%;
  max-width: 1240px;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  font-weight: 600;
  letter-spacing: -0.02em;
  white-space: nowrap;
}

.brand-mark {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 11px;
  background: linear-gradient(135deg, var(--coral), var(--amber));
  color: #fff;
  font: 700 14px var(--sans);
  letter-spacing: -0.03em;
  box-shadow: var(--shadow-sm);
}

.nav {
  display: flex;
  align-items: center;
  gap: 4px;
}

.nav a {
  position: relative;
  padding: 9px 14px;
  border-radius: var(--radius-pill);
  font-size: 14.5px;
  font-weight: 500;
  color: var(--ink-2);
  transition: color 0.2s, background-color 0.2s;
}

.nav a:hover { color: var(--ink); background: var(--paper-2); }
.nav a[aria-current='true'] { color: var(--ink); font-weight: 600; }

/* Shown only inside the mobile menu sheet, where the header buttons are gone. */
.nav-only { display: none; }

.header-cta { display: flex; align-items: center; gap: 10px; }
.header-cta .btn { min-height: 42px; padding: 9px 20px; font-size: 14px; }

.nav-toggle {
  display: none;
  width: 42px;
  height: 42px;
  border-radius: 12px;
  place-items: center;
  border: 1px solid var(--line-2);
}

.nav-toggle svg { width: 20px; height: 20px; }

/* ==========================================================================
   Hero
   ========================================================================== */

.hero {
  position: relative;
  padding-block: clamp(40px, 7vw, 84px) clamp(56px, 8vw, 104px);
  overflow: hidden;
}

/* Soft colour wash behind the hero. */
.hero::before {
  content: '';
  position: absolute;
  inset: -30% -10% auto;
  height: 130%;
  z-index: -1;
  background:
    radial-gradient(48% 42% at 18% 26%, #f2604a24, transparent 70%),
    radial-gradient(44% 40% at 82% 18%, #3f8fd422, transparent 70%),
    radial-gradient(40% 46% at 62% 76%, #f2a03d22, transparent 72%);
  pointer-events: none;
}

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  align-items: center;
  gap: clamp(28px, 5vw, 68px);
}

.status {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 22px;
  padding: 7px 15px 7px 11px;
  border-radius: var(--radius-pill);
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink-2);
}

.status-dot {
  position: relative;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--leaf);
}

.status-dot::after {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 2px solid var(--leaf);
  opacity: 0;
  animation: ping 2.4s var(--ease) infinite;
}

@keyframes ping {
  0% { transform: scale(0.6); opacity: 0.8; }
  70%, 100% { transform: scale(1.5); opacity: 0; }
}

.hero h1 {
  font-size: clamp(34px, 4.9vw, 60px);
  font-weight: 600;
  line-height: 1.04;
  letter-spacing: -0.04em;
  text-wrap: balance;
}

/* Animated gradient sweep on the highlighted phrase. */
.hero h1 .grad {
  background: linear-gradient(100deg, var(--coral), var(--amber) 34%, var(--rose) 68%, var(--coral));
  background-size: 260% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: sweep 9s linear infinite;
}

@keyframes sweep {
  to { background-position: 260% 0; }
}

.hero-lead {
  max-width: 46ch;
  margin-top: 22px;
  font-size: clamp(16px, 1.55vw, 19px);
  line-height: 1.68;
  color: var(--ink-2);
  text-wrap: pretty;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 30px;
}

.hero-meta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 16px 24px;
  margin-top: 34px;
  padding-top: 26px;
  border-top: 1px solid var(--line);
}

.hero-meta div { min-width: 0; }

.hero-meta dt {
  font: 600 11px var(--mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.hero-meta dd {
  margin: 4px 0 0;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.015em;
}

/* --- Hero 3D stage --- */

.hero-stage {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background:
    radial-gradient(70% 70% at 50% 40%, #fff 0%, var(--paper-2) 62%, var(--paper-3) 100%);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-lg);
}

/* Static SVG shown when WebGL is unavailable or motion is reduced. */
.hero-fallback {
  position: absolute;
  inset: 0;
  display: none;
  place-items: center;
  padding: 12%;
}

.no-webgl .hero-fallback { display: grid; }

/* ==========================================================================
   The world — one fixed canvas behind the whole document

   The page scrolls over it normally: no wheel handler, no scroll-jacking, and
   no pointer events on the canvas itself. With `.world-on` absent, every rule
   here is inert and the site is exactly the flat version it has always been.
   ========================================================================== */

#world {
  position: fixed;
  inset: 0;
  z-index: 0;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Content rides above the canvas. The header already sits at z-index 100. */
.world-on main,
.world-on .site-footer {
  position: relative;
  z-index: 1;
}

/* Let the world through where the page used to paint solid panels. */
.world-on .hero::before { opacity: 0.5; }

.world-on .hero-stage {
  background: none;
  border-color: transparent;
  box-shadow: none;
}

.world-on .strip { background: #f7efe6cc; }

/* Over a continuous shot a solid
   edge reads as a seam — the world is vivid on one side of it and washed on the
   other — so the veil fades in and out instead of starting hard. */
.world-on .journey,
.world-on .research,
.world-on .proof {
  background: linear-gradient(
    to bottom,
    #f7efe600 0%,
    #f7efe6de 9%,
    #f7efe6de 91%,
    #f7efe600 100%
  );
}

.stage-badge {
  position: absolute;
  left: 16px;
  bottom: 16px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-radius: var(--radius-pill);
  background: #fffffff0;
  border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
  font: 500 12px var(--mono);
  color: var(--ink-2);
}

/* ==========================================================================
   Marquee strip
   ========================================================================== */

.strip {
  padding-block: 18px;
  border-block: 1px solid var(--line);
  background: var(--paper-2);
  overflow: hidden;
}

.marquee {
  display: flex;
  width: max-content;
  gap: 44px;
  animation: marquee 34s linear infinite;
}

.strip:hover .marquee { animation-play-state: paused; }

.marquee span {
  display: inline-flex;
  align-items: center;
  gap: 44px;
  font: 500 14px var(--mono);
  letter-spacing: 0.02em;
  color: var(--ink-3);
  white-space: nowrap;
}

.marquee span::after {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0.55;
}

@keyframes marquee {
  to { transform: translateX(-50%); }
}

/* ==========================================================================
   Work
   ========================================================================== */

.work { background: var(--paper); }

.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
  margin-bottom: clamp(30px, 4vw, 52px);
}

.work-list {
  display: grid;
  gap: clamp(16px, 2vw, 22px);
}

.project {
  --tint: var(--sky);
  --tint-soft: #eaf2fb;
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.82fr);
  align-items: stretch;
  gap: clamp(20px, 3vw, 44px);
  padding: clamp(22px, 2.6vw, 38px);
  border-radius: var(--radius-lg);
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease),
              border-color 0.35s var(--ease);
}

.project::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 4px;
  background: var(--tint);
  opacity: 0;
  transition: opacity 0.35s var(--ease);
}

/* The lift is a variable rather than a transform of its own, so it composes
   with the entrance instead of replacing it. */
.project:hover,
.project:focus-within {
  --lift: -6px;
  border-color: var(--tint);
  box-shadow: var(--shadow-lg);
}

.project:hover::before,
.project:focus-within::before { opacity: 1; }

.project.tone-sky    { --tint: var(--sky);    --tint-soft: #eaf2fb; }
.project.tone-violet { --tint: var(--violet); --tint-soft: #efecfb; }
.project.tone-leaf   { --tint: var(--leaf);   --tint-soft: #e6f5ef; }
.project.tone-coral  { --tint: var(--coral);  --tint-soft: #fdeae6; }
.project.tone-amber  { --tint: var(--amber);  --tint-soft: #fdf1e0; }
.project.tone-teal   { --tint: var(--teal);   --tint-soft: #e2f4f1; }

.project-body { display: flex; flex-direction: column; min-width: 0; }

.project-top {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}

.project-index {
  font: 600 12px var(--mono);
  color: var(--tint);
  letter-spacing: 0.06em;
}

.project-year {
  margin-left: auto;
  padding: 4px 11px;
  border-radius: var(--radius-pill);
  background: var(--tint-soft);
  color: var(--tint);
  font: 600 11.5px var(--mono);
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.project h3 {
  font-size: clamp(23px, 2.5vw, 31px);
  font-weight: 600;
  letter-spacing: -0.028em;
  line-height: 1.14;
}

.project-role {
  margin-top: 5px;
  font: 500 12.5px var(--mono);
  letter-spacing: 0.03em;
  color: var(--ink-3);
  text-transform: uppercase;
}

.project-question {
  margin-top: 16px;
  font-size: clamp(16px, 1.5vw, 19px);
  font-weight: 500;
  line-height: 1.45;
  letter-spacing: -0.018em;
  color: var(--tint);
  text-wrap: pretty;
}

.project-desc {
  margin-top: 12px;
  font-size: 15px;
  line-height: 1.72;
  color: var(--ink-2);
  text-wrap: pretty;
}

.project-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 18px;
}

.project-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: auto;
  padding-top: 22px;
}

.project-actions .btn { min-height: 44px; padding: 10px 20px; font-size: 14px; }

/* Architecture diagram panel */
.project-visual {
  display: grid;
  place-items: center;
  min-height: 208px;
  padding: 20px;
  border-radius: var(--radius);
  background:
    radial-gradient(120% 100% at 50% 0%, var(--tint-soft), var(--paper-2));
  border: 1px solid var(--line);
}

.project-visual svg { width: 100%; height: auto; }

/* --- Live products ------------------------------------------------------ */

/* A live project gives the screenshot more of the row than a diagram gets. */
.project.is-live { grid-template-columns: minmax(0, 0.92fr) minmax(0, 1fr); }

.live-dot {
  position: relative;
  width: 7px;
  height: 7px;
  flex: none;
  border-radius: 50%;
  background: #22b573;
}

.live-dot::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: inherit;
  animation: live-ping 1.8s var(--ease) infinite;
}

@keyframes live-ping {
  to { transform: scale(2.8); opacity: 0; }
}

.project-live {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 11px 4px 10px;
  border-radius: var(--radius-pill);
  background: #e7f6ee;
  color: #17824f;
  font: 600 11.5px var(--mono);
  letter-spacing: 0.03em;
  white-space: nowrap;
}

/* Numbers read off the deployment, set large so they land before the prose. */
.project-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(104px, 1fr));
  gap: 1px;
  margin-top: 20px;
  border-radius: 14px;
  overflow: hidden;
  background: var(--line);
  border: 1px solid var(--line);
}

.project-stats > div {
  display: flex;
  flex-direction: column-reverse;
  justify-content: flex-end;
  align-items: flex-start;
  gap: 2px;
  min-width: 0;
  padding: 12px 14px;
  background: var(--card);
}

.project-stats dd {
  font-size: clamp(19px, 1.8vw, 23px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.1;
  color: var(--tint);
  font-variant-numeric: tabular-nums;
  margin: 0;
  white-space: nowrap;
}

.project-stats dt {
  font: 500 11px var(--mono);
  letter-spacing: 0.03em;
  color: var(--ink-3);
  text-transform: uppercase;
}

/* The screenshot panel: a browser window in front, a second view behind it. */
.project-visual--shot {
  position: relative;
  display: block;
  min-height: 0;
  padding: clamp(18px, 2.4vw, 30px) clamp(16px, 2vw, 26px) 0;
  overflow: hidden;
  align-self: stretch;
  isolation: isolate;
}

.project-visual--shot::after {
  /* Fades the window's lower edge into the panel, as if it continues below. */
  content: '';
  position: absolute;
  inset: auto 0 0;
  height: 26%;
  z-index: 2;
  background: linear-gradient(transparent, var(--paper-2));
  pointer-events: none;
}

.shot {
  position: relative;
  z-index: 1;
  border-radius: 12px;
  overflow: hidden;
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: 0 2px 6px #4a352314, 0 24px 50px -18px #4a352347;
}

.shot-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 30px;
  padding: 0 10px;
  background: #f5f0ea;
  border-bottom: 1px solid var(--line);
}

.shot-dots { display: flex; gap: 5px; flex: none; }
.shot-dots i { width: 8px; height: 8px; border-radius: 50%; background: #e4d9cd; }
.shot-dots i:first-child { background: #f2786a; }
.shot-dots i:nth-child(2) { background: #f2bf4a; }
.shot-dots i:nth-child(3) { background: #55c27a; }

.shot-url {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
  margin: 0 auto;
  padding: 3px 12px;
  border-radius: var(--radius-pill);
  background: var(--card);
  border: 1px solid var(--line);
  font: 500 11px var(--mono);
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.shot-url svg { width: 11px; height: 11px; flex: none; color: #17824f; }

.live-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: none;
  font: 600 10.5px var(--mono);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #17824f;
}

.shot img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  object-position: top center;
}

.project-visual--shot > .shot:first-child {
  transition: transform 0.6s var(--ease);
  transform-origin: 50% 100%;
}

.shot-back {
  position: absolute;
  z-index: 0;
  top: 54%;
  right: -14%;
  width: 62%;
  transform: rotate(-4deg);
  opacity: 0.95;
  transition: transform 0.6s var(--ease);
}

.project:hover .project-visual--shot > .shot:first-child {
  transform: translateY(-6px) scale(1.015);
}

.project:hover .shot-back { transform: rotate(-2deg) translate(-8%, -16%); }

.motion-on .project-visual--shot > .shot:first-child {
  transform:
    perspective(900px)
    rotateX(calc(var(--tx, 0) * 0.6deg))
    rotateY(calc(var(--ty, 0) * 0.6deg));
}

.motion-on .project:hover .project-visual--shot > .shot:first-child {
  transform:
    perspective(900px)
    rotateX(calc(var(--tx, 0) * 0.6deg))
    rotateY(calc(var(--ty, 0) * 0.6deg))
    translateY(-6px) scale(1.015);
}

.btn-live svg { width: 15px; height: 15px; }

/* Case study: live link, screenshots, stats */
.sheet-live {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 16px;
  margin-top: 20px;
}

.sheet-host { font: 500 12.5px var(--mono); color: var(--ink-3); }

.sheet-gallery {
  display: grid;
  gap: 14px;
  margin-top: 22px;
}

.sheet-gallery.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }

.sheet-stats { margin-top: 18px; }

@media (prefers-reduced-motion: reduce) {
  .live-dot::after { animation: none; }
}

@media (max-width: 420px) {
  .shot-dots,
  .shot .live-pill { display: none; }
  .project-visual--shot { padding: 12px 12px 12px; }
}

@media (max-width: 640px) {
  .sheet-gallery.two { grid-template-columns: 1fr; }
  .shot-back { display: none; }
  .project-visual--shot { padding-bottom: clamp(16px, 4vw, 22px); }
  .project-visual--shot::after { display: none; }
}

/* ==========================================================================
   Research — each paper is a cover and a page
   ========================================================================== */

.research { background: var(--paper); }

.paper-list {
  display: grid;
  gap: clamp(28px, 4vw, 48px);
}

.paper {
  --tint: var(--amber);
  --tint-soft: #fdf1e0;
  display: grid;
  grid-template-columns: minmax(0, 0.6fr) minmax(0, 1.4fr);
  border-radius: var(--radius-lg);
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: box-shadow 0.35s var(--ease), border-color 0.35s var(--ease);
}

.paper:hover,
.paper:focus-within { border-color: var(--tint); box-shadow: var(--shadow-lg); }

.paper.tone-amber { --tint: #d9861f; --tint-soft: #fdf1e0; }
.paper.tone-coral { --tint: var(--coral); --tint-soft: #fdeae6; }

.paper-cover {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: clamp(22px, 2.6vw, 34px);
  background:
    radial-gradient(130% 90% at 0% 0%, var(--tint-soft), transparent 70%),
    var(--paper-2);
  border-right: 1px solid var(--line);
}

.paper-badges { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }

.paper-ieee {
  padding: 4px 9px;
  border-radius: 6px;
  background: #00629b;
  color: #fff;
  font: 700 12px var(--sans);
  letter-spacing: 0.08em;
}

.paper-kind {
  font: 600 11px var(--mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.paper-diagram {
  display: grid;
  place-items: center;
  flex: 1;
  min-height: 150px;
  padding: 8px 0;
}

.paper-diagram svg { width: 100%; max-width: 340px; height: auto; }

.paper-venue-big {
  font: 400 clamp(34px, 4vw, 48px)/1 var(--serif);
  letter-spacing: -0.01em;
  color: var(--tint);
}

.paper-venue-full {
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink-2);
  text-wrap: pretty;
}

.paper-body {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: clamp(24px, 3.5vw, 48px);
}

.paper-q {
  font-size: 15px;
  line-height: 1.65;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--tint);
}

.paper-title {
  margin-top: 18px;
  font: 500 clamp(23px, 2.2vw, 30px)/1.4 var(--sans);
  letter-spacing: -0.02em;
  text-wrap: pretty;
}

.paper-title a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: transparent;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 5px;
  transition: text-decoration-color 0.25s var(--ease);
}

.paper-title a:hover { text-decoration-color: var(--tint); }

.paper-authors {
  margin-top: 20px;
  font-size: 14px;
  line-height: 1.85;
  color: var(--ink-3);
}

.paper-authors span + span::before { content: ', '; color: var(--ink-3); font-weight: 400; }

.paper-authors .me {
  color: var(--ink);
  font-weight: 600;
  background: linear-gradient(transparent 62%, var(--tint-soft) 62%);
}

.paper-abstract {
  margin-top: 28px;
  font-size: 16px;
  line-height: 1.85;
  color: var(--ink-2);
  text-wrap: pretty;
}

.paper-points {
  display: grid;
  gap: 14px;
  margin: 24px 0 0;
  padding: 0;
  list-style: none;
}

.paper-points li {
  display: flex;
  gap: 10px;
  font-size: 14.5px;
  line-height: 1.75;
  color: var(--ink-2);
}

.paper-points svg {
  flex: none;
  width: 15px;
  height: 15px;
  margin-top: 3px;
  color: var(--tint);
}

.paper-meta {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
  margin: 32px 0 0;
  padding-top: 28px;
  border-top: 1px dashed var(--line);
}

.paper-meta dt {
  font: 600 10.5px var(--mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.paper-meta dd {
  margin: 8px 0 0;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink);
}

.paper-doi { grid-column: 1 / -1; }
.paper .project-tags { margin-top: 28px; gap: 10px; }

.paper-doi dd a {
  font: 500 12.5px var(--mono);
  color: var(--ink);
  overflow-wrap: anywhere;
  text-decoration: underline;
  text-decoration-color: var(--line);
  text-underline-offset: 3px;
}

.paper-doi dd a:hover { text-decoration-color: var(--tint); }

.paper-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: auto;
  padding-top: 32px;
}

.paper-actions .btn { min-height: 42px; padding: 9px 18px; font-size: 14px; }
.paper-actions .btn svg { width: 15px; height: 15px; }
.btn-cite.is-done { border-color: #22b573; color: #17824f; }

.hero-meta dd a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--line);
  text-underline-offset: 4px;
}

.hero-meta dd a:hover { text-decoration-color: var(--accent); }

@media (max-width: 900px) {
  .paper { grid-template-columns: 1fr; }
  .paper-cover { border-right: 0; border-bottom: 1px solid var(--line); }
  .paper-diagram { min-height: 0; }
  .paper-diagram svg { max-width: 300px; }
  .paper-meta { grid-template-columns: repeat(3, auto); }
  .paper-doi { grid-column: 1 / -1; }
}

@media (max-width: 480px) {
  .paper-meta { grid-template-columns: 1fr 1fr; }
  .paper-actions .btn { flex: 1 1 auto; justify-content: center; }
}

/* ==========================================================================
   Animated architecture diagrams (inline SVG)
   ========================================================================== */

.diagram { --stroke: var(--tint); }

.diagram .node {
  fill: #fff;
  stroke: var(--stroke);
  stroke-width: 1.6;
}

.diagram .node-label {
  font: 600 8.5px var(--mono);
  fill: var(--ink-2);
  letter-spacing: 0.02em;
  text-anchor: middle;
}

.diagram .wire {
  fill: none;
  stroke: var(--stroke);
  stroke-width: 1.4;
  stroke-opacity: 0.42;
  stroke-linecap: round;
}

/* A packet travelling the wire, drawn with a dash that walks the path. */
.diagram .pulse {
  fill: none;
  stroke: var(--stroke);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-dasharray: 14 190;
  animation: flow 2.6s linear infinite;
  animation-delay: var(--d, 0s);
}

@keyframes flow {
  to { stroke-dashoffset: -204; }
}

.diagram .halo {
  fill: var(--stroke);
  opacity: 0.12;
  transform-origin: center;
  animation: breathe 3.4s var(--ease) infinite;
}

@keyframes breathe {
  50% { opacity: 0.24; transform: scale(1.08); }
}

/* ==========================================================================
   Journey — the story, condensed
   ========================================================================== */

.journey { background: var(--paper-2); }

.timeline {
  position: relative;
  display: grid;
  gap: clamp(20px, 2.6vw, 34px);
  margin-top: clamp(30px, 4vw, 50px);
}

/* The spine. */
.timeline::before {
  content: '';
  position: absolute;
  top: 12px;
  bottom: 12px;
  left: 19px;
  width: 2px;
  border-radius: 2px;
  background: linear-gradient(var(--coral), var(--amber), var(--leaf), var(--sky), var(--violet));
  opacity: 0.35;
}

.chapter {
  position: relative;
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr);
  align-items: start;
  gap: clamp(16px, 2.4vw, 30px);
}

.chapter-dot {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--card);
  border: 2px solid var(--tone, var(--coral));
  color: var(--tone, var(--coral));
  font: 700 13px var(--mono);
  box-shadow: var(--shadow-sm);
}

.chapter-card {
  padding: clamp(18px, 2.2vw, 28px);
  border-radius: var(--radius);
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
}

.chapter-card:hover {
  transform: translateX(4px);
  box-shadow: var(--shadow);
}

.chapter-era {
  font: 600 11.5px var(--mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--tone, var(--coral));
}

.chapter-card h3 {
  margin-top: 8px;
  font-size: clamp(20px, 2.2vw, 27px);
  font-weight: 600;
  letter-spacing: -0.026em;
  line-height: 1.16;
}

.chapter-card p {
  margin-top: 10px;
  max-width: 62ch;
  font-size: 15px;
  line-height: 1.72;
  color: var(--ink-2);
  text-wrap: pretty;
}

.chapter-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 14px;
}

/* ==========================================================================
   Toolbox
   ========================================================================== */

.toolbox-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(248px, 1fr));
  gap: clamp(14px, 1.8vw, 20px);
  margin-top: clamp(28px, 3.6vw, 46px);
}

.tool-card {
  position: relative;
  padding: clamp(20px, 2.2vw, 28px);
  border-radius: var(--radius);
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease),
              border-color 0.3s var(--ease);
}

.tool-card::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 3px;
  background: var(--tone);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.4s var(--ease);
}

.tool-card:hover {
  --lift: -6px;
  border-color: var(--tone);
  box-shadow: var(--shadow);
}

.tool-card:hover::after { transform: scaleX(1); }

.tool-icon {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-bottom: 16px;
  border-radius: 13px;
  background: color-mix(in srgb, var(--tone) 12%, #fff);
  color: var(--tone);
}

.tool-icon svg { width: 22px; height: 22px; }

.tool-card h3 {
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.022em;
}

.tool-card .tool-line {
  margin-top: 6px;
  font-size: 14.5px;
  font-weight: 500;
  color: var(--tone);
}

.tool-card p {
  margin-top: 10px;
  font-size: 14px;
  line-height: 1.7;
  color: var(--ink-2);
}

.tool-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 16px;
}

/* ==========================================================================
   Proof / stats
   ========================================================================== */

.proof { background: var(--paper-2); }

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: clamp(14px, 1.8vw, 20px);
  margin-top: clamp(28px, 3.6vw, 46px);
}

.stat {
  padding: clamp(20px, 2.2vw, 28px);
  border-radius: var(--radius);
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
}

.stat-value {
  font-size: clamp(30px, 3.6vw, 44px);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--tone);
}

.stat h3 {
  margin-top: 12px;
  font-size: 15.5px;
  font-weight: 600;
  letter-spacing: -0.015em;
}

/* The figure is also a <p>, and this rule used to win on specificity and shrink
   it back to detail-text size. Name the detail paragraphs instead. */
.stat p:not(.stat-value) {
  margin-top: 4px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-3);
}

.certs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 26px;
}

/* ==========================================================================
   Contact
   ========================================================================== */

.contact-card {
  position: relative;
  padding: clamp(32px, 5vw, 72px);
  border-radius: var(--radius-lg);
  background: linear-gradient(140deg, #241c16, #3a2a20 52%, #4a3122);
  color: var(--paper);
  overflow: hidden;
  box-shadow: var(--shadow-lg);
}

.contact-card::before {
  content: '';
  position: absolute;
  inset: -40% -20% auto;
  height: 150%;
  background:
    radial-gradient(38% 42% at 22% 28%, #f2604a4d, transparent 68%),
    radial-gradient(34% 40% at 78% 22%, #f2a03d3d, transparent 68%);
  pointer-events: none;
}

.contact-inner { position: relative; }

.contact-card h2 {
  max-width: 18ch;
  font-size: clamp(29px, 4.6vw, 54px);
  font-weight: 600;
  line-height: 1.06;
  letter-spacing: -0.036em;
  text-wrap: balance;
}

.contact-card p {
  max-width: 52ch;
  margin-top: 16px;
  font-size: clamp(15px, 1.4vw, 18px);
  line-height: 1.7;
  color: #e8dcd0;
}

.contact-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 32px;
}

.contact-card .btn-primary {
  background: var(--paper);
  color: var(--ink);
}

.contact-card .btn-primary:hover {
  background: var(--amber);
  color: #241c16;
}

.contact-card .btn-ghost {
  color: var(--paper);
  border-color: #ffffff40;
}

.contact-card .btn-ghost:hover {
  background: #ffffff14;
  border-color: var(--paper);
  color: var(--paper);
}

.contact-links {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 26px;
  margin-top: 34px;
  padding-top: 26px;
  border-top: 1px solid #ffffff26;
}

.contact-links a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  font: 500 14px var(--mono);
  color: #e0d2c4;
  transition: color 0.2s;
}

.contact-links a:hover { color: var(--amber); }
.contact-links svg { width: 16px; height: 16px; }

/* ==========================================================================
   Footer
   ========================================================================== */

.site-footer {
  padding-block: 34px 40px;
  border-top: 1px solid var(--line);
}

.footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  font-size: 14px;
  color: var(--ink-3);
}

.footer-inner a { color: var(--ink-2); font-weight: 500; }
.footer-inner a:hover { color: var(--accent); }

/* ==========================================================================
   Project dialog
   ========================================================================== */

dialog {
  padding: 0;
  border: 0;
  background: transparent;
  max-width: none;
  max-height: none;
}

dialog::backdrop {
  background: #241c16b8;
  backdrop-filter: blur(6px);
  animation: fade 0.3s var(--ease);
}

@keyframes fade { from { opacity: 0; } }

.sheet {
  width: min(820px, calc(100vw - 28px));
  max-height: min(88svh, 900px);
  margin: auto;
  overflow: auto;
  border-radius: var(--radius-lg);
  background: var(--paper);
  box-shadow: var(--shadow-lg);
  animation: sheet-in 0.36s var(--spring);
}

@keyframes sheet-in {
  from { opacity: 0; transform: translateY(20px) scale(0.98); }
}

.sheet-top {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 16px clamp(20px, 3vw, 34px);
  background: #fdf8f3f2;
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}

.sheet-top strong {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.sheet-close {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--paper-2);
  border: 1px solid var(--line);
  transition: background-color 0.2s, transform 0.2s var(--spring);
}

.sheet-close:hover { background: var(--paper-3); transform: rotate(90deg); }
.sheet-close svg { width: 17px; height: 17px; }

.sheet-body { padding: clamp(22px, 3vw, 38px); }

.sheet-body h2 {
  font-size: clamp(26px, 3.4vw, 38px);
  font-weight: 600;
  letter-spacing: -0.032em;
  line-height: 1.1;
}

.sheet-q {
  margin-top: 14px;
  font-size: clamp(17px, 1.8vw, 21px);
  font-weight: 500;
  line-height: 1.42;
  letter-spacing: -0.02em;
  color: var(--tint, var(--accent));
  text-wrap: pretty;
}

.sheet-flow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 24px 0;
  padding: 18px;
  border-radius: var(--radius);
  background: var(--paper-2);
  border: 1px solid var(--line);
}

.sheet-flow span {
  padding: 7px 13px;
  border-radius: var(--radius-pill);
  background: var(--card);
  border: 1px solid var(--line);
  font: 500 12.5px var(--mono);
  white-space: nowrap;
}

.sheet-flow i {
  color: var(--tint, var(--accent));
  font-style: normal;
  font-weight: 700;
}

.sheet-section { margin-top: 24px; }

.sheet-section h3 {
  margin-bottom: 9px;
  font: 600 11.5px var(--mono);
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.sheet-section p {
  font-size: 15px;
  line-height: 1.76;
  color: var(--ink-2);
  text-wrap: pretty;
}

.sheet-note {
  margin-top: 26px;
  padding: 16px 18px;
  border-radius: var(--radius);
  border-left: 3px solid var(--tint, var(--accent));
  background: var(--paper-2);
  font-size: 14.5px;
  line-height: 1.7;
  color: var(--ink-2);
}

/* ==========================================================================
   Responsive
   ========================================================================== */

@media (max-width: 900px) {
  /* Keep the mobile scene inside the hero visual. The boundary follows the
     actual copy position as the page scrolls, so no particles reach the text. */
  #world {
    -webkit-mask-image: linear-gradient(to bottom, #000 0, #000 var(--world-fade-start, 0px), transparent var(--world-fade-end, 0px));
    mask-image: linear-gradient(to bottom, #000 0, #000 var(--world-fade-start, 0px), transparent var(--world-fade-end, 0px));
  }

  /* Fixed fade lengths finish inside the section padding. Percentage fades
     stretched behind headings when stacked mobile content made sections tall. */
  .world-on .research,
  .world-on .journey,
  .world-on .toolbox,
  .world-on .proof {
    background: linear-gradient(
      to bottom,
      #f7efe600 0,
      #f7efe6de 32px,
      #f7efe6de calc(100% - 32px),
      #f7efe600 100%
    );
  }
}

@media (max-width: 980px) {
  .hero-grid { grid-template-columns: 1fr; }

  .hero-stage {
    order: -1;
    aspect-ratio: 16 / 11;
    max-height: 46svh;
  }

  .project,
  .project.is-live { grid-template-columns: 1fr; }
  .project-visual { min-height: 168px; order: -1; }
}

@media (max-width: 980px) {
  .nav,
  .header-cta .btn-ghost { display: none; }

  .nav-toggle { display: grid; }

  /* Mobile nav sheet */
  .nav.open {
    position: fixed;
    inset: var(--header-h) 0 auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 14px var(--gutter) 22px;
    background: var(--paper);
    border-bottom: 1px solid var(--line);
    box-shadow: var(--shadow);
    animation: nav-in 0.25s var(--ease);
  }

  @keyframes nav-in {
    from { opacity: 0; transform: translateY(-8px); }
  }

  .nav.open a {
    padding: 14px 12px;
    font-size: 16.5px;
    border-radius: 12px;
  }

  .nav.open .nav-only { display: block; }

  .nav.open .nav-only:first-of-type {
    margin-top: 6px;
    padding-top: 14px;
    border-top: 1px solid var(--line);
    border-radius: 0 0 12px 12px;
  }

}

@media (max-width: 760px) {
  /* Surname is dropped so the brand, CTA, and menu button share one line. */
  .brand-last { display: none; }

  .section { padding-block: clamp(52px, 11vw, 78px); }

  .chapter { grid-template-columns: 32px minmax(0, 1fr); gap: 14px; }
  .chapter-dot { width: 32px; height: 32px; font-size: 11.5px; }
  .timeline::before { left: 15px; }
  .chapter-card:hover { transform: none; }

  .hero-meta { gap: 16px 24px; }
  .contact-links { gap: 8px 20px; }
}

@media (max-width: 420px) {
  .hero-actions .btn,
  .contact-actions .btn { width: 100%; }

  .stat-grid { grid-template-columns: 1fr 1fr; }
  .stat { padding: 16px; }
  .stat-value { font-size: 27px; }
  .stat h3 { font-size: 14px; }
  .stat p { font-size: 12.5px; }
}

/* Very narrow phones: the header CTA and the menu button no longer both fit. */
@media (max-width: 380px) {
  .header-cta .btn-primary { display: none; }
  .brand span:last-child { font-size: 15px; }
}

/* ==========================================================================
   Reduced motion
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .reveal { opacity: 1; transform: none; }
  .marquee { animation: none; }
}

/* ==========================================================================
   Print
   ========================================================================== */

@media print {
  .site-header,
  .hero-stage,
  .strip,
  .nav-toggle,
  .contact-actions,
  dialog { display: none !important; }

  body { background: #fff; }
  .section { padding-block: 18px; }
  .project { break-inside: avoid; box-shadow: none; }
}
