/* ============================================================================
   OFF — teaser web
   Pixel-faithful rebuild of off_web_teaser.pen  →  node "OFF — Teaser web" (bi8Au)

   SCALE MODEL
   The .pen artboard is 1440 x 1609. Every design pixel is expressed here in
   rem, using 16px = 1rem, and the root font-size is 1.1111vw so that the whole
   artboard scales proportionally with the viewport:
        1440px viewport -> 1rem = 16px -> 90rem = 1440px  (exact artboard)
   Above 1440px the artboard is capped at its native size and centred.
   Below 900px a purpose-built stacked layout takes over (see the last block).

   PARALLAX
   motion.js only writes two custom properties per frame:
        --hp  0..1   scroll progress through the hero
        --mp  0..1   scroll progress through the manifesto
   Every parallax transform is a pure CSS calc() of those two numbers, so the
   compositor does the per-element work (216 independent particles included).
   ========================================================================= */

/* ---------------------------------------------------------------- tokens -- */
:root {
  --ink: #000000;
  --paper: #ffffff;
  --paper-warm: #f4f1ea;
  --signal-yellow: #ffe000;
  --signal-blue: #001aff;

  --e-void: #000000;
  --e-surface-0: #08090b;
  --e-surface-1: #0e1013;
  --e-surface-2: #16181d;
  --e-surface-3: #1f2228;
  --e-line: #262a31;
  --e-line-hi: #363b44;
  --e-text-hi: #f2f4f7;
  --e-text-mid: #9aa1ac;
  --e-text-low: #656c77;

  --font-display: 'Gabarito', system-ui, sans-serif;
  --font-headline: 'Inter Tight', system-ui, sans-serif;
  --font-subhead: 'Inter Tight', system-ui, sans-serif;
  --font-sans: 'Inter Tight', system-ui, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, monospace;

  /* Grid rules (from the .pen rectangles) */
  --rule-col: rgba(38, 42, 49, 0.4);   /* #262A3166 */
  --rule-row: rgba(38, 42, 49, 0.239); /* #262A313D */

  /* scroll-driven, written by motion.js */
  --hp: 0;
  --mp: 0;

  /* global parallax amplitude multiplier: 1 on desktop, reduced on touch so a
     phone-sized viewport does not get desktop-scale travel */
  --par: 1;
}

html {
  /* 1440 / 90 = exactly 16px, so the artboard is pixel-exact at 1440 */
  font-size: clamp(9px, calc(100vw / 90), 16px);
  background: var(--e-surface-0);
  -webkit-text-size-adjust: 100%;
}

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

body {
  margin: 0;
  overflow-x: hidden;
  background: var(--e-surface-0);
  color: var(--e-text-hi);
  font-family: var(--font-sans);
  font-synthesis-weight: none;
  /* the artboard relies on exact monospace advances (the particle and terrain
     rasters are character grids): keep glyph metrics unhinted / fractional
     instead of letting the rasteriser snap them to whole pixels */
  text-rendering: geometricPrecision;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

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

/* ============================================================ HERO / OWN == */
.hero {
  position: relative;
  /* The artboard hero is 741px, but on a monitor TALLER than the whole page
     (1609px) the leftover height goes to the hero, pushing the yellow block
     down so the header clip fills the screen instead of leaving a dark strip.
     100vh - manifesto height, floored at the artboard value:
       1440x900  -> max(741, 32)  = 741  (unchanged)
       1440x1609 -> max(741, 741) = 741  (unchanged, boundary)
       1440x1700 -> max(741, 832) = 832  (91px of extra video) */
  height: max(46.3125rem, calc(100vh - 54.25rem));
  overflow: hidden;
  background: var(--e-surface-0);
  isolation: isolate;
}

/* --- background media (video, scrubbed by scroll) ------------------------- */
.hero__media {
  position: absolute;
  left: 0;
  right: 0;
  top: -0.8125rem;             /* -13 */
  /* the artboard overscans the hero by 13px top and bottom */
  height: calc(100% + 1.625rem);
  overflow: hidden;
  background: var(--e-surface-0) url('./assets/hero-poster.jpg') center / cover no-repeat;
}

.hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.6s ease;
}
.is-ready .hero__video { opacity: 1; }

