/* ═══════════════════════════════════════════════════════════════════
   DOCURENSIC DESIGN TOKENS + CORE COMPONENTS  (from mockups/docurensic-app.html)
   Drop into app/static/tokens.css and load BEFORE style.css / report.css.
   Pages migrate by using these classes; legacy rp-* styles keep working
   until each page is ported (extend, don't fork).
   Fonts (load on every page): <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
   ═══════════════════════════════════════════════════════════════════ */
:root{
  --bg:#EFEFF6; --panel:#FFFFFF; --panel-2:#F8F8FC;
  --ink:#14121F; --ink-2:#4B4768; --ink-3:#837BA8;
  --line:#DBD9E8; --line-2:#E9E8F2;
  --uv:#6E60E8; --uv-2:#5D4FD6; --uv-soft:#EFECFE; --uv-glow:rgba(124,111,240,.28);
  --ok:#188A5F; --ok-soft:#DFF3EA;
  --low:#8A5D09; --low-soft:#F4ECD9;
  --warn:#B07E0C; --warn-soft:#FBF1D6;
  --hot:#E68A3D; --hot-soft:#FCEBDC;
  --bad:#CE3B3B; --bad-soft:#FBE5E5;
  --sidebar:#12102A; --sidebar-ink:#B7B0D6;
  --shadow:0 10px 30px rgba(20,18,31,.10); --shadow-lg:0 24px 60px rgba(20,18,31,.22);
  /* Type system — brand guide V1.0 (Violet): IBM Plex Sans (UI/body) + IBM Plex Mono
     (codes, metadata, micro-labels) + Oswald (display: wordmark + headings). Every page
     loads the matching Google Fonts link; the old families stay as fallbacks. */
  --mono:'IBM Plex Mono','JetBrains Mono',ui-monospace,monospace;
  --sans:'IBM Plex Sans','Inter',-apple-system,system-ui,sans-serif;
  --display:'Oswald','Arial Narrow',system-ui,sans-serif;
  --r:10px; --r-lg:14px;
}
[data-theme="dark"]{
  --bg:#07070F; --panel:#12102A; --panel-2:#171436;
  --ink:#F5F4FB; --ink-2:#B7B0D6; --ink-3:#837BA8;
  --line:#241E48; --line-2:#191536;
  --uv:#7C6FF0; --uv-2:#A99BF7; --uv-soft:#1C1640; --uv-glow:rgba(124,111,240,.32);
  --ok:#2FB380; --ok-soft:#0F2C22;
  --low:#C89B45; --low-soft:#2A2210;
  --warn:#D9A62E; --warn-soft:#2E2510;
  --hot:#E89A55; --hot-soft:#332211;
  --bad:#E45858; --bad-soft:#331416;
  --sidebar:#0A0918; --sidebar-ink:#9E96C2;
  --shadow:0 10px 30px rgba(0,0,0,.4); --shadow-lg:0 24px 60px rgba(0,0,0,.6);
}

/* Collision guard: style.css (loaded AFTER tokens.css on every app page) re-declares a
   handful of shared names at plain :root specificity and, by source order, would otherwise
   win — dragging the brand Ink Black / Paper / violet-tinted shadows back to the legacy
   blue-slate palette. Re-asserting them here at :root:root (specificity 0,2,0) lets the
   brand values win the cascade. Pages that load style.css WITHOUT tokens.css (producers.html)
   are unaffected and keep their own values. Keep this list in sync with the vars both files
   define: --bg, --ink, --shadow, --shadow-lg, --r-lg. */
:root:root{
  --bg:#EFEFF6; --ink:#14121F;
  --shadow:0 10px 30px rgba(20,18,31,.10); --shadow-lg:0 24px 60px rgba(20,18,31,.22);
  --r-lg:14px;
}
:root:root[data-theme="dark"]{
  --bg:#07070F; --ink:#F5F4FB;
  --shadow:0 10px 30px rgba(0,0,0,.4); --shadow-lg:0 24px 60px rgba(0,0,0,.6);
}

