/* =====================================================================
   null;limit — /styles.css
   One stylesheet for the one page. Tokens and metal treatments are
   pasted verbatim from the brand kit (snippets/tokens.css, metal.css)
   and are the only colour values on the site. Do not invent values.
   ===================================================================== */


/* ---------------------------------------------------------------------
   1. TOKENS  (brand kit: snippets/tokens.css)
   --------------------------------------------------------------------- */
:root {
  /* ---- field: neutral near-black. no blue, no purple */
  --bg:          #0B0C0E;
  --surface:     #131518;
  --surface-2:   #1B1E22;
  --border:      #262A2F;
  --border-hi:   #363B42;

  /* ---- text ramp */
  --text:        #E8EAED;
  --text-2:      #A8AEB5;
  --muted:       #6B7278;
  --dim:         #464C52;

  /* ---- metals. separate by tone and luminance, never by hue */
  --silver:      #C9CFD6;   /* THE accent. flat stand-in for the gradient */
  --platinum:    #DDE3E8; /* lightest, coolest */
  --steel:       #9AA3AC;    /* neutral mid */
  --titanium:    #B8B2AA; /* warm grey */
  --nickel:      #A9A29B;   /* warmer still */
  --gunmetal:    #5C646D; /* dark metal — use on light backgrounds */

  --grad-silver: linear-gradient(135deg,
    #FFFFFF 0%, #B9BEC4 18%, #F4F6F8 38%, #8D949B 55%,
    #E6E9EC 72%, #A2A8AE 88%, #DFE3E6 100%);
  --grad-silver-soft: linear-gradient(135deg, #E6E9EC 0%, #A2A8AE 50%, #DFE3E6 100%);
  --grad-edge: linear-gradient(135deg, #363B42 0%, #6B7278 45%, #2A2E33 100%);

  --nl-accent: var(--silver);

  /* ---- light, never pigment. These two hues appear only as glow, bloom,
     focus, and hover — never a fill, never body text, never a resting
     border, never on the metal. Remove every glow and the page must still
     be a correct monochrome null;limit page. */
  --glow-green:  #3DFFA8;   /* phosphor. the primary signal */
  --glow-purple: #A78BFA;   /* secondary, ~a third as often */
}

/* ---- ecosystem categories.
   The old set separated by hue: purple / blue / gold / pink / volt.
   Hue is gone. Categories now separate by metal tone plus luminance, and the
   scale runs light to dark so it reads as a sequence, not a rainbow. */
:root {
  --cat-agents:  var(--platinum);
  --cat-tools:   var(--silver);
  --cat-crypto:  var(--titanium);
  --cat-consult: var(--steel);
  --cat-content: var(--nickel);
  --cat-future:  var(--gunmetal);
}


/* ---------------------------------------------------------------------
   2. METAL  (brand kit: snippets/metal.css)
   --------------------------------------------------------------------- */
/* Metal surfaces.
   Gradients belong on things that are LARGE or SHINY — display type, the mark,
   a hairline, a key border. Body copy stays flat --text. A gradient under 20px
   is noise and it costs you contrast. */

.metal-text {                       /* display type only, 28px and up */
  color: var(--platinum);           /* fallback if background-clip is unsupported */
  background-image: var(--grad-silver);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .metal-text { color: var(--platinum); -webkit-text-fill-color: currentColor; }
}

.metal-border {
  border: 1px solid transparent;
  border-radius: 10px;
  background:
    linear-gradient(var(--surface), var(--surface)) padding-box,
    var(--grad-edge) border-box;
}

.metal-rule { height: 1px; border: 0; background: var(--grad-edge); }

.metal-panel {
  background: linear-gradient(160deg, var(--surface-2) 0%, var(--surface) 60%);
  border: 1px solid var(--border);
}

.metal-btn {
  color: var(--text); background: var(--surface);
  border: 1px solid var(--border-hi); border-radius: 8px; padding: .7em 1.4em;
  transition: border-color .18s ease, color .18s ease;
}
.metal-btn:hover { border-color: var(--silver); color: var(--platinum); }

/* ---- THE MARK. Primary. Use on its own. */
.nl-mark {
  height: 28px; width: auto; display: block;
  color: var(--text);            /* the two bars */
  min-height: 20px;
}
.nl-mark--nav  { height: 26px; }
.nl-mark--hero { height: 120px; }
.nl-mark--small { --nl-accent: var(--silver); }   /* flat below ~28px */
.section--light .nl-mark { color: var(--bg); --nl-accent: var(--gunmetal); }

/* ---- THE WORDMARK. Alternative. Never in the same place as the mark. */
.nl-wordmark { height: 22px; width: auto; display: block; color: var(--text); }
.section--light .nl-wordmark { color: var(--bg); --nl-accent: var(--gunmetal); }

@media (prefers-reduced-motion: no-preference) {
  .nl-mark--link, .nl-wordmark--link { transition: opacity .15s ease; }
  .nl-mark--link:hover, .nl-wordmark--link:hover { opacity: .82; }
}


/* ---------------------------------------------------------------------
   3. BASE
   --------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --serif: 'Playfair Display', Georgia, 'Times New Roman', serif;
  --gap-section: clamp(96px, 14vh, 180px);
  --measure: min(1040px, 92vw);
}

html {
  background: var(--bg);
  color: var(--text);
  font-family: var(--mono);
  font-size: 15px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-text-size-adjust: 100%;
  scrollbar-gutter: stable;
  scroll-behavior: smooth;
}
body {
  background: var(--bg);
  min-height: 100vh;
  overflow-x: hidden;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* ---------------------------------------------------------------------
   FX STACK — depth, back to front:
   vignette (z1) → grid (z2) → glow pools (z3) → grain + scanlines (z4)
   → content (z5). Everything fixed, everything pointer-events: none.
   --------------------------------------------------------------------- */

/* Vignette — pulls focus to the column. */
html::before {
  content: '';
  position: fixed; inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(ellipse 120% 90% at 50% 42%, transparent 58%, rgba(0, 0, 0, .42) 100%);
}

/* Grid — 1px lines at 80px, masked so it dies at the edges. */
html::after {
  content: '';
  position: fixed; inset: 0;
  z-index: 2;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(255,255,255,.02) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.02) 1px, transparent 1px);
  background-size: 80px 80px;
  -webkit-mask-image: radial-gradient(ellipse 90% 80% at 50% 45%, #000 30%, transparent 75%);
  mask-image: radial-gradient(ellipse 90% 80% at 50% 45%, #000 30%, transparent 75%);
}

/* Glow pools — light in the dead space. Drift is transform-only; the pulse
   after the count-up is an opacity transition driven from intro.js. */
.fx-glow {
  position: fixed;
  z-index: 3;
  pointer-events: none;
  width: min(900px, 92vw);
  height: 540px;
  left: 50%;
  margin-left: calc(min(900px, 92vw) / -2);
  border-radius: 50%;
  filter: blur(90px);
  opacity: .7;                      /* pulse raises this to 1, then settles */
  transition: opacity 1.3s ease;
}
.fx-glow--green {
  top: 4vh;
  background: radial-gradient(closest-side, rgba(61, 255, 168, .14), transparent 70%);
}
.fx-glow--purple {
  bottom: -14vh;
  background: radial-gradient(closest-side, rgba(167, 139, 250, .11), transparent 70%);
}

/* Grain — texture, not effect. Oversized so the shimmer can travel. */
body::before {
  content: '';
  position: fixed; inset: -50%;
  z-index: 4;
  pointer-events: none;
  opacity: .028;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* Scanlines — barely there. */
body::after {
  content: '';
  position: fixed; inset: 0;
  z-index: 4;
  pointer-events: none;
  background: repeating-linear-gradient(0deg, transparent 0 3px, rgba(0,0,0,.018) 3px 4px);
}

/* Motion for the stack — all of it dies with prefers-reduced-motion.
   Glows stay: they're light, not motion. */
@media (prefers-reduced-motion: no-preference) {
  .fx-glow--green  { animation: fx-drift-a 75s ease-in-out infinite alternate; }
  .fx-glow--purple { animation: fx-drift-b 90s ease-in-out infinite alternate; }
  body::before     { animation: fx-grain 1.2s steps(1, end) infinite; }
}
@keyframes fx-drift-a { from { transform: translate(0, 0); } to { transform: translate(34px, 18px); } }
@keyframes fx-drift-b { from { transform: translate(0, 0); } to { transform: translate(-30px, -22px); } }
@keyframes fx-grain {
  0%, 100% { transform: translate(0, 0); }
  12.5%    { transform: translate(-2%, -3%); }
  25%      { transform: translate(3%, -1%); }
  37.5%    { transform: translate(-1%, 2%); }
  50%      { transform: translate(2%, 3%); }
  62.5%    { transform: translate(-3%, 1%); }
  75%      { transform: translate(1%, -2%); }
  87.5%    { transform: translate(-2%, 2%); }
}

::selection { background: var(--silver); color: var(--bg); }

a { color: inherit; text-decoration: none; }
a:focus-visible, button:focus-visible {
  outline: 1px solid var(--silver);
  outline-offset: 4px;
}

.site {
  position: relative;
  z-index: 5;
  max-width: var(--measure);
  margin: 0 auto;
  padding: 0 clamp(20px, 5vw, 40px);
}

/* Pre-intro: keep the page from flashing for the frame before the overlay
   mounts. Failsafe restores it after 4s in case the script never runs.
   The class is only ever set by JS, so no-JS visitors never hit this. */
html.nl-intro { overflow: hidden; }
html.nl-intro .site { opacity: 0; animation: nl-failsafe 0s linear 4s forwards; }
@keyframes nl-failsafe { to { opacity: 1; } }


/* ---------------------------------------------------------------------
   4. SHARED PIECES
   --------------------------------------------------------------------- */
.section { padding-top: var(--gap-section); }

/* terminal-style label, at section-heading scale.
   The glyph is the light source; the label text stays --text-2, unshadowed,
   so its contrast is untouched. */
.prompt {
  font-size: clamp(18px, 2.2vw, 26px);
  letter-spacing: .12em;
  color: var(--text-2);
}
.prompt::before {
  content: '> ';
  color: var(--glow-green);
  text-shadow: 0 0 12px rgba(61, 255, 168, .45);
}

/* display type */
.display {
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.05;
  font-size: clamp(38px, 8vw, 76px);
}

/* hairline rows — numeral, icon, title, description */
.rows { list-style: none; margin-top: 40px; }
.row {
  display: grid;
  grid-template-columns: 3ch 30px minmax(0, 1fr) minmax(0, 1.45fr);
  column-gap: clamp(14px, 3vw, 36px);
  align-items: baseline;
  padding: 36px 0;
  border-top: 1px solid var(--border);
  transition: background-color .22s ease, border-color .22s ease;
}
.row:last-child { border-bottom: 1px solid var(--border); }
.row-n {                              /* the mismatch: serif italic against the mono */
  font-family: var(--serif);
  font-style: italic;
  font-size: 20px;
  color: var(--muted);
  transition: text-shadow .22s ease;
}
.row-i {
  align-self: center;
  color: var(--muted);
  transition: color .22s ease, filter .22s ease;
}
.row-i svg { display: block; width: 22px; height: 22px; }
.row-t { color: var(--text); font-weight: 700; font-size: clamp(21px, 1.8vw, 25px); letter-spacing: -0.01em; }
.row-d { color: var(--text-2); font-size: 15px; }

/* hover: the hairlines catch the light. Fine pointers only. */
@media (hover: hover) {
  .row:hover {
    background-color: rgba(61, 255, 168, .03);
    border-top-color: rgba(61, 255, 168, .35);
  }
  .row:hover + .row { border-top-color: rgba(61, 255, 168, .35); }
  .row:hover:last-child { border-bottom-color: rgba(61, 255, 168, .35); }
  .row:hover .row-n { text-shadow: 0 0 8px rgba(61, 255, 168, .55); }
  .row:hover .row-i { color: var(--text-2); filter: drop-shadow(0 0 6px rgba(61, 255, 168, .45)); }
}
@media (max-width: 639px) {
  .row {
    grid-template-columns: 3ch 26px minmax(0, 1fr);
    row-gap: 6px;
  }
  .row-d { grid-column: 3; }
}


/* cells — the services as a set, not a sequence. One bordered container,
   hairlines between cells (the 1px gap shows the border colour through),
   a whisper of surface fill. Breaks the rhythm of the row lists. */
.cells {
  list-style: none;
  margin-top: 40px;
  display: grid;
  grid-template-columns: 1fr;
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}
.cell {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 220px;
  padding: 28px 28px 30px;
  background: var(--surface);
  transition: background-color .22s ease;
}
.cell-n {
  font-family: var(--serif);
  font-style: italic;
  font-size: 20px;
  color: var(--muted);
  transition: text-shadow .22s ease;
}
.cell-i {
  position: absolute;
  top: 26px; right: 26px;
  color: var(--muted);
  transition: color .22s ease, filter .22s ease;
}
.cell-i svg { display: block; width: 22px; height: 22px; }
.cell-t {
  margin-top: auto;
  padding-top: 40px;
  color: var(--text);
  font-weight: 700;
  font-size: clamp(20px, 1.6vw, 24px);
  letter-spacing: -0.01em;
  line-height: 1.2;
}
.cell-d { margin-top: 10px; color: var(--text-2); font-size: 15px; }

@media (min-width: 640px)  { .cells { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .cells { grid-template-columns: repeat(3, 1fr); margin-top: 0; } }

@media (hover: hover) {
  .cell:hover { background-color: #171A1E; }
  .cell:hover .cell-n { text-shadow: 0 0 8px rgba(61, 255, 168, .55); }
  .cell:hover .cell-i { color: var(--text-2); filter: drop-shadow(0 0 6px rgba(61, 255, 168, .45)); }
}


/* ---------------------------------------------------------------------
   5. TOP — the mark, alone
   --------------------------------------------------------------------- */
.top { padding-top: clamp(56px, 10vh, 120px); }
.top .nl-mark { height: 56px; }


/* ---------------------------------------------------------------------
   6. BUILDS SHIPPED
   --------------------------------------------------------------------- */
.builds { padding-top: clamp(72px, 12vh, 140px); }
.builds-n {
  display: block;
  font-weight: 700;
  font-size: clamp(140px, 18vw, 240px);
  line-height: .95;
  letter-spacing: -0.05em;
  margin-top: 8px;
  margin-left: -0.04em;  /* optical: pull the glyph to the text edge */
}
/* the counter's band was dead space — the pool fills it with light,
   and the next section sits a third closer */
.builds + .section { padding-top: calc(var(--gap-section) * 2 / 3); }


/* ---------------------------------------------------------------------
   7. CERTIFICATION BADGES — metal plaques with a serrated seal.
   Silver only; the seal catches green light on hover like everything else.
   --------------------------------------------------------------------- */
.badges {
  list-style: none;
  margin-top: 32px;
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}
.badge {
  display: inline-flex;
  align-items: center;
  gap: 16px;
  padding: 14px 24px 14px 16px;
  transition: filter .22s ease;
}
.badge-seal {
  width: 52px; height: 52px;
  flex: none;
  color: var(--silver);
  transition: filter .22s ease, color .22s ease;
}
.badge-t {
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--text-2);
  line-height: 1.6;
  white-space: nowrap;
}
.badge-t strong {
  display: block;
  font-size: 14px;
  letter-spacing: .06em;
  color: var(--text);
}
@media (hover: hover) {
  .badge:hover .badge-seal { color: var(--platinum); filter: drop-shadow(0 0 7px rgba(61, 255, 168, .5)); }
}


/* ---------------------------------------------------------------------
   9. THE FORM
   --------------------------------------------------------------------- */
.build .display { margin-top: 20px; }
.build .lede {
  margin-top: 20px;
  color: var(--text-2);
  font-family: var(--serif);            /* the mismatch again, quietly */
  font-style: italic;
  font-size: 18px;
}

/* one serif word inside the metal headline — the clip travels through */
.accent-serif {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: 1.06em;
}

.form { margin-top: 56px; }
.form-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 40px clamp(24px, 5vw, 48px);
}
@media (min-width: 640px) {
  .form-grid { grid-template-columns: 1fr 1fr; }
  .field--full { grid-column: 1 / -1; }
}

.field { display: flex; flex-direction: column; min-width: 0; }
.field label {
  font-size: 13px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--glow-green);
  margin-bottom: 10px;
}
.field label .opt {
  text-transform: none;
  letter-spacing: .04em;
  color: var(--muted);
}

.field input,
.field select,
.field textarea {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  background: rgba(61, 255, 168, .035);
  border: 1px solid rgba(61, 255, 168, .30);
  border-radius: 2px;
  color: var(--glow-green);
  caret-color: var(--glow-green);
  font: inherit;
  font-size: 17px;            /* ≥16px: iOS won't zoom on focus */
  line-height: 1.5;
  padding: 13px 15px;
  transition: border-color .18s ease, box-shadow .18s ease, background-color .18s ease;
}
.field textarea { resize: vertical; min-height: 96px; }
.field input::placeholder,
.field textarea::placeholder { color: rgba(61, 255, 168, .38); opacity: 1; }

.field select {
  cursor: pointer;
  padding-right: 40px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%233DFFA8' stroke-width='1.25'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
}
.field select option { background: var(--surface); color: var(--text); }
.field select:invalid,
.field select.is-empty { color: rgba(61, 255, 168, .55); }

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--glow-green);
  background-color: rgba(61, 255, 168, .07);
  box-shadow: 0 0 0 1px var(--glow-green), 0 0 14px rgba(61, 255, 168, .30);
}
.field input:hover,
.field select:hover,
.field textarea:hover { border-color: rgba(61, 255, 168, .55); }

/* Chrome repaints an autofilled field white-on-blue. Hold the phosphor. */
.field input:-webkit-autofill,
.field input:-webkit-autofill:hover,
.field input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--glow-green);
  caret-color: var(--glow-green);
  -webkit-box-shadow: 0 0 0 1000px #0F1A16 inset;
  transition: background-color 9999s ease-out;
}

