/* atinformatics.com, the design system
 *
 * Docket CX, settled 2026-10-02 after six rejected passes. The decisions below
 * are LOCKED. See STYLE-LOCK.md before changing any of them.
 *
 * PALETTE is not invented. It was extracted from his own artwork
 * (AI/Website For Claude Images/Aftertime light 2 .png) with a deterministic
 * script: every dominant colour in that image sits at hue 39, saturation
 * 0.08-0.09, which is why it reads as one warm family rather than a scheme.
 * All 21 pairings were then measured. Run check_contrast.py --matrix after any
 * change here.
 *
 * THE GOLD TRAP. The artwork's bright gold #d4af6a measures 1.9:1 on paper and
 * FAILS outright as text. It survives as graphics only. Anything readable uses
 * #866113. This was caught by measuring, not by looking -- and deepened again
 * on 2026-10-03, from #8a6414, because the repaired checker showed gold links
 * on a raised surface at 4.32:1. Four points of lightness, hue unchanged at
 * 40.7 degrees.
 *
 * NO SCROLL-ZOOM, EVER. A previous build scaled the page as you scrolled; the
 * founder reported vertigo and wanting to leave. Motion lives in the looping
 * hero video and in opacity/translate reveals. Nothing scales on scroll.
 *
 * TYPE is Manrope, self-hosted. The "no web fonts" rule only ever meant "no
 * third-party request", self-hosting satisfies both, so the strict CSP and
 * the zero-third-party claim survive. He rejects SF Pro and rejects serifs.
 */

@font-face{
  font-family:'Manrope';
  src:url('fonts/manrope-var.woff2') format('woff2');
  font-weight:200 800; font-style:normal; font-display:swap;
}

:root{
  /* measured, see the header */
  --text:#15181a;  --bg:#f2ece0;  --surface:#ede6d9;
  --primary:#866113; --accent:#b07d12; --border:#d4cdc0; --on-primary:#faf6ec;
  --muted:#5d625c;
  --ink-soft:#6f746d;

  /* spacing scale, picked once and reused. internal padding never exceeds the
     gap to the neighbour, which is what stops a layout reading cramped. */
  --s2:8px; --s3:12px; --s4:20px; --s5:32px; --s6:52px; --s7:84px; --s8:136px;

  --r-sm:6px; --r-md:12px; --r-lg:22px;
  --ease:cubic-bezier(.22,.8,.2,1);
  --measure:52ch;
}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--bg); color:var(--text);
  font-family:'Manrope',system-ui,-apple-system,sans-serif;
  font-size:17px; line-height:1.6; -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img,video{max-width:100%}
a{color:inherit;text-decoration:none}
a:focus-visible,button:focus-visible{outline:2px solid var(--primary);outline-offset:3px}

.wrap{width:min(1640px,88vw);margin:0 auto}
.narrow{width:min(900px,88vw);margin:0 auto}

h1,h2,h3,h4{margin:0;font-weight:800;letter-spacing:-.04em;line-height:.96}
h1{font-size:clamp(2.6rem,5.6vw,5.4rem)}
h2{font-size:clamp(2rem,4.4vw,4rem)}
h3{font-size:clamp(1.25rem,1.9vw,1.75rem);letter-spacing:-.03em}
h4{font-size:1.06rem;letter-spacing:-.02em;font-weight:700}
p{margin:0}
.lede{font-size:clamp(1.04rem,1.3vw,1.28rem);line-height:1.55;color:var(--muted);max-width:var(--measure)}
.mono{font:700 11px/1 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.24em;text-transform:uppercase}
.gold{color:var(--primary)}
.stack>*+*{margin-top:var(--s4)}

.skip{position:absolute;left:-9999px;background:var(--primary);color:var(--on-primary);
  padding:12px 18px;z-index:200;font-weight:700}
.skip:focus{left:12px;top:12px}

