﻿/* ============================================================
   LUMINA — design system v5 "engineering editorial"
   Light paper surface, ink typography, one signal colour,
   hard 1px rules, real data tables. No glow, no gradients-as-decor.
   Token names are kept stable: dashboard.html / admin.html
   generate markup in JS that references var(--...) directly.
   ============================================================ */

:root{
  /* surfaces */
  --paper:#fbfaf7;        /* page */
  --paper2:#f4f2ed;       /* alternating band */
  --card:#ffffff;         /* raised surface */
  --bg:var(--paper);      /* legacy alias */
  --bg2:var(--paper2);    /* legacy alias */
  --panel:var(--card);    /* legacy alias */
  --panel2:#f7f5f0;       /* legacy alias */

  /* rules */
  --rule:#151513;         /* hard structural rule */
  --line:#d9d5cb;         /* standard border */
  --line2:#e7e3da;        /* hairline */

  /* ink */
  --ink:#141412;
  --ink2:#4d4b45;         /* body — 8.4:1 on paper */
  --ink3:#6f6c63;         /* meta — 4.9:1 on paper, AA compliant */

  /* signal — single accent */
  --signal:#1d4ed8;
  --signal-ink:#1a44bd;   /* text-safe variant */
  --signal-wash:#eaeeff;
  --accent:var(--signal);
  --accent2:var(--signal-ink);
  --violet:var(--signal);
  --violet2:var(--signal-ink);

  /* semantic */
  --green:#166534;
  --green-wash:#e6f2e9;
  --red:#a71d2a;
  --red-wash:#fbeaec;
  --amber:#8a5a00;
  --amber-wash:#fdf1dc;
  --cyan:#0f5d70;         /* used by legacy inline styles for code/keys */

  /* type */
  --sans:"Inter","Inter Tight",system-ui,-apple-system,sans-serif;
  --disp:"Inter Tight","Inter",system-ui,sans-serif;
  --mono:"JetBrains Mono","SFMono-Regular",ui-monospace,monospace;
  --serif:var(--disp);    /* legacy alias: no serif in v5 */

  /* geometry — deliberately tight, near-square */
  --r:4px;--r2:6px;--r3:8px;
  --ease:cubic-bezier(.2,.7,.3,1);
  --shadow:0 1px 2px rgba(20,20,18,.06),0 8px 24px -12px rgba(20,20,18,.14);
  --gut:clamp(20px,4vw,40px);
}

