:root{--ink:#16181d;--ink-muted:#6e7480;--surface:#f6f7f9;--surface-raised:#ffffff;--line:#e6e8ec;--accent:#0f766e;--accent-ink:#ffffff;--font-display:'Plus Jakarta Sans', system-ui, sans-serif;--font-text:'Plus Jakarta Sans', system-ui, sans-serif;--step--1:0.8125rem;--step-0:1rem;--step-1:1.25rem;--step-2:1.75rem;--step-3:2.5rem;--space-1:4px;--space-2:8px;--space-3:16px;--space-4:24px;--space-6:40px;--space-8:72px;--ok:#16a34a;--warn:#d97706;--danger:#dc2626;--focus:#0f766e;--radius:12px;--radius-lg:20px;--shadow:0 1px 2px rgba(16,18,29,.06), 0 8px 24px rgba(16,18,29,.06);--ease:cubic-bezier(.2,.7,.3,1);--dur:180ms}

/* Acuvo component layer — every value is a token from :root above. */
*,*::before,*::after{box-sizing:border-box}
body{margin:0;background:var(--surface);color:var(--ink);font-family:var(--font-text);font-size:var(--step-0);line-height:1.55;-webkit-font-smoothing:antialiased}
h1,h2,h3{font-family:var(--font-display);line-height:1.15;margin:0 0 var(--space-3)}
h1{font-size:var(--step-3)}h2{font-size:var(--step-2)}h3{font-size:var(--step-1)}
p{margin:0 0 var(--space-3)}
a{color:var(--accent);text-underline-offset:.2em}
small,.ax-muted{color:var(--ink-muted);font-size:var(--step--1)}

summary{cursor:pointer;list-style:none}
summary::-webkit-details-marker{display:none}

/* ⚠️ ONE focus ring, defined once. A model writing per-component focus styles
   is how a page ends up with three of them and one missing entirely. */
:where(a,button,input,select,textarea,[tabindex]):focus-visible{outline:2px solid var(--focus);outline-offset:2px;border-radius:var(--radius)}

/* Layout primitives — the four shapes every page actually needs. */
.ax-container{width:min(100% - var(--space-4)*2,72rem);margin-inline:auto}
.ax-stack>*+*{margin-top:var(--space-3)}
.ax-row{display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap}
.ax-grid{display:grid;gap:var(--space-4);grid-template-columns:repeat(auto-fit,minmax(min(100%,16rem),1fr))}
.ax-section{padding-block:var(--space-8)}

/* ⭐⭐⭐ THE BAND — the primitive that stops a page being one centred column.
   LAYOUT_RATIONALE in design-elements.ts carries the browser measurement and
   the sources; this is the same CSS on the agentic path, because a build must
   not get a different vocabulary depending on which path generated it.
   A band is a FULL-WIDTH section that centres its own children on named grid
   lines, so its background reaches both screen edges while every heading and
   every list under it shares one left edge. Grid, not 100vw: 100vw includes
   the scrollbar and hands every desktop page a horizontal scrollbar. */
html{--ax-ink-bg:var(--ink);--ax-ink-fg:var(--surface)}
.ax-band{display:grid;padding-block:min(var(--space-8),calc(var(--space-4) + 5vw));grid-template-columns:[full-start] minmax(var(--space-4),1fr) [wide-start] minmax(0,4rem) [content-start] min(var(--ax-page,72rem),100% - var(--space-4)*2) [content-end] minmax(0,4rem) [wide-end] minmax(var(--space-4),1fr) [full-end]}
.ax-band>*{grid-column:content}
.ax-band>.ax-wide{grid-column:wide}
.ax-band>.ax-full{grid-column:full}
.ax-band-tight{padding-block:var(--space-6)}
.ax-band-tint{background:var(--surface-raised)}
/* The band paints from --ax-ink-*, snapshots taken on html (never the token it
   redefines: circular). Its CHILDREN get the inverted tokens, so a model's own
   band rule reading var(--ink) still means the page ink. --surface is not
   remapped: models use it for light type on the band. Fields read --ax-field-bg. */
.ax-band-ink{background:var(--ax-ink-bg);color:var(--ax-ink-fg)}
.ax-band-ink>*{--ink:var(--ax-ink-fg);--ink-muted:color-mix(in oklab,var(--ax-ink-fg) 72%,var(--ax-ink-bg));--line:color-mix(in oklab,var(--ax-ink-fg) 26%,var(--ax-ink-bg));--surface-raised:color-mix(in oklab,var(--ax-ink-fg) 8%,var(--ax-ink-bg));--ax-field-bg:var(--ax-ink-bg)}
.ax-split{display:grid;gap:var(--space-6);align-items:center;grid-template-columns:1fr}
.ax-sidebar{display:flex;flex-wrap:wrap;gap:var(--space-6)}
.ax-sidebar>:first-child{flex:1 1 20rem}
.ax-sidebar>:last-child{flex:999 1 0;min-width:55%}
.ax-measure{max-width:66ch}
@media(min-width:820px){.ax-split{grid-template-columns:1.45fr 1fr}
.ax-split-flip{grid-template-columns:1fr 1.45fr}
.ax-split-flip>:first-child{order:2}}

/* Buttons. Three variants, because a fourth is a decision nobody needs. */
.ax-btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-1);padding:var(--space-2) var(--space-4);border:1px solid transparent;border-radius:var(--radius);background:var(--accent);color:var(--accent-ink);font:inherit;font-weight:600;cursor:pointer;text-decoration:none;transition:filter var(--dur) var(--ease),transform var(--dur) var(--ease)}
.ax-btn:hover{filter:brightness(1.08)}
.ax-btn:active{transform:translateY(1px)}
.ax-btn[disabled],.ax-btn[aria-disabled=true]{opacity:.55;cursor:not-allowed;filter:none;transform:none}
.ax-btn-quiet{background:transparent;color:var(--ink);border-color:var(--line)}
.ax-btn-quiet:hover{background:var(--surface-raised);filter:none}
.ax-btn-danger{background:var(--danger);color:var(--accent-ink)}