/* ───────────────────────────── nav ───────────────────────────── */
.nav{position:fixed;inset:0 0 auto 0;z-index:90;display:flex;align-items:center;
  gap:var(--s5);padding:16px clamp(20px,6vw,56px);
  background:linear-gradient(180deg,rgba(242,236,224,.92),rgba(242,236,224,0));
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
.nav .brand{font-weight:800;font-size:14px;letter-spacing:-.02em;white-space:nowrap}
.nav .brand .dot{color:var(--primary)}
.nav ul{margin:0 0 0 auto;padding:0;display:flex;gap:var(--s5);list-style:none;flex-wrap:wrap}
.nav a{font-size:13.5px;color:var(--muted);transition:color .2s}
.nav a[aria-current="page"]{color:var(--text)}
@media (hover:hover) and (pointer:fine){ .nav a:hover{color:var(--text)} }
@media (max-width:620px){
  .nav{gap:var(--s3) var(--s4);flex-wrap:wrap;padding-bottom:12px}
  .nav ul{margin-left:0;width:100%;gap:var(--s4)}
}

/* ───────────────────────────── hero ─────────────────────────────
   Full bleed. The plate IS the page, not an object floating on it. */
.hero{position:relative;min-height:100svh;display:flex;flex-direction:column;
  justify-content:flex-end;overflow:hidden;isolation:isolate}
.hero video,.hero>img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;z-index:-2}
.hero::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(180deg,rgba(242,236,224,.74) 0,rgba(242,236,224,0) 24%,
             rgba(242,236,224,0) 44%,rgba(242,236,224,.9) 88%,var(--bg) 100%)}
.hero .wrap{padding-bottom:clamp(40px,7vh,88px)}
.wordmark{font-weight:800;letter-spacing:-.055em;line-height:.84;
  font-size:clamp(3rem,13vw,13rem);margin:0 0 var(--s4)}
.wordmark .dot{color:var(--primary)}
.herorow{display:flex;align-items:flex-end;justify-content:space-between;
  gap:var(--s6);flex-wrap:wrap}
.hero .lede{max-width:36ch}
.cue{display:flex;align-items:center;gap:12px;color:var(--muted)}
.cue i{display:block;width:54px;height:1px;background:var(--primary)}

/* a shorter hero for inner pages: no video, just air and a title */
.pagehead{padding:clamp(7rem,13vh,10rem) 0 var(--s7);border-bottom:1px solid var(--border)}
.pagehead .mono{color:var(--primary);margin-bottom:var(--s4);display:block}
.pagehead .lede{margin-top:var(--s4)}

/* ───────────────────────────── chapters ───────────────────────────── */
.chapter{padding:var(--s8) 0;border-top:1px solid var(--border)}
.chapter:first-of-type{border-top:0}
.chead{display:grid;gap:var(--s4);margin-bottom:var(--s6)}
@media(min-width:900px){.chead{grid-template-columns:14rem 1fr;gap:var(--s6);align-items:start}}
.chead .num{color:var(--primary)}
.chead .sub{margin-top:var(--s4);color:var(--muted);line-height:1.55;max-width:var(--measure)}

/* ───────────────────────────── cards & rows ───────────────────────────── */
.grid{display:grid;gap:1px;background:var(--border);border:1px solid var(--border)}
@media(min-width:900px){
  .grid-2{grid-template-columns:repeat(2,1fr)}
  .grid-3{grid-template-columns:repeat(3,1fr)}
  .grid-lead{grid-template-columns:1.5fr 1fr 1fr}
}
.cell{background:var(--bg);padding:clamp(1.7rem,2.5vw,2.7rem);display:flex;
  flex-direction:column;justify-content:space-between;min-height:19rem;
  transition:background .3s var(--ease)}
