/* Oreja de Van Gogh — the night.
   The product is one small room: an AI voice, a record player, and a man who gave away an ear.
   So the site is a painted night, and the whole page is the light in it. Warm paper survives
   inside the app panel; the marketing surface is indigo, cream and wheat.

   Tokens mirror apps/macos/Theme.swift and docs/brand.md. Self-hosted fonts only, no third-party
   requests, no build step. */

@font-face {
  font-family: "Manrope";
  src: url("assets/fonts/manrope-variable.ttf") format("truetype-variations"),
    url("assets/fonts/manrope-variable.ttf") format("truetype");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Instrument Serif";
  src: url("assets/fonts/instrument-serif-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "Instrument Serif";
  src: url("assets/fonts/instrument-serif-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  /* The night. */
  --night: #080a20;
  --night-raised: #0c0f28;
  --night-deep: #05060f;
  --cream: #f6ecd9;
  --cream-soft: rgba(246, 236, 217, 0.68);
  --cream-faint: rgba(246, 236, 217, 0.44);
  --hair: rgba(246, 236, 217, 0.15);
  --hair-strong: rgba(246, 236, 217, 0.3);

  /* The paint. Wheat is the voice; coral is the ear, and only the ear. */
  --wheat: #efc36a;
  --wheat-deep: #c9973f;
  --coral: #f08a5f;
  --coral-soft: #ffb891;

  /* Paper, for the one object that is literally the app. */
  --paper: #fbf7f0;
  --paper-deep: #f4ebdf;
  --ink: #24211d;
  --ink-soft: #6f675c;
  --paper-line: #e8dfd2;

  --serif: "Instrument Serif", "Iowan Old Style", Georgia, serif;
  --sans: "Manrope", -apple-system, BlinkMacSystemFont, "SF Pro Text", ui-sans-serif, system-ui,
    sans-serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;

  /* The engine's roles follow the brand, so drift and grounds land on our indigo. */
  --sc-canvas: var(--night);
  --sc-surface: var(--night-raised);
  --sc-ink: var(--cream);
  --sc-ink-soft: var(--cream-soft);
  --sc-accent: var(--wheat);
  --sc-accent-ink: #1a1408;
  --sc-font-display: var(--sans);
  --sc-font-text: var(--sans);

  --wrap: 1200px;
  --gutter: clamp(20px, 4.5vw, 56px);

  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-soft: cubic-bezier(0.4, 0, 0.2, 1);
}

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

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body.n-body {
  margin: 0;
  overflow-x: clip;
  background: var(--night);
  color: var(--cream);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

h1,
h2,
h3 {
  margin: 0;
  font-weight: 800;
  letter-spacing: -0.045em;
  line-height: 0.94;
  text-wrap: balance;
}

p {
  margin: 0;
}

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

em {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  letter-spacing: -0.012em;
}

code {
  font-family: var(--mono);
  font-size: 0.86em;
  color: var(--cream-soft);
}

::selection {
  background: var(--wheat);
  color: #17110a;
}

:focus-visible {
  outline: 2px solid var(--wheat);
  outline-offset: 3px;
  border-radius: 4px;
}

.n-sprite {
  position: absolute;
}

.n-skip {
  position: fixed;
  left: 16px;
  top: -60px;
  z-index: 200;
  padding: 10px 16px;
  border-radius: 999px;
  background: var(--cream);
  color: var(--night);
  font-weight: 700;
}

.n-skip:focus {
  top: 12px;
}

/* ------------------------------------------------------------------ chrome -- */

.n-progress {
  position: fixed;
  inset: 0 0 auto;
  height: 2px;
  z-index: 90;
  pointer-events: none;
  background: rgba(246, 236, 217, 0.06);
}

.n-progress span {
  display: block;
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, var(--coral), var(--wheat));
  transform-origin: 0 50%;
  transition: width 90ms linear;
}

.n-grain {
  position: fixed;
  inset: 0;
  z-index: 80;
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}

.n-wrap {
  width: min(100% - 2 * var(--gutter), var(--wrap));
  margin-inline: auto;
}

.n-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 70;
  /* No backdrop-filter in the transition: animating a blur behind a fixed bar re-runs the blur on
     every frame of the fade, on every scroll that crosses the threshold. */
  transition: background 320ms var(--ease-soft), border-color 320ms var(--ease-soft);
  border-bottom: 1px solid transparent;
}

.n-header.is-scrolled {
  background: color-mix(in srgb, var(--night) 72%, transparent);
  -webkit-backdrop-filter: blur(16px) saturate(1.1);
  backdrop-filter: blur(16px) saturate(1.1);
  border-bottom-color: var(--hair);
}

.n-header-inner {
  display: flex;
  align-items: center;
  gap: 28px;
  height: 76px;
}

.n-brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  margin-right: auto;
}

/* The mark is a portrait now, not a two-stroke glyph: at 30 px the hat, the eyes and the beard
   collapse into one another, so it gets the height of the wordmark it sits beside. */
.n-mark {
  width: 38px;
  height: 38px;
  border-radius: 26%;
  flex: none;
  filter: drop-shadow(0 4px 14px rgba(240, 138, 95, 0.28));
}

.n-brand-text {
  display: grid;
  line-height: 1;
}

.n-brand-name {
  font-size: 19px;
  font-weight: 800;
  letter-spacing: -0.05em;
  text-transform: lowercase;
}

.n-brand-sub {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--cream-faint);
  margin-top: 3px;
}

.n-nav {
  display: flex;
  align-items: center;
  gap: 26px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--cream-soft);
}

.n-nav a {
  position: relative;
  padding: 6px 0;
  transition: color 180ms;
}

.n-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--wheat);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 240ms var(--ease-out);
}

.n-nav a:hover {
  color: var(--cream);
}

.n-nav a:hover::after {
  transform: scaleX(1);
}

/* ------------------------------------------------------------------ atoms -- */

.n-btn {
  --btn-bg: transparent;
  --btn-fg: var(--cream);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 13px 22px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.015em;
  white-space: nowrap;
  cursor: pointer;
  transition: transform 220ms var(--ease-out), background 220ms, color 220ms,
    border-color 220ms, box-shadow 220ms;
}

.n-btn-sm {
  padding: 9px 16px;
  font-size: 13.5px;
}

.n-btn-lg {
  padding: 16px 28px;
  font-size: 16px;
}

.n-btn-solid {
  --btn-bg: var(--cream);
  --btn-fg: #14101c;
  box-shadow: 0 18px 44px -22px rgba(246, 236, 217, 0.55);
}

.n-btn-solid:hover {
  --btn-bg: #fff8ea;
  transform: translateY(-1px);
}

.n-btn-ghost {
  border-color: var(--hair-strong);
  --btn-fg: var(--cream);
}

/* The hero's second action lands on the painting's bright horizon, where a cream hairline and
   15px text disappeared into the swirls. It gets its own dark glass, like the readout card, so the
   pair reads as two buttons at any point of the sky behind them. */
.n-actions .n-link {
  padding: 13px 22px;
  border: 1px solid rgba(246, 236, 217, 0.26);
  border-radius: 999px;
  background: rgba(6, 8, 26, 0.52);
  -webkit-backdrop-filter: blur(10px) saturate(125%);
  backdrop-filter: blur(10px) saturate(125%);
  transition: border-color 180ms, background 220ms, gap 220ms var(--ease-out);
}

