/* ===========================================================================
   ZEROCREDITS : design tokens (locked from assets/avatar.png + banner.png)
   ---------------------------------------------------------------------------
   Palette   : lime      #B9F234  (sampled background, exact avatar match)
               ink       #040404  (sampled zero fill, exact avatar match)
               fail-red  #E8394A  (the one non-avatar color: every denial beat
                                   and the fake copy-fail use it, nothing else
                                   does, so red always reads as "this failed")
   Type      : Inter 900/700/500, plain geometric grotesk, the same "typed
               and stretched in a free editor" register as the avatar's own
               glyph, not a display face. Self-hosted woff2, no runtime fetch.
               IBM Plex Mono 500/400 for the CA readout and the attempts
               tally only, so anything numeric/system reads as a readout.
   Spacing   : 4 . 8 . 12 . 16 . 24 . 32 . 48 . 64 (px)
   Radius    : 0 everywhere except the CA pill and the corner mark (999px) -
               the concept is a flat rectangle of color, no soft edges to earn.
   Motion    : "denial", cubic-bezier(.36,.07,.19,.97) for the shake (a sharp,
               unpleasant snap, not a bouncy one), linear for the spinner,
               180ms fades for toast/line swaps. prefers-reduced-motion drops
               the shake amplitude to near zero and keeps state changes instant.

   Rule note: the X icon below is inline SVG, not a Higgsfield raster (house
   style default). It has to be pixel-identical in letterform to the live
   "0" heading right above it on the same page (same font, same weight), a
   guarantee a separately generated image can't give, and the whole site's
   register is already flat crude typography, not illustrated art - so this
   is the "pure CSS/SVG pattern where a raster makes no sense" carve-out in
   01_RULES.md Visuals, not a silent fallback.
   =========================================================================== */