/* Surfaces. */
.ax-card{min-width:0;background:var(--surface-raised);border:1px solid var(--line);border-radius:var(--radius-lg);padding:var(--space-4);box-shadow:var(--shadow)}
.ax-card-head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-2);margin-bottom:var(--space-3)}

/* Forms — the label/field/error trio, so an error state exists by default. */
.ax-field{display:block;margin-bottom:var(--space-3)}
.ax-label{display:block;margin-bottom:var(--space-1);font-size:var(--step--1);font-weight:600;color:var(--ink)}
.ax-input,.ax-select,.ax-textarea{width:100%;padding:var(--space-2) var(--space-3);border:1px solid var(--line);border-radius:var(--radius);background:var(--ax-field-bg,var(--surface));color:var(--ink);font:inherit;transition:border-color var(--dur) var(--ease)}
.ax-input:hover,.ax-select:hover,.ax-textarea:hover{border-color:var(--ink-muted)}
.ax-input[aria-invalid=true]{border-color:var(--danger)}
.ax-error{display:block;margin-top:var(--space-1);color:var(--danger);font-size:var(--step--1)}
.ax-hint{display:block;margin-top:var(--space-1);color:var(--ink-muted);font-size:var(--step--1)}

/* Status. */
.ax-badge{display:inline-flex;align-items:center;gap:var(--space-1);padding:calc(var(--space-1)/1.5) var(--space-2);border-radius:999px;background:var(--surface-raised);border:1px solid var(--line);font-size:var(--step--1);font-weight:600}
.ax-badge-ok{background:var(--ok);color:var(--accent-ink);border-color:transparent}
.ax-badge-warn{background:var(--warn);color:var(--accent-ink);border-color:transparent}
.ax-badge-danger{background:var(--danger);color:var(--accent-ink);border-color:transparent}

/* Tables — a real one, because a model writing its own always forgets the
   header contrast and the row rhythm. */
.ax-table{width:100%;border-collapse:collapse;font-size:var(--step-0)}
.ax-table th{text-align:left;font-size:var(--step--1);color:var(--ink-muted);font-weight:600;padding:var(--space-2) var(--space-3);border-bottom:1px solid var(--line)}
.ax-table td{padding:var(--space-3);border-bottom:1px solid var(--line)}
.ax-table tr:last-child td{border-bottom:0}

/* ⭐ THE TWO STATES EVERY GENERATED APP FORGETS. An app with data looks fine
   in a screenshot and broken the first time it is empty or loading. */
.ax-empty{padding:var(--space-8) var(--space-4);text-align:center;color:var(--ink-muted);border:1px dashed var(--line);border-radius:var(--radius-lg)}
/* ⚠️ THE display DECLARATION IS PARITY, NOT DECORATION. No backticks in this
   comment: the sheet is a template literal. This layer already had the
   min-height that ELEMENT_CSS was missing (measured: 14.00px here, 0.00px
   there), but a skeleton is routinely written as a "span" inside a cell, and an
   inline box ignores min-height entirely — the same invisible-loading-state
   defect through a different door. */