.n-actions .n-link:hover {
  border-color: rgba(246, 236, 217, 0.6);
  background: rgba(6, 8, 26, 0.66);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .n-actions .n-link { background: rgba(6, 8, 26, 0.82); }
}

.n-btn-ghost:hover {
  border-color: var(--cream);
  background: rgba(246, 236, 217, 0.06);
}

.n-btn-dark {
  --btn-bg: #1b1207;
  --btn-fg: #fdf3e2;
  box-shadow: 0 20px 50px -24px rgba(20, 10, 4, 0.8);
}

.n-btn-dark:hover {
  --btn-bg: #2a1b0a;
  transform: translateY(-1px);
}

.n-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding-bottom: 3px;
  border-bottom: 1px solid var(--hair-strong);
  font-size: 15px;
  font-weight: 700;
  color: var(--cream);
  transition: border-color 180ms, gap 220ms var(--ease-out);
}

.n-link span {
  color: var(--wheat);
  transition: transform 240ms var(--ease-out);
}

.n-link:hover {
  border-color: var(--wheat);
}

.n-link:hover span {
  transform: translateX(3px);
}

.n-link-dark {
  border-color: rgba(26, 16, 8, 0.35);
  color: #1c1309;
}

.n-eyebrow {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--wheat);
}

.n-eyebrow::before {
  content: "";
  width: 26px;
  height: 1px;
  background: currentColor;
  opacity: 0.7;
}

.n-eyebrow-dark {
  color: #7d3d1c;
}

.n-h2 {
  font-size: clamp(2.35rem, 4.6vw, 4.15rem);
  line-height: 0.96;
}

.n-h2 em {
  font-size: 1.04em;
  color: var(--wheat);
}

.n-body-copy {
  max-width: 56ch;
  margin-top: 22px;
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--cream-soft);
}

.n-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--coral);
  box-shadow: 0 0 0 3px rgba(240, 138, 95, 0.16);
  flex: none;
  animation: n-breathe 3.6s var(--ease-soft) infinite;
}

.n-ring {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  border: 1.5px solid var(--cream-faint);
  flex: none;
}

@keyframes n-breathe {
  0%, 100% { box-shadow: 0 0 0 3px rgba(240, 138, 95, 0.14); }
  50% { box-shadow: 0 0 0 6px rgba(240, 138, 95, 0.05); }
}

/* ------------------------------------------------------------------- hero -- */

.n-hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  isolation: isolate;
  overflow: hidden;
  padding: 120px 0 40px;
  /* The frame of the painting: a hairline at the very bottom edge. */
  border-bottom: 1px solid var(--hair);
}

/* A scrim under the fixed header. The painted moon sits in that corner, and white nav text over it
   was unreadable at some widths. */
.n-hero::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 200px;
  z-index: 6;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgba(6, 8, 24, 0.78) 0%,
    rgba(6, 8, 24, 0.34) 48%,
    transparent 100%
  );
}

.n-sky,
.n-hills,
.n-front {
  position: absolute;
  left: 0;
  right: 0;
  pointer-events: none;
}