/* ── base ── */
.dz-app{font-family:var(--sans);background:var(--bg);color:var(--ink);font-size:13.5px;line-height:1.55}
.dz-app .mono{font-family:var(--mono)} .dz-app .spacer{flex:1}
/* Long-content guards (shared): .dz-wrap breaks an unbroken string onto new lines
   (long case names, filenames) so it never overflows its container; .dz-clip keeps
   one line and ellipsises the overflow (webhook URLs, IDs). Both set min-width:0 so
   they behave correctly inside flex/grid cells too. Reused across cases + settings. */
.dz-wrap{overflow-wrap:anywhere;word-break:break-word;min-width:0}
.dz-clip{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
@media (prefers-reduced-motion:reduce){.dz-app *,.dz-app *::before,.dz-app *::after{animation:none!important;transition:none!important}}

/* ── shell: topbar + sidebar (mobile-first, burger below 820px) ── */
.dz-shell{display:grid;grid-template-columns:238px minmax(0,1fr);grid-template-rows:54px 1fr;grid-template-areas:"side top" "side main";height:100vh}
.dz-topbar{grid-area:top;display:flex;align-items:center;gap:12px;padding:0 18px;background:var(--panel);border-bottom:1px solid var(--line);z-index:20;min-width:0}
.dz-side{grid-area:side;background:var(--sidebar);color:var(--sidebar-ink);display:flex;flex-direction:column;overflow-y:auto}
/* overflow-x:hidden is a hard invariant: the app content region must never scroll
   sideways. Without it, overflow-x computes to `auto` (because overflow-y is set),
   so a single stray element wider than the column — a rendered PDF preview, an
   unbreakable string that escaped a card's overflow:hidden, etc. — turns into real
   horizontal scroll ("extra blank space on the right" when you swipe on mobile).
   Safe for: the nav drawer (a fixed SIBLING of .dz-main, not a descendant — not
   clipped), the sticky .sev-strip (still sticks vertically), and .dz-table (scrolls
   inside its own .table-card .scroll{overflow-x:auto}, unaffected). */
.dz-main{grid-area:main;overflow-x:hidden;overflow-y:auto;padding:22px 26px 70px;-webkit-overflow-scrolling:touch}
.dz-side nav{padding:6px 10px;display:flex;flex-direction:column;gap:1px}
.dz-side nav a{display:flex;align-items:center;gap:11px;padding:10px 12px;border-radius:8px;color:inherit;text-decoration:none;font-weight:500;font-size:13px;min-height:40px;box-sizing:border-box}
.dz-side nav a:hover{background:rgba(255,255,255,.06);color:#fff}
.dz-side nav a.active{background:var(--uv);color:#fff}
.dz-side nav a.active:hover{background:var(--uv)}
.dz-side nav a .count{margin-left:auto;font-family:var(--mono);font-size:10.5px;background:rgba(255,255,255,.12);padding:1px 7px;border-radius:99px}
.dz-side .dz-ico{flex:none;width:18px;height:18px;opacity:.85}
.dz-side nav a.active .dz-ico{opacity:1}
.dz-nav-label{font-family:var(--mono);font-size:9.5px;letter-spacing:.16em;text-transform:uppercase;color:#847EA0;padding:14px 12px 5px}
/* Sidebar version/status footer (desktop) — pinned to the bottom of the rail. */
.dz-side-foot{margin-top:auto;padding:16px 22px 18px;display:flex;flex-direction:column;gap:2px;font-family:var(--mono);font-size:11px;line-height:1.5;color:#847EA0}
@media (max-width:820px){.dz-side-foot{display:none}}
.dz-burger{display:none;width:38px;height:38px;place-items:center;border-radius:8px}
@media (max-width:820px){
  .dz-shell{grid-template-columns:minmax(0,1fr);grid-template-rows:54px 1fr;grid-template-areas:"top" "main"}
  .dz-side{position:fixed;inset:0 25% 0 0;z-index:60;transform:translateX(-102%);transition:transform .22s ease;box-shadow:var(--shadow-lg)}
  .dz-side.open{transform:none}
  .dz-burger{display:grid}
  .dz-main{padding:16px 14px 70px}
  /* Account chrome (email + Account/Admin/Log out) moves into the drawer on mobile —
     it doesn't fit next to the search box at 375px and was forcing page-wide
     horizontal scroll on every screen. */
  .dz-topbar .dz-acct{display:none}
  /* The topbar spacer exists only to push .dz-acct away from the search box on
     desktop. With .dz-acct hidden there's nothing left to push, but the spacer's
     flex:1 was still splitting the freed-up width 50/50 with .dz-search-wrap
     (also flex:1) — leaving a large dead gap between the search box and the
     theme toggle instead of letting the search box actually use that space. */
  .dz-topbar .spacer{flex:none}
}
/* Drawer account footer — mobile counterpart of the topbar account chrome. Populated by
   the same auth.js data-* hooks (initAuthChrome fills every match on the page). */
.dz-side-acct{margin-top:auto;padding:14px 16px 18px;border-top:1px solid rgba(255,255,255,.08);display:flex;flex-direction:column;gap:2px}
.dz-side-acct .dz-acct-email{font-family:var(--mono);font-size:11px;color:#847EA0;padding:0 12px 8px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dz-side-acct a{display:flex;align-items:center;gap:11px;padding:10px 12px;min-height:40px;box-sizing:border-box;border-radius:8px;color:inherit;text-decoration:none;font-weight:500;font-size:13px}
.dz-side-acct a:hover{background:rgba(255,255,255,.06);color:#fff}
.dz-side-acct .dz-ico{flex:none;opacity:.85}
@media (min-width:821px){.dz-side-acct{display:none}}

/* ── topbar account chip + dropdown (desktop; hidden below 820px, drawer takes over) ── */
.dz-acctbar{display:flex;align-items:center;gap:10px}
.dz-brandmark{width:36px;height:36px;flex:none;display:grid;place-items:center;border:1px solid var(--line);border-radius:9px;background:var(--panel-2);color:var(--uv);text-decoration:none}
.dz-brandmark:hover{border-color:var(--uv);background:var(--uv-soft)}
.dz-acctmenu{position:relative}
.dz-acct-trigger{display:flex;align-items:center;gap:9px;max-width:260px;padding:5px 10px 5px 6px;border:1px solid var(--line);border-radius:99px;background:var(--panel);color:var(--ink);cursor:pointer;font-family:inherit;min-height:40px}
.dz-acct-trigger:hover{border-color:var(--ink-3);background:var(--panel-2)}
.dz-avatar{flex:none;width:28px;height:28px;border-radius:8px;display:grid;place-items:center;background:linear-gradient(135deg,var(--uv),var(--uv-2));color:#fff;font-weight:700;font-size:11.5px;letter-spacing:.02em}
.dz-acct-email-chip{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:500;color:var(--ink-2)}
.dz-caret{flex:none;color:var(--ink-3);transition:transform .15s}
.dz-acct-trigger[aria-expanded="true"] .dz-caret{transform:rotate(180deg)}
.dz-acct-pop{position:absolute;top:calc(100% + 8px);right:0;z-index:50;min-width:230px;background:var(--panel);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow-lg);padding:7px}
.dz-acct-pop a{display:flex;align-items:center;gap:12px;padding:10px 12px;border-radius:8px;color:var(--ink);text-decoration:none;font-size:14px;font-weight:500;min-height:42px;box-sizing:border-box}
.dz-acct-pop a:hover{background:var(--panel-2)}
.dz-acct-pop .dz-ico{flex:none;color:var(--ink-3)}
.dz-acct-pop a:hover .dz-ico{color:var(--ink-2)}
.dz-acct-sep{height:1px;background:var(--line-2);margin:6px 8px}

/* Inside the shell the main panel already provides gutters — legacy .wrap containers
   (1080px marketing column) must not box the content into the middle of the panel. */
.dz-main .wrap{max-width:none;padding:0}

/* Slim in-app footer (replaces the old full-bleed marketing footer on shell pages). */
.dz-footer{margin-top:44px;padding:16px 2px 0;border-top:1px solid var(--line-2);display:flex;align-items:center;gap:16px;flex-wrap:wrap;font-family:var(--mono);font-size:11px;color:var(--ink-3)}
.dz-footer a{color:inherit;text-decoration:none}
.dz-footer a:hover{color:var(--ink-2);text-decoration:underline}

/* ── global search (topbar) — command-palette style; behavior in shell.js dzInitSearch ── */
.dz-search-wrap{position:relative;flex:1;max-width:460px;min-width:0}
.dz-gsearch{display:flex;align-items:center;gap:8px;min-height:36px;border:1px solid var(--line);border-radius:10px;padding:0 8px 0 12px;background:var(--panel-2);transition:border-color .15s ease,box-shadow .15s ease,background .15s ease}
.dz-gsearch:focus-within{border-color:var(--uv);background:var(--panel);box-shadow:0 0 0 3px var(--uv-glow)}
.dz-gsearch-ico{flex:none;color:var(--ink-3);transition:color .15s ease}
.dz-gsearch:focus-within .dz-gsearch-ico{color:var(--uv)}
.dz-gsearch input{flex:1;min-width:0;border:none;background:none;font:inherit;font-size:16px;color:var(--ink);min-height:34px}
.dz-gsearch input:focus{outline:none}
.dz-gsearch input::-webkit-search-cancel-button,.dz-gsearch input::-webkit-search-decoration{-webkit-appearance:none;appearance:none}
.dz-gsearch-kbd{flex:none;font-family:var(--mono);font-size:10px;line-height:1.4;color:var(--ink-3);border:1px solid var(--line);border-radius:5px;padding:2px 6px;background:var(--panel);white-space:nowrap}
.dz-gsearch:focus-within .dz-gsearch-kbd{display:none}
.dz-gsearch-clear{flex:none;display:grid;place-items:center;width:24px;height:24px;border:none;border-radius:6px;background:none;color:var(--ink-3);cursor:pointer;padding:0}
.dz-gsearch-clear:hover{background:var(--line-2);color:var(--ink)}
.dz-search-panel{position:absolute;top:calc(100% + 8px);left:0;right:0;z-index:40;background:var(--panel);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow-lg);max-height:min(480px,70vh);overflow-y:auto;padding:6px;transform-origin:top center;animation:dz-search-in .16s ease}
@keyframes dz-search-in{from{opacity:0;transform:translateY(-4px) scale(.985)}to{opacity:1;transform:none}}
.dz-search-panel.hidden{display:none}
.dz-search-group{display:flex;align-items:center;gap:8px;font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);padding:10px 10px 5px}
.dz-search-group .n{margin-left:auto;letter-spacing:0;background:var(--panel-2);border:1px solid var(--line-2);border-radius:99px;padding:0 7px;line-height:1.6}
.dz-search-forget{margin-left:auto;border:none;background:none;font-family:var(--mono);font-size:9.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--uv);cursor:pointer;padding:0}
.dz-search-forget:hover{text-decoration:underline}
.dz-search-hit{display:flex;align-items:center;gap:10px;padding:7px 10px;border-radius:9px;color:var(--ink);text-decoration:none;min-height:46px}
.dz-search-hit:hover{background:var(--panel-2)}
.dz-search-hit.sel{background:var(--uv-soft)}
.dz-search-hit .tile{flex:none;display:grid;place-items:center;width:32px;height:32px;border-radius:8px;background:var(--panel-2);border:1px solid var(--line-2);color:var(--ink-3)}
.dz-search-hit:hover .tile,.dz-search-hit.sel .tile{color:var(--uv);border-color:var(--uv-glow)}
.dz-search-hit.sel .tile{background:var(--panel)}
.dz-search-hit .body{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.dz-search-hit .name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500;font-size:13px}
.dz-search-hit .name mark,.dz-search-hit .meta mark{background:var(--uv-soft);color:var(--uv-2);border-radius:3px;padding:0 1px}
.dz-search-hit.sel .name mark,.dz-search-hit.sel .meta mark{background:var(--panel)}
.dz-search-hit .meta{font-family:var(--mono);font-size:10.5px;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dz-search-hit .badge{flex:none}
.dz-search-loading{display:flex;flex-direction:column;gap:4px;padding:4px}
.dz-skel{height:46px;border-radius:9px;background:linear-gradient(90deg,var(--panel-2) 25%,var(--line-2) 50%,var(--panel-2) 75%);background-size:200% 100%;animation:dz-shimmer 1.1s linear infinite}
@keyframes dz-shimmer{to{background-position:-200% 0}}
.dz-search-empty{padding:24px 14px 18px;text-align:center;color:var(--ink-3)}
.dz-search-empty svg{opacity:.45}
.dz-search-empty .t{font-size:13px;font-weight:500;color:var(--ink-2);margin-top:6px}
.dz-search-empty .s{font-family:var(--mono);font-size:10.5px;margin-top:3px}
.dz-search-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:6px 4px 2px;padding:8px 6px 2px;border-top:1px solid var(--line-2);font-family:var(--mono);font-size:10px;color:var(--ink-3)}
.dz-search-foot .keys{display:flex;align-items:center;gap:3px;white-space:nowrap}
.dz-search-foot kbd{font-family:inherit;border:1px solid var(--line);border-radius:4px;padding:0 4px;background:var(--panel-2);line-height:1.6}
.dz-search-all{color:var(--uv);text-decoration:none;font-weight:600;white-space:nowrap}
.dz-search-all:hover{text-decoration:underline}
@media (max-width:820px){.dz-search-wrap{max-width:none}.dz-gsearch-kbd{display:none}.dz-search-foot .keys{display:none}}

/* ── typography blocks ── */
.dz-h1{font-family:var(--display);font-variation-settings:'wdth' 125;font-weight:850;font-size:24px;text-transform:uppercase;line-height:1.1}
.dz-sub{font-family:var(--mono);font-size:11.5px;color:var(--ink-3);margin-top:5px}

/* ── buttons / badges / chips ── */
.btn{display:inline-flex;align-items:center;gap:8px;padding:8px 14px;border-radius:8px;font-weight:600;font-size:13px;transition:.15s;border:none;background:none;color:inherit;cursor:pointer;font-family:inherit;min-height:40px;box-sizing:border-box;text-decoration:none}
.btn-primary{background:var(--uv);color:#fff;box-shadow:0 2px 10px var(--uv-glow)}
.btn-primary:hover{background:var(--uv-2)}
.btn-ghost{border:1px solid var(--line);background:var(--panel)}
.btn-ghost:hover{border-color:var(--ink-3)}
.btn-sm{padding:5px 10px;font-size:12px;border-radius:7px;min-height:40px}
.badge{font-family:var(--mono);font-size:10.5px;font-weight:600;letter-spacing:.06em;padding:3px 10px;border-radius:6px;text-transform:uppercase;white-space:nowrap}
.b-ok{background:var(--ok-soft);color:var(--ok)} .b-low{background:var(--low-soft);color:var(--low)}
.b-warn{background:var(--warn-soft);color:var(--warn)} .b-hot{background:var(--hot-soft);color:var(--hot)}
.b-bad{background:var(--bad-soft);color:var(--bad)} .b-uv{background:var(--uv-soft);color:var(--uv)}
.b-mute{background:var(--panel-2);color:var(--ink-3);border:1px solid var(--line)}
.chip{padding:6px 13px;border-radius:99px;border:1px solid var(--line);background:var(--panel);font-size:12.5px;font-weight:500;color:var(--ink-2);display:inline-flex;align-items:center;gap:7px;cursor:pointer;min-height:40px;box-sizing:border-box}
.chip .dot{width:7px;height:7px;border-radius:50%}
.chip.active{background:var(--ink);border-color:var(--ink);color:var(--bg)}

/* ── card / section ── */
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);padding:18px}
.card h3{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);margin:0 0 12px;display:flex;align-items:center;gap:8px}
.card h3::after{content:"";flex:1;height:1px;background:var(--line-2)}
.section{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden}
.sec-head{display:flex;align-items:center;gap:12px;padding:15px 20px;border-bottom:1px solid var(--line-2)}
.sec-head .num{width:26px;height:26px;flex:none;border-radius:8px;background:var(--uv-soft);color:var(--uv);display:grid;place-items:center;font-family:var(--mono);font-size:11px;font-weight:700}
.sec-head h2{font-family:var(--display);font-variation-settings:'wdth' 125;font-weight:800;font-size:14.5px;text-transform:uppercase;margin:0}
.sec-head p{font-size:12px;color:var(--ink-3);margin:1px 0 0}
.sec-body{padding:18px 20px}

/* ── table ── */
.table-card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden}
.table-card .scroll{overflow-x:auto}
.dz-table{width:100%;border-collapse:collapse;min-width:640px}
.dz-table thead th{font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);text-align:left;padding:11px 14px;border-bottom:1px solid var(--line);background:var(--panel-2);white-space:nowrap}
.dz-table tbody td{padding:12px 14px;border-bottom:1px solid var(--line-2);vertical-align:middle}
.dz-table tbody tr{cursor:pointer}
.dz-table tbody tr:hover{background:var(--panel-2)}
.dz-table tbody tr:last-child td{border-bottom:none}
@media (max-width:640px){.dz-table th.hide-m,.dz-table td.hide-m{display:none}.dz-table{min-width:0}}
/* Document/filename cells must shrink before forcing an in-card horizontal scroll —
   otherwise a long filename pushes Verdict/Risk out of the visible card at 375px. */