.field.is-invalid input,
.field.is-invalid select,
.field.is-invalid textarea {
  border-color: var(--glow-purple);
  background-color: rgba(167, 139, 250, .05);
  box-shadow: 0 0 0 1px var(--glow-purple), 0 0 14px rgba(167, 139, 250, .30);
}
.err {
  display: none;
  margin-top: 8px;
  font-size: 12px;
  color: var(--glow-purple);
}
.field.is-invalid .err { display: block; }

/* honeypot */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form-foot {
  margin-top: 48px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 24px 40px;
}
.btn {
  display: inline-block;
  font: inherit;
  font-size: 14px;
  letter-spacing: .04em;
  color: var(--glow-green);
  background: rgba(61, 255, 168, .05);
  border: 1px solid rgba(61, 255, 168, .45);
  border-radius: 2px;
  padding: 18px 32px;
  cursor: pointer;
  transition: border-color .18s ease, color .18s ease, background-color .18s ease, box-shadow .18s ease;
}
.btn:hover {
  border-color: var(--glow-green);
  background-color: rgba(61, 255, 168, .10);
  box-shadow: 0 0 16px rgba(61, 255, 168, .28);
}
.btn[disabled] { opacity: .5; cursor: default; }
@media (max-width: 639px) {
  .btn { width: 100%; text-align: center; }
}
.form-note { font-size: 12px; color: var(--text-2); }
.form-note a {
  color: var(--silver);
  border-bottom: 1px solid var(--border-hi);
  transition: border-color .18s ease, box-shadow .18s ease;
}
.form-note a:hover {
  border-bottom-color: rgba(61, 255, 168, .6);
  box-shadow: 0 6px 10px -7px rgba(61, 255, 168, .8);
}