.n-sky {
  top: -12%;
  bottom: -6%;
  z-index: 0;
  overflow: hidden;
  /* The paint has to reach the horizon: stopping it early leaves a flat band above the hills that
     reads as a seam, not as night. */
  -webkit-mask-image: linear-gradient(180deg, #000 0 94%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 0 94%, transparent 100%);
}

/* The painting is four copies of one image, each on its own clock.

   The base holds the whole sky and inches forward so the frame never sits still. Three further
   copies are masked to a single current each — the two spirals and the low cloud river — and move
   against the base at different speeds and directions, which is what reads as paint turning. Every
   layer stays on the same pixel grid and only transforms and opacity animate, so the compositor
   does the work: no repaint, no layout, no filter animated per frame. */
.n-sky-base,
.n-sky-swirl {
  position: absolute;
  inset: -4%;
  background-image: url("assets/night-sky.png");
  background-size: cover;
  background-position: center 42%;
  will-change: transform;
}

.n-sky-base {
  animation: n-sky-breathe 72s var(--ease-soft) infinite alternate;
}

/* Each masked copy turns about the centre of its own vortex, so the brush strokes inside move the
   way the paint was laid down. The mask is a radial gradient centred on that same point, which is
   also the transform origin: a circle turned about its own centre stays put while the image inside
   it rotates. Centres are in the sky layer's coordinates, not the viewport's. */
.n-sky-swirl {
  opacity: 0.5;
  animation: n-swirl-a 46s var(--ease-soft) infinite alternate;
}

/* No filter on these three. A blurred, masked, full-bleed layer that also rotates has to be
   re-rastered every frame it moves; the mask's soft edge already does the blending they needed. */
.n-sky-swirl-a {
  transform-origin: 61.1% 23.8%;
  -webkit-mask-image: radial-gradient(13% 17% at 61.1% 23.8%, #000 0%, rgba(0, 0, 0, 0.72) 52%, transparent 80%);
  mask-image: radial-gradient(13% 17% at 61.1% 23.8%, #000 0%, rgba(0, 0, 0, 0.72) 52%, transparent 80%);
}

.n-sky-swirl-b {
  opacity: 0.46;
  transform-origin: 84.3% 20.2%;
  -webkit-mask-image: radial-gradient(9% 12% at 84.3% 20.2%, #000 0%, rgba(0, 0, 0, 0.6) 50%, transparent 80%);
  mask-image: radial-gradient(9% 12% at 84.3% 20.2%, #000 0%, rgba(0, 0, 0, 0.6) 50%, transparent 80%);
  animation: n-swirl-b 58s var(--ease-soft) infinite alternate;
}

.n-sky-swirl-c {
  opacity: 0.4;
  transform-origin: 7.4% 44.5%;
  -webkit-mask-image: radial-gradient(10% 14% at 7.4% 44.5%, #000 0%, rgba(0, 0, 0, 0.66) 52%, transparent 80%);
  mask-image: radial-gradient(10% 14% at 7.4% 44.5%, #000 0%, rgba(0, 0, 0, 0.66) 52%, transparent 80%);
  animation: n-swirl-c 71s var(--ease-soft) infinite alternate;
}

/* Moonlight crossing the clouds: one broad warm band drifting over the paint. It sits outside
   .n-sky on purpose. As a child of that masked group, animated, Chrome 141 composites the group
   without its backdrop and the entire painting disappears (verified: the base layer painted 0
   pixels with the band present, and painted normally once it was removed). */
.n-sky-light {
  position: absolute;
  top: -6%;
  bottom: -2%;
  left: -10%;
  right: -10%;
  z-index: 1;
  background: linear-gradient(
    104deg,
    transparent 24%,
    rgba(246, 236, 217, 0.09) 42%,
    rgba(239, 195, 106, 0.1) 50%,
    transparent 68%
  );
  pointer-events: none;
  will-change: transform, opacity;
  animation: n-sky-light 38s var(--ease-soft) infinite alternate;
}

@keyframes n-sky-breathe {
  from { transform: scale(1.01) translate3d(0, 0, 0); }
  to { transform: scale(1.07) translate3d(-10px, -7px, 0); }
}

@keyframes n-swirl-a {
  0% { transform: rotate(-7deg) scale(1); opacity: 0.4; }
  50% { opacity: 0.62; }
  100% { transform: rotate(7deg) scale(1.05); opacity: 0.5; }
}

@keyframes n-swirl-b {
  0% { transform: rotate(6deg) scale(1.02); opacity: 0.36; }
  50% { opacity: 0.56; }
  100% { transform: rotate(-6deg) scale(1); opacity: 0.44; }
}

@keyframes n-swirl-c {
  0% { transform: rotate(-5deg) scale(1.01); opacity: 0.28; }
  100% { transform: rotate(5deg) scale(1.04); opacity: 0.46; }
}

@keyframes n-sky-light {
  0% { transform: translate3d(-6%, 0, 0) rotate(-1deg); opacity: 0.35; }
  100% { transform: translate3d(8%, -2%, 0) rotate(1.4deg); opacity: 0.8; }
}

/* Offscreen, the painting is invisible and still costs the compositor: four full-viewport layers
   turning under masks, every frame, for the whole length of the page. Parked, they cost nothing. */
.n-hero.is-parked .n-sky-base,
.n-hero.is-parked .n-sky-swirl,
.n-hero.is-parked .n-sky-light,
.n-hero.is-parked .n-sun::after {
  animation-play-state: paused;
}

@media (prefers-reduced-motion: reduce) {
  .n-sky-base,
  .n-sky-swirl,
  .n-sky-light {
    animation: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .n-dawn-figure,
  .n-dawn-figure::before,
  .n-dawn-figure::after,
  .n-sun::after {
    animation: none;
  }

  .n-dawn-figure::after {
    opacity: 0.55;
  }
}

/* The painted sky already carries a moon and its light; a second, CSS-drawn glow could not follow
   the image's crop across widths, so the canvas and the sheen do that job instead. */
.n-starfield {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Decorative paint, and painted above Vincent: without this they would swallow clicks on his lower
   half before the ouch could play. */
.n-hills {
  z-index: 4;
  bottom: 0;
  height: 50%;
  background-image: url("assets/night-hills.png");
  background-size: cover;
  background-position: bottom center;
  pointer-events: none;
}

.n-front {
  z-index: 6;
  bottom: 0;
  height: 14%;
  background-image: url("assets/night-front.png");
  background-size: cover;
  background-position: bottom center;
  pointer-events: none;
}

/* Vincent is a five-frame sprite pinned to frame one. He never loops on the site: the only frame
   change is the blink timer and the ouch on a click, the two reactions the app also has. */
.n-vincent {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  background-image: url("assets/oreja-vincent.png");
  background-repeat: no-repeat;
  background-size: 500% 100%;
  background-position: 0 0;
  image-rendering: pixelated;
  -webkit-user-select: none;
  user-select: none;
}

.n-figure {
  position: absolute;
  z-index: 3;
  right: 11%;
  bottom: 24%;
  width: clamp(190px, 24vw, 330px);
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.n-figure:focus-visible {
  outline-offset: -6px;
  border-radius: 12px;
}

/* He does not move: no float, no bob, no parallax. The light around him moves instead. */
.n-figure .n-vincent.is-blink {
  background-position: 25% 0;
}

/* The ouch, frame for frame the app's `VincentCompanion.snip()`: the ouch sprite stays up for the
   whole 810ms while the figure steps -step, +step, -step/2, rest, 60ms of travel and 10ms of hold
   each. `--ouch-step` is 4% of the sprite's rendered width, set by landing.js on click, so the
   shake reads the same at 190px as at 330px — the app scales it by sprite size too. */
.n-figure .n-vincent.is-ouch {
  background-position: 100% 0;
  animation: n-ouch 810ms linear both;
}

@keyframes n-ouch {
  0% { transform: translateX(0); }
  7.4%,
  8.6% { transform: translateX(calc(var(--ouch-step, 8px) * -1)); }
  16%,
  17.3% { transform: translateX(var(--ouch-step, 8px)); }
  24.7%,
  25.9% { transform: translateX(calc(var(--ouch-step, 8px) * -0.5)); }
  35.8%,
  100% { transform: translateX(0); }
}

/* Reduced motion keeps the frame (the bandage leaves his head) and drops the shake, exactly as the
   app does; landing.js holds the frame for the app's 900ms in that case. */
@media (prefers-reduced-motion: reduce) {
  .n-figure .n-vincent.is-ouch {
    animation: none;
  }
}

.n-egg-note {
  position: absolute;
  z-index: 8;
  right: 11%;
  bottom: 19%;
  width: 24ch;
  font-family: var(--serif);
  font-style: italic;
  font-size: 16px;
  line-height: 1.35;
  color: var(--wheat);
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 320ms var(--ease-out), transform 320ms var(--ease-out);
  pointer-events: none;
  text-align: right;
}

.n-egg-note.is-shown {
  opacity: 1;
  transform: none;
}

.n-figure-glow {
  position: absolute;
  left: 50%;
  top: 46%;
  width: 190%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(
    circle,
    rgba(240, 170, 110, 0.3) 0%,
    rgba(219, 140, 96, 0.12) 38%,
    transparent 70%
  );
  filter: blur(6px);
  animation: n-halo 7s var(--ease-soft) infinite;
}

@keyframes n-halo {
  0%, 100% { opacity: 0.85; transform: translate(-50%, -50%) scale(1); }
  50% { opacity: 1; transform: translate(-50%, -50%) scale(1.045); }
}

/* A small light on the listening ear, absolutely placed over the sprite. The sprite's ear sits
   at roughly 78% across and 33% down the 40x40 grid. */
.n-figure-ear {
  position: absolute;
  z-index: 2;
  left: 82%;
  top: 36%;
  width: 8%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--coral-soft);
  box-shadow: 0 0 16px 6px rgba(255, 184, 145, 0.55), 0 0 44px 18px rgba(240, 138, 95, 0.22);
  opacity: 0.72;
  animation: n-ear 4.6s var(--ease-soft) infinite;
}

@keyframes n-ear {
  0%, 100% { opacity: 0.5; }
  50% { opacity: 0.95; }
}

.n-hero-inner {
  position: relative;
  z-index: 7;
  width: min(100% - 2 * var(--gutter), var(--wrap));
  padding-bottom: 6vh;
}

.n-kicker {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--cream-soft);
}

.n-display {
  margin-top: 22px;
  font-size: clamp(2.7rem, 6.9vw, 6.2rem);
  line-height: 0.92;
  letter-spacing: -0.055em;
  text-shadow: 0 22px 60px rgba(8, 10, 32, 0.45);
}

.n-display > span:not(.n-underline) {
  display: block;
}

.n-display em {
  font-size: 1.02em;
  color: var(--wheat);
  text-shadow: 0 0 44px rgba(239, 195, 106, 0.3);
}

.n-underline {
  position: relative;
  display: inline-block;
}

.n-underline svg {
  position: absolute;
  left: -1%;
  bottom: -0.16em;
  width: 102%;
  height: 0.22em;
  overflow: visible;
  pointer-events: none;
}

.n-underline path {
  fill: none;
  stroke: var(--wheat);
  stroke-width: 2.6;
  stroke-linecap: round;
  opacity: 0.5;
  stroke-dasharray: 340;
  stroke-dashoffset: 340;
  animation: n-draw 1.7s var(--ease-out) 900ms forwards;
}

@keyframes n-draw {
  to { stroke-dashoffset: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .n-underline path {
    animation: none;
    stroke-dashoffset: 0;
  }
}

.n-lede {
  max-width: 47ch;
  margin-top: 26px;
  font-size: clamp(1rem, 1.15vw, 1.125rem);
  line-height: 1.62;
  color: var(--cream-soft);
  /* The copy sits on painted currents. A shadow, not a panel: the painting stays visible. */
  text-shadow: 0 2px 18px rgba(4, 6, 18, 0.8), 0 1px 3px rgba(4, 6, 18, 0.6);
}

.n-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 26px;
  margin-top: 34px;
}

.n-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  margin: 44px 0 0;
  padding: 0;
  list-style: none;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cream-faint);
}

.n-facts li {
  padding: 0 16px;
  border-left: 1px solid var(--hair);
}

.n-facts li:first-child {
  padding-left: 0;
  border-left: 0;
}

.n-readout {
  position: absolute;
  z-index: 7;
  right: 6%;
  top: 21%;
  width: 232px;
  padding: 13px 16px 14px;
  border: 1px solid var(--hair);
  border-radius: 16px;
  background: color-mix(in srgb, #0b0f2a 68%, transparent);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: 0 26px 60px -30px rgba(0, 0, 0, 0.9);
  font-size: 12px;
}

.n-readout-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 12px;
  align-items: center;
  padding: 7px 0;
}

.n-readout-row + .n-readout-row {
  border-top: 1px solid var(--hair);
}

.n-readout-key {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--cream-soft);
}

.n-readout-val {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--cream);
  font-variant-numeric: tabular-nums;
}

.n-readout-val small {
  font-size: 9px;
  color: var(--cream-faint);
}

.n-bars {
  grid-column: 1 / -1;
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 14px;
  margin-top: 2px;
}

.n-bars i {
  flex: 1;
  background: var(--wheat);
  border-radius: 1px;
  height: 30%;
  animation: n-eq 1.1s var(--ease-soft) infinite alternate;
}

.n-bars i:nth-child(2) { animation-delay: -0.2s; height: 62%; }
.n-bars i:nth-child(3) { animation-delay: -0.55s; height: 96%; }
.n-bars i:nth-child(4) { animation-delay: -0.35s; height: 74%; }
.n-bars i:nth-child(5) { animation-delay: -0.75s; height: 48%; }
.n-bars i:nth-child(6) { animation-delay: -0.1s; height: 24%; }

@keyframes n-eq {
  from { transform: scaleY(0.55); }
  to { transform: scaleY(1); }
}

.n-readout-meter {
  grid-column: 1 / -1;
  display: block;
  height: 2px;
  margin-top: 4px;
  background: rgba(246, 236, 217, 0.14);
}

.n-readout-meter i {
  display: block;
  width: 12%;
  height: 100%;
  background: var(--coral);
}

.n-scroll-cue {
  position: absolute;
  z-index: 7;
  left: var(--gutter);
  bottom: 4.5%;
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--cream-faint);
}

.n-scroll-cue i {
  display: block;
  width: 1px;
  height: 34px;
  background: linear-gradient(180deg, transparent, var(--wheat));
  position: relative;
}

.n-scroll-cue i::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 4px;
  height: 4px;
  margin-left: -2px;
  border-radius: 50%;
  background: var(--wheat);
  animation: n-cue 2.4s var(--ease-soft) infinite;
}

@keyframes n-cue {
  0% { transform: translateY(-30px); opacity: 0; }
  40% { opacity: 1; }
  100% { transform: translateY(0); opacity: 0; }
}

.n-hero-caption {
  position: absolute;
  z-index: 7;
  right: 6%;
  bottom: 5.5%;
  max-width: 26ch;
  font-family: var(--serif);
  font-style: italic;
  font-size: 17px;
  line-height: 1.35;
  text-align: right;
  color: rgba(246, 236, 217, 0.62);
}

/* ------------------------------------------------------------------ act 1 -- */

.n-act {
  position: relative;
  background: #06081a;
}

.n-act-stage {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  display: flex;
  align-items: center;
  background:
    radial-gradient(120% 80% at 50% 108%, rgba(58, 44, 96, 0.55) 0%, transparent 62%),
    #06081a;
}

.n-wave {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}

/* The bars pass under the copy column, so this scrim has to be strong enough for text to sit on
   it: at 0.55 the paragraph's last line and the gold beat caption were read through the waveform.
   It clears by 58% so the wave is still the brightest thing on the right half. */
.n-act-vignette {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(90deg, rgba(5, 6, 18, 0.97) 0%, rgba(5, 6, 18, 0.92) 30%, rgba(5, 6, 18, 0.62) 48%, transparent 76%),
    linear-gradient(180deg, rgba(5, 6, 18, 0.75) 0%, transparent 30%, rgba(5, 6, 18, 0.6) 100%);
}

.n-act-inner {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 48px;
  align-items: center;
  width: min(100% - 2 * var(--gutter), var(--wrap));
  padding-bottom: 72px;
}

.n-act-copy {
  max-width: 600px;
}

.n-act-copy .n-h2 {
  margin-top: 18px;
  font-size: clamp(2.2rem, 4.1vw, 3.8rem);
}

.n-beats {
  position: relative;
  height: 244px;
  margin-top: 40px;
}

.n-beat {
  position: absolute;
  inset: 0;
  max-width: 46ch;
}

.n-beat h3 {
  font-size: clamp(1.35rem, 2vw, 1.7rem);
  letter-spacing: -0.03em;
  color: var(--cream);
}

.n-beat p {
  margin-top: 12px;
  font-size: 1rem;
  line-height: 1.62;
  color: var(--cream-soft);
}

.n-beat .n-state {
  margin-top: 16px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--wheat);
  font-variant-numeric: tabular-nums;
}

.n-act-side {
  display: grid;
  gap: 20px;
  justify-items: stretch;
}

.n-desk {
  position: relative;
  margin: 0;
}

.n-desk img,
.n-desk svg {
  position: relative;
  display: block;
  width: 100%;
  height: auto;
  image-rendering: pixelated;
  filter: drop-shadow(0 26px 40px rgba(2, 3, 12, 0.6));
  -webkit-mask-image: radial-gradient(ellipse 76% 74% at 50% 48%, #000 62%, transparent 100%);
  mask-image: radial-gradient(ellipse 76% 74% at 50% 48%, #000 62%, transparent 100%);
}

/* The scene's layers, in the same spirit as the rest of the page: slow, small, and only where the
   app would show something happening. The record turns under its sheen, steam leaves the mug, the
   painting twinkles, the headphone LEDs breathe and he blinks. He never leaves the chair. */
/* The sheen is an ellipse in the disc's perspective, so the light is pushed around it with the dash
   offset instead of a rotation: rotating the ellipse would tilt it out of the record's plane. */
.n-desk-art #sheen ellipse {
  animation: n-sheen 7.6s linear infinite;
}

.n-desk-art #steam-a {
  animation: n-steam-a 4.6s ease-in-out infinite;
}

.n-desk-art #steam-b {
  animation: n-steam-b 5.4s ease-in-out -1.8s infinite;
}

