/* ============================================================================
   Veld — app styles (the synced, paid workspace)
   ----------------------------------------------------------------------------
   /app.html only. portal.html keeps portal.css: the on-device portal is the
   free tier, and the two are no longer meant to look like the same product.

   This file started as the whole of that difference, back when one renderer
   served both pages. The views have since been forked too — app.html loads
   app-ui.js, portal.html loads portal.js — so the class names here are the
   app's own and are free to drift from portal.css.

   The chrome follows dub's app: a neutral greyscale, a floating sidebar panel
   on a white page, thin borders, small radii, restrained shadows. The brand
   sits on top of that — navy is the only saturated colour in the chrome, used
   for the active nav item, primary buttons and focus rings, and Spectral is
   kept for headings so the workspace still reads as Veld.

   No inline styles: the CSP allows style attributes but this file has never
   needed them, and the utilities near the end cover the few cases that arise.
   ========================================================================== */

:root{
  /* Neutral chrome. Names follow dub's token vocabulary so the intent of each
     step stays legible: bg- for surfaces, border- for lines, content- for text. */
  --bg-default:#ffffff;
  --bg-muted:#fafafa;
  --bg-subtle:#f5f5f5;
  --bg-emphasis:#e5e5e5;

  --border-muted:#f5f5f5;
  --border-subtle:#e5e5e5;
  --border-default:#d4d4d4;
  --border-emphasis:#a3a3a3;

  --content-muted:#a3a3a3;
  --content-subtle:#737373;
  --content-default:#404040;
  --content-emphasis:#171717;

  /* Brand accent. The only saturated colour in the chrome. */
  --navy:#0a2540; --navy-2:#0e3155;
  --steel:#356087; --steel-bg:#eef3f8; --steel-bd:#dce7f1;

  /* Semantic. Two jobs, two steps: the bare token is the *mark* (a bar, a
     dot, a chart segment) and is validated for 3:1 on white; the -tx step is
     the same state as *text* and clears 4.5:1 on white and on its own tint.
     Using the mark colour for small text was the old file's one real sin. */
  --ok:#22a06b;   --ok-bg:#f0fdf4;   --ok-bd:#bbf7d0;   --ok-tx:#15803d;
  --warn:#d97706; --warn-bg:#fefce8; --warn-bd:#fde68a; --warn-tx:#a16207;
  --due:#b91c1c;  --due-bg:#fef2f2;  --due-bd:#fecaca;  --due-tx:#991b1b;

  /* Chart marks. charts.js reads these and falls back to the portal's palette
     when they are absent, which is how the two products' charts differ without
     forking the file. Validated with the dataviz validator against this card
     surface (#ffffff): every mark >= 3:1 (series 7.35, good 3.33, warning 3.19,
     critical 6.47, neutral 4.74); worst CVD pair dE 8.6 against a target of 8;
     worst normal-vision pair 18.8 against a gate of 15. The status three still
     ship an icon and a label, so colour never carries the meaning alone. */
  --vz-surface:#ffffff;
  --vz-series:#1f5890;
  --vz-series-soft:rgba(31,88,144,.10);
  --vz-good:#22a06b;
  --vz-warning:#d97706;
  --vz-critical:#b91c1c;
  --vz-neutral:#737373;
  --vz-grid:#f0f0f0;
  --vz-axis:#d4d4d4;
  --vz-ink:#171717;
  --vz-ink-soft:#404040;
  --vz-muted:#737373;

  --radius-sm:8px; --radius:12px; --radius-lg:14px;
  --shadow-xs:0 1px 2px rgba(23,23,23,.05);
  --shadow-sm:0 1px 3px rgba(23,23,23,.06),0 1px 2px rgba(23,23,23,.04);
  --shadow-md:0 4px 12px rgba(23,23,23,.07),0 1px 3px rgba(23,23,23,.04);
  --shadow-lg:0 16px 40px rgba(23,23,23,.12),0 2px 8px rgba(23,23,23,.05);
  --ring:0 0 0 3px rgba(10,37,64,.12);
}

*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
  font-family:'Hanken Grotesk',system-ui,sans-serif;
  background:var(--bg-default); color:var(--content-default);
  line-height:1.5; font-size:14px; -webkit-font-smoothing:antialiased;
}
h1,h2,h3,h4{
  font-family:'Spectral',Georgia,serif;font-weight:600;line-height:1.25;
  color:var(--content-emphasis);letter-spacing:-.01em;
}
button{font:inherit;cursor:pointer;border:none;background:none;color:inherit}
input,select,textarea{font-family:inherit;font-size:13.5px}
a{color:var(--steel);text-decoration:none}
a:hover{color:var(--navy)}
svg{display:block}
:focus-visible{outline:2px solid var(--navy);outline-offset:2px;border-radius:6px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important;scroll-behavior:auto!important}}

.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
.wordmark{font-family:'Jost',sans-serif;font-weight:600;letter-spacing:.04em}

/* ============================================================== lock screen */
/* Light, not the portal's navy slab. Signing in to the synced workspace should
   feel like arriving at the product, not like passing a barrier. */

.lock{
  min-height:100vh;display:flex;align-items:center;justify-content:center;
  padding:40px 20px;background:var(--bg-muted);
  background-image:radial-gradient(900px 420px at 50% -10%,rgba(10,37,64,.07) 0,transparent 64%);
  position:relative;overflow:hidden;
}
.lock[hidden]{display:none}
/* Ambient sync lines behind the card — see lock-flow.js. Purely decorative,
   so it sits under the card and never intercepts clicks. */
.lock-flow{position:absolute;inset:0;width:100%;height:100%;z-index:0;pointer-events:none}
.lock-card{
  width:100%;max-width:440px;background:var(--bg-default);
  border:1px solid var(--border-subtle);border-radius:16px;
  box-shadow:var(--shadow-lg);padding:34px 32px;
  position:relative;z-index:1;
}
.lock-brand{display:flex;align-items:center;gap:9px;margin-bottom:26px}
.lock-brand .wordmark{font-size:20px;color:var(--navy)}
.lock h1{font-size:21px;margin-bottom:7px}
.lock .sub{color:var(--content-subtle);font-size:13.5px;line-height:1.55;margin-bottom:22px}
.lock .field{margin-bottom:15px}
.lock .btn{width:100%;justify-content:center;margin-top:6px}
.lock-alt{margin-top:18px;text-align:center;font-size:13px;color:var(--content-subtle)}
.lock-alt button{color:var(--navy);font-weight:600;text-decoration:underline}
.lock-err{
  background:var(--due-bg);border:1px solid var(--due-bd);color:var(--due-tx);
  padding:10px 12px;border-radius:var(--radius-sm);font-size:13px;
  font-weight:500;margin-bottom:16px;
}
.lock-or{
  display:flex;align-items:center;gap:12px;margin:18px 0 14px;
  color:var(--content-muted);font-size:12px;font-weight:500;
}
.lock-or::before,.lock-or::after{content:"";flex:1;height:1px;background:var(--border-subtle)}
.lock-passkey{width:100%;justify-content:center}
.lock-passkey svg{width:16px;height:16px;stroke-width:1.7}
.lock-note{
  margin-top:20px;padding-top:18px;border-top:1px solid var(--border-subtle);
  font-size:12.5px;color:var(--content-subtle);line-height:1.6;
}
.lock-note b{color:var(--content-emphasis);font-weight:600}
/* Someone who pressed Subscribe on the pricing page and landed on an account
   screen. Distinct from .lock-note, which is the card's quiet footer: this one
   answers "why am I here and not at a card form". */
.lock-intent{
  margin:16px 0 20px;padding:12px 14px;border-radius:var(--radius-sm);
  background:var(--steel-bg);border:1px solid var(--steel-bd);
  font-size:13px;color:var(--content-default);line-height:1.55;
}
.lock-intent b{color:var(--navy);font-weight:600}
/* The recovery key itself, shown once. Monospace and spaced out because it
   gets copied by hand about as often as by clipboard. */
.lock-key{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:15px;
  letter-spacing:.06em;text-align:center;color:var(--navy);font-weight:600;
}

/* ====================================================== sign-in transition */
/* Five columns that close over the account card when Sign in is pressed and
   open again onto whatever comes next — the workspace, the passkey offer, or
   the same card carrying an error. Adapted from a framer-motion "double
   stairs" page transition down to plain CSS keyframes, the same way
   lock-flow.js was adapted: no React, no animation library, nothing added to
   a client that still ships unbundled.

   It covers a real wait rather than decorating an instant one. Deriving the
   key is 600,000 rounds on the device, which is seconds, and the status line
   below rides on top of the columns so that the "what is happening" message
   survives being covered up. See transition.js.

   Navy because navy is the one saturated colour the app owns, and because the
   workspace underneath is white — the columns parting onto it is the arrival
   the lock screen's copy promises. */

.xtn{
  position:fixed;inset:0;z-index:70;display:flex;
  /* Never intercepts a click. If a column were ever left on screen by a
     mislaid animationend, the page underneath must still work. */
  pointer-events:none;
}
.xtn[hidden]{display:none}
.xtn > span{
  flex:1;height:100%;background:var(--navy);
  border-right:1px solid var(--navy-2);
  /* Parked off-screen in the direction each column will arrive from, so the
     element is harmless before the first animation and after the last one. */
  transform:translateY(-100%);
}
.xtn > span:nth-child(even){transform:translateY(100%)}
.xtn > span:last-of-type{border-right:none}

/* in: alternate columns drop and rise into place, 50ms apart.
   out: each carries on the way it was heading, so the screen is wiped rather
   than un-wiped — a reversal reads as a mistake being undone. */