.form-status { margin-top: 24px; font-size: 13px; color: var(--text-2); }
.form-status:empty { display: none; }
.form-status a { color: var(--silver); border-bottom: 1px solid var(--border-hi); }

/* confirmation, replaces the form */
.form-done { margin-top: 56px; }
.form-done .display { font-size: clamp(28px, 5vw, 44px); margin-top: 12px; }
.form-done p { margin-top: 16px; color: var(--text-2); }


/* ---------------------------------------------------------------------
   10. FOOTER — the wordmark, never the mark
   --------------------------------------------------------------------- */
.foot {
  margin-top: var(--gap-section);
  padding: 40px 0 clamp(40px, 8vh, 80px);
  border-top: 1px solid var(--border);
  display: grid;
  grid-template-columns: 1fr;
  gap: 40px;
}
@media (min-width: 640px) {
  .foot { grid-template-columns: 1fr auto; align-items: end; }
}
.foot .nl-wordmark { height: 44px; }       /* ≈124px wide — above the 110px minimum */
.foot-links { list-style: none; display: grid; gap: 8px; }
.foot-links a {
  font-size: 13px;
  color: var(--text-2);
  border-bottom: 1px solid transparent;
  transition: color .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.foot-links a:hover {
  color: var(--silver);
  border-bottom-color: rgba(61, 255, 168, .55);
  box-shadow: 0 6px 10px -7px rgba(61, 255, 168, .8);
}
.legal {
  grid-column: 1 / -1;
  font-size: 10px;
  letter-spacing: .08em;
  color: var(--muted);
}


/* ---------------------------------------------------------------------
   11. CURSOR — thin silver ring. Fine pointers only. Never on fields.
   --------------------------------------------------------------------- */
.cur { display: none; }
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  html.has-cur { cursor: none; }
  html.has-cur a, html.has-cur button { cursor: none; }
  html.has-cur input, html.has-cur textarea, html.has-cur select { cursor: auto; }
  html.has-cur .cur {
    display: block;
    position: fixed; top: 0; left: 0;
    width: 26px; height: 26px;
    border: 1px solid var(--silver);
    border-radius: 50%;
    pointer-events: none;
    z-index: 20000;
    opacity: 0;
    transform: translate(-50%, -50%) scale(1);
    transition: transform .15s ease, opacity .2s ease;
    will-change: transform;
  }
  html.has-cur .cur::after {           /* faint phosphor core inside the ring */
    content: '';
    position: absolute;
    inset: 0;
    margin: auto;
    width: 3px; height: 3px;
    border-radius: 50%;
    background: var(--glow-green);
    box-shadow: 0 0 6px rgba(61, 255, 168, .8);
    opacity: .8;
  }
  html.has-cur .cur.on { opacity: .8; }
  html.has-cur .cur.big { transform: translate(-50%, -50%) scale(1.5); }
  html.has-cur .cur.off { opacity: 0; }
}


