/* design.css — the shared system for centram.ai
 *
 * ONE GROUND. bf851ab argued the site shipped two of the three looks
 * generated design currently defaults to -- a near-black ground with one
 * bright accent, and a cream one -- by having a theme for each. 76c8e1b
 * removed the second. What remains is a single dry, pale mineral ground:
 * deliberately not the warm cream (#F4F1EA and its neighbours) that is itself
 * one of those defaults, and not the near-black that is another.
 *
 * Two rules carry the identity.
 *
 * 1. STRATA. The page is a cross-section of a riverbed read from the top
 *    down: the hero is the bright surface (--st-0) and each section settles
 *    into shadow (--st-3). That is not decoration -- the page really does
 *    move from the mechanism, through the claims, down to the plain-language
 *    status, and the ground darkens as it does.
 *
 * 2. MEASURED THINGS ARE MONOSPACE. Anything a reader could check -- a
 *    number, a path, a command, a verification state -- is set in --code.
 *    Anything argued is set in --sans. The distinction is this project's
 *    thesis made typographic: claims and measurements must not look alike.
 *
 * No web fonts: the site loads nothing from anyone else's server, which is
 * worth more than a bespoke typeface. Personality comes from scale, weight
 * and the sans/mono split instead.
 *
 * Colour is reserved for state that is true (bf851ab's rule, kept): see the
 * .state--* markers. It is never spent on decoration.
 */

:root {
  /* Strata: bright surface -> shadow */
  --st-0:#EEF1F0;
  --st-1:#E6EBE9;
  --st-2:#DCE3E1;
  --st-3:#D0D9D7;

  /* Ink on paper. Names kept from the dark pass so components did not fork. */
  --bone:  #101A1C;
  --bone-2:#3D4A49;
  /* The dimmest text token sets the contrast budget for the WHOLE stratum
     stack, not just the lightest one -- home.css already learned this and
     said so, and the first pass here still measured against --st-0 alone.
     At #5E6B6A it was 4.88:1 on --st-0 but 3.85:1 on --st-3, i.e. body text
     failing AA at the bottom of the page. Measured on every stratum now. */
  --bone-3:#54605F;   /* 5.75:1 on --st-0, 4.54:1 on --st-3 */

  /* Cold water: instruments, links, live values */
  --flux:  #14606C;
  --flux-2:#0C4550;

  /* Oxidised iron: the merge, emphasis, the unproven */
  --oxide:  #9A3D14;
  --oxide-2:#B87A5A;

  /* Verification states. These are the section markers, and they are true. */
  --st-measured:#1F6B2A;
  --st-unproven:#9A3D14;
  --st-designed:#14606C;

  --rule:#C7D1CF;
  --rule-2:#B0BDBB;

  --sans:-apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI",Roboto,
         "Helvetica Neue",Arial,sans-serif;
  --code:"SF Mono",Menlo,Consolas,"JetBrains Mono",monospace;

  /* Handed to the WebGL instrument so the renderer carries no palette:
     dark marks on a light ground, with far points fading toward the paper
     rather than toward black. */
  --gl-near:#16323A;
  --gl-far:#9FB0AF;
  --gl-arc:#9A3D14;
  --gl-arc-ghost:#C0A08E;
  --gl-parent:#101A1C;

  --measure:64ch;
  --pad-x:clamp(20px,6vw,88px);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--st-0);color:var(--bone);
  font-family:var(--sans);font-size:16px;line-height:1.6;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
}
img{max-width:100%;height:auto}

a{color:var(--flux);text-decoration:none;
  border-bottom:1px solid color-mix(in srgb,var(--flux) 34%,transparent)}
a:hover{color:var(--flux-2);border-bottom-color:var(--flux-2)}
:focus-visible{outline:2px solid var(--flux);outline-offset:3px;border-radius:2px}

.skip{position:absolute;left:-9999px}
.skip:focus{left:var(--pad-x);top:12px;z-index:99;background:#fff;
            padding:10px 16px;border:1px solid var(--flux)}

/* ---- Strata sections ------------------------------------------------- */
.stratum{padding:clamp(72px,10vh,132px) var(--pad-x)}
.stratum--1{background:var(--st-1)}
.stratum--2{background:var(--st-2)}
.stratum--3{background:var(--st-3)}
.wrap{max-width:1200px;margin:0 auto}

/* ---- Eyebrow + verification state ------------------------------------ */
.eyebrow{
  font-family:var(--code);font-size:11px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--flux);margin:0 0 22px;
  display:flex;align-items:center;gap:14px;
}
.eyebrow::after{content:"";flex:1;height:1px;background:var(--rule-2)}

/* Not 01/02/03. Each section says how far its claim has actually been
   taken, which is information the reader needs and the project tracks. */
.state{
  font-family:var(--code);font-size:10px;letter-spacing:.16em;
  text-transform:uppercase;padding:3px 8px;border:1px solid currentColor;
  white-space:nowrap;
}
.state--measured{color:var(--st-measured)}
.state--implemented{color:var(--flux)}
.state--designed{color:var(--bone-3)}
.state--unproven{color:var(--st-unproven)}

