/* ============================================================
   SATURNSHOP.ORG — closed-beta drop door, poster cut
   NAMED DIRECTION (saturndesign compose 2026-08-02, izzy's ruling
   2026-08-02: "whole page = the animated saturn, atmospheric,
   just an email box, minimal and premium, same theme"):
   "CLAIM-TICKET PHOTOCOPIER — FULL-BLEED PLATE."
   The page IS the halftone print. One action: email in the slot,
   the machine prints a claim ticket, the invite link lands by mail.
   Compass: paper/ink xerox-zine; mint = sticker OUTLINE only.
   Motion: stepped photocopier cadence; copier light-sweep; never tweens.
   ============================================================ */

:root {
  --paper: #ece7db;
  --paper-deep: #e0dac9;
  --ink: #141312;
  --mint: #d9e8cf;
  --muted: #5f5b53;
  --line: 2px solid var(--ink);
  --pad: clamp(20px, 4vw, 44px);
  --font: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --display: "Anton", "Archivo", sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, monospace;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body { height: 100%; }

body {
  font-family: var(--font);
  background: var(--paper);
  color: var(--ink);
  font-weight: 500;
  line-height: 1.35;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
  display: flex;
  flex-direction: column;
  min-height: 100svh;
}

::selection { background: var(--mint); color: var(--ink); }

h1 { text-transform: uppercase; font-weight: 400; }
a { color: inherit; text-decoration: none; }

/* ---------- the full-bleed plate ---------- */

.plate {
  position: fixed;
  inset: 0;
  z-index: 0;
  color: var(--ink);
}

.plate-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
.plate-canvas[hidden] { display: none; }

/* static fallback — the canvas paints over it; if WebGL dies this shows */
.plate-fallback {
  position: absolute;
  left: 50%;
  top: 40%;
  width: min(72vmin, 640px);
  height: min(72vmin, 640px);
  transform: translate(-50%, -50%);
  opacity: 0.85;
}
.plate-has-gl .plate-fallback { visibility: hidden; }

.grain {
  position: fixed;
  inset: 0;
  z-index: 30;
  pointer-events: none;
  opacity: 0.5;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.10 0'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)'/%3E%3C/svg%3E");
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 8px;
  z-index: 200;
  background: var(--ink);
  color: var(--paper);
  font-weight: 800;
  padding: 14px 18px;
}
.skip-link:focus { left: 8px; }

/* ---------- header ---------- */

.site-header {
  position: relative;
  z-index: 10;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: clamp(14px, 2.5vh, 24px) var(--pad) 0;
}

.brand {
  background: var(--ink);
  color: var(--paper);
  font-family: var(--display);
  font-size: clamp(18px, 3.4vw, 24px);
  letter-spacing: 0.02em;
  display: inline-flex;
  align-items: center;
  padding: 0 14px;
  min-height: 44px;
}
.brand-tld { color: var(--mint); }

.chip {
  display: inline-block;
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  border: 2px solid var(--ink);
  padding: 6px 10px;
  background: var(--paper);
}
/* mint = outline / sticker stroke — never a fill field */
.chip--mint { box-shadow: 0 0 0 4px var(--mint); }

/* ---------- the stage ---------- */

.stage {
  position: relative;
  z-index: 10;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  text-align: center;
  padding: 0 var(--pad) clamp(16px, 3vh, 36px);
  width: 100%;
  max-width: 720px;
  margin: 0 auto;
}

.stage-core {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* one line, so it can carry the whole header — crypto lives in the sub */
.claim {
  font-family: var(--display);
  font-size: clamp(44px, 8vw, 104px);
  line-height: 0.92;
  display: flex;
  flex-direction: column;
  margin-bottom: 12px;
  animation: claim-rise 0.5s steps(5) both;
}

@keyframes claim-rise {
  from { transform: translateY(10px); opacity: 0; }
  to { transform: none; opacity: 1; }
}

.claim-sub {
  font-weight: 600;
  color: var(--muted);
  margin-bottom: clamp(14px, 2.2vh, 22px);
}

/* ---------- the machine (email slot + ticket printer) ---------- */

.machine {
  position: relative;
  z-index: 10;
  width: 100%;
  max-width: 560px;
  background: var(--ink);
  color: var(--paper);
  border: var(--line);
  box-shadow: 0 0 0 4px var(--mint), 6px 6px 0 var(--ink);
  padding: 16px 16px 20px;
  text-align: left;
  scroll-margin-top: 24px;
}

.machine-label {
  display: block;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  margin-bottom: 8px;
}

.machine-row { display: flex; flex-wrap: wrap; gap: 10px; }

.machine-field {
  flex: 1 1 200px;
  display: flex;
  flex-direction: column;
}
.machine-field--wide { flex: 1 1 100%; }

.machine-row input,
.machine-form textarea {
  width: 100%;
  font-family: var(--font);
  font-size: 16px;
  font-weight: 600;
  border: 2px solid var(--paper);
  background: var(--ink);
  color: var(--paper);
  padding: 12px;
  min-height: 48px;
  border-radius: 0;
  resize: vertical;
}
.machine-row input::placeholder,
.machine-form textarea::placeholder { color: rgba(236, 231, 219, 0.55); }
.machine-row input:focus,
.machine-form textarea:focus { outline: 4px solid var(--mint); outline-offset: 0; }

/* ---------- form blocks: the application reads as two stamped steps ---------- */

.machine-block { margin-bottom: 14px; }

.block-stamp {
  display: block;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  color: rgba(236, 231, 219, 0.62);
  border-bottom: 1px dashed rgba(236, 231, 219, 0.35);
  padding-bottom: 7px;
  margin-bottom: 12px;
}

.stage-set { border: 0; margin-top: 12px; }
.stage-set legend { padding: 0; margin-bottom: 8px; }
.stage-row { display: flex; flex-wrap: wrap; gap: 8px; }

/* radio kept in the DOM for keyboard + form semantics; the stamp is the control */
.stage-chip { position: relative; display: block; }
.stage-chip input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.stage-chip span {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 10px 13px;
  border: 2px solid var(--paper);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
}
.stage-chip input:checked + span {
  background: var(--paper);
  color: var(--ink);
  box-shadow: 0 0 0 3px var(--mint);
}
.stage-chip input:focus-visible + span { outline: 3px solid var(--mint); outline-offset: 3px; }

.btn {
  font-family: var(--font);
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  border: 2px solid var(--ink);
  display: inline-flex;
  align-items: stretch;
  cursor: pointer;
  min-height: 44px;
  transition: background 0.15s, color 0.15s;
}
.btn > span { display: flex; align-items: center; padding: 0 14px; }
.btn .btn-arrow { border-left: 2px solid var(--ink); font-size: 16px; }

.machine-btn {
  background: var(--paper);
  color: var(--ink);
  border-color: var(--paper);
  flex: 0 0 auto;
}
.machine-btn--block {
  width: 100%;
  margin-top: 12px;
}
.machine-btn--block > span:first-child { flex: 1; justify-content: center; }
.machine-btn .btn-arrow { border-left-color: var(--ink); }
.machine-btn:hover { background: var(--mint); color: var(--ink); }
.machine-btn[disabled] { opacity: 0.7; cursor: wait; }

.machine-jam {
  margin-top: 12px;
  font-size: 13px;
  font-weight: 600;
  color: var(--paper);
}
.machine-jam a { text-decoration: underline; }

.machine-fine {
  margin-top: 12px;
  max-width: 40em;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
}

/* ---------- the ticket ---------- */

.ticket-slot {
  position: relative;
  margin: 0 6px;
}
.ticket-slot:empty { display: none; }

.ticket {
  position: relative;
  background: var(--paper);
  color: var(--ink);
  border: var(--line);
  border-top: 0;
  padding: 18px 18px 14px;
  text-align: left;
  transform-origin: top center;
  animation: ticket-print 0.7s steps(8) both;
  clip-path: polygon(0 0, 100% 0, 100% 96%, 94% 100%, 88% 96%, 82% 100%, 76% 96%,
    70% 100%, 64% 96%, 58% 100%, 52% 96%, 46% 100%, 40% 96%, 34% 100%, 28% 96%,
    22% 100%, 16% 96%, 10% 100%, 4% 96%, 0 100%);
}

@keyframes ticket-print {
  from { transform: translateY(-100%); }
  to { transform: none; }
}

.ticket-head {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  border-bottom: 1px dashed var(--ink);
  padding-bottom: 8px;
  margin-bottom: 12px;
  padding-right: 96px;
}

.ticket-title {
  font-family: var(--display);
  font-size: clamp(30px, 5vw, 44px);
  line-height: 0.95;
  margin-bottom: 12px;
  text-transform: uppercase;
}

.ticket-meta {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.7;
  margin-bottom: 12px;
  overflow-wrap: anywhere;
}

.ticket-stamp {
  position: absolute;
  top: 14px;
  right: 12px;
  font-family: var(--display);
  font-size: 15px;
  letter-spacing: 0.04em;
  border: 2px solid var(--ink);
  box-shadow: 0 0 0 3px var(--mint);
  background: var(--paper);
  padding: 6px 10px;
  transform: rotate(7deg);
}

.ticket-note {
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  max-width: 40ch;
  margin-bottom: 10px;
}

.ticket-barcode {
  height: 34px;
  background: repeating-linear-gradient(90deg,
    var(--ink) 0 2px, transparent 2px 5px,
    var(--ink) 5px 8px, transparent 8px 10px,
    var(--ink) 10px 11px, transparent 11px 16px,
    var(--ink) 16px 20px, transparent 20px 22px);
}

/* ---------- the build sheet ---------- */

/* Margin annotations, not a card wall: a hairline rule and a state stamp per
   point, printed straight onto the plate (the shader calms the dots behind
   this block). Boxing them would make uniform cards — the named slop
   tell this direction forbids — and an opaque paper box on a live ground
   reads as the print being ERASED, not as a label sitting on it.

   Every line carries a TRUE state stamp. LIVE items exist in the engine
   today; NEXT items are direction, not shipped capability — and the key
   line says so in the reader's own words, because a beta page that implies
   an unbuilt feature buys a signup and loses the customer.

   NO 01–04 NUMBERS ON THESE POINTS (izzy, 2026-08-06: "having these numbered
   is confusing"). The invite form directly above already stamps 01 · YOU and
   02 · WHAT YOU'RE SELLING in this exact mono — one page cannot spend the same
   mark on two meanings. A number is A STEP YOU TAKE; the stamp is WHETHER THE
   THING EXISTS. Numbering four capabilities also promised an order the reader
   can neither act on nor hold me to, and it printed first, so it outranked the
   one fact they came for. The stamp is the mark now, which is why it sits
   flush left with the rule and the headline — no margin-left on .point-state,
   and the mint halo bleeds into the gutter on purpose. */
.sheet {
  width: 100%;
  margin-top: clamp(20px, 3.2vh, 34px);
  text-align: left;
}

/* On wide screens the sheet BREAKS OUT of the 720px stage column and prints
   across the full plate, like the footer margin bar it rhymes with. Four
   stamped columns instead of a 2x2 block keeps the poster on one screen —
   the reason the breakout exists is height, not decoration.

   WIDTH ONLY, no margin/transform: .stage-core is a centring flex column and
   .stage is itself viewport-centred, so an over-wide child is already centred
   on the viewport. Adding margin-left:50% + translateX(-50%) on top of
   align-items:center double-shifts it and hangs the first column off the
   left edge (measured: -144px). */
@media (min-width: 1040px) {
  .sheet { width: min(1180px, calc(100vw - 2 * var(--pad))); }
}

.sheet-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin-bottom: 12px;
}

.sheet-head-name { color: var(--ink); }
.sheet-head-key { color: var(--muted); letter-spacing: 0.08em; }

.points {
  width: 100%;
  display: grid;
  gap: 16px 24px;
  text-align: left;
}

.point { border-top: 2px solid var(--ink); padding-top: 10px; }

/* the state stamp — mint reads as sticker OUTLINE only, per the compass */
.point-state {
  display: inline-block;
  border: 2px solid var(--muted);
  color: var(--muted);
  padding: 1px 5px;
  letter-spacing: 0.1em;
}

.point-state--live {
  border-color: var(--ink);
  color: var(--ink);
  box-shadow: 0 0 0 3px var(--mint);
}

.point-mark {
  display: block;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--muted);
  margin-bottom: 6px;
}