@media (hover:hover) and (pointer:fine){ a.cell:hover{background:#fffdf7} }
.cell .tag{color:var(--ink-soft);margin:0 0 var(--s4)}
.cell h3{margin-bottom:10px}
.cell p{color:var(--muted);line-height:1.52;font-size:.98rem}

.go{display:inline-flex;align-items:center;gap:10px;margin-top:var(--s5);color:var(--primary)}
.go::after{content:"";width:40px;height:1px;background:currentColor;
  transform:scaleX(.55);transform-origin:left;transition:transform .25s var(--ease)}
@media (hover:hover) and (pointer:fine){ a:hover .go::after{transform:scaleX(1)} }
.pending{opacity:.5;cursor:default}

.rows{border-top:1px solid var(--border)}
.row{display:grid;gap:6px;padding:var(--s5) 0;border-bottom:1px solid var(--border)}
@media(min-width:800px){.row{grid-template-columns:12rem 1fr 10rem;gap:var(--s5);align-items:baseline}}
.row b{font-weight:700;font-size:1.1rem;letter-spacing:-.02em}
.row p{color:var(--muted);line-height:1.5;font-size:.97rem}
.row .meta{color:var(--primary)}

/* status pills. colour is never the ONLY carrier: each has its own word. */
.status{display:inline-block;padding:.34em .7em;border:1px solid var(--border);
  border-radius:999px;font:700 10px/1 ui-monospace,monospace;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-soft);white-space:nowrap}
.s-live{background:var(--primary);border-color:var(--primary);color:var(--on-primary)}
.s-ready{color:var(--primary);border-color:var(--primary)}

/* ───────────────────────────── figures ───────────────────────────── */
.stats{display:grid;gap:1px;background:var(--border);border:1px solid var(--border)}
@media(min-width:620px){.stats-2,.stats-4{grid-template-columns:repeat(2,1fr)}}
@media(min-width:900px){
  .stats-3{grid-template-columns:repeat(3,1fr)}
  .stats-4{grid-template-columns:repeat(4,1fr)}
}
.stat{background:var(--bg);padding:var(--s5)}
.stat b{display:block;font-size:clamp(1.9rem,3.2vw,2.9rem);font-weight:800;
  letter-spacing:-.045em;line-height:1}
.stat span{display:block;margin-top:10px;color:var(--muted);font-size:.9rem;line-height:1.45}

/* a real message exchange. shows the product instead of describing it. */
.phone{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);
  padding:var(--s5);display:grid;gap:14px;align-content:start;
  box-shadow:0 30px 60px -40px rgba(60,48,20,.5)}
.phone .when{justify-self:center;color:var(--ink-soft);font-size:11px;letter-spacing:.1em}
.msg{max-width:84%;padding:12px 16px;border-radius:16px;font-size:.95rem;line-height:1.45}
.msg.them{background:var(--bg);border:1px solid var(--border);border-bottom-left-radius:5px}
.msg.us{margin-left:auto;background:var(--primary);color:var(--on-primary);
  border-bottom-right-radius:5px}

/* ───────────────────────────── pricing ─────────────────────────────
   No checkout anywhere. A "from" price with no Buy button is an invitation to
   treat, not a shop, which is what keeps the EU distance-selling rules off.
   See STYLE-LOCK.md and legal/README.md before adding one. */