.dz-table .td-clip{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:340px}
@media (max-width:640px){
  .dz-table .td-clip{max-width:38vw}
  .dz-table .scorebar{min-width:80px}
  .page-head .btn{width:100%;justify-content:center}
}

/* Slim trailing actions column (Documents list delete) */
.dz-table td.dz-doc-actions{width:36px;text-align:right;padding-left:4px}

/* ── score bar / gauges helpers ── */
.scorebar{display:flex;align-items:center;gap:9px;min-width:110px}
.scorebar .track{flex:1;height:5px;background:var(--line-2);border-radius:99px;overflow:hidden}
.scorebar .fill{display:block;height:100%;border-radius:99px;min-width:0}
.scorebar b{font-family:var(--mono);font-size:12px;min-width:26px;text-align:right}

/* ── KPI strip / search+filter toolbar (Documents, and future Analytics/Cases pages) ── */
.dz-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;margin-bottom:16px}
.dz-kpi{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);padding:14px 16px}
.dz-kpi-label{display:block;font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3)}
.dz-kpi-value{display:block;font-family:var(--display);font-variation-settings:'wdth' 125;font-weight:800;font-size:26px;margin-top:6px;line-height:1}
.dz-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:14px}
.dz-search{flex:1;min-width:200px;display:flex;align-items:center;gap:8px;border:1px solid var(--line);background:var(--panel);border-radius:10px;padding:0 12px;min-height:40px}
.dz-search svg{flex:none;color:var(--ink-3)}
.dz-search input{border:none;background:none;flex:1;font:inherit;font-size:16px;color:var(--ink);min-height:38px}
.dz-search input:focus{outline:none}
.dz-chipset{display:flex;flex-wrap:wrap;gap:8px}

