@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;800&display=swap');
/* =====================================================================
   kaizen-style v4 — ELEMENT GRAMMAR pass (2026-07-09, model: claude-fable-5)
   v4 adds the locked element vocabulary (DS23): kz-chip / kz-timeline / kz-row
   / kz-table+kz-num / kz-empty / kz-skeleton / kz-field / kz-stat / kz-steps /
   kz-envnote — all ADDITIVE; encoded user-consensus rules; see the v4 block.
   Previous: v3 ACCENT + ICONS pass (2026-07-07)
   · every theme now ships a real accent + a per-theme --on-accent, ALL pairs
     measured (WCAG 2.1): text-on-accent >= 4.5:1 — ratios inline below.
   · shared inline-SVG icon set (DS19) injected by kaizen.js; style via .kz-icon.
   · touchpanel accent-glow card hover (DS18) is now KIT-standard (was a hub override).
   Previous: v2 CRAFT ELEVATION (2026-07-06) · ratio-audited rev
   House style, served at style.kaizenlogic.com. Single source for ALL
   Kaizen hosted apps. Edit HERE; every linked app updates.

   PROPORTION LAW (this rev): every value derives from the shared scales —
     · type  = named tokens only (display / title=h2 / lead / h3 / lg / body
               / sm / hint / label / micro). No raw off-scale font sizes.
     · space = 4·8 ramp {4 8 12 16 22 24 32 44 48 64 96} + gap 14 + pad 18.
     · radius= ONE scale by role: 8 small (buttons/inputs) · 10 default
               (cards/menus) · 12 brand coin. (DECISIONS DS6.)
     · button= ONE scale: 44 default (page) · 36 compact (.kz-btn-sm, bars).
     · control height = 44 tap · 36 compact. Icon glyphs sized deliberately.
   Adoption (2 tags):
     <link rel="stylesheet" href="https://style.kaizenlogic.com/kaizen.css">
     <script src="https://style.kaizenlogic.com/kaizen.js" defer></script>
   ===================================================================== */

