/* maratus — the site stylesheet. Shared by index.html and docs.html.

   The hybrid voice: paper, ink, one acid accent, Archivo Black lowercase
   display, IBM Plex Mono labels. The page is canvas turn 12b ("the
   board") — one full-bleed 12-column grid of unequal cells, materials
   carried by the cells, a mid type scale between display and body, and
   one 8 s CSS clock running the storyboard. Turn 12a ("surfaces") is
   archived on the canvas; `.v-b` scoping is kept so the two can still be
   diffed there. */

:root {
  --paper: #f4f3ee;
  --panel: #eae7de;
  --ink: #16150f;
  --ink-2: #2a2820;
  --ink-line: #3a3730;
  --body: #45423a;
  --muted: #8a8577;
  --hairline: #d8d5cc;
  --acid: #e8ff2f;
  --terminal-fg: #c9c5b8;
  --terminal-dim: #6f6d66;
  --display: 'Archivo Black', Arial, sans-serif;
  --sans: 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --mono: 'IBM Plex Mono', monospace;
  /* Strong ease-out — the built-in curves are too weak to read as intentional. */
  --out: cubic-bezier(.23, 1, .32, 1);
  --inout: cubic-bezier(.77, 0, .175, 1);
  --gutter: clamp(20px, 4vw, 44px);
}

/* --edge is where TEXT starts, on every section. Bands and cells still
   bleed to the page edge — only their inner padding uses this, so the
   material runs edge to edge while every line of type sits on one left
   margin. Mixing full-bleed and column-constrained sections without this
   left text starting at two different x positions. */
:root { --edge: var(--gutter); }

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body { background: var(--paper); color: var(--ink); font: 400 16px/1.5 var(--sans); -webkit-font-smoothing: antialiased; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
img { max-width: 100%; display: block; }
:focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; }

.wrap { max-width: 1240px; margin: 0 auto; padding: 0 var(--gutter); }
.v-b .wrap { max-width: none; }
.rule-b { border-bottom: 2px solid var(--ink); }
.skip { position: absolute; left: -9999px; }
.skip:focus { left: 12px; top: 12px; z-index: 50; background: var(--acid); color: var(--ink); padding: 10px 16px; font: 500 12px var(--mono); text-transform: uppercase; }

/* ---------- texture ---------- */
/* Film grain over the whole surface. Flat vector backgrounds read sterile;
   this is the cheapest way to give paper and ink some tooth. */
.grain { position: relative; }
.grain::after {
  content: ''; position: absolute; inset: 0; z-index: 4; pointer-events: none;
  opacity: .3; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.42'/%3E%3C/svg%3E");
}
.grain.on-ink::after { opacity: .26; mix-blend-mode: screen; }

