/* Palette + fonts are injected as CSS variables from site.config.js (see app.js). */
:root {
  --bg: #080808;
  --text: #f2ede4;
  --error: #ff2b2b;
  --success: #2bff6f;  /* THE MACHINE saying everything is fine: status dot, progress, BUY */
  --accent: #2b7bff;   /* THE HUMAN: the prompt caret, what we ask for, the ticker */
  --dim: #6f6a61;      /* LABELS + decoration only — too low-contrast to read a sentence in */
  --muted: #9a948a;    /* SUPPORTING SENTENCES — footnotes, hints, small print */
  --display: 'Anonymous Pro', monospace;
  --mono: 'Anonymous Pro', monospace;

  /* ---- TYPE SCALE ----------------------------------------------------
     Every font-size on this page comes from this list. Nine sizes, no
     one-offs: that is what makes the top of the page and the bottom read
     as the same site. Adding a tenth size is how a page starts looking
     assembled rather than designed. */
  --fs-display: clamp(2.4rem, 8.5vw, 4.4rem);   /* the one big thing on a screen */
  --fs-1:       clamp(1.8rem, 6vw, 3rem);       /* section statements */
  --fs-2:       clamp(1.3rem, 4.2vw, 1.9rem);   /* sub-statements */
  --fs-3:       clamp(1.05rem, 2.8vw, 1.3rem);  /* lead body */
  --fs-body:    .95rem;
  --fs-sm:      .85rem;   /* supporting sentences: a sentence needs reading size */
  --fs-xs:      .75rem;   /* labels only: one or two words can be tiny */
  --fs-wall:    clamp(2rem, 9vw, 5.5rem);       /* the error wall is deliberately oversized */
  --fs-final:   clamp(2rem, 10.5vw, 16rem);     /* the last word, and the only thing on its screen */

  /* ---- LINES + SURFACES ---------------------------------------------- */
  --line:        #1e1e1e;   /* every quiet border */
  --line-strong: #303030;   /* borders you can interact with */
  --surface:     #0b0b0b;   /* raised panels */

  /* ---- RHYTHM --------------------------------------------------------- */
  --track: .16em;   /* letter-spacing for all label-scale uppercase text */
  --r-sm: 6px;
  --r:    8px;
  --r-lg: 12px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html {
  scroll-behavior: smooth;
  /* Seven scenes, one per screen. Native snapping: no scroll hijacking, so the
     keyboard, the scrollbar, anchor links and crawlers all keep working. */
  scroll-snap-type: y mandatory;
}
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--display);
  overflow-x: hidden;
  overflow-x: clip;   /* clip contains the bleed WITHOUT becoming a scroll container,
                         which would otherwise fight the snap points on <html> */
  min-height: 100vh;
}
.mono { font-family: var(--mono); }
.dim { color: var(--dim); }
.accent { color: var(--accent); }

/* Label scale. Section titles, the benchmark line, the CA label and the
   prompt placeholder are all the same class so they cannot drift apart. */
.kicker {
  font-family: var(--mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--track);
  color: var(--dim);
  font-weight: 400;
}
.hidden { display: none !important; }
noscript { display: block; padding: 2rem; font-family: var(--mono); color: var(--error); }

/* ===== HERO ===== */
.hero {
  scroll-snap-align: start;
  min-height: 100vh;
  min-height: 100svh;   /* svh, not vh: mobile browser chrome must not steal the scene */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  position: relative;
}
.hero-shell {
  width: min(680px, 100%);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 2rem 1.75rem 2.5rem;
  background: linear-gradient(180deg, #0d0d0d, #090909);
  box-shadow: 0 0 60px rgba(43, 123, 255, 0.06);
  transition: border-color .3s;
}
.hero-shell.erroring { border-color: rgba(255,43,43,.4); box-shadow: 0 0 60px rgba(255,43,43,.08); }
.fake-brand {
  display: flex; align-items: center; gap: .6rem;
  font-family: var(--mono); font-size: var(--fs-sm); color: var(--dim);
  margin-bottom: 2.2rem;
}
.fake-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--success); box-shadow: 0 0 8px var(--success); }
.fake-brand #fake-name { color: var(--text); font-weight: 600; }
.fake-model { border: 1px solid var(--line); border-radius: 999px; padding: .1rem .6rem; font-size: var(--fs-xs); }
.fake-tagline { margin-left: auto; font-size: var(--fs-xs); letter-spacing: .06em; }
@media (max-width: 560px) { .fake-tagline { display: none; } }

