@font-face {
  font-family: "n-display";
  font-style: normal;
  font-weight: 700 900;
  font-display: swap;
  src: url("fonts/unbounded-latin-var.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+2122, U+2212, U+FFFD;
}

/* =========================================================================
   waitnroom - VHS landing. One screen, no scroll. The page is a tape:
   the reference fbm smoke shader fills the viewport, film layers ride
   above it, and a CRT chrome frames the edges. Every chrome element
   carries true information: the wordmark (top center), the line's real
   number (bottom left, wide screens), 18+ (bottom center), and the room
   clock (bottom right - rooms run 5 minutes; the loop is the urgency).
   Center stage holds exactly one message and one control.
   Single committed theme. All motion freezes under reduced motion.
   ========================================================================= */

:root {
  --v-font: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, Roboto,
            "Helvetica Neue", Arial, sans-serif;
  --v-display: "n-display", "Trebuchet MS", -apple-system, BlinkMacSystemFont,
            "Segoe UI", system-ui, Arial, sans-serif;
  --v-mono: ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;

  --v-bg:   #0A0714;
  --v-ink:  #F5F2FA;
  --v-dim:  rgba(245, 242, 250, 0.86);
  --v-mint: #7DF5B6;
  --v-red:  #FF3B5C;

  /* one radius language for the rounded controls */
  --v-radius: 8px;

  /* the CRT type system: every text element carries a channel split scaled
     to its size, plus phosphor bloom - nothing sits sharp ON the tape,
     everything lives IN it. three tiers: lg (headline), md (sub/cta),
     sm (labels, chrome, whispers). */
  --v-split-lg: 2px 0 rgba(255, 59, 92, 0.65), -2px 0 rgba(57, 208, 255, 0.65);
  --v-split-md: 1.5px 0 rgba(255, 59, 92, 0.55), -1.5px 0 rgba(57, 208, 255, 0.55);
  --v-split-sm: 1px 0 rgba(255, 59, 92, 0.45), -1px 0 rgba(57, 208, 255, 0.45);

  /* chrome inset honors notches / home indicators */
  --v-edge-x: max(18px, env(safe-area-inset-left), env(safe-area-inset-right));
  --v-edge-t: max(20px, env(safe-area-inset-top));
  --v-edge-b: max(24px, env(safe-area-inset-bottom));
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0;
  height: 100%;
  color-scheme: dark;             /* single committed dark theme; no UA light widgets */
  overflow: hidden;               /* one screen. the tape does not scroll. */
  background: var(--v-bg);
  color: var(--v-ink);
  font-family: var(--v-font);
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }

/* --- layer 0: the smoke shader ------------------------------------------ */
#glbg {
  position: fixed; inset: 0;
  width: 100vw; height: 100dvh;
  z-index: 0;
  opacity: 1;                     /* permanent gradient underlay: ANY WebGL
                                     failure still shows a tape-like field */
  background: radial-gradient(ellipse at 30% 20%,
    #3A2E8C 0%, #16102E 45%, #0A0714 100%);
}
@media (prefers-reduced-motion: no-preference) {
  #glbg { opacity: 0; animation: v-canvas-in 2s ease-out 0.15s forwards; }
}
@keyframes v-canvas-in { from { opacity: 0; transform: scale(1.06); }
                         to   { opacity: 1; transform: scale(1); } }

/* the reference's 800 noise particles, above the smoke */
#pfx {
  position: fixed; inset: 0;
  width: 100vw; height: 100dvh;
  z-index: 1; pointer-events: none;
  opacity: 0.8;
}

/* faint scrim so the mono lines stay readable over hot pink */
.v-scrim {
  position: fixed; inset: 0; z-index: 2; pointer-events: none; contain: paint;
  background: radial-gradient(
    ellipse 80% 74% at 50% 52%,
    rgba(6, 4, 14, 0.44) 0%,
    rgba(6, 4, 14, 0.20) 58%,
    transparent 100%
  );
}