*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
body{
  background:var(--paper);color:var(--ink);
  font-family:var(--sans);font-size:16.5px;line-height:1.6;
  font-feature-settings:"kern" 1,"liga" 1,"cv05" 1;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  overflow-x:hidden;
}
a{color:inherit;text-decoration:none}
button{font-family:inherit;font-size:inherit;border:none;background:none;color:inherit;cursor:pointer}
input,select,textarea{font-family:inherit;font-size:inherit;accent-color:var(--signal)}
:focus-visible{outline:2px solid var(--signal);outline-offset:2px;border-radius:2px}
::selection{background:#dfe6ff;color:var(--ink)}
img,svg{display:block;max-width:100%}
mark{background:#fdf3c8;color:inherit;padding:0 3px}
s{color:var(--ink3)}
code{font-family:var(--mono);font-size:.92em}
hr{border:none;border-top:1px solid var(--line)}

.wrap{max-width:1160px;margin:0 auto;padding:0 var(--gut)}
.wrap-narrow{max-width:760px;margin:0 auto;padding:0 var(--gut)}
.mono{font-family:var(--mono);font-feature-settings:"tnum" 1,"zero" 1}
.serif{font-family:var(--disp)}
.muted{color:var(--ink2)}
.dim{color:var(--ink3)}
.nowrap{white-space:nowrap}
.hidden{display:none!important}
.offscreen,.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ---------- skip link ---------- */
.skip{position:fixed;top:-60px;left:16px;z-index:200;background:var(--ink);color:var(--paper);font:600 13px var(--sans);padding:10px 16px;transition:top .15s var(--ease)}
.skip:focus{top:12px}

/* ---------- reveal (opt-in, tiny) ---------- */
html.js .rv{opacity:0;transform:translateY(10px);transition:opacity .5s var(--ease),transform .5s var(--ease);transition-delay:calc(var(--i,0)*55ms)}
html.js .rv.in{opacity:1;transform:none}

/* ============================================================
   MOTION
   Restrained, structural motion: things slide into their own
   grid position instead of bouncing. Every effect below is
   disabled by the prefers-reduced-motion block at the bottom.
   ============================================================ */

/* page enter: nav + first screen settle in, no layout shift */
@keyframes fade-down{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
@keyframes fade-up{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes rule-in{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes pop-in{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:none}}

html.js .nav{animation:fade-down .45s var(--ease) both}
html.js .hero h1{animation:fade-up .6s var(--ease) both}
html.js .hero .lead{animation:fade-up .6s var(--ease) .08s both}
html.js .hero .cta{animation:fade-up .6s var(--ease) .16s both}
html.js .hero .micro,html.js .hero .hero-note{animation:fade-up .6s var(--ease) .24s both}
html.js .hero .eyebrow{animation:fade-up .5s var(--ease) both}

/* staggered reveal for grouped children (set by JS) */
html.js .rv[data-stagger]>*{opacity:0;transform:translateY(12px);transition:opacity .5s var(--ease),transform .5s var(--ease)}
html.js .rv[data-stagger].in>*{opacity:1;transform:none;transition-delay:calc(var(--c,0)*60ms)}

/* section eyebrow: the number ticks in before the label */
.eyebrow::before{display:inline-block;transition:transform .3s var(--ease)}
html.js .rv .eyebrow::before{transform:translateX(-4px);opacity:.4;transition:transform .4s var(--ease),opacity .4s var(--ease)}
html.js .rv.in .eyebrow::before{transform:none;opacity:1}

/* split-head bottom rule draws itself */
html.js .split-head{position:relative}
html.js .split-head::after{content:"";position:absolute;left:0;right:0;bottom:-1px;height:1px;background:var(--rule);transform:scaleX(0);transform-origin:left;transition:transform .7s var(--ease)}
html.js .split-head.in::after{transform:scaleX(1)}

/* nav links: underline grows from left */
.menu a::before{content:"";position:absolute;left:13px;right:13px;bottom:-1px;height:2px;background:var(--ink);transform:scaleX(0);transform-origin:left;transition:transform .22s var(--ease)}
.menu a:hover::before{transform:scaleX(1)}
.menu a.on::before{display:none}

/* buttons: lift + arrow nudge */
.btn{will-change:transform}
.btn.primary:hover,.btn.ghost:hover{transform:translateY(-1px)}
.btn.primary,.btn.ghost{transition:background .18s var(--ease),border-color .18s var(--ease),color .18s var(--ease),transform .18s var(--ease),box-shadow .18s var(--ease)}
.btn.primary:hover{box-shadow:0 6px 18px -8px rgba(29,78,216,.5)}
.btn:active{transform:translateY(1px)!important}
.btn .arrow{display:inline-block;transition:transform .22s var(--ease)}
.btn:hover .arrow{transform:translateX(3px)}

/* cards: raise and reveal a top signal rule */
.card{position:relative;will-change:transform}
.card::before{content:"";position:absolute;left:0;right:0;top:0;height:2px;background:var(--signal);transform:scaleX(0);transform-origin:left;transition:transform .3s var(--ease)}
.card:hover{transform:translateY(-3px)}
.card:hover::before{transform:scaleX(1)}

/* editorial rows: indent + accent the index on hover */
.row-item{transition:background .2s var(--ease),padding-left .2s var(--ease)}
.row-item:hover{background:var(--paper2);padding-left:10px}
.row-item .num{transition:color .2s var(--ease)}
.row-item:hover .num{color:var(--ink)}

/* plan cards */
.plan{transition:transform .2s var(--ease),border-color .2s var(--ease),box-shadow .2s var(--ease)}
.plan:hover{transform:translateY(-3px);border-color:var(--ink);box-shadow:var(--shadow)}
.plan.featured::before{transform-origin:left;animation:rule-in .6s var(--ease) both}

/* stats / KPI numerals */

html.js [data-count]{display:inline-block}

/* table rows */
.table tbody tr{transition:background .15s var(--ease)}
.table tbody tr:hover td{background:var(--paper2)}
.admin-table tbody tr{transition:background .15s var(--ease)}
/* freshly rendered rows fade in (class added by JS after render) */
html.js .table tbody tr.row-in,html.js .admin-table tbody tr.row-in{animation:fade-up .35s var(--ease) both;animation-delay:calc(var(--r,0)*28ms)}

/* filter bar */
.fbtn{transition:background .18s var(--ease),color .18s var(--ease)}

/* code tabs: active tab slides */
.code-tab{transition:background .18s var(--ease),color .18s var(--ease)}
.code [data-pane]{animation:fade-up .28s var(--ease) both}

/* copy button confirmation */
.copybtn{transition:color .18s var(--ease),border-color .18s var(--ease),background .18s var(--ease)}
.copybtn.ok{animation:pop-in .25s var(--ease)}

/* FAQ accordion: chevron rotate + body slide */
.faq-item summary{transition:color .18s var(--ease)}
.faq-item .faq-body{animation:fade-up .3s var(--ease) both}

/* TOC active marker */
.toc a{position:relative;transition:color .18s var(--ease),padding-left .18s var(--ease)}
.toc a::before{content:"";position:absolute;left:-17px;top:50%;width:2px;height:0;background:var(--signal);transform:translateY(-50%);transition:height .25s var(--ease)}
.toc a.on::before,.toc a:hover::before{height:70%}
.toc a.on{padding-left:3px}

/* reading progress bar (docs) */
.progress{position:fixed;top:0;left:0;height:2px;width:100%;transform:scaleX(0);transform-origin:left;background:var(--signal);z-index:150;pointer-events:none}

/* modal / toast entrance */
.modal .box{transform:translateY(10px) scale(.99);transition:transform .22s var(--ease)}
.modal.open .box{transform:none}

/* footer links */
.foot-col a{transition:color .15s var(--ease),transform .15s var(--ease)}
.foot-col a:hover{transform:translateX(2px)}

/* skeleton shimmer already animated; keep key reveal subtle */
.keyrow input{transition:border-color .18s var(--ease)}

/* ============================================================
   NAV
   ============================================================ */
.nav{position:sticky;top:0;z-index:100;background:rgba(251,250,247,.92);backdrop-filter:blur(8px);border-bottom:1px solid var(--rule)}
.nav .wrap{display:flex;align-items:center;gap:14px;height:62px}
.logo{display:flex;align-items:center;gap:9px;font-family:var(--disp);font-weight:700;font-size:17px;letter-spacing:-.02em;flex:0 0 auto}
.logo .mark{width:26px;height:26px;display:grid;place-items:center;flex:0 0 auto}
.logo .mark img,.logo .mark svg{width:26px;height:26px}
.menu{display:none;gap:0;margin-left:20px}
.menu a{position:relative;font-size:14.5px;font-weight:500;color:var(--ink2);padding:8px 13px;transition:color .15s}
.menu a:hover{color:var(--ink)}
.menu a.on{color:var(--ink);font-weight:600}
.menu a.on::after{content:"";position:absolute;left:13px;right:13px;bottom:-1px;height:2px;background:var(--signal)}
.nav .spacer{flex:1}
.language-picker{display:flex;align-items:center;flex:0 0 auto}
.language-picker select{appearance:none;background:var(--card);border:1px solid var(--line);border-radius:var(--r);color:var(--ink);cursor:pointer;padding:7px 25px 7px 10px;font:600 12px var(--mono);background-image:linear-gradient(45deg,transparent 50%,var(--ink2) 50%),linear-gradient(135deg,var(--ink2) 50%,transparent 50%);background-position:calc(100% - 12px) 11px,calc(100% - 8px) 11px;background-size:4px 4px,4px 4px;background-repeat:no-repeat}
.language-picker select:focus{outline:2px solid var(--signal);outline-offset:1px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
html.js:not(.i18n-ready) body{visibility:hidden}
/* The auth buttons are injected by JS after the hidden attribute is removed.
   Without a layout of their own they were an inline span whose two buttons
   wrapped onto a second line, so on a 320-360px screen they rendered 82px
   tall and spilled above and below the 57px nav bar. */
.authbox{display:flex;align-items:center;gap:8px;flex:0 0 auto;white-space:nowrap}
.authbox>span{display:flex;align-items:center;gap:8px}
.authbox>span[hidden]{display:none}
.nav-toggle{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;border:1px solid var(--line);color:var(--ink);font:16px/1 var(--mono);background:var(--card)}
.nav-toggle .close{display:none}
.nav-toggle[aria-expanded="true"] .open{display:none}
.nav-toggle[aria-expanded="true"] .close{display:inline}
.menu.open{display:grid;position:fixed;top:62px;left:0;right:0;z-index:101;margin:0;padding:6px;background:var(--card);border-bottom:1px solid var(--rule);box-shadow:var(--shadow)}
.menu.open a{padding:13px 14px;border-bottom:1px solid var(--line2)}
.menu.open a:last-child{border-bottom:none}
.menu.open a.on::after{left:0;right:auto;width:3px;top:0;bottom:0;height:auto}
/* Mirrored auth action (added by lumina.js). It only exists to replace the
   ghost button that is hidden on narrow bars, so it must never appear in the
   horizontal desktop menu. */
.menu-auth{display:none}
.menu.open .menu-auth{display:block;font-weight:600;color:var(--signal-ink)}

/* ============================================================
   BUTTONS
   ============================================================ */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;padding:11px 20px;font-family:var(--sans);font-size:14.5px;font-weight:600;letter-spacing:-.005em;border:1px solid transparent;transition:background .15s,border-color .15s,color .15s,transform .1s;white-space:nowrap;border-radius:var(--r)}
.btn:active{transform:translateY(1px)}
.btn.primary{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.btn.primary:hover{background:var(--signal);border-color:var(--signal)}
.btn.ghost{background:var(--card);border-color:var(--line);color:var(--ink)}
.btn.ghost:hover{border-color:var(--ink);background:var(--paper2)}
.btn.link{padding:0;border:none;background:none;color:var(--signal-ink);text-decoration:underline;text-underline-offset:3px;font-weight:600}
.btn.link:hover{color:var(--ink)}
.btn.danger{background:var(--card);border-color:#e0b6bc;color:var(--red)}
.btn.danger:hover{background:var(--red);border-color:var(--red);color:#fff}
.btn.big{padding:14px 26px;font-size:15.5px}
.btn.small{padding:7px 13px;font-size:13px}
.btn:disabled{opacity:.45;cursor:not-allowed;transform:none}
.btn-row{display:flex;gap:10px;flex-wrap:wrap}

/* ============================================================
   TOAST / MODAL
   ============================================================ */
.toast{position:fixed;z-index:300;right:20px;bottom:20px;left:20px;background:var(--ink);color:var(--paper);padding:13px 16px;font:13px var(--mono);border-radius:var(--r);opacity:0;transform:translateY(8px);pointer-events:none;transition:opacity .2s var(--ease),transform .2s var(--ease)}
.toast.show{opacity:1;transform:none}
.toast.err{background:var(--red)}
@media(min-width:560px){.toast{left:auto;max-width:420px}}

.modal{position:fixed;inset:0;z-index:250;display:flex;align-items:center;justify-content:center;padding:20px;background:rgba(20,20,18,.42);opacity:0;visibility:hidden;pointer-events:none;transition:opacity .18s var(--ease),visibility .18s}
.modal.open{opacity:1;visibility:visible;pointer-events:auto}
.modal .box{width:min(100%,540px);max-height:calc(100vh - 40px);overflow:auto;background:var(--card);border:1px solid var(--rule);border-radius:var(--r2);padding:26px;box-shadow:0 24px 60px -20px rgba(20,20,18,.4)}
.modal h3{font:700 22px/1.2 var(--disp);margin-bottom:6px}
.modal .box>p{margin-bottom:14px;color:var(--ink2);font-size:14.5px}
.modal input,.modal select{width:100%;border:1px solid var(--line);background:var(--paper);color:var(--ink);padding:11px 12px;font:13.5px var(--mono);margin-top:9px;border-radius:var(--r)}
.modal input:focus,.modal select:focus{outline:2px solid var(--signal);outline-offset:-1px;border-color:var(--signal)}
.modal .keyrow{display:flex;gap:8px;align-items:center}
.modal .keyrow input{margin-top:0;flex:1}
.modal .keyrow button{flex:0 0 auto}

/* skeleton */
.sk{display:inline-block;min-width:60px;min-height:1em;background:linear-gradient(90deg,var(--paper2),#eae7df,var(--paper2));background-size:200% 100%;animation:sk 1.3s linear infinite;vertical-align:-.12em;border-radius:2px}
@keyframes sk{from{background-position:200% 0}to{background-position:-200% 0}}

/* ============================================================
   SECTIONS + EDITORIAL HEADS
   ============================================================ */
section{padding:clamp(56px,8vw,92px) 0;position:relative}
.band{background:var(--paper2);border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}

/* eyebrow: numbered, not "// slashes" */
.eyebrow{display:flex;align-items:baseline;gap:10px;font:600 12px var(--mono);letter-spacing:.06em;text-transform:uppercase;color:var(--ink3);margin-bottom:18px}
.eyebrow::before{content:attr(data-n);color:var(--signal-ink);font-weight:700}
.sec-tag{font:600 12px var(--mono);letter-spacing:.06em;text-transform:uppercase;color:var(--ink3);margin-bottom:14px;display:block}

.sec-head{max-width:660px;margin-bottom:clamp(30px,4vw,46px)}
.sec-head h1,.sec-head h2{font-family:var(--disp);font-weight:700;font-size:clamp(30px,4.4vw,50px);line-height:1.04;letter-spacing:-.035em;margin-bottom:14px;text-wrap:balance}
.sec-head p{color:var(--ink2);font-size:17.5px;line-height:1.62;max-width:60ch}

/* split head: title left, note right */
.split-head{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,320px);gap:28px;align-items:end;padding-bottom:20px;border-bottom:1px solid var(--rule);margin-bottom:clamp(28px,4vw,44px)}
.split-head h1,.split-head h2{font-family:var(--disp);font-weight:700;font-size:clamp(30px,4.4vw,50px);line-height:1.04;letter-spacing:-.035em;text-wrap:balance}
.split-head .aside{font-size:14.5px;color:var(--ink2);line-height:1.6}

/* ============================================================
   HERO — asymmetric editorial, no floating cards
   ============================================================ */
.hero{padding:clamp(48px,7vw,86px) 0 0;border-bottom:1px solid var(--rule)}
.hero-grid{display:grid;grid-template-columns:minmax(0,1.08fr) minmax(0,.92fr);gap:clamp(28px,5vw,60px);align-items:start}
.hero h1{font-family:var(--disp);font-weight:700;font-size:clamp(38px,6.2vw,74px);line-height:1;letter-spacing:-.042em;margin-bottom:22px;text-wrap:balance}
.hero h1 em{font-style:normal;color:var(--signal-ink)}
.hero .lead{font-size:clamp(17px,2vw,20px);color:var(--ink2);line-height:1.58;max-width:52ch;margin-bottom:26px}
.hero .cta{display:flex;gap:11px;flex-wrap:wrap;margin-bottom:22px}
.hero .micro{font:12.5px var(--mono);color:var(--ink3)}
.hero-note{display:flex;flex-wrap:wrap;gap:6px 18px;padding-top:20px;margin-top:24px;border-top:1px solid var(--line);font:12.5px var(--mono);color:var(--ink3)}

/* hero side: live terminal-ish spec sheet, but on paper */
.spec{border:1px solid var(--rule);background:var(--card);border-radius:var(--r2);overflow:hidden}
.spec-top{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:10px 14px;border-bottom:1px solid var(--rule);background:var(--paper2);font:600 11.5px var(--mono);letter-spacing:.05em;text-transform:uppercase;color:var(--ink3)}
.spec-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:12px;align-items:baseline;padding:11px 14px;border-bottom:1px solid var(--line2)}
.spec-row:last-child{border-bottom:none}
.spec-row .n{font-weight:600;font-size:14.5px}
.spec-row .n small{display:block;font:11.5px var(--mono);color:var(--ink3);font-weight:400;margin-top:2px}
.spec-row .v{font:600 13.5px var(--mono);text-align:right;white-space:nowrap}
.spec-row .v s{color:var(--ink3);font-weight:400;margin-right:6px}
.spec-row .v b{color:var(--green)}
.spec-foot{padding:11px 14px;border-top:1px solid var(--rule);background:var(--paper2);font:11.5px var(--mono);color:var(--ink3)}

/* ============================================================
   CARDS / GRIDS
   ============================================================ */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--r2);padding:22px;transition:border-color .18s,box-shadow .18s}
.card:hover{border-color:var(--ink);box-shadow:var(--shadow)}
.card h3{font-family:var(--disp);font-size:18px;font-weight:700;letter-spacing:-.015em;margin-bottom:8px}
.card p{font-size:14.5px;color:var(--ink2);line-height:1.6}
.grid2{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:14px}
.grid3{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:14px}
.grid4{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:14px}

/* numbered feature list — replaces the 6 identical "why us" cards */
.rows{border-top:1px solid var(--rule)}
.row-item{display:grid;grid-template-columns:52px minmax(0,290px) minmax(0,1fr);gap:20px;align-items:baseline;padding:20px 0;border-bottom:1px solid var(--line)}
.row-item .num{font:600 12px var(--mono);color:var(--signal-ink);padding-top:3px}
.row-item h3{font-family:var(--disp);font-size:18px;font-weight:700;letter-spacing:-.015em}
.row-item p{color:var(--ink2);font-size:15px;line-height:1.6}
.row-item .kbd{margin-top:8px}

/* stat strip */
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));border:1px solid var(--rule);border-radius:var(--r2);overflow:hidden;background:var(--card)}
.stats>div{padding:20px;border-right:1px solid var(--line)}
.stats>div:last-child{border-right:none}
.stats b{display:block;font:700 clamp(26px,3.4vw,38px)/1 var(--mono);letter-spacing:-.03em;margin-bottom:7px}
.stats span{font:12px var(--mono);letter-spacing:.04em;text-transform:uppercase;color:var(--ink3)}
.proof-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:0;border-top:1px solid var(--rule)}
.proof{padding:18px 18px 18px 0;border-right:1px solid var(--line)}
.proof:last-child{border-right:none}
.proof b{display:block;font:700 22px var(--mono);margin-bottom:4px}
.proof span{display:block;color:var(--ink2);font-size:13.5px;line-height:1.5}

/* pipeline diagram — flat, labelled, honest */
.pipe{border:1px solid var(--rule);border-radius:var(--r2);background:var(--card);overflow:hidden}
.pipe-top{padding:10px 16px;border-bottom:1px solid var(--rule);background:var(--paper2);font:600 11.5px var(--mono);letter-spacing:.05em;text-transform:uppercase;color:var(--ink3)}
.pipe-body{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1px;background:var(--line)}
.pipe-step{background:var(--card);padding:20px 16px}
.pipe-step .s{font:600 11.5px var(--mono);color:var(--signal-ink);margin-bottom:10px}
.pipe-step strong{display:block;font-family:var(--disp);font-size:15.5px;font-weight:700;margin-bottom:6px}
.pipe-step small{display:block;font-size:13px;color:var(--ink2);line-height:1.55}
.pipe-foot{padding:13px 16px;border-top:1px solid var(--rule);font:12.5px/1.65 var(--mono);color:var(--ink3)}

/* ============================================================
   CODE
   ============================================================ */
.code{border:1px solid var(--rule);border-radius:var(--r2);overflow:hidden;background:#16161a}
.code-top{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:9px 13px;background:#1f1f25;border-bottom:1px solid #2c2c34}
.code-tabs{display:flex;gap:2px}
.code-tab{font:600 12px var(--mono);color:#9b9baa;padding:5px 11px;border-radius:3px}
.code-tab:hover{color:#e9e9f2}
.code-tab[aria-selected="true"]{background:#33333d;color:#fff}
.code pre{margin:0;padding:16px 18px;overflow-x:auto;font:13px/1.75 var(--mono);color:#dcdce8;tab-size:2}
.code .cm{color:#7f8496}      /* comment */
.code .kw{color:#c39bff}      /* keyword */
.code .st{color:#7fd6a6}      /* string */
.code .fn{color:#79b8ff}      /* function/prop */
.code .nu{color:#ffab70}      /* number */
.copybtn{font:600 12px var(--mono);color:#9b9baa;border:1px solid #34343e;padding:5px 10px;border-radius:3px;transition:all .15s;background:none}
.copybtn:hover{color:#fff;border-color:#54545f}
.copybtn.ok{color:#7fd6a6;border-color:#2f5c45}
.codeblock{font:13px/1.75 var(--mono);overflow-x:auto;white-space:pre}
/* inline key/endpoint chip */
.kbd{display:inline-block;font:12.5px var(--mono);background:var(--paper2);border:1px solid var(--line);padding:2px 7px;border-radius:3px;color:var(--ink)}

/* ============================================================
   TABLES
   ============================================================ */
.tablewrap{overflow-x:auto;border:1px solid var(--rule);border-radius:var(--r2);background:var(--card)}
.table{width:100%;border-collapse:collapse;min-width:620px}
.table th{font:600 11.5px var(--mono);letter-spacing:.05em;text-transform:uppercase;color:var(--ink3);text-align:left;padding:12px 18px;border-bottom:1px solid var(--rule);background:var(--paper2);white-space:nowrap}
.table td{padding:14px 18px;border-bottom:1px solid var(--line2);font-size:14.5px;vertical-align:middle}
.table tr:last-child td{border-bottom:none}
.table tbody tr:hover td{background:var(--paper2)}
.table .num{font-family:var(--mono);font-feature-settings:"tnum" 1;white-space:nowrap}
.table caption{caption-side:top;text-align:left;padding:12px 18px;font:600 11.5px var(--mono);letter-spacing:.05em;text-transform:uppercase;color:var(--ink3);background:var(--paper2);border-bottom:1px solid var(--rule)}

/* tags */
.tag{display:inline-block;font:700 11px var(--mono);letter-spacing:.04em;padding:2px 7px;border:1px solid var(--line);color:var(--ink2);border-radius:3px;background:var(--card)}
.tag.pro{background:var(--signal-wash);color:var(--signal-ink);border-color:#bfcbfa}
.tag.free{background:var(--green-wash);color:var(--green);border-color:#c3ddc9}
.tag.new{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.tag.hot{background:var(--amber-wash);color:var(--amber);border-color:#eccf9a}

.note{font:12.5px/1.6 var(--mono);color:var(--ink3);margin-top:14px}

/* filter bar */
.filterbar{display:flex;gap:0;flex-wrap:wrap;border:1px solid var(--line);border-radius:var(--r);overflow:hidden;margin-bottom:20px;width:max-content;max-width:100%;background:var(--card)}
.fbtn{font:600 13px var(--sans);padding:9px 15px;color:var(--ink2);border-right:1px solid var(--line);transition:background .15s,color .15s}
.fbtn:last-child{border-right:none}
.fbtn:hover{background:var(--paper2);color:var(--ink)}
.fbtn.on{background:var(--ink);color:var(--paper)}
.fbtn .n{font-family:var(--mono);font-size:11.5px;color:var(--ink3);margin-left:5px}
.fbtn.on .n{color:rgba(251,250,247,.7)}

/* matrix */
.fit-scroll{overflow-x:auto}
.fit-matrix{display:grid;grid-template-columns:1.3fr repeat(4,1fr);border:1px solid var(--rule);border-radius:var(--r2);overflow:hidden;background:var(--card);min-width:620px}
.fit-matrix>div{padding:13px 14px;border-right:1px solid var(--line2);border-bottom:1px solid var(--line2);font-size:13.5px}
.fit-matrix>div:nth-child(5n){border-right:none}
.fit-matrix>div:nth-last-child(-n+5){border-bottom:none}
.fit-matrix .head{font:600 11px var(--mono);letter-spacing:.05em;text-transform:uppercase;color:var(--ink3);background:var(--paper2)}
.fit-matrix .model{font-weight:600}
.fit-matrix .yes{color:var(--green);font:700 13px var(--mono)}
.fit-matrix .low{color:var(--ink3);font:700 13px var(--mono)}

/* ============================================================
   FAQ
   ============================================================ */
.faq{border-top:1px solid var(--rule)}
.faq-item{border-bottom:1px solid var(--line);background:none;margin:0;border-radius:0}
.faq-item summary{padding:18px 0;font-family:var(--disp);font-weight:600;font-size:16.5px;cursor:pointer;list-style:none;display:flex;justify-content:space-between;align-items:center;gap:16px}
.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary:hover{color:var(--signal-ink)}
.faq-item summary .pl{font:400 18px var(--mono);color:var(--ink3);transition:transform .2s var(--ease);flex:0 0 auto}
.faq-item[open] summary .pl{transform:rotate(45deg)}
.faq-item .faq-body{padding:0 0 20px;color:var(--ink2);font-size:15px;line-height:1.65;max-width:70ch}

/* ============================================================
   CTA
   ============================================================ */
.cta-final{border:1px solid var(--rule);border-radius:var(--r2);background:var(--card);padding:clamp(32px,5vw,54px);display:grid;grid-template-columns:minmax(0,1fr) auto;gap:28px;align-items:center}
.cta-kicker{font:600 12px var(--mono);letter-spacing:.06em;text-transform:uppercase;color:var(--ink3);margin-bottom:12px}
.cta-title{font-family:var(--disp);font-weight:700;font-size:clamp(26px,3.6vw,40px);line-height:1.06;letter-spacing:-.035em;margin-bottom:12px;text-wrap:balance}
.cta-sub{color:var(--ink2);font-size:16px;max-width:52ch}
.cta-btns{display:flex;gap:11px;flex-wrap:wrap}

/* ============================================================
   FOOTER
   ============================================================ */
.footer{border-top:1px solid var(--rule);padding:44px 0 28px;background:var(--paper2)}
.foot-grid{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:32px;margin-bottom:32px}
.foot-desc{font-size:14px;color:var(--ink2);max-width:34ch;margin-top:12px;line-height:1.6}
.foot-col h4{font:600 11.5px var(--mono);letter-spacing:.06em;text-transform:uppercase;color:var(--ink3);margin-bottom:12px}
.foot-col a{display:block;font-size:14.5px;color:var(--ink2);padding:4px 0;transition:color .15s}
.foot-col a:hover{color:var(--signal-ink)}
.foot-bottom{border-top:1px solid var(--line);padding-top:18px;display:flex;justify-content:space-between;align-items:center;color:var(--ink3);font-size:13px;flex-wrap:wrap;gap:10px}
.foot-bottom.simple{border-top:none;padding-top:0}

/* ============================================================
   AUTH
   ============================================================ */
.auth-shell{min-height:calc(100vh - 62px - 90px);display:grid;place-items:center;padding:56px var(--gut)}
/* min() resolves against the grid area, which is the full viewport here, so the
   card ignored the shell's gutters and overflowed a 320px screen.
   min-width:0 is required as well: the Turnstile iframe is a fixed 300px wide,
   and a grid item's automatic minimum size would otherwise refuse to shrink
   below that plus the card's own padding. */
.auth-card{width:100%;max-width:440px;min-width:0;background:var(--card);border:1px solid var(--rule);border-radius:var(--r2);padding:32px;box-shadow:var(--shadow)}
/* Let the widget scale down on the narrowest phones instead of pushing the
   layout wider than the screen. */
.cf-turnstile{max-width:100%;overflow:hidden}
.auth-card h1{font-family:var(--disp);font-weight:700;font-size:30px;line-height:1.1;letter-spacing:-.03em;margin-bottom:7px}
.auth-card>p{color:var(--ink2);margin-bottom:22px;font-size:14.5px}
.auth-card label{display:block;font:600 11.5px var(--mono);letter-spacing:.05em;text-transform:uppercase;color:var(--ink3);margin:15px 0 6px}
.auth-card input{width:100%;border:1px solid var(--line);background:var(--paper);padding:11px 13px;font:14px var(--mono);color:var(--ink);border-radius:var(--r);transition:border-color .15s}
.auth-card input:focus{outline:2px solid var(--signal);outline-offset:-1px;border-color:var(--signal)}
.auth-card .btn{width:100%;margin-top:20px}
.auth-switch{font-size:13.5px;margin-top:20px;text-align:center;color:var(--ink3)}
.auth-switch button{color:var(--signal-ink);text-decoration:underline;text-underline-offset:2px;font-weight:600}
.auth-message{min-height:20px;margin-top:12px;color:var(--red);font-size:14px}
.auth-note{margin-top:12px;padding:11px 13px;border:1px solid #eccf9a;background:var(--amber-wash);border-radius:var(--r);font:12.5px/1.55 var(--mono);color:var(--amber);display:none}
.auth-note.show{display:block}

/* ============================================================
   DASHBOARD
   ============================================================ */
.dash-head{display:flex;justify-content:space-between;align-items:flex-end;flex-wrap:wrap;gap:16px;margin-bottom:26px;padding-bottom:18px;border-bottom:1px solid var(--rule)}
.dash-head h1{font-family:var(--disp);font-weight:700;font-size:clamp(28px,4vw,42px);line-height:1.05;letter-spacing:-.035em}
.dash-actions{display:flex;gap:9px;flex-wrap:wrap}
.dash-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));border:1px solid var(--rule);border-radius:var(--r2);overflow:hidden;background:var(--card);margin-bottom:22px}
.dstat{padding:18px 20px;border-right:1px solid var(--line)}
.dstat:last-child{border-right:none}
.dstat .v{font:700 26px/1.1 var(--mono);letter-spacing:-.02em}
.dstat .l{font:11.5px var(--mono);letter-spacing:.05em;text-transform:uppercase;color:var(--ink3);margin-top:6px}
.panel{background:var(--card);border:1px solid var(--rule);border-radius:var(--r2);margin-bottom:18px;overflow:hidden}
.panel .ph{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:14px 20px;border-bottom:1px solid var(--rule);background:var(--paper2);flex-wrap:wrap}
.panel .ph h2,.panel .ph h3{font-family:var(--disp);font-weight:700;font-size:16px}
.panel .ph .note{font:11.5px var(--mono);color:var(--ink3);margin:0}
.panel .body{padding:20px}
.keyrow{display:flex;gap:8px;margin-top:14px;flex-wrap:wrap}
.keyrow input{flex:1;min-width:200px;background:var(--paper);border:1px solid var(--line);color:var(--ink);padding:11px 12px;font:13px var(--mono);border-radius:var(--r)}
.field-inline{background:var(--paper);border:1px solid var(--line);border-radius:var(--r);padding:11px 12px;color:var(--ink);font:13px var(--mono)}
.field-inline:focus{outline:2px solid var(--signal);outline-offset:-1px;border-color:var(--signal)}
/* Panel body variants, so pages stop re-declaring the same inline flex row. */
.panel .body.row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.panel .body.divided{border-top:1px solid var(--line2)}
.panel .body.flush{padding:0}
/* Boxed sub-section inside a panel (admin balance/promo forms). */
.subpanel{padding:16px;border:1px solid var(--line2);border-radius:var(--r2);background:var(--paper2);margin-bottom:18px}
.modal-actions{display:flex;gap:10px;justify-content:flex-end;margin-top:18px}
.invoice-log{display:grid;gap:6px;font:12px var(--mono)}
.invoice-log>div{padding-bottom:6px;border-bottom:1px solid var(--line2)}
.invoice-log>div:last-child{border-bottom:none;padding-bottom:0}
.invoice-log .status{margin-left:6px}

/* ---- usage explorer ----
   Three breakdowns used to be stacked, so a busy account turned the page into
   a several-screen scroll. They are one switchable view now, and the rows
   scroll inside the panel with a pinned header instead of growing the page. */
.usage-sub{font:600 11.5px var(--mono);letter-spacing:.05em;text-transform:uppercase;color:var(--ink3)}
.usage-bar{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:12px}
.usage-bar .filterbar{margin-bottom:0}
.usage-scroll{max-height:340px;overflow:auto;overscroll-behavior:contain}
/* The pinned header is what makes in-panel scrolling readable. `background` is
   already opaque on .table th, which sticky positioning requires. */
.usage-scroll thead th{position:sticky;top:0;z-index:2}
.usage-scroll table{margin:0}
/* Compact table for panel-embedded breakdowns: the 620px base min-width is
   sized for full-bleed page tables and forced needless horizontal scroll. */
.table.compact{min-width:460px}
.table.compact th{padding:10px 14px}
.table.compact td{padding:11px 14px;font-size:13.5px}

/* ============================================================
   PRICING
   ============================================================ */
.calc{background:var(--card);border:1px solid var(--rule);border-radius:var(--r2);padding:26px;margin-top:32px}
.calc h3{font-family:var(--disp);font-weight:700;font-size:20px;margin-bottom:6px}
.calc-grid{display:grid;grid-template-columns:1fr 1fr;gap:30px;align-items:start;margin-top:20px}
.calc label{font:600 11.5px var(--mono);letter-spacing:.05em;text-transform:uppercase;color:var(--ink3);display:block;margin-bottom:7px}
.calc input[type=range]{width:100%}
.calc input[type=number],.calc select{width:100%;background:var(--paper);border:1px solid var(--line);color:var(--ink);padding:10px 12px;font:13.5px var(--mono);border-radius:var(--r)}
.calc .field{margin-bottom:16px}
.calc .big{font:13.5px var(--mono);color:var(--ink2)}
.calc .big b{color:var(--ink);font-size:16px}
.calc .save-box{border:1px solid var(--line);padding:22px;background:var(--paper2);border-radius:var(--r2)}
.calc .save-box .amount{font:700 clamp(30px,4.2vw,44px)/1 var(--mono);letter-spacing:-.03em;color:var(--ink)}
.calc .save-box .lbl{font:11.5px var(--mono);letter-spacing:.05em;text-transform:uppercase;color:var(--ink3);margin-top:8px}
.calc .breakdown{margin-top:16px;border-top:1px solid var(--line);padding-top:14px;display:grid;gap:8px}
.calc .breakdown div{display:flex;justify-content:space-between;gap:12px;font:13px var(--mono);color:var(--ink2)}
.calc .breakdown div b{color:var(--ink)}
.calc .compare{display:flex;justify-content:space-between;font:13px var(--mono);color:var(--ink3);margin-top:14px;gap:12px;flex-wrap:wrap}
.calc .compare .now{color:var(--green);font-weight:700}

/* plan cards */
.plans{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
.plan{border:1px solid var(--line);border-radius:var(--r2);background:var(--card);padding:24px;display:flex;flex-direction:column}
.plan.featured{border-color:var(--rule);border-width:1px;box-shadow:var(--shadow);position:relative}
.plan.featured::before{content:"";position:absolute;left:-1px;right:-1px;top:-1px;height:3px;background:var(--signal)}
.plan .price{font:700 clamp(30px,4vw,40px)/1 var(--mono);letter-spacing:-.03em;margin:14px 0 4px}
.plan .per{font:12.5px var(--mono);color:var(--ink3);margin-bottom:18px}
.plan ul{list-style:none;display:grid;gap:9px;font-size:14.5px;color:var(--ink2);margin-bottom:22px}
.plan ul li{display:flex;gap:9px;align-items:flex-start;line-height:1.5}
.plan ul li::before{content:"—";color:var(--ink3);flex:0 0 auto}
.plan .btn{margin-top:auto;width:100%}

.keyblock{background:var(--card);border:1px solid var(--rule);border-radius:var(--r2);padding:clamp(28px,4.5vw,46px);margin-top:44px}
.keyblock h2{font-family:var(--disp);font-weight:700;font-size:clamp(24px,3.4vw,36px);line-height:1.08;letter-spacing:-.035em;margin-bottom:12px}
.keyblock p{color:var(--ink2);font-size:16px;margin-bottom:22px;max-width:60ch}
.keyblock .micro{font:12.5px var(--mono);color:var(--ink3);margin-top:14px}
.keyblock .micro a{color:var(--signal-ink);text-decoration:underline}

/* ============================================================
   MODELS / LISTS
   ============================================================ */
.list-head{display:flex;justify-content:space-between;align-items:flex-end;flex-wrap:wrap;gap:16px;margin-bottom:24px;padding-bottom:18px;border-bottom:1px solid var(--rule)}
.list-head h1{font-family:var(--disp);font-weight:700;font-size:clamp(30px,4.4vw,50px);line-height:1.04;letter-spacing:-.035em}
.list-head .count{font:12.5px/1.6 var(--mono);color:var(--ink3);text-align:right}

/* ============================================================
   DOCS
   ============================================================ */
.docs-layout{display:grid;grid-template-columns:210px minmax(0,1fr);gap:clamp(24px,4vw,52px);align-items:start}
.toc{position:sticky;top:82px;border-left:1px solid var(--line);padding-left:16px}
.toc h4{font:600 11.5px var(--mono);letter-spacing:.06em;text-transform:uppercase;color:var(--ink3);margin-bottom:10px}
.toc a{display:block;font-size:14px;color:var(--ink2);padding:5px 0;transition:color .15s}
.toc a:hover,.toc a.on{color:var(--signal-ink)}
.doc-block{padding-bottom:40px;margin-bottom:40px;border-bottom:1px solid var(--line)}
.doc-block:last-child{border-bottom:none;margin-bottom:0}
/* The anchor id lives on the .doc-block wrapper, not on the h2, so the offset
   has to be here or a TOC jump parks the heading under the sticky nav. */
.doc-block[id]{scroll-margin-top:78px}
.doc-block h2{font-family:var(--disp);font-weight:700;font-size:clamp(24px,3.2vw,34px);line-height:1.1;letter-spacing:-.03em;margin-bottom:12px;scroll-margin-top:84px}
.doc-block h3{font-family:var(--disp);font-weight:700;font-size:17px;margin:24px 0 8px}
.doc-block p{color:var(--ink2);font-size:15.5px;line-height:1.68;max-width:70ch;margin-bottom:12px}
.doc-block ul,.doc-block ol{color:var(--ink2);font-size:15.5px;line-height:1.68;max-width:70ch;margin:0 0 14px 20px;display:grid;gap:6px}
.doc-block .code{margin:16px 0}

/* ============================================================
   JOURNAL
   ============================================================ */
.entry{border-bottom:1px solid var(--line);padding:26px 0;display:grid;grid-template-columns:160px minmax(0,1fr);gap:26px}
.entry:first-of-type{border-top:1px solid var(--rule)}
.entry .date{font:12.5px var(--mono);color:var(--ink3)}
.entry .date .cat{display:inline-block;margin-top:7px;font:600 10.5px var(--mono);text-transform:uppercase;letter-spacing:.06em;color:var(--signal-ink);border:1px solid #bfcbfa;background:var(--signal-wash);padding:2px 7px;border-radius:3px}
.entry h2{font-family:var(--disp);font-weight:700;font-size:clamp(19px,2.4vw,25px);line-height:1.15;letter-spacing:-.025em;margin-bottom:8px}
.entry h2 a:hover{color:var(--signal-ink)}
.entry p{color:var(--ink2);font-size:15.5px;line-height:1.66;max-width:70ch}

/* ============================================================
   ADMIN
   ============================================================ */
main.admin-main{padding:40px 0 60px}
.admin-shell{display:grid;grid-template-columns:210px minmax(0,1fr);gap:22px}
.admin-side{position:sticky;top:82px;height:max-content;background:var(--card);border:1px solid var(--rule);border-radius:var(--r2);padding:8px}
.side-title{font:600 11px var(--mono);color:var(--ink3);letter-spacing:.06em;text-transform:uppercase;padding:10px}
.side-btn{display:block;width:100%;text-align:left;padding:10px;border-radius:var(--r);color:var(--ink2);font-size:14px;transition:background .15s,color .15s}
.side-btn:hover{background:var(--paper2);color:var(--ink)}
.side-btn.on{background:var(--ink);color:var(--paper);font-weight:600}
.admin-content{min-width:0}
.admin-top{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;margin-bottom:24px;padding-bottom:16px;border-bottom:1px solid var(--rule)}
.admin-kicker{font:600 11.5px var(--mono);color:var(--ink3);letter-spacing:.06em;text-transform:uppercase;margin-bottom:8px}
.admin-top h1{font-family:var(--disp);font-weight:700;font-size:clamp(26px,3.6vw,40px);line-height:1.05;letter-spacing:-.035em}
.admin-top p{color:var(--ink2);margin-top:8px;font-size:14.5px}
.admin-actions{display:flex;gap:9px;align-items:center}
.kpis{display:grid;grid-template-columns:repeat(4,1fr);border:1px solid var(--rule);border-radius:var(--r2);overflow:hidden;background:var(--card);margin-bottom:16px}
.kpi{padding:16px 18px;border-right:1px solid var(--line)}
.kpi:last-child{border-right:none}
.kpi b{display:block;font:700 clamp(22px,2.8vw,30px)/1 var(--mono);margin:7px 0;letter-spacing:-.02em}
.kpi span{font:11px var(--mono);color:var(--ink3);text-transform:uppercase;letter-spacing:.05em}
.kpi small{font-size:12px;color:var(--ink3)}
.panel-head{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-bottom:16px;flex-wrap:wrap}
.panel-head h2{font:700 17px var(--disp)}
.panel-head h3{font:700 17px var(--disp)}
.toolbar{display:flex;gap:8px;flex-wrap:wrap}
.toolbar input,.toolbar select,.admin-form input,.admin-form select{background:var(--paper);border:1px solid var(--line);color:var(--ink);border-radius:var(--r);padding:10px 12px;font:13px var(--mono)}
.toolbar input:focus,.admin-form input:focus{outline:2px solid var(--signal);outline-offset:-1px}
.toolbar input{min-width:200px}
.admin-table{width:100%;border-collapse:collapse;min-width:700px}
.admin-table th{font:600 11px var(--mono);letter-spacing:.05em;text-transform:uppercase;color:var(--ink3);text-align:left;padding:12px 16px;border-bottom:1px solid var(--rule);background:var(--paper2)}
.admin-table td{padding:12px 16px;border-bottom:1px solid var(--line2);font-size:13.5px}
.admin-table tr:last-child td{border-bottom:none}
.admin-form label{display:block;font:600 11px var(--mono);letter-spacing:.05em;text-transform:uppercase;color:var(--ink3);margin:13px 0 6px}
.admin-form input{width:100%}
.admin-error{min-height:19px;margin-top:11px;color:var(--red);font-size:13.5px}
.detail-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:8px}
.detail-item{background:var(--paper2);border:1px solid var(--line2);border-radius:var(--r);padding:12px}
.detail-item small{display:block;font:10.5px var(--mono);color:var(--ink3);text-transform:uppercase;letter-spacing:.05em}
.detail-item b{display:block;margin-top:5px;font:700 14.5px var(--disp)}
.danger-note{margin-top:12px;padding:11px 13px;border:1px solid #e0b6bc;background:var(--red-wash);border-radius:var(--r);font:12.5px/1.55 var(--mono);color:var(--red)}
.status{font:600 10.5px var(--mono);padding:3px 8px;border-radius:3px;border:1px solid var(--line);color:var(--ink2);display:inline-block}
.status.good{color:var(--green);border-color:#c3ddc9;background:var(--green-wash)}
.status.off{color:var(--ink3);background:var(--paper2)}
.empty{color:var(--ink3);text-align:center;padding:20px}
.pagination{display:flex;justify-content:space-between;align-items:center;margin-top:14px;font:12.5px var(--mono);color:var(--ink3);gap:12px;flex-wrap:wrap}
.login-card{max-width:480px;margin:0 auto;padding:30px}
.login-card h1{font-family:var(--disp);font-weight:700;font-size:clamp(26px,3.4vw,34px);line-height:1.08;letter-spacing:-.03em;margin:6px 0 10px}
.login-card p{color:var(--ink2);font-size:14.5px}
.login-card .btn{width:100%;margin-top:18px}
.audit-meta{max-width:260px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:11px var(--mono);color:var(--ink3)}
/* Signed-in admin chip in the nav. Was referenced by admin.html but never
   styled, so the identity rendered as bare inline text. */
.statuschip{display:inline-flex;align-items:center;gap:7px;font:600 12px var(--mono);color:var(--ink2);background:var(--paper2);border:1px solid var(--line);border-radius:999px;padding:5px 11px;max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.statuschip .dot{flex:0 0 auto;width:7px;height:7px;border-radius:50%;background:var(--green)}
/* Compact pager used under an in-panel scroll region. */
.subpager{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;margin-top:12px;font:12px var(--mono);color:var(--ink3)}
.subpager .btn{min-width:0}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media(min-width:900px){
  .menu{display:flex}
  .nav-toggle{display:none}
  .menu-auth,.menu.open .menu-auth{display:none}

}
@media(max-width:1000px){
  .hero-grid{grid-template-columns:1fr;gap:32px}
  .pipe-body{grid-template-columns:repeat(2,minmax(0,1fr))}
  .foot-grid{grid-template-columns:1fr 1fr;gap:26px}
  .docs-layout{grid-template-columns:minmax(0,1fr)}
  /* The horizontal TOC must wrap. As plain inline-blocks in a grid item the
     links formed one long line and forced the page ~580px wide. */
  .toc{position:static;border-left:none;border-top:1px solid var(--rule);padding:14px 0 0;margin-bottom:24px;display:flex;flex-wrap:wrap;gap:0 16px;align-items:baseline}
  .toc h4{flex:1 1 100%}
  .toc a{display:inline-block;margin-right:0}
  /* The left marker is positioned at -17px, which pokes outside the column. */
  .toc a::before{display:none}
}
@media(max-width:860px){
  .split-head{grid-template-columns:1fr;gap:14px;align-items:start}
  .cta-final{grid-template-columns:1fr;gap:22px}
  .row-item{grid-template-columns:32px minmax(0,1fr);gap:14px;row-gap:6px}
  .row-item .num{grid-row:1}
  .row-item p{grid-column:2}
  .admin-shell{grid-template-columns:1fr}
  .admin-side{position:static;display:flex;overflow-x:auto;gap:4px}
  .side-title{display:none}
  .side-btn{white-space:nowrap;width:auto}
  .kpis{grid-template-columns:repeat(2,1fr)}
  .kpi:nth-child(2n){border-right:none}
  .kpi:nth-child(-n+2){border-bottom:1px solid var(--line)}
  .admin-top{align-items:flex-start;flex-direction:column}
  .calc-grid{grid-template-columns:1fr;gap:22px}
  .entry{grid-template-columns:1fr;gap:10px}
  .detail-grid{grid-template-columns:1fr}
}
@media(max-width:620px){
  body{font-size:16px}
  .pipe-body{grid-template-columns:1fr}
  .foot-grid{grid-template-columns:1fr}

  .proof{border-right:none;border-bottom:1px solid var(--line);padding-right:0}
  .proof:last-child{border-bottom:none}
  .filterbar{width:100%}
  .fbtn{flex:1;text-align:center}
  .modal{padding:12px}
  .modal .box{padding:20px}
  .modal .keyrow{flex-wrap:wrap}
  .modal .keyrow input{flex-basis:100%}
  .modal .keyrow button{width:100%}
}

/* ============================================================
   MOBILE / TOUCH
   Phone-specific corrections. These are behavioural fixes, not
   cosmetics:
     1. iOS Safari zooms the page when a focused control has
        font-size < 16px, and the zoom is not undone on blur.
     2. Touch targets below ~44px are unreliable to hit.
     3. :hover latches on touch: a tapped card keeps its lifted
        state until something else is tapped.
     4. 100vh on mobile Safari includes the retracted toolbar, so
        full-height panes get clipped.
   ============================================================ */

/* ---- 1. never let iOS zoom the page on focus ---- */
@media (max-width: 820px) {
  input, select, textarea,
  .modal input, .modal select,
  .auth-card input,
  .toolbar input, .toolbar select,
  .admin-form input, .admin-form select,
  .calc input[type=number], .calc select,
  .keyrow input,
  /* The nav picker is the one control present on every page, and its own
     0-1-1 rule outranked the bare `select` above, so iOS zoomed the page on
     every focus. */
  .language-picker select,
  .field-inline {
    font-size: 16px;
  }
  /* Fixed min-widths overflow a 320px viewport, so let fields fill. */
  .toolbar { min-width: 0 }
  .toolbar input, .toolbar select { min-width: 0; width: 100%; flex: 1 1 100% }
  .toolbar .btn { width: 100% }
  .keyrow input { min-width: 0; flex-basis: 100% }
  .keyrow .btn { width: 100% }
}

/* ---- 2. touch targets ---- */
@media (pointer: coarse) {
  .btn { min-height: 44px }
  .btn.small { min-height: 40px; padding: 9px 14px }
  .btn.big { min-height: 50px }
  .btn.link { min-height: 0; padding: 0 }
  .nav-toggle { width: 44px; height: 44px }
  /* The picker is a real control in the nav; it was ~32px tall. */
  .language-picker select { min-height: 40px }
  .fbtn { min-height: 44px; display: inline-flex; align-items: center; justify-content: center }
  .side-btn { min-height: 44px }
  .menu.open a { padding: 15px 14px }
  .foot-col a { padding: 8px 0 }
  .toc a { padding: 8px 0 }
  .code-tab { min-height: 44px; display: inline-flex; align-items: center }
  .copybtn { min-height: 44px }
  .faq-item summary { padding: 19px 0 }
  /* Row actions in tables are the smallest targets in the product. */
  .table td .btn, .admin-table td .btn { min-height: 38px }
  /* Inline text buttons ("Зарегистрироваться", "Войти") sit on their own line,
     so give them a real tap area without turning them into blocks. */
  .auth-switch button { min-height: 44px; padding: 0 6px }
  /* Android's default grey tap flash reads as a rendering glitch. */
  a, button, summary, .fbtn, .side-btn { -webkit-tap-highlight-color: rgba(29, 78, 216, .12) }
}

/* ---- 3. hover effects must not latch on touch ---- */
@media (hover: none) {
  .card:hover { transform: none; box-shadow: none; border-color: var(--line) }
  .card:hover::before { transform: scaleX(0) }
  .plan:hover { transform: none; border-color: var(--line); box-shadow: none }
  .plan.featured:hover { border-color: var(--rule); box-shadow: var(--shadow) }
  .btn.primary:hover, .btn.ghost:hover { transform: none; box-shadow: none }
  .btn.primary:hover { background: var(--ink); border-color: var(--ink) }
  .btn.ghost:hover { border-color: var(--line); background: var(--card) }
  .row-item:hover { background: none; padding-left: 0 }
  .foot-col a:hover { transform: none }
  .menu a:hover::before { transform: scaleX(0) }
  .table tbody tr:hover td { background: none }
  /* Keep an explicit pressed state so taps still feel acknowledged. */
  .btn:active { transform: translateY(1px) }
  .card:active { border-color: var(--ink) }
}

/* ---- 4. layout fixes for narrow screens ---- */
@media (max-width: 620px) {
  /* Sticky nav + sticky panes eat a phone screen; drop to 8px gutters. */
  :root { --gut: 16px }

  /* dvh accounts for the retractable browser toolbar; vh does not. */
  .auth-shell { min-height: auto; padding: 32px var(--gut) 40px }
  .modal .box { max-height: calc(100dvh - 24px) }

  /* The nav is 62px of a ~640px viewport: tighten it and the offsets
     that were hardcoded against it. */
  .nav .wrap { height: 56px; gap: 10px }
  /* 320px cannot hold logo + two buttons + burger, so the pair wrapped onto
     a second line and spilled outside the bar. The opened menu already
     carries navigation, so keep only the primary action beside the burger
     and surface the sign-in link inside the menu instead. */
  .authbox { gap: 6px }
  .authbox [data-auth-anon] .btn.ghost { display: none }
  .authbox .btn.small { padding: 8px 11px; font-size: 12.5px }
  .menu.open { top: 56px }
  .toc { top: 68px }
  .admin-side { top: 68px }
  .doc-block h2 { scroll-margin-top: 68px }
  .doc-block[id] { scroll-margin-top: 64px }

  /* Stat strips: side borders leave hairlines dangling at 1 column. */
  .stats { grid-template-columns: 1fr 1fr }
  .stats > div { border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: 16px }
  .stats > div:nth-child(2n) { border-right: none }
  .stats > div:nth-last-child(-n+2) { border-bottom: none }
  .stats b { font-size: 26px }

  .dash-grid { grid-template-columns: 1fr 1fr }
  .dstat { border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: 15px 16px }
  .dstat:nth-child(2n) { border-right: none }
  .dstat .v { font-size: 21px }
  .dstat .l { font-size: 10.5px }

  .kpis { grid-template-columns: 1fr 1fr }
  .kpi { padding: 14px }

  /* Panels and cards: 20-26px of padding is a lot at this width. */
  .panel .body { padding: 16px }
  .panel .ph { padding: 12px 16px }
  .card { padding: 18px }
  .plan { padding: 20px }
  .calc { padding: 18px }
  .calc .save-box { padding: 18px }
  .auth-card { padding: 24px 20px }
  /* The Turnstile iframe is a hard 300px. Below ~360px of viewport the card
     content box is narrower than that, so scale the widget down rather than
     let it dictate the page width. transform keeps the iframe untouched. */
  .cf-turnstile { transform: scale(.92); transform-origin: left center }
  .login-card { padding: 24px 20px }
  .modal .box { padding: 20px 18px }
  .cta-final { padding: 26px 20px }
  .keyblock { padding: 26px 20px }

  /* Headings: clamp() minimums are still wide for 320px screens. */
  .hero h1 { font-size: clamp(31px, 9vw, 44px); letter-spacing: -.03em }
  .hero .lead { font-size: 16.5px }
  .split-head h1, .split-head h2, .sec-head h1, .sec-head h2, .list-head h1 { font-size: clamp(25px, 7.2vw, 34px) }
  .cta-title { font-size: clamp(23px, 6.4vw, 30px) }
  .doc-block h2 { font-size: clamp(21px, 6vw, 27px) }

  /* Stack the actions instead of letting them wrap into ragged rows. */
  .hero .cta, .cta-btns, .btn-row { flex-direction: column; align-items: stretch }
  .hero .cta .btn, .cta-btns .btn, .btn-row .btn { width: 100% }
  .dash-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; width: 100% }
  .dash-actions .btn { width: 100% }

  /* Tables scroll horizontally; make that discoverable and smooth. */
  .tablewrap, .fit-scroll { -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain }
  .table th, .table td { padding: 11px 13px }
  .admin-table th, .admin-table td { padding: 10px 12px }
  .table { min-width: 560px }
  .table.compact { min-width: 380px }
  /* 700px never relaxed, so every admin table forced a horizontal scroll of
     more than twice the viewport width. */
  .admin-table { min-width: 520px }
  /* Panel-height cap plus page scroll is two nested scrollbars on a short
     screen; give the in-panel region more of the viewport instead. */
  .usage-scroll { max-height: 60vh }

  /* The code sample is the most-read element on the docs page. */
  .code pre { padding: 14px; font-size: 12px; line-height: 1.7 }
  .code-top { padding: 8px 10px; flex-wrap: wrap }
  .code-tabs { flex: 1 1 auto }

  /* 12.5px mono captions are legible on a desktop but not at arm's length
     on a phone. Nudge the long-form ones up; tags and table meta stay small. */
  .note, .hero .micro, .keyblock .micro, .pipe-foot, .spec-foot { font-size: 14px; line-height: 1.66 }
  .calc .note, .panel .body .note { font-size: 14px }
  .spec-row { padding: 10px 12px }
  .spec-row .n { font-size: 13.5px }
  .spec-row .v { font-size: 12.5px }
  .pipe-step { padding: 16px 14px }
  .entry { padding: 20px 0 }
  .foot-bottom { flex-direction: column; align-items: flex-start; gap: 6px }
  .list-head .count { text-align: left }
  .audit-meta { max-width: 160px }
  .pagination { gap: 8px }
  .pagination > div { display: flex; gap: 8px; width: 100% }
  .pagination .btn { flex: 1 }
  section { padding: 44px 0 }
}

/* Very narrow phones (<=380px): the single-column fallbacks. */
@media (max-width: 380px) {
  .stats, .dash-grid, .kpis, .detail-grid { grid-template-columns: 1fr }
  .stats > div, .dstat, .kpi { border-right: none }
  .dash-actions { grid-template-columns: 1fr }
  .hero h1 { font-size: 29px }
  .logo { font-size: 15.5px }
  /* 320px: 300px widget + 40px padding will not fit; scale harder. */
  .cf-turnstile { transform: scale(.82); transform-origin: left center }
  .auth-card { padding: 22px 16px }
  .filterbar { flex-direction: column; width: 100% }
  .fbtn { border-right: none; border-bottom: 1px solid var(--line); width: 100% }
  .fbtn:last-child { border-bottom: none }
  .usage-bar { align-items: stretch }
  .subpager > div { display: flex; gap: 8px; width: 100% }
  .subpager .btn { flex: 1 }
}

/* Landscape phones: vertical space, not width, is the constraint. */
@media (max-height: 480px) and (orientation: landscape) {
  .nav { position: static }
  .auth-shell { min-height: auto; padding: 24px var(--gut) }
  .modal { align-items: flex-start }
  .modal .box { max-height: calc(100dvh - 24px) }
}

/* ============================================================
   REDUCED MOTION / PRINT
   ============================================================ */
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}
  html.js .rv{opacity:1;transform:none}
  html.js .rv[data-stagger]>*{opacity:1;transform:none}
  /* neutralise decorative transforms so nothing is left mid-animation */
  html.js .split-head::after,html.js .plan.featured::before{transform:scaleX(1)}
  html.js .rv .eyebrow::before{transform:none;opacity:1}
  .card:hover,.plan:hover,.btn.primary:hover,.btn.ghost:hover,.foot-col a:hover{transform:none}
  .row-item:hover{padding-left:0}
  .card::before{display:none}

  .progress{display:none}
}
@media print{
  .nav,.footer,.toast,.skip,.cta-final,.btn{display:none}
  body{background:#fff;color:#000;font-size:11pt}
  .card,.panel,.tablewrap{border-color:#999;box-shadow:none}
}