.prices{display:grid;gap:1px;background:var(--border);border:1px solid var(--border)}
@media(min-width:800px){.prices{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1100px){.prices-3{grid-template-columns:repeat(3,1fr)}}
.price{background:var(--bg);padding:clamp(1.8rem,2.6vw,2.6rem);display:flex;
  flex-direction:column;gap:var(--s4)}
.price .what{font-weight:700;font-size:1.12rem;letter-spacing:-.02em}
.price .amt{font-size:clamp(2rem,3.4vw,3rem);font-weight:800;letter-spacing:-.05em;
  line-height:1;color:var(--primary)}
.price .amt small{font-size:.38em;font-weight:700;letter-spacing:0;color:var(--muted)}
.price p{color:var(--muted);font-size:.95rem;line-height:1.5}
.price ul{margin:0;padding:0;list-style:none;display:grid;gap:9px}
.price li{color:var(--muted);font-size:.93rem;padding-left:18px;position:relative;line-height:1.45}
.price li::before{content:"";position:absolute;left:0;top:.55em;width:7px;height:1px;
  background:var(--primary)}
.pricenote{margin-top:var(--s5);color:var(--ink-soft);font-size:.92rem;max-width:var(--measure)}

/* ───────────────────────────── contact ───────────────────────────── */
.contact{padding:var(--s8) 0;border-top:1px solid var(--border);text-align:center}
.contact .lede{margin:var(--s4) auto 0}
.mailrow{display:flex;gap:1px;background:var(--border);border:1px solid var(--border);
  margin-top:var(--s6);flex-wrap:wrap;text-align:left}
.mailrow>div{background:var(--bg);padding:var(--s5);flex:1 1 16rem}
.mailrow .tag{color:var(--ink-soft);margin-bottom:12px}
.mailrow a{color:var(--primary);overflow-wrap:anywhere}

footer{padding:var(--s7) 0 var(--s6);border-top:1px solid var(--border);
  color:var(--muted);font-size:.9rem}
footer .cols{display:grid;gap:var(--s6)}
@media(min-width:900px){footer .cols{grid-template-columns:2fr 1fr 1fr 1fr}}
footer h4{font:700 10px/1 ui-monospace,monospace;letter-spacing:.2em;text-transform:uppercase;
  color:var(--ink-soft);margin:0 0 var(--s4)}
footer ul{margin:0;padding:0;list-style:none;display:grid;gap:10px}
footer a{color:var(--muted)}
@media (hover:hover) and (pointer:fine){ footer a:hover{color:var(--text)} }
.legal-line{margin-top:var(--s6);padding-top:var(--s5);border-top:1px solid var(--border);
  font-size:.82rem;color:var(--ink-soft);line-height:1.8}

/* ───────────────────────────── documents ───────────────────────────── */
.doc{padding:clamp(7rem,12vh,9rem) 0 var(--s8)}
.doc .wrap{max-width:46rem}
.doc h1{font-size:clamp(2rem,4.4vw,3rem)}
.doc h2{font-size:clamp(1.2rem,2.2vw,1.5rem);margin-top:2.6em}
.doc h3{font-size:1.04rem;margin-top:2em}
.doc p,.doc li{color:var(--muted);line-height:1.68}
.doc p{margin:0 0 1.1em}
.doc ul,.doc ol{padding-left:1.2em;margin:0 0 1.2em}
.doc li{margin:.4em 0}
.doc code{font-family:ui-monospace,monospace;font-size:.88em;background:var(--surface);
  border:1px solid var(--border);padding:.12em .4em;border-radius:var(--r-sm)}
.doc pre{background:var(--surface);border:1px solid var(--border);border-left:2px solid var(--primary);
  padding:1.1rem 1.25rem;overflow-x:auto;margin:0 0 1.3em}
.doc pre code{background:none;border:0;padding:0}
.doc-meta{font:700 11px/1.7 ui-monospace,monospace;letter-spacing:.1em;color:var(--ink-soft);
  border-bottom:1px solid var(--border);padding-bottom:var(--s4);margin-bottom:var(--s6)}
.doc-nav{display:flex;flex-wrap:wrap;gap:var(--s4);margin:0 0 var(--s6);
  padding-bottom:var(--s4);border-bottom:1px solid var(--border)}
.doc-nav a{font:700 11px/1 ui-monospace,monospace;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-soft)}
.doc-nav a[aria-current="page"]{color:var(--primary)}
.table-scroll{overflow-x:auto;margin:0 0 1.4em;border:1px solid var(--border)}
table{border-collapse:collapse;width:100%;font-size:.93rem}
th,td{text-align:left;padding:.8rem 1rem;border-bottom:1px solid var(--border);vertical-align:top}
th{font:700 10px/1 ui-monospace,monospace;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-soft);white-space:nowrap}
td{color:var(--muted)}
tr:last-child td{border-bottom:0}

/* ═══════════════════════ SWAMP FROG ═══════════════════════
   Its own world. The logo's palette, never the company gold. Scoped to
   .sf so one stylesheet serves both hosts without either bleeding into
   the other. Greens verified against the near-black ground separately. */
.sf{
  --text:#f2f6ee; --bg:#0a0f0b; --surface:#121a13;
  --primary:#9ccc3c; --accent:#fc9c24; --border:#24301f; --on-primary:#0a0f0b;
  --muted:#b9c7ae; --ink-soft:#8ea081;
  background:var(--bg); color:var(--text);
}
.sf .nav{background:linear-gradient(180deg,rgba(10,15,11,.94),rgba(10,15,11,0))}
.sf .hero::after{background:linear-gradient(180deg,rgba(10,15,11,.55) 0,rgba(10,15,11,.1) 22%,
  rgba(10,15,11,.35) 58%,rgba(10,15,11,.92) 88%,var(--bg) 100%)}