.n-desk-art #stars-a {
  animation: n-twinkle-a 3.4s ease-in-out infinite;
}

.n-desk-art #stars-b {
  animation: n-twinkle-b 4.3s ease-in-out -1.2s infinite;
}

.n-desk-art #led {
  animation: n-led 2.6s ease-in-out infinite;
}

.n-desk-art #eyes {
  opacity: 0;
  animation: n-desk-blink 7s steps(1, end) infinite;
}

@keyframes n-sheen {
  to { stroke-dashoffset: -27; }
}

@keyframes n-steam-a {
  0% { transform: translate(0, 0); opacity: 0; }
  22% { opacity: 1; }
  70% { opacity: 0.45; }
  100% { transform: translate(-1px, -8px); opacity: 0; }
}

@keyframes n-steam-b {
  0% { transform: translate(0, 0); opacity: 0; }
  18% { opacity: 0.9; }
  66% { opacity: 0.4; }
  100% { transform: translate(1px, -8px); opacity: 0; }
}

@keyframes n-twinkle-a {
  0%, 100% { opacity: 0.2; }
  45% { opacity: 1; }
}

@keyframes n-twinkle-b {
  0%, 100% { opacity: 0.3; }
  60% { opacity: 1; }
}

@keyframes n-led {
  0%, 100% { opacity: 0.35; }
  50% { opacity: 1; }
}