/* ---------------------------------------------------------------------
   12. INTRO — built entirely by JS. No JS, no overlay.
   --------------------------------------------------------------------- */
.intro {
  position: fixed; inset: 0;
  z-index: 10000;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  transition: opacity .35s ease;
}
.intro.out { opacity: 0; pointer-events: none; }

.intro-in {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(32px, 6vh, 56px);
  width: 100%;
  max-width: 720px;
}

/* beat 1 — terminal */
.intro-term {
  width: 22ch;                 /* longest line is 21ch — never wraps mid-token */
  max-width: 100%;
  text-align: left;
  font-size: clamp(14px, 3.8vw, 16px);
  line-height: 1.9;
  white-space: pre;
}
.intro-term .ln { display: block; min-height: 1.9em; color: var(--text-2); }
.intro-term .ln.ret {              /* the returned value is the signal */
  color: var(--glow-green);
  text-shadow: 0 0 10px rgba(61, 255, 168, .4);
}
.intro-term .cur-blk {
  display: inline-block;
  width: .6em; height: 1.1em;
  vertical-align: -0.15em;
  background: var(--glow-green);
  box-shadow: 0 0 8px rgba(61, 255, 168, .6);
  animation: nl-blink 1s steps(1) infinite;
}
@keyframes nl-blink { 50% { opacity: 0; } }