.ax-skeleton{display:block;background:var(--surface-raised);border-radius:var(--radius);min-height:1em;animation:ax-pulse 1.2s var(--ease) infinite}
@keyframes ax-pulse{0%,100%{opacity:1}50%{opacity:.55}}

/* ── ⭐⭐⭐ THE APP SHELL (added 2026-08-21) ────────────────────────────────
   The layer above is a DOCUMENT vocabulary — container, card, field, table.
   It cannot build an application, and this file's own note predicted the
   symptom: "a model inventing `ax-hero` is telling us the layer is missing
   something". It was. There was no hero, no nav, no tabs, no dialog, no stat,
   no list — so every generated app invented them, and invented CSS is exactly
   where the output stops looking designed and starts looking generated.

   ⚠️ THE COST IS ONE-TIME AND THE BENEFIT IS EVERY BUILD. This ships as
   `styles/system.css` written into the project once; it is never re-sent, so
   it costs no output tokens per round — which is the opposite of the model
   hand-writing the same nav on every build at 56%-of-the-bill prices. */

/* Navigation — the one every app needs and none of them had. */
.ax-nav{display:flex;align-items:center;gap:var(--space-4);flex-wrap:wrap;padding:var(--space-3) 0;border-bottom:1px solid var(--line)}
.ax-nav-brand{font-family:var(--font-display);font-weight:700;font-size:var(--step-1);margin-right:auto;color:var(--ink);text-decoration:none}
.ax-nav-link{color:var(--ink-muted);text-decoration:none;font-weight:600;padding:var(--space-1) 0;border-bottom:2px solid transparent;transition:color var(--dur) var(--ease),border-color var(--dur) var(--ease)}
.ax-nav-link:hover{color:var(--ink)}
.ax-nav-link[aria-current]{color:var(--ink);border-bottom-color:var(--accent)}

/* ⭐ The hero this file named as missing. Restrained on purpose: a hero that
   shouts is the fastest way to look like a template. */
.ax-hero{padding-block:calc(var(--space-8)*1.5);text-align:center;max-width:44rem;margin-inline:auto}
.ax-hero h1{font-size:var(--step-3);text-wrap:balance;margin-bottom:var(--space-4)}
.ax-hero p{font-size:var(--step-1);color:var(--ink-muted);text-wrap:pretty}

/* ⚠️ THE DASHBOARD PRIMITIVE. "Show me the numbers" is the most common app
   brief there is, and a model with no stat block builds it out of cards with
   invented type scales — which is why generated dashboards read as flat. */
.ax-stat{padding:var(--space-4);border:1px solid var(--line);border-radius:var(--radius-lg);background:var(--surface-raised)}
.ax-stat-label{display:block;font-size:var(--step--1);color:var(--ink-muted);font-weight:600;letter-spacing:.02em}
.ax-stat-value{display:block;font-family:var(--font-display);font-size:var(--step-2);line-height:1.1;margin-top:var(--space-1);font-variant-numeric:tabular-nums}
.ax-stat-delta{font-size:var(--step--1);font-weight:600}
.ax-stat-delta[data-dir=up]{color:var(--ok)}
.ax-stat-delta[data-dir=down]{color:var(--danger)}

/* Tabs — CSS only; the app toggles [aria-selected]. */
.ax-tabs{display:flex;gap:var(--space-1);border-bottom:1px solid var(--line);margin-bottom:var(--space-4)}
.ax-tab{appearance:none;background:none;border:0;border-bottom:2px solid transparent;padding:var(--space-2) var(--space-3);font:inherit;font-weight:600;color:var(--ink-muted);cursor:pointer;transition:color var(--dur) var(--ease),border-color var(--dur) var(--ease)}
.ax-tab[aria-selected=true]{color:var(--ink);border-bottom-color:var(--accent)}

/* Dialog. Uses <dialog> so focus trapping and Esc are the platform's job, not
   the model's — a hand-rolled modal is where generated apps trap keyboards. */
.ax-modal{border:1px solid var(--line);border-radius:var(--radius-lg);padding:var(--space-4);background:var(--surface-raised);color:var(--ink);max-width:min(100% - var(--space-4)*2,32rem);box-shadow:var(--shadow)}
.ax-modal::backdrop{background:color-mix(in oklab,var(--ink) 45%,transparent)}

/* Lists — the shape a model otherwise builds from divs and forgets to space. */
.ax-list{list-style:none;margin:0;padding:0;border:1px solid var(--line);border-radius:var(--radius-lg);overflow:hidden}
.ax-list-item{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3);border-bottom:1px solid var(--line)}
.ax-list-item:last-child{border-bottom:0}
.ax-list-item:hover{background:var(--surface-raised)}