/* --- film layers ---------------------------------------------------------- */
.v-grain {
  position: fixed; inset: 0; width: 100vw; height: 100dvh;
  z-index: 40; pointer-events: none; contain: paint;
  opacity: 0.11; mix-blend-mode: screen;
  image-rendering: pixelated;
}
.v-scanlines {
  position: fixed; inset: 0; z-index: 41; pointer-events: none; contain: paint;
  background: repeating-linear-gradient(
    0deg,
    transparent 0px, transparent 2px,
    rgba(255, 255, 255, 0.1) 2px, rgba(255, 255, 255, 0.1) 4px
  );
  opacity: 0.35;
}
.v-vignette {
  position: fixed; inset: 0; z-index: 42; pointer-events: none; contain: paint;
  background: radial-gradient(ellipse at center,
    transparent 52%, rgba(2, 1, 8, 0.66) 100%);
}

/* --- CRT chrome (real information wearing the tape's uniform) ------------- */
.v-chrome { position: fixed; inset: 0; z-index: 60; pointer-events: none; }
.osd {
  position: fixed;
  font-family: var(--v-mono);
  font-size: 0.74rem;
  line-height: 1;
  letter-spacing: 0.16em;
  color: var(--v-dim);
  text-shadow: var(--v-split-sm), 0 0 10px rgba(0, 0, 0, 0.85);
  white-space: nowrap;
}
.osd-tl { top: var(--v-edge-t); left: var(--v-edge-x); color: var(--v-mint); }
.osd-tr { top: var(--v-edge-t); right: var(--v-edge-x); }
.osd-bc { bottom: var(--v-edge-b); left: 50%; transform: translateX(-50%);
          text-indent: 0.16em; }
.osd-br { bottom: var(--v-edge-b); right: var(--v-edge-x);
          color: var(--v-mint); font-variant-numeric: tabular-nums; }
.osd-br .clock-lbl { color: var(--v-dim); }
/* mint bloom only on the live/mint indicators, not the neutral chrome */
.osd-tl, .osd-br { text-shadow: var(--v-split-sm),
             0 0 10px rgba(0, 0, 0, 0.85), 0 0 8px rgba(125, 245, 182, 0.25); }

/* the wordmark rides the frame like a channel bug */
.v-bug {
  position: fixed;
  top: calc(var(--v-edge-t) - 2px); left: 50%; transform: translateX(-50%);
  margin: 0;
  line-height: 1;
  font-family: var(--v-display);
  font-weight: 800;
  font-size: 1.02rem;
  letter-spacing: 0.03em;
  text-indent: 0.03em;
  color: var(--v-ink);
  text-shadow: var(--v-split-md), 0 0 14px rgba(0, 0, 0, 0.8);
}
.v-bug .dot { color: var(--v-mint); }

/* the line's real number: wide screens only (on a phone, the CTA is the way) */
.osd-bl {
  bottom: var(--v-edge-b); left: var(--v-edge-x);
  display: none;
}
@media (min-width: 880px) and (hover: hover) and (pointer: fine) {
  .osd-bl { display: block; }
}

.rec-dot {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  background: var(--v-red); vertical-align: 1px;
  box-shadow: 0 0 6px rgba(255, 59, 92, 0.9);
}
@media (prefers-reduced-motion: no-preference) {
  .rec-dot { animation: v-blink 1.4s steps(1) infinite; }
}
@keyframes v-blink { 0%, 60% { opacity: 1; } 61%, 100% { opacity: 0.15; } }

/* --- the stage: one message, one control ----------------------------------- */
.v-stage {
  position: relative; z-index: 50;
  height: 100dvh;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center;
  padding: 0 var(--v-edge-x);
}