/* beat 2 — the mark draws itself */
.intro-mark {
  height: clamp(96px, 22vw, 168px);
  width: auto;
  color: var(--text);
  display: block;
}
.intro-mark .seg {
  fill: none;
  stroke-width: 105;
  stroke-dasharray: var(--len);
  stroke-dashoffset: var(--len);
  transition: stroke-dashoffset .5s cubic-bezier(.4, 0, .2, 1);
}
.intro-mark .seg.bar { stroke: currentColor; }
.intro-mark .seg.ring { stroke: url(#nlSilverIntro); }
.intro-mark .seg.in { stroke-dashoffset: 0; }
.intro.done .seg { transition: none; stroke-dashoffset: 0; }

/* beat 3 — the line */
.intro-line {
  font-weight: 700;
  font-size: clamp(22px, 5.4vw, 40px);
  letter-spacing: -0.02em;
  line-height: 1.1;
  text-align: center;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity .5s ease, transform .5s ease;
}
@media (max-width: 400px) { .intro-line { white-space: normal; } }

/* beat 4 — the door */
.intro-door {
  font: inherit;
  font-size: 14px;
  letter-spacing: .04em;
  color: var(--silver);
  background: transparent;
  border: 1px solid var(--border-hi);
  padding: 16px 28px;
  cursor: pointer;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity .5s ease, transform .5s ease, border-color .18s ease;
}
.intro-door:hover { border-color: var(--silver); }
.intro .show { opacity: 1; transform: none; }
.intro.done .intro-line, .intro.done .intro-door { transition: none; opacity: 1; transform: none; }

.intro-skip {
  position: fixed;
  right: 24px; bottom: 20px;
  font-size: 12px;
  letter-spacing: .06em;
  color: var(--text-2);
  opacity: 0;
  transition: opacity .6s ease;
}
.intro-skip.show { opacity: .8; }

@media (prefers-reduced-motion: reduce) {
  .intro { transition: none; }
  .intro-term .cur-blk { animation: none; }
}


/* ---------------------------------------------------------------------
   12b. DESKTOP — the editorial layout. Below 1024px the page is the single
   column above (phones and tablets). From 1024px each section becomes a
   two-column spread: the terminal label lives in a sticky left rail, the
   content runs in a wide right column, the counter gets the width it earns.
   --------------------------------------------------------------------- */
@media (min-width: 1024px) {
  :root { --measure: min(1440px, 94vw); }

  .top { padding-top: clamp(48px, 7vh, 88px); }
  .top .nl-mark { height: 64px; }

  .section,
  .builds {
    display: grid;
    grid-template-columns: minmax(300px, 1fr) minmax(0, 3.2fr);
    column-gap: clamp(40px, 5vw, 96px);
    align-items: start;
  }
  .section > .prompt,
  .builds > .prompt {
    grid-column: 1;
    position: sticky;
    top: 48px;
    align-self: start;
    white-space: nowrap;              /* the rail is sized so no label wraps */
  }
  .section > :not(.prompt),
  .builds > :not(.prompt) { grid-column: 2; }

  /* the rail label reads as a heading here */
  .prompt { font-size: clamp(20px, 1.6vw, 24px); }

  /* the counter, freed from the column, goes as big as the rail allows */
  .builds-n {
    font-size: clamp(240px, 22vw, 340px);
    margin-top: -0.12em;              /* optical: cap height meets the label's baseline */
  }
  .builds + .section { padding-top: calc(var(--gap-section) * .75); }

  .rows { margin-top: 0; }
  .row {
    grid-template-columns: 3ch 34px minmax(0, 1.25fr) minmax(0, 1fr);
    padding: 40px 0;
  }
  .row-t { font-size: clamp(24px, 1.8vw, 28px); white-space: nowrap; }
  .row-d { font-size: 16px; }
  .row-i svg { width: 24px; height: 24px; }

  .build .display { margin-top: 0; font-size: clamp(56px, 6.2vw, 96px); }
  .form { margin-top: 48px; }

  .foot { padding-top: 56px; }
  .foot .nl-wordmark { height: 56px; }
}


/* ---------------------------------------------------------------------
   13. SCROLL REVEAL — .rv is only ever added by JS, which also checks
   reduced-motion and IntersectionObserver support, so no-JS and
   reduced-motion visitors always see the static final state.
   --------------------------------------------------------------------- */
.rv {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .5s ease-out, transform .5s ease-out;
  transition-delay: var(--rv-d, 0ms);
}
.rv.rv-in { opacity: 1; transform: none; }