/* ── page header (title + sub + spacer + actions), and Cases components ── */
.page-head{display:flex;align-items:flex-end;gap:16px;flex-wrap:wrap;margin-bottom:20px}
.page-head h1{font-family:var(--display);font-variation-settings:'wdth' 125;font-weight:850;font-size:24px;text-transform:uppercase;line-height:1.1;margin:0}
.page-head .sub{font-family:var(--mono);font-size:11.5px;color:var(--ink-3);margin-top:5px}
.explain-strip{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:18px}
.explain{border:1px dashed var(--line);border-radius:11px;padding:13px 15px;font-size:12.5px;color:var(--ink-2);background:var(--panel)}
.explain b{display:block;color:var(--ink);margin-bottom:3px}
.explain .link-reason{margin-top:8px;display:inline-block}
.link-reason{font-family:var(--mono);font-size:10.5px;border:1px solid var(--uv);border-radius:6px;padding:2px 9px;color:var(--uv);background:var(--uv-soft);white-space:nowrap}
.link-reason.manual{border-color:var(--line);color:var(--ink-3);background:var(--panel-2)}
.cases-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:14px}
.case-card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);padding:18px;cursor:pointer;transition:.15s}
.case-card:hover{box-shadow:var(--shadow);transform:translateY(-1px)}
.case-card .cid{font-family:var(--mono);font-size:10.5px;color:var(--ink-3)}
/* overflow-wrap guards against a long unbroken case name overflowing the card
   (and, since cards sit in a grid, spilling over the neighbouring card). */