.v-title {
  position: relative;
  margin: 0;
  font-family: var(--v-display);
  font-weight: 900;
  /* ONE centered line always. font is sized so even the longest rotating phrase
     ("n knows a co-founder…") fits on a single line at any width; shorter words
     simply center with side space. no wrap, so the hero never re-flows. */
  font-size: clamp(1.2rem, 5.8vw, 6rem);
  line-height: 1.05;
  letter-spacing: -0.015em;
  white-space: nowrap;
  color: var(--v-ink);
  text-shadow: var(--v-split-lg),
               0 4px 34px rgba(0, 0, 0, 0.75),
               0 0 26px rgba(255, 255, 255, 0.22);
}
.v-title .accent, .v-bug .accent { color: var(--v-mint); }

/* scramble overlay: bursts show corruption for ~100ms while the real copy blinks
   off - the actual text node is never mutated. one centered line matching the
   headline, so the corruption lands exactly over the real words. */
.v-scramble {
  position: absolute; inset: 0;
  display: none;
  white-space: nowrap;
  color: var(--v-ink);
  pointer-events: none;
  text-shadow: var(--v-split-lg), 0 4px 34px rgba(0, 0, 0, 0.75);
}
.v-title.is-scrambling .v-real     { visibility: hidden; }
.v-title.is-scrambling .v-scramble { display: block; }

.v-sub {
  margin: clamp(16px, 3dvh, 28px) 0 0;
  font-family: var(--v-mono);
  font-size: clamp(0.82rem, 2.6vw, 1.12rem);
  letter-spacing: 0.14em;
  text-indent: 0.14em;
  color: var(--v-ink);
  text-shadow: var(--v-split-md), 0 0 12px rgba(0, 0, 0, 0.9);
}

/* moods: quieter than the sub line - a whispered tag row, not a second slogan */
.v-moods {
  margin: clamp(8px, 1.6dvh, 14px) 0 0;
  font-family: var(--v-mono);
  font-size: clamp(0.68rem, 2.1vw, 0.85rem);
  letter-spacing: 0.3em;
  text-indent: 0.3em;
  color: var(--v-mint);
  opacity: 0.9;
  text-shadow: var(--v-split-sm),
               0 0 8px rgba(125, 245, 182, 0.55),
               0 0 14px rgba(0, 0, 0, 0.9);
}

.v-cta {
  position: relative;
  display: inline-block;
  margin-top: clamp(22px, 4.5dvh, 40px);
  padding: 16px 46px;
  font-family: var(--v-mono);
  font-size: clamp(1rem, 3vw, 1.2rem);
  font-weight: 700;
  letter-spacing: 0.22em;
  text-indent: 0.22em;
  text-decoration: none;
  color: var(--v-mint);
  background: rgba(125, 245, 182, 0.10);
  border: 2px solid var(--v-mint);
  border-radius: var(--v-radius);
  overflow: hidden;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  text-shadow: var(--v-split-md), 0 0 10px rgba(125, 245, 182, 0.6);
  box-shadow: 0 0 22px rgba(125, 245, 182, 0.25),
              inset 0 0 18px rgba(125, 245, 182, 0.06);
  transition: transform 0.2s ease, background 0.2s ease, color 0.2s ease;
}
.v-cta:hover, .v-cta:focus-visible {
  background: rgba(125, 245, 182, 0.28);
  color: #EAFFF4;
  transform: scale(1.04);
}
.v-cta:active {                       /* touch gets tactility, not hover */
  background: rgba(125, 245, 182, 0.34);
  color: #EAFFF4;
  transform: scale(0.97);
}
.v-cta:focus-visible { outline: 2px solid var(--v-ink); outline-offset: 3px; }
.v-cta .shine {
  position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 30%,
    rgba(125, 245, 182, 0.35) 50%, transparent 70%);
  transform: translateX(-110%);
  pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  .v-cta:hover .shine, .v-cta:focus-visible .shine, .v-cta:active .shine {
    animation: v-shine 0.5s linear forwards;
  }
}
@keyframes v-shine { to { transform: translateX(110%); } }

.v-waitlist {
  margin: clamp(12px, 2.4dvh, 18px) 0 0;
  font-family: var(--v-mono);
  font-size: clamp(0.66rem, 2vw, 0.74rem);
  letter-spacing: 0.12em;
  text-indent: 0.12em;
  color: var(--v-dim);
  text-shadow: var(--v-split-sm), 0 0 10px rgba(0, 0, 0, 0.9);
}