@keyframes n-desk-blink {
  0%, 94% { opacity: 0; }
  95%, 97% { opacity: 1; }
  98%, 100% { opacity: 0; }
}

/* With reduced motion the scene is the still frame: steam present, eyes open, sheen at rest. */
@media (prefers-reduced-motion: reduce) {
  .n-desk-art #sheen ellipse,
  .n-desk-art #steam-a,
  .n-desk-art #steam-b,
  .n-desk-art #stars-a,
  .n-desk-art #stars-b,
  .n-desk-art #led,
  .n-desk-art #eyes {
    animation: none;
  }
  .n-desk-art #steam-b { opacity: 0.6; }
}

.n-desk-glow {
  position: absolute;
  inset: 12% 2% 2%;
  border-radius: 50%;
  background: radial-gradient(circle at 52% 48%, rgba(240, 165, 110, 0.3), transparent 66%);
  filter: blur(18px);
  animation: n-lamp 6.5s var(--ease-soft) infinite;
}

@keyframes n-lamp {
  0%, 100% { opacity: 0.78; }
  42% { opacity: 1; }
  70% { opacity: 0.86; }
}

.n-levels {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  padding: 12px 14px;
  border: 1px solid var(--hair);
  border-radius: 14px;
  background: rgba(6, 8, 26, 0.62);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}

.n-level {
  border-top: 1px solid var(--hair);
  padding-top: 12px;
}

.n-level-label {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--cream-faint);
}

.n-level-track {
  position: relative;
  height: 3px;
  margin: 12px 0 10px;
  background: rgba(246, 236, 217, 0.12);
  overflow: hidden;
}

.n-level-track span {
  display: block;
  height: 100%;
  width: 92%;
  background: var(--wheat);
  transform-origin: 0 50%;
  transition: width 120ms linear, background 240ms;
}

.n-level-music .n-level-track span {
  width: 0;
  background: var(--coral);
}

.n-level-value {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--cream);
}

.n-timeline {
  position: absolute;
  z-index: 3;
  left: var(--gutter);
  right: var(--gutter);
  bottom: 34px;
  max-width: var(--wrap);
  margin-inline: auto;
}

.n-timeline-line {
  position: relative;
  display: block;
  height: 1px;
  background: var(--hair);
}

.n-timeline-line i {
  position: absolute;
  left: 0;
  top: 50%;
  width: 9px;
  height: 9px;
  margin: -4px 0 0 -4px;
  border-radius: 50%;
  background: var(--wheat);
  box-shadow: 0 0 0 4px rgba(239, 195, 106, 0.12), 0 0 22px 6px rgba(239, 195, 106, 0.22);
  transition: left 80ms linear;
}

.n-timeline-labels {
  display: flex;
  justify-content: space-between;
  margin-top: 10px;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--cream-faint);
}

.n-timeline-labels span {
  transition: color 260ms;
}

.n-timeline-labels span.is-live {
  color: var(--wheat);
}

.n-act-hint {
  position: absolute;
  z-index: 3;
  right: var(--gutter);
  top: 96px;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--cream-faint);
  writing-mode: vertical-rl;
}

/* ------------------------------------------------------------------ panel -- */

.n-section {
  position: relative;
  padding: clamp(84px, 12vh, 150px) 0;
}

.n-panel-section {
  background:
    radial-gradient(70% 60% at 74% 46%, rgba(214, 137, 85, 0.12) 0%, transparent 68%),
    linear-gradient(180deg, #06081a 0%, #0a0d26 40%, #080a20 100%);
}

.n-panel-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, 0.98fr);
  gap: clamp(40px, 7vw, 96px);
  align-items: center;
}

.n-panel-copy .n-h2 {
  margin-top: 18px;
}

.n-rows {
  margin: 38px 0 0;
  border-top: 1px solid var(--hair);
}

.n-rows > div {
  display: grid;
  grid-template-columns: 110px minmax(0, 1fr);
  gap: 20px;
  padding: 15px 0;
  border-bottom: 1px solid var(--hair);
}

.n-rows dt {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--wheat);
  padding-top: 3px;
}

.n-rows dd {
  margin: 0;
  font-size: 0.98rem;
  line-height: 1.5;
  color: var(--cream-soft);
}

.n-panel-art {
  position: relative;
  display: flex;
  justify-content: center;
  perspective: 1200px;
}

.n-panel-glow {
  position: absolute;
  inset: 8% 4%;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 55%, rgba(240, 168, 118, 0.24), transparent 68%);
  filter: blur(22px);
}

.n-panel {
  position: relative;
  width: min(100%, 396px);
  padding: 18px;
  border-radius: 26px;
  background: linear-gradient(180deg, #fffdf9 0%, var(--paper) 42%, #f7efe3 100%);
  color: var(--ink);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.9) inset,
    0 40px 90px -40px rgba(0, 0, 0, 0.85),
    0 0 0 1px rgba(255, 255, 255, 0.06);
  transform-style: preserve-3d;
  will-change: transform;
}

.n-panel-head {
  display: flex;
  align-items: center;
  gap: 12px;
}

.n-panel-wordmark {
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.03em;
  color: var(--ink);
}

/* SettingsView's own header, in order: mark and wordmark, then the page title, then the caption
   that says when the app is allowed to touch playback. */
.n-panel-page {
  margin: 14px 0 0;
  font-size: 25px;
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.1;
  color: var(--ink);
}

.n-panel-caption {
  margin: 4px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-soft);
}