.xtn.in > span{animation:xtnInDown .8s cubic-bezier(.76,0,.24,1) both}
.xtn.in > span:nth-child(even){animation-name:xtnInUp}
.xtn.out > span{animation:xtnOutDown .8s cubic-bezier(.76,0,.24,1) both}
.xtn.out > span:nth-child(even){animation-name:xtnOutUp}

.xtn > span:nth-child(1){animation-delay:0s}
.xtn > span:nth-child(2){animation-delay:.05s}
.xtn > span:nth-child(3){animation-delay:.1s}
.xtn > span:nth-child(4){animation-delay:.15s}
.xtn > span:nth-child(5){animation-delay:.2s}

@keyframes xtnInDown{from{transform:translateY(-100%)}to{transform:translateY(0)}}
@keyframes xtnInUp{from{transform:translateY(100%)}to{transform:translateY(0)}}
@keyframes xtnOutDown{from{transform:translateY(0)}to{transform:translateY(100%)}}
@keyframes xtnOutUp{from{transform:translateY(0)}to{transform:translateY(-100%)}}

/* The same words as #acctBusy, on the curtain instead of under it. Fades in once
   the columns have met — the stagger means the last one lands a full second
   in, and starting sooner shows the message through a gap. */
.xtn-status{
  position:absolute;inset:0;z-index:2;
  display:flex;align-items:center;justify-content:center;gap:11px;
  padding:0 24px;color:#fff;font-size:13.5px;font-weight:600;
  opacity:0;transition:opacity .35s ease;
}
.xtn.in .xtn-status{opacity:1;transition-delay:1s}
.xtn-status small{
  display:block;font-weight:400;font-size:12px;margin-top:3px;
  color:rgba(255,255,255,.62);
}
.xtn-status .spin{
  flex:none;width:15px;height:15px;border-radius:50%;
  border:2px solid rgba(255,255,255,.28);border-top-color:#fff;
  animation:acctSpin .8s linear infinite;
}

/* ------------------------------------------------- the arrival splash --- */
/* Cut to once the columns have met, and the same navy they are, so the cut
   itself is invisible: the slab stops being five moving things and becomes
   one still one, and the lockup and the crowd rise out of it. A white splash
   would have been a flashbulb between two dark screens. */

.xtn-splash{
  position:absolute;inset:0;z-index:1;background:var(--navy);
  background-image:radial-gradient(880px 560px at 50% 14%,rgba(53,96,135,.34) 0,transparent 66%);
  opacity:0;transition:opacity .4s ease;
}
.xtn-splash[hidden]{display:none}
.xtn.lit .xtn-splash{opacity:1}
.xtn-crowd{position:absolute;inset:0;width:100%;height:100%}

/* Centred in the top half, which leaves the status line where it already was
   in the middle of the screen and the crowd's band below that. Three things
   on one vertical and nothing moving when the splash arrives or goes: the
   status is the only element shared between the two states, and a status that
   jumped position at the cut would be the one thing the eye followed. */