.case-card .ct{font-weight:700;font-size:15px;margin:3px 0 10px;overflow-wrap:anywhere}
.case-card .stats{display:flex;gap:14px;font-family:var(--mono);font-size:11px;color:var(--ink-2);flex-wrap:wrap}
.case-card .stats b{font-size:14px;color:var(--ink)}
.case-head{display:flex;gap:16px;align-items:flex-start;flex-wrap:wrap;background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);padding:20px 22px;margin-bottom:16px}
.audit-row{display:flex;gap:10px;align-items:baseline;padding:9px 0;border-bottom:1px solid var(--line-2);font-size:12.5px}
.audit-row:last-child{border-bottom:none}
.audit-row .at{font-family:var(--mono);font-size:10.5px;color:var(--ink-3);white-space:nowrap}
@media (max-width:820px){.explain-strip{grid-template-columns:1fr}}

/* ── feature-gated placeholder card (§5 placeholder inventory) — dimmed "Coming soon" card
   gated by settings.features.<key>; moved here from analytics.html once Image forensics and
   Signature checks (redesign Phase 9) needed the exact same pattern (extend, don't fork). */
.dz-feature-placeholder{opacity:.55}
.dz-feature-placeholder.enabled{opacity:1}
.dz-feature-placeholder p{color:var(--ink-2);font-size:13.5px;margin:0}