@font-face{font-family:"Inter";src:url("assets/fonts/inter-500.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;}
@font-face{font-family:"Inter";src:url("assets/fonts/inter-700.woff2") format("woff2");font-weight:700;font-style:normal;font-display:swap;}
@font-face{font-family:"Inter";src:url("assets/fonts/inter-900.woff2") format("woff2");font-weight:900;font-style:normal;font-display:swap;}
@font-face{font-family:"IBM Plex Mono";src:url("assets/fonts/plexmono-400.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;}
@font-face{font-family:"IBM Plex Mono";src:url("assets/fonts/plexmono-500.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;}

:root{
  --clr-lime:#B9F234;
  --clr-lime-dim:#A9DE2C;
  --clr-ink:#040404;
  --clr-ink-soft:rgba(4,4,4,.62);
  --clr-ink-faint:rgba(4,4,4,.4);
  --clr-fail:#E8394A;
  --clr-fail-dim:rgba(232,57,74,.14);

  --font-display:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  --font-mono:"IBM Plex Mono","SFMono-Regular",Consolas,monospace;

  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:24px;
  --sp-6:32px; --sp-7:48px; --sp-8:64px;

  --ease-denial:cubic-bezier(.36,.07,.19,.97);
  --dur-fade:180ms;
}

@media (prefers-reduced-motion:reduce){
  :root{ --dur-fade:1ms; }
}

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

html,body{height:100%;}
body{
  margin:0;
  background:var(--clr-lime);
  color:var(--clr-ink);
  font-family:var(--font-display);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-x:hidden;
  overflow-y:auto;
  overscroll-behavior:none;
}

button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;}
a{color:inherit;text-decoration:none;}

/* ---------- inline error banner (injected by head script) ---------- */
#boot-error-banner{
  position:fixed;inset:auto 0 0 0;z-index:9999;
  background:var(--clr-ink);color:#FFE9DC;
  font:600 13px/1.5 var(--font-mono);
  padding:12px 16px;text-align:center;
  border-top:2px solid var(--clr-fail);
}

/* ===========================================================================
   X CORNER MARK - the only chrome besides the CA readout and the button
   =========================================================================== */
.x-corner{
  position:fixed; top:var(--sp-4); right:var(--sp-4); z-index:20;
  width:30px;height:30px;
  display:flex;align-items:center;justify-content:center;
  border-radius:999px;
  opacity:.55;
  transition:opacity var(--dur-fade) ease, transform var(--dur-fade) ease;
}
.x-corner:hover{ opacity:1; transform:scale(1.08); }
.x-icon{ width:22px; height:22px; }
.x-icon-glyph{
  font-family:var(--font-display); font-weight:900; font-size:74px;
  fill:var(--clr-ink);
}
.x-icon-strike{
  stroke:var(--clr-ink); stroke-width:9; stroke-linecap:round;
}

/* ===========================================================================
   STAGE - single flat viewport, no scroll, no nav
   =========================================================================== */
.stage{
  min-height:100vh; min-height:100dvh;
  width:100%;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  padding:var(--sp-4);
  text-align:center;
}

.zero-wrap{
  width:min(66vw, 46vh, 460px);
  height:min(66vw, 46vh, 460px);
  overflow:hidden;
  display:flex;
  align-items:center;
  justify-content:center;
  position:relative;
  flex-shrink:0;
}
.zero{
  font-family:var(--font-display);
  font-weight:900;
  font-size:min(112vw, 78vh, 780px);
  line-height:.8;
  letter-spacing:-0.01em;
  color:var(--clr-ink);
  user-select:none;
  transform:translateY(2%);
}

.caption{
  margin:0 0 var(--sp-5);
  font-family:var(--font-display);
  font-weight:500;
  font-size:clamp(13px, 2.6vw, 17px);
  color:var(--clr-ink-soft);
}

/* ===========================================================================
   CA BOX - the only other element on the page, dead center below the 0
   ===========================================================================
*/
.ca-box{
  display:inline-flex;
  align-items:center;
  gap:var(--sp-2);
  padding:9px 16px;
  border:1.5px solid var(--clr-ink);
  border-radius:999px;
  margin-bottom:var(--sp-6);
  max-width:min(92vw, 420px);
  transition:border-color var(--dur-fade) ease, background var(--dur-fade) ease;
}
.ca-box:hover{ background:rgba(4,4,4,.06); }
.ca-box:active{ transform:translateY(1px); }
.ca-label{
  font-family:var(--font-mono);
  font-size:10px;
  font-weight:500;
  letter-spacing:.14em;
  color:var(--clr-ink-faint);
  flex-shrink:0;
}
.ca-value{
  font-family:var(--font-mono);
  font-size:12.5px;
  font-weight:500;
  color:var(--clr-ink);
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
}
.ca-fail{
  font-family:var(--font-mono);
  font-size:10px;
  font-weight:500;
  letter-spacing:.06em;
  color:var(--clr-fail);
  flex-shrink:0;
  min-width:0;
  opacity:0;
  transition:opacity var(--dur-fade) ease;
}
.ca-fail.is-shown{ opacity:1; }

/* ===========================================================================
   ADD CREDITS - the whole real mechanic, and the buy button
   =========================================================================== */
.cta-wrap{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:var(--sp-3);
}

.add-btn{
  position:relative;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  min-width:min(84vw, 320px);
  padding:18px var(--sp-7);
  background:var(--clr-ink);
  color:var(--clr-lime);
  border-radius:0;
  font-family:var(--font-display);
  font-weight:900;
  font-size:clamp(16px, 3.4vw, 20px);
  letter-spacing:.02em;
  cursor:pointer;
  border:2px solid var(--clr-ink);
  transition:transform 90ms ease;
}
.add-btn:hover{ transform:translateY(-1px); }
.add-btn:active{ transform:translateY(1px); }

.add-btn.is-shaking{
  animation:denial-shake 420ms var(--ease-denial);
}
@keyframes denial-shake{
  0%{ transform:translateX(0); }
  15%{ transform:translateX(-10px) rotate(-1deg); }
  30%{ transform:translateX(9px) rotate(1deg); }
  45%{ transform:translateX(-7px); }
  60%{ transform:translateX(6px); }
  75%{ transform:translateX(-3px); }
  100%{ transform:translateX(0); }
}
@media (prefers-reduced-motion:reduce){
  .add-btn.is-shaking{ animation:denial-shake-reduced 200ms var(--ease-denial); }
  @keyframes denial-shake-reduced{
    0%{ background:var(--clr-fail); }
    100%{ background:var(--clr-ink); }
  }
}

.add-btn.is-denied{ border-color:var(--clr-fail); }

.add-btn-label{ position:relative; z-index:1; }
.add-btn.is-loading .add-btn-label{ opacity:.35; }

.add-btn-spinner{
  position:absolute;
  right:var(--sp-4);
  top:50%;
  width:18px;height:18px;
  margin-top:-9px;
  border-radius:50%;
  border:2.5px solid rgba(185,242,52,.28);
  border-top-color:var(--clr-lime);
  opacity:0;
  transform:scale(.6);
  transition:opacity var(--dur-fade) ease;
}
.add-btn.is-loading .add-btn-spinner{
  opacity:1;
  transform:scale(1);
  animation:denial-spin 620ms linear infinite;
}
.add-btn.is-failed .add-btn-spinner{
  animation:none;
  border-color:var(--clr-fail);
  border-top-color:var(--clr-fail);
  opacity:1;
}
@keyframes denial-spin{ to{ transform:rotate(360deg); } }
@media (prefers-reduced-motion:reduce){
  .add-btn.is-loading .add-btn-spinner{ animation:none; }
}

.feedback{
  min-height:20px;
  font-family:var(--font-mono);
  font-size:12.5px;
  font-weight:500;
  color:var(--clr-fail);
  letter-spacing:.01em;
  opacity:0;
  transition:opacity var(--dur-fade) ease;
  max-width:min(90vw, 380px);
}
.feedback.is-shown{ opacity:1; }

.tally{
  margin:var(--sp-6) 0 0;
  font-family:var(--font-mono);
  font-size:11px;
  font-weight:400;
  letter-spacing:.06em;
  color:var(--clr-ink-faint);
}

/* ===========================================================================
   SCAN LINES - subtle ambient texture over the whole flat field, always on
   =========================================================================== */
.scan-lines{
  position:fixed; inset:0; z-index:5; pointer-events:none;
  background:repeating-linear-gradient(to bottom, rgba(4,4,4,.035) 0px, rgba(4,4,4,.035) 1px, transparent 1px, transparent 3px);
  mix-blend-mode:multiply; opacity:.5;
}

/* ===========================================================================
   FULL-SCREEN DENIAL FLASH
   =========================================================================== */
.flash-overlay{ position:fixed; inset:0; z-index:30; pointer-events:none; background:var(--clr-fail); opacity:0; }
.flash-overlay.is-flashing{ animation:denial-flash 280ms var(--ease-denial); }
@keyframes denial-flash{ 0%{opacity:0;} 12%{opacity:.5;} 100%{opacity:0;} }
@media (prefers-reduced-motion:reduce){ .flash-overlay.is-flashing{ animation:none; opacity:0 !important; } }

/* ===========================================================================
   SYSTEM LOG - a permanent, growing record of every denial. Newest on top.
   =========================================================================== */
.log-panel{
  width:min(92vw, 420px); margin:var(--sp-6) 0 0;
  border:1.5px solid var(--clr-ink); background:rgba(4,4,4,.045);
  max-height:168px; display:flex; flex-direction:column; text-align:left;
}
.log-head{ display:flex; align-items:center; gap:var(--sp-2); padding:8px 12px; border-bottom:1.5px solid var(--clr-ink); flex-shrink:0; }
.log-dot{ width:7px;height:7px;border-radius:50%; background:var(--clr-fail); animation:denial-pulse 1.4s ease-in-out infinite; flex-shrink:0; }
@keyframes denial-pulse{ 0%,100%{opacity:1;} 50%{opacity:.25;} }
.log-title{ font-family:var(--font-mono); font-size:10px; font-weight:500; letter-spacing:.14em; color:var(--clr-ink-soft); }
.log-live{ margin-left:auto; font-family:var(--font-mono); font-size:9px; font-weight:500; letter-spacing:.1em; color:var(--clr-fail); border:1px solid var(--clr-fail); border-radius:2px; padding:1px 5px; }
.log-list{ margin:0; padding:8px 12px; list-style:none; overflow-y:auto; display:flex; flex-direction:column; gap:6px; }
.log-list:empty::after{ content:"no attempts yet. that will change."; font-family:var(--font-mono); font-size:11px; color:var(--clr-ink-faint); }
.log-list li{ font-family:var(--font-mono); font-size:11px; line-height:1.4; color:var(--clr-ink-soft); display:flex; gap:8px; opacity:0; animation:log-in 220ms ease forwards; }
.log-list li .log-stamp{ color:var(--clr-ink-faint); flex-shrink:0; }
.log-list li .log-msg{ color:var(--clr-ink); }
@keyframes log-in{ from{opacity:0; transform:translateY(-4px);} to{opacity:1; transform:translateY(0);} }
@media (prefers-reduced-motion:reduce){ .log-list li{ animation:none; opacity:1; } }

/* ===========================================================================
   DEPTH - the scroll below the mechanic. Same flat lime field, same ink
   panels as the denial log, reused as "the rest of the fake dashboard":
   a release log, a roadmap, a support page. Nothing here is live - only
   the panel-dot on the real denial log up top pulses. These dots sit still,
   because these are records, not a feed.
   =========================================================================== */
.depth{
  width:100%;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:var(--sp-7);
  padding:var(--sp-8) var(--sp-4) calc(var(--sp-8) + var(--sp-4));
  position:relative;
  z-index:2;
}

.depth-lede,.depth-outro{
  max-width:480px;
  margin:0;
  text-align:center;
  font-family:var(--font-mono);
  font-size:12px;
  line-height:1.6;
  color:var(--clr-ink-soft);
}
.depth-outro{ margin-top:calc(-1 * var(--sp-3)); }

.panel{
  width:min(92vw, 640px);
  border:1.5px solid var(--clr-ink);
  background:rgba(4,4,4,.045);
  text-align:left;
}
.panel-head{
  display:flex; align-items:center; gap:var(--sp-2);
  padding:8px 12px; border-bottom:1.5px solid var(--clr-ink);
}
.panel-dot{ width:7px; height:7px; border-radius:50%; background:var(--clr-ink-faint); flex-shrink:0; }
.panel-title{ font-family:var(--font-mono); font-size:10px; font-weight:500; letter-spacing:.14em; color:var(--clr-ink-soft); }
.panel-tag{
  margin-left:auto; font-family:var(--font-mono); font-size:9px; font-weight:500; letter-spacing:.1em;
  color:var(--clr-ink-faint); border:1px solid var(--clr-ink-faint); border-radius:2px; padding:1px 5px;
}
.panel-body{ padding:var(--sp-4) var(--sp-4) var(--sp-5); }
.panel-sub{
  margin:0 0 var(--sp-4); font-family:var(--font-mono); font-size:11.5px; line-height:1.55; color:var(--clr-ink-soft);
}

/* ---------- RELEASE LOG ---------- */
.changelog-list{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; }
.changelog-entry{ padding:var(--sp-4) 0; border-top:1px dashed rgba(4,4,4,.18); }
.changelog-entry:first-child{ border-top:0; padding-top:0; }
.changelog-meta{ display:flex; align-items:baseline; gap:var(--sp-3); margin-bottom:6px; }
.changelog-version{ font-family:var(--font-mono); font-weight:600; font-size:12.5px; color:var(--clr-ink); }
.changelog-date{ font-family:var(--font-mono); font-size:10.5px; color:var(--clr-ink-faint); }
.changelog-changes{ margin:0 0 10px; padding-left:16px; display:flex; flex-direction:column; gap:4px; }
.changelog-changes li{ font-family:var(--font-display); font-weight:500; font-size:13px; line-height:1.45; color:var(--clr-ink-soft); }
.changelog-credits{ margin:0; font-family:var(--font-mono); font-size:10.5px; font-weight:600; letter-spacing:.08em; color:var(--clr-fail); }

/* ---------- ROADMAP ---------- */
.roadmap-list{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; }
.roadmap-row{
  display:grid; grid-template-columns:64px 1fr auto; gap:var(--sp-3); align-items:center;
  padding:10px 0; border-top:1px dashed rgba(4,4,4,.18);
}
.roadmap-row:first-child{ border-top:0; padding-top:0; }
.roadmap-quarter{ font-family:var(--font-mono); font-size:10px; color:var(--clr-ink-faint); }
.roadmap-item{ font-family:var(--font-display); font-weight:500; font-size:13.5px; line-height:1.35; color:var(--clr-ink); }
.roadmap-status{
  font-family:var(--font-mono); font-size:9px; font-weight:600; letter-spacing:.06em;
  padding:2px 6px; border:1px solid currentColor; justify-self:end; white-space:nowrap;
}
.status-shipped{ color:var(--clr-ink-soft); }
.status-progress{ color:var(--clr-ink); }
.status-planned{ color:var(--clr-ink-faint); }
.status-review{ color:var(--clr-fail); }

/* ---------- SUPPORT / FAQ ---------- */
.faq-list{ display:flex; flex-direction:column; }
.faq-item{ padding:12px 0; border-top:1px dashed rgba(4,4,4,.18); }
.faq-item:first-child{ border-top:0; padding-top:0; }
.faq-q{ margin:0 0 4px; font-family:var(--font-display); font-weight:700; font-size:13.5px; color:var(--clr-ink); }
.faq-a{ margin:0; font-family:var(--font-mono); font-size:12.5px; letter-spacing:.02em; color:var(--clr-fail); }

/* ===========================================================================
   RESPONSIVE
   =========================================================================== */
@media (max-width:520px){
  .stage{ padding:var(--sp-3); }
  .ca-box{ padding:8px 12px; }
  .add-btn{ padding:16px var(--sp-5); min-width:78vw; }
  .x-corner{ top:var(--sp-3); right:var(--sp-3); }
  .depth{ padding:var(--sp-6) var(--sp-3) calc(var(--sp-6) + var(--sp-3)); gap:var(--sp-6); }
  .roadmap-row{ grid-template-columns:1fr; row-gap:4px; }
  .roadmap-status{ justify-self:start; }
}

@media (max-height:560px){
  .caption{ margin-bottom:var(--sp-3); }
  .ca-box{ margin-bottom:var(--sp-4); }
  .cta-wrap{ gap:var(--sp-2); }
  .tally{ margin-top:var(--sp-4); }
}

/* Very short viewports (landscape phones, embedded frames): shrink the
   zero further and collapse the vertical rhythm so every element still
   fits without relying on the overflow-y:auto fallback above. */
@media (max-height:420px){
  .zero-wrap{ width:min(50vw, 34vh, 300px); height:min(50vw, 34vh, 300px); }
  .zero{ font-size:min(88vw, 60vh, 600px); }
  .stage{ padding:var(--sp-2); }
  .caption{ margin-bottom:var(--sp-2); font-size:12px; }
  .ca-box{ margin-bottom:var(--sp-2); padding:6px 12px; }
  .add-btn{ padding:12px var(--sp-4); }
  .tally{ margin-top:var(--sp-2); }
}