/* --- qr chip (wide, hover-capable screens) ---------------------------------- */
.v-qr {
  position: fixed;
  right: var(--v-edge-x);
  bottom: calc(var(--v-edge-b) + 1.6rem + 12px);
  z-index: 60;
  display: none;
  align-items: center; gap: 10px;
  padding: 8px;
  background: rgba(10, 7, 20, 0.72);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: var(--v-radius);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
@media (min-width: 880px) and (hover: hover) and (pointer: fine) {
  .v-qr { display: flex; }
}
.v-qr svg { width: 68px; height: 68px; display: block; background: #fff;
            border-radius: 4px; padding: 4px; }
.v-qr .lbl {
  font-family: var(--v-mono); font-size: 0.66rem; letter-spacing: 0.14em;
  color: var(--v-dim); max-width: 9ch; text-align: left;
  text-shadow: var(--v-split-sm), 0 0 8px rgba(0, 0, 0, 0.8);
}

/* --- entrance sequence -------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  .v-in {
    opacity: 0;
    transform: translateY(46px) scale(0.94);
    filter: blur(10px);
    animation: v-rise 1.15s cubic-bezier(0.19, 1, 0.22, 1) forwards;
  }
  .v-in-1 { animation-delay: 0.50s; }
  .v-in-2 { animation-delay: 0.66s; }
  .v-in-3 { animation-delay: 0.82s; }
  .v-in-4 { animation-delay: 0.98s; }
  .v-in-5 { animation-delay: 1.14s; }
}
@keyframes v-rise {
  to { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); }
}

/* once the page has been 'watched', the film texture recedes a notch so the
   hero becomes the loud element. body.is-settled is added by JS ~2.4s after
   load; base state stays fully lit so reduced motion is never dimmed. */
@media (prefers-reduced-motion: no-preference) {
  #pfx, .v-grain { transition: opacity 1.4s ease; }
  body.is-settled #pfx { opacity: 0.55; }
  body.is-settled .v-grain { opacity: 0.08; }
}

/* CRT chrome powers up with the tape: one soft unified fade, not a stagger */
@media (prefers-reduced-motion: no-preference) {
  .v-chrome { opacity: 0; animation: chrome-fade 0.6s ease 0.15s forwards; }
}
@keyframes chrome-fade { to { opacity: 1; } }

/* whole-stage glitch pulse (hue snap + jitter), fired by JS every few sec */
@media (prefers-reduced-motion: no-preference) {
  .v-stage.is-pulsing { animation: v-pulse 0.28s steps(2) 1; }
}
@keyframes v-pulse {
  0%   { filter: hue-rotate(45deg) saturate(1.2); transform: translateX(2px); }
  50%  { filter: none;                            transform: translateX(-2px); }
  100% { filter: none;                            transform: translateX(0); }
}

/* --- small / short screens ------------------------------------------------------ */
@media (max-width: 480px) {
  .osd { font-size: 0.62rem; }
  .v-bug { font-size: 0.92rem; }
  .v-cta { padding: 15px 36px; }
  .v-sub { letter-spacing: 0.12em; }
  .v-moods { letter-spacing: 0.22em; }
  /* the phone number corner is empty on mobile - 18+ takes it, so the
     centered label can never collide with the room clock at 320px */
  .osd-bc { left: var(--v-edge-x); transform: none; }
}
@media (max-width: 340px) {
  /* headline font stays on the base clamp so the longest word still fits one line */
  .v-sub { font-size: 0.72rem; }
}
@media (max-height: 620px) {
  /* short/landscape screens: shrink the headline for height, still one line + fits width */
  .v-title { font-size: clamp(1.4rem, 3.4vw, 2.4rem); }
  .v-sub { margin-top: 12px; }
  .v-cta { margin-top: 16px; }
  .v-waitlist { margin-top: 6px; }
}