/* canvas fallback for browsers/servers where the clip cannot be seeked */
.hero__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* --- 104px column + 96px row rules --------------------------------------- */
.hero__grid {
  position: absolute;
  inset: 0;
  width: 90rem;
  margin-inline: auto;
  overflow: hidden;
  pointer-events: none;
  background-image:
    linear-gradient(90deg, var(--rule-col) 1px, transparent 1px),
    linear-gradient(0deg, var(--rule-row) 1px, transparent 1px);
  background-size: 6.5rem 100%, 100% 6rem;
  background-position: 6rem 0, 0 6rem;
  background-repeat: repeat, repeat;
}

/* --- content column ------------------------------------------------------ */
.hero__column {
  position: absolute;
  inset: 0;
  width: 90rem;
  margin-inline: auto;
}

.nav {
  position: absolute;
  top: 3rem;                   /* 48 */
  left: 6rem;                  /* 96 */
  width: 78rem;                /* 1248 */
  height: 3rem;                /* 48 */
  display: flex;
  align-items: center;
}

.brand {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 3.875rem;         /* 62 */
  line-height: 1;
  letter-spacing: -0.20625rem; /* -3.3 */
  color: var(--e-text-hi);
  text-decoration: none;
}

.nav__spacer { flex: 1; }

.signup {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;                /* 12 */
  height: 3rem;                /* 48 */
  padding: 0 1.5rem;           /* 0 24 */
  background: var(--signal-yellow);
  color: var(--ink);
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 0.8125rem;        /* 13 */
  line-height: 1;
  letter-spacing: 0.08px;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.2s ease;
}
.signup:hover { background: #fff200; }
.signup:focus-visible { outline: 2px solid var(--paper); outline-offset: 3px; }
.signup svg { width: 1rem; height: 1rem; flex: none; }

/* --- hero copy ----------------------------------------------------------- */
.kicker {
  position: absolute;
  left: 6.625rem;              /* 106 */
  top: 11rem;                  /* 176 */
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.6875rem;        /* 11 */
  line-height: 1.6;
  letter-spacing: 0.08px;
  color: var(--e-text-mid);
  transform: translate3d(0, calc(var(--hp) * var(--par) * -4.375rem), 0);
}

.headline {
  position: absolute;
  left: 6rem;                  /* 96 */
  top: 13.625rem;              /* 218 */
  margin: 0;
  font-family: var(--font-headline);
  font-weight: 200;
  font-size: 6rem;             /* 96 */
  line-height: 1.05;
  letter-spacing: -0.11875rem; /* -1.9 */
  color: var(--e-text-hi);
  white-space: nowrap;
  transform: translate3d(0, calc(var(--hp) * var(--par) * -8.125rem), 0);
}

.subhead {
  position: absolute;
  left: 6.5625rem;             /* 105 */
  top: 21.375rem;              /* 342 */
  margin: 0;
  font-family: var(--font-subhead);
  font-weight: 600;
  font-size: 2.3125rem;        /* 37 */
  line-height: 1.05;
  color: var(--paper);
  white-space: nowrap;
  transform: translate3d(0, calc(var(--hp) * var(--par) * -6.25rem), 0);
}

/* --- yellow particle field ---------------------------------------------- */
/* Full-bleed so the field can reach both viewport edges on wide screens.
   motion.js generates the extra columns and offsets the raster with a negative
   margin-left so the ORIGINAL 200 columns stay exactly where the artboard puts
   them. The artboard node (pIPzU) now sits at x=0, y=624, i.e. 117px above the
   hero's bottom edge -> `top: 100% - 7.3125rem` is 624 when the hero is 741. */
.hero__particles {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(100% - 7.3125rem); /* 117 above the hero's bottom edge -> 624 */
  height: 44rem;               /* 704 (the raster overflows and is clipped) */
  pointer-events: none;
  /* clip horizontally only: the raster is shifted left of the viewport and the
     hero clips the band vertically, but the particles must be free to travel
     up with the parallax */
  overflow-x: clip;
  overflow-y: visible;
}

.grain {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.6875rem;        /* 11 */
  font-weight: 400;
  line-height: 1;
  /* no tracking: pen.dev renders the generated raster at exactly 0.6em per
     cell (200 cells = 1320px, matching the pen export to the pixel) */
  letter-spacing: 0;
  color: #ffd900;
  white-space: pre;
  font-variant-ligatures: none;
}

/* one particle = one <i>, each with its own parallax vector */
.grain i {
  display: inline-block;
  font-style: normal;
  font-weight: 400;
  will-change: transform;
  transform: translate3d(
    calc(var(--hp) * var(--par) * var(--dx, 0rem)),
    calc(var(--hp) * var(--par) * var(--dy, 0rem)),
    0
  );
}

/* ====================================================== MANIFESTO / LOCAL == */
.manifesto {
  position: relative;
  height: 54.25rem;            /* 868 */
  overflow: hidden;
  background: var(--signal-yellow);
}

.manifesto__inner {
  position: absolute;
  inset: 0;
  width: 90rem;
  margin-inline: auto;
  transform: translate3d(0, calc(var(--mp) * var(--par) * 4.375rem), 0);
}

/* dash terrain, masked by the two flat copy bands */
.terrain {
  position: absolute;
  left: 1.25rem;               /* 20 */
  top: 12.6875rem;             /* 203 */
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.6875rem;        /* 11 */
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0;           /* raster node: untracked, like the grain */
  color: var(--ink);
  white-space: pre;
  font-variant-ligatures: none;
}

.band {
  position: absolute;
  left: 0;
  width: 100%;
  background: var(--signal-yellow);
}

.band--top {
  top: 1rem;                   /* 16  (path node y=4 + geometry y=12) */
  height: 25.75rem;            /* 412 */
}

.band--bottom {
  top: 45.3125rem;             /* 725 */
  height: 5.8125rem;           /* 93 */
}

/* --- manifesto copy ------------------------------------------------------ */
.manifesto__headline {
  position: absolute;
  left: 27.5rem;               /* 440 */
  top: 7.5625rem;              /* 121 */
  width: 45.9375rem;           /* 735 */
  margin: 0;
  /* the artboard splits this into a frame with two stacked text nodes */
  display: flex;
  flex-direction: column;
  font-family: var(--font-headline);
  font-weight: 200;
  font-size: 4rem;             /* 64 */
  line-height: 1.05;
  letter-spacing: -0.08125rem; /* -1.3 */
  color: var(--ink);
  /* the block moves as a unit (parent); the headline gets its own extra
     offset so it reads as a headline-level parallax layer */
  transform: translate3d(0, calc(var(--mp) * var(--par) * -2.8125rem), 0);
}

.manifesto__headline-tokens { font-weight: 500; }
.manifesto__headline-date { font-weight: 200; }

.manifesto__body {
  position: absolute;
  left: 27.5rem;               /* 440 */
  top: 22.3125rem;             /* 357 */
  width: 31.6875rem;           /* 507 */
  margin: 0;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 1.5rem;           /* 24 */
  line-height: 1.5;
  color: var(--ink);
}

/* --- subscription form --------------------------------------------------- */
/* --- subscription block + temporary gate --------------------------------- */
/* pen node Xwh4J: the form (440,464) 560x64 and the consent row at +80.
   pen node oShcg covers the whole block: (440,464) 560x98. */
.signup-gate {
  position: absolute;
  left: 27.5rem;               /* 440 */
  top: 29rem;                  /* 464 */
  width: 35rem;                /* 560 */
  height: 6.125rem;            /* 98  = form 64 + gap + consent */
}

.form {
  position: static;
  width: 100%;
  height: 4rem;                /* 64 */
  display: flex;
  background: var(--e-surface-0);
  border: 1px solid var(--e-line-hi);
  scroll-margin-top: 6rem;
}

.form__input {
  flex: 1;
  min-width: 0;
  padding: 0 1.5rem;           /* 0 24 */
  background: transparent;
  border: 0;
  color: var(--e-text-hi);
  font-family: var(--font-mono);
  font-size: 0.875rem;         /* 14 */
  line-height: 1.7142;
  letter-spacing: 0.08px;
}
.form__input::placeholder { color: var(--e-text-mid); opacity: 1; }
.form__input:focus { outline: none; }
.form__input:focus-visible { box-shadow: inset 0 0 0 1px var(--signal-blue); }

.form__submit {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;                /* 12 */
  height: 100%;
  padding: 0 2rem;             /* 0 32 */
  background: var(--signal-blue);
  border: 0;
  color: var(--paper);
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 0.875rem;         /* 14 */
  line-height: 1.5;
  letter-spacing: 0.08px;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.2s ease;
}
.form__submit:hover { background: #0026ff; }
.form__submit:focus-visible { outline: 2px solid var(--e-surface-0); outline-offset: -3px; }
.form__submit svg { width: 1rem; height: 1rem; flex: none; }

/* --- consent ------------------------------------------------------------- */
.consent {
  position: absolute;
  left: 0;
  top: 5rem;                   /* 80 -> 544 from the section top */
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;                 /* 8 */
  cursor: pointer;
}

/* pen node oShcg — temporary "coming soon" gate over the subscription block.
   Translucent #08090B (0xE0 = 87.8%) with a backdrop blur and an inner 1px
   yellow rule.
   The artboard declares `background_blur radius 12`; measured against the
   pen.dev render, radius 12 behaves like a CSS blur of about half that (their
   radius is diameter-ish, CSS blur() takes a standard deviation), so 0.375rem
   — 6px at the 1440 artboard — reproduces it: mean panel diff 4.06/255 at
   blur(6px) versus 5.18/255 at blur(12px). */
.coming-soon {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #08090be0;
  border: 1px solid var(--signal-yellow);
  backdrop-filter: blur(0.375rem);
  -webkit-backdrop-filter: blur(0.375rem);
}

.coming-soon__label {
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: 0.8125rem;        /* 13 */
  line-height: 1;
  letter-spacing: 0.52px;
  color: var(--e-text-hi);
}

.consent__box {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  width: 1rem;                 /* 16 */
  height: 1rem;
  margin: 0;
  border: 1px solid var(--ink);
  border-radius: 0;
  background: transparent;
  cursor: pointer;
}
.consent__box:checked {
  background: var(--ink)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 8.5l3.2 3.2L13 5' fill='none' stroke='%23FFE000' stroke-width='2'/%3E%3C/svg%3E")
    center / 0.75rem 0.75rem no-repeat;
}
.consent__box:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

.consent__text {
  font-family: var(--font-mono);
  font-size: 0.6875rem;        /* 11 */
  line-height: 1.6;
  letter-spacing: 0.08px;
  color: var(--ink);
}

/* --- footer note --------------------------------------------------------- */
.note {
  position: absolute;
  left: 37.0625rem;            /* 593 */
  top: 47.6875rem;             /* 763 */
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.6875rem;        /* 11 */
  line-height: 1.6;
  letter-spacing: 0.08px;
  color: var(--ink);
}

/* form status (no backend yet) -------------------------------------------- */
.form-status {
  position: absolute;
  left: 27.5rem;
  top: 34.75rem;
  margin: 0;
  max-width: 35rem;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  line-height: 1.6;
  color: var(--ink);
  opacity: 0;
  transition: opacity 0.3s ease;
}
.form-status:not(:empty) { opacity: 0.75; }

/* ========================================================== accessiblity == */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ======================================================= reduced motion == */
@media (prefers-reduced-motion: reduce) {
  :root { --hp: 0 !important; --mp: 0 !important; }
  .kicker,
  .headline,
  .subhead,
  .manifesto__inner,
  .manifesto__headline,
  .grain i { transform: none !important; }

  html { scroll-behavior: smooth; }
}

/* ================================================================ mobile == */
@media (max-width: 900px) {
  html { font-size: 16px; }

  /* the parallax runs on touch too, just with shorter travel: desktop
     amplitudes are sized for a 1440x900 artboard, not for a phone */
  :root { --par: 0.45; }

  .hero {
    height: auto;
    min-height: 100svh;
    padding: 1.5rem 1.5rem 3rem;
    display: flex;
    flex-direction: column;
  }

  .hero__media {
    top: 0;
    height: 100%;
  }

  .hero__grid {
    width: 100%;
    background-size: 5.5rem 100%, 100% 5rem;
    background-position: 1.5rem 0, 0 5rem;
  }

  .hero__column {
    position: static;
    width: auto;
    margin: 0;
    display: contents;
  }

  /* the media/grid are absolutely positioned, so the copy and the nav have to
     be lifted out of the normal flow to stay in front of them (the copy used to
     rely on its parallax transform, which reduced-motion removes) */
  .nav,
  .kicker,
  .headline,
  .subhead { position: relative; z-index: 2; inset: auto; }

  .nav {
    width: auto;
    height: auto;
    margin-bottom: auto;
  }

  .brand { font-size: 2.75rem; letter-spacing: -0.15rem; }
  .signup { height: 2.5rem; padding: 0 1rem; font-size: 0.75rem; }

  .kicker {
    margin: 3.5rem 0 0;
    font-size: 0.6875rem;
  }

  .headline {
    margin: 0.75rem 0 0;
    font-size: clamp(2.75rem, 13.5vw, 5rem);
    letter-spacing: -0.03em;
    white-space: normal;
  }

  .subhead {
    margin: 1rem 0 0;
    font-size: clamp(1.0625rem, 4.6vw, 1.625rem);
    white-space: normal;
    max-width: 24rem;
  }

  .hero__particles {
    /* same 117px band as the artboard, absolute rather than proportional so it
       stays clear of the copy; the hero clips it */
    bottom: auto;
    height: auto;
    z-index: 1;
    opacity: 0.92;
  }
  .grain { font-size: 0.5rem; }

  .manifesto {
    height: auto;
    padding: 4.5rem 1.5rem 3.5rem;
  }

  /* full-bleed ground: expand into the section padding so the texture covers
     the whole block, and keep the copy above it for legibility */
  .manifesto__ground { position: absolute; inset: -4.5rem -1.5rem -3.5rem; overflow: hidden; z-index: 0; }
  .band { display: none; }
  .terrain {
    left: 0.5rem;
    top: -9rem;
    font-size: 0.5rem;
    opacity: 0.35;
  }

  .manifesto__inner {
    /* relative (not static): the ground/terrain/bands inside are absolutely
       positioned and need a containing block even when the parallax transform
       is neutralised */
    position: relative;
    width: auto;
    margin: 0;
  }

  .manifesto__headline,
  .manifesto__body,
  .form,
  .consent,
  .note,
  .form-status {
    position: relative;
    z-index: 1;
    inset: auto;
  }

  .manifesto__headline {
    width: auto;
    font-size: clamp(1.875rem, 8.6vw, 2.75rem);
    letter-spacing: -0.02em;
  }

  .manifesto__body {
    width: auto;
    max-width: 26rem;
    margin: 1.5rem 0 0;
    font-size: 1rem;
  }

  .form {
    width: 100%;
    height: auto;
    flex-direction: column;
  }
  /* .form__input inherits `flex: 1` (basis 0) from the desktop rule, which
     collapses it to a hairline in a column container. Stack both full width. */
  .form__input {
    flex: none;
    width: 100%;
    height: 3.25rem;
  }
  .form__submit {
    width: 100%;
    height: 3.25rem;
    justify-content: center;
  }

  /* the gate wraps the stacked form + consent and covers both */
  .signup-gate {
    position: relative;
    inset: auto;
    width: 100%;
    max-width: 30rem;
    height: auto;
    margin: 1.75rem 0 0;
  }

  .consent {
    position: static;
    margin: 0.875rem 0 0;
  }
  .consent__text { white-space: normal; }

  .form-status {
    margin: 0.75rem 0 0;
    max-width: 30rem;
  }

  .note {
    margin: 3rem 0 0;
  }
}

/* keep the layout usable on very short viewports */
@media (max-width: 900px) and (max-height: 560px) {
  .hero { min-height: 32rem; }
}

/* footer note: the privacy policy link inherits the note, lights up yellow */
.note a { color: inherit; }
.note a:hover, .note a:focus-visible { color: #ffd900; }