/* Small parts that otherwise get invented one page at a time. */
.ax-avatar{display:inline-grid;place-items:center;width:var(--space-8);aspect-ratio:1;border-radius:999px;background:var(--surface-raised);border:1px solid var(--line);font-weight:700;font-size:var(--step--1);overflow:hidden}
.ax-avatar img{width:100%;height:100%;object-fit:cover}
.ax-chip{display:inline-flex;align-items:center;gap:var(--space-1);padding:calc(var(--space-1)/1.5) var(--space-2);border-radius:var(--radius);background:var(--surface-raised);border:1px solid var(--line);font-size:var(--step--1)}
.ax-divider{height:1px;background:var(--line);border:0;margin-block:var(--space-4)}
.ax-toolbar{display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap;margin-bottom:var(--space-4)}
.ax-progress{height:var(--space-2);border-radius:999px;background:var(--surface-raised);overflow:hidden}
.ax-progress>span{display:block;height:100%;background:var(--accent);transition:width var(--dur) var(--ease)}
.ax-kbd{font-family:ui-monospace,monospace;font-size:var(--step--1);padding:0 var(--space-1);border:1px solid var(--line);border-bottom-width:2px;border-radius:var(--radius);background:var(--surface-raised)}

/* Page blocks. Rationale: PAGE_BLOCKS_RATIONALE below. */
.ax-price{display:flex;flex-direction:column;gap:var(--space-3);padding:var(--space-4);border:1px solid var(--line);border-radius:var(--radius-lg);background:var(--surface-raised)}
.ax-price-featured{border-color:var(--accent);border-width:2px}
.ax-price-amount{font-family:var(--font-display);font-size:var(--step-2);line-height:1;font-variant-numeric:tabular-nums}
.ax-price-period{font-size:var(--step--1);color:var(--ink-muted);font-family:var(--font-text)}
.ax-price-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-2);font-size:var(--step-0)}
.ax-price-list li{display:flex;gap:var(--space-2);align-items:flex-start}
.ax-price>.ax-btn{margin-top:auto}

.ax-faq{border:1px solid var(--line);border-radius:var(--radius-lg);background:var(--surface-raised);overflow:hidden}
.ax-faq+.ax-faq{margin-top:var(--space-2)}
.ax-faq>summary{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);padding:var(--space-3) var(--space-4);font-family:var(--font-display);font-weight:600}
.ax-faq>summary::after{content:"+";font-family:var(--font-text);color:var(--ink-muted);transition:transform var(--dur) var(--ease)}
.ax-faq[open]>summary::after{transform:rotate(45deg)}
.ax-faq>:not(summary){padding:0 var(--space-4) var(--space-3);margin:0;color:var(--ink-muted)}

.ax-footer{border-top:1px solid var(--line);padding-block:var(--space-6);color:var(--ink-muted);font-size:var(--step--1)}
.ax-footer-grid{display:grid;gap:var(--space-6);grid-template-columns:repeat(auto-fit,minmax(min(100%,12rem),1fr));margin-bottom:var(--space-4)}
.ax-footer a{display:block;padding:calc(var(--space-1)/1.5) 0;color:var(--ink-muted);text-decoration:none}
.ax-footer a:hover{color:var(--ink)}

.ax-icon-btn{display:inline-grid;place-items:center;width:44px;height:44px;padding:0;border:1px solid transparent;border-radius:var(--radius);background:none;color:var(--ink-muted);cursor:pointer}
.ax-icon-btn:hover{background:var(--surface-raised);color:var(--ink)}

.ax-eyebrow{display:block;font-size:var(--step--1);font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-muted);margin-bottom:var(--space-2)}

/* ⚠️ Toast is FIXED and polite. A model placing its own toast usually pins it
   over the primary action on mobile. */
.ax-toast{position:fixed;inset-block-end:var(--space-4);inset-inline:var(--space-4);margin-inline:auto;width:fit-content;max-width:calc(100% - var(--space-4)*2);padding:var(--space-3) var(--space-4);border-radius:var(--radius-lg);background:var(--ink);color:var(--surface);box-shadow:var(--shadow);z-index:50}

/* ⚠️ Motion is opt-out by system preference, once, here — rather than being
   forgotten in twenty places. */
@media (prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important}}