/* ---- Type ------------------------------------------------------------ */
h1,h2,h3{margin:0 0 22px;letter-spacing:-.03em;font-weight:640;line-height:1.02}
h1{font-size:clamp(38px,5.4vw,74px);max-width:15ch}
h2{font-size:clamp(28px,3.4vw,46px);max-width:20ch;letter-spacing:-.028em}
h3{font-size:clamp(18px,1.5vw,22px);letter-spacing:-.015em;line-height:1.25}
p{margin:0 0 18px;max-width:var(--measure)}
.lede{font-size:clamp(16px,1.25vw,18px);line-height:1.62;color:var(--bone-2);
      max-width:52ch}
.small{font-size:13.5px;color:var(--bone-3)}

/* Measurable things. */
.mono,code,kbd,samp{font-family:var(--code);font-variant-numeric:tabular-nums}
code{font-size:.9em;color:var(--bone-2)}

/* ---- Instrument panel ------------------------------------------------ */
.panel{border:1px solid var(--rule-2);background:rgba(255,255,255,.62);
       padding:20px 22px}
.panel h2,.panel-title{
  font-family:var(--code);font-size:10.5px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--bone-3);margin:0 0 16px;font-weight:500;
}
.row{display:flex;justify-content:space-between;align-items:baseline;gap:16px;
     font-family:var(--code);font-size:12.5px;padding:6px 0;
     border-bottom:1px dotted var(--rule-2)}
.row:last-child{border-bottom:0}
.row > :first-child{color:var(--bone-3)}
.row > :last-child{color:var(--bone);font-variant-numeric:tabular-nums;
                   text-align:right}
.row--out > :last-child{color:var(--oxide)}

/* ---- Controls -------------------------------------------------------- */
.btn{display:inline-block;font-family:var(--code);font-size:12.5px;
     letter-spacing:.08em;text-transform:uppercase;padding:12px 22px;
     border:1px solid var(--flux);color:var(--flux);background:none;
     cursor:pointer;border-bottom-width:1px}
.btn:hover{background:var(--flux);color:#fff}
.btn--quiet{border-color:var(--rule-2);color:var(--bone-2)}
.btn--quiet:hover{background:var(--rule-2);color:var(--bone)}

input[type=range]{width:100%;accent-color:var(--oxide);height:22px}

/* ---- Grid ------------------------------------------------------------ */
.cols{display:grid;gap:clamp(24px,3vw,44px)}
.cols--2{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
.cols--3{grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}

.card{border:1px solid var(--rule);padding:24px;background:rgba(255,255,255,.5)}
.card h3{margin-bottom:10px}
.card p:last-child{margin-bottom:0}

/* Wide content scrolls inside itself; the page body never scrolls sideways. */
.scroll-x{overflow-x:auto;-webkit-overflow-scrolling:touch}
table{border-collapse:collapse;width:100%;font-size:14px}
th,td{text-align:left;padding:10px 14px;border-bottom:1px solid var(--rule)}
th{font-family:var(--code);font-size:10.5px;letter-spacing:.14em;
   text-transform:uppercase;color:var(--bone-3);font-weight:500}
td.num{font-family:var(--code);font-variant-numeric:tabular-nums;text-align:right}


/* ── Release waitlist ──────────────────────────────────────────────────────
   Nothing here can be installed from a package yet, so on every page the one
   thing a convinced reader can actually do is ask to be told when that
   changes. The markup lives on each page; these rules were inline in
   index.html while it was the only page carrying the form. */
.notify{margin-top:26px}
.notify label{display:block;font-family:var(--code);font-size:10.5px;
              letter-spacing:.18em;text-transform:uppercase;color:var(--bone-3);
              margin-bottom:10px}
.notify-row{display:flex;gap:10px;flex-wrap:wrap}
.notify input{flex:1 1 210px;min-width:0;font-family:var(--code);font-size:13px;
              padding:11px 12px;border:1px solid var(--rule-2);
              background:rgba(255,255,255,.62);color:var(--bone)}
.notify input:disabled{color:var(--bone-3)}
.notify-note{font-size:12.5px;color:var(--bone-3);margin:12px 0 0;max-width:46ch}
.notify-status{font-family:var(--code);font-size:12.5px;margin:10px 0 0}
.notify-status.ok{color:var(--st-measured)}
.notify-status.err{color:var(--oxide)}

/* The form closes a page rather than sitting inside a numbered stratum, so it
   gets its own rule above the colophon instead of a section background. It
   still has to take --pad-x: the horizontal inset every other section has
   comes from .stratum, not from .wrap, so without it the form alone runs edge
   to edge while the rest of the page is inset. */
.notify-band{border-top:1px solid var(--rule);
             padding:30px var(--pad-x) 4px;margin-top:34px}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;
                       animation-iteration-count:1!important;
                       transition-duration:.001ms!important;
                       scroll-behavior:auto!important}
}