.prompt-box { margin-bottom: 1.6rem; }
.prompt-label { margin-bottom: .9rem; }
.prompt-line { font-family: var(--mono); font-size: var(--fs-3); display: flex; gap: .6rem; align-items: baseline; }
.caret { color: var(--accent); }
.cursor { animation: blink 1s steps(1) infinite; color: var(--text); }
@keyframes blink { 50% { opacity: 0; } }

/* One button geometry, three skins: solid-light, solid-green, outline. */
.btn-generate, .btn-buy, .btn-copy, .btn-retry {
  font-family: var(--mono); cursor: pointer;
  text-decoration: none; display: inline-block;
  font-size: var(--fs-body); letter-spacing: .12em;
  padding: .85rem 2.2rem; border-radius: var(--r);
  border: 1px solid transparent;
  transition: transform .12s, background .2s, border-color .2s, color .2s;
}
.btn-generate { background: var(--text); color: var(--bg); font-weight: 600; }
.btn-generate:hover { transform: translateY(-2px); background: #fff; }
.btn-copy, .btn-retry { background: transparent; color: var(--text); border-color: var(--line-strong); }
.terminal-send { font-family: var(--mono); cursor: pointer; border: none; }

.gen-step { font-size: var(--fs-body); color: var(--text); min-height: 1.4em; letter-spacing: .1em; margin-bottom: 1.4rem; }
.progress-wrap { display: flex; align-items: center; gap: 1rem; }
.progress-bar { flex: 1; height: 14px; border: 1px solid var(--line-strong); border-radius: var(--r-sm); overflow: hidden; background: var(--surface); }
.progress-fill { height: 100%; width: 0%; background: var(--success); transition: width .25s linear; }
.progress-fill.stuck { background: repeating-linear-gradient(45deg, var(--success), var(--success) 6px, #1a4d2c 6px, #1a4d2c 12px); animation: crawl 1s linear infinite; }
@keyframes crawl { to { background-position: 17px 0; } }
.progress-num { color: var(--success); font-size: var(--fs-sm); width: 3.2em; text-align: right; }
/* the bill, running while it fails you */
.credit-line { margin-top: 1.1rem; font-size: var(--fs-sm); color: var(--muted); letter-spacing: .04em; }
.credit-line .over { color: var(--error); }

.error-big {
  color: var(--error);
  font-size: var(--fs-display);
  line-height: 1.05; letter-spacing: -.01em;
  white-space: pre-line;
  margin-bottom: 1.1rem;
}
.error-reason { color: var(--muted); font-size: var(--fs-sm); white-space: pre-line; margin-bottom: 2rem; }
.btn-retry { position: relative; transition: transform .15s ease-out, border-color .2s, color .2s; }
.btn-retry:hover { border-color: var(--text); }

/* ===== REVEAL ===== */
.reveal { text-align: center; padding: 2rem 0; }
.reveal-cursor { font-size: var(--fs-2); animation: blink 1s steps(1) infinite; }
.reveal-beat { font-size: var(--fs-2); color: var(--text); letter-spacing: .05em; }
.reveal-slogan { font-size: var(--fs-1); letter-spacing: -.01em; margin-top: 1rem; }
.reveal-ticker { font-size: var(--fs-display); color: var(--accent); margin-top: .6rem; font-family: var(--mono); }
.reveal-support { color: var(--muted); font-size: var(--fs-sm); margin-top: 1.4rem; line-height: 1.8; white-space: pre-line; }
.reveal-ctas { margin-top: 2rem; }
.btn-buy { background: var(--success); color: var(--bg); font-weight: 600; }
.btn-buy:hover { transform: translateY(-2px); }
.btn-buy.disabled { background: var(--line); color: var(--dim); pointer-events: none; }

.scroll-hint { position: absolute; bottom: 1.2rem; color: var(--dim); font-size: var(--fs-sm); animation: bob 2s ease-in-out infinite; }
@keyframes bob { 50% { transform: translateY(6px); } }

/* ===== SECTIONS ===== */
section, .footer {
  scroll-snap-align: start;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
section { padding: 4rem 1.5rem; max-width: 900px; margin: 0 auto; }
.kicker { margin-bottom: 0; }
#terminal-title, #lore-title { margin-bottom: 2rem; }

/* terminal */
.terminal {
  border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface);
  padding: 1.2rem; font-family: var(--mono);
}
.terminal-log { min-height: 200px; max-height: 340px; overflow-y: auto; margin-bottom: 1rem; font-size: var(--fs-body); line-height: 1.55; }
.terminal-log .line { white-space: pre-wrap; margin-bottom: .55rem; }
.terminal-log .u { color: var(--accent); }
.terminal-log .a { color: var(--text); }
.terminal-log .err { color: var(--error); font-weight: 600; }
.terminal-log .ok { color: var(--success); }
.terminal-log .thinking { color: var(--dim); }
.terminal-input-row { display: flex; align-items: center; gap: .6rem; border-top: 1px solid var(--line); padding-top: .9rem; }
.terminal-input { flex: 1; background: transparent; border: none; outline: none; color: var(--text); font-family: var(--mono); font-size: var(--fs-body); }
.terminal-send { background: transparent; border: 1px solid var(--line-strong); color: var(--dim); border-radius: var(--r-sm); padding: .3rem .8rem; font-size: var(--fs-body); }
.terminal-send:hover { color: var(--text); border-color: var(--text); }
.hint { margin-top: .9rem; font-size: var(--fs-sm); color: var(--muted); }

/* problem */
.problem { text-align: center; }
.problem-heading { font-size: var(--fs-1); margin-bottom: 2rem; }
.problem-list { list-style: none; color: var(--muted); font-family: var(--mono); line-height: 2.1; font-size: var(--fs-body); margin-bottom: 2rem; }
.problem-list li::before { content: "✓ "; color: var(--success); }
.problem-punch { font-size: var(--fs-1); color: var(--error); margin-bottom: 4rem; }
.benchmark-q { font-size: var(--fs-1); margin-top: .8rem; }

/* ===== AFTERMATH =====
   Same scanline geometry as the error glitch, at roughly a third of its
   strength. The flash lives for 0.45s and can afford to be loud; this one has
   to sit under eight lines of lore without vibrating, so it is dialled back
   and the red wash decays downward — anger peaks at the error wall and cools
   into the token. The whole thing fades in over 240px so there is no seam. */
.aftermath { position: relative; isolation: isolate; }
.aftermath::before {
  content: "";
  position: absolute; inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    repeating-linear-gradient(0deg, rgba(255, 43, 43, .05) 0 2px, transparent 2px 5px),
    repeating-linear-gradient(90deg, rgba(43, 123, 255, .022) 0 1px, transparent 1px 6px),
    linear-gradient(180deg, rgba(255, 43, 43, .05) 0, rgba(255, 43, 43, .018) 45%, transparent 85%);
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 240px);
  mask-image: linear-gradient(180deg, transparent 0, #000 240px);
}

/* error wall */
.error-wall { max-width: none; padding: 4rem 0; overflow: hidden; }
.error-wall .wall-line {
  font-family: var(--mono); font-weight: 600;
  font-size: var(--fs-wall);
  color: #151515; white-space: nowrap; line-height: 1.15;
  transition: color .3s;
  user-select: none;
}
.error-wall .wall-line.seen { color: #471111; }   /* resolves as you scroll past (mobile has no hover) */
.error-wall .wall-line:hover { color: var(--error); }
.error-wall .wall-line.hot { color: var(--error); }
/* The hero's glitch replaces the text behind an opaque slice; on the wall the
   lines are nowrap and oversized, so ghost them instead of slabbing them. */
.error-wall .wall-line.glitching::before,
.error-wall .wall-line.glitching::after { background: transparent; white-space: nowrap; }

/* Each row is one exchange: what was asked, then what came back. The prompt
   caret is the same one from the hero, so the wall reads as the same session. */
.wall-exchange {
  /* Left/right alignment did nothing here: these lines are nearly as wide as
     any container, so a right-aligned row still started near the left edge and
     the whole wall read as one left block. Indentation is the control that
     actually works at this size — each exchange steps in by its own amount and
     runs off the right edge wherever it happens to end. Irregular on both
     sides, which is what makes it a wall rather than a list. */
  padding-left: var(--indent, 4vw);
  padding-right: 1.5rem;
  margin-bottom: 1.8rem;
}
.wall-exchange:nth-child(1) { --indent: 4vw; }
.wall-exchange:nth-child(2) { --indent: 24vw; }
.wall-exchange:nth-child(3) { --indent: 10vw; }
.wall-exchange:nth-child(4) { --indent: 32vw; }
.wall-exchange:nth-child(5) { --indent: 16vw; }
.wall-exchange:nth-child(6) { --indent: 28vw; }
.wall-exchange:nth-child(7) { --indent: 4vw; }   /* the last demand comes back to the margin */

/* The lines are meant to run off the edge, but a reader should still be able to
   reach the end of one. Each row pans horizontally: drag on touch, trackpad
   swipe or shift-scroll with a pointer. Native overflow means the travel stops
   exactly where the text does — no further. overflow-y must be stated or it
   computes to auto and each row grows its own vertical scrollbar. */
.wall-exchange {
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.wall-exchange::-webkit-scrollbar { display: none; }
.wall-line { padding-right: 1.5rem; }   /* the last character is not flush to the edge */
.wall-human {
  font-size: var(--fs-sm); color: var(--muted); letter-spacing: .04em;
  margin-bottom: .3rem;
  opacity: 0; transform: translateY(8px);
  transition: opacity .5s ease, transform .5s ease;
}
.wall-human::before { content: "> "; color: var(--accent); }
.wall-exchange.in .wall-human { opacity: 1; transform: none; }
/* Indentation is a wide-screen device; on a phone it would just clip the text. */
@media (max-width: 760px) {
  .wall-exchange:nth-child(n) { --indent: 1.1rem; }
  .wall-exchange { padding-right: 1.1rem; margin-bottom: 1.4rem; }
}

/* lore */
.lore-lines { font-size: var(--fs-3); line-height: 2.2; }
.lore-lines .lore-line { opacity: 0; transform: translateY(8px); transition: opacity .6s, transform .6s; }
.lore-lines .lore-line.show { opacity: 1; transform: none; }
/* The point, stated plainly. Same reveal as the story, one step louder. */
.manifesto { margin-top: 3rem; border-left: 2px solid var(--line); padding-left: 1.4rem; }
.manifesto .manifesto-line { font-size: var(--fs-2); line-height: 1.6; color: var(--text); }
.manifesto .manifesto-line:last-child { color: var(--accent); margin-top: .6rem; }
.lore-close { margin-top: 3rem; }
.lore-slogan { font-size: var(--fs-1); font-weight: 700; }

/* token */
.token { text-align: center; }
.token-ticker { font-family: var(--mono); font-size: var(--fs-display); color: var(--accent); }
.ticker-note { font-family: var(--mono); color: var(--muted); font-size: var(--fs-sm); margin-top: 1rem; line-height: 1.9; white-space: pre-line; }
.token-oneliner { color: var(--text); margin-top: 1.4rem; font-size: var(--fs-3); }
.token-secondary { color: var(--accent); margin-top: .6rem; }
.token-principles { list-style: none; display: flex; flex-wrap: wrap; gap: .6rem; justify-content: center; margin: 1.6rem 0 2.4rem; }
.token-principles li { font-family: var(--mono); border: 1px solid var(--line); border-radius: 999px; padding: .3rem .9rem; font-size: var(--fs-xs); color: var(--muted); }
.ca-box { padding: 1rem 0 0; }
.ca-label { margin-bottom: .9rem; }
.ca-value { font-size: clamp(.72rem, 2.4vw, var(--fs-body)); word-break: break-all; color: var(--text); min-height: 1.4em; }
.ca-value.redacted { color: var(--error); letter-spacing: .04em; }
.ca-actions { display: flex; gap: .8rem; justify-content: center; margin-top: 1.6rem; flex-wrap: wrap; }
.btn-copy:hover { border-color: var(--accent); color: var(--accent); }
.ca-joke { margin-top: 1.4rem; font-size: var(--fs-sm); color: var(--muted); }
/* Where to go look at it. Quiet next to BUY — these are destinations, not the CTA. */
.ext-links { display: flex; gap: 1.4rem; justify-content: center; flex-wrap: wrap; margin-top: 1.6rem; }
.ext-links:empty { display: none; }
.ext-link {
  display: inline-flex; align-items: center; gap: .5rem;
  font-size: var(--fs-sm); color: var(--muted);
  text-decoration: none; transition: color .2s;
}
.ext-link img { width: 16px; height: 16px; object-fit: contain; }
.ext-link:hover { color: var(--text); }

/* footer */
.footer { text-align: center; padding: 4rem 1.5rem; border-top: 1px solid var(--line); }
/* The closing demand takes the whole screen. Sized so the longer of its two
   lines runs nearly edge to edge at any width — 15 characters of Anonymous Pro
   at ~0.55em advance is what sets the 10.5vw. */
.footer-slogan {
  font-size: var(--fs-final);
  font-weight: 700;
  line-height: .95;
  letter-spacing: -.02em;
  white-space: pre-line;
}
/* No button chrome: the mark plus the line of credit, nothing around it. */
.credit { margin-top: 3rem; font-size: var(--fs-sm); color: var(--muted); letter-spacing: .04em; }
/* The mark is the only link here; the credit above it is prose. */
/* align-self, because the footer became a column flex container when it became
   a scene: without it the link stretches the full width and the 17px mark ends
   up wherever the box starts instead of under the credit line. */
.social-x { display: inline-flex; align-self: center; margin-top: .9rem; color: var(--muted); transition: color .2s, transform .2s; }
.social-x svg { width: 17px; height: 17px; fill: currentColor; }
.social-x:hover { color: var(--text); transform: translateY(-1px); }
.social-x.disabled { pointer-events: none; }
.disclaimer { margin-top: 1.8rem; font-size: var(--fs-xs); color: var(--muted); max-width: 62ch; margin-inline: auto; line-height: 1.7; text-wrap: balance; }
.disclaimer + .disclaimer { margin-top: .4rem; }

/* ===== GLITCH ===== */
.glitch-overlay {
  position: fixed; inset: 0; pointer-events: none; z-index: 99;
  opacity: 0; background:
    repeating-linear-gradient(0deg, rgba(255,43,43,.12) 0 2px, transparent 2px 5px),
    repeating-linear-gradient(90deg, rgba(43,123,255,.08) 0 1px, transparent 1px 6px);
  mix-blend-mode: screen;
}
.glitch-overlay.on { animation: glitchflash .45s steps(3) 1; }
@keyframes glitchflash { 0% {opacity:.9; transform: translateX(-6px);} 40% {opacity:.5; transform: translateX(5px);} 100% {opacity:0; transform:none;} }
/* real RGB-split slice glitch (runs only while .glitching, ~0.65s) */
.glitchable { position: relative; }
.glitchable.glitching { animation: glitch-skew .65s steps(2) 1; }
.glitchable.glitching::before,
.glitchable.glitching::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  background: var(--bg);
  overflow: hidden;
  white-space: pre-line;
  color: inherit;
}
.glitchable.glitching::before {
  left: 3px;
  text-shadow: -2px 0 var(--accent);
  animation: glitch-slice-a .65s steps(8) 1;
}
.glitchable.glitching::after {
  left: -3px;
  text-shadow: 2px 0 var(--success);
  animation: glitch-slice-b .65s steps(8) 1;
}
@keyframes glitch-skew {
  0% { transform: skewX(0); } 20% { transform: skewX(-2deg); }
  40% { transform: skewX(1.5deg); } 60% { transform: skewX(-1deg) translateX(2px); }
  80% { transform: skewX(.5deg); } 100% { transform: skewX(0); }
}
@keyframes glitch-slice-a {
  0%   { clip-path: inset(12% 0 78% 0); }
  15%  { clip-path: inset(64% 0 8% 0); }
  30%  { clip-path: inset(32% 0 51% 0); }
  45%  { clip-path: inset(85% 0 4% 0); }
  60%  { clip-path: inset(5% 0 86% 0); }
  75%  { clip-path: inset(48% 0 33% 0); }
  100% { clip-path: inset(70% 0 15% 0); }
}
@keyframes glitch-slice-b {
  0%   { clip-path: inset(76% 0 10% 0); }
  15%  { clip-path: inset(8% 0 74% 0); }
  30%  { clip-path: inset(55% 0 28% 0); }
  45%  { clip-path: inset(20% 0 66% 0); }
  60%  { clip-path: inset(88% 0 3% 0); }
  75%  { clip-path: inset(38% 0 45% 0); }
  100% { clip-path: inset(2% 0 90% 0); }
}
body.redesigned { filter: invert(1) hue-rotate(160deg); }
body.redesigned .glitch-overlay { mix-blend-mode: multiply; }

/* motion respect */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  html { scroll-behavior: auto; }
}

@media (max-width: 560px) {
  .hero-shell { padding: 1.4rem 1.1rem 1.8rem; }
  section { padding: 2.5rem 1.1rem; }
}