.xtn-lockup{
  position:absolute;inset:0 0 50% 0;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:0 24px;text-align:center;
  opacity:0;transform:translateY(12px);
  transition:opacity .4s ease,transform .5s cubic-bezier(.22,1,.36,1);
}
.xtn.lit .xtn-lockup{
  opacity:1;transform:none;
  transition-duration:.55s,.7s;transition-delay:.14s;
}
.xtn-mark{width:46px;height:47px;margin-bottom:16px}
.xtn-lockup .wordmark{font-size:42px;line-height:1;color:#fff}
.xtn-lockup .u-dot{color:#8fbae3}
/* Set as written, not uppercased. The capital in DPOs is doing work — it is an
   acronym with an English plural on it — and text-transform flattens it to
   DPOS, which reads as a shout and a typo at the same time. */
.xtn-tagline{
  margin-top:16px;font-size:13px;font-weight:500;letter-spacing:.07em;
  color:rgba(255,255,255,.56);
}
/* At phone width the note is within a few pixels of the screen. Stacking it
   under the spinner gives back the width the row was spending on sitting
   beside it, which is the difference between one line and two. */
@media (max-width:420px){
  .xtn-status{flex-direction:column;gap:13px;text-align:center;padding:0 18px}
  .xtn-lockup .wordmark{font-size:34px}
  .xtn-mark{width:38px;height:39px}
  .xtn-tagline{font-size:12.5px}
}

/* =================================================================== shell */
/* A white page with the sidebar as a floating panel — dub's signature move.
   The inset is what makes this feel like an application rather than a page,
   and it is the first thing that separates the app from the free portal. */

.app{display:none;grid-template-columns:268px minmax(0,1fr);min-height:100vh;background:var(--bg-default)}
.app.on{display:grid}

.side{
  position:sticky;top:0;height:100vh;padding:10px 0 10px 10px;
  display:flex;flex-direction:column;
}
/* The panel surface is painted behind the sidebar's own children rather than
   on a wrapper element. The shell markup came from the portal and still has
   the same shape; an extra wrapper div is not worth the churn. */
.side::before{
  content:"";position:absolute;inset:10px 0 10px 10px;
  background:var(--bg-muted);border:1px solid var(--border-subtle);
  border-radius:var(--radius-lg);z-index:0;
}
.side > *{position:relative;z-index:1}

.side-brand{
  display:flex;align-items:center;gap:10px;
  margin:4px 12px 12px;padding:10px 11px;
  background:var(--bg-default);border:1px solid var(--border-subtle);
  border-radius:10px;box-shadow:var(--shadow-xs);
}
.side-brand .nm{display:flex;flex-direction:column;line-height:1.2;min-width:0}
.side-brand .nm b{
  font-family:'Jost',sans-serif;font-weight:600;color:var(--navy);
  font-size:16px;letter-spacing:.04em;
}
.side-brand .nm small{
  color:var(--content-subtle);font-size:11.5px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:150px;
}

/* The one place the chrome says out loud what the free portal cannot do. */
.side-plan{
  display:inline-flex;align-items:center;gap:6px;align-self:flex-start;
  margin:0 12px 12px;padding:4px 9px;border-radius:99px;
  background:var(--ok-bg);border:1px solid var(--ok-bd);
  font-size:11px;font-weight:700;color:var(--ok-tx);letter-spacing:.02em;
}
.side-plan::before{content:"";width:6px;height:6px;border-radius:99px;background:var(--ok);flex:none}

.nav{
  display:flex;flex-direction:column;gap:2px;padding:0 12px;
  overflow-y:auto;min-height:0;flex:1;scrollbar-width:none;
}
.nav::-webkit-scrollbar{width:0;height:0}
.nav button{
  display:flex;align-items:center;gap:10px;width:100%;text-align:left;
  padding:8px 11px;border-radius:9px;color:var(--content-subtle);
  font-size:13.5px;font-weight:500;
  transition:background .15s,color .15s,box-shadow .15s;
}
.nav button:hover{background:var(--bg-default);color:var(--content-emphasis);box-shadow:var(--shadow-xs)}
.nav button.on{background:var(--navy);color:#fff;box-shadow:var(--shadow-sm)}
.nav button.on:hover{background:var(--navy-2);color:#fff}
.nav button .count{
  margin-left:auto;background:var(--bg-emphasis);color:var(--content-subtle);
  font-size:11px;font-weight:700;padding:1px 7px;border-radius:99px;
  font-variant-numeric:tabular-nums;
}
.nav button:hover .count{background:var(--bg-subtle)}
.nav button.on .count{background:rgba(255,255,255,.2);color:#fff}
.nav svg{width:16px;height:16px;flex:none;stroke-width:1.8}

.side-foot{margin-top:auto;padding:12px 12px 4px;border-top:1px solid var(--border-subtle)}
.side-foot button{
  display:flex;align-items:center;gap:10px;width:100%;text-align:left;
  padding:7px 11px;border-radius:9px;color:var(--content-subtle);
  font-size:13px;font-weight:500;transition:background .15s,color .15s;
}
.side-foot button:hover{background:var(--bg-default);color:var(--content-emphasis)}
.side-foot svg{width:15px;height:15px;stroke-width:1.8;flex:none}
.side-cross{
  display:flex;align-items:flex-start;gap:9px;width:100%;text-align:left;
  margin-top:6px;padding:9px 11px;border-radius:9px;
  color:var(--content-subtle);font-size:12.5px;line-height:1.45;
  transition:background .15s,color .15s;
}
.side-cross:hover{background:var(--bg-default);color:var(--content-default)}
.side-cross b{color:var(--content-emphasis);font-weight:600}
.side-cross svg{width:15px;height:15px;stroke-width:1.8;flex:none;margin-top:2px}
.side-meta{font-size:11px;color:var(--content-muted);padding:10px 11px 0;line-height:1.55}

.main{padding:26px 30px 64px;max-width:1220px;width:100%;min-width:0}
.topbar{
  display:flex;align-items:flex-start;justify-content:space-between;gap:16px;
  flex-wrap:wrap;margin-bottom:22px;padding-bottom:18px;
  border-bottom:1px solid var(--border-subtle);
}
.topbar h1{font-size:20px}
.topbar .sub{color:var(--content-subtle);font-size:13.5px;margin-top:4px}
.topbar-actions{display:flex;gap:8px;flex-wrap:wrap}

/* ================================================================= buttons */

.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  padding:8px 13px;border-radius:var(--radius-sm);border:1px solid transparent;
  font-size:13px;font-weight:600;line-height:1.25;white-space:nowrap;
  transition:background .15s,border-color .15s,color .15s,box-shadow .15s;
}
.btn svg{width:15px;height:15px;stroke-width:2;flex:none}
/* .primary and .steel are both navy here. The portal used two different blues
   for "the main action" and "the account action"; on a neutral page one is
   enough, and keeping both selectors means app-ui.js needs no changes. */
.btn.primary,.btn.steel{background:var(--navy);color:#fff;box-shadow:var(--shadow-xs)}
.btn.primary:hover,.btn.steel:hover{background:var(--navy-2)}
.btn.ghost{background:var(--bg-default);border-color:var(--border-default);color:var(--content-default);box-shadow:var(--shadow-xs)}
.btn.ghost:hover{background:var(--bg-muted);color:var(--content-emphasis);border-color:var(--border-emphasis)}
.btn.sm{padding:6px 10px;font-size:12.5px;border-radius:7px}
.btn.danger{color:var(--due-tx);background:var(--bg-default);border-color:var(--border-default);box-shadow:var(--shadow-xs)}
.btn.danger:hover{background:var(--due-bg);border-color:var(--due-bd)}
.btn:disabled{opacity:.45;cursor:not-allowed;box-shadow:none}

/* =================================================== stat tiles & panels == */

/* Eight tiles on a four-column grid: pressure on the top row, the size of the
   book on the second. Each one is a button, because a number you cannot open
   is decoration. */
.tiles{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin-bottom:22px}
/* Flex, not block: a button centres its contents in any spare height, so on a
   row of tiles the short ones would sit a few pixels below the tall ones and
   the labels would not line up. */
.tile{
  display:flex;flex-direction:column;align-items:stretch;justify-content:flex-start;
  width:100%;text-align:left;font:inherit;cursor:pointer;
  background:var(--bg-default);border:1px solid var(--border-subtle);
  border-radius:var(--radius);padding:15px 16px;box-shadow:var(--shadow-xs);
  transition:border-color .15s,box-shadow .15s;
}
.tile:hover{border-color:var(--border-default);box-shadow:var(--shadow-sm)}
.tile .k{
  display:block;font-size:11.5px;font-weight:600;color:var(--content-subtle);
  letter-spacing:.03em;text-transform:uppercase;
}
.tile .v{
  display:block;
  font-size:27px;color:var(--content-emphasis);margin-top:6px;font-weight:600;
  line-height:1.1;font-variant-numeric:tabular-nums;letter-spacing:-.02em;
}
.tile .v.warn{color:var(--warn)}
.tile .v.bad{color:var(--due)}
.tile .v.good{color:var(--ok)}
.tile .d{display:block;font-size:12.5px;color:var(--content-subtle);margin-top:4px}

.panel{
  background:var(--bg-default);border:1px solid var(--border-subtle);
  border-radius:var(--radius);box-shadow:var(--shadow-xs);
  margin-bottom:20px;overflow:hidden;
}
.panel-h{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  padding:14px 18px;border-bottom:1px solid var(--border-muted);
}
.panel-h h3{font-size:15px}
.panel-h .cap{font-size:12.5px;color:var(--content-subtle)}
.panel-h .btn{margin-left:auto}
.panel-b{padding:18px}
.panel-grid{display:grid;grid-template-columns:1fr 1fr;gap:20px}

/* ========================================================= statutory rail = */

.rail-row{
  display:grid;grid-template-columns:1fr auto;gap:14px;align-items:center;
  padding:13px 18px;border-bottom:1px solid var(--border-muted);
  transition:background .12s;
}
.rail-row:last-child{border-bottom:none}
.rail-row:hover{background:var(--bg-muted);cursor:pointer}
.rail-row .who b{font-weight:600;color:var(--content-emphasis);display:block;font-size:13.5px}
.rail-row .who small{display:block;color:var(--content-subtle);font-size:12.5px;margin-top:2px}
.rail-meta{text-align:right;font-size:12.5px;color:var(--content-subtle)}
.rail-meta b{display:block;font-size:13.5px;color:var(--content-emphasis);font-weight:600}
.gauge{display:flex;flex-direction:column;gap:5px;min-width:150px}
.gauge .lab{display:flex;justify-content:space-between;font-size:12px;font-weight:600;gap:8px}
.gauge .lab .st{color:var(--content-subtle);font-weight:500}
.gauge .lab .d{color:var(--ok-tx)}
.gauge.soon .lab .d{color:var(--warn-tx)}
.gauge.overdue .lab .d{color:var(--due-tx)}
.bar{height:5px;border-radius:99px;background:var(--bg-emphasis);overflow:hidden}
.bar i{display:block;height:100%;border-radius:99px;background:var(--ok);transition:width .3s}
.gauge.soon .bar i{background:var(--warn)}
.gauge.overdue .bar i{background:var(--due)}

/* ================================================================== tables */

.tbl{width:100%;border-collapse:collapse}
.tbl th{
  text-align:left;padding:9px 18px;background:var(--bg-muted);
  border-bottom:1px solid var(--border-subtle);
  font-size:11px;font-weight:600;color:var(--content-subtle);
  text-transform:uppercase;letter-spacing:.05em;white-space:nowrap;
}
.tbl td{padding:12px 18px;border-bottom:1px solid var(--border-muted);font-size:13.5px;vertical-align:top}
.tbl tr:last-child td{border-bottom:none}
.tbl tr.clickable{cursor:pointer}
.tbl tr.clickable:hover td{background:var(--bg-muted)}
.tbl .org{font-weight:600;color:var(--content-emphasis)}
.tbl .num{font-variant-numeric:tabular-nums}
.muted{color:var(--content-subtle);font-size:13px}

/* =================================================================== pills */
/* Squared off rather than fully round: dub's badges read as labels, and a
   label is what these are. */

.pill{
  display:inline-flex;align-items:center;gap:5px;padding:2px 8px;
  border-radius:6px;font-size:11.5px;font-weight:600;white-space:nowrap;
  background:var(--bg-subtle);color:var(--content-default);
}
.pill.steel{background:var(--steel-bg);color:var(--navy)}
.pill.slate{background:var(--bg-subtle);color:var(--content-subtle)}
.pill.warn{background:var(--warn-bg);color:var(--warn-tx)}
.pill.due{background:var(--due-bg);color:var(--due-tx)}
.pill.ok{background:var(--ok-bg);color:var(--ok-tx)}
.pill.dot::before{content:"";width:6px;height:6px;border-radius:99px;background:currentColor;flex:none}

/* ============================================================ empty states */

.empty{padding:48px 26px;text-align:center;max-width:520px;margin:0 auto}
.empty .ic{
  width:44px;height:44px;border-radius:12px;margin:0 auto 14px;
  display:flex;align-items:center;justify-content:center;
  background:var(--bg-subtle);border:1px solid var(--border-subtle);color:var(--content-subtle);
}
.empty .ic svg{width:21px;height:21px;stroke-width:1.7}
.empty h3{font-size:17px;margin-bottom:7px}
.empty p{color:var(--content-subtle);font-size:13.5px;margin-bottom:18px;line-height:1.6}
.empty .btn{margin:0 3px}
.empty-row td{padding:0!important;background:var(--bg-default)!important}

/* ================================================================= filters */

.filters{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  padding:12px 18px;border-bottom:1px solid var(--border-muted);
}
.filters select,.filters input[type=search]{
  padding:7px 10px;border:1px solid var(--border-default);border-radius:var(--radius-sm);
  background:var(--bg-default);color:var(--content-default);font-size:13px;
}
.filters select:focus,.filters input[type=search]:focus{
  outline:none;border-color:var(--navy);box-shadow:var(--ring);
}
.filters .spacer{flex:1}

/* ================================================================== modals */

.scrim{
  position:fixed;inset:0;background:rgba(23,23,23,.45);
  display:none;align-items:flex-start;justify-content:center;
  padding:40px 18px;z-index:120;overflow:auto;
  -webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);
}
.scrim.on{display:flex}
.modal{
  background:var(--bg-default);border:1px solid var(--border-subtle);
  border-radius:var(--radius-lg);width:100%;max-width:520px;
  box-shadow:var(--shadow-lg);animation:modalIn .2s cubic-bezier(.16,1,.3,1);
}
@keyframes modalIn{from{opacity:0;transform:scale(.97)}to{opacity:1;transform:scale(1)}}
.modal.wide{max-width:760px}
.modal.widest{max-width:1180px}
.modal-h{
  display:flex;align-items:flex-start;gap:12px;
  padding:18px 20px 15px;border-bottom:1px solid var(--border-muted);
}
.modal-h h3{font-size:16.5px}
.modal-h .sub{font-size:12.5px;color:var(--content-subtle);margin-top:3px;line-height:1.5}
.modal-x{
  margin-left:auto;color:var(--content-subtle);font-size:20px;line-height:1;
  padding:3px 8px;border-radius:7px;transition:background .15s,color .15s;
}
.modal-x:hover{background:var(--bg-subtle);color:var(--content-emphasis)}
.modal-b{padding:20px;display:flex;flex-direction:column;gap:15px}
.modal-f{
  display:flex;align-items:center;justify-content:flex-end;gap:9px;flex-wrap:wrap;
  padding:14px 20px;border-top:1px solid var(--border-muted);background:var(--bg-muted);
  border-radius:0 0 var(--radius-lg) var(--radius-lg);
}
.modal-f .left{margin-right:auto}
.modal-f .cap{font-size:12.5px;color:var(--content-subtle);align-self:center}
.modal-f .cap.bad{color:var(--due-tx);font-weight:600}

/* ================================================================== fields */

.field{display:flex;flex-direction:column;gap:6px}
.field label{font-size:12.5px;font-weight:600;color:var(--content-emphasis)}
.field input,.field select,.field textarea{
  padding:9px 11px;border:1px solid var(--border-default);border-radius:var(--radius-sm);
  background:var(--bg-default);color:var(--content-emphasis);width:100%;
  transition:border-color .15s,box-shadow .15s;
}
.field input::placeholder,.field textarea::placeholder{color:var(--content-muted)}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:none;border-color:var(--navy);box-shadow:var(--ring);
}
.field textarea{resize:vertical;min-height:70px;line-height:1.55}
.field .hint{font-size:12px;color:var(--content-subtle);line-height:1.5}
.field .hint.good{color:var(--ok-tx);font-weight:600}
.field .hint.bad{color:var(--due-tx);font-weight:600}
.row2{display:grid;grid-template-columns:1fr 1fr;gap:13px}
.check{display:flex;align-items:flex-start;gap:9px;cursor:pointer;font-size:13.5px;color:var(--content-default)}
.check input{width:auto;margin-top:3px;flex:none;accent-color:var(--navy)}
.note{
  background:var(--bg-muted);border:1px solid var(--border-subtle);
  border-radius:var(--radius-sm);padding:11px 13px;font-size:12.5px;
  color:var(--content-default);line-height:1.6;
}
.note b{font-weight:600;color:var(--content-emphasis)}
.note.warn{background:var(--warn-bg);border-color:var(--warn-bd);color:#854d0e}
.note.warn b{color:#713f12}
.dl{display:grid;grid-template-columns:136px 1fr;gap:9px 14px;font-size:13.5px}
.dl dt{color:var(--content-subtle);font-weight:600}
.dl dd{color:var(--content-emphasis)}

/* ============================================================ doc chooser = */

.doc-grid{display:grid;grid-template-columns:1fr 1fr;gap:11px}
.doc-card{
  text-align:left;padding:14px 15px;border:1px solid var(--border-subtle);
  border-radius:var(--radius);background:var(--bg-default);box-shadow:var(--shadow-xs);
  transition:border-color .15s,box-shadow .15s;
}
.doc-card:hover{border-color:var(--navy);box-shadow:var(--shadow-md)}
.doc-card b{display:block;color:var(--content-emphasis);font-size:14px;margin-bottom:4px}
.doc-card span{display:block;color:var(--content-subtle);font-size:12.5px;line-height:1.5}
.doc-card .fmt{
  display:inline-block;margin-top:9px;font-size:11px;font-weight:700;
  letter-spacing:.05em;text-transform:uppercase;color:var(--content-subtle);
  background:var(--bg-subtle);padding:2px 7px;border-radius:5px;
}

/* ========================================================== privacy radar = */

.radar-summary{display:flex;flex-wrap:wrap;gap:14px;margin-left:auto}
.radar-count{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;color:var(--content-default)}
.sev{width:8px;height:8px;border-radius:99px;flex:none;display:inline-block}
.sev-critical{background:var(--due)}
.sev-high{background:#ea580c}
.sev-medium{background:var(--warn)}
.sev-low{background:var(--content-muted)}
.radar-tbl td{padding:11px 18px}
.radar-tbl td.ta-c{width:34px;text-align:center;vertical-align:middle}
.radar-tbl tr:first-child td{border-top:none}

/* The next move, not a decoration: it sits quiet until the row is under the
   cursor, so eight of them do not read as eight buttons competing. */
.radar-tbl td.radar-next{
  width:1%;white-space:nowrap;text-align:right;vertical-align:middle;
  font-size:12.5px;font-weight:600;color:var(--content-muted);
}
.radar-row:hover td.radar-next,
.radar-row:focus-within td.radar-next{color:var(--steel)}

/* ========================================================= recent activity = */

.feed{padding:4px 0}
.feed-row{
  display:grid;grid-template-columns:auto 1fr auto;gap:11px;align-items:baseline;
  padding:9px 18px;font-size:13px;color:var(--content-default);
}
.feed-row + .feed-row{border-top:1px solid var(--border-muted)}
.feed-row .dot{
  width:6px;height:6px;border-radius:99px;background:var(--border-default);
  position:relative;top:-2px;
}
.feed-row:first-child .dot{background:var(--steel)}
.feed-row .what{min-width:0}
.feed-row .when{
  font-size:12px;color:var(--content-subtle);white-space:nowrap;
  font-variant-numeric:tabular-nums;
}

/* ================================================================== tabs = */
/* A raised current tab on a quiet track, joined to the panel below it. */

.tabs{
  display:flex;flex-wrap:wrap;gap:3px;padding:10px 14px 0;
  border-bottom:1px solid var(--border-muted);
}
.tab{
  display:inline-flex;align-items:center;gap:7px;padding:7px 12px;
  border:1px solid transparent;border-bottom:none;
  border-radius:9px 9px 0 0;font-size:13px;font-weight:600;
  color:var(--content-subtle);transition:background .15s,color .15s;
}
.tab:hover{color:var(--content-emphasis);background:var(--bg-muted)}
.tab.on{
  background:var(--bg-default);border-color:var(--border-subtle);
  color:var(--navy);margin-bottom:-1px;padding-bottom:8px;
}
.tab .count{
  background:var(--bg-emphasis);color:var(--content-subtle);font-size:11px;
  font-weight:700;padding:1px 6px;border-radius:99px;font-variant-numeric:tabular-nums;
}
.tab.on .count{background:var(--navy);color:#fff}

/* =========================================================== health score = */

.score-head{display:flex;align-items:center;gap:14px;margin-bottom:16px}
.score-total{
  width:58px;height:58px;border-radius:14px;flex:none;
  display:flex;align-items:center;justify-content:center;
  font-size:21px;font-weight:700;font-variant-numeric:tabular-nums;
  background:var(--bg-subtle);color:var(--content-emphasis);
}
.score-total.ok{background:var(--ok-bg);color:var(--ok-tx)}
.score-total.warn{background:var(--warn-bg);color:var(--warn-tx)}
.score-total.due{background:var(--due-bg);color:var(--due)}
.score-head b{color:var(--content-emphasis);font-size:14.5px}
.score-head .muted{display:block;font-size:12.5px;line-height:1.5;margin-top:2px}

.score-rows{display:flex;flex-direction:column;gap:10px}
.score-row{display:grid;grid-template-columns:1fr 120px 46px 52px;gap:12px;align-items:center}
.score-label b{display:block;font-size:13.5px;color:var(--content-emphasis);font-weight:600}
.score-label .muted{display:block;font-size:12px;line-height:1.45}
.score-weight{font-size:12px;text-align:right;font-variant-numeric:tabular-nums;color:var(--content-subtle)}
.score-bar{height:5px;border-radius:99px;background:var(--bg-emphasis);overflow:hidden}
.score-bar i{display:block;height:100%;border-radius:99px;background:var(--navy)}
.score-val{
  font-size:13.5px;font-weight:700;text-align:right;color:var(--content-emphasis);
  font-variant-numeric:tabular-nums;
}
.score-row.unassessed{opacity:.5}
.score-row.unassessed .score-val{color:var(--content-muted);font-weight:500}
@media (max-width:640px){
  .score-row{grid-template-columns:1fr 60px;gap:4px}
  .score-bar,.score-weight{display:none}
}

/* ================================================= alert bands (dashboard) */
/* The 72-hour breach window and the backup nudge — things that need to be seen
   before the rest of the page, not found in a list. */

.alert{
  border:1px solid var(--warn-bd);background:var(--warn-bg);
  border-radius:var(--radius);padding:15px 17px;margin-bottom:20px;
}
.alert.bad{border-color:var(--due-bd);background:var(--due-bg)}
.alert-h{margin-bottom:11px}
.alert-h b{display:block;color:#854d0e;font-size:14.5px;font-weight:600}
.alert.bad .alert-h b{color:var(--due-tx)}
.alert-h span{display:block;color:var(--warn-tx);font-size:13px;margin-top:3px;line-height:1.5}
.alert.bad .alert-h span{color:#b91c1c}
.alert-rows{display:flex;flex-direction:column;gap:6px}
.alert-row{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  width:100%;text-align:left;background:var(--bg-default);
  border:1px solid var(--border-subtle);border-radius:var(--radius-sm);
  padding:9px 12px;font-size:13px;color:var(--content-default);
  transition:border-color .15s,box-shadow .15s;
}
.alert-row:hover{border-color:var(--border-emphasis);box-shadow:var(--shadow-xs)}
.alert-row .r{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.alert-row .r b{color:var(--content-emphasis);font-weight:600}
.alert-actions{display:flex;gap:9px;flex-wrap:wrap}

/* -------------------------------------------------- stopping the clock --- */

.stop-clock{
  border:1px solid var(--border-subtle);border-radius:var(--radius);
  background:var(--bg-muted);padding:15px 16px;
}
.stop-clock h4{
  font-family:'Hanken Grotesk',sans-serif;font-size:11.5px;font-weight:700;
  letter-spacing:.05em;text-transform:uppercase;color:var(--content-subtle);margin-bottom:5px;
}
.stop-clock .hint{display:block;font-size:12.5px;color:var(--content-subtle);margin-bottom:12px;line-height:1.5}
.stop-clock .field label{font-size:12px}

/* ======================================================= disclosure bundle */

.dropzone{
  border:1px dashed var(--border-default);border-radius:var(--radius);
  background:var(--bg-muted);padding:28px 18px;text-align:center;cursor:pointer;
  transition:border-color .15s,background .15s;
}
.dropzone:hover{border-color:var(--navy);background:var(--steel-bg)}
.dropzone.over{border-color:var(--navy);background:var(--steel-bg);border-style:solid}
.dropzone b{display:block;color:var(--content-emphasis);font-size:14px;margin-bottom:4px}
.dropzone span{display:block;color:var(--content-subtle);font-size:12.5px;line-height:1.5}

.doc-tbl{margin-top:14px;border:1px solid var(--border-subtle);border-radius:var(--radius);overflow:hidden}
.doc-tbl th{padding:9px 12px}
.doc-tbl td{padding:10px 12px;font-size:13px}
.doc-tbl td.ta-r{text-align:right}
.doc-tbl .dn{font-size:13px;color:var(--content-emphasis);word-break:break-all;font-weight:600}
.doc-tbl .muted{font-size:12px}
.doc-tbl select{
  padding:6px 8px;border:1px solid var(--border-default);border-radius:7px;
  background:var(--bg-default);color:var(--content-default);font-size:12.5px;
}
.note-in{
  width:100%;margin-top:6px;padding:7px 9px;border:1px solid var(--border-default);
  border-radius:7px;font-size:12.5px;color:var(--content-emphasis);background:var(--bg-default);
}
.note-in:focus,.doc-tbl select:focus{outline:none;border-color:var(--navy);box-shadow:var(--ring)}

/* ========================================================= response pack == */
/* Decisions on the left, the document they produce on the right. The preview
   is deliberately styled like paper rather than like the app: the practitioner
   is reading a draft response, not a form. */

.pk-grid{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);
  gap:20px;align-items:start;
}
.pk-form{display:flex;flex-direction:column;gap:15px;min-width:0}
.pk-form > .hint{font-size:12.5px;color:var(--content-subtle);line-height:1.55}

.pk-checks{display:grid;grid-template-columns:1fr 1fr;gap:8px 14px}
.pk-check span{display:block;line-height:1.35}
.pk-check span b{display:block;font-size:13px;font-weight:600;color:var(--content-emphasis)}
.pk-check span em{display:block;font-style:normal;font-size:11.5px;color:var(--content-subtle)}

.pk-exlist{display:flex;flex-direction:column;gap:8px}
.pk-ex{
  border:1px solid var(--border-subtle);border-radius:var(--radius-sm);
  background:var(--bg-default);padding:10px 12px;
  transition:border-color .15s,background .15s;
}
.pk-ex.on{border-color:var(--navy);background:var(--steel-bg)}
.pk-ex span{display:block;line-height:1.35}
.pk-ex span b{display:block;font-size:13px;font-weight:600;color:var(--content-emphasis)}
.pk-ex span em{
  display:block;font-style:normal;font-size:11.5px;font-weight:600;color:var(--navy);margin-top:2px;
}
.pk-ex span i{display:block;font-style:normal;font-size:11.5px;color:var(--content-subtle);margin-top:3px}
.pk-ex .pk-note{display:none}
.pk-ex.on .pk-note{
  display:block;width:100%;margin-top:9px;padding:7px 9px;
  border:1px solid var(--border-default);border-radius:7px;font-size:12.5px;background:var(--bg-default);
}
.pk-ex .pk-note:focus{outline:none;border-color:var(--navy);box-shadow:var(--ring)}

.pk-preview{
  border:1px solid var(--border-subtle);border-radius:var(--radius);background:var(--bg-muted);
  max-height:66vh;overflow:auto;padding:16px;min-width:0;
}
.pk-gaps{
  border:1px solid var(--warn-bd);background:var(--warn-bg);border-radius:var(--radius-sm);
  padding:12px 13px;margin-bottom:14px;
}
.pk-gaps.clear{border-color:var(--ok-bd);background:var(--ok-bg)}
.pk-gaps h4{
  font-family:'Hanken Grotesk',sans-serif;font-size:11.5px;font-weight:700;
  letter-spacing:.05em;text-transform:uppercase;color:var(--warn-tx);margin-bottom:7px;
}
.pk-gaps.clear h4{color:var(--ok-tx)}
.pk-gaps.clear p{font-size:12.5px;color:var(--ok-tx)}
.pk-gaps ul{list-style:none;display:flex;flex-direction:column;gap:5px}
.pk-gaps li{font-size:12.5px;color:#854d0e;line-height:1.45;padding-left:15px;position:relative}
.pk-gaps li::before{content:"";position:absolute;left:0;top:6px;width:7px;height:7px;border-radius:50%}
.pk-gaps li.high::before{background:var(--due)}
.pk-gaps li.medium::before{background:var(--warn)}
.pk-gaps li.low::before{background:var(--content-muted)}

.pk-doc{
  background:var(--bg-default);border:1px solid var(--border-subtle);border-radius:var(--radius-sm);
  padding:19px 20px;font-size:13px;line-height:1.65;color:var(--content-default);
}
.pk-sec + .pk-sec{margin-top:16px;padding-top:15px;border-top:1px solid var(--border-muted)}
.pk-sec h4{font-size:14.5px;margin-bottom:7px}
.pk-sec h5{
  font-family:'Hanken Grotesk',sans-serif;font-size:11.5px;font-weight:700;
  letter-spacing:.04em;text-transform:uppercase;color:var(--content-subtle);margin:12px 0 5px;
}
.pk-sec p{margin-bottom:8px}
.pk-sec ul{margin:0 0 9px 17px;display:flex;flex-direction:column;gap:2px}
.pk-sec li{font-size:12.5px}
.pk-sec.internal{
  margin-top:18px;padding:14px 15px;border:1px dashed var(--border-default);
  border-radius:var(--radius-sm);background:var(--bg-muted);
}
.pk-kv{display:grid;grid-template-columns:130px 1fr;gap:10px;margin-bottom:4px}
.pk-kv span{color:var(--content-subtle);font-weight:600;font-size:12.5px}
.pk-todo{
  color:#854d0e;font-style:italic;background:var(--warn-bg);
  border-left:2px solid var(--warn);padding:7px 10px;border-radius:0 5px 5px 0;
}
.pk-tbl{margin:6px 0 10px;border:1px solid var(--border-subtle);border-radius:8px;overflow:hidden}
.pk-tbl th{padding:7px 9px;font-size:10.5px}
.pk-tbl td{padding:7px 9px;font-size:12px;vertical-align:top}

/* ================================================================== charts */

.vz-plot{width:100%}
.vz-empty{
  padding:24px 16px;text-align:center;color:var(--content-subtle);font-size:13px;
  background:var(--bg-muted);border-radius:var(--radius);border:1px dashed var(--border-default);
}
.vz-legend{display:flex;flex-wrap:wrap;gap:14px;margin-top:12px}
.vz-leg-item{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;color:var(--content-subtle)}
.vz-leg-item b{color:var(--content-emphasis);font-weight:600}
.vz-sw{width:9px;height:9px;border-radius:3px;flex:none}
.vz-leg-ic{font-size:10px;color:var(--content-muted);width:11px;text-align:center}
.vz-table-wrap{margin-top:12px}
.vz-table-btn{font-size:12px;font-weight:600;color:var(--navy);text-decoration:underline;padding:2px 0}
.vz-table{width:100%;border-collapse:collapse;margin-top:9px;font-size:12.5px}
.vz-table th,.vz-table td{text-align:left;padding:6px 9px;border-bottom:1px solid var(--border-muted)}
.vz-table thead th{color:var(--content-subtle);font-size:11px;text-transform:uppercase;letter-spacing:.05em}
.vz-table td{font-variant-numeric:tabular-nums}
.vz-num{font-variant-numeric:tabular-nums}
.vz-tip{
  position:fixed;top:0;left:0;z-index:90;pointer-events:none;opacity:0;
  background:var(--content-emphasis);color:#fff;padding:7px 11px;border-radius:8px;
  font-size:12.5px;line-height:1.45;box-shadow:var(--shadow-md);
  transition:opacity .12s;max-width:230px;
}
.vz-tip.on{opacity:1}
.vz-tip b{display:block;font-weight:700}
.vz-tip span{color:#d4d4d4}

/* ==================================================================== tour */

.tour-root{position:fixed;inset:0;z-index:150;display:none}
.tour-root.on{display:block}
.tour-scrim{position:absolute;inset:0;background:rgba(23,23,23,.5)}
.tour-spot{
  position:fixed;border-radius:10px;pointer-events:none;opacity:0;
  box-shadow:0 0 0 3px rgba(255,255,255,.9),0 0 0 9999px rgba(23,23,23,.5);
  transition:all .22s ease;
}
.tour-pop{
  position:fixed;width:334px;max-width:calc(100vw - 28px);background:var(--bg-default);
  border:1px solid var(--border-subtle);border-radius:var(--radius-lg);
  padding:19px 20px;box-shadow:var(--shadow-lg);
}
.tour-step-count{
  font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--content-muted);margin-bottom:7px;
}
.tour-pop h3{font-size:16.5px;margin-bottom:7px}
.tour-body{font-size:13.5px;color:var(--content-default);line-height:1.6}
.tour-actions{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:18px}
.tour-nav{display:flex;gap:8px}
.tour-skip{font-size:12.5px;color:var(--content-subtle);text-decoration:underline}
.tour-back,.tour-next{padding:7px 13px;border-radius:var(--radius-sm);font-size:13px;font-weight:600}
.tour-back{background:var(--bg-default);border:1px solid var(--border-default);color:var(--content-default)}
.tour-back:hover{background:var(--bg-muted)}
.tour-next{background:var(--navy);color:#fff}
.tour-next:hover{background:var(--navy-2)}
body.tour-locked{overflow:hidden}

/* ================================================ utilities (no inline CSS) */

.u-dot{color:var(--content-muted)}
.u-mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}
.u-mt-10{margin-top:10px}
.u-mt-14{margin-top:14px}
.u-mb-14{margin-bottom:14px}

/* =================================================================== toast */

.toast{
  position:fixed;bottom:22px;left:50%;transform:translateX(-50%) translateY(18px);
  background:var(--content-emphasis);color:#fff;padding:11px 18px;border-radius:10px;
  font-size:13.5px;font-weight:500;box-shadow:var(--shadow-lg);
  opacity:0;transition:.24s;z-index:160;pointer-events:none;max-width:88vw;text-align:center;
}
.toast.on{opacity:1;transform:translateX(-50%) translateY(0)}
.toast.has-action{pointer-events:auto;display:flex;align-items:center;gap:14px}
.toast-action{
  color:#93c5fd;font-weight:700;font-size:13.5px;text-decoration:underline;
  padding:2px 4px;border-radius:5px;flex:none;
}
.toast-action:hover{color:#fff}

/* Account-screen progress. A multi-second wait behind a line of small grey
   hint text reads as a frozen page; this is deliberately unmissable, and the
   spinner keeps moving so it is obvious something is still happening. */
.acct-busy{
  display:flex;align-items:center;gap:10px;margin:16px 0 4px;
  padding:11px 13px;border-radius:var(--radius-sm);
  background:var(--steel-bg);border:1px solid var(--steel-bd);
  color:var(--navy);font-size:13px;font-weight:600;
}
.acct-busy[hidden]{display:none}
.acct-busy .spin{
  flex:none;width:15px;height:15px;border-radius:50%;
  border:2px solid #c7d8e7;border-top-color:var(--navy);animation:acctSpin .8s linear infinite;
}
@keyframes acctSpin{to{transform:rotate(360deg)}}
.acct-busy small{display:block;font-weight:400;color:var(--content-subtle);font-size:12px;margin-top:2px}
@media (prefers-reduced-motion:reduce){.acct-busy .spin{animation:none;border-top-color:#c7d8e7}}

/* ========================================================= conflict dialog */
/* veld-sync-spec.md §8. Its own scrim rather than the portal's modal: a
   divergence surfaces during sign-in, before app-ui.js is on the page, and
   this dialog must not be dismissible — the app's modal closes on Escape
   and on a backdrop click, and either would leave the workspace in exactly the
   ambiguous state the dialog exists to end. */

.cf-scrim{
  position:fixed;inset:0;background:rgba(23,23,23,.55);display:flex;
  align-items:flex-start;justify-content:center;padding:38px 18px;
  z-index:200;overflow:auto;
  -webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);
}
.cf-modal{
  background:var(--bg-default);border:1px solid var(--border-subtle);
  border-radius:var(--radius-lg);width:100%;max-width:840px;box-shadow:var(--shadow-lg);
}
.cf-h{padding:20px 22px 16px;border-bottom:1px solid var(--border-muted)}
.cf-h h3{font-size:19px}
.cf-h p{font-size:13.5px;color:var(--content-default);margin-top:8px;max-width:64ch;line-height:1.6}

.cf-diff{padding:16px 22px;background:var(--warn-bg);border-bottom:1px solid var(--warn-bd)}
.cf-diff h4{
  font-family:'Hanken Grotesk',system-ui,sans-serif;font-size:11.5px;
  font-weight:700;color:var(--warn-tx);text-transform:uppercase;letter-spacing:.05em;
}
.cf-diff ul{margin:8px 0 0 17px}
.cf-diff li{font-size:13.5px;color:#854d0e;margin-top:3px}

.cf-sides{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--border-subtle)}
.cf-side{background:var(--bg-default);padding:19px 21px;display:flex;flex-direction:column;gap:11px}
.cf-side h4{font-size:15.5px}
.cf-note{font-size:12.5px;color:var(--content-subtle);margin-top:-7px}
.cf-when{font-size:13px;color:var(--content-default);font-weight:600}

.cf-counts{width:100%;border-collapse:collapse}
.cf-counts td{padding:6px 0;border-bottom:1px solid var(--border-muted);font-size:13.5px}
.cf-counts td.num{text-align:right;font-variant-numeric:tabular-nums;font-weight:600}
.cf-counts tr.cf-total td{
  border-bottom:none;border-top:1px solid var(--border-default);
  padding-top:8px;font-weight:700;color:var(--content-emphasis);
}

.cf-recent{border-top:1px solid var(--border-muted);padding-top:11px}
.cf-recent-h{
  font-size:11px;font-weight:700;color:var(--content-subtle);
  text-transform:uppercase;letter-spacing:.05em;
}
.cf-recent ul{margin:6px 0 0 16px}
.cf-recent li{font-size:12.5px;color:var(--content-subtle);margin-top:2px}

.cf-pick{margin-top:auto;width:100%;justify-content:center}

.cf-f{
  display:flex;align-items:center;gap:13px;padding:15px 22px;flex-wrap:wrap;
  border-top:1px solid var(--border-muted);background:var(--bg-muted);
  border-radius:0 0 var(--radius-lg) var(--radius-lg);
}
.cf-warn{font-size:12.5px;color:var(--due-tx);font-weight:600}

@media (max-width:720px){
  .cf-sides{grid-template-columns:1fr}
}

/* ============================================================= sync status */
/* Sits above the toast so a save confirmation and a toast never fight for the
   same strip of screen. */

.sync-status{
  position:fixed;bottom:64px;left:50%;transform:translateX(-50%) translateY(14px);
  background:var(--content-emphasis);color:#fff;padding:9px 16px;border-radius:9px;
  font-size:12.5px;font-weight:500;box-shadow:var(--shadow-md);
  opacity:0;transition:.24s;z-index:155;pointer-events:none;
  max-width:88vw;text-align:center;
}
.sync-status.on{opacity:1;transform:translateX(-50%) translateY(0)}
.sync-status.warn{background:var(--warn);pointer-events:auto}

/* =============================================================== assistant */
/* The log scrolls, the composer does not. A conversation that pushes its own
   input off the bottom of a long answer is the single most irritating thing a
   chat UI does, and it is avoided by giving the panel a height rather than
   letting it grow. */

.asst{display:flex;flex-direction:column;height:calc(100vh - 190px);min-height:420px;overflow:hidden}
.asst-log{flex:1;overflow-y:auto;padding:20px;display:flex;flex-direction:column;gap:16px}

.asst-empty{margin:auto;text-align:center;max-width:520px;padding:20px 0}
.asst-empty h3{font-size:17px;margin-bottom:8px}
.asst-empty p{font-size:13.5px;color:var(--content-subtle);margin-bottom:18px;line-height:1.6}
.asst-suggest{display:flex;flex-wrap:wrap;gap:8px;justify-content:center}

.asst-turn{display:flex;flex-direction:column;gap:7px;max-width:82%}
.asst-turn.you{align-self:flex-end;align-items:flex-end}
.asst-turn.veld{align-self:flex-start}

.asst-bubble{
  padding:12px 15px;border-radius:var(--radius);font-size:14px;line-height:1.65;
  background:var(--bg-muted);border:1px solid var(--border-subtle);color:var(--content-default);
}
.asst-turn.you .asst-bubble{background:var(--navy);color:#fff;border-color:var(--navy)}
.asst-bubble.err{background:var(--due-bg);border-color:var(--due-bd);color:var(--due-tx)}
.asst-bubble p + p{margin-top:10px}

/* What the assistant looked at, while it looks. §08 asks the interface to name
   what it can see; showing the lookups as they happen does that better than a
   paragraph of policy nobody reads. */
.asst-tools{display:flex;flex-wrap:wrap;gap:6px}
.asst-tools span{
  font-size:11px;font-weight:600;color:var(--content-subtle);background:var(--bg-subtle);
  border:1px solid var(--border-subtle);padding:2px 8px;border-radius:6px;
}

.asst-cites{
  border-left:2px solid var(--border-subtle);padding-left:12px;display:flex;
  flex-direction:column;gap:5px;align-items:flex-start;
}
.asst-cites-h{
  font-size:10.5px;font-weight:700;color:var(--content-muted);
  text-transform:uppercase;letter-spacing:.05em;
}
.asst-cite{
  font-size:13px;color:var(--navy);text-align:left;padding:2px 0;font-weight:500;
  border-bottom:1px solid transparent;
}
.asst-cite:hover{border-bottom-color:var(--navy)}

.asst-foot{border-top:1px solid var(--border-muted);padding:14px 20px;background:var(--bg-muted)}
.asst-form{display:flex;gap:9px}
.asst-form input{
  flex:1;padding:10px 13px;border:1px solid var(--border-default);
  border-radius:var(--radius-sm);background:var(--bg-default);
}
.asst-form input:focus{outline:none;border-color:var(--navy);box-shadow:var(--ring)}
.asst-form input:disabled{background:var(--bg-subtle);color:var(--content-muted)}
.asst-meta{font-size:12px;color:var(--content-subtle);margin-top:9px}
.asst-usage{color:var(--navy);font-weight:600}

@media (max-width:760px){
  .asst{height:calc(100vh - 150px)}
  .asst-turn{max-width:95%}
}

/* ================================================================= billing */
/* Deliberately plain. A plan panel that looks like a pricing page is a plan
   panel that is selling to someone who has already bought. */

.plan-now{
  display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:15px 16px;border:1px solid var(--border-subtle);border-radius:var(--radius);
  background:var(--bg-muted);flex-wrap:wrap;
}
.plan-name{font-family:'Spectral',Georgia,serif;font-size:16.5px;font-weight:600;color:var(--content-emphasis)}
.plan-sub{font-size:12.5px;color:var(--content-subtle);margin-top:3px}

.plan-offers{display:flex;flex-direction:column;gap:9px}
.plan-offer{
  display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:13px 16px;border:1px solid var(--border-subtle);border-radius:var(--radius);
  flex-wrap:wrap;transition:border-color .15s,box-shadow .15s;
}
.plan-offer:hover{border-color:var(--border-default);box-shadow:var(--shadow-xs)}

/* The secondary route under a plan button. Practice includes onboarding and
   house-style template work, so a conversation is still a legitimate way in
   — it just should not be the ONLY way in. */
.tier-alt{margin:10px 0 0;text-align:center;font-size:13px}
.tier-alt a{color:var(--content-subtle);text-decoration:underline}
.tier-alt a:hover{color:var(--content-emphasis)}

/* ========================================================= client workspace */
/* The header is the thing that makes nine tabs feel like one workspace: it
   does not move, and only the panel underneath changes. */

.chead{
  display:grid;grid-template-columns:1fr auto auto;gap:16px 20px;align-items:center;
  padding:0 0 18px;margin-bottom:2px;border-bottom:1px solid var(--border-muted);
}
.cback{
  grid-column:1/-1;display:inline-flex;align-items:center;gap:5px;align-self:start;
  font-size:12.5px;font-weight:600;color:var(--content-subtle);
  background:none;border:none;padding:0;cursor:pointer;
}
.cback:hover{color:var(--steel)}
.cback svg{width:15px;height:15px;stroke-width:2}
.chead-main h1{font-size:23px;line-height:1.2;letter-spacing:-.01em}
.chead-meta{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px 12px;margin-top:7px;
  font-size:12.5px;color:var(--content-subtle);
}
.chead-actions{display:flex;gap:8px;flex-wrap:wrap}

.chealth{
  display:flex;align-items:center;gap:12px;padding:10px 16px;cursor:pointer;
  border:1px solid var(--border-subtle);border-radius:var(--radius);
  background:var(--bg-default);font:inherit;text-align:left;
  transition:border-color .15s,box-shadow .15s;
}
.chealth:hover{border-color:var(--border-default);box-shadow:var(--shadow-xs)}
.chealth.none{cursor:default}
.chealth b{
  font-size:28px;font-weight:600;line-height:1;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;color:var(--content-emphasis);
}
.chealth b small{font-size:13px;font-weight:500;color:var(--content-muted);margin-left:1px}
.chealth.ok b{color:var(--ok)}
.chealth.warn b{color:var(--warn)}
.chealth.due b{color:var(--due)}
.chealth>span{
  display:block;font-size:11.5px;font-weight:600;letter-spacing:.03em;
  text-transform:uppercase;color:var(--content-subtle);
}
.chealth>span small{
  display:block;font-size:12.5px;font-weight:500;letter-spacing:0;
  text-transform:none;color:var(--content-default);margin-top:3px;
}

.ctabs{margin:14px 0 18px;flex-wrap:wrap}
.cbody>.panel:last-child{margin-bottom:0}
.cgrid{display:grid;grid-template-columns:1fr 1fr;gap:20px;align-items:start}
.cgrid>.panel{margin-bottom:0}

/* what changed */
.changes{list-style:none;display:flex;flex-direction:column;gap:9px}
.changes li{display:flex;align-items:baseline;gap:9px;font-size:13.5px;color:var(--content-default)}
.changes .plus{
  font-weight:700;color:var(--ok);font-size:14px;line-height:1;flex:none;
  font-variant-numeric:tabular-nums;
}

/* ================================================ data protection health == */

.hhead{display:flex;align-items:center;gap:16px;padding:16px 18px;border-bottom:1px solid var(--border-muted)}
.hrows{display:flex;flex-direction:column}
.hrow{
  display:grid;grid-template-columns:1fr auto 110px 34px 18px;gap:12px;align-items:center;
  width:100%;padding:11px 18px;background:none;border:none;border-top:1px solid var(--border-muted);
  font:inherit;text-align:left;cursor:pointer;transition:background .12s;
}
.hrows .hrow:first-child{border-top:none}
.hrow:hover{background:var(--bg-subtle)}
.hrow.on{background:var(--bg-subtle)}
.hrow.unassessed{opacity:.62}
.hrow-label b{display:block;font-size:13.5px;color:var(--content-emphasis);font-weight:600}
.hrow-label small{display:block;font-size:12px;color:var(--content-subtle);margin-top:2px;line-height:1.45}
.hrow-weight{font-size:12px;color:var(--content-muted);font-variant-numeric:tabular-nums}
.hbar{display:block;height:6px;border-radius:99px;background:var(--bg-muted);overflow:hidden}
.hbar i{display:block;height:100%;background:var(--steel);border-radius:99px}
.hrow-val{
  font-size:14.5px;font-weight:600;text-align:right;
  font-variant-numeric:tabular-nums;color:var(--content-emphasis);
}
.hrow-chev{width:16px;height:16px;stroke-width:2;color:var(--content-muted);transition:transform .15s}
.hrow.on .hrow-chev{transform:rotate(180deg)}

.hdetail{padding:4px 18px 18px;background:var(--bg-subtle);border-top:1px solid var(--border-muted)}
.hdetail .hint{margin-bottom:10px}
.hitems{list-style:none;display:flex;flex-direction:column;gap:1px;margin:10px 0}
.hitems li{
  display:grid;grid-template-columns:auto 1fr;gap:4px 10px;align-items:baseline;
  padding:8px 10px 8px 24px;background:var(--bg-default);position:relative;
  border-radius:6px;font-size:13px;
}
.hitems li::before{
  content:"";position:absolute;left:10px;top:13px;width:7px;height:7px;border-radius:99px;
}
.hitems li.ok::before{background:var(--ok)}
.hitems li.bad::before{background:var(--warn)}
.hitems li.na::before{background:var(--content-muted)}
.hitems li b{grid-column:1/-1;font-weight:600;color:var(--content-emphasis)}
.hitems li span{grid-column:1/-1;color:var(--content-subtle);font-size:12.5px;line-height:1.5}
.hitems li.clickable{cursor:pointer}
.hitems li.clickable:hover{background:var(--steel-bg)}

/* ==================================================== derived timeline ==== */

.chips{display:flex;flex-wrap:wrap;gap:7px}
.chip{
  padding:5px 11px;border-radius:99px;border:1px solid var(--border-subtle);
  background:var(--bg-default);font-size:12.5px;font-weight:500;color:var(--content-default);
  cursor:pointer;transition:background .12s,border-color .12s,color .12s;
}
.chip:hover{border-color:var(--border-default)}
.chip.on{background:var(--navy);border-color:var(--navy);color:#fff}

.tline{padding:0 0 4px}
.tline-m{
  padding:12px 18px 8px;font-size:11.5px;font-weight:700;letter-spacing:.05em;
  text-transform:uppercase;color:var(--content-muted);
  border-top:1px solid var(--border-muted);background:var(--bg-subtle);
}
.tline-row{
  display:grid;grid-template-columns:92px 84px 1fr;gap:14px;align-items:baseline;
  padding:10px 18px;border-top:1px solid var(--border-muted);transition:background .12s;
}
.tline-row:hover{background:var(--bg-subtle)}
.tline-d{font-size:12.5px;color:var(--content-subtle);font-variant-numeric:tabular-nums;white-space:nowrap}
.tline-k{
  font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  color:var(--content-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.tline-t{font-size:13.5px;color:var(--content-emphasis)}
.tline-t small{display:block;font-size:12.5px;color:var(--content-subtle);margin-top:2px;line-height:1.5}

/* ======================================================== meeting mode ==== */

.rev .tabs{margin-bottom:16px}
.revpane h4{
  font-size:13px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;
  color:var(--content-subtle);margin:20px 0 9px;
}
.revpane h4:first-child{margin-top:0}
.revlist{list-style:none;display:flex;flex-direction:column;gap:7px}
.revlist li{
  padding:9px 12px;border-radius:7px;background:var(--bg-subtle);
  border:1px solid var(--border-muted);position:relative;
}
.revlist li b{display:block;font-size:13.5px;font-weight:500;color:var(--content-emphasis);line-height:1.5}
.revlist li span{display:block;font-size:12.5px;color:var(--content-subtle);margin-top:2px}
.linkish{
  background:none;border:none;padding:0;margin-top:5px;cursor:pointer;
  font:inherit;font-size:12px;color:var(--steel);text-decoration:underline;
}

.revscore{
  display:grid;grid-template-columns:auto 1fr;gap:6px 16px;align-items:center;
  padding:16px;border-radius:var(--radius);background:var(--bg-subtle);
  border:1px solid var(--border-muted);margin-bottom:6px;
}
.revscore>b{font-size:34px;font-weight:600;line-height:1;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.revscore>b small{font-size:14px;font-weight:500;color:var(--content-muted)}
.revscore>span{font-size:11.5px;font-weight:600;letter-spacing:.03em;text-transform:uppercase;color:var(--content-subtle)}
.revscore>span small{display:block;font-size:13px;font-weight:500;letter-spacing:0;text-transform:none;color:var(--content-default);margin-top:2px}
.revcomp{grid-column:1/-1;display:flex;flex-wrap:wrap;gap:6px 16px;margin-top:6px}
.revcomp span{font-size:12px;color:var(--content-subtle)}
.revcomp b{margin-left:5px;color:var(--content-emphasis);font-variant-numeric:tabular-nums}

.revsum{
  padding:18px;border-radius:var(--radius);border:1px solid var(--border-muted);
  background:var(--bg-subtle);font-size:13.5px;line-height:1.65;
}
.revsum h4{margin-top:16px}
.revsum h4:first-child{margin-top:0;font-size:15px;text-transform:none;letter-spacing:0;color:var(--content-emphasis)}
.revsum p{margin-bottom:10px;color:var(--content-default)}
.revsum ul{margin:0 0 10px 18px}
.revsum li{margin-bottom:4px;color:var(--content-default)}

/* ======================================================= evidence packs === */

.packlist{display:flex;flex-direction:column;gap:7px;margin:4px 0 14px}
.packrow{
  display:grid;grid-template-columns:auto 1fr auto;gap:11px;align-items:start;
  padding:11px 13px;border:1px solid var(--border-subtle);border-radius:8px;
  background:var(--bg-default);transition:border-color .12s;
}
.packrow:hover{border-color:var(--border-default)}
.packrow b{display:block;font-size:13.5px;color:var(--content-emphasis);font-weight:600}
.packrow small{display:block;font-size:12.5px;color:var(--content-subtle);margin-top:2px;line-height:1.5}
.packn{
  font-size:12px;font-weight:600;color:var(--content-muted);
  font-variant-numeric:tabular-nums;padding-top:2px;
}

/* ======================================================== client exposure = */

.shrcats{display:flex;flex-direction:column;gap:9px;margin-top:12px}
.shrcat{border:1px solid var(--border-subtle);border-radius:8px;overflow:hidden}
.shrcat.on{border-color:var(--steel-bd);background:var(--steel-bg)}
.shrcat .packrow{border:none;background:none;margin:0}
.shrcaution{margin:0 13px 10px;color:var(--warn)}
.shritems{display:flex;flex-direction:column;gap:6px;padding:0 13px 13px 40px}
.shritems .check{font-size:13px}
.shrmaster{background:var(--bg-subtle)}

/* The client's-eye view. Deliberately styled as a different surface from the
   app around it, so nobody mistakes it for another Veld panel. */
.preview{
  border:1px solid var(--border-default);border-radius:10px;overflow:hidden;
  background:var(--bg-subtle);
}
.pvhead{
  padding:16px 18px;background:var(--navy);color:#fff;
}
.pvhead b{display:block;font-family:'Spectral',Georgia,serif;font-size:17px}
.pvhead span{display:block;font-size:12.5px;opacity:.75;margin-top:3px}
.pvblock{padding:15px 18px;border-top:1px solid var(--border-muted);background:var(--bg-default)}
.pvblock h4{
  font-size:11.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  color:var(--content-subtle);margin-bottom:10px;
}
.pvscore{display:flex;align-items:center;gap:12px}
.pvscore b{font-size:30px;font-weight:600;line-height:1;font-variant-numeric:tabular-nums}
.pvscore b small{font-size:13px;color:var(--content-muted)}
.pvscore span{font-size:13.5px;color:var(--content-default)}
.pvlist{list-style:none;display:flex;flex-direction:column;gap:9px}
.pvlist li{
  padding:10px 12px;border-radius:7px;background:var(--bg-subtle);
  border-left:3px solid var(--border-default);
}
.pvlist li.bad{border-left-color:var(--due)}
.pvlist li b{display:block;font-size:13.5px;font-weight:600;color:var(--content-emphasis)}
.pvlist li span{display:block;font-size:12.5px;color:var(--content-subtle);margin-top:2px;line-height:1.5}

/* ========================================================= annual review == */

.annual .alert{margin-bottom:16px}
.ansec{margin-bottom:18px}
.ansec-h{display:flex;align-items:center;gap:10px;margin-bottom:6px}
.ansec-h b{font-size:14px;color:var(--content-emphasis)}
.ansec-h .pill{margin-left:auto}
.ansec textarea{font-size:13.5px;line-height:1.6}
.ansec.judgement textarea{border-color:var(--warn-bd,#f0d8a8);background:#fffdf7}
.ansec.judgement.edited textarea{border-color:var(--border-subtle);background:var(--bg-default)}

/* ===================================================== practice analytics = */

.metrow{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.metbar{
  flex:1 1 220px;height:10px;border-radius:99px;background:var(--due);
  overflow:hidden;min-width:160px;
}
.metbar i{display:block;height:100%;border-radius:99px}
.metbar i.ok{background:var(--ok)}
.metrow b{font-size:13.5px;color:var(--ok);font-variant-numeric:tabular-nums}
.metrow b.bad{color:var(--due)}

/* =========================================================== onboarding === */

.wizgrid{display:grid;grid-template-columns:210px 1fr;gap:24px;align-items:start}
.wizrail{list-style:none;display:flex;flex-direction:column;gap:1px;counter-reset:none}
.wizrail li{
  display:flex;align-items:center;gap:10px;padding:9px 12px;border-radius:7px;
  font-size:13px;color:var(--content-subtle);
}
.wizrail li .n{
  font-size:11px;font-weight:700;letter-spacing:.04em;color:var(--content-muted);
  font-variant-numeric:tabular-nums;
}
.wizrail li.on{background:var(--navy);color:#fff;font-weight:600}
.wizrail li.on .n{color:rgba(255,255,255,.7)}
.wizrail li.done{color:var(--content-default)}
.wizrail li.done .n{color:var(--ok)}
.wizbody .panel{margin-bottom:0}
.wiznav{display:flex;gap:9px;align-items:center;border-top:1px solid var(--border-muted)}
.wiznav .btn:last-child{margin-left:auto}

.wizlist{list-style:none;display:flex;flex-direction:column;gap:7px;margin-bottom:16px}
.wizlist li{
  padding:10px 12px;border-radius:7px;background:var(--bg-subtle);
  border:1px solid var(--border-muted);
}
.wizlist li b{display:block;font-size:13.5px;color:var(--content-emphasis)}
.wizlist li span{display:block;font-size:12.5px;color:var(--content-subtle);margin-top:2px}

.wizrows{display:flex;flex-direction:column;gap:12px;margin-bottom:16px}
.wizrow{
  padding:13px;border-radius:8px;border:1px solid var(--border-muted);
  background:var(--bg-subtle);
}
.wizrow .hint{margin:0}

.wizsummary{
  margin-top:18px;padding:15px 16px;border-radius:8px;
  background:var(--steel-bg);border:1px solid var(--steel-bd);
}
.wizsummary h4{font-size:13px;color:var(--navy);margin-bottom:8px}
.wizsummary ul{list-style:none;display:flex;flex-direction:column;gap:4px}
.wizsummary li{font-size:13px;color:var(--content-default)}
.wizsummary li::before{content:"· ";color:var(--content-muted)}

/* ============================================================== responsive */

@media (max-width:1000px){
  .tiles{grid-template-columns:1fr 1fr}
  .panel-grid{grid-template-columns:1fr}
  .cgrid{grid-template-columns:1fr}
  .chead{grid-template-columns:1fr}
  .chead-actions{justify-content:flex-start}
  /* The rail becomes a horizontal ribbon rather than eating half the width. */
  .wizgrid{grid-template-columns:1fr;gap:16px}
  .wizrail{flex-direction:row;flex-wrap:wrap;gap:4px}
  .wizrail li{padding:6px 10px;font-size:12px}
}
@media (max-width:860px){
  .app.on{grid-template-columns:1fr}
  /* relative, not static: the panel behind the sidebar is an absolutely
     positioned ::before and needs .side to stay its containing block. */
  .side{position:relative;top:auto;height:auto;padding:10px;flex-direction:row;flex-wrap:wrap;align-items:center;gap:6px}
  .side::before{inset:10px}
  .side-brand{margin:0 0 4px;width:100%}
  .side-plan{margin:0 0 4px}
  .nav{flex-direction:row;flex-wrap:wrap;padding:0;overflow:visible;flex:0 0 100%}
  .nav button{width:auto}
  .nav button .count{margin-left:6px}
  .side-foot{margin:0;border:none;padding:0;display:flex;gap:6px;flex-wrap:wrap}
  .side-foot button{width:auto}
  .side-meta{display:none}
  /* Not hidden with .side-meta: on a phone, "can I use this on my laptop too"
     is a more likely question, not a less likely one. */
  .side-cross{width:auto;margin-top:0;font-size:12px}
  .side-cross span br{display:none}
  .main{padding:20px 16px 52px}
  .rail-row{grid-template-columns:1fr;gap:9px}
  .rail-meta{text-align:left}
  .row2,.doc-grid{grid-template-columns:1fr}
  /* The verb is a hover affordance, and there is no hover here — the row is
     tappable and the third column would only steal width from the title. */
  .radar-tbl td.radar-next{display:none}
  /* The health row drops its bar rather than its numbers: on a phone the score
     is the information and the bar is the decoration. */
  .hrow{grid-template-columns:1fr 34px 18px}
  .hrow .hrow-weight,.hrow .hbar{display:none}
  .tline-row{grid-template-columns:1fr;gap:3px}
  .tline-k{font-size:10.5px}
  .pk-grid,.pk-checks{grid-template-columns:1fr}
  .pk-preview{max-height:none}
  .pk-kv{grid-template-columns:1fr;gap:0}
  .topbar h1{font-size:18.5px}
}