/* ---------- type ---------- */
.display { font-family: var(--display); text-transform: lowercase; letter-spacing: -.04em; }
h1.hero-h { font-family: var(--display); text-transform: lowercase; font-size: clamp(58px, 10.5vw, 148px); line-height: .8; letter-spacing: -.06em; }
.h2 { font-family: var(--display); text-transform: lowercase; font-size: clamp(32px, 4.4vw, 48px); line-height: .92; letter-spacing: -.04em; }
.h3 { font: 600 clamp(14px, 1.2vw, 15px)/1.3 var(--sans); }
.lede { font-size: clamp(16.5px, 1.5vw, 19px); line-height: 1.5; color: var(--body); text-wrap: pretty; }
p.body { font-size: clamp(14px, 1.15vw, 15.5px); line-height: 1.55; color: var(--body); text-wrap: pretty; }
.eyebrow { font: 500 11px var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
.mono { font: 400 10.5px/1.6 var(--mono); color: var(--muted); }
.mono-up { text-transform: uppercase; letter-spacing: .07em; }
.stamp-mono { font: 500 12px/1.65 var(--mono); text-transform: uppercase; color: var(--ink); }
/* Acid always carries ink text — it turns up inside the dark story band too,
   where the inherited paper colour would be unreadable on yellow. */
.hl { background: var(--acid); color: var(--ink); padding: 0 .18em; }
.hl-s { background: var(--acid); color: var(--ink); padding: 0 3px; }

/* ---------- nav ---------- */
.nav { border-bottom: 2px solid var(--ink); background: var(--paper); position: sticky; top: 0; z-index: 30; }
.nav .wrap { height: 62px; display: flex; align-items: center; justify-content: space-between; }
.nav .brand { font-family: var(--display); font-size: 17px; letter-spacing: -.02em; text-transform: lowercase; }
.nav-links { display: flex; gap: clamp(12px, 2vw, 22px); align-items: center; font: 500 11px var(--mono); letter-spacing: .1em; text-transform: uppercase; color: #6b675c; }
.nav-links a { transition: color .16s ease; }
.nav-links a:hover { color: var(--ink); }
.nav-links .gh { display: inline-flex; color: var(--ink); }
.nav-links .cta { background: var(--acid); color: var(--ink); padding: 6px 13px; transition: background .16s ease, color .16s ease, transform .16s var(--out); }
.nav-links .cta:hover { background: var(--ink); color: var(--acid); }
.nav-links .cta:active { transform: scale(.97); }

/* ---------- buttons ---------- */
.btn, .btn-ghost {
  display: inline-block; padding: 15px 26px; font: 500 12px var(--mono);
  letter-spacing: .1em; text-transform: uppercase;
  transition: background .16s ease, color .16s ease, transform .16s var(--out);
}
.btn { background: var(--ink); color: var(--paper); }
.btn:hover { background: var(--acid); color: var(--ink); }
.btn-ghost { border: 2px solid var(--ink); color: var(--ink); }
.btn-ghost:hover { background: var(--acid); }
.btn:active, .btn-ghost:active { transform: scale(.97); }

.keycap {
  width: 100%; padding: 20px 24px; background: var(--acid); border: 2px solid var(--ink); color: var(--ink);
  font-family: var(--display); font-size: clamp(21px, 2.4vw, 28px); text-transform: lowercase;
  letter-spacing: -.02em; line-height: 1; display: flex; align-items: center; justify-content: space-between; gap: 16px;
  transition: background .16s ease, color .16s ease, transform .14s var(--out);
}
.keycap:hover { background: var(--ink); color: var(--acid); }
.keycap:active { transform: translateY(3px); }
.keycap.on-ink { background: var(--acid); }
.keycap.on-ink:hover { background: var(--paper); color: var(--ink); }
.keycap.inverse { background: var(--ink); color: var(--acid); }
.keycap.inverse:hover { background: var(--acid); color: var(--ink); }

/* ---------- scroll reveal ---------- */
/* Transform + opacity only, one strong ease-out, staggered by --d.
   Elements never enter from scale(0) — nothing in the world does that.

   EVERY hidden state is scoped to .js, which the inline snippet in <head>
   sets before first paint. Content is therefore visible by DEFAULT and
   only hides once scripting is confirmed to be running. Without that
   scoping, a blocked or failed site.js leaves 24 elements stuck at
   opacity:0 — which emptied the entire hero. Never hide content on the
   assumption that JS will arrive to bring it back. */
.rv-drop { transform: rotate(-2.5deg); }
.js .rv { opacity: 0; transform: translateY(22px); transition: opacity .75s var(--out), transform .75s var(--out); transition-delay: var(--d, 0s); }
.js .rv.in { opacity: 1; transform: none; }
.js .rv-x { opacity: 0; transform: translateX(-16px); transition: opacity .65s var(--out), transform .65s var(--out); transition-delay: var(--d, 0s); }
.js .rv-x.in { opacity: 1; transform: none; }
.js .rv-drop { opacity: 0; transform: translateY(-16px) scale(1.05) rotate(-2.5deg); transition: opacity .85s var(--out), transform .85s var(--out); transition-delay: var(--d, 0s); }
.js .rv-drop.in { opacity: 1; transform: rotate(-2.5deg); }

/* ---------- hero ---------- */
.hero { position: relative; border-bottom: 2px solid var(--ink); }
/* The break-out photo anchors to the content column, not the viewport —
   otherwise it drifts into the outer margin on wide screens. */
.hero .wrap { position: relative; padding-top: clamp(40px, 5.5vw, 68px); }
.hero-h .l { display: block; }
.hero-cells { display: grid; margin-top: clamp(28px, 3.5vw, 46px); border-top: 1px solid var(--hairline); }
.hero-cell { padding: 28px clamp(18px, 2vw, 30px) 36px; }
.hero-cell:first-child { padding-left: 0; }
.hero-cells > .hero-cell + .hero-cell { border-left: 1px solid var(--hairline); }
.hero-copy { max-width: 42ch; }
.hero-cta { display: flex; gap: 12px; margin-top: 30px; flex-wrap: wrap; }
.hero-stamp { display: flex; flex-direction: column; justify-content: space-between; height: 100%; gap: 20px; }
.hero-plate { background: var(--ink); border-left: 2px solid var(--ink); }

/* The device photo breaks the rule line — the one moment the grid is
   allowed to leak. Absolutely placed in 12a (the cell below it carries
   extra top padding to clear it), in flow with a negative margin in 12b. */
.device-break {
  position: absolute; right: clamp(20px, 4vw, 44px); bottom: -52px; z-index: 6;
  width: clamp(160px, 17vw, 224px); aspect-ratio: 200 / 208;
  border: 2px solid var(--ink); background: #eceade center/cover;
  box-shadow: 14px 17px 0 rgba(22, 21, 15, .16);
}
.device-inflow {
  width: 100%; aspect-ratio: 200 / 196; margin-top: -58px;
  border: 2px solid var(--ink); background: #eceade center/cover;
  box-shadow: 11px 14px 0 rgba(22, 21, 15, .16);
}

/* ---------- meet the box ---------- */
.meet { position: relative; z-index: 1; background: var(--paper); border-bottom: 2px solid var(--ink); display: grid; }
.meet-copy { padding: clamp(34px, 4vw, 52px) var(--gutter) clamp(34px, 4vw, 48px) var(--edge); }
.meet-copy p { margin-top: 18px; max-width: 46ch; }
.meet-panel { background: var(--panel); border-left: 2px solid var(--ink); padding: 92px var(--edge) 30px 26px; display: flex; flex-direction: column; justify-content: flex-end; gap: 14px; }
.states { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.state-shot { aspect-ratio: 1; background: var(--ink); padding: 7px; }
.state-shot > div { width: 100%; height: 100%; background: #fff; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px; }
/* Higher specificity than the flex rule above, or the QR's 169 cells
   collapse to zero height inside a centred flex column. */
.state-shot > .qr { display: grid; align-items: stretch; justify-items: stretch; gap: 0; }
.state-shot .dot { width: 10px; height: 10px; background: #0f7a54; }
.state-shot .nm { font: 600 9.5px var(--sans); }
.state-shot .tm { font: 400 8.5px var(--sans); color: var(--muted); }
.state-cap { margin-top: 7px; font: 500 9px var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.state-cap.now { color: var(--ink); }

/* ---------- the story, on the ink band ---------- */
.story { background: var(--ink); border-bottom: 2px solid var(--ink); color: var(--paper); }
.story-head { display: flex; align-items: baseline; justify-content: space-between; gap: 24px; padding-top: clamp(32px, 4vw, 48px); }
.story-head .h2 { color: var(--paper); }
.story-head .meta { text-align: right; font: 500 10px/1.7 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--terminal-dim); flex: none; }
.story-head .meta b { display: block; color: var(--acid); font-weight: 500; }

/* One 8 s clock, four 2 s beats. No JS: the page performs the thing it
   describes. Reduced motion parks every element on its settled state. */
/* overflow:hidden is load-bearing. .runner is a third of the rail wide so
   that translateX(0/100/200/300%) lands the square on the four stations;
   at the last one its trailing two-thirds hang past the rail and widen
   the whole page (measured: 388px of horizontal scroll at 1440). Only the
   14px square at its leading edge is ever visible, so clipping the rest
   costs nothing. */
.rail { position: relative; height: 14px; margin: clamp(24px, 3vw, 34px) 0 24px; overflow: hidden; }
.rail::before { content: ''; position: absolute; left: 0; right: 0; top: 6px; height: 2px; background: var(--ink-line); }
.runner { position: absolute; left: 0; top: 0; width: calc((100% - 14px) / 3); height: 14px; animation: runX 8s var(--out) infinite; }
.runner::before { content: ''; display: block; width: 14px; height: 14px; background: var(--acid); }
@keyframes runX {
  0%, 18% { transform: translateX(0); }
  28%, 46% { transform: translateX(100%); }
  56%, 74% { transform: translateX(200%); }
  84%, 100% { transform: translateX(300%); }
}
@keyframes numLit { 0%, 2% { opacity: .3; } 6%, 22% { opacity: 1; } 26%, 100% { opacity: .3; } }
@keyframes screenCode { 0%, 46% { opacity: 0; } 52%, 72% { opacity: 1; } 78%, 100% { opacity: 0; } }
@keyframes screenIdle { 0%, 46% { opacity: 1; } 52%, 72% { opacity: 0; } 78%, 100% { opacity: 1; } }
@keyframes holdLit {
  0%, 22% { background: transparent; border-color: var(--ink-line); color: var(--muted); }
  27%, 74% { background: var(--acid); border-color: var(--ink); color: var(--ink); }
  79%, 100% { background: transparent; border-color: var(--ink-line); color: var(--muted); }
}

.beats { display: grid; grid-template-columns: repeat(4, 1fr); border-top: 1px solid var(--ink-line); }
.beat { padding: 22px clamp(14px, 1.6vw, 24px) 30px; }
.beats > .beat:first-child { padding-left: var(--edge); }
.beats > .beat:last-child { padding-right: var(--edge); }
.beat + .beat { border-left: 1px solid var(--ink-line); }
.beat .n { font-family: var(--display); font-size: clamp(34px, 3.6vw, 50px); line-height: 1; color: var(--acid); opacity: 1; animation: numLit 8s linear infinite; }
.beat:nth-child(2) .n { animation-delay: 2s; }
.beat:nth-child(3) .n { animation-delay: 4s; }
.beat:nth-child(4) .n { animation-delay: 6s; }
.beat h3 { margin-top: 11px; font: 600 clamp(13px, 1.15vw, 14.5px)/1.3 var(--sans); color: var(--paper); }
.beat p { margin-top: 9px; font: 400 clamp(12.5px, 1.05vw, 13.5px)/1.5 var(--sans); color: #b8b4a6; }

.story-foot { display: grid; grid-template-columns: 1fr auto; gap: 24px; align-items: center; border-top: 1px solid var(--ink-line); padding: 24px 0; }
.story-log { font: 400 clamp(10px, .95vw, 11.5px)/1.95 var(--mono); color: var(--terminal-dim); }
.story-log .mid { color: var(--terminal-fg); }
.story-log .ok { color: var(--acid); }
.story-live { display: flex; align-items: center; gap: 16px; }
.mini-box { position: relative; flex: none; width: 84px; height: 84px; background: var(--ink-2); padding: 6px; }
.mini-screen { position: relative; width: 100%; height: 100%; background: #fff; overflow: hidden; }
.mini-idle { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font: 500 8.5px var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--muted); opacity: 0; animation: screenIdle 8s linear infinite; }
.mini-qr { position: absolute; inset: 4px; opacity: 1; animation: screenCode 8s linear infinite; }
.credit-pill { flex: none; border: 2px solid var(--ink); background: var(--acid); color: var(--ink); padding: 5px 12px; font: 500 10px var(--mono); text-transform: uppercase; letter-spacing: .06em; animation: holdLit 8s linear infinite; }

/* ---------- QR ---------- */
.qr { display: grid; grid-template-columns: repeat(13, 1fr); grid-template-rows: repeat(13, 1fr); }

/* ---------- live demo ---------- */
.demo { background: var(--panel); border-bottom: 2px solid var(--ink); padding: clamp(28px, 3.4vw, 40px) 0; }
.demo-head { display: flex; align-items: baseline; justify-content: space-between; gap: 20px; margin-bottom: 18px; }
.demo-head .live { display: flex; align-items: center; gap: 7px; font: 500 11px var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--ink); flex: none; }
.demo-head .live::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--ink); animation: blink 1.6s infinite; }
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: .15; } }
.demo-grid { display: grid; grid-template-columns: 1fr 200px; gap: 16px; align-items: stretch; }
.terminal { border: 2px solid var(--ink); background: var(--ink); display: flex; flex-direction: column; overflow: hidden; }
.terminal-bar { display: flex; justify-content: space-between; gap: 12px; padding: 9px 14px; background: var(--acid); color: var(--ink); font: 600 9.5px var(--mono); text-transform: uppercase; letter-spacing: .14em; }
.terminal-log { padding: 14px; font: 400 clamp(10.5px, 1vw, 12px)/1.95 var(--mono); color: var(--terminal-fg); flex: 1; min-height: 150px; }
.terminal-log div { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.terminal-log .actor { display: inline-block; width: 54px; color: var(--terminal-dim); text-transform: uppercase; font-size: 9.5px; letter-spacing: .08em; }
.terminal-log .dim { color: var(--terminal-dim); }
.terminal-log .ok { color: var(--acid); }
.panel-qr { border: 2px solid var(--ink); background: #fff; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; padding: 16px; }
.panel-qr .qr { width: 132px; height: 132px; opacity: .18; transition: opacity .4s var(--out); }
.panel-qr .qr.shown { opacity: 1; }
/* Same track sizes and gap as .demo-grid above it — the two rows read as
   one two-column block, so the terminal/QR seam and the button/meta seam
   have to fall on the same line. */
.demo-actions { display: grid; grid-template-columns: 1fr 200px; gap: 16px; align-items: stretch; margin-top: 16px; }
.demo-meta { border: 2px solid var(--ink); padding: 11px 14px; font: 500 9.5px/1.5 var(--mono); text-transform: uppercase; letter-spacing: .06em; display: flex; flex-direction: column; justify-content: center; }
.demo-meta .k { color: var(--muted); }
.demo-meta .v { color: var(--ink); font-size: 11.5px; }
.demo-meta .k + .v { margin-bottom: 6px; }

/* ---------- marquee ---------- */
.marquee { background: var(--ink); border-bottom: 2px solid var(--ink); overflow: hidden; padding: 13px 0; }
.marquee-track { display: flex; width: 200%; animation: marq 30s linear infinite; font-family: var(--display); font-size: clamp(16px, 1.7vw, 21px); letter-spacing: -.02em; text-transform: lowercase; color: var(--acid); white-space: nowrap; }
.marquee-track span { flex: none; width: 50%; }
@keyframes marq { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ---------- beyond, as a ledger ---------- */
.beyond { padding: clamp(34px, 4vw, 52px) 0; border-bottom: 2px solid var(--ink); }
.ledger { margin-top: 26px; border-top: 1px solid var(--hairline); }
.ledger-row { display: flex; align-items: baseline; gap: 20px; padding: 15px 8px; border-bottom: 1px solid var(--hairline); transition: background .2s ease, padding-left .2s var(--out); }
.ledger-row .who { flex: none; width: 108px; font: 500 10px var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.ledger-row .what { font-size: clamp(15px, 1.4vw, 18px); line-height: 1.4; color: var(--body); }
@media (hover: hover) and (pointer: fine) {
  .ledger-row:hover { background: var(--panel); padding-left: 18px; }
}

/* ---------- price, on acid ---------- */
.price { background: var(--acid); border-bottom: 2px solid var(--ink); display: grid; }
.price-big { padding: clamp(38px, 4.4vw, 58px) var(--gutter) clamp(38px, 4.4vw, 58px) var(--edge); border-right: 2px solid var(--ink); }
.price-big .h2 { font-size: clamp(36px, 5.4vw, 66px); line-height: .86; letter-spacing: -.05em; }
.price-side { padding: clamp(30px, 4vw, 58px) var(--edge) clamp(30px, 4vw, 58px) var(--gutter); display: flex; flex-direction: column; justify-content: center; gap: 16px; }
.price-side p { font-size: clamp(14px, 1.2vw, 15px); line-height: 1.55; color: var(--ink); }
.price-side .fine { font: 500 10px/1.7 var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--ink); opacity: .62; }

/* ---------- pilot ---------- */
.pilot { border-bottom: 2px solid var(--ink); display: grid; }
.pilot-copy { padding: clamp(34px, 4vw, 50px) var(--gutter) clamp(34px, 4vw, 50px) var(--edge); }
.pilot-copy p { margin-top: 18px; max-width: 52ch; }
.founder { margin-top: 16px; max-width: 56ch; font: 400 12px/1.65 var(--mono); color: #6b675c; }
.founder a { border-bottom: 1px solid var(--ink); color: var(--ink); }
.pilot-act { border-left: 2px solid var(--ink); background: var(--panel); display: flex; align-items: center; padding: 26px var(--edge) 26px 26px; }

/* ---------- faq ---------- */
.faq { padding: clamp(30px, 3.6vw, 44px) 0 clamp(34px, 4vw, 48px); border-bottom: 2px solid var(--ink); }
.faq-list { margin-top: 20px; border-top: 2px solid var(--ink); }
.faq-row { display: grid; grid-template-columns: 320px 1fr; gap: 34px; padding: 17px 8px; border-bottom: 1px solid var(--hairline); transition: background .2s ease; }
.faq-row p { font-size: 13.5px; line-height: 1.55; color: var(--body); }
@media (hover: hover) and (pointer: fine) { .faq-row:hover { background: var(--panel); } }

/* ---------- dev strip ---------- */
.dev { border-bottom: 2px solid var(--ink); display: grid; }
/* min-width:0 defeats the grid item's automatic minimum size. Without it
   the cell cannot shrink below the min-content width of the `pre` code
   block it holds, so on a phone the 1fr column grows past the viewport
   and the whole page scrolls sideways (measured: 418px in a 390px view). */
.dev-code { min-width: 0; padding: clamp(28px, 3.4vw, 42px) var(--gutter) clamp(28px, 3.4vw, 42px) var(--edge); border-right: 2px solid var(--ink); }
.codeblock { margin-top: 14px; background: var(--ink); color: var(--terminal-fg); padding: 16px 18px; font: 400 clamp(10px, .95vw, 11.5px)/1.85 var(--mono); overflow-x: auto; white-space: pre; }
.codeblock .c-hl { color: var(--acid); }
.dev-side { padding: clamp(28px, 3.4vw, 42px) var(--edge) clamp(28px, 3.4vw, 42px) var(--gutter); background: var(--panel); display: flex; flex-direction: column; justify-content: center; }
.dev-side p { margin-top: 12px; font-size: 13.5px; line-height: 1.5; color: var(--body); }

/* ---------- footer ---------- */
/* The wordmark is clipped by the page edge on purpose — the site ends
   mid-letter rather than trailing off into a link farm. */
.footer { position: relative; height: clamp(74px, 9vw, 116px); overflow: hidden; background: var(--paper); }
.footer .mark { position: absolute; left: calc(var(--edge) - .07em); top: 12px; font-family: var(--display); font-size: clamp(84px, 12vw, 150px); line-height: 1; letter-spacing: -.06em; text-transform: lowercase; color: var(--ink); }
.footer .meta { position: absolute; right: var(--edge); bottom: 16px; text-align: right; font: 500 10.5px/1.7 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.footer .meta a { color: var(--muted); }
.footer .meta a:hover { color: var(--ink); }
/* Seven letters need more room than five. On a phone the wordmark would run
   under the email line, so the two stop sharing a row: the meta lifts to the
   top and the mark takes the floor, still cut off by the bottom edge. */
@media (max-width: 560px) {
  .footer { height: 100px; }
  .footer .mark { font-size: 76px; top: 36px; }
  .footer .meta { top: 12px; bottom: auto; }
}

/* ======================================================================
   12b — the grid leads. Same components, but every section is a row on
   one 12-column board, and cells (not bands) carry the materials.
   ====================================================================== */
.v-b .board { display: grid; grid-template-columns: repeat(12, 1fr); }
.v-b .hero .wrap { max-width: none; padding: 0; }
.v-b .hero-main { grid-column: span 9; padding: clamp(36px, 4.4vw, 56px) clamp(20px, 2.4vw, 32px) clamp(56px, 7vw, 96px) var(--edge); border-right: 2px solid var(--ink); }
.v-b .hero-main .lede { margin-top: clamp(22px, 2.6vw, 32px); max-width: 44ch; }
.v-b .hero-bye { grid-column: span 3; background: var(--acid); display: flex; align-items: center; justify-content: center; padding: 24px 0; }
.v-b .hero-bye span { font-family: var(--display); font-size: clamp(38px, 5vw, 70px); line-height: 1; letter-spacing: -.05em; text-transform: lowercase; writing-mode: vertical-rl; transform: rotate(180deg); }
.v-b .meet { grid-template-columns: repeat(12, 1fr); }
.v-b .meet-shelf { grid-column: span 3; background: var(--panel); border-right: 2px solid var(--ink); padding: 0 clamp(14px, 1.8vw, 22px) 22px var(--edge); display: flex; flex-direction: column; }
.v-b .meet-copy { grid-column: span 6; border-right: 2px solid var(--ink); }
.v-b .meet-stamp { grid-column: span 3; background: var(--panel); padding: 30px clamp(16px, 2vw, 24px); display: flex; flex-direction: column; justify-content: center; gap: 14px; }
.v-b .price { grid-template-columns: repeat(12, 1fr); }
.v-b .price-big { grid-column: span 7; }
.v-b .price-side { grid-column: span 5; }
.v-b .pilot { grid-template-columns: repeat(12, 1fr); }
.v-b .pilot-copy { grid-column: span 8; border-right: 2px solid var(--ink); }
.v-b .pilot-act { grid-column: span 4; background: var(--ink); border-left: none; }
.v-b .dev { grid-template-columns: repeat(12, 1fr); }
.v-b .dev-code { grid-column: span 8; }
.v-b .dev-side { grid-column: span 4; }
/* 12b keeps 12a's dark story band — it is the one place the page should
   go quiet and let the mechanism speak. What stays 12b's own is that the
   whole CELL takes the beat, not just the number.

   Text colour has to travel with the background: an acid cell under
   paper-coloured type is unreadable, so the keyframe animates `color`
   too and the children inherit it. At rest that reads as dim paper on
   ink; on the beat, solid ink on acid. */
@keyframes cellDark {
  0%, 2% { background: transparent; color: var(--paper); }
  6%, 22% { background: var(--acid); color: var(--ink); }
  26%, 100% { background: transparent; color: var(--paper); }
}
.v-b .beat { color: var(--paper); animation: cellDark 8s linear infinite; }
.v-b .beat:nth-child(2) { animation-delay: 2s; }
.v-b .beat:nth-child(3) { animation-delay: 4s; }
.v-b .beat:nth-child(4) { animation-delay: 6s; }
.v-b .beat .n, .v-b .beat h3, .v-b .beat p { color: inherit; }
.v-b .beat p { opacity: .74; }

/* ---------- responsive ---------- */
@media (max-width: 1020px) {
  .hero-plate { display: none; }
  .device-break { position: static; width: 100%; max-width: 260px; margin: 26px 0 0; box-shadow: 10px 12px 0 rgba(22, 21, 15, .16); }
  .meet-panel { padding-top: 34px; }
  .faq-row { grid-template-columns: 260px 1fr; gap: 24px; }
}

@media (max-width: 880px) {
  .hero-cell { padding-left: 0; padding-right: 0; }
  .hero-cells > .hero-cell + .hero-cell { border-left: none; border-top: 1px solid var(--hairline); }
  .beats { grid-template-columns: 1fr 1fr; }
  .beat:nth-child(3), .beat:nth-child(4) { border-top: 1px solid var(--ink-line); }
  .beat:nth-child(3) { border-left: none; }
  .demo-grid { grid-template-columns: 1fr; }
  .panel-qr { padding: 22px; }
  .story-foot { grid-template-columns: 1fr; }
  .meet-panel, .price-big, .price-side, .dev-code, .dev-side, .pilot-act, .pilot-copy { border-left: none; border-right: none; }
  .meet-panel, .pilot-act { border-top: 2px solid var(--ink); }
  .price-big { border-right: none; border-bottom: 2px solid var(--ink); }
  .dev-code { border-right: none; border-bottom: 2px solid var(--ink); }
  .faq-row { grid-template-columns: 1fr; gap: 6px; }
  .demo-actions { grid-template-columns: 1fr; }
  /* 12b's board collapses to single-column bands — a 12-column grid on a
     phone is just four illegible slivers. */
  .v-b .board, .v-b .meet, .v-b .price, .v-b .pilot, .v-b .dev { grid-template-columns: 1fr; }
  .v-b .hero-main, .v-b .meet-copy, .v-b .meet-shelf, .v-b .pilot-copy, .v-b .dev-code, .v-b .price-big { border-right: none; }
  .v-b .hero-main { grid-column: auto; padding-bottom: 34px; }
  .v-b .hero-bye { grid-column: auto; padding: 16px 0; }
  .v-b .hero-bye span { writing-mode: horizontal-tb; transform: none; font-size: 44px; }
  .v-b .meet-shelf, .v-b .meet-copy, .v-b .meet-stamp, .v-b .price-big, .v-b .price-side, .v-b .pilot-copy, .v-b .pilot-act, .v-b .dev-code, .v-b .dev-side { grid-column: auto; }
  .v-b .meet-shelf { padding-top: 26px; }
  .device-inflow { margin-top: 0; max-width: 260px; }
  .v-b .price-big { border-bottom: 2px solid var(--ink); }
  .v-b .dev-code { border-bottom: 2px solid var(--ink); }
  .v-b .pilot-act { border-top: 2px solid var(--ink); }
  .nav-links { font-size: 10px; letter-spacing: .06em; }
  .nav-links .hide-sm { display: none; }
}

@media (max-width: 560px) {
  .beats { grid-template-columns: 1fr; }
  .beat + .beat { border-left: none; border-top: 1px solid var(--ink-line); }
  .ledger-row { flex-direction: column; gap: 4px; }
  .ledger-row .who { width: auto; }
  .story-live { flex-wrap: wrap; }
}

/* ---------- reduced motion ---------- */
/* Fewer and gentler, not zero: the reveals resolve instantly and the
   8 s clock parks on its settled state — code shown, credit spent. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .rv, .rv-x, .rv-drop { opacity: 1; transform: none; }
  .rv-drop { transform: rotate(-2.5deg); }
  .device-break, .device-inflow { transform: rotate(-2.5deg); }
  .panel-qr .qr { opacity: 1; }
}

/* ======================================================================
   BRANDING STUDIO — #brand
   A looping replay of an editing session in the console: logo and text
   dragged onto the 720x720 screen, then real preset themes repainting
   background, text and accent together. Clicking a theme hands control
   over and stops the loop.
   ====================================================================== */
.branding { border-bottom: 2px solid var(--ink); display: grid; }
.v-b .branding { grid-template-columns: repeat(12, 1fr); }
.v-b .brand-copy { grid-column: span 7; }
.v-b .brand-stage { grid-column: span 5; }
.brand-copy { padding: clamp(34px, 4vw, 50px) var(--gutter) clamp(34px, 4vw, 50px) var(--edge); border-right: 2px solid var(--ink); }
.brand-copy p { margin-top: 16px; max-width: 52ch; }
.themes { display: flex; gap: 9px; align-items: center; flex-wrap: wrap; margin-top: 22px; }
.pill { display: inline-flex; align-items: center; gap: 8px; border: 2px solid var(--ink); background: #fff; color: var(--ink);
  padding: 7px 14px; font: 500 10.5px var(--mono); text-transform: uppercase; letter-spacing: .06em;
  transition: background .16s ease, transform .16s var(--out); }
.pill:hover { background: var(--acid); }
.pill:active { transform: scale(.97); }
.pill[aria-pressed="true"] { background: var(--acid); }
.swatch-dot { width: 11px; height: 11px; border-radius: 50%; }

.brand-stage { position: relative; background: var(--ink); display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 14px; padding: 30px 22px; }
.brand-stage .cap { font: 500 10px var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--acid); }
.studio-tray { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
.tray-chip { border: 2px dashed var(--ink-line); color: var(--muted); padding: 4px 12px;
  font: 500 10px var(--mono); text-transform: uppercase; letter-spacing: .08em; transition: border-color .2s ease, color .2s ease; }
.tray-chip.dim { opacity: .4; }
.studio[data-step="1"] .tray-chip[data-obj="logo"],
.studio[data-step="2"] .tray-chip[data-obj="text"] { border-color: var(--acid); color: var(--acid); }
/* The screen is the one surface on the page that is NOT ours — it takes
   the merchant's palette, so its colours come from custom properties the
   theme picker sets, never from the site tokens. */
.studio-screen { position: relative; width: 210px; height: 210px; border: 2px solid #000; overflow: hidden;
  background: var(--p-bg, #FAF6F0); transition: background .5s ease;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; }
.pc-logo { display: flex; align-items: center; gap: 8px; font: 600 18px var(--sans); color: var(--p-fg, #2B211A); transition: color .5s ease; }
.js .pc-logo { opacity: 0; }
.pc-logo i { width: 15px; height: 15px; background: var(--p-accent, #B4541F); transition: background .5s ease; }
.pc-text { font: 400 11px var(--sans); color: var(--p-muted, #9A8B7D); transition: color .5s ease; }
.js .pc-text { opacity: 0; }
@keyframes dropIn { 0% { opacity: 0; transform: translateY(-14px) scale(1.18); } 60% { opacity: 1; transform: translateY(2px) scale(.97); } 100% { opacity: 1; transform: none; } }
.studio .on { opacity: 1; animation: dropIn .45s cubic-bezier(.34, 1.3, .5, 1); }
.drag-ghost { position: absolute; left: 0; top: 0; z-index: 3; border: 2px dashed var(--acid); color: var(--acid);
  background: rgba(22, 21, 15, .85); padding: 4px 12px; font: 500 10px var(--mono); text-transform: uppercase;
  letter-spacing: .08em; opacity: 0; pointer-events: none;
  transition: transform .7s cubic-bezier(.45, 0, .3, 1), opacity .2s ease; }
.drag-ghost.flying { opacity: 1; transform: rotate(-4deg); }
@keyframes savedFlash { 0%, 100% { box-shadow: 0 0 0 0 rgba(232, 255, 47, 0); } 40% { box-shadow: 0 0 0 5px rgba(232, 255, 47, .9); } }
.studio[data-step="4"] .studio-screen { animation: savedFlash 1s ease; }
.studio-status { min-height: 16px; text-align: center; font: 500 10px var(--mono); letter-spacing: .06em; color: var(--muted); }
.studio[data-step="4"] .studio-status { color: var(--acid); }

/* ======================================================================
   DOCS PAGE — docs.html shares this stylesheet, so its own components
   live here rather than in a second file.
   ====================================================================== */
.hero-sub { padding: clamp(34px, 4.4vw, 56px) 0 clamp(28px, 3.4vw, 40px); border-bottom: 2px solid var(--ink); }
.hero-sub h1 { font-family: var(--display); text-transform: lowercase; font-size: clamp(38px, 6vw, 72px); line-height: .88; letter-spacing: -.045em; }
.hero-sub p { margin-top: 24px; max-width: 62ch; font-size: clamp(15px, 1.4vw, 17.5px); line-height: 1.55; color: var(--body); text-wrap: pretty; }
.doc-sec { padding: clamp(28px, 3.4vw, 40px) 0 clamp(30px, 3.6vw, 44px); border-bottom: 2px solid var(--ink); }
.doc-h2 { font-family: var(--display); text-transform: lowercase; font-size: clamp(22px, 2.8vw, 32px); line-height: .95; letter-spacing: -.035em; }
.doc-p { margin-top: 14px; max-width: 68ch; font-size: clamp(14px, 1.2vw, 15.5px); line-height: 1.6; color: var(--body); text-wrap: pretty; }
.doc-p + .doc-p { margin-top: 12px; }
.doc-p strong { color: var(--ink); }
.doc-link, .doc-p a { color: var(--ink); border-bottom: 1px solid var(--ink); }
.inline-code { font: 500 12px var(--mono); background: var(--panel); padding: 1px 6px; }
.doc-sec .codeblock { margin-top: 18px; }
/* Was unstyled on the shipped page — the 202 line rendered as bare text. */
.resultblock { margin-top: 10px; border: 2px solid var(--ink); border-left: 6px solid var(--acid);
  padding: 11px 14px; font: 500 clamp(10.5px, 1vw, 12px)/1.6 var(--mono); color: var(--ink); background: var(--panel); }
.err-table { margin-top: 20px; border: 2px solid var(--ink); overflow-x: auto; }
.err-row { display: grid; grid-template-columns: 64px 240px 1fr; gap: 16px; padding: 10px 15px;
  font: 400 clamp(11px, 1vw, 12.5px)/1.5 var(--mono); color: var(--body); min-width: 620px; }
.err-row + .err-row { border-top: 1px solid var(--hairline); }
.err-row span:first-child { color: var(--ink); font-weight: 600; }
.err-row span:nth-child(2) { color: var(--ink); }
.err-ok { background: var(--acid); }
.err-ok span { color: var(--ink) !important; }

@media (max-width: 880px) {
  .branding, .v-b .branding { grid-template-columns: 1fr; }
  .v-b .brand-copy, .v-b .brand-stage { grid-column: auto; }
  .brand-copy { border-right: none; border-bottom: 2px solid var(--ink); }
  .err-row { grid-template-columns: 56px 1fr; min-width: 0; }
  .err-row span:last-child { grid-column: 1 / -1; }
}