:root{
  --shadow-1:0 1px 2px -1px hsl(var(--shadow-color)/var(--shadow-strength-10));
  --shadow-2:0 3px 5px -2px hsl(var(--shadow-color)/var(--shadow-strength-4)),0 7px 14px -5px hsl(var(--shadow-color)/var(--shadow-strength-6));
  --shadow-3:0 -1px 3px 0 hsl(var(--shadow-color)/var(--shadow-strength-3)),0 1px 2px -5px hsl(var(--shadow-color)/var(--shadow-strength-3)),0 2px 5px -5px hsl(var(--shadow-color)/var(--shadow-strength-5)),0 4px 12px -5px hsl(var(--shadow-color)/var(--shadow-strength-6)),0 12px 15px -5px hsl(var(--shadow-color)/var(--shadow-strength-8));
  --shadow-4:0 -2px 5px 0 hsl(var(--shadow-color)/var(--shadow-strength-3)),0 1px 1px -2px hsl(var(--shadow-color)/var(--shadow-strength-4)),0 2px 2px -2px hsl(var(--shadow-color)/var(--shadow-strength-4)),0 5px 5px -2px hsl(var(--shadow-color)/var(--shadow-strength-5)),0 9px 9px -2px hsl(var(--shadow-color)/var(--shadow-strength-6)),0 16px 16px -2px hsl(var(--shadow-color)/var(--shadow-strength-7));
  --shadow-5:0 -1px 2px 0 hsl(var(--shadow-color)/var(--shadow-strength-3)),0 2px 1px -2px hsl(var(--shadow-color)/var(--shadow-strength-4)),0 5px 5px -2px hsl(var(--shadow-color)/var(--shadow-strength-4)),0 10px 10px -2px hsl(var(--shadow-color)/var(--shadow-strength-5)),0 20px 20px -2px hsl(var(--shadow-color)/var(--shadow-strength-6)),0 40px 40px -2px hsl(var(--shadow-color)/var(--shadow-strength-8));
  --shadow-6:0 -1px 2px 0 hsl(var(--shadow-color)/var(--shadow-strength-3)),0 3px 2px -2px hsl(var(--shadow-color)/var(--shadow-strength-4)),0 7px 5px -2px hsl(var(--shadow-color)/var(--shadow-strength-4)),0 12px 10px -2px hsl(var(--shadow-color)/var(--shadow-strength-5)),0 22px 18px -2px hsl(var(--shadow-color)/var(--shadow-strength-6)),0 41px 33px -2px hsl(var(--shadow-color)/var(--shadow-strength-7)),0 100px 80px -2px hsl(var(--shadow-color)/var(--shadow-strength-8));
  --shadow-color:220 3% 15%;
  --shadow-strength:1%;
  --ease-1:cubic-bezier(.25,0,.5,1);
  --ease-2:cubic-bezier(.25,0,.4,1);
  --ease-3:cubic-bezier(.25,0,.3,1);
  --ease-4:cubic-bezier(.25,0,.2,1);
  --ease-5:cubic-bezier(.25,0,.1,1);
  --ease-out-3:cubic-bezier(0,0,.3,1);
  --ease-out-5:cubic-bezier(0,0,0,1);
  --ease-in-out-3:cubic-bezier(.5,0,.5,1);
  --ease-elastic-3:var(--ease-elastic-out-3);
  --ease-spring-3:linear(0,0.009,0.035 2.1%,0.141 4.4%,0.723 12.9%,0.938 16.7%,1.017,1.077,1.121,1.149 24.3%,1.159,1.163,1.161,1.154 29.9%,1.129 32.8%,1.051 39.6%,1.017 43.1%,0.991,0.977 51%,0.974 53.8%,0.975 57.1%,0.997 69.8%,1.003 76.9%,1);
  --animation-fade-in:fade-in .5s var(--ease-3);
  --animation-fade-out:fade-out .5s var(--ease-3);
  --animation-scale-up:scale-up .5s var(--ease-3);
  --animation-slide-in-up:slide-in-up .5s var(--ease-3);
  --animation-slide-in-down:slide-in-down .5s var(--ease-3);
  --animation-shake-x:shake-x .75s var(--ease-out-5);
  --animation-pulse:pulse 2s var(--ease-out-3) infinite;
}
@keyframes fade-in{to{opacity:1}}
@keyframes fade-out{to{opacity:0}}
@keyframes scale-up{to{transform:scale(1.25)}}
@keyframes slide-in-up{0%{transform:translateY(100%)}}
@keyframes slide-in-down{0%{transform:translateY(-100%)}}
@keyframes shake-x{0%,to{transform:translateX(0)}20%{transform:translateX(-5%)}40%{transform:translateX(5%)}60%{transform:translateX(-5%)}80%{transform:translateX(5%)}}
@keyframes pulse{50%{transform:scale(.9)}}