.sf .cell,.sf .stat,.sf .price,.sf .mailrow>div{background:var(--bg)}
@media (hover:hover) and (pointer:fine){ .sf a.cell:hover{background:#162116} }
.sf .s-live{background:var(--primary);color:var(--on-primary);border-color:var(--primary)}
.sf-logo{display:block;height:auto}
.sf-mark{width:clamp(220px,34vw,460px);margin-bottom:var(--s5)}
.sf .nav .sf-logo{height:26px;width:auto}
/* The stage-lights wash behind the studio's prices. His image, duotoned onto
   the Swamp Frog ramp: the violet original has near-white hotspots that read
   1.01:1 against the body text, and darkening it far enough to be legible
   left no violet worth having. Measured worst case here is 5.10:1. */
.sf .chapter.lit{position:relative;isolation:isolate}
.sf .chapter.lit::before{content:"";position:absolute;inset:0;z-index:-1;
  background:url(img/stagelights.webp) center/cover no-repeat;
  -webkit-mask-image:linear-gradient(180deg,#000,rgba(0,0,0,.35) 70%,transparent);
  mask-image:linear-gradient(180deg,#000,rgba(0,0,0,.35) 70%,transparent)}
.tags{display:flex;flex-wrap:wrap;gap:10px;margin-top:var(--s5);padding:0;list-style:none}
.tags li{border:1px solid rgba(156,204,60,.46);color:#cfe8a6;padding:8px 15px;
  border-radius:999px;font-size:.85rem}

/* ───────────────────────────── motion ─────────────────────────────
   Opacity and a 26px lift. Nothing scales, nothing zooms, nothing pins.
   This is deliberate and it is not a placeholder: see the header. */
.rv{opacity:0;transform:translateY(26px);
  transition:opacity .6s var(--ease),transform .6s var(--ease)}
.rv.in{opacity:1;transform:none}
@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  .rv{opacity:1;transform:none;transition:none}
  .hero video{display:none}
  *,*::before,*::after{animation-duration:.001ms !important;transition-duration:.001ms !important}
}

/* ───────────────────────────── tracks ─────────────────────────────
   Native <audio>. No player library, so there is still no third-party
   request and media-src 'self' holds. content.py gates on `cleared`. */
.tracklist{border-top:1px solid var(--border)}
.track{display:grid;gap:var(--s3);padding:var(--s4) 0;border-bottom:1px solid var(--border);
  align-items:center}
@media(min-width:760px){.track{grid-template-columns:18rem 1fr;gap:var(--s5)}}
.track>div{display:flex;align-items:baseline;gap:var(--s4)}
.track b{font-weight:700;font-size:1.08rem;letter-spacing:-.02em}
.track span{color:var(--ink-soft)}
.track audio{width:100%;height:36px}

/* A single line of figures. The four bordered boxes read as filler and the
   column beside them was a wall of text; this is the same information at a
   glance. */
.figrow{display:flex;flex-wrap:wrap;gap:var(--s5) var(--s6);margin-top:var(--s6);
  padding-top:var(--s5);border-top:1px solid var(--border)}
.figrow>div{min-width:5.5rem}
.figrow b{display:block;font-size:clamp(1.5rem,2.4vw,2.1rem);font-weight:800;
  letter-spacing:-.04em;line-height:1;color:var(--primary)}
.figrow span{display:block;margin-top:7px;color:var(--ink-soft);font-size:.82rem;
  line-height:1.35}

/* Problem, then the rule that answers it. Reading the failure first is what
   makes the rule land; a rule on its own is a slogan. */
.probs{border-top:1px solid var(--border)}
.prob{display:grid;gap:10px;padding:var(--s5) 0;border-bottom:1px solid var(--border)}
@media(min-width:900px){.prob{grid-template-columns:1fr 1fr;gap:var(--s6);align-items:start}}
.prob .pq{font-size:clamp(1.05rem,1.5vw,1.3rem);font-weight:700;letter-spacing:-.025em;
  line-height:1.35;color:var(--text)}
.prob .pa{font-weight:700;color:var(--primary);line-height:1.45}
.prob .pa .mono{display:block;color:var(--ink-soft);margin-bottom:7px}
.prob .ph{grid-column:1/-1;color:var(--muted);font-size:.95rem;line-height:1.55;
  max-width:70ch}
@media(min-width:900px){.prob .ph{grid-column:2}}