.n-panel-vincent {
  width: 38px;
  height: 38px;
  border-radius: 11px;
  background-color: #fde7d5;
  background-image: url("assets/oreja-vincent.png");
  background-repeat: no-repeat;
  background-size: 500% 100%;
  background-position: 0 0;
  image-rendering: pixelated;
  flex: none;
}


.n-panel-block {
  padding: 13px 14px;
  border-radius: 16px;
  background: #fffdfa;
  border: 1px solid var(--paper-line);
  margin-top: 14px;
}

/* `behaviorPreview` from SettingsView: the dot, the headline it derives from the selected mode,
   and the two levels underneath. Sits above the controls, divided from them like the app does. */
.n-panel-preview {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 0 0 12px;
  border-bottom: 1px solid var(--paper-line);
}

/* StatusDot: a 7 px fill in the state tint and, when active, a 1 px ring at 2.1× and 35% opacity.
   It does not pulse in the app, so it does not pulse here. */
.n-panel-preview-dot {
  width: 7px;
  height: 7px;
  margin-top: 4px;
  border-radius: 50%;
  background: #a7472a;
  box-shadow: 0 0 0 3.5px rgba(167, 71, 42, 0.35);
  flex: none;
}

.n-panel-preview-text {
  display: grid;
  gap: 2px;
}

.n-panel-preview-text strong {
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.n-panel-preview-text span {
  font-size: 11.5px;
  color: var(--ink-soft);
}

/* The macOS switch the app uses for `Automation enabled`, at panel scale. */
.n-switch {
  position: relative;
  width: 30px;
  height: 18px;
  border-radius: 999px;
  background: var(--coral);
  flex: none;
  align-self: center;
}

.n-switch::after {
  content: "";
  position: absolute;
  top: 2px;
  right: 2px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #fffdfa;
  box-shadow: 0 1px 2px rgba(74, 48, 24, 0.28);
}

/* A picker's value is a word, not a number: it keeps its own weight instead of the tabular
   treatment the percentages get. */
.n-panel-value {
  padding: 3px 8px;
  border-radius: 7px;
  background: #f2e9dc;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
}

.n-panel-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--ink-soft);
  margin-bottom: 10px;
}

.n-panel-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding-top: 11px;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
}

.n-panel-row strong {
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}

.n-panel-slider {
  position: relative;
  height: 4px;
  margin: 10px 0 0;
  border-radius: 999px;
  background: #ece1d0;
}

.n-panel-slider span {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: var(--at);
  border-radius: 999px;
  background: linear-gradient(90deg, #e77952, #c95f3c);
}

.n-panel-slider span::after {
  content: "";
  position: absolute;
  right: -5px;
  top: 50%;
  width: 11px;
  height: 11px;
  margin-top: -5.5px;
  border-radius: 50%;
  background: #fffdfa;
  box-shadow: 0 1px 3px rgba(74, 48, 24, 0.3);
}

.n-panel-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 5px 2px;
  font-size: 11px;
  letter-spacing: 0;
  color: var(--ink-soft);
}

/* Picker values such as "ChatGPT desktop app" are longer than a number, so they get their own
   weight and size instead of the tabular number treatment, and a row label that wraps keeps its
   leading. */
.n-panel-row > span:first-child {
  min-width: 0;
  font-size: 12.5px;
  line-height: 1.3;
}

.n-panel-row strong {
  flex: none;
}

/* ---------------------------------------------------------------- privacy -- */

.n-privacy {
  position: relative;
  padding: clamp(90px, 14vh, 170px) 0;
  background: var(--night-deep);
  border-top: 1px solid var(--hair);
  border-bottom: 1px solid var(--hair);
}

.n-privacy::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(60% 70% at 18% 0%, rgba(240, 138, 95, 0.07), transparent 60%);
  pointer-events: none;
}

.n-privacy .n-wrap {
  position: relative;
}

.n-h2-wide {
  max-width: 20ch;
  margin-top: 20px;
  font-size: clamp(2.4rem, 5vw, 4.4rem);
}

.n-privacy-head .n-body-copy {
  max-width: 58ch;
}

.n-privacy-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
  margin: 72px 0 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--hair);
}

.n-privacy-grid li {
  padding: 26px 26px 0 0;
  border-right: 1px solid var(--hair);
}

.n-privacy-grid li:last-child {
  border-right: 0;
}

.n-privacy-grid li:not(:first-child) {
  padding-left: 26px;
}

.n-num {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--wheat);
}

.n-privacy-grid h3 {
  margin-top: 18px;
  font-size: 1.15rem;
  letter-spacing: -0.025em;
  line-height: 1.2;
}

.n-privacy-grid p {
  margin-top: 10px;
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--cream-soft);
}

/* -------------------------------------------------------------------- faq -- */

.n-faq {
  background: var(--night);
  border-top: 1px solid var(--hair);
}

.n-faq-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.62fr) minmax(0, 1.38fr);
  gap: clamp(32px, 6vw, 90px);
  align-items: start;
}

.n-faq-head {
  position: sticky;
  top: 118px;
}

.n-faq-head .n-h2 {
  margin-top: 18px;
  font-size: clamp(2rem, 3.6vw, 3.2rem);
}

.n-faq-list details {
  border-top: 1px solid var(--hair);
}

.n-faq-list details:last-child {
  border-bottom: 1px solid var(--hair);
}

.n-faq-list summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 22px 2px;
  list-style: none;
  cursor: pointer;
  font-size: 1.02rem;
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--cream);
  transition: color 180ms;
}

.n-faq-list summary::-webkit-details-marker {
  display: none;
}

.n-faq-list summary::after {
  content: "";
  width: 11px;
  height: 11px;
  flex: none;
  border-right: 1.5px solid var(--cream-faint);
  border-bottom: 1.5px solid var(--cream-faint);
  transform: rotate(45deg) translateY(-2px);
  transition: transform 260ms var(--ease-out), border-color 200ms;
}

.n-faq-list details[open] summary::after {
  transform: rotate(-135deg) translateY(-2px);
  border-color: var(--wheat);
}

.n-faq-list summary:hover {
  color: var(--wheat);
}

.n-faq-list p {
  max-width: 62ch;
  padding: 0 40px 24px 2px;
  font-size: 0.98rem;
  line-height: 1.65;
  color: var(--cream-soft);
}

/* ------------------------------------------------------------------- dawn -- */

/* The one warm screen on the page. The night burns off from the top down as the section
   arrives: scroll drives --dawn, the sun climbs, and the hills go from navy to oxblood. */
.n-dawn {
  --dawn: 0;
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: center;
  overflow: hidden;
  padding: 140px 0 120px;
  isolation: isolate;
  background: #0a0d24;
}

.n-dawn-sky {
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    linear-gradient(
      180deg,
      #0a0d24 0%,
      #171331 22%,
      #392139 46%,
      #7b3d3e 68%,
      #c76c46 84%,
      #eda361 94%,
      #f8cd92 100%
    );
}

.n-dawn-sky::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(120% 70% at 66% 84%, rgba(255, 214, 150, 0.45), transparent 60%);
  opacity: calc(0.25 + var(--dawn) * 0.75);
}