/* ── AI usage footer (testing) — render under EVERY Claude-powered response ── */
.ai-tok{display:flex;gap:14px;flex-wrap:wrap;padding:9px 14px;border-top:1px dashed var(--line);font-family:var(--mono);font-size:10.5px;color:var(--ink-3)}
.ai-tok b{color:var(--ink-2)}
.ai-tok .cost{color:var(--uv);font-weight:600}

/* ── toasts ── */
.toasts{position:fixed;bottom:22px;right:22px;z-index:80;display:flex;flex-direction:column;gap:10px}
.toast{display:flex;align-items:center;gap:11px;background:var(--ink);color:var(--bg);padding:12px 16px;border-radius:11px;box-shadow:var(--shadow);font-size:13px;font-weight:500;max-width:360px;animation:toastIn .25s ease}
@keyframes toastIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
.toast .ic{width:22px;height:22px;flex:none;border-radius:50%;display:grid;place-items:center;font-size:12px}
.toast.ok .ic{background:var(--ok)} .toast.info .ic{background:var(--uv)} .toast.bad .ic{background:var(--bad)}

/* ── keyboard a11y: one visible focus ring app-wide + the skip link ── */
:focus-visible{outline:2px solid var(--uv);outline-offset:2px}
.dz-skip{position:fixed;left:-9999px;top:0;z-index:9999;background:var(--uv);color:#fff;padding:10px 18px;border-radius:0 0 10px 0;font-weight:600;font-size:13px;text-decoration:none}
.dz-skip:focus{left:0}