/* ---------- tokens: Nightman (default, dark) ---------- */
:root{
  --bg:#0a0a0b; --panel:#101012; --panel2:#161618; --line:#26262a;
  --ink:#f4f4f5; --mut:#8a8a92; --dim:#5a5a62;
  /* ACCENT (v3): nightman carries the brand blue (BL11) — the default theme finally
     has an accent instead of a white box. MEASURED: on-accent #0a0a0b on #4f8ef7 = 6.17:1,
     accent vs bg = 6.17:1. Dark glyph on lit key = the touchpanel language (DS18). */
  --stripe:#4f8ef7; --ok:#3ad29f; --bad:#ff5a5f; --warn:#f5b14c; --trace:#9aa0ff;
  --on-accent:#0a0a0b;
  /* elevation — restrained, premium (not a drop-shadow contest) */
  --kz-shadow-1:0 1px 2px rgba(0,0,0,.28);
  --kz-shadow-2:0 6px 24px -8px rgba(0,0,0,.45);
  --kz-shadow-pop:0 18px 48px -12px rgba(0,0,0,.55);
  --kz-scrim:rgba(6,6,8,.56);
  /* BRAND LOCKUP — one FIXED treatment, identical on every theme (Bud 2026-07-06:
     the logo NEVER recolors). Derived from the real white-on-black masters in
     Brand/real-logos/; the whole lockup carries its own dark "coin". */
  --kz-coin-bg:#000000;
  --kz-coin-ink:#ffffff;
  --kz-coin-edge:rgba(255,255,255,.18);
  --kz-coin-radius:12px;
  /* motion (DESIGN_SYSTEM.md 6.1; DP-9) */
  --kz-dur-fast:120ms; --kz-dur:200ms; --kz-dur-lg:300ms;
  --kz-ease-decel:cubic-bezier(.16,1,.3,1);           /* enter/settle — strong decelerate */
  --kz-ease-standard:cubic-bezier(.4,0,.2,1);
}
/* ---------- themes (ids stable — they live in users' localStorage) ---------- */
[data-theme="daylight"]{--bg:#f5f7fa;--panel:#ffffff;--panel2:#eef2f7;--line:#d9e0e8;--ink:#1b2733;--mut:#586675;--dim:#93a1b0;--stripe:#2059e0;--on-accent:#ffffff;/* 5.89:1 on accent; accent vs bg 5.49:1 (was #2f6df6: white text 4.53:1 — too close to the wire) */--trace:#2f6df6;--ok:#0f9d68;--warn:#b8690a;--bad:#d8384f;--kz-scrim:rgba(20,28,40,.34);--kz-shadow-1:0 1px 2px rgba(20,28,40,.10);--kz-shadow-2:0 8px 28px -10px rgba(20,28,40,.22);--kz-shadow-pop:0 24px 56px -16px rgba(20,28,40,.30);}
[data-theme="synthwave"]{--bg:#190b2e;--panel:#241141;--panel2:#2d1850;--line:#3d2470;--ink:#f4e9ff;--mut:#a98fd0;--dim:#6b549a;--stripe:#ff5dcd;--on-accent:#190b2e;/* 6.82:1 */--trace:#36e0ff;--ok:#3ddc97;/* DS24: ok stays GREEN in every theme (was cyan #36e0ff = the info color — semantic collision); 9.65:1 on panel */--warn:#ffd24a;--bad:#ff5d8f;--kz-scrim:rgba(10,4,22,.60);}
[data-theme="matrix"]{--bg:#020a04;--panel:#06180c;--panel2:#0a2613;--line:#11401d;--ink:#b6ffb6;--mut:#4f9f5f;--dim:#2f7040;--stripe:#39ff14;--on-accent:#020a04;/* 14.78:1 */--trace:#39ff14;--ok:#39ff14;--warn:#ffd24a;/* DS24: warn stays AMBER in every theme (was lime #c8ff4a — read as a second green); 12.74:1 on panel */--bad:#ff6a6f;--kz-scrim:rgba(1,6,3,.62);}
[data-theme="plumber"]{--bg:#5c94fc;--panel:#ffffff;--panel2:#eaf1ff;--line:#b3c9ee;--ink:#15233f;--mut:#33507e;--dim:#294573;--stripe:#e52521;--on-accent:#ffffff;/* 4.55:1 on accent; accent vs WHITE PANEL 4.55:1 (buttons live on panels; on the raw blue bg the red key reads by shadow+border, luminance-close by theme design) */--trace:#1f9e3a;--ok:#1f9e3a;--warn:#b06f00;--bad:#e52521;--kz-scrim:rgba(8,20,45,.42);--kz-shadow-1:0 1px 2px rgba(8,20,45,.14);--kz-shadow-2:0 10px 30px -10px rgba(8,20,45,.28);--kz-shadow-pop:0 24px 56px -16px rgba(8,20,45,.36);}
[data-theme="dk"]{--bg:#3a9a5c;--panel:#ffffff;--panel2:#e7f2e7;--line:#bcd9bc;--ink:#16280f;--mut:#3c5a30;--dim:#2e4824;--stripe:#d8541f;--on-accent:#120e06;/* 4.77:1 (white was 4.03 — fails; dark glyph on the orange key) */--trace:#7a4a1f;--ok:#2f9e3a;--warn:#c07a00;--bad:#d8541f;--kz-scrim:rgba(10,24,10,.42);--kz-shadow-1:0 1px 2px rgba(10,24,10,.14);--kz-shadow-2:0 10px 30px -10px rgba(10,24,10,.26);--kz-shadow-pop:0 24px 56px -16px rgba(10,24,10,.34);}
[data-theme="brawler"]{--bg:#2b2f3a;--panel:#363b48;--panel2:#424857;--line:#525a6b;--ink:#eef1f6;--mut:#aab2c2;--dim:#7b8496;--stripe:#e8403a;--on-accent:#0a0b0e;/* 4.90:1 (white was 4.02 — fails) */--trace:#ffb02e;--ok:#43c07a;--warn:#ffb02e;--bad:#ff6b62;--kz-scrim:rgba(10,12,18,.56);}
html[data-theme="plumber"]{background:#3cb043}
html[data-theme="dk"]{background:#5a3a1a}

/* ---------- base ---------- */
.kz-body, body.kz{margin:0;padding:0;background:var(--bg);color:var(--ink);
  font-family:"Montserrat","Inter",system-ui,-apple-system,"Segoe UI",sans-serif;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;}
.kz code,.kz .mono,.kz pre{font-family:"JetBrains Mono",ui-monospace,"SF Mono",Menlo,Consolas,monospace;}
.kz ::selection{background:var(--ink);color:var(--bg)}
.kz a{color:var(--ink)}
.kz-body.kz-scroll-lock,body.kz.kz-scroll-lock{overflow:hidden}

/* ---------- BRAND LOCKUP (one FIXED treatment — never recolors per theme) ----------
   Source of truth = real masters in Brand/real-logos/. "kaizen" BOLD, "Logic" THIN
   — Montserrat 800 / 300, NEVER bold on "Logic". Glyph sizes are a deliberate brand
   ramp (24 stacked · 20 horizontal/icon · 18 in-bar · 16 stacked-in-bar). */
.kz-header{border-bottom:1px solid var(--line);padding:22px 28px 0;position:relative;background:var(--bg)}
.kz-brand{display:flex;align-items:center;gap:14px;margin-bottom:16px;flex-wrap:wrap}

/* the coin: shared dark backing for EVERY lockup variant (fixed, theme-independent) */
.kz-coin{display:inline-flex;background:var(--kz-coin-bg);border:1px solid var(--kz-coin-edge);
  border-radius:var(--kz-coin-radius);box-shadow:var(--kz-shadow-1);text-decoration:none;
  transition:transform var(--kz-dur-fast) var(--kz-ease-standard),box-shadow var(--kz-dur) var(--kz-ease-decel)}
a.kz-coin:hover{box-shadow:var(--kz-shadow-2)}
a.kz-coin:active{transform:translateY(.5px)}
.kz-coin .logo{font-family:"Montserrat",system-ui,-apple-system,"Segoe UI",sans-serif;
  color:var(--kz-coin-ink);letter-spacing:-.02em;line-height:.98}
.kz-coin .logo.k{font-weight:800}   /* kaizen — BOLD  */
.kz-coin .logo.l{font-weight:300}   /* Logic  — THIN (acceptable floor 400; never 800) */

/* STACKED = the PRIMARY lockup (Bud 2026-07-06). kaizen over Logic. */
.kz-lockup{display:inline-flex;flex-direction:column;align-items:center;text-align:center;
  padding:8px 18px;text-decoration:none}
.kz-lockup .logo{display:block;font-size:24px}
.kz-lockup .logo.l{margin-top:-1px}

/* HORIZONTAL = the one-row lockup — kaizenLogic on one line (single capital L).
   The APP BAR + hub header default to this (a horizontal lockup sits in a single
   row far more cleanly than the taller stacked coin — DESIGN_SYSTEM §5.3). */
.kz-lockup-h{flex-direction:row;align-items:baseline;padding:8px 16px}
.kz-lockup-h .logo{display:inline;font-size:20px}

/* ICON = kL monogram for the tightest spots / favicon-scale (k bold, L thin) */
.kz-lockup-icon{padding:8px 12px}
.kz-lockup-icon .logo{display:inline;font-size:20px}
.kz-vdiv{width:1px;height:32px;background:var(--line)}
.kz-tagline{color:var(--mut);font-size:var(--kz-fs-hint);letter-spacing:.08em;text-transform:uppercase}
.kz-beta{color:var(--stripe);font-size:var(--kz-fs-micro);letter-spacing:.1em;text-transform:uppercase;
  border:1px solid var(--stripe);border-radius:999px;padding:2px 8px;vertical-align:middle;font-weight:600}
/* L3: --stripe as micro TEXT fails 4.5:1 on the 3 game themes (plumber 1.54-4.55 · dk 1.14-4.03 · brawler 2.28-3.33
   across panel/panel2/bg) — measured overrides below pass ALL three contexts; the other 4 themes' --stripe
   measures >=5.24 everywhere and keeps the accent (DS4 / DS20 pattern) */
[data-theme="plumber"] .kz-beta{color:#15233f;border-color:#15233f} /* 15.62 panel / 13.78 panel2 / 5.28 bg */
[data-theme="dk"] .kz-beta{color:#0d2012;border-color:#0d2012}      /* 17.04 panel / 14.81 panel2 / 4.83 bg */
[data-theme="brawler"] .kz-beta{color:var(--ink);border-color:var(--ink)} /* 9.89 panel / 8.08 panel2 / 11.81 bg */
/* brand tick — a STATIC accent (the auto-sweep was decorative motion; cut for restraint, DP-9) */
.kz-stripe{height:3px;background:var(--stripe);width:44px;margin:16px 0 0;border-radius:2px}

/* ---------- theme picker ---------- */
.kz-themewrap{position:relative;margin-left:auto}
.kz-themebtn{display:inline-flex;align-items:center;gap:8px;background:var(--panel2);color:var(--mut);
  border:1px solid var(--line);border-radius:var(--kz-radius-sm);font:inherit;font-size:var(--kz-fs-label);
  padding:8px 12px;cursor:pointer;
  transition:color var(--kz-dur-fast) var(--kz-ease-standard),border-color var(--kz-dur-fast) var(--kz-ease-standard),background var(--kz-dur-fast) var(--kz-ease-standard)}
.kz-themebtn:hover{color:var(--ink);border-color:var(--dim)}
.kz-themebtn:focus-visible{outline:2px solid var(--stripe);outline-offset:2px}
.kz-themebtn .tlbl{font-size:var(--kz-fs-micro);letter-spacing:.1em;text-transform:uppercase;color:inherit;margin-right:2px} /* L3: --dim failed 4.5:1 on every theme (2.3-2.7); inherit = the button's --mut (+ brawler's own override), measured >=4.97 all themes */
.kz-themebtn .tcar{font-size:var(--kz-fs-micro);opacity:.7;margin-left:1px}
.kz-thememenu{position:absolute;top:calc(100% + 8px);right:0;z-index:60;background:var(--panel);
  border:1px solid var(--line);border-radius:var(--kz-radius);padding:8px;min-width:196px;box-shadow:var(--kz-shadow-pop);
  max-height:min(70vh,440px);overflow:auto;transform-origin:top right;
  animation:kz-menu-in var(--kz-dur) var(--kz-ease-decel)}
@keyframes kz-menu-in{from{opacity:0;transform:translateY(-6px) scale(.98)}to{opacity:1;transform:none}}
.kz-thememenu[hidden]{display:none}
.kz-thememenu button{display:flex;align-items:center;gap:8px;width:100%;background:none;border:0;color:var(--mut);
  font:inherit;font-size:var(--kz-fs-hint);text-align:left;padding:8px 12px;border-radius:var(--kz-radius-sm);cursor:pointer;
  transition:background var(--kz-dur-fast) var(--kz-ease-standard),color var(--kz-dur-fast) var(--kz-ease-standard)}
.kz-thememenu button:hover{background:var(--panel2);color:var(--ink)}
.kz-thememenu button[aria-checked="true"]{color:var(--ink)}
.kz-thememenu button[aria-checked="true"]::after{content:"\2713";margin-left:auto;color:var(--stripe);font-size:var(--kz-fs-label)}

/* ---------- footer (v3: the lockup stands ALONE on a centered brand row — Bud 2026-07-07;
   meta line + theme picker beneath it) ---------- */
/* L36 footer (2026-07-09, Claudio redesign — Bud: "fighting the footer the whole time"):
   ONE calm row. Lockup small + horizontal on the left, meta inline beside it,
   links + theme picker pushed right. Wraps gracefully narrow; never centered,
   never stacked. */
.kz-footer{position:relative;border-top:1px solid var(--line);color:var(--mut);font-size:var(--kz-fs-micro);
  padding:16px 32px;background:var(--bg)}
.kz-footer-row{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.kz-footer-meta{display:inline-flex;align-items:center;min-width:0}
.kz-footer-links{display:inline-flex;align-items:center;gap:14px;margin-left:auto}
@media(max-width:560px){ /* narrow: TWO tidy rows — brand + theme up top, meta beneath (never three staggered lines) */
  .kz-footer{padding:14px 20px}
  .kz-footer-meta{flex-basis:100%;order:3}
  .kz-footer-links a{display:none} /* the lockup IS the home link — the text link is redundant where width is scarce */
}
.kz-footer .kz-lockup-h{flex:0 0 auto}
.kz-footer .kz-lockup-h .logo{font-size:14px}
.kz-footer-theme{display:inline-flex}
.kz-footer-theme .kz-themebtn .tlbl{display:inline}
.kz-footer-theme .kz-thememenu{top:auto;bottom:calc(100% + 8px);transform-origin:bottom right;animation:kz-menu-up var(--kz-dur) var(--kz-ease-decel)}
@keyframes kz-menu-up{from{opacity:0;transform:translateY(6px) scale(.98)}to{opacity:1;transform:none}}
.kz-footer .cta{color:var(--mut)}
.kz-footer .cta a{color:var(--ink);text-decoration:none;border-bottom:1px solid var(--stripe)}
.kz-sigdots{display:inline-flex;gap:4px;margin-right:8px;vertical-align:middle}
.kz-sigdots i{width:6px;height:6px;border-radius:2px;display:inline-block}
.kz-sigdots i:nth-child(1){background:#4f8ef7}.kz-sigdots i:nth-child(2){background:#ef4444}.kz-sigdots i:nth-child(3){background:#cfcfd4}
/* footer brand lockup — small HORIZONTAL coin (L36 2026-07-09; the stacked footer coin is dead) */
.kz-footer .kz-lockup-h{padding:4px 10px}
[data-theme="plumber"] .kz-footer{background:#3cb043;border-top:4px solid #2a7d2f;color:#0c2a08}
[data-theme="plumber"] .kz-footer .cta,[data-theme="plumber"] .kz-footer .cta a{color:#0c2a08;border-bottom-color:#0c2a08}
[data-theme="dk"] .kz-footer{background:#5a3a1a;border-top:4px solid #3a2410;color:#f3e9d8}
[data-theme="dk"] .kz-footer .cta,[data-theme="dk"] .kz-footer .cta a{color:#f3e9d8;border-bottom-color:#f3e9d8}

/* on-colored-bg taglines: plumber/dk backgrounds need darker text than --mut (WCAG AA) */
[data-theme="plumber"] .kz-tagline{color:#15233f}
[data-theme="dk"] .kz-tagline{color:#0d2012}
[data-theme="brawler"] .kz-themebtn{color:#b8c0cf}

/* =====================================================================
   kz- component kit — tokens are the single source for type + spacing.
   ===================================================================== */

/* ---------- type scale ---------- */
:root{
  --kz-fs-display:clamp(32px,5.4vw,52px);  /* hero */
  --kz-fs-h1:28px;                          /* console page title (kz-canvas h1) — DS25 */
  --kz-fs-title:22px;                       /* section statement (= h2 step) */
  --kz-fs-h2:22px;
  --kz-fs-lead:18px;                        /* marketing lead: hero sub / section lead (the step above lg) */
  --kz-fs-h3:17px;
  --kz-fs-lg:16px;
  --kz-fs-body:16px;
  --kz-fs-sm:14px;
  --kz-fs-hint:13px;
  --kz-fs-label:12px;
  --kz-fs-micro:11px;                       /* uppercase micro-labels (beta / theme / appearance / footer) */
  --kz-fw-normal:400;
  --kz-fw-medium:500;
  --kz-fw-semibold:600;
  --kz-fw-bold:700;
  --kz-fw-black:800;
  --kz-lh-tight:1.06;      /* display */
  --kz-lh-snug:1.3;        /* headings */
  --kz-lh-body:1.6;        /* body */
  --kz-tr-tight:-.03em;    /* display/wordmark optical tightening */
  --kz-tr-label:.14em;
}

/* ---------- spacing scale (one rhythm everywhere) ---------- */
:root{
  --kz-space-1:4px;
  --kz-space-2:8px;
  --kz-space-3:12px;
  --kz-space-4:16px;
  --kz-space-5:24px;      /* layout ramp (DESIGN_SYSTEM §3) */
  --kz-space-6:32px;
  --kz-space-7:48px;
  --kz-space-8:64px;
  --kz-space-9:96px;
  --kz-touch:22px;        /* tap-ergonomic insertion (arm's-length reading) */
  --kz-tap:44px;          /* minimum tap target (Fisher-Price / Apple HIG) */
  --kz-gap:14px;          /* default grid/flex gap */
  --kz-pad:18px;          /* default card/panel padding */
  --kz-radius:10px;       /* default corner (cards/menus) — DECISIONS DS6 */
  --kz-radius-sm:8px;     /* buttons / inputs / chips */
  --kz-col:880px;         /* standard content column */
  --kz-ctrl:36px;         /* compact control height (nav link / .kz-btn-sm) */
  --kz-bar-h:60px;        /* app-bar height, used to offset the mobile drawer */
}

/* ---------- kz-appbar: the shared cross-nav bar (injected by kaizen.js) ----------
   Desktop: [ lockup -> home ] [ app switcher ] ····· [ (cta) ] [ theme toggle ]
   Mobile : [ lockup -> home ] ················· [ burger ]     — nothing else in the bar. */
.kz-appbar{display:flex;align-items:center;gap:var(--kz-space-4);
  padding:8px max(32px,calc(50% - 560px));min-height:var(--kz-bar-h);
  border-bottom:1px solid var(--line);background:color-mix(in srgb,var(--bg) 86%,transparent);
  -webkit-backdrop-filter:saturate(1.4) blur(14px);backdrop-filter:saturate(1.4) blur(14px);
  position:sticky;top:0;z-index:50}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .kz-appbar{background:var(--bg)}
}
.kz-appbar .kz-appbrand{flex:0 0 auto;text-decoration:none;white-space:nowrap;padding:8px 12px}
.kz-appbar .kz-appbrand .logo{font-size:18px}
.kz-appbar .kz-appbrand.kz-lockup .logo{font-size:16px}   /* stacked, if a surface opts in */
/* app switcher: dead-simple horizontal-scroll link row */
.kz-appswitch{display:flex;align-items:center;gap:var(--kz-space-1);overflow-x:auto;-webkit-overflow-scrolling:touch;
  scrollbar-width:none;flex:1 1 auto;min-width:0}
.kz-appswitch::-webkit-scrollbar{display:none}
.kz-appswitch a{display:inline-flex;align-items:center;min-height:var(--kz-ctrl);padding:8px 12px;border-radius:var(--kz-radius-sm);
  color:var(--mut);text-decoration:none;font-size:var(--kz-fs-sm);font-weight:var(--kz-fw-medium);white-space:nowrap;
  transition:color var(--kz-dur-fast) var(--kz-ease-standard),background var(--kz-dur-fast) var(--kz-ease-standard)}
.kz-appswitch a:hover{color:var(--ink);background:var(--panel2)}
.kz-appswitch a[aria-current="page"]{color:var(--ink);background:var(--panel2);font-weight:var(--kz-fw-semibold)}
.kz-appswitch a[aria-current="page"]::before{content:"";width:6px;height:6px;border-radius:2px;background:var(--stripe);margin-right:8px}
/* hamburger toggle — only shown on narrow viewports */
.kz-appmenu-btn{display:none;align-items:center;justify-content:center;width:var(--kz-tap);height:var(--kz-tap);
  background:transparent;border:1px solid var(--line);border-radius:var(--kz-radius-sm);color:var(--ink);
  cursor:pointer;flex:0 0 auto;padding:0;transition:background var(--kz-dur-fast) var(--kz-ease-standard),border-color var(--kz-dur-fast) var(--kz-ease-standard)}
.kz-appmenu-btn:hover{background:var(--panel2)}
.kz-appmenu-btn:active{background:var(--panel2)}
.kz-appmenu-btn:focus-visible{outline:2px solid var(--stripe);outline-offset:2px}
/* crisp 2-line glyph (rotates/fades into an X when open) — no emoji hamburger */
.kz-burger-glyph{position:relative;width:18px;height:12px;display:block}
.kz-burger-glyph::before,.kz-burger-glyph::after{content:"";position:absolute;left:0;right:0;height:2px;border-radius:2px;
  background:currentColor;transition:transform var(--kz-dur) var(--kz-ease-decel),opacity var(--kz-dur-fast) linear}
.kz-burger-glyph::before{top:2px}.kz-burger-glyph::after{bottom:2px}

/* the drawer wrapper: on desktop it lays out inline (switcher + cta + theme pinned right).
   On mobile it becomes a real OVERLAY SHEET (scrim + slide), so the bar is ONLY lockup+burger. */
.kz-appnav{display:flex;align-items:center;gap:var(--kz-space-4);flex:1 1 auto;min-width:0}
.kz-appnav .kz-themewrap{margin-left:auto}
.kz-appbar .kz-beta{flex:0 0 auto;align-self:center;line-height:1}
/* optional primary CTA in the bar/drawer (data-kaizen-cta on <body>) — a compact bar button on
   desktop, a full-width primary in the mobile sheet. Only for surfaces WITHOUT the app switcher
   (the switcher's own Portal tab is the door on tool surfaces — don't double up). */
.kz-appcta{display:none}
.kz-appnav > .kz-appcta{display:inline-flex;flex:0 0 auto}

/* the scrim — one shared element, sits under the sheet on mobile */
.kz-scrim{position:fixed;inset:0;z-index:45;background:var(--kz-scrim);opacity:0;visibility:hidden;
  -webkit-backdrop-filter:blur(1px);backdrop-filter:blur(1px);
  transition:opacity var(--kz-dur-lg) var(--kz-ease-decel),visibility var(--kz-dur-lg)}
.kz-scrim[data-show="1"]{opacity:1;visibility:visible}

@media(max-width:640px){
  .kz-appbar{padding:8px 24px}
  .kz-appmenu-btn{display:inline-flex;margin-left:auto}
  .kz-appbar[data-open="1"] .kz-burger-glyph::before{top:5px;transform:rotate(45deg)}
  .kz-appbar[data-open="1"] .kz-burger-glyph::after{bottom:5px;transform:rotate(-45deg)}
  /* the sheet: a fixed panel that slides down from under the bar, full width */
  .kz-appnav{position:fixed;left:0;right:0;top:var(--kz-bar-h);z-index:48;
    flex-direction:column;align-items:stretch;gap:0;
    padding:var(--kz-space-5) var(--kz-space-5) calc(env(safe-area-inset-bottom,0px) + var(--kz-space-5));
    background:var(--panel);border-bottom:1px solid var(--line);box-shadow:var(--kz-shadow-pop);
    max-height:calc(100dvh - var(--kz-bar-h));overflow:auto;
    transform:translateY(-16px);opacity:0;visibility:hidden;pointer-events:none;
    transition:transform var(--kz-dur-lg) var(--kz-ease-decel),opacity var(--kz-dur) var(--kz-ease-decel),visibility var(--kz-dur-lg)}
  .kz-appbar[data-open="1"] .kz-appnav{transform:none;opacity:1;visibility:visible;pointer-events:auto}
  /* nav rows: big, calm, tappable */
  .kz-appnav .kz-appswitch{flex-direction:column;align-items:stretch;overflow:visible;gap:var(--kz-space-1);width:100%}
  .kz-appnav .kz-appswitch a{min-height:48px;font-size:var(--kz-fs-lg);padding:0 16px;border-radius:var(--kz-radius)}
  /* primary CTA — one clear door, full width */
  .kz-appnav > .kz-appcta{display:flex;width:100%;min-height:var(--kz-tap);margin-top:var(--kz-space-4)}
  /* theme picker — a PREFERENCE, tucked at the very bottom under a divider */
  .kz-appnav .kz-themewrap{margin:var(--kz-space-5) 0 0;padding-top:var(--kz-space-4);
    border-top:1px solid var(--line);width:100%}
  .kz-appnav .kz-themewrap::before{content:"Appearance";display:block;font-size:var(--kz-fs-micro);letter-spacing:.1em;
    text-transform:uppercase;color:var(--dim);margin-bottom:var(--kz-space-2)}
  .kz-appnav .kz-themebtn{width:100%;justify-content:flex-start;min-height:var(--kz-tap);border-radius:var(--kz-radius)}
  .kz-appnav .kz-thememenu{position:static;box-shadow:none;border:0;padding:8px 0 0;min-width:0;animation:none;max-height:none}
  .kz-appnav .kz-beta{align-self:flex-start;margin-top:var(--kz-space-3)}
}
[data-theme="plumber"] .kz-appbar,[data-theme="dk"] .kz-appbar{border-bottom-width:2px}

/* ---------- kz-card ---------- */
.kz-card{background:var(--panel);border:1px solid var(--line);border-radius:var(--kz-radius);
  padding:var(--kz-pad);color:var(--ink);font-size:var(--kz-fs-body);line-height:var(--kz-lh-body)}
.kz-card > h3,.kz-card-title{margin:0 0 var(--kz-space-2);font-size:var(--kz-fs-h3);font-weight:var(--kz-fw-bold);
  line-height:var(--kz-lh-snug);color:var(--ink)}
.kz-card-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:var(--kz-space-4)}
/* interactive card affordance (opt-in via .kz-card-link) — calm lift, no bounce */
a.kz-card-link{display:block;text-decoration:none;color:var(--ink);
  transition:border-color var(--kz-dur) var(--kz-ease-decel),transform var(--kz-dur) var(--kz-ease-decel),box-shadow var(--kz-dur) var(--kz-ease-decel),background var(--kz-dur) var(--kz-ease-decel)}
a.kz-card-link:hover{border-color:color-mix(in srgb,var(--stripe) 60%,var(--line));transform:translateY(-2px);
  box-shadow:0 0 0 1px color-mix(in srgb,var(--stripe) 55%,transparent),0 10px 30px -6px color-mix(in srgb,var(--stripe) 55%,transparent)}
a.kz-card-link:active{transform:translateY(0);box-shadow:0 0 0 1px color-mix(in srgb,var(--stripe) 55%,transparent),inset 0 0 24px -12px color-mix(in srgb,var(--stripe) 45%,transparent)}
a.kz-card-link:active{transform:translateY(0)}
a.kz-card-link:focus-visible{outline:2px solid var(--stripe);outline-offset:2px}

/* ---------- kz-btn — ONE scale: 44 default, 36 compact (.kz-btn-sm) ---------- */
.kz-btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--kz-space-2);
  min-height:var(--kz-tap);padding:12px 24px;border-radius:var(--kz-radius-sm);border:1px solid var(--line);
  background:var(--panel2);color:var(--ink);font:inherit;font-size:var(--kz-fs-body);font-weight:var(--kz-fw-semibold);
  line-height:1;cursor:pointer;text-decoration:none;letter-spacing:.005em;
  transition:transform var(--kz-dur-fast) var(--kz-ease-standard),background var(--kz-dur-fast) var(--kz-ease-standard),border-color var(--kz-dur-fast) var(--kz-ease-standard),box-shadow var(--kz-dur) var(--kz-ease-decel)}
.kz-btn:hover{transform:translateY(-1px)}
.kz-btn:active{transform:translateY(0)}
.kz-btn:focus-visible{outline:2px solid var(--stripe);outline-offset:2px}
.kz-btn:disabled,.kz-btn[aria-disabled="true"]{opacity:.5;cursor:not-allowed;transform:none}
/* compact — bar/toolbar contexts. Same radius + weight, smaller box. */
.kz-btn-sm{min-height:var(--kz-ctrl);padding:8px 16px;font-size:var(--kz-fs-sm)}
.kz-btn-primary{background:var(--stripe);border-color:var(--stripe);color:var(--on-accent);box-shadow:var(--kz-shadow-1)}
.kz-btn-primary:hover{box-shadow:var(--kz-shadow-2)}
.kz-btn-secondary{background:var(--panel2);border-color:var(--dim);color:var(--ink)}
.kz-btn-secondary:hover{border-color:var(--ink)}
.kz-btn-ghost{background:transparent;border-color:transparent;color:var(--mut)}
.kz-btn-ghost:hover{background:var(--panel2);color:var(--ink)}
.kz a.kz-btn{color:var(--ink)}
.kz a.kz-btn-primary{color:var(--on-accent)}
.kz a.kz-btn-ghost{color:var(--mut)}

/* ---------- kz-toolbar ---------- */
.kz-toolbar{display:flex;align-items:center;gap:var(--kz-space-2);flex-wrap:wrap;
  padding:var(--kz-space-3) 0;border-bottom:1px solid var(--line)}
.kz-toolbar .kz-toolbar-spacer{flex:1 1 auto}
.kz-toolbar .kz-toolbar-group{display:flex;align-items:center;gap:var(--kz-space-2);flex-wrap:wrap}

/* ---------- kz-tabs ---------- */
.kz-tabs{display:flex;align-items:stretch;gap:var(--kz-space-1);overflow-x:auto;scrollbar-width:none;
  border-bottom:1px solid var(--line)}
.kz-tabs::-webkit-scrollbar{display:none}
.kz-tab{display:inline-flex;align-items:center;min-height:var(--kz-tap);padding:8px 16px;border:0;
  background:transparent;color:var(--mut);font:inherit;font-size:var(--kz-fs-body);font-weight:var(--kz-fw-medium);
  cursor:pointer;white-space:nowrap;border-bottom:2px solid transparent;margin-bottom:-1px;transition:color var(--kz-dur-fast) var(--kz-ease-standard)}
.kz-tab:hover{color:var(--ink)}
.kz-tab[aria-selected="true"],.kz-tab.is-active{color:var(--ink);font-weight:var(--kz-fw-semibold);border-bottom-color:var(--stripe)}
.kz-tab:focus-visible{outline:2px solid var(--stripe);outline-offset:-2px}

/* ---------- kz-details (styled disclosure) ---------- */
.kz-details{border:1px solid var(--line);border-radius:var(--kz-radius);background:var(--panel);overflow:hidden}
.kz-details > summary{list-style:none;cursor:pointer;padding:var(--kz-space-3) var(--kz-pad);
  font-size:var(--kz-fs-body);font-weight:var(--kz-fw-semibold);color:var(--ink);
  display:flex;align-items:center;gap:var(--kz-space-2);min-height:var(--kz-tap)}
.kz-details > summary::-webkit-details-marker{display:none}
.kz-details > summary::after{content:"▾";margin-left:auto;color:var(--mut);font-size:var(--kz-fs-label);transition:transform var(--kz-dur) var(--kz-ease-decel)}
.kz-details[open] > summary::after{transform:rotate(180deg)}
.kz-details > summary:focus-visible{outline:2px solid var(--stripe);outline-offset:-2px}
.kz-details .kz-details-body{padding:0 var(--kz-pad) var(--kz-space-3);color:var(--ink);
  font-size:var(--kz-fs-body);line-height:var(--kz-lh-body)}

/* ---------- kz-icon (DS19: icon-forward, glanceable) ----------
   Sprite is injected by kaizen.js (id #kzIcons). Usage:
     <svg class="kz-icon" aria-hidden="true"><use href="#kz-i-layers"/></svg>
   Inherits currentColor -> themeable for free. Sizes: 20 default / 16 sm / 24 lg. */
.kz-icon{width:20px;height:20px;flex:0 0 auto;fill:none;stroke:currentColor;
  stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round;vertical-align:-4px}
.kz-icon-sm{width:16px;height:16px;stroke-width:2;vertical-align:-3px}
.kz-icon-lg{width:24px;height:24px;stroke-width:1.6}
.kz-icon-accent{color:var(--stripe)}
/* icon chip — the glanceable anchor for cards/tiles (a lit key, not a decoration) */
.kz-iconchip{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;
  border-radius:var(--kz-radius-sm);background:color-mix(in srgb,var(--stripe) 12%,var(--panel2));
  color:var(--stripe);border:1px solid color-mix(in srgb,var(--stripe) 22%,var(--line))}
.kz-iconchip .kz-icon{width:18px;height:18px}
/* icon list — icon + short label rows (replaces bullet walls; DS19) */
.kz-iconlist{list-style:none;margin:var(--kz-space-2) 0 2px;padding:0;display:grid;gap:var(--kz-space-3)}
.kz-iconlist li{display:flex;gap:var(--kz-space-3);align-items:flex-start;margin:0}
.kz-iconlist .kz-icon{margin-top:2px;color:var(--stripe)}
.kz-iconlist b{color:var(--ink);font-weight:var(--kz-fw-semibold)}

/* ---------- kz-hint ---------- */
.kz-hint{color:var(--mut);font-size:var(--kz-fs-hint);line-height:var(--kz-lh-snug)}
/* Flash messages — status lines that must be SEEN (VC9/DS21 era, 2026-07-08).
   Use .kz-flash for errors/blockers, .kz-flash-ok for confirmations; swap back
   to .kz-meta/.kz-hint for neutral status. Pair with aria-invalid on the field. */
.kz-flash{color:var(--bad);font-size:var(--kz-fs-sm);font-weight:var(--kz-fw-bold)}
.kz-flash-ok{color:var(--ok);font-size:var(--kz-fs-sm);font-weight:var(--kz-fw-bold)}
input[aria-invalid="true"],select[aria-invalid="true"],textarea[aria-invalid="true"]{outline:2px solid var(--bad);outline-offset:1px}
[data-theme="plumber"] .kz-hint{color:#15233f}
[data-theme="dk"] .kz-hint{color:#0d2012}

/* ---------- AA on colored backgrounds (plumber/dk have colored --bg) ---------- */
[data-theme="plumber"] .kz-appswitch a{color:#15233f}
[data-theme="plumber"] .kz-tab{color:#15233f}
[data-theme="dk"] .kz-appswitch a{color:#0d2012}
[data-theme="dk"] .kz-tab{color:#0d2012}
[data-theme="plumber"] .kz-appswitch a[aria-current="page"],[data-theme="plumber"] .kz-tab[aria-selected="true"],[data-theme="plumber"] .kz-tab.is-active{color:var(--ink)}
[data-theme="dk"] .kz-appswitch a[aria-current="page"]{color:var(--ink)}
[data-theme="dk"] .kz-tab[aria-selected="true"],[data-theme="dk"] .kz-tab.is-active{color:#0d2012}
@media(max-width:640px){
  [data-theme="plumber"] .kz-appnav .kz-appswitch a,[data-theme="dk"] .kz-appnav .kz-appswitch a{color:var(--ink)}
}

/* =====================================================================
   kz v4 — ELEMENT GRAMMAR (UI lock-in pass 2026-07-09, model: claude-fable-5)
   DECISIONS DS23 · spec DESIGN_SYSTEM 7.1 · evidence DESIGN_RESEARCH Parts E/F.
   ALL additive. Each component ENCODES its user-consensus rules:
   chips = tint bg + ink text + dot, sentence-case adjectives, never clickable
   (GOV.UK); timeline = vertical/reverse-chron/plain-language (NN/g); tables =
   mono tabular numerals + row hover + load-more (NN/g/Baymard); empty state
   NEVER renders while loading (skeleton instead); labels above fields, 16px
   inputs, blur validation (Penzo/Baymard/GOV.UK). No toast component — ever:
   feedback is inline (kz-flash). Cmd-K rejected estate-wide (BM5).
   ===================================================================== */

/* ---------- kz-chip: THE status element ---------- */
.kz-chip{display:inline-flex;align-items:center;gap:7px;padding:3px 10px;border-radius:999px;
  background:var(--panel2);color:var(--ink);border:1px solid var(--line);
  font-size:var(--kz-fs-hint);font-weight:var(--kz-fw-semibold);line-height:1.4;white-space:nowrap}
.kz-chip::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--mut);flex:0 0 auto}
.kz-chip-ok{background:color-mix(in srgb,var(--ok) 13%,var(--panel2));border-color:color-mix(in srgb,var(--ok) 30%,var(--line))}
.kz-chip-ok::before{background:var(--ok)}
.kz-chip-warn{background:color-mix(in srgb,var(--warn) 14%,var(--panel2));border-color:color-mix(in srgb,var(--warn) 32%,var(--line))}
.kz-chip-warn::before{background:var(--warn)}
.kz-chip-bad{background:color-mix(in srgb,var(--bad) 13%,var(--panel2));border-color:color-mix(in srgb,var(--bad) 30%,var(--line))}
.kz-chip-bad::before{background:var(--bad)}
.kz-chip-info{background:color-mix(in srgb,var(--trace) 13%,var(--panel2));border-color:color-mix(in srgb,var(--trace) 30%,var(--line))}
.kz-chip-info::before{background:var(--trace)}
/* filter chip = the ONE interactive chip: carries a visible dismiss glyph */
button.kz-chip{cursor:pointer;font:inherit;font-size:var(--kz-fs-hint);font-weight:var(--kz-fw-semibold)}
button.kz-chip .x{color:var(--mut);font-weight:400;margin-left:2px}
button.kz-chip:hover .x{color:var(--ink)}
button.kz-chip:focus-visible{outline:2px solid var(--stripe);outline-offset:2px}

/* ---------- kz-timeline: vertical event history ---------- */
.kz-timeline{list-style:none;margin:0;padding:0}
.kz-timeline > li{position:relative;padding:0 0 var(--kz-space-4) 26px}
.kz-timeline > li::before{content:"";position:absolute;left:0;top:5px;width:9px;height:9px;border-radius:50%;
  background:var(--mut);border:2px solid var(--panel);box-shadow:0 0 0 1px var(--line)}
.kz-timeline > li::after{content:"";position:absolute;left:4px;top:20px;bottom:2px;width:1px;background:var(--line)}
.kz-timeline > li:last-child{padding-bottom:0}
.kz-timeline > li:last-child::after{display:none}
.kz-timeline > li.ok::before{background:var(--ok)}
.kz-timeline > li.warn::before{background:var(--warn)}
.kz-timeline > li.bad::before{background:var(--bad)}
.kz-timeline > li.info::before{background:var(--trace)}
.kz-timeline .kz-tl-head{display:flex;align-items:baseline;gap:var(--kz-space-2);flex-wrap:wrap}
.kz-timeline .kz-tl-head b{font-size:var(--kz-fs-sm);font-weight:var(--kz-fw-semibold);color:var(--ink)}
.kz-timeline .kz-tl-head time,.kz-timeline .kz-tl-head .t{color:var(--mut);font-size:var(--kz-fs-hint)}
.kz-timeline .kz-tl-detail{margin:2px 0 0;color:var(--mut);font-size:var(--kz-fs-hint);line-height:var(--kz-lh-snug)}

/* ---------- kz-list / kz-row: the list->detail row ---------- */
.kz-list{list-style:none;margin:0;padding:0;border:1px solid var(--line);border-radius:var(--kz-radius);
  background:var(--panel);overflow:hidden}
.kz-row{display:flex;align-items:center;gap:var(--kz-space-3);min-height:var(--kz-tap);
  padding:var(--kz-space-3) var(--kz-pad);border-bottom:1px solid var(--line);
  color:var(--ink);text-decoration:none;font-size:var(--kz-fs-body)}
.kz-list > li:last-child > .kz-row,.kz-list > .kz-row:last-child{border-bottom:0}
a.kz-row,button.kz-row{cursor:pointer;transition:background var(--kz-dur-fast) var(--kz-ease-standard);width:100%;
  background:transparent;border-left:0;border-right:0;border-top:0;font:inherit;text-align:left}
a.kz-row:hover,button.kz-row:hover{background:var(--panel2)}
a.kz-row:focus-visible,button.kz-row:focus-visible{outline:2px solid var(--stripe);outline-offset:-2px}
.kz-row-main{flex:1 1 auto;min-width:0}
.kz-row-title{display:block;font-weight:var(--kz-fw-semibold);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kz-row-sub{display:block;color:var(--mut);font-size:var(--kz-fs-hint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kz-row-meta{display:flex;align-items:center;gap:var(--kz-space-2);margin-left:auto;flex:0 0 auto;
  color:var(--mut);font-size:var(--kz-fs-hint);white-space:nowrap}

/* ---------- kz-table: data table + kz-num numerals ---------- */
.kz-tablewrap{overflow-x:auto;border:1px solid var(--line);border-radius:var(--kz-radius);background:var(--panel);
  background-image:linear-gradient(to right,var(--panel),var(--panel)),linear-gradient(to right,var(--panel),var(--panel)),
    linear-gradient(to right,var(--kz-scrim),transparent),linear-gradient(to left,var(--kz-scrim),transparent);
  background-position:left center,right center,left center,right center;
  background-repeat:no-repeat;background-size:24px 100%,24px 100%,12px 100%,12px 100%;
  background-attachment:local,local,scroll,scroll}
.kz-table{width:100%;border-collapse:collapse;font-size:var(--kz-fs-sm)}
.kz-table th{text-align:left;padding:10px var(--kz-pad);border-bottom:1px solid var(--line);
  font-size:var(--kz-fs-micro);font-weight:var(--kz-fw-semibold);letter-spacing:.1em;text-transform:uppercase;color:var(--mut)}
.kz-table td{padding:10px var(--kz-pad);border-bottom:1px solid var(--line);color:var(--ink);vertical-align:middle}
.kz-table tbody tr:last-child td{border-bottom:0}
.kz-table tbody tr:hover td{background:var(--panel2)}
.kz-num{font-family:"JetBrains Mono",ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  font-variant-numeric:tabular-nums;text-align:right}
th.kz-num,td.kz-num{text-align:right}

/* ---------- kz-empty: teach-the-next-action (NEVER while loading) ---------- */
.kz-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;
  gap:var(--kz-space-3);padding:var(--kz-space-8) var(--kz-space-5);color:var(--mut)}
.kz-empty .kz-icon{width:28px;height:28px;color:var(--dim);stroke-width:1.5}
.kz-empty b{color:var(--ink);font-size:var(--kz-fs-h3);font-weight:var(--kz-fw-bold)}
.kz-empty p{margin:0;font-size:var(--kz-fs-sm);line-height:var(--kz-lh-snug);max-width:38ch}
.kz-empty .kz-btn{margin-top:var(--kz-space-2)}

/* ---------- kz-skeleton: content-load placeholder (replaces spinners) ---------- */
.kz-skeleton{position:relative;overflow:hidden;background:var(--panel2);border-radius:var(--kz-radius-sm)}
.kz-skeleton::after{content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--ink) 7%,transparent),transparent);
  animation:kz-shimmer 1.4s var(--kz-ease-standard) infinite}
@keyframes kz-shimmer{to{transform:translateX(100%)}}
.kz-skeleton-line{height:14px;margin:10px 0}
.kz-skeleton-block{height:72px;margin:10px 0}

/* ---------- kz-field: form anatomy (label ABOVE, 16px inputs, blur validation) ---------- */
.kz-field{display:flex;flex-direction:column;gap:6px;margin:0 0 var(--kz-space-4)}
.kz-field > label{font-size:var(--kz-fs-sm);font-weight:var(--kz-fw-medium);color:var(--ink)}
.kz-input,.kz-select,.kz-textarea{font:inherit;font-size:var(--kz-fs-body);width:100%;box-sizing:border-box;
  background:var(--panel2);color:var(--ink);border:1px solid var(--line);border-radius:var(--kz-radius-sm);
  padding:10px 14px;min-height:var(--kz-tap);
  transition:border-color var(--kz-dur-fast) var(--kz-ease-standard)}
.kz-input::placeholder,.kz-textarea::placeholder{color:var(--dim)}
.kz-input:hover,.kz-select:hover,.kz-textarea:hover{border-color:var(--dim)}
.kz-input:focus-visible,.kz-select:focus-visible,.kz-textarea:focus-visible{outline:2px solid var(--stripe);outline-offset:1px;border-color:var(--stripe)}
.kz-textarea{min-height:88px;resize:vertical;line-height:var(--kz-lh-body)}
.kz-field .kz-hint{margin:0}

/* ---------- kz-stat: KPI glance tile (ONE number; no gauges, ever) ---------- */
.kz-stat{display:flex;flex-direction:column;gap:4px;padding:var(--kz-pad);
  background:var(--panel);border:1px solid var(--line);border-radius:var(--kz-radius)}
.kz-stat .kz-stat-l{font-size:var(--kz-fs-micro);font-weight:var(--kz-fw-semibold);letter-spacing:.1em;
  text-transform:uppercase;color:var(--mut)}
.kz-stat .kz-stat-v{font-size:var(--kz-fs-title);font-weight:var(--kz-fw-black);color:var(--ink);
  font-variant-numeric:tabular-nums;letter-spacing:-.01em;line-height:1.1}
.kz-stat .kz-stat-d{font-size:var(--kz-fs-hint);color:var(--mut)}
.kz-stat .kz-stat-d.up{color:var(--ok)}
.kz-stat .kz-stat-d.down{color:var(--bad)}

/* ---------- kz-steps: wizard step indicator (setup flows ONLY) ---------- */
.kz-steps{list-style:none;display:flex;align-items:center;gap:var(--kz-space-4);flex-wrap:wrap;
  margin:0 0 var(--kz-space-5);padding:0;counter-reset:kzstep}
.kz-steps > li{counter-increment:kzstep;display:inline-flex;align-items:center;gap:8px;
  color:var(--mut);font-size:var(--kz-fs-sm);font-weight:var(--kz-fw-medium)}
.kz-steps > li::before{content:counter(kzstep);width:24px;height:24px;border-radius:50%;flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--line);background:var(--panel2);color:var(--mut);
  font-size:var(--kz-fs-micro);font-weight:var(--kz-fw-semibold)}
.kz-steps > li[aria-current="step"]{color:var(--ink);font-weight:var(--kz-fw-semibold)}
.kz-steps > li[aria-current="step"]::before{background:var(--stripe);border-color:var(--stripe);color:var(--on-accent)}
.kz-steps > li.done{color:var(--mut)}
.kz-steps > li.done::before{content:"\2713";background:color-mix(in srgb,var(--ok) 15%,var(--panel2));
  border-color:color-mix(in srgb,var(--ok) 40%,var(--line));color:var(--ok)}

/* ---------- kz-envnote: environment honesty (theme-INDEPENDENT, like the coin) ----------
   Injected by kaizen.js from body[data-kaizen-env]; DS16 made visible. Fixed amber:
   #231603 on #f5b14c = 9.4:1. Never themed - it is a signal, not content. */
.kz-envnote{position:fixed;bottom:16px;left:50%;transform:translateX(-50%);z-index:70;
  background:#f5b14c;color:#231603;border:1px solid #b97f14;border-radius:999px;
  padding:7px 16px;font-size:var(--kz-fs-micro);font-weight:var(--kz-fw-bold);
  letter-spacing:.1em;text-transform:uppercase;box-shadow:var(--kz-shadow-2);pointer-events:none;white-space:nowrap}

/* ---------- kz-shell: the CONSOLE chrome (DS25 two-tier, 2026-07-09) ----------
   Ecosystem/product surfaces (hub, portal) = left rail + canvas; marketing keeps
   its top-nav page. Rail rows: icon+label, selection = bg pill + ink shift ONLY
   (never bolds -> zero text reflow). Page authors the markup; kaizen.js skips the
   injected appbar when body[data-kaizen-chrome="shell"]. Mobile: rail becomes a
   burger sheet (visible-nav is a desktop rule). */
.kz-shell{display:grid;grid-template-columns:236px minmax(0,1fr);min-height:100dvh;align-items:start}
.kz-rail{display:flex;flex-direction:column;gap:2px;padding:14px 12px calc(env(safe-area-inset-bottom,0px) + 14px);
  border-right:1px solid var(--line);position:sticky;top:0;height:100dvh;overflow:auto;box-sizing:border-box}
.kz-rail-brand{display:flex;align-items:center;padding:2px 4px 12px}
.kz-rail-brand .kz-coin{text-decoration:none}
.kz-rail-brand .logo{font-size:16px}
.kz-rail nav{display:flex;flex-direction:column;gap:2px}
/* row rules scoped to nav/foot so the BRAND anchor is never restyled (BL1: no gap in kaizenLogic) */
.kz-rail nav a,.kz-rail-foot a{display:flex;align-items:center;gap:10px;min-height:34px;padding:0 10px;border-radius:var(--kz-radius);
  color:var(--mut);text-decoration:none;font-size:var(--kz-fs-sm);font-weight:var(--kz-fw-medium);
  transition:background var(--kz-dur-fast) var(--kz-ease-standard),color var(--kz-dur-fast) var(--kz-ease-standard)}
.kz-rail nav a:hover,.kz-rail-foot a:hover{background:var(--panel2);color:var(--ink)}
.kz-rail nav a[aria-current="page"]{background:var(--panel2);color:var(--ink)} /* NO weight change — reflow-free (DS25) */
.kz-rail nav a:focus-visible,.kz-rail-foot a:focus-visible{outline:2px solid var(--stripe);outline-offset:-2px}
.kz-rail nav .kz-icon,.kz-rail-foot .kz-icon{width:18px;height:18px;flex:0 0 auto}
/* DS26 THE ONE RAIL: the current app's row expands to expose its sections as
   indented sub-rows (kit-injected app group + page-registered sections).
   Sub-rows: hint-size, indented under the app label; active = pill + accent
   submark (inset bar) — still NO weight change (reflow-free law). When sections
   are present the app row drops its pill (ink only); the pill lives on the
   active sub-row. */
.kz-rail nav a[data-current="1"]{color:var(--ink)}
.kz-rail-sub{display:flex;flex-direction:column;gap:1px;margin:2px 0 6px 28px}
.kz-rail-sub[hidden]{display:none}
.kz-rail .kz-rail-sub a{min-height:30px;padding:0 8px;font-size:var(--kz-fs-hint);min-width:0}
.kz-rail .kz-rail-sub a > span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0} /* long item names truncate, never wrap into blobs (full name = title tooltip) */
.kz-rail-sub-label{font-size:10px;font-weight:var(--kz-fw-semibold);letter-spacing:.09em;text-transform:uppercase;color:var(--dim);padding:6px 8px 2px} /* group label — dummy-proof: says what the sub-rows ARE */
.kz-rail-sub-gap{border-top:1px solid var(--line);margin:6px 8px 2px} /* items ↑ / actions ↓ divider */
.kz-rail .kz-rail-sub a .kz-icon{width:15px;height:15px}
.kz-rail .kz-rail-sub a[aria-current="page"]{background:var(--panel2);color:var(--ink);box-shadow:inset 2px 0 0 0 var(--stripe)}
.kz-rail-foot{margin-top:auto;padding-top:12px;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:2px}
.kz-rail-foot:empty{display:none} /* no pill, no line — the separator only exists when something sits under it */
/* game-theme GROUND BAND (Bud 2026-07-09: consoles lost the marketing footer's themed
   ground when shells dropped the footer — the rail-foot IS the console's ground).
   Same pairs as the .kz-footer bands (WCAG-passed there); bleeds through the rail's
   own padding to its edges. The games launcher stands just ABOVE this band. */
[data-theme="plumber"] .kz-rail-foot,[data-theme="dk"] .kz-rail-foot{
  margin-left:-12px;margin-right:-12px;margin-bottom:calc(-1*(env(safe-area-inset-bottom,0px) + 14px));
  padding:12px 12px calc(env(safe-area-inset-bottom,0px) + 14px)}
[data-theme="plumber"] .kz-rail-foot{background:#3cb043;border-top:4px solid #2a7d2f}
[data-theme="dk"] .kz-rail-foot{background:#5a3a1a;border-top:4px solid #3a2410}
[data-theme="plumber"] .kz-rail-foot a{color:#0c2a08}
[data-theme="dk"] .kz-rail-foot a{color:#f3e9d8}
/* theme picker LIVES IN THE RAIL on consoles (Bud 2026-07-09: it was footer-buried;
   consoles no longer inject a footer at all). Menu opens UPWARD from the rail foot. */
.kz-rail-theme{margin-top:6px;order:99} /* DS28 (Bud 2026-07-10): theme = its own element BELOW the pills — rail-foot is flex-column, order pins it last regardless of injection timing */
.kz-rail-theme .kz-themewrap{margin-left:0;display:block}
.kz-rail-theme .kz-themebtn{width:100%;justify-content:flex-start;font-size:var(--kz-fs-hint)}
.kz-rail-theme .kz-themebtn .kz-tname{margin-left:auto}
.kz-rail-theme .kz-thememenu{top:auto;bottom:calc(100% + 8px);left:0;right:auto;transform-origin:bottom left;animation:kz-menu-up var(--kz-dur) var(--kz-ease-decel)}
/* kz-acct — the ACCOUNT PILL (FT21 round 3, promoted kit-level for continuity):
   one pill per identity/provider in any console rail-foot. States: .on = live
   (soft ok-glow, DS18) · .warn = remembered, needs a tap · .off = not connected.
   Body: dot + who (name over sub) + ONE action (button or a.kz-acct-act). */
.kz-acct{display:flex;align-items:center;gap:9px;border:1px solid var(--line);background:var(--panel);
  border-radius:10px;padding:8px 10px;margin:0 0 6px;min-width:0}
.kz-acct .kz-acct-dot{width:9px;height:9px;border-radius:50%;flex:0 0 auto;background:var(--bad)}
.kz-acct.on{border-color:color-mix(in srgb,var(--ok) 45%,var(--line));box-shadow:0 0 14px -7px var(--ok)}
.kz-acct.on .kz-acct-dot{background:var(--ok);box-shadow:0 0 8px -2px var(--ok)}
.kz-acct.warn{border-color:color-mix(in srgb,var(--warn) 40%,var(--line))}
.kz-acct.warn .kz-acct-dot{background:var(--warn)}
.kz-acct-who{min-width:0;flex:1}
.kz-acct-who b{display:block;font-size:var(--kz-fs-hint);color:var(--ink);font-weight:var(--kz-fw-semibold)}
.kz-acct-who span{display:block;font-size:11px;color:var(--mut);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kz-acct button,.kz-acct a.kz-acct-act{background:none;border:0;padding:2px 0;font:inherit;font-size:11px;
  color:var(--mut);cursor:pointer;flex:0 0 auto;text-decoration:none}
.kz-acct button:hover,.kz-acct a.kz-acct-act:hover{color:var(--ink)}
.kz-acct .kz-acct-connect{color:var(--stripe);font-weight:var(--kz-fw-semibold)}
@media(prefers-reduced-motion:reduce){.kz-acct.on{box-shadow:none}}
/* kz-acct POPOVER (L35, Bud 2026-07-09 — the Resend bottom-left account row):
   the rail-foot identity pill becomes ONE button; the popover (opens UPWARD)
   carries profile head + Appearance (the theme picker moves inside) + Sign out.
   Portal (true login) adopts first; tracker's per-provider pills stay pills. */
.kz-acct-popwrap{position:relative}
button.kz-acct{width:100%;cursor:pointer;text-align:left;font:inherit;box-sizing:border-box}
button.kz-acct:focus-visible{outline:2px solid var(--stripe);outline-offset:2px}
.kz-acct .kz-acct-caret{margin-left:auto;color:var(--dim);font-size:var(--kz-fs-micro);flex:0 0 auto}
.kz-acct-pop{position:absolute;bottom:calc(100% + 8px);left:0;right:0;min-width:220px;z-index:60;
  background:var(--panel);border:1px solid var(--line);border-radius:var(--kz-radius);
  box-shadow:var(--kz-shadow-pop);padding:8px;transform-origin:bottom left;
  animation:kz-menu-up var(--kz-dur) var(--kz-ease-decel)}
.kz-acct-pop[hidden]{display:none}
.kz-acct-pop-head{padding:8px 10px 10px;border-bottom:1px solid var(--line);margin:0 0 6px}
.kz-acct-pop-head b{display:block;font-size:var(--kz-fs-sm);font-weight:var(--kz-fw-semibold);color:var(--ink)}
.kz-acct-pop-head span{display:block;font-size:var(--kz-fs-micro);color:var(--mut);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kz-acct-pop-item{display:flex;align-items:center;gap:10px;width:100%;min-height:34px;padding:0 10px;
  border:0;background:none;border-radius:var(--kz-radius-sm);color:var(--mut);font:inherit;font-size:var(--kz-fs-sm);
  text-decoration:none;cursor:pointer;box-sizing:border-box}
.kz-acct-pop-item:hover{background:var(--panel2);color:var(--ink)}
.kz-acct-pop-label{font-size:10px;font-weight:var(--kz-fw-semibold);letter-spacing:.09em;text-transform:uppercase;color:var(--dim);padding:8px 10px 2px}
.kz-acct-pop .kz-rail-theme{margin:0;padding:0 4px}
.kz-acct-pop .kz-thememenu{bottom:calc(100% + 4px)}
.kz-rail-foot a{min-height:32px;font-size:var(--kz-fs-hint)}
.kz-canvas{padding:28px clamp(24px,4vw,48px) 64px;max-width:1100px;box-sizing:border-box;min-width:0}
/* ---------------------------------------------------------------------
   kz-aside — the RIGHT CONTEXT PANEL (L38, Bud 2026-07-09: "rail left,
   relevant shit right"). A kit primitive with STRICT rules — clutter is
   the named failure mode:
   1. GLANCEABLE CONTEXT ONLY — read-only summaries, upcoming items, meta.
      Never primary actions, never forms, never anything that exists ONLY here.
   2. Max ~3 modules per view; ONE aside per view; lives inside .kz-canvas.
   3. Desktop-only enhancement (>=1024px). Narrow: it drops UNDER the content —
      the page must be complete without it.
   Markup: .kz-withaside > (.kz-main + aside.kz-aside > .kz-aside-mod*)      */
.kz-withaside{display:grid;grid-template-columns:minmax(0,1fr) 280px;gap:var(--kz-space-6);align-items:start}
.kz-withaside > .kz-main{min-width:0}
.kz-aside{position:sticky;top:24px;display:flex;flex-direction:column;gap:var(--kz-space-4);min-width:0}
.kz-aside-mod{border:1px solid var(--line);background:var(--panel);border-radius:var(--kz-radius);padding:14px 16px}
.kz-aside-mod h3{margin:0 0 10px;font-size:var(--kz-fs-label);font-weight:var(--kz-fw-semibold);letter-spacing:var(--kz-tr-label);text-transform:uppercase;color:var(--dim)}
.kz-aside-mod p{margin:0;font-size:var(--kz-fs-sm);color:var(--mut);line-height:1.55}
.kz-aside-mod .kz-row{padding:6px 0}
@media(max-width:1023px){
  .kz-withaside{display:block}
  .kz-aside{position:static;margin-top:var(--kz-space-6);border-top:1px solid var(--line);padding-top:var(--kz-space-5)}
}
.kz-canvas-head{display:flex;align-items:center;gap:var(--kz-space-4);margin:0 0 var(--kz-space-5);flex-wrap:wrap}
.kz-canvas-head h1{margin:0;font-size:var(--kz-fs-h1);font-weight:var(--kz-fw-semibold);letter-spacing:-.02em;color:var(--ink)}
.kz-utility{display:flex;align-items:center;gap:var(--kz-space-2);margin-left:auto}
.kz-utility a,.kz-utility button{display:inline-flex;align-items:center;gap:6px;min-height:32px;padding:0 12px;
  border-radius:var(--kz-radius);background:transparent;border:0;color:var(--mut);font:inherit;font-size:var(--kz-fs-sm);
  text-decoration:none;cursor:pointer;transition:background var(--kz-dur-fast) var(--kz-ease-standard),color var(--kz-dur-fast) var(--kz-ease-standard)}
.kz-utility a:hover,.kz-utility button:hover{background:var(--panel2);color:var(--ink)}
/* mobile: rail off-canvas, toggled by a page-provided burger (same sheet feel as the kit drawer) */
.kz-shell-bar{display:none}
@media(max-width:767px){
  .kz-shell{display:block}
  .kz-shell-bar{display:flex;align-items:center;gap:12px;min-height:var(--kz-bar-h);padding:8px 20px;
    border-bottom:1px solid var(--line);position:sticky;top:0;z-index:50;
    background:color-mix(in srgb,var(--bg) 86%,transparent);
    -webkit-backdrop-filter:saturate(1.4) blur(14px);backdrop-filter:saturate(1.4) blur(14px)}
  .kz-shell-bar .kz-appmenu-btn{display:inline-flex;margin-left:auto}
  .kz-rail{position:fixed;left:0;right:0;top:var(--kz-bar-h);height:auto;max-height:calc(100dvh - var(--kz-bar-h));
    z-index:48;border-right:0;border-bottom:1px solid var(--line);background:var(--panel);box-shadow:var(--kz-shadow-pop);
    transform:translateY(-16px);opacity:0;visibility:hidden;pointer-events:none;
    transition:transform var(--kz-dur-lg) var(--kz-ease-decel),opacity var(--kz-dur) var(--kz-ease-decel),visibility var(--kz-dur-lg)}
  .kz-shell[data-open="1"] .kz-rail{transform:none;opacity:1;visibility:visible;pointer-events:auto}
  .kz-rail nav a{min-height:48px;font-size:var(--kz-fs-lg)}
  .kz-rail .kz-rail-sub a{min-height:44px;font-size:var(--kz-fs-sm)} /* DS26 sub-rows: 44px tap targets in the sheet */
  .kz-rail-brand{display:none} /* brand lives in the mobile bar */
  .kz-canvas{padding:24px 20px 48px}
}

/* =====================================================================
   reduced motion (DESIGN_SYSTEM.md 6.2 / DP-9 / WCAG 2.3.3)
   ===================================================================== */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;scroll-behavior:auto!important}
}

/* =====================================================================
   v6 — DS29 FOLD / SORT / HINT + kz-i-dog (L60, 2026-07-11)
   All ADDITIVE. The collapse grammar below is the portal cockpit's kl-exp,
   promoted verbatim (one grammar estate-wide — the DS2-drift lesson).
   ===================================================================== */

/* ---------- kz-fold: THE collapse primitive ----------
   LAW (DS29): secondary/long content rests folded; PRIMARY glance content
   never hides behind a tap. Summary = caret + icon + title + honest count. */
details.kz-fold{border:1px solid var(--line);border-radius:16px;background:var(--panel);overflow:hidden}
details.kz-fold > summary{cursor:pointer;list-style:none;padding:var(--kz-space-4,18px) var(--kz-space-5,22px);
  display:flex;align-items:center;gap:12px}
details.kz-fold > summary::-webkit-details-marker{display:none}
details.kz-fold > summary::before{content:"\25B8";color:var(--mut);transition:transform .15s ease;flex:0 0 auto}
details.kz-fold[open] > summary::before{transform:rotate(90deg)}
details.kz-fold[open] > summary{border-bottom:1px solid var(--line)}
.kz-fold-body{padding:var(--kz-space-4,18px) var(--kz-space-5,22px)}
.kz-fold-title{font-weight:var(--kz-fw-semibold,600);color:var(--ink)}
.kz-fold-note{margin-left:auto;color:var(--mut);font-size:var(--kz-fs-sm,13px);text-align:right}

/* ---------- sortable kz-table headers (DS29) ----------
   Any table with more than one meaningful order gets them (joins the v4
   "filter what you display" law). Markup: <th data-kz-sort>Header</th> —
   kaizen.js wires the click; state rides aria-sort (screen readers included). */
.kz-table th[data-kz-sort]{cursor:pointer;user-select:none;-webkit-user-select:none;white-space:nowrap}
.kz-table th[data-kz-sort]::after{content:"\2195";margin-left:6px;color:var(--mut);opacity:.55;font-size:.85em}
.kz-table th[aria-sort="ascending"]::after{content:"\2191";color:var(--ink);opacity:1}
.kz-table th[aria-sort="descending"]::after{content:"\2193";color:var(--ink);opacity:1}

/* ---------- kz-hint-i: the tap-info micro-affordance (DS29) ----------
   LAW: a hint bubble is the LAST resort — if a control needs one, rename the
   control first (head-scratching is a naming bug before it is a help gap).
   Reads as INFO per the coaching standard: muted i, panel2 bubble, never a
   warn color, never blocking, dismisses on outside tap / Esc.
   Markup: <button class="kz-hint-i" type="button" data-kz-hint="one plain line"
   aria-label="What is this?"></button> — the bubble is built on first tap. */
.kz-hint-i{position:relative;display:inline-flex;align-items:center;justify-content:center;
  width:18px;height:18px;border-radius:50%;border:1px solid var(--line);background:transparent;
  color:var(--mut);cursor:pointer;padding:0;vertical-align:middle;flex:0 0 auto}
.kz-hint-i::before{content:"i";font:italic 600 11px/1 Georgia,'Times New Roman',serif}
.kz-hint-i:hover,.kz-hint-i[aria-expanded="true"]{color:var(--ink);border-color:var(--mut)}
.kz-hint-pop{position:absolute;z-index:40;top:calc(100% + 7px);left:50%;transform:translateX(-50%);
  width:max-content;min-width:140px;max-width:240px;background:var(--panel2);border:1px solid var(--line);
  border-radius:10px;padding:8px 12px;color:var(--ink);font:400 var(--kz-fs-sm,13px)/1.45 inherit;
  font-family:inherit;font-style:normal;text-align:left;box-shadow:0 6px 20px rgba(0,0,0,.18);cursor:default}

/* =====================================================================
   v7 — DS34-2 kz-live (L68, 2026-07-13): no-flicker live surfaces
   A heartbeat tick patches IN PLACE (kzLiveMorph in kaizen.js); the only
   visible change a tick may make is genuinely-new data. New keyed rows
   enter quietly; reduced-motion (above) kills the entrance like all motion.
   ===================================================================== */
.kz-live-new{animation:kz-live-in .32s ease}
@keyframes kz-live-in{from{opacity:0;transform:translateY(-3px)}to{opacity:1;transform:none}}