.n-sun {
  position: absolute;
  z-index: 1;
  left: 63%;
  bottom: 27%;
  width: clamp(200px, 22vw, 340px);
  aspect-ratio: 1;
  margin-left: clamp(-170px, -11vw, -100px);
  border-radius: 50%;
  background: radial-gradient(
    circle,
    #fff8e2 0 34%,
    #ffe0aa 42%,
    rgba(255, 196, 132, 0.85) 52%,
    rgba(244, 154, 92, 0.35) 62%,
    transparent 71%
  );
  transform: translateY(calc((1 - var(--dawn)) * 150px));
  opacity: calc(0.55 + var(--dawn) * 0.45);
}

/* The sun's own halo breathes. On a pseudo-element, because the sun's own transform and opacity
   are scroll-driven and an animation would overwrite them. */
.n-sun::after {
  content: "";
  position: absolute;
  inset: -22%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 218, 166, 0.34), transparent 66%);
  animation: n-sun-halo 8.5s var(--ease-soft) infinite alternate;
}

@keyframes n-sun-halo {
  from { transform: scale(0.94); opacity: 0.45; }
  to { transform: scale(1.06); opacity: 0.9; }
}

/* A silhouette in a colour of our choosing, rather than the navy art pushed through a filter. */
.n-dawn-hills {
  position: absolute;
  z-index: 3;
  inset: auto 0 0;
  height: 34%;
  background: #25101b;
  -webkit-mask-image: url("assets/night-hills.png");
  mask-image: url("assets/night-hills.png");
  -webkit-mask-size: cover;
  mask-size: cover;
  -webkit-mask-position: bottom center;
  mask-position: bottom center;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

.n-dawn-hills::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(196, 96, 58, 0.55) 0%, transparent 34%);
  mix-blend-mode: screen;
}

.n-dawn-figure {
  position: absolute;
  z-index: 4;
  right: 20%;
  bottom: 15%;
  width: clamp(170px, 19vw, 260px);
  opacity: calc(0.85 + var(--dawn) * 0.15);
  filter: drop-shadow(0 28px 38px rgba(60, 18, 8, 0.45));
  /* He is watching, not posing: weight shifts from one foot to the other while he breathes. */
  transform-origin: 50% 100%;
  animation: n-back-breathe 9s var(--ease-soft) infinite;
  will-change: transform;
}

/* The warmth the sun puts on him, in front of the hills but behind his pixels. */
.n-dawn-figure::before {
  content: "";
  position: absolute;
  inset: -24% -34% -12%;
  z-index: -1;
  border-radius: 50%;
  background: radial-gradient(
    50% 46% at 52% 58%,
    rgba(255, 206, 150, 0.55) 0%,
    rgba(255, 170, 112, 0.18) 48%,
    transparent 72%
  );
  animation: n-rim-light 7.5s var(--ease-soft) infinite alternate;
  pointer-events: none;
}

/* A few fireflies over the hill. One element, five dots, drifting up and fading. */
.n-dawn-figure::after {
  content: "";
  position: absolute;
  inset: -10% -40% 6%;
  background-image:
    radial-gradient(2.5px 2.5px at 16% 86%, rgba(255, 226, 170, 0.95), transparent 70%),
    radial-gradient(2px 2px at 76% 80%, rgba(255, 214, 150, 0.9), transparent 70%),
    radial-gradient(1.8px 1.8px at 44% 64%, rgba(255, 236, 190, 0.8), transparent 70%),
    radial-gradient(1.6px 1.6px at 90% 54%, rgba(255, 214, 150, 0.75), transparent 70%),
    radial-gradient(1.6px 1.6px at 6% 48%, rgba(255, 236, 190, 0.7), transparent 70%);
  background-repeat: no-repeat;
  opacity: 0;
  animation: n-fireflies 14s linear infinite;
  pointer-events: none;
}

@keyframes n-back-breathe {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  35% { transform: translateY(-3px) rotate(0.35deg); }
  70% { transform: translateY(-1px) rotate(-0.3deg); }
}

@keyframes n-rim-light {
  from { opacity: 0.34; transform: scale(0.96); }
  to { opacity: 0.72; transform: scale(1.04); }
}

@keyframes n-fireflies {
  0% { transform: translateY(22px) scale(0.98); opacity: 0; }
  22% { opacity: 0.9; }
  68% { opacity: 0.6; }
  100% { transform: translateY(-52px) scale(1.03); opacity: 0; }
}

.n-dawn-inner {
  position: relative;
  z-index: 5;
  max-width: 640px;
  margin-left: max(var(--gutter), calc((100% - var(--wrap)) / 2));
}

.n-dawn-title {
  margin-top: 20px;
  font-size: clamp(3rem, 7vw, 6.2rem);
  color: #fff6e6;
  text-shadow: 0 20px 50px rgba(40, 12, 6, 0.3);
}

.n-lede-dark {
  color: rgba(255, 246, 232, 0.86);
  max-width: 46ch;
}

.n-facts-dark {
  color: rgba(255, 246, 232, 0.66);
}

.n-facts-dark li {
  border-color: rgba(255, 246, 232, 0.24);
}

.n-eyebrow-dark {
  color: #f6c08a;
}

.n-link-dark {
  border-color: rgba(255, 246, 232, 0.4);
  color: #fff6e6;
}

.n-link-dark:hover {
  border-color: #fff6e6;
}

@media (max-width: 820px) {
  .n-dawn {
    align-items: flex-start;
    padding-top: 120px;
  }

  .n-dawn-inner {
    margin-inline: var(--gutter);
  }

  .n-sun {
    left: 74%;
    bottom: 30%;
    width: 200px;
    margin-left: -100px;
  }

  .n-dawn-hills {
    height: 26%;
  }

  .n-dawn-figure {
    right: 8%;
    bottom: 9%;
    width: 150px;
  }
}

/* ----------------------------------------------------------------- footer -- */

.n-footer {
  position: relative;
  z-index: 2;
  background: var(--night-deep);
  border-top: 1px solid var(--hair);
  padding: 58px 0 34px;
  color: var(--cream-soft);
}

.n-footer-top {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 40px;
}

.n-footer-note {
  max-width: 38ch;
  margin-top: 16px;
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--cream-faint);
}

.n-footer-links {
  display: grid;
  grid-template-columns: repeat(2, minmax(120px, auto));
  gap: 10px 40px;
  font-size: 13.5px;
  align-content: start;
}

.n-footer-links a {
  color: var(--cream-soft);
  transition: color 160ms;
}

.n-footer-links a:hover {
  color: var(--wheat);
}

.n-footer-fine {
  margin-top: 46px;
  padding-top: 20px;
  border-top: 1px solid var(--hair);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  color: rgba(246, 236, 217, 0.36);
}

/* ------------------------------------------------------------- responsive -- */

@media (max-width: 1080px) {
  .n-readout {
    right: 5%;
    width: 208px;
  }

  .n-scroll-cue {
  position: absolute;
  z-index: 7;
  left: var(--gutter);
  bottom: 4.5%;
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--cream-faint);
}

.n-scroll-cue i {
  display: block;
  width: 1px;
  height: 34px;
  background: linear-gradient(180deg, transparent, var(--wheat));
  position: relative;
}