.point h3 {
  font-family: var(--display);
  font-size: clamp(21px, 3vw, 27px);
  line-height: 1;
  font-weight: 400;
  text-transform: uppercase;
  margin-bottom: 6px;
}

.point p {
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  max-width: 36ch;
}

@media (min-width: 720px) {
  .points { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1040px) {
  .points { grid-template-columns: repeat(4, 1fr); }
}

/* honeypot — invisible to people, magnetic to bots */
.hp {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

[hidden] { display: none !important; }

/* ---------- margin bar (print-margin data line) ---------- */

.margin-bar {
  position: relative;
  z-index: 10;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 16px;
  padding: 0 var(--pad) clamp(10px, 2vh, 18px);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--muted);
}

.margin-left { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 4px 16px; }

/* The signature line. nowrap keeps the heart welded to the words — an inline
   mark that shrink-to-fits can drop onto its own line and read as a stray
   glyph (the GEN-chip phantom-line bug, same shape). */
.margin-note {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

/* Black heart, drawn — never an emoji: the compass bans them, and an emoji
   would render in the reader's system font, full colour, off-palette. */
.margin-heart {
  width: 11px;
  height: 11px;
  flex: 0 0 auto;
  display: block;
  fill: var(--ink);
}

.margin-links { display: inline-flex; gap: 18px; }

.margin-links a {
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}
.margin-links a:hover { color: var(--muted); }

/* ---------- small screens ---------- */

@media (max-width: 640px) {
  .claim { font-size: clamp(38px, 13vw, 64px); margin-top: 10px; }
  .machine { padding: 14px 14px 18px; }
  .machine-btn { flex: 1 1 auto; }
  .machine-btn > span:first-child { flex: 1; justify-content: center; }
  .margin-bar { justify-content: center; text-align: center; }
}

/* short viewports (landscape phones): let the page scroll instead of crushing */
@media (max-height: 560px) {
  body { min-height: 560px; }
}

@media (prefers-reduced-motion: reduce) {
  .claim { animation: none; }
  .ticket { animation: none; }
}