.n-scroll-cue i::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 4px;
  height: 4px;
  margin-left: -2px;
  border-radius: 50%;
  background: var(--wheat);
  animation: n-cue 2.4s var(--ease-soft) infinite;
}

@keyframes n-cue {
  0% { transform: translateY(-30px); opacity: 0; }
  40% { opacity: 1; }
  100% { transform: translateY(0); opacity: 0; }
}

.n-hero-caption {
    display: none;
  }

  .n-figure {
    right: 6%;
    bottom: 26%;
  }

  .n-privacy-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .n-privacy-grid li:nth-child(2) {
    border-right: 0;
  }

  .n-privacy-grid li:nth-child(3),
  .n-privacy-grid li:nth-child(4) {
    border-top: 1px solid var(--hair);
    margin-top: 26px;
  }

  .n-privacy-grid li:nth-child(3) {
    padding-left: 0;
  }

  .n-panel-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .n-panel-art {
    order: -1;
    margin-bottom: 10px;
  }

  .n-panel {
    width: min(100%, 400px);
  }

  .n-act-inner {
    grid-template-columns: minmax(0, 1fr);
    gap: 26px;
  }

  .n-act-side {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    max-width: 460px;
    gap: 20px;
  }

  .n-beats {
    height: 260px;
  }
}

@media (max-width: 820px) {
  .n-header-inner {
    height: 68px;
    gap: 16px;
  }

  /* Three screened swirls at phone size cost more than they show, and the base zoom is enough. */
  .n-sky-swirl {
    display: none;
  }

  .n-sky-base {
    animation-duration: 96s;
  }

  .n-nav {
    display: none;
  }

  .n-hero {
    padding-top: 104px;
    min-height: max(100svh, 760px);
    justify-content: flex-start;
  }

  .n-hero-inner {
    padding-top: 4vh;
  }

  .n-display {
    font-size: clamp(2.6rem, 11vw, 4rem);
    max-width: 11ch;
  }

  .n-lede {
    max-width: 40ch;
    font-size: 0.98rem;
  }

  .n-facts {
    margin-top: 30px;
    font-size: 9.5px;
    letter-spacing: 0.1em;
  }

  .n-facts li {
    padding: 0 10px;
  }

  /* Phones lay out in flow instead of overlapping. The hero becomes a two-column grid: the copy
     spans both, then the sprite and the panel sit side by side. No viewport height or text length
     can push one element on top of another, and the pair still reads as one object. */
  .n-hero {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-content: start;
    align-items: start;
    column-gap: 18px;
    padding: 104px var(--gutter) 46px;
    min-height: 100svh;
  }

  .n-hero-inner {
    grid-column: 1 / -1;
    width: 100%;
    padding-bottom: 0;
  }

  .n-figure {
    position: static;
    grid-column: 1;
    grid-row: 2;
    width: clamp(132px, 38vw, 170px);
    margin: 18px 0 0;
  }

  .n-egg-note {
    position: static;
    grid-column: 1 / -1;
    grid-row: 3;
    width: auto;
    margin: 10px 0 0;
    text-align: left;
  }

  .n-hills {
    height: 32%;
  }

  .n-front {
    height: 12%;
  }

  .n-readout {
    position: static;
    grid-column: 2;
    grid-row: 2;
    align-self: center;
    width: 100%;
    max-width: 300px;
    margin: 18px 0 0;
  }

  .n-scroll-cue {
    display: none;
  }

  .n-dawn .n-facts {
    max-width: 62%;
  }

  .n-starfield {
    opacity: 0.85;
  }

  .n-act-inner {
    padding-bottom: 96px;
    align-content: center;
  }

  .n-act-copy .n-h2 {
    font-size: clamp(1.9rem, 7vw, 2.6rem);
  }

  .n-beats {
    height: 300px;
    margin-top: 28px;
  }

  .n-beat h3 {
    font-size: 1.25rem;
  }

  .n-beat p {
    font-size: 0.94rem;
  }

  .n-act-side {
    display: none;
  }

  .n-timeline {
    bottom: 22px;
  }

  .n-act-hint {
    display: none;
  }

  .n-privacy-grid {
    grid-template-columns: minmax(0, 1fr);
    margin-top: 44px;
  }

  .n-privacy-grid li {
    padding: 22px 0 0 !important;
    border-right: 0;
    border-top: 1px solid var(--hair);
    margin-top: 0 !important;
  }

  .n-privacy-grid li:first-child {
    border-top: 0;
  }

  .n-faq-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .n-faq-head {
    position: static;
  }

  .n-dawn {
    padding: 100px 0 80px;
    align-items: flex-start;
  }

  .n-dawn-inner {
    margin-left: var(--gutter);
    margin-right: var(--gutter);
  }

  /* Bottom-right, not centred: centred, his hat sat on the facts line. */
  .n-dawn-figure {
    right: 4%;
    bottom: 6%;
    width: 132px;
    margin-right: 0;
  }

  .n-sun {
    left: 66%;
    bottom: 20%;
  }

  .n-dawn-hills {
    height: 30%;
  }

  .n-footer-links {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 420px) {
  .n-btn-lg {
    padding: 14px 22px;
    font-size: 15px;
  }

  .n-actions {
    gap: 18px;
  }

  .n-beats {
    height: 330px;
  }
}

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

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

  .n-figure-glow,
  .n-figure-ear {
    opacity: 0.8;
  }
}


/* --------------------------------------------------------- wave edge labels -- */

.n-wave-label {
  position: absolute;
  z-index: 2;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(246, 236, 217, 0.34);
  pointer-events: none;
}

.n-wave-label-ai {
  left: var(--gutter);
  bottom: 38%;
  color: rgba(239, 195, 106, 0.6);
}

.n-wave-label-music {
  left: var(--gutter);
  bottom: 20%;
  color: rgba(240, 138, 95, 0.62);
}

/* ------------------------------------------------------------- choreography -- */

/* The first screen assembles once, in reading order. It is the only entrance the page performs
   on its own; everything after it belongs to the scroll. */
@keyframes n-rise {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.n-kicker,
.n-display,
.n-lede,
.n-actions,
.n-facts,
.n-readout {
  animation: n-rise 900ms var(--ease-out) both;
}

.n-kicker { animation-delay: 80ms; }
.n-display { animation-delay: 150ms; }
.n-lede { animation-delay: 300ms; }
.n-actions { animation-delay: 400ms; }
.n-facts { animation-delay: 500ms; }
.n-readout { animation-delay: 620ms; }

.n-dawn-figure img {
  display: block;
  width: 100%;
  height: auto;
  image-rendering: pixelated;
}

@media (max-width: 1080px) {
  .n-desk img,
  .n-desk svg { width: 78%; margin-inline: auto; }
}

@media (max-width: 820px) {
  .n-egg-note {
    position: static;
    width: auto;
    margin: 10px 0 0;
    text-align: left;
  }

  .n-wave-label-ai { bottom: 40%; }
  .n-wave-label-music { bottom: 22%; }
}

@media (prefers-reduced-motion: reduce) {
  .n-kicker,
  .n-display,
  .n-lede,
  .n-actions,
  .n-facts,
  .n-readout {
    animation: none;
  }
}
