/* GENERATED by kit/check.mjs --write from Design/app.css — do not edit here.
   app.css minus its Tailwind v4 glue (lines 1-7 and 14-17). Load kit/fonts.css
   first: it declares --font-sans / --font-mono, which the @theme block did. */
/* =========================================================================
   KoraxLabs — The Night Watch.  Canonical stylesheet for the whole family.
   One teal signal, deep ink surfaces, hairline structure, generous air.
   Lines 1-7 and 14-17 are Tailwind v4 glue; everything else is plain CSS.
   ========================================================================= */


:root {
  color-scheme: dark;

  --ink-900: #070a0d;
  --ink-850: #0a0e12;
  --ink-800: #0e1318;
  --ink-780: #11171d;
  --ink-700: #161d24;
  --ink-650: #1b232b;

  --line: color-mix(in oklab, #cfe6ff 8%, transparent);
  --line-2: color-mix(in oklab, #cfe6ff 14%, transparent);
  --line-3: color-mix(in oklab, #cfe6ff 22%, transparent);

  --text: #e9eef3;
  --text-2: #9fb0bd;
  --text-3: #66757f;

  /* The signal — a watchful teal-cyan. Used sparingly. */
  --signal: #38e0c6;
  --signal-2: #63ecd6;
  --signal-ink: #032420;
  --signal-glow: color-mix(in oklab, var(--signal) 28%, transparent);
  --signal-wash: color-mix(in oklab, var(--signal) 12%, transparent);

  /* Traffic semantics */
  --allow: #56d597;
  --block: #ff6b72;
  --flag: #f3b64d;

  --radius: 14px;
  --radius-sm: 10px;
  --radius-xs: 8px;
  --radius-pill: 999px;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .45);
  --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 12px 32px -16px rgba(0, 0, 0, .6);
  --shadow-lg: 0 2px 4px rgba(0, 0, 0, .4), 0 28px 60px -24px rgba(0, 0, 0, .7);

  --ease: cubic-bezier(.2, .7, .2, 1);

  /* Chart grid and tick colours as plain values: a canvas cannot parse
     color-mix(), so these mirror --line and --text-3 for Chart.js. */
  --chart-grid: rgba(207, 230, 255, 0.08);
  --chart-tick: #66757f;
}

/* ---------------------------------------------------------------- Light
   KoraxDB #417 (2026-09-14): a second token set, not a second design. Dark
   stays the default and the brand; light is for the daylight office, the
   projected screen, and the reader for whom light-on-dark is hard work.
   One accent still — the teal is deepened so it holds AA on white. The
   contract: <html data-theme="light"> is light, "system" follows the OS,
   anything else (or nothing) is dark. Explicit choices are rendered
   server-side, so there is no flash of the wrong theme. */
:root[data-theme="light"] {
  color-scheme: light;

  /* Ink, back to front — on light the front is the lighter surface. */
  --ink-900: #f2f5f8;
  --ink-850: #e9eef3;
  --ink-800: #ffffff;
  --ink-780: #f3f6f9;
  --ink-700: #e5ebf1;
  --ink-650: #d9e1e9;

  --line: color-mix(in oklab, #0b1a26 10%, transparent);
  --line-2: color-mix(in oklab, #0b1a26 16%, transparent);
  --line-3: color-mix(in oklab, #0b1a26 24%, transparent);

  --text: #101820;
  --text-2: #3d4d5a;
  --text-3: #586873;

  /* The one signal, deepened so it holds AA on white (#38e0c6 is 1.6:1 there). */
  --signal: #0b7d6c;
  --signal-2: #12998a;
  --signal-ink: #ffffff;
  --signal-glow: color-mix(in oklab, var(--signal) 22%, transparent);
  --signal-wash: color-mix(in oklab, var(--signal) 10%, transparent);

  /* Traffic semantics — deepened, and kept apart in luminance for colour-blind readers. */
  --allow: #177a4a;
  --block: #9e1f28;
  --flag: #8a5a00;

  --shadow-sm: 0 1px 2px rgba(10, 20, 30, .08);
  --shadow: 0 1px 2px rgba(10, 20, 30, .06), 0 12px 32px -16px rgba(10, 20, 30, .18);
  --shadow-lg: 0 2px 4px rgba(10, 20, 30, .06), 0 28px 60px -24px rgba(10, 20, 30, .22);

  --chart-grid: rgba(11, 26, 38, 0.10);
  --chart-tick: #586873;
}
@media (prefers-color-scheme: light) {
  :root[data-theme="system"] {
    color-scheme: light;

    /* Ink, back to front — on light the front is the lighter surface. */
    --ink-900: #f2f5f8;
    --ink-850: #e9eef3;
    --ink-800: #ffffff;
    --ink-780: #f3f6f9;
    --ink-700: #e5ebf1;
    --ink-650: #d9e1e9;

    --line: color-mix(in oklab, #0b1a26 10%, transparent);
    --line-2: color-mix(in oklab, #0b1a26 16%, transparent);
    --line-3: color-mix(in oklab, #0b1a26 24%, transparent);

    --text: #101820;
    --text-2: #3d4d5a;
    --text-3: #586873;

    /* The one signal, deepened so it holds AA on white (#38e0c6 is 1.6:1 there). */
    --signal: #0b7d6c;
    --signal-2: #12998a;
    --signal-ink: #ffffff;
    --signal-glow: color-mix(in oklab, var(--signal) 22%, transparent);
    --signal-wash: color-mix(in oklab, var(--signal) 10%, transparent);

    /* Traffic semantics — deepened, and kept apart in luminance for colour-blind readers. */
    --allow: #177a4a;
    --block: #9e1f28;
    --flag: #8a5a00;

    --shadow-sm: 0 1px 2px rgba(10, 20, 30, .08);
    --shadow: 0 1px 2px rgba(10, 20, 30, .06), 0 12px 32px -16px rgba(10, 20, 30, .18);
    --shadow-lg: 0 2px 4px rgba(10, 20, 30, .06), 0 28px 60px -24px rgba(10, 20, 30, .22);

    --chart-grid: rgba(11, 26, 38, 0.10);
    --chart-tick: #586873;
  }
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.5;
  letter-spacing: -0.01em;
  color: var(--text);
  background:
    radial-gradient(1200px 620px at 12% -8%, color-mix(in oklab, var(--signal) 9%, transparent), transparent 60%),
    radial-gradient(900px 500px at 100% 0%, color-mix(in oklab, #4a7cff 6%, transparent), transparent 55%),
    var(--ink-900);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-variant-numeric: tabular-nums;
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: .028;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; border-radius: var(--radius-xs); }

/* Calm motion is a principle, not a preference — honour the OS setting. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}

/* --------------------------------------------------------------------- Shell */
.shell { position: relative; z-index: 1; display: grid; grid-template-columns: 268px 1fr; min-height: 100vh; }

.sidebar {
  position: sticky; top: 0; align-self: start; height: 100vh;
  display: flex; flex-direction: column; gap: 6px; padding: 22px 16px;
  border-right: 1px solid var(--line);
  background: linear-gradient(180deg, color-mix(in oklab, var(--ink-850) 92%, transparent), var(--ink-900));
  backdrop-filter: blur(6px);
}

.brand { display: flex; align-items: center; gap: 11px; padding: 6px 10px 4px; margin-bottom: 10px; }
.brand__mark {
  width: 34px; height: 34px; display: grid; place-items: center; border-radius: 11px; color: var(--signal);
  background: radial-gradient(120% 120% at 30% 20%, var(--signal-wash), transparent 70%), var(--ink-780);
  border: 1px solid var(--line-2); box-shadow: inset 0 0 20px -10px var(--signal-glow);
}
.brand__mark svg { width: 21px; height: 21px; display: block; }
.brand__name { font-weight: 700; letter-spacing: -0.02em; font-size: 15.5px; line-height: 1; }
.brand__eyebrow { font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--text-3); margin-top: 3px; }

.watch { display: flex; align-items: center; gap: 8px; margin: 2px 10px 14px; font-size: 12px; color: var(--text-2); }
.watch__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--signal); box-shadow: 0 0 0 0 var(--signal-glow); animation: pulse 2.4s var(--ease) infinite; }
@keyframes pulse { 0% { box-shadow: 0 0 0 0 var(--signal-glow); } 70% { box-shadow: 0 0 0 7px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }

.nav { display: grid; gap: 3px; }
.nav__label { padding: 12px 12px 6px; font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--text-3); }
.nav a { position: relative; display: flex; align-items: center; gap: 11px; padding: 9px 12px; border-radius: var(--radius-sm); color: var(--text-2); font-weight: 500; font-size: 14px; transition: background .18s var(--ease), color .18s var(--ease); }
.nav a svg { width: 17px; height: 17px; flex: none; opacity: .85; }
.nav a:hover { background: var(--ink-780); color: var(--text); }
.nav a.is-active { background: linear-gradient(90deg, var(--signal-wash), transparent 80%), var(--ink-700); color: var(--text); }
.nav a.is-active::before { content: ""; position: absolute; left: -16px; top: 8px; bottom: 8px; width: 3px; border-radius: 0 3px 3px 0; background: var(--signal); box-shadow: 0 0 14px var(--signal-glow); }
.nav a.is-active svg { opacity: 1; color: var(--signal); }

.sidebar__foot { margin-top: auto; display: grid; gap: 8px; padding-top: 14px; border-top: 1px solid var(--line); }
.account { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: var(--radius-sm); background: var(--ink-800); border: 1px solid var(--line); }
.account__avatar { width: 30px; height: 30px; border-radius: 50%; flex: none; display: grid; place-items: center; font-weight: 700; font-size: 12px; color: var(--signal); background: var(--ink-700); border: 1px solid var(--line-2); }
.account__who { min-width: 0; }
.account__who b { display: block; font-size: 12.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.account__who span { font-size: 11px; color: var(--text-3); }
.linkbtn { background: none; border: 0; padding: 7px 10px; text-align: left; color: var(--text-3); font-size: 12.5px; cursor: pointer; border-radius: var(--radius-xs); transition: color .15s var(--ease), background .15s var(--ease); }
.linkbtn:hover { color: var(--text); background: var(--ink-780); }

/* ------------------------------------------------------------------ Content */
.content { position: relative; padding: 30px 40px 64px; max-width: 1180px; }
.topbar { display: flex; align-items: center; justify-content: space-between; gap: 20px; margin-bottom: 26px; }
.topbar__crumb { font-size: 12.5px; color: var(--text-3); letter-spacing: .02em; }
.topbar__crumb b { color: var(--text-2); font-weight: 600; }
/* The topbar's trailing slot: what must stay reachable on a phone once the rail is
   a drawer — the burger, and the unread bell. Empty on a desk. */
.topbar__tools { display: flex; align-items: center; gap: 8px; margin-left: auto; }
/* The burger. Hidden at desk widths; a 44 px target on a phone. It is the way
   OUT of a page that failed to boot, so it must work before any framework does. */
.burger { display: none; width: 44px; height: 44px; align-items: center; justify-content: center; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--ink-800); color: var(--text-2); cursor: pointer; transition: background .18s var(--ease), color .18s var(--ease), border-color .18s var(--ease); }
.burger:hover { background: var(--ink-780); color: var(--text); }
.burger svg { width: 20px; height: 20px; }
.burger[aria-expanded="true"] { color: var(--signal); border-color: color-mix(in oklab, var(--signal) 40%, transparent); }
/* The bell beside it — the one nav row a phone user is most likely looking for. */
.topbar__bell { display: none; width: 44px; height: 44px; align-items: center; justify-content: center; position: relative; border-radius: var(--radius-sm); color: var(--text-2); }
.topbar__bell svg { width: 20px; height: 20px; }
.topbar__bell .nav__count { position: absolute; top: 2px; right: 2px; margin: 0; }
/* The scrim behind an open drawer: the console dims, one decision at a time. */
.drawer-scrim { display: none; position: fixed; inset: 0; z-index: 40; background: color-mix(in oklab, var(--ink-900) 70%, transparent); backdrop-filter: blur(3px); }

.page-head { margin-bottom: 26px; }
.page-head h1 { margin: 0; font-size: 27px; font-weight: 700; letter-spacing: -0.03em; line-height: 1.1; }
.page-head p { margin: 9px 0 0; color: var(--text-2); max-width: 62ch; font-size: 14.5px; }

/* ------------------------------------------------------------------- Blocks */
.card { border: 1px solid var(--line); background: linear-gradient(180deg, color-mix(in oklab, var(--ink-800) 88%, transparent), var(--ink-850)); border-radius: var(--radius); box-shadow: var(--shadow-sm); }
.card--pad { padding: 20px; }
.grid { display: grid; gap: 16px; }
.reveal { opacity: 0; transform: translateY(8px); animation: reveal .55s var(--ease) forwards; }
@keyframes reveal { to { opacity: 1; transform: none; } }
.section-title { font-size: 13px; font-weight: 700; letter-spacing: -0.01em; color: var(--text); display: flex; align-items: center; gap: 9px; margin: 0 0 14px; }
.section-title .count { color: var(--text-3); font-weight: 500; }

/* Stat tiles */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.stat { padding: 17px 18px; border-radius: var(--radius); border: 1px solid var(--line); background: linear-gradient(180deg, var(--ink-800), var(--ink-850)); position: relative; overflow: hidden; transition: border-color .2s var(--ease), transform .2s var(--ease); }
.stat:hover { border-color: var(--line-2); transform: translateY(-2px); }
.stat__label { display: flex; align-items: center; gap: 8px; color: var(--text-2); font-size: 12.5px; }
.stat__label svg { width: 15px; height: 15px; color: var(--signal); opacity: .9; }
.stat__value { margin-top: 12px; font-size: 30px; font-weight: 700; letter-spacing: -0.03em; line-height: 1; }
.stat__value small { font-size: 15px; color: var(--text-3); font-weight: 500; letter-spacing: 0; }
.stat__trend { margin-top: 9px; font-size: 12px; color: var(--text-3); display: flex; gap: 6px; align-items: center; }
.stat__trend.up { color: var(--allow); }

/* Pills */
.pill { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: var(--radius-pill); font-size: 12px; font-weight: 600; letter-spacing: .01em; border: 1px solid var(--line-2); color: var(--text-2); background: var(--ink-780); }
.pill--dot::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.pill.allow { color: var(--allow); border-color: color-mix(in oklab, var(--allow) 34%, transparent); background: color-mix(in oklab, var(--allow) 10%, transparent); }
.pill.block { color: var(--block); border-color: color-mix(in oklab, var(--block) 34%, transparent); background: color-mix(in oklab, var(--block) 10%, transparent); }
.pill.flag  { color: var(--flag);  border-color: color-mix(in oklab, var(--flag) 34%, transparent);  background: color-mix(in oklab, var(--flag) 10%, transparent); }
.pill.signal { color: var(--signal); border-color: color-mix(in oklab, var(--signal) 34%, transparent); background: var(--signal-wash); }
.mono { font-family: var(--font-mono); font-size: .92em; letter-spacing: -0.02em; }

/* Buttons */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; padding: 10px 15px; border-radius: var(--radius-sm); cursor: pointer; font-weight: 600; font-size: 13.5px; letter-spacing: -0.01em; border: 1px solid var(--line-2); background: var(--ink-780); color: var(--text); transition: transform .12s var(--ease), border-color .18s var(--ease), background .18s var(--ease), box-shadow .2s var(--ease); }
.btn:hover { border-color: var(--line-3); background: var(--ink-700); }
.btn:active { transform: translateY(1px); }
.btn svg { width: 16px; height: 16px; }
.btn--ghost { background: transparent; border-color: transparent; color: var(--text-2); padding: 8px 10px; }
.btn--ghost:hover { background: var(--ink-780); color: var(--text); }
.btn--primary { color: var(--signal-ink); background: linear-gradient(180deg, var(--signal-2), var(--signal)); border-color: transparent; box-shadow: 0 8px 26px -12px var(--signal-glow); }
.btn--primary:hover { filter: brightness(1.06); border-color: transparent; }
.btn:disabled { opacity: .4; cursor: not-allowed; transform: none; }

/* ------------------------------------------------- Shell & block additions
   Grown on the customer portal between 2026-09-14 and 2026-09-20 and folded
   back here on 2026-09-23. They sit AFTER line 300 on purpose: the website's
   transcription test pins lines 19-151, 153-191, 261-268 and 281-299 by
   number, so nothing may be inserted above this point — append only. */
/* Tailwind's preflight gives the portal these two; a consumer without Tailwind
   needs them here or a hidden dialog stays on screen (display: grid wins over
   the UA's [hidden]) and screen-reader-only labels become visible. */
[hidden]:where(:not([hidden="until-found"])) { display: none !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; }
.page-head h1 { text-wrap: balance; }
.brand__mark img { width: 24px; height: auto; display: block; }
/* The guest card's brand block is the first impression — the raven at 40px (#326). */
.brand--lg { gap: 14px; }
.brand__mark--lg { width: 56px; height: 56px; border-radius: 16px; }
.brand__mark--lg img { width: 40px; }
.brand--lg .brand__name { font-size: 20px; }
.brand--lg .brand__eyebrow { font-size: 11px; margin-top: 5px; }
.watch__dot.sm { width: 8px; height: 8px; }
/* Wrapper for the (Livewire) unread badge: it holds the nav row's trailing
   slot whether or not there is a number to put in it. */
.nav__count { margin-left: auto; display: inline-flex; align-items: center; }
.nav__badge { margin-left: auto; display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--radius-pill); font-size: 11px; font-weight: 700; color: var(--signal); background: var(--signal-wash); border: 1px solid color-mix(in oklab, var(--signal) 34%, transparent); }
/* As a link (#328) it answers like a nav row: lifts on hover, lit when you are on it. */
a.account { cursor: pointer; transition: background .18s var(--ease), border-color .18s var(--ease), color .18s var(--ease); }
a.account:hover { background: var(--ink-780); border-color: var(--line-2); }
a.account.is-active { background: linear-gradient(90deg, var(--signal-wash), transparent 80%), var(--ink-700); border-color: var(--line-2); }
a.account.is-active .account__avatar { border-color: var(--signal); box-shadow: 0 0 14px var(--signal-glow); }
/* KoraxDB #360: the organisation under the name — bold, one step dimmer, same ellipsis. */
.account__who .account__org { font-size: 11.5px; color: var(--text-2); }
.section-title svg { width: 16px; height: 16px; color: var(--signal); }

/* Segmented */
.segmented { display: inline-flex; padding: 4px; gap: 4px; border-radius: var(--radius-sm); background: var(--ink-850); border: 1px solid var(--line); }
.segmented button { padding: 8px 16px; border-radius: 7px; border: 0; background: transparent; color: var(--text-2); font-weight: 600; font-size: 13px; cursor: pointer; transition: background .18s var(--ease), color .18s var(--ease); display: inline-flex; align-items: center; gap: 8px; }
.segmented button svg { width: 15px; height: 15px; }
.segmented button.active { background: var(--ink-700); color: var(--text); box-shadow: var(--shadow-sm); }
/* Portal #296: the one code entry (x-mfa-code-input) — sign-in, step-up dialog, enrolment. */
.mfacode { display: grid; gap: 16px; }
.mfacode .notice { margin: 0; }
.mfacode .segmented { justify-self: start; }
.input--otp { font-size: 20px; letter-spacing: .5em; text-align: center; }
.segmented button.active svg { color: var(--signal); }
/* KoraxDB #417: the theme switch — the same control, sized for the topbar
   and for a phone (44 px targets). */
.segmented--compact button { padding: 6px 10px; min-height: 32px; }
.theme-toggle button { min-width: 44px; justify-content: center; }
.theme-toggle .theme-toggle__label { display: none; }
.theme-toggle--card button { min-height: 44px; }
.theme-toggle--card .theme-toggle__label { display: inline; }

/* Form controls — teal only on the on-state. */
.field { display: grid; gap: 9px; }
.field__title { font-weight: 600; font-size: 13.5px; letter-spacing: -0.01em; }
.field__hint { color: var(--text-3); font-size: 12.5px; }
.row { display: flex; flex-wrap: wrap; gap: 9px; align-items: center; }
.input, select.input, textarea.input { min-height: 42px; padding: 10px 12px; width: 100%; border-radius: var(--radius-sm); border: 1px solid var(--line-2); background: var(--ink-850); color: var(--text); font: inherit; font-size: 14px; transition: border-color .16s var(--ease), box-shadow .16s var(--ease); }
.input::placeholder { color: var(--text-3); }
.input:focus { outline: 0; border-color: var(--signal); box-shadow: 0 0 0 3px var(--signal-wash); }
.input--auto { width: auto; min-width: 180px; }
select.input { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%2366757f' stroke-width='1.6'%3E%3Cpath d='M2 4l4 4 4-4'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; padding-right: 32px; }
textarea.input { min-height: 130px; resize: vertical; line-height: 1.55; }
.toggle-chip { padding: 8px 12px; border-radius: var(--radius-sm); cursor: pointer; border: 1px solid var(--line-2); background: var(--ink-850); color: var(--text-2); font-size: 13px; font-weight: 600; transition: all .15s var(--ease); }
.toggle-chip.active { border-color: var(--signal); color: var(--signal); background: var(--signal-wash); }
.chip { display: inline-flex; align-items: center; gap: 7px; padding: 6px 10px 6px 12px; border-radius: var(--radius-pill); border: 1px solid var(--line-2); background: var(--ink-780); color: var(--text); font-size: 12.5px; font-weight: 500; cursor: pointer; }
.chip:hover { border-color: var(--block); color: var(--block); }

.switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; user-select: none; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch__track { width: 38px; height: 22px; border-radius: 999px; background: var(--ink-700); border: 1px solid var(--line-2); position: relative; transition: background .18s var(--ease), border-color .18s var(--ease); }
.switch__track::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: var(--text-2); transition: transform .18s var(--ease), background .18s var(--ease); }
.switch input:checked + .switch__track { background: var(--signal-wash); border-color: var(--signal); }
.switch input:checked + .switch__track::after { transform: translateX(16px); background: var(--signal); }

/* Ranked bars (KoraxDB #449): HTML bars, numbers in the DOM, fixed per-key colour, never the signal. */
.rank { display: grid; gap: 10px; }
.rank__row { display: grid; gap: 6px; }
.rank__head { display: flex; align-items: center; gap: 9px; font-size: 13.5px; }
.rank__swatch { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.rank__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.rank__name--btn { background: transparent; border: 0; color: inherit; font: inherit; font-weight: 600; text-align: left; padding: 0; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
.rank__name--btn:hover { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }
.rank__count { color: var(--text-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.rank__bar { height: 6px; border-radius: 999px; background: var(--ink-700); overflow: hidden; }
.rank__bar span { display: block; height: 100%; border-radius: 999px; transition: width .3s var(--ease); }
.rank__detail { margin: 6px 0 4px 19px; padding: 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--ink-850); }
.rank__detail .table th, .rank__detail .table td { padding: 6px 8px; font-size: 12.5px; text-align: left; border-bottom: 1px solid var(--line); }
.rank__detail .table td.n, .rank__detail .table th.n { text-align: right; font-variant-numeric: tabular-nums; }
.vendors { display: grid; gap: 8px; }
.vendors__item { display: grid; grid-template-columns: 10px 180px 1fr auto auto auto; gap: 10px; align-items: center; font-size: 13px; }
.vendors__name { font-weight: 600; }
.vendors__hosts { color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 720px) { .vendors__item { grid-template-columns: 10px 1fr auto auto auto; } .vendors__hosts { display: none; } }

/* Notices */
.notice { padding: 12px 14px; border-radius: var(--radius-sm); font-size: 13.5px; display: flex; gap: 10px; align-items: center; }
.notice svg { width: 17px; height: 17px; flex: none; }
.notice--ok { color: var(--signal); border: 1px solid color-mix(in oklab, var(--signal) 32%, transparent); background: var(--signal-wash); }
.notice--err { color: var(--block); border: 1px solid color-mix(in oklab, var(--block) 36%, transparent); background: color-mix(in oklab, var(--block) 9%, transparent); }
/* Portal #198: the trial-ended banner — a title in the verdict colour, a sentence, ONE full-width
   primary action and its hint, stacked. The one exception to "never .btn--primary in a banner": a
   lapsed trial has no other working action on any page it appears on, so the request IS the page's
   primary action. Text in --text-2 (--text-3 misses 4.5:1 on the dark wash); the verdict colour stays
   on the title and the edge, never on the button (semantic ≠ accent). */
.notice--stack { flex-direction: column; align-items: stretch; gap: 8px; padding: 14px 16px; }
.notice__title { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }
.notice__body { margin: 0; color: var(--text-2); }
.notice__cta { width: 100%; min-height: 44px; margin-top: 4px; }
.notice__hint { margin: 0; color: var(--text-2); font-size: 12.5px; text-align: center; }
.err-text { color: var(--block); font-size: 12.5px; margin: 2px 0 0; }

/* Rule card — the signature component. Precedence you can read, never raw config. */
.policy-rule-card { border: 1px solid var(--line-2); border-radius: var(--radius); background: var(--ink-800); padding: 18px; box-shadow: var(--shadow); }
.rulecard__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; }
.rulecard__eyebrow { font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--signal); margin: 0 0 7px; }
.rulecard__title { margin: 0; font-size: 17px; font-weight: 700; letter-spacing: -0.02em; }
.rulecard__sub { margin: 6px 0 0; color: var(--text-2); font-size: 13px; }
.layers { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 8px; }
.layer { display: grid; grid-template-columns: 82px 1fr auto; gap: 12px; align-items: center; padding: 11px 13px; border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--ink-850); }
.layer__kind { font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-3); }
.layer__sentence { font-size: 13.5px; }
.layer__action { font-size: 11.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.layer.signal { border-color: color-mix(in oklab, var(--allow) 30%, transparent); }
.layer.signal .layer__action { color: var(--allow); }
.layer.danger { border-color: color-mix(in oklab, var(--block) 30%, transparent); }
.layer.danger .layer__action { color: var(--block); }
.layer.neutral .layer__action { color: var(--text-2); }

/* Preview / dry-run counts */
.preview-counts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.pcount { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 14px; background: var(--ink-850); }
.pcount span { color: var(--text-2); font-size: 12px; }
.pcount strong { display: block; margin-top: 6px; font-size: 26px; font-weight: 700; letter-spacing: -0.03em; }
.pcount.block strong { color: var(--block); }
.pcount.allow strong { color: var(--allow); }
.pexample { font-size: 12.5px; color: var(--text-2); padding: 8px 0; border-bottom: 1px solid var(--line); }
.pexample:last-child { border-bottom: 0; }

/* Attention / suggestions */
.attn { display: grid; gap: 12px; }
.suggestion { display: flex; gap: 14px; align-items: flex-start; padding: 16px 18px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--ink-800); transition: border-color .2s var(--ease); }
.suggestion:hover { border-color: var(--line-2); }
.suggestion__icon { width: 36px; height: 36px; border-radius: 10px; flex: none; display: grid; place-items: center; color: var(--signal); background: var(--signal-wash); border: 1px solid color-mix(in oklab, var(--signal) 24%, transparent); }
.suggestion__icon svg { width: 18px; height: 18px; }
.suggestion__body { flex: 1; min-width: 0; }
.suggestion__body p { margin: 0; font-size: 14px; }
.suggestion__body span { display: block; margin-top: 4px; color: var(--text-3); font-size: 12.5px; }
.suggestion__act { display: flex; align-items: center; gap: 6px; flex: none; }

/* Decision feed */
.stream { display: grid; gap: 2px; }
.streamrow { display: grid; grid-template-columns: 92px 1.4fr 1fr auto; gap: 16px; align-items: center; padding: 12px 16px; border-radius: var(--radius-sm); font-size: 13px; transition: background .15s var(--ease); }
.streamrow:hover { background: var(--ink-800); }
.streamrow__time { color: var(--text-3); font-family: var(--font-mono); font-size: 12px; }
.streamrow__who b { font-weight: 600; }
.streamrow__who span { color: var(--text-3); font-size: 12px; display: block; }
.streamrow__site { color: var(--text-2); }
.streamrow__site .cat { color: var(--text-3); font-size: 11.5px; }

/* Diff */
.diffrow { display: grid; grid-template-columns: 90px 1fr; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line); font-size: 13px; }
.diffrow:last-child { border-bottom: 0; }
.diff-tag { font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.diff-tag.added { color: var(--allow); }
.diff-tag.removed { color: var(--block); }
.diff-tag.changed { color: var(--flag); }

/* Versions */
.vlist { display: grid; gap: 8px; }
.vitem { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--ink-850); cursor: pointer; transition: border-color .16s var(--ease), background .16s var(--ease); }
.vitem:hover { border-color: var(--line-2); background: var(--ink-800); }
.vitem.is-active { border-color: color-mix(in oklab, var(--signal) 40%, transparent); background: var(--signal-wash); }
.vitem__id { font-family: var(--font-mono); font-weight: 700; }

.two-col { display: grid; grid-template-columns: 1.15fr .85fr; gap: 20px; align-items: start; }
.split { display: grid; grid-template-columns: 340px 1fr; gap: 20px; align-items: start; }

/* Honest empty state: say what will appear here, and why. */
.empty { text-align: center; padding: 48px 24px; color: var(--text-3); }
.empty svg { display: block; width: 34px; height: 34px; margin: 0 auto 12px; opacity: .6; }

/* ------------------------------------------------------------------ PHASE 5
   Everything below was added for the list screens. It introduces no new
   colour: the dialog is the existing .card lifted over a scrim of --ink-900,
   the sort head borrows the on-state teal that .toggle-chip.active already
   uses, and rows are the .streamrow with a grid that fits an editable table.
   ------------------------------------------------------------------------ */

/* Dialog — one decision at a time, over a dimmed console. */
.dialog { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; padding: 24px; overflow-y: auto; background: color-mix(in oklab, var(--ink-900) 74%, transparent); backdrop-filter: blur(5px); animation: reveal .2s var(--ease) forwards; }
.dialog__panel { width: 100%; max-width: 470px; box-shadow: var(--shadow); }
.dialog__foot { display: flex; justify-content: flex-end; gap: 9px; }

/* List table — the decision feed, widened for rows that can be edited. */
/* Portal #252: the five columns share the width as on the PortalReview mockups
   (≈ 24 / 30 / 18 / 15 / 13 %), fractional so they scale; the actions never under 92 px. */
.streamrow--list { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1.65fr) minmax(0, 1fr) minmax(0, .85fr) minmax(92px, .75fr); border-radius: 0; border-bottom: 1px solid var(--line); }
.streamrow--list:last-child { border-bottom: 0; }
.streamrow--head { padding-top: 4px; padding-bottom: 10px; }
.streamrow--head:hover { background: transparent; }
.streamrow__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.streamrow__acts { display: flex; align-items: center; justify-content: flex-end; gap: 2px; }

/* Sortable column head — teal marks the active sort, as an on-state. */
.colhead { display: inline-flex; align-items: center; gap: 5px; padding: 0; border: 0; background: none; cursor: pointer; color: var(--text-3); font: inherit; font-size: 10.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; transition: color .15s var(--ease); }
.colhead:hover { color: var(--text-2); }
.colhead.is-sorted { color: var(--signal); }
.colhead svg { width: 11px; height: 11px; }

/* Pager */
.pager { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }
.pager__count { color: var(--text-3); font-size: 12.5px; }
.pager__acts { display: flex; align-items: center; gap: 8px; }

/* Guest shell — auth screens sit on the same atmosphere, without the sidebar. */
.guest { position: relative; z-index: 1; min-height: 100vh; display: grid; place-items: center; padding: 40px 20px; }
.guest__inner { width: 100%; max-width: 420px; }
.guest__brand { display: flex; align-items: center; justify-content: center; gap: 11px; margin-bottom: 22px; }

/* ------------------------------------------------------------------ PHASE 6
   The dashboard. No new colour is introduced: the cache-hit donut wears the
   semantic allow / flag / block, the charts take their palette from the same
   tokens (teal for the TOTAL series only), and the activity feed is the
   existing .streamrow on a grid that fits an event.
   ------------------------------------------------------------------------ */

/* Cache-hit donut — one number, and whether to worry about it. */
.donut { position: relative; width: 108px; height: 108px; display: grid; place-items: center; }
.donut svg { width: 108px; height: 108px; transform: rotate(-90deg); display: block; }
.donut__track { fill: none; stroke: var(--ink-700); stroke-width: 3; }
.donut__arc { fill: none; stroke-width: 3; stroke-linecap: round; transition: stroke-dasharray .6s var(--ease); }
.donut__arc.is-good { stroke: var(--allow); }
.donut__arc.is-warn { stroke: var(--flag); }
.donut__arc.is-bad { stroke: var(--block); }
.donut__value { position: absolute; inset: 0; display: grid; place-items: center; font-size: 16px; font-weight: 700; letter-spacing: -0.02em; }

/* Chart frame — a fixed box, so a canvas cannot grow the page as data lands. */
.chartbox { position: relative; height: 264px; }
.chartbox canvas { display: block; }

/* Chart legend — the doughnut's key, and its numbers. */
.legend { display: grid; gap: 8px; align-content: start; min-width: 0; }
.legend__item { display: flex; align-items: center; gap: 9px; font-size: 12.5px; color: var(--text-2); min-width: 0; }
.legend__swatch { width: 9px; height: 9px; border-radius: 3px; flex: none; }
.legend__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.legend__count { margin-left: auto; font-family: var(--font-mono); font-size: 12px; color: var(--text-3); }

/* Filter tray — the category pills, folded away until asked for. */
.filters { margin-top: 12px; padding: 12px; border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--ink-850); display: flex; flex-wrap: wrap; gap: 8px; }

/* KoraxDB #471: API token rows — state, name over prefix, added, last used, expires, revoke. */
.streamrow--apitokens { grid-template-columns: 110px minmax(0, 1.6fr) 96px 120px 96px 44px; border-radius: 0; border-bottom: 1px solid var(--line); }
.streamrow--apitokens:last-child { border-bottom: 0; }
.streamrow--apitokens .streamrow__domain { display: block; }
/* Block, or the ellipsis never happens: overflow does not clip an inline span, and a long name ran under the revoke button. */
.streamrow--apitokens .streamrow__name { display: block; }

/* KoraxDB #418: the setup wizard's stepper — buttons, so every step can be returned to. */
.wizard__steps { list-style: none; margin: 0 0 18px; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.wizard__steps > li { min-width: 0; }
.wizard .row { flex-wrap: wrap; }
.wizard__step { width: 100%; display: flex; align-items: center; gap: 10px; padding: 10px 12px; min-height: 44px; border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--ink-850); color: var(--text-2); font: inherit; font-size: 13px; font-weight: 600; text-align: left; cursor: pointer; transition: border-color .15s var(--ease), background .15s var(--ease); }
.wizard__step:hover { border-color: var(--line-2); background: var(--ink-800); }
.wizard__step.is-current { border-color: color-mix(in oklab, var(--signal) 40%, transparent); background: var(--signal-wash); color: var(--text); }
.wizard__step.is-done .wizard__num { background: color-mix(in oklab, var(--allow) 14%, transparent); border-color: color-mix(in oklab, var(--allow) 40%, transparent); color: var(--allow); }
.wizard__num { flex: none; width: 24px; height: 24px; display: grid; place-items: center; border-radius: 50%; border: 1px solid var(--line-2); background: var(--ink-700); font-family: var(--font-mono); font-size: 11px; }
.wizard__num svg { width: 13px; height: 13px; }
.wizard__label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* KoraxDB #418: the tour's popover — a non-modal dialog under its anchor. */
.tour__pop { position: fixed; z-index: 70; width: min(320px, calc(100vw - 32px)); box-shadow: var(--shadow-lg); border-color: color-mix(in oklab, var(--signal) 40%, transparent); }
.tour__eyebrow { margin: 0 0 4px; font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--text-3); font-family: var(--font-mono); }
.tour__title { margin: 0 0 6px; font-size: 15px; font-weight: 700; letter-spacing: -0.01em; }
.tour__text { margin: 0; font-size: 13.5px; color: var(--text-2); line-height: 1.5; }

/* Event feed rows. */
.streamrow--activity { grid-template-columns: 84px minmax(0, 1.5fr) 130px 118px minmax(0, 1fr) auto; border-radius: 0; border-bottom: 1px solid var(--line); }
/* KoraxDB #331: the repeat count rides on the domain; the client cell stacks ip over device. */
.streamrow__count { flex: none; font-family: var(--font-mono); font-size: 11px; color: var(--text-2); background: var(--ink-780); border: 1px solid var(--line-2); border-radius: 999px; padding: 1px 7px; }
.streamrow__layer { min-width: 0; }
.streamrow__client { min-width: 0; color: var(--text-3); font-family: var(--font-mono); font-size: 12px; line-height: 1.35; }
.streamrow__client small { display: block; color: var(--text-3); font-family: var(--font); font-size: 11px; }
.streamrow--activity:last-child { border-bottom: 0; }
.streamrow__domain { min-width: 0; display: flex; align-items: center; gap: 7px; }
.streamrow__domain span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.streamrow__cat { min-width: 0; }
.streamrow__ip { color: var(--text-3); font-family: var(--font-mono); font-size: 12px; }
.linkout { display: inline-flex; align-items: center; color: var(--text-3); flex: none; transition: color .15s var(--ease); }
.linkout:hover { color: var(--signal); }
.linkout svg { width: 13px; height: 13px; }

/* ------------------------------------------------------------------ PHASE 7
   Notifications and the audit trail. Again no new colour: an unread
   notification wears the same teal on-state the sidebar badge and the active
   nav item already use — it is the one thing on the page asking for
   attention — and an audit row's action pill takes the semantic verdict
   colours (created allow, deleted block, updated flag), never the accent.
   ------------------------------------------------------------------------ */

/* Notification rows — the hairline and the dot are the whole unread signal. */
/* KoraxDB #330: a report row — period, headline, download. */
.streamrow--report { grid-template-columns: 190px minmax(0, 1fr) auto; }
.streamrow--notif { grid-template-columns: 10px minmax(0, 1fr) auto; align-items: start; padding: 14px 16px; border-radius: 0; border-bottom: 1px solid var(--line); }
.streamrow--notif:last-child { border-bottom: 0; }
.streamrow--notif.is-unread { background: linear-gradient(90deg, var(--signal-wash), transparent 70%); box-shadow: inset 2px 0 0 var(--signal); }
.streamrow--notif.is-unread:hover { background: linear-gradient(90deg, var(--signal-wash), transparent 55%), var(--ink-800); }
.notif__dot { width: 8px; height: 8px; margin-top: 5px; border-radius: 50%; background: var(--ink-700); border: 1px solid var(--line-2); }
.is-unread .notif__dot { background: var(--signal); border-color: transparent; box-shadow: 0 0 10px var(--signal-glow); }
.notif__title { font-weight: 600; font-size: 13.5px; }
.notif__body { margin: 3px 0 0; color: var(--text-2); }
.notif__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 9px; }
.notif__when { color: var(--text-3); font-family: var(--font-mono); font-size: 11.5px; }
.notif__acts { display: flex; align-items: center; justify-content: flex-end; gap: 2px; }

/* Audit rows: the grid lives with the rest of /audit at the end of this file. */
.streamrow__user { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.streamrow__what { min-width: 0; color: var(--text-2); }

/* A detail panel carries more than one decision's worth of text. */
.dialog__panel--wide { max-width: 640px; }

@media (max-width: 1040px) {
  .stats { grid-template-columns: repeat(2, 1fr); }
  .two-col, .split { grid-template-columns: 1fr; }
  /* Keep the verdict, the name and the action; the rest folds away rather
     than being squeezed into an unreadable column. */
  .streamrow--activity { grid-template-columns: 84px minmax(0, 1fr) 130px auto; }
  .streamrow--activity .streamrow__cat, .streamrow--activity .streamrow__client { display: none; }
}
/* ---------------------------------------------------------- Phone shell
   Transcribed from the canonical stylesheet (KoraxDB #413). Below 900px the
   rail becomes an off-canvas DRAWER: one column, the sidebar fixed off the
   left edge, sliding in when <html> carries data-drawer="open" (set by the
   burger), over a scrim. Desk widths are untouched. Tap targets inside the
   drawer and on row actions grow to 44 px. */
@media (max-width: 900px) {
  .shell { grid-template-columns: 1fr; min-width: 0; }
  .sidebar {
    position: fixed; inset: 0 auto 0 0; z-index: 50; width: min(300px, 86vw);
    height: 100vh; height: 100dvh; overflow-y: auto;
    border-right: 1px solid var(--line-2); box-shadow: var(--shadow-lg);
    transform: translateX(-104%); transition: transform .24s var(--ease);
  }
  html[data-drawer="open"] .sidebar { transform: none; }
  html[data-drawer="open"] .drawer-scrim { display: block; }
  html[data-drawer="open"] { overflow: hidden; }
  .burger, .topbar__bell { display: inline-flex; }
  .nav a, .sidebar .linkbtn, .account { min-height: 44px; }
  .content { min-width: 0; padding: 18px 16px 48px; }
  .topbar { margin-bottom: 18px; }
  .streamrow > * { min-width: 0; }
  .streamrow__acts .btn, .streamrow .btn--ghost { min-width: 44px; min-height: 44px; }
}
@media (max-width: 820px) {
  .stats { grid-template-columns: 1fr; }
  .streamrow { grid-template-columns: 1fr auto; }
  .streamrow__time, .streamrow__site { display: none; }
  /* The list table keeps the domain and the actions; the description and the
     switch fold away rather than being squeezed into an unreadable column. */
  .streamrow--list { grid-template-columns: minmax(0, 1fr) 92px; }
  .streamrow--apitokens { grid-template-columns: 100px minmax(0, 1fr) 44px; }
  .streamrow--apitokens .streamrow__added, .streamrow--apitokens .streamrow__used, .streamrow--apitokens .streamrow__expires { display: none; }
  .wizard__steps { grid-template-columns: 1fr; }
  .wizard__label { white-space: normal; }
  .streamrow--list .streamrow__desc,
  .streamrow--list .streamrow__added,
  .streamrow--list .streamrow__switch { display: none; }
  /* .streamrow hides its time column here, so the activity feed drops to the
     two columns that are left: what was asked for, and what you can do. */
  .streamrow--activity { grid-template-columns: minmax(0, 1fr) auto; }
  /* The mark-read button moves under the text rather than off the edge. */
  .streamrow--notif { grid-template-columns: 10px minmax(0, 1fr); }
  .streamrow--notif .notif__acts { grid-column: 2; justify-content: flex-start; margin-top: 10px; }
  .chartbox { height: 220px; }
  .pager { flex-direction: column; align-items: flex-start; }
}

/* ------------------------------------------------- Phone shell, continued
   Found by the specimen on 2026-09-23: a suggestion card (icon · body · two
   buttons) is wider than a phone. The actions drop under the text; the icon
   and the finding stay side by side. Appended here, not inside the block
   above — see the append-only note at "Shell & block additions". */
@media (max-width: 900px) {
  .suggestion { flex-wrap: wrap; }
  .suggestion__act { width: 100%; justify-content: flex-end; }
}

/* ------------------------------------------------------ The mark, on light
   Found by the specimen on 2026-09-23: the brand-kit raven is a light-grey
   gradient (#939598 → #eaebeb), drawn for the dark chip. On the light token
   set it vanished into the chip. Inverting the image turns those greys into
   deep inks — the same raven, the same file, readable on both grounds. This
   is the one place the light theme touches an asset rather than a token.
   .brand__logo is the wordmark (korax-logo-white.svg), same treatment. */
.brand__logo { height: 34px; width: auto; display: block; }
:root[data-theme="light"] .brand__mark img, :root[data-theme="light"] .brand__logo { filter: invert(1); }
@media (prefers-color-scheme: light) {
  :root[data-theme="system"] .brand__mark img, :root[data-theme="system"] .brand__logo { filter: invert(1); }
}

/* ------------------------------------------------------ The primary button, hovered (Portal #183)
   `.btn:hover` (0,2,0) sets `background` — the shorthand — and so resets background-image on a
   hovered `.btn--primary` (0,1,0): the teal gradient gave way to the flat --ink-700 fill, dark ink
   on dark at 1.1:1 (white on #e5ebf1, 1.2:1, on light). The hover restates the gradient from two
   hover stops per theme: brighter on dark, darker on light. Not a brightness() filter — a filter
   scales the label with the fill, so on light the hovered top stop fell to 4.2:1 and no darkening
   factor clears 4.5:1 either. With hex stops the label stays --signal-ink: 11:1 / 12:1 on dark,
   5.1:1 / 5.5:1 on light (kit/check.mjs holds both). A disabled primary stays at rest. */
:root {
  --signal-hover: #3bedd2;
  --signal-2-hover: #69fae3;
}
:root[data-theme="light"] {
  --signal-hover: #0a7666;
  --signal-2-hover: #0d7b6e;
}
@media (prefers-color-scheme: light) {
  :root[data-theme="system"] {
    --signal-hover: #0a7666;
    --signal-2-hover: #0d7b6e;
  }
}
.btn--primary:hover { background: linear-gradient(180deg, var(--signal-2-hover), var(--signal-hover)); filter: none; border-color: transparent; }
.btn--primary:disabled:hover { background: linear-gradient(180deg, var(--signal-2), var(--signal)); }

/* ---------------------------------------------------- Code block (Portal #185)
   Ported from the portal on 2026-10-19: a command to copy — one block, one
   copy control, wrapping rather than scrolling (nothing may scroll sideways on
   a phone, and a command is read whole, not panned). The copy control is a
   .btn--ghost placed over the block's right edge; with a label above, it drops
   below the label. Appended, never inserted — see the append-only note at
   "Shell & block additions". */
@layer components {
  .codeblock-wrap { position: relative; min-width: 0; }
  .codeblock { margin: 0; padding: 12px 92px 12px 14px; border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--ink-850); color: var(--text-2); font-family: var(--font-mono); font-size: 12.5px; line-height: 1.55; white-space: pre-wrap; overflow-wrap: anywhere; }
  .codeblock__label { margin: 0 0 6px; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--text-3); }
  .codeblock__copy { position: absolute; top: 0; right: 4px; min-height: 36px; }
  .codeblock__label + .codeblock + .codeblock__copy { top: 22px; }
}

/* ------------------------------------------- Mode cards (Portal #196)
   Ported from the portal on 2026-10-20: the Protection mode page's pick — a
   native radio inside a card, the card's border and wash following :checked,
   the mode in force told by a text pill; a notice for a standing fact that is
   neither success nor fault; and the rules list as a modifier with an icon
   column (.layer itself untouched). Appended, never inserted — see the
   append-only note at "Shell & block additions". */
@layer components {
  /* Portal #196: the Protection mode page — the mode in force, the pick, the change.
     A mode card is a native radio inside a card: the ring and the checked dot are the
     browser's (accent-color), the card's border and wash follow :checked, and the
     "Current mode" pill is text. Current ≠ selected is told by words, a checked
     radio and a border — never by colour alone. .layer itself is untouched (the audit
     trail, the domain lookup and the two-factor card use it); the rules list on this
     page is a modifier with an icon column. */
  .modecards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin: 0; padding: 0; border: 0; min-width: 0; }
  .modecard { position: relative; display: grid; grid-template-columns: auto auto minmax(0, 1fr); gap: 12px; align-items: start; padding: 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--ink-850); transition: border-color .18s var(--ease), background .18s var(--ease), box-shadow .18s var(--ease); }
  .modecard:hover { border-color: var(--line-2); }
  .modecard:has(.modecard__input:checked) { border-color: var(--signal); box-shadow: inset 0 0 0 1px var(--signal); background: var(--signal-wash); }
  .modecard:has(.modecard__input:focus-visible) { outline: 2px solid var(--signal); outline-offset: 2px; }
  .modecard:has(.modecard__input:disabled) { opacity: .6; }
  .modecard:has(.modecard__input:disabled) label { cursor: not-allowed; }
  .modecard__input { position: relative; z-index: 1; width: 18px; height: 18px; margin: 11px 0 0; accent-color: var(--signal); cursor: pointer; }
  .modecard__input:disabled { cursor: not-allowed; }
  .modecard__text { min-width: 0; display: grid; gap: 6px; }
  .modecard__title { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 15px; font-weight: 700; letter-spacing: -0.01em; min-height: 24px; }
  .modecard__title label { cursor: pointer; }
  /* The whole card is the label's hit area (an overlay); the radio sits above it, so it still takes its own clicks and keeps the keyboard. */
  .modecard__title label::before { content: ""; position: absolute; inset: 0; }
  .modecard__desc { margin: 0; color: var(--text-2); font-size: 13.5px; }
  .modecard__points { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 5px; font-size: 13px; color: var(--text-2); }
  .modecard__points li { display: flex; gap: 8px; align-items: flex-start; }
  .modecard__points svg { width: 15px; height: 15px; flex: none; color: var(--allow); margin-top: 1px; }
  .modeicon { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: var(--radius-sm); background: var(--signal-wash); color: var(--signal); flex: none; }
  .modeicon svg { width: 20px; height: 20px; }
  .rulecard__lead { display: flex; gap: 14px; align-items: flex-start; min-width: 0; }
  /* A standing fact that is neither a success nor a fault: "you have selected…". */
  .notice--info { color: var(--text-2); border: 1px solid var(--line-2); background: var(--ink-780); }
  .notice--info svg { color: var(--signal); }
  .notice--info b { color: var(--text); }
  .layers--rules .layer { grid-template-columns: 22px 120px minmax(0, 1fr) auto; }
  .layer__icon { display: inline-flex; color: var(--text-3); }
  .layer__icon svg { width: 18px; height: 18px; }
  .layer.danger .layer__icon { color: var(--block); }
  .layer.signal .layer__icon { color: var(--allow); }
  @media (max-width: 720px) {
    .modecards { grid-template-columns: minmax(0, 1fr); }
  }
  @media (max-width: 720px) {
    .layers--rules .layer { grid-template-columns: 22px minmax(0, 1fr) auto; row-gap: 4px; }
    .layers--rules .layer__icon { grid-column: 1; grid-row: 1 / span 2; }
    .layers--rules .layer__kind { grid-column: 2; grid-row: 1; }
    .layers--rules .layer__action { grid-column: 3; grid-row: 1; }
    .layers--rules .layer__sentence { grid-column: 2 / span 2; grid-row: 2; }
    .rulecard__lead { gap: 12px; }
  }

  /* Portal #207: Protection & policies — the mode and the blocking policies on one page.
     A section opens with an icon tile, the H2 and one sentence (.sectionhead; three
     glyphs, never one twice). Policies are rows on one grid — icon · title · sentence ·
     control — so every sentence starts on the same column. The NRD windows are ONE radio
     group (.segradio): Off · 7 days · 14 days, the checked option told by fill AND weight.
     The detectors carry a text badge (.pill--beta), never a dead switch. .layer, .modecard
     and .segmented (buttons) are untouched. */
  .sectionhead { display: flex; gap: 14px; align-items: flex-start; margin: 0 0 16px; min-width: 0; }
  .sectionhead__text { min-width: 0; }
  .sectionhead__title { margin: 0; font-size: 17px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.25; }
  .sectionhead__sub { margin: 5px 0 0; color: var(--text-2); font-size: 13.5px; max-width: 80ch; }
  .modecard__since { margin: 2px 0 0; color: var(--text-3); font-size: 12.5px; }
  .modechange { margin-top: 16px; }
  .policyrows { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
  .policyrow { display: grid; grid-template-columns: 22px 210px minmax(0, 1fr) auto; gap: 14px; align-items: center; padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--ink-850); }
  .policyrow__icon { display: inline-flex; color: var(--text-2); }
  .policyrow__icon svg { width: 20px; height: 20px; }
  .policyrow__title { font-size: 14.5px; font-weight: 700; letter-spacing: -0.01em; color: var(--text); }
  .policyrow__body { min-width: 0; }
  .policyrow__sentence { margin: 0; color: var(--text-2); font-size: 13px; }
  .policyrow__state { margin: 7px 0 0; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; color: var(--text-3); font-size: 12.5px; }
  .policyrow__control { display: flex; justify-content: flex-end; }
  .switch__state { min-width: 2.2em; font-size: 13px; font-weight: 600; color: var(--text-2); }
  .switch:has(input:checked) .switch__state { color: var(--text); }
  .pill--beta { color: var(--text-2); border-color: var(--line-2); background: var(--ink-780); white-space: nowrap; }
  .segradio { display: inline-flex; margin: 0; padding: 3px; gap: 3px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--ink-800); min-width: 0; }
  .segradio__opt { position: relative; display: inline-flex; }
  .segradio__opt input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
  .segradio__opt span { padding: 6px 12px; border-radius: 6px; font-size: 13px; font-weight: 500; color: var(--text-2); white-space: nowrap; transition: background .18s var(--ease), color .18s var(--ease); }
  .segradio__opt:hover span { color: var(--text); }
  .segradio__opt input:checked + span { background: var(--signal-wash); color: var(--text); font-weight: 700; box-shadow: inset 0 0 0 1px var(--signal); }
  .segradio__opt input:focus-visible + span { outline: 2px solid var(--signal); outline-offset: 2px; }
  .segradio__opt input:disabled { cursor: not-allowed; }
  .segradio__opt:has(input:disabled) span { opacity: .55; }
  .segradio__opt:has(input:disabled:checked) span { opacity: 1; }
  @media (max-width: 1040px) {
    .policyrow { grid-template-columns: 22px minmax(0, 1fr); row-gap: 8px; align-items: start; }
    .policyrow__icon { grid-column: 1; grid-row: 1; margin-top: 1px; }
    .policyrow__title { grid-column: 2; grid-row: 1; }
    .policyrow__body { grid-column: 2; grid-row: 2; }
    .policyrow__control { grid-column: 2; grid-row: 3; justify-content: flex-start; }
  }
}

/* Portal #208 — Help: the customer guide inside the portal, and its entry in the
   sidebar footer between the account and Sign out. Everything is help__* so the
   guide's vocabulary never touches the shell's (.pill, .notice, .card…); every
   colour is a token, so both themes follow. One reading column, full-width
   figures, tables that scroll inside their own wrapper. */
@layer components {
  .sidebar__help { display: flex; align-items: center; gap: 9px; padding: 7px 10px; border-radius: var(--radius-xs); color: var(--text-2); font-size: 12.5px; font-weight: 500; transition: color .15s var(--ease), background .15s var(--ease); }
  .sidebar__help svg { width: 15px; height: 15px; flex: none; opacity: .85; }
  .sidebar__help:hover { color: var(--text); background: var(--ink-780); }
  .sidebar__help.is-active { color: var(--text); background: linear-gradient(90deg, var(--signal-wash), transparent 80%), var(--ink-700); }
  .sidebar__help.is-active svg { opacity: 1; color: var(--signal); }

  .help { max-width: 920px; font-size: 14.5px; line-height: 1.6; color: var(--text); }
  .help [id] { scroll-margin-top: 84px; }
  .help h2 { margin: 44px 0 0; padding-top: 22px; border-top: 1px solid var(--line); font-size: 20px; font-weight: 700; letter-spacing: -0.02em; text-wrap: balance; }
  .help h3 { margin: 24px 0 0; font-size: 15.5px; font-weight: 700; letter-spacing: -0.01em; }
  .help h4 { margin: 16px 0 0; font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-2); }
  .help p, .help ul { max-width: 72ch; margin: 10px 0; }
  .help ul { padding-left: 20px; list-style: disc; }
  .help a { color: var(--signal-text); }
  .help code { font-family: var(--font-mono); font-size: .88em; background: var(--ink-700); padding: 1px 5px; border-radius: 4px; overflow-wrap: anywhere; }
  .help pre { font-family: var(--font-mono); font-size: 12.5px; line-height: 1.5; background: var(--ink-700); border: 1px solid var(--line); border-radius: var(--radius-xs); padding: 12px 14px; overflow-x: auto; margin: 12px 0; }
  .help figure { margin: 18px 0; }
  .help figure img { display: block; width: 100%; height: auto; border: 1px solid var(--line-2); border-radius: var(--radius-xs); background: var(--ink-800); }
  .help figure.help__fig--half img { max-width: 520px; }
  .help figcaption { margin-top: 7px; max-width: 72ch; font-size: 13px; color: var(--text-2); }
  .help__lead { color: var(--text-2); }
  .help__toc { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 6px 22px; margin: 0 0 6px; padding: 0 !important; list-style: none !important; max-width: none !important; font-size: 14px; }
  .help__toc a { color: var(--text); text-decoration: none; border-bottom: 1px solid var(--line); }
  .help__toc a:hover, .help__toc a:focus-visible { border-color: var(--signal); outline: none; }
  .help__toc span { color: var(--text-3); font-family: var(--font-mono); font-size: 11.5px; margin-right: 8px; }
  .help__legend, .help__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 12px; margin: 16px 0; }
  .help__legend > div, .help__grid > div { min-width: 0; background: var(--ink-780); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 12px 14px; font-size: 13.5px; }
  .help__legend h3, .help__grid h3 { margin: 0 0 6px; font-size: 13.5px; }
  .help__grid p { margin: 5px 0; }
  .help__kv { font-family: var(--font-mono); font-size: 12px; color: var(--text-2); }
  .help__note { border-left: 3px solid var(--signal); background: var(--ink-780); border-radius: 0 var(--radius-xs) var(--radius-xs) 0; padding: 10px 14px; margin: 16px 0; max-width: 76ch; }
  .help__note--warn { border-left-color: var(--flag); }
  .help__note--crit { border-left-color: var(--block); }
  .help__ph { border: 1px dashed var(--flag); background: color-mix(in oklab, var(--flag) 8%, transparent); border-radius: var(--radius-xs); padding: 12px 14px; margin: 16px 0; max-width: 76ch; }
  .help__ph .help__kv { color: var(--text); }
  .help__steps { counter-reset: step; list-style: none; padding: 0; margin: 12px 0; max-width: 76ch; }
  .help__steps li { position: relative; padding-left: 36px; margin: 9px 0; }
  .help__steps li::before { counter-increment: step; content: counter(step); position: absolute; left: 0; top: 1px; width: 24px; height: 24px; border-radius: 50%; background: var(--signal); color: var(--signal-ink); font-weight: 700; font-size: 12px; display: grid; place-items: center; }
  .help__tbl { overflow-x: auto; margin: 14px 0; }
  .help__tbl table { border-collapse: collapse; width: 100%; font-size: 13.5px; }
  .help__tbl th, .help__tbl td { text-align: left; padding: 7px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
  .help__tbl th { font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--text-2); }
  .help__pill { display: inline-block; font-size: 11.5px; font-weight: 600; padding: 1px 8px; border-radius: var(--radius-pill); border: 1px solid var(--line-2); margin: 2px 4px 2px 0; white-space: nowrap; }
  .help__pill--info { color: var(--signal-text); }
  .help__pill--warn { color: var(--flag); }
  .help__pill--high { color: var(--block); }
  .help__pill--ok { color: var(--allow); }
  .help__role, .help__code { display: inline-block; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .03em; padding: 0 6px; border-radius: 4px; border: 1px solid var(--line-2); color: var(--text-2); margin: 0 2px; white-space: nowrap; vertical-align: middle; }
  .help__role--owner { border-color: var(--signal); color: var(--signal-text); }
  .help__code { border-color: var(--flag); color: var(--flag); }
  .help__code--always { border-color: var(--block); color: var(--block); }
  .help__foot { margin-top: 48px; padding-top: 16px; border-top: 1px solid var(--line); color: var(--text-3); font-size: 12.5px; }
  @media (max-width: 900px) {
    .sidebar__help { min-height: 44px; }
  }
  @media (max-width: 720px) {
    .help { font-size: 14px; }
    .help h2 { margin-top: 36px; font-size: 18px; }
  }
}

/* Portal #207 (2026-10-22) — ported from Portal resources/css/app.css. */
@layer components {
  /* Portal #207 / #239 — "How requests are handled", laid out after PortalReview mockup 01: a
     full-width table under the two mode cards. Its header row shows the title and sentence on the
     left and one boxed header per mode; each row is glyph · rule · sentence, then one verdict per
     mode. The table describes BOTH modes; it never follows the pick or the mode in force. On a
     phone the mode headers go to screen readers and each verdict names its mode instead. */
  .modehead { margin: 0 0 16px; min-width: 0; }
  .modehead__title { margin: 0; font-size: 17px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.25; }
  .modehead__sub { margin: 5px 0 0; color: var(--text-2); font-size: 13.5px; max-width: 80ch; }
  .modecard .modeicon { border-radius: 50%; }
  /* The Active pill at the card's top right (mockup 01). */
  .modecard__title .pill { margin-left: auto; }
  .ruletable { display: grid; grid-template-columns: minmax(0, 1.6fr) repeat(2, minmax(0, 1fr)); gap: 8px; margin: 22px 0 0; border-collapse: separate; border-spacing: 0; }
  .ruletable thead, .ruletable tbody { display: contents; }
  .ruletable tr { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; }
  .ruletable th, .ruletable td { padding: 10px 13px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--ink-850); }
  .ruletable thead th { display: flex; align-items: center; justify-content: center; font-size: 13.5px; font-weight: 700; color: var(--text); background: var(--ink-800); }
  .ruletable thead th.ruletable__lead { display: grid; gap: 3px; justify-content: stretch; align-content: end; padding: 0 4px 2px; border: 0; background: none; text-align: left; }
  .ruletable__title { font-size: 15px; font-weight: 700; letter-spacing: -0.01em; }
  .ruletable__sub { font-size: 13px; font-weight: 400; color: var(--text-2); }
  .ruletable tbody th { display: grid; grid-template-columns: 22px minmax(0, 1fr); column-gap: 12px; row-gap: 2px; align-items: center; text-align: left; font-weight: 400; }
  .ruletable td { display: flex; align-items: center; justify-content: center; }
  .ruletable__icon { grid-row: 1 / span 2; display: inline-flex; color: var(--text-2); }
  .ruletable__icon svg { width: 19px; height: 19px; }
  .ruletable__kind { font-size: 14px; font-weight: 700; }
  .ruletable__sentence { font-size: 13px; color: var(--text-2); }
  .ruletable tr.is-default th, .ruletable tr.is-default td { background: transparent; border-style: dashed; }
  .ruletable tr.is-default .ruletable__kind { color: var(--text-2); }
  .ruletable .pill svg { width: 13px; height: 13px; flex: none; }
  /* The Block verdict is `.is-block`, not `.block`: Tailwind's `.block { display: block }`
     utility outranks this layer and would drop the icon onto its own line. Same colours. */
  .ruletable .pill.is-block { color: var(--block); border-color: color-mix(in oklab, var(--block) 34%, transparent); background: color-mix(in oklab, var(--block) 10%, transparent); }
  .ruletable__note { margin: 10px 0 0; font-size: 13px; color: var(--text-3); }
  @media (max-width: 720px) {
    .ruletable { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .ruletable thead th.ruletable__lead, .ruletable tbody th { grid-column: 1 / -1; }
    .ruletable thead th.ruletable__mode { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
    .ruletable td { flex-direction: column; gap: 6px; }
    .ruletable td::before { content: attr(data-mode-label); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); }
  }

  /* The flag notice — a caution that is not an error (an unconfirmed change, a lock with its reason).
     In the portal since KoraxDB #651; ported here with KoraxDB #1183, whose coverage lock wears it. */
  .notice--flag { color: var(--flag); border: 1px solid color-mix(in oklab, var(--flag) 36%, transparent); background: color-mix(in oklab, var(--flag) 9%, transparent); }
  .notice--flag a { color: inherit; font-weight: 600; }

  /* ---------------------------------------------------------------- Coverage (KoraxDB #1183)
     How much of an organisation's traffic the classifier can label, at the top of Content
     categories: the figure and its state pill, a .meter with the bar KoraxDB grants at marked on
     it (the words say the state; the fill colour only repeats it: --ok met, --low not yet), and "Your traffic by category"
     — a doughnut beside its .legend, then the web-filter labels in a small table. */
  .coverage { display: grid; gap: 4px; margin: 0 0 16px; padding: 16px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--ink-800); min-width: 0; }
  .coverage__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 12px; }
  .coverage__figure { margin: 0; font-size: 15px; font-weight: 700; letter-spacing: -0.01em; color: var(--text); min-width: 0; }
  .meter { position: relative; height: 8px; margin-top: 10px; border-radius: 999px; background: var(--ink-700); box-shadow: inset 0 0 0 1px var(--line); }
  .meter__fill { display: block; height: 100%; max-width: 100%; border-radius: 999px; background: var(--text-3); transition: width .3s var(--ease); }
  .meter--ok .meter__fill { background: var(--allow); }
  .meter--low .meter__fill { background: var(--flag); }
  .meter__mark { position: absolute; top: -4px; bottom: -4px; width: 2px; margin-left: -1px; border-radius: 1px; background: var(--text); }
  .meter__scale { position: relative; display: flex; justify-content: space-between; margin-top: 5px; font-size: 11.5px; color: var(--text-3); font-variant-numeric: tabular-nums; }
  .meter__marklabel { position: absolute; top: 0; transform: translateX(-50%); color: var(--text-2); white-space: nowrap; }
  .coverage__usage { display: grid; gap: 12px; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); min-width: 0; }
  .coverage__usagehead { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 12px; }
  .coverage__title { margin: 0; font-size: 14px; font-weight: 700; color: var(--text); }
  .coverage__chart { display: grid; grid-template-columns: 216px minmax(0, 1fr); gap: 20px; align-items: center; min-width: 0; }
  .coverage__donut { height: 200px; }
  .legend__item--total { padding-top: 8px; border-top: 1px solid var(--line); color: var(--text); font-weight: 600; }
  .coverage__web { min-width: 0; overflow-x: auto; }
  .coverage__table { width: 100%; border-collapse: collapse; font-size: 13px; }
  .coverage__table th, .coverage__table td { padding: 8px 5px; text-align: left; border-bottom: 1px solid var(--line); }
  .coverage__table th { color: var(--text-3); font-weight: 600; font-size: 11.5px; }
  .coverage__table .n { text-align: right; font-variant-numeric: tabular-nums; }
  .coverage__caption { caption-side: top; text-align: left; padding: 0 5px 6px; font-size: 12.5px; font-weight: 600; color: var(--text-2); }
  .coverage__caption span { font-weight: 400; color: var(--text-3); }
  @media (max-width: 720px) {
    .coverage { padding: 14px 12px; }
    .coverage__chart { grid-template-columns: minmax(0, 1fr); gap: 14px; }
    .coverage__donut { height: 180px; }
  }
}

/* Ported from Portal (dashboard review against Design/PortalReview/dashboard.jpeg). */
@layer components {
  /* ------------------------------------------- Dashboard layout (PortalReview mockup)
     Tiles: the value and its day-over-day change on one line; Blocked and Flagged carry
     a faint wash of their verdict colour. Then the cache card beside the domain test,
     and a row of compact cards that share the width (an empty card wrapper is hidden). */
  .stats--3 { grid-template-columns: repeat(3, 1fr); }
  .stat__row { margin-top: 12px; display: flex; align-items: center; gap: 14px; min-width: 0; }
  .stat__row .stat__value { margin-top: 0; }
  .stat--block { background: linear-gradient(180deg, color-mix(in oklab, var(--block) 7%, var(--ink-800)), var(--ink-850)); }
  .stat--flag { background: linear-gradient(180deg, color-mix(in oklab, var(--flag) 8%, var(--ink-800)), var(--ink-850)); }
  .stat__live { width: 10px; height: 10px; border-radius: 50%; background: var(--allow); box-shadow: 0 0 0 4px color-mix(in oklab, var(--allow) 18%, transparent); flex: none; }
  .stat__delta { display: inline-flex; align-items: center; gap: 4px; font-size: 15px; font-weight: 700; color: var(--text-3); font-variant-numeric: tabular-nums; }
  .stat__delta svg { width: 16px; height: 16px; }
  .stat__delta.is-allow { color: var(--allow); }
  .stat__delta.is-block { color: var(--block); }
  .stat__delta.is-flag { color: var(--flag); }
  .dash-split { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: 16px; align-items: stretch; margin-top: 16px; }
  .dash-split > .card, .dash-split > .policy-rule-card { height: 100%; }
  .cachecard { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
  .cachecard__text { min-width: 0; }
  /* The dashboard runs wider than the other pages: four cards in a row need the room. */
  /* Portal #250: the whitelist / blacklist tables and Protection & policies run as wide as the dashboard. */
  .content:has(.dash-cards, .listhead, #protection-tabpanel) { max-width: 1440px; }
  /* A wrapping row: top blocked categories (first) takes about twice a card's width. */
  .dash-cards { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 16px; align-items: stretch; }
  .dash-cards > * { flex: 1 1 200px; min-width: 0; }
  .dash-cards > :first-child { flex: 1.9 1 340px; }
  /* Every card as tall as the row: a card is the flex item, or fills the Livewire wrapper that is. */
  .dash-cards > :not(.card) { display: flex; flex-direction: column; }
  .dash-cards > :not(.card):not(:has(.card)) { display: none; }
  .dash-cards .card { display: flex; flex-direction: column; }
  .dash-cards > * > .card { flex: 1; }
  /* The card's one link sits at its foot, whatever the height of the others. */
  .card__more { margin: auto 0 0; padding-top: 12px; }
  .minichart { display: grid; grid-template-columns: 140px minmax(0, 1fr); gap: 20px; align-items: center; }
  .minichart__donut { height: 140px; }
  .legend--compact { display: grid; gap: 9px; }
  .legend__item--more { color: var(--text-3); }
  /* Portal #267: a legend row that opens /activity narrowed to its category — the whole row is the target. */
  .legend__link { display: flex; align-items: center; gap: 9px; flex: 1; min-width: 0; color: inherit; text-decoration: none; border-radius: 4px; }
  .legend__link:hover .legend__name, .legend__link:focus-visible .legend__name { color: var(--text); text-decoration: underline; text-underline-offset: 2px; }
  .legend__link:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }
  .donut--lg, .donut--lg svg { width: 104px; height: 104px; }
  .donut--lg .donut__value { font-size: 21px; }
  .donut__value small { font-size: 12px; font-weight: 600; color: var(--text-3); margin-left: 1px; }
  .dash-cards .section-title { flex-wrap: wrap; row-gap: 2px; }
  .fleetsum { text-align: center; }
  .fleetsum__split > div { text-transform: capitalize; }
  .fleetsum__total { display: grid; gap: 2px; font-size: 12.5px; color: var(--text-3); }
  .fleetsum__total .mono { font-size: 28px; font-weight: 700; color: var(--text); line-height: 1.1; }
  .fleetsum__split { display: grid; grid-template-columns: repeat(3, 1fr); margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); font-size: 12.5px; color: var(--text-3); }
  .fleetsum__split > div { display: grid; gap: 2px; }
  .fleetsum__split > div + div { border-left: 1px solid var(--line); }
  .fleetsum__split .mono { font-size: 18px; font-weight: 700; color: var(--text); }
  @media (max-width: 1040px) {
    .stats--3 { grid-template-columns: repeat(2, 1fr); }
    .dash-split { grid-template-columns: minmax(0, 1fr); }
  }
  @media (max-width: 820px) { .stats--3 { grid-template-columns: 1fr; } }
  @media (max-width: 560px) {
    .minichart { grid-template-columns: minmax(0, 1fr); justify-items: center; }
    .legend--compact { width: 100%; }
  }
  /* ------------------------------------------- Protection & policies tabs (Portal #234)
     One card: the tab bar (Protection mode · Blocking policies · Content categories), then the
     open tab's section, which drops its own card chrome inside it. The selected tab is told by
     weight, the accent underline AND aria-selected, never colour alone. Blocking policies rows get
     a round icon tile (PortalReview mockup 02); content categories are a grid of compact cells —
     icon · title · (i) · switch — 3 / 2 / 1 columns, the description opening inside the cell. */
  .protab { padding: 0; min-width: 0; }
  .tabs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border-bottom: 1px solid var(--line); }
  .tab { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-width: 0; margin: 0 0 -1px; padding: 15px 14px 13px; border: 0; border-bottom: 2px solid transparent; background: none; color: var(--text-2); font: inherit; font-size: 14px; font-weight: 600; text-align: center; cursor: pointer; transition: color .18s var(--ease), background .18s var(--ease), border-color .18s var(--ease); }
  .tab:first-child { border-top-left-radius: var(--radius); }
  .tab:last-child { border-top-right-radius: var(--radius); }
  .tab svg { width: 18px; height: 18px; flex: none; color: var(--text-3); }
  .tab:hover { color: var(--text); background: var(--ink-800); }
  .tab[aria-selected="true"] { color: var(--text); font-weight: 700; border-bottom-color: var(--signal); background: var(--signal-wash); cursor: default; }
  .tab[aria-selected="true"] svg { color: var(--signal); }
  .tab:focus-visible { outline: 2px solid var(--signal); outline-offset: -3px; }
  .protab__panel { padding: 22px 20px 20px; min-width: 0; }
  .protab__panel:focus { outline: none; }
  .protab__panel > div > section.card { padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; }
  .modechange__row { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 12px 16px; }
  .modechange__row > .field__hint { margin-right: auto; max-width: 60ch; }
  .protab .policyrow { grid-template-columns: 40px 210px minmax(0, 1fr) auto; padding: 14px 16px 14px 14px; }
  .protab .policyrow__icon { align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 50%; background: var(--ink-780); color: var(--text-2); }
  .catgrid__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 16px; margin: 4px 0 12px; }
  .catgrid__title { margin: 0; font-size: 14px; font-weight: 700; color: var(--text); }
  .catgrid__count { margin-left: 4px; color: var(--text-3); font-weight: 600; font-variant-numeric: tabular-nums; }
  .catgrid__search { flex: 0 1 320px; min-width: 0; }
  .catgrid__search .input { width: 100%; }
  .catgrid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; align-items: start; }
  .catcell { display: grid; gap: 6px; min-width: 0; padding: 9px 10px 9px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--ink-850); transition: border-color .18s var(--ease); }
  .catcell.is-on { border-color: var(--line-2); background: var(--ink-800); }
  .catcell__main { display: grid; grid-template-columns: 18px minmax(0, auto) auto 1fr auto; align-items: center; gap: 8px; min-width: 0; }
  .catcell__icon { display: inline-flex; color: var(--text-3); }
  .catcell__icon svg { width: 17px; height: 17px; }
  .catcell__title { min-width: 0; font-size: 13.5px; font-weight: 600; color: var(--text); overflow-wrap: anywhere; }
  .catcell__info { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; margin: -4px 0; padding: 0; border: 0; border-radius: 50%; background: none; color: var(--text-3); cursor: pointer; }
  .catcell__info svg { width: 16px; height: 16px; }
  .catcell__info:hover, .catcell__info[aria-expanded="true"] { color: var(--text); background: var(--ink-780); }
  .catcell__info:focus-visible { outline: 2px solid var(--signal); outline-offset: 1px; }
  .catcell__control { grid-column: 5; display: flex; justify-content: flex-end; }
  .catcell__control .switch { gap: 8px; }
  /* Beside a switch the On/Off word only repeats it (the knob, and the state line when on); a read-only member's word stays. */
  .catcell__control .switch .switch__state { display: none; }
  .catcell__desc { margin: 0; padding: 8px 10px; border-radius: 6px; background: var(--ink-780); color: var(--text-2); font-size: 12.5px; line-height: 1.45; }
  .catcell__state { margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; color: var(--text-3); font-size: 12px; }
  .catcell__hint { margin: 0; color: var(--text-3); font-size: 12px; }
  .catcell__hint b { color: var(--text-2); }
  @media (max-width: 1040px) {
    .catgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .protab .policyrow { grid-template-columns: 40px minmax(0, 1fr); }
    .protab .policyrow__icon { grid-row: 1 / span 2; margin-top: 0; }
  }
  @media (max-width: 720px) {
    .catgrid { grid-template-columns: minmax(0, 1fr); }
    .catgrid__search { flex-basis: 100%; }
    .protab__panel { padding: 18px 14px 16px; }
    .tab { flex-direction: column; gap: 5px; padding: 12px 6px 10px; font-size: 12.5px; line-height: 1.25; }
    .modechange__row > .btn { width: 100%; justify-content: center; }
  }
}

/* Portal #238 — the setup wizard at /setup (PortalReview Wizard01–04). The wizard
   draws its own shell: a rail with the brand, the vertical stepper and the
   Need-help card, then the page. Night Watch tokens only, so both themes hold. */
@layer components {
  .setup { position: relative; z-index: 1; display: grid; grid-template-columns: 300px minmax(0, 1fr); min-height: 100vh; min-height: 100dvh; }
  .setup__rail {
    position: sticky; top: 0; align-self: start; height: 100vh; height: 100dvh; overflow-y: auto;
    display: flex; flex-direction: column; gap: 18px; padding: 24px 18px;
    border-right: 1px solid var(--line);
    background: linear-gradient(180deg, color-mix(in oklab, var(--ink-850) 92%, transparent), var(--ink-900));
  }
  .setup__steps { list-style: none; margin: 18px 0 0; padding: 0; display: grid; gap: 0; }
  .setup__steps > li { position: relative; }
  /* The connector between two numbers. */
  .setup__steps > li + li::before { content: ""; position: absolute; left: 27px; top: -10px; height: 20px; width: 2px; border-radius: 2px; background: var(--line-2); }
  .setup__steps > li:has(.is-done) + li::before { background: color-mix(in oklab, var(--signal) 55%, transparent); }
  .setup__step { width: 100%; display: flex; align-items: flex-start; gap: 12px; padding: 10px; min-height: 44px; margin: 0 0 10px; border: 1px solid transparent; border-radius: var(--radius-sm); background: none; color: var(--text-2); font: inherit; text-align: left; cursor: pointer; transition: background .15s var(--ease), border-color .15s var(--ease); }
  .setup__step:hover { background: var(--ink-780); }
  .setup__step.is-current { background: var(--signal-wash); border-color: color-mix(in oklab, var(--signal) 30%, transparent); color: var(--text); }
  .setup__num { flex: none; width: 34px; height: 34px; display: grid; place-items: center; border-radius: 50%; border: 1px solid var(--line-2); background: var(--ink-700); font-family: var(--font-mono); font-size: 13px; font-weight: 700; color: var(--text-2); }
  .setup__num svg { width: 15px; height: 15px; }
  .setup__step.is-current .setup__num { background: var(--signal); border-color: var(--signal); color: var(--signal-ink); box-shadow: 0 0 0 4px var(--signal-wash); }
  .setup__step.is-done .setup__num { background: color-mix(in oklab, var(--allow) 14%, transparent); border-color: color-mix(in oklab, var(--allow) 45%, transparent); color: var(--allow); }
  .setup__label { min-width: 0; display: grid; gap: 2px; padding-top: 2px; }
  .setup__label b { font-size: 14px; font-weight: 650; color: var(--text); }
  .setup__label span { font-size: 12.5px; color: var(--text-3); }
  .setup__step.is-skipped .setup__label span { color: var(--flag); }

  .setup__main { min-width: 0; padding: 22px 32px 48px; }
  .setup__topbar { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 18px; }
  .setup__org { font-size: 13px; color: var(--text-3); }
  .setup__tools { display: flex; align-items: center; gap: 10px; }
  .setup__account { position: relative; }
  .setup__account > summary { list-style: none; display: inline-flex; align-items: center; gap: 4px; min-height: 40px; padding: 6px 10px; border-radius: var(--radius-sm); cursor: pointer; color: var(--text-2); }
  .setup__account > summary::-webkit-details-marker { display: none; }
  .setup__account > summary:hover, .setup__account[open] > summary { background: var(--ink-780); color: var(--text); }
  .setup__account > summary svg { width: 20px; height: 20px; }
  .setup__account > summary .setup__chev { width: 15px; height: 15px; }
  .setup__menu { position: absolute; right: 0; top: calc(100% + 6px); z-index: 20; min-width: 220px; padding: 8px; display: grid; gap: 2px; box-shadow: var(--shadow-lg); }
  .setup__menu a, .setup__menu .linkbtn { display: flex; width: 100%; min-height: 36px; align-items: center; padding: 7px 10px; border-radius: var(--radius-xs); font-size: 13.5px; color: var(--text-2); }
  .setup__menu a:hover { background: var(--ink-780); color: var(--text); }
  .setup__who { display: grid; gap: 2px; padding: 6px 10px 10px; margin-bottom: 4px; border-bottom: 1px solid var(--line); }
  .setup__who b { font-size: 13px; }
  .setup__who span { font-size: 12px; color: var(--text-3); overflow-wrap: anywhere; }

  .setup__panel { padding: 28px 30px; max-width: 1120px; }
  .setup__eyebrow { margin: 0 0 6px; font-size: 13px; font-weight: 650; color: var(--signal-text); }
  .setup__title { margin: 0 0 8px; font-size: 30px; line-height: 1.15; letter-spacing: -0.03em; }
  .setup__lead { margin: 0 0 22px; max-width: 74ch; color: var(--text-2); line-height: 1.55; }
  .setup__actions { display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 12px; margin-top: 22px; }
  .setup__actions .field__hint { margin: 0 auto 0 0; }
  /* Portal #307: the footer of an optional step — hint on the left, "Do this later" + Continue on the right. */
  .setup__foot { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px 20px; margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line); }
  .setup__foot-hint { display: flex; align-items: center; gap: 8px; margin: 0; color: var(--text-3); font-size: 13px; font-style: italic; }
  .setup__foot-hint svg { flex: none; width: 16px; height: 16px; }
  .setup__foot-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-left: auto; }
  .setup .btn--lg { padding: 13px 22px; font-size: 15px; border-radius: var(--radius); }
  .setup .btn svg { width: 17px; height: 17px; }

  .setup__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; align-items: start; }
  .setup-card { min-width: 0; padding: 18px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--ink-850); }
  .setup-card__head { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
  .setup-card__icon { flex: none; width: 40px; height: 40px; display: grid; place-items: center; border-radius: var(--radius-sm); background: var(--signal-wash); color: var(--signal-text); }
  .setup-card__icon svg { width: 22px; height: 22px; }
  .setup-card__title { margin: 0; font-size: 16px; font-weight: 650; }
  .setup-card__sub { font-weight: 500; color: var(--text-2); }
  .setup-card__text { margin: 0 0 14px; font-size: 13.5px; line-height: 1.55; color: var(--text-2); }
  .setup-card__foot { margin: 14px 0 0; padding-top: 12px; border-top: 1px solid var(--line); font-size: 12.5px; line-height: 1.55; color: var(--text-3); }
  .setup-card__foot a { color: var(--signal-text); }

  .setup-detected { padding: 14px; border-radius: var(--radius-sm); border: 1px solid color-mix(in oklab, var(--signal) 26%, transparent); background: var(--signal-wash); }
  .setup-detected__label { margin: 0 0 10px; font-size: 13px; font-weight: 600; }
  .setup-detected__row { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
  .setup-detected__globe { width: 22px; height: 22px; flex: none; color: var(--text-2); }
  .setup-detected__ip { font-size: 16px; font-weight: 700; overflow-wrap: anywhere; }
  .setup-detected__add { margin-left: auto; }
  .setup-info { position: relative; display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; color: var(--text-3); cursor: help; }
  .setup-info svg { width: 17px; height: 17px; }
  .setup-info__tip { position: absolute; z-index: 10; bottom: calc(100% + 8px); left: 50%; translate: -50% 0; width: 250px; padding: 10px 12px; border-radius: var(--radius-sm); border: 1px solid var(--line-2); background: var(--ink-700); box-shadow: var(--shadow); font-size: 12.5px; line-height: 1.45; color: var(--text); opacity: 0; pointer-events: none; transition: opacity .15s var(--ease); }
  .setup-info:hover .setup-info__tip, .setup-info:focus .setup-info__tip { opacity: 1; }

  .setup-ranges { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 6px; }
  .setup-ranges li { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding: 8px 10px; border-radius: var(--radius-xs); background: var(--ink-800); border: 1px solid var(--line); font-size: 13px; }
  .setup-ranges li > svg { width: 15px; height: 15px; color: var(--allow); flex: none; }
  .setup-ranges__name { color: var(--text-3); }
  .setup-ranges .pill { margin-left: auto; }
  .setup-or { display: flex; align-items: center; gap: 12px; margin: 12px 0; font-size: 12.5px; color: var(--text-3); }
  .setup-or::before, .setup-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }
  .setup-another { width: 100%; display: flex; align-items: center; gap: 10px; min-height: 48px; margin-top: 12px; padding: 10px 14px; border-radius: var(--radius-sm); border: 1px solid var(--line-2); background: var(--ink-800); color: var(--text); font: inherit; font-weight: 600; font-size: 14px; cursor: pointer; transition: border-color .15s var(--ease), background .15s var(--ease); }
  .setup-or + .setup-another { margin-top: 0; }
  .setup-another:hover { border-color: var(--line-3); background: var(--ink-780); }
  .setup-another:disabled { opacity: .55; cursor: not-allowed; }
  .setup-another svg { width: 18px; height: 18px; flex: none; }
  .setup-another__arrow { margin-left: auto; color: var(--text-2); }

  .setup-token { display: flex; align-items: center; gap: 6px; }
  .setup-token__value { flex: 1; min-width: 0; letter-spacing: .04em; }
  .setup-token__icon { flex: none; width: 40px; height: 40px; display: grid; place-items: center; border-radius: var(--radius-sm); border: 1px solid var(--line-2); background: var(--ink-800); color: var(--text-2); cursor: pointer; }
  .setup-token__icon:hover { color: var(--text); border-color: var(--line-3); }
  .setup-token__icon[aria-pressed="true"] { color: var(--signal-text); }
  .setup-token__icon svg { width: 18px; height: 18px; }
  .setup-token__copy { flex: none; background: var(--signal-wash); border-color: color-mix(in oklab, var(--signal) 30%, transparent); color: var(--signal-text); }

  /* Portal #297 — step 2 after the mockup: one office card (resolvers | authorised IPs) and
     the optional devices section folded below it. */
  .setup-office__pill { margin-left: auto; }
  .setup-office__grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 18px; align-items: start; margin-top: 14px; }
  .setup-resolvers { padding: 14px; border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--ink-800); }
  .setup-resolvers__title { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; font-size: 13px; font-weight: 600; color: var(--text); }
  .setup-office__count { margin-left: auto; }
  .setup-resolvers__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
  .setup-resolvers__list li { display: grid; grid-template-columns: 80px minmax(0, 1fr) auto; align-items: center; gap: 8px; padding: 6px 6px 6px 10px; border-radius: var(--radius-xs); border: 1px solid var(--line); background: var(--ink-850); font-size: 13px; }
  .setup-resolvers__role { color: var(--text-3); font-size: 12.5px; }
  .setup-resolvers__ip { overflow-wrap: anywhere; }
  .setup-resolvers__all { width: 100%; margin-top: 10px; justify-content: center; }
  .setup-resolvers__all svg { width: 16px; height: 16px; }
  .setup-office__ips .setup-ranges { margin-top: 0; }
  .setup-office__ips .setup-detected { margin-top: 12px; }
  .setup-ranges__text { display: inline-flex; flex-wrap: wrap; gap: 4px 8px; min-width: 0; }
  .setup-ranges__acts { margin-left: auto; display: inline-flex; gap: 4px; }
  .setup-ranges .pill + .setup-ranges__acts { margin-left: 0; }
  .setup-ranges__ask { flex-basis: 100%; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding-top: 8px; border-top: 1px solid var(--line); font-size: 12.5px; color: var(--text-2); }
  .setup-ranges__ask > span { flex: 1 1 200px; }
  .setup-optional { margin-top: 18px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--ink-850); }
  .setup-optional > summary { list-style: none; display: flex; align-items: center; gap: 12px; min-height: 60px; padding: 12px 18px; cursor: pointer; }
  .setup-optional > summary::-webkit-details-marker { display: none; }
  .setup-optional > summary > span { display: grid; gap: 2px; }
  .setup-optional > summary b { font-size: 14.5px; }
  .setup-optional > summary span span { font-size: 12.5px; color: var(--text-3); }
  .setup-optional__chev { width: 18px; height: 18px; flex: none; margin-left: auto; color: var(--text-2); transition: transform .15s var(--ease); }
  .setup-optional[open] .setup-optional__chev { transform: rotate(180deg); }
  .setup-optional > .setup-card { margin: 0 12px 12px; }

  .setup-howto { margin-top: 14px; border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--ink-800); }
  .setup-howto > summary { list-style: none; display: flex; align-items: center; gap: 12px; min-height: 52px; padding: 10px 14px; cursor: pointer; }
  .setup-howto > summary::-webkit-details-marker { display: none; }
  .setup-howto > summary > svg { width: 18px; height: 18px; flex: none; color: var(--text-2); transition: transform .15s var(--ease); }
  .setup-howto[open] > summary > svg { transform: rotate(180deg); }
  .setup-howto > summary > span { display: grid; gap: 2px; }
  .setup-howto > summary b { font-size: 14px; }
  .setup-howto > summary span span { font-size: 12.5px; color: var(--text-3); }
  .setup-howto ul { margin: 0; padding: 4px 16px 14px 34px; display: grid; gap: 10px; font-size: 13px; line-height: 1.55; color: var(--text-2); }
  .setup-howto a { color: var(--signal-text); }

  .setup-mode { display: flex; gap: 14px; margin-top: 18px; padding: 16px 18px; border-radius: var(--radius); border: 1px solid color-mix(in oklab, var(--signal) 22%, transparent); background: color-mix(in oklab, var(--signal) 6%, var(--ink-850)); }
  .setup-mode--blocking { border-color: var(--line); background: var(--ink-850); }
  .setup-mode__icon { flex: none; width: 44px; height: 44px; display: grid; place-items: center; border-radius: 50%; background: var(--signal-wash); color: var(--signal-text); }
  .setup-mode__icon svg { width: 22px; height: 22px; }
  .setup-mode__title { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin: 2px 0 6px; font-size: 15px; }
  .setup-mode__text { margin: 0; font-size: 13px; line-height: 1.6; color: var(--text-2); }
  .setup-mode__text a { color: var(--signal-text); }

  /* Wizard02 — the check in progress. */
  .setup-radar { position: relative; width: 220px; height: 220px; margin: 18px auto 6px; display: grid; place-items: center; }
  .setup-radar__ring { position: absolute; inset: 0; border-radius: 50%; border: 1px solid var(--line-2); }
  .setup-radar__ring + .setup-radar__ring { inset: 30px; border-color: var(--line); }
  .setup-radar__arc { position: absolute; inset: 30px; border-radius: 50%; border: 3px solid transparent; border-top-color: var(--signal); border-right-color: var(--signal); animation: setup-spin 1.6s linear infinite; }
  .setup-radar__core { width: 86px; height: 86px; display: grid; place-items: center; border-radius: 50%; background: var(--signal-wash); color: var(--signal-text); box-shadow: 0 0 40px -6px var(--signal-glow); }
  .setup-radar__core svg { width: 34px; height: 34px; }
  .setup__status { display: grid; gap: 4px; margin: 10px 0 22px; text-align: center; }
  .setup__status b { font-size: 19px; }
  .setup__status span { color: var(--text-2); }
  .setup-progress { list-style: none; margin: 0 auto; padding: 0; max-width: 560px; display: grid; grid-template-columns: repeat(3, 1fr); text-align: center; font-size: 13px; color: var(--text-3); }
  .setup-progress li { position: relative; display: grid; justify-items: center; gap: 8px; }
  .setup-progress li + li::before { content: ""; position: absolute; top: 15px; right: calc(50% + 20px); width: calc(100% - 40px); height: 2px; background: var(--line-2); }
  .setup-progress li.is-done + li::before { background: color-mix(in oklab, var(--signal) 55%, transparent); }
  .setup-progress__dot { width: 32px; height: 32px; display: grid; place-items: center; border-radius: 50%; border: 2px solid var(--line-2); background: var(--ink-700); font-size: 11px; letter-spacing: 1px; }
  .setup-progress__dot svg { width: 15px; height: 15px; }
  .setup-progress .is-done { color: var(--text); }
  .setup-progress .is-done .setup-progress__dot { background: var(--signal); border-color: var(--signal); color: var(--signal-ink); }
  .setup-progress .is-current { color: var(--text); font-weight: 600; }
  .setup-progress .is-current .setup-progress__dot { border-color: var(--signal); color: var(--signal-text); }

  /* Wizard03 / 04 — the result. */
  .setup__result { text-align: center; }
  .setup__result .setup__lead { margin-left: auto; margin-right: auto; }
  .setup__result .setup__actions { justify-content: center; }
  .setup__badge { width: 112px; height: 112px; margin: 6px auto 18px; display: grid; place-items: center; border-radius: 50%; }
  .setup__badge svg { width: 46px; height: 46px; }
  .setup__badge--ok { background: var(--signal-wash); color: var(--signal-text); }
  .setup__badge--err { background: color-mix(in oklab, var(--block) 12%, transparent); color: var(--block); }
  .setup__badge--neutral { background: var(--ink-780); color: var(--text-2); }
  .setup-facts { list-style: none; margin: 0; padding: 18px; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; text-align: left; border-radius: var(--radius); border: 1px solid var(--line); background: var(--ink-850); }
  .setup-facts li { display: flex; gap: 12px; }
  .setup-facts__icon { flex: none; width: 44px; height: 44px; display: grid; place-items: center; border-radius: 50%; background: var(--signal-wash); color: var(--signal-text); }
  .setup-facts__icon svg { width: 20px; height: 20px; }
  .setup-facts li > span:last-child { display: grid; gap: 3px; font-size: 13px; color: var(--text-2); }
  .setup-facts li b { font-size: 14px; color: var(--text); }
  .setup-facts li b a { color: var(--text); text-decoration: underline; text-decoration-color: var(--line-3); text-underline-offset: 3px; }
  .setup-facts--plain { grid-template-columns: 1fr; gap: 10px; }
  .setup-facts--plain dt { font-size: 12px; color: var(--text-3); }
  .setup-facts--plain dd { margin: 2px 0 0; }
  .setup-checklist { display: grid; grid-template-columns: minmax(0, 1fr) 190px; gap: 18px; align-items: center; margin: 0 auto; max-width: 860px; padding: 20px 22px; text-align: left; border-radius: var(--radius); border: 1px solid color-mix(in oklab, var(--block) 30%, transparent); background: color-mix(in oklab, var(--block) 7%, transparent); }
  .setup-checklist--neutral { border-color: var(--line-2); background: var(--ink-850); }
  .setup-checklist b { display: block; margin-bottom: 8px; }
  .setup-checklist ul { margin: 0; padding-left: 18px; display: grid; gap: 8px; font-size: 13.5px; color: var(--text-2); }
  .setup-checklist li::marker { color: var(--block); }
  .setup-checklist--neutral li::marker { color: var(--text-3); }
  .setup-countdown { display: grid; justify-items: center; gap: 10px; text-align: center; font-size: 13px; color: var(--text-2); }
  .setup-countdown__spin { width: 46px; height: 46px; border-radius: 50%; border: 3px solid var(--line-2); border-top-color: var(--text-2); animation: setup-spin 1.4s linear infinite; }

  @media (prefers-reduced-motion: reduce) {
    .setup-radar__arc, .setup-countdown__spin { animation: none; }
  }
  @media (max-width: 1040px) {
    .setup__grid { grid-template-columns: minmax(0, 1fr); }
    .setup-office__grid { grid-template-columns: minmax(0, 1fr); }
  }
  /* Phone and narrow tablet: the rail becomes a block above the page — the stepper
     is the one thing the wizard cannot hide in a drawer. */
  @media (max-width: 900px) {
    .setup { grid-template-columns: minmax(0, 1fr); }
    .setup__rail { position: static; height: auto; overflow: visible; padding: 16px; gap: 10px; border-right: 0; border-bottom: 1px solid var(--line); }
    .setup__steps { margin-top: 4px; }
    .setup__main { padding: 16px 16px 40px; }
    .setup__panel { padding: 20px 16px; }
    .setup__title { font-size: 24px; }
    .setup-facts { grid-template-columns: minmax(0, 1fr); }
    .setup-checklist { grid-template-columns: minmax(0, 1fr); }
    .setup-detected__add { margin-left: 0; width: 100%; }
    .setup-info__tip { left: auto; right: -40px; translate: none; width: min(250px, 70vw); }
    .setup-token { flex-wrap: wrap; }
    .setup-token__value { flex-basis: calc(100% - 92px); }
    .setup-token__copy { width: 100%; min-height: 44px; }
    .setup .btn--lg { width: 100%; }
    .setup__foot { flex-direction: column; align-items: stretch; }
    .setup__foot-actions { flex-direction: column-reverse; margin-left: 0; }
    .setup__foot-actions .btn { width: 100%; min-height: 44px; justify-content: center; }
  }
}

@keyframes setup-spin { to { transform: rotate(360deg); } }

/* Portal #242 — wizard step 1 "Secure your account": two-factor enrolment in the
   wizard's cards (App\Livewire\Portal\Profile\TwoFactorManager, variant setup). The
   QR code sits on white in both themes: scanners need the contrast. */
@layer components {
  .setup-qr { width: max-content; max-width: 100%; margin: 4px 0 0; padding: 12px; border-radius: var(--radius-sm); background: #fff; line-height: 0; }
  .setup-qr svg { display: block; width: 184px; height: 184px; max-width: 100%; }
  .setup-2fa__key { display: inline-block; margin-top: 4px; font-size: 13.5px; letter-spacing: .06em; color: var(--text); overflow-wrap: anywhere; }
  .setup-2fa__form { display: grid; gap: 10px; }
  .setup-2fa .setup__actions { margin-top: 6px; }
  .setup-codes { margin: 0 0 6px; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .setup-codes li { padding: 9px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--ink-900); font-size: 14px; text-align: center; }
  .setup-done { display: flex; align-items: center; gap: 12px; padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--ink-850); }
  .setup-done svg { flex: none; width: 22px; height: 22px; color: var(--allow); }
  @media (max-width: 900px) {
    .setup-codes { grid-template-columns: minmax(0, 1fr); }
  }
}

/* Portal #248 — /whitelist and /blacklist after the PortalReview mockups: the
   search sits beside the title with its glyph, the heading icon wears the list's
   semantic colour, a paused / expired entry carries a small tag next to its name
   (the verdict column is gone), and adding or editing is an inline row of the
   table with Cancel / Save changes under it. No new colour: the row's tint is
   the signal wash the focused input already uses. */
@layer components {
  .listhead { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px 16px; margin-bottom: 16px; }
  .listhead__title { display: flex; align-items: center; flex-wrap: wrap; gap: 12px 18px; min-width: 0; }
  .listhead__search { position: relative; width: 300px; max-width: 100%; }
  .listhead__search svg { position: absolute; left: 12px; top: 50%; width: 18px; height: 18px; translate: 0 -50%; color: var(--text-3); pointer-events: none; }
  .listhead__search .input { padding-left: 40px; }
  .section-title--allow svg { color: var(--allow); }
  .section-title--block svg { color: var(--block); }
  .section-title--allow .count, .section-title--block .count { margin-left: 4px; }

  /* The actions column has a fixed width (grid above): as `auto` it collapsed
     to nothing in the head row, whose cell is empty, and every head sat to the
     right of its column. */
  .streamrow--head .colhead svg { opacity: .55; }
  /* Portal #252: icons sized as on the mockups — the list screens only. */
  .listhead .section-title { font-size: 15px; gap: 10px; }
  .listhead .section-title svg { width: 22px; height: 22px; }
  .streamrow--list .colhead svg { width: 12px; height: 12px; }
  .streamrow--list .streamrow__acts .btn svg { width: 20px; height: 20px; }
  .streamrow--head .colhead.is-sorted svg { opacity: 1; }

  .listtag { flex: none; padding: 1px 8px; font-size: 11px; }

  .streamrow--edit { row-gap: 6px; background: var(--signal-wash); }
  .streamrow--edit:hover { background: var(--signal-wash); }
  .streamrow--edit .input { min-height: 38px; padding-top: 8px; padding-bottom: 8px; font-size: 13.5px; }
  .streamrow--edit .input[readonly] { color: var(--text-2); background: var(--ink-800); cursor: default; }
  .streamrow--edit .input.is-invalid { border-color: var(--block); }
  .streamrow__msg { grid-column: 1 / -1; margin: 0; color: var(--text-3); font-size: 12px; }
  .streamrow__msg .err-text { margin: 0; }
  .streamrow--list .switch input:disabled + .switch__track { opacity: .5; cursor: not-allowed; }
  /* Portal #254: an "on" switch wears the list's verdict — green on the whitelist, red on the
     blacklist, as on the mockups. Off stays the neutral track. */
  .listform--allow .switch input:checked + .switch__track { background: color-mix(in oklab, var(--allow) 16%, transparent); border-color: var(--allow); }
  .listform--allow .switch input:checked + .switch__track::after { background: var(--allow); }
  .listform--block .switch input:checked + .switch__track { background: color-mix(in oklab, var(--block) 16%, transparent); border-color: var(--block); }
  .listform--block .switch input:checked + .switch__track::after { background: var(--block); }

  .listform__foot { display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 9px; margin-top: 16px; }

  @media (max-width: 820px) {
    .listhead__search { width: 100%; }
    .listhead__title { width: 100%; }
    /* The inline row stacks: domain and its ×, then the note, then the switch. */
    .streamrow--edit .streamrow__domain { grid-row: 1; grid-column: 1; }
    .streamrow--edit .streamrow__acts { grid-row: 1; grid-column: 2; }
    .streamrow--list.streamrow--edit .streamrow__desc { display: block; grid-row: 2; grid-column: 1 / -1; }
    .streamrow--list.streamrow--edit .streamrow__switch { display: flex; grid-row: 3; grid-column: 1 / -1; }
    .streamrow--edit .streamrow__msg { grid-row: 4; }
    .listform__foot .btn { flex: 1 1 0; min-height: 44px; }
  }
}

/* Ported from Portal #257: DoH tokens and IP ranges wear the list table (PortalReview DohToken /
   IpRanges mockups). IP ranges take the five list columns as they are (range, name, added, valid
   until, actions). Tokens have no note: the name column takes the note's width and the last three
   columns (expires, on, actions) keep the list's, so the switches and the icons sit at the same
   place on every list-shaped page. */
.streamrow--tokenlist { grid-template-columns: minmax(0, 1.9fr) minmax(0, 1.05fr) minmax(0, 1fr) minmax(0, .85fr) minmax(92px, .75fr); }
/* Name over the masked prefix. */
.streamrow__stack { display: grid; gap: 1px; min-width: 0; }
.streamrow__stack .streamrow__domain { min-width: 0; }
.streamrow__sub { color: var(--text-3); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.streamrow--list .streamrow__expires { color: var(--text-2); }
/* A sortable head with an ⓘ beside it (IP range). */
.colcell { display: inline-flex; align-items: center; gap: 4px; min-width: 0; }
.colcell .setup-info { width: 20px; height: 20px; }
.colcell .setup-info svg { width: 14px; height: 14px; }
.colcell .setup-info__tip { left: 0; translate: none; text-transform: none; letter-spacing: normal; font-weight: 400; }
.streamrow--edit select.input { min-height: 38px; padding-top: 6px; padding-bottom: 6px; font-size: 13.5px; }

@media (max-width: 820px) {
  .streamrow--tokenlist { grid-template-columns: minmax(0, 1fr) 92px; }
  .streamrow--list .streamrow__expires { display: none; }
  .streamrow--list.streamrow--edit .streamrow__pick { display: block; grid-row: 2; grid-column: 1 / -1; }
}

/* Ported from Portal (connect-download layout). */
/* Download Korax Connect after the PortalReview mockup (downloadKoraxConnect.jpeg):
   platform tiles, numbered step cards with a filled circle, the two install
   commands side by side, verify and uninstall / rotate next to each other. No new
   colour: the selected tile and the first download wear the signal wash the
   rest of the portal uses for "current", the circles are the primary button's
   signal on signal-ink. */
@layer components {
  .content:has(.connectstep) { max-width: 1440px; }
  .connect-head p { max-width: 82ch; }

  .ostabs { list-style: none; margin: 0 0 18px; padding: 0; display: flex; flex-wrap: wrap; gap: 12px; }
  .ostab { display: flex; align-items: center; gap: 12px; min-height: 54px; padding: 10px 20px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--ink-850); color: var(--text-2); font-size: 14.5px; font-weight: 600; }
  .ostab__icon { flex: none; width: 22px; height: 22px; }
  .ostab.is-current { border-color: var(--signal); box-shadow: inset 0 0 0 1px var(--signal); background: var(--signal-wash); color: var(--signal-text); }
  .ostab.is-soon { cursor: default; }
  .ostab.is-soon .ostab__icon, .ostab.is-soon .ostab__name { opacity: .75; }
  .ostab__soon { padding: 2px 9px; font-size: 11.5px; font-weight: 500; }

  .connectstep { padding: 22px 24px; margin-top: 16px; min-width: 0; }
  .connectstep__head { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 18px; }
  .connectstep__num { flex: none; width: 38px; height: 38px; display: grid; place-items: center; border-radius: 50%; background: var(--signal); color: var(--signal-ink); font-size: 17px; font-weight: 700; }
  .connectstep__titles { flex: 1 1 auto; min-width: 0; }
  .connectstep__title { margin: 2px 0 2px; font-size: 19px; font-weight: 700; letter-spacing: -0.015em; }
  .connectstep__sub { margin: 0; color: var(--text-2); font-size: 13.5px; }
  .connectstep__action { flex: none; align-self: center; }
  .connectstep__foot { margin: 14px 0 0; color: var(--text-3); font-size: 12.5px; }

  .connectstep__split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(240px, 380px); gap: 24px; padding-left: 52px; }
  .connectdl { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 16px; }
  .connectdl__btn { min-height: 42px; padding-inline: 16px; }
  .connectdl__btn.is-first { border-color: color-mix(in oklab, var(--signal) 45%, transparent); background: var(--signal-wash); color: var(--signal-text); }
  .connectdl__btn.is-missing { opacity: .4; cursor: not-allowed; }

  .connectfacts { display: grid; grid-template-columns: 130px minmax(0, 1fr); gap: 7px 16px; margin: 0; font-size: 13px; }
  .connectfacts dt { color: var(--text-3); }
  .connectfacts dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
  .connectfacts__aside { color: var(--text-3); }
  .connectfacts--paths { margin-top: 14px; grid-template-columns: 110px minmax(0, 1fr); }

  .connectmore { margin-top: 12px; font-size: 13px; }
  .connectmore summary { cursor: pointer; width: fit-content; color: var(--text-3); }
  .connectmore summary:hover { color: var(--text-2); }
  .connectmore[open] summary { margin-bottom: 8px; }
  .connectmore .connectfacts { grid-template-columns: auto minmax(0, 1fr); }

  .connectsign { display: flex; align-items: flex-start; gap: 14px; padding-left: 24px; border-left: 1px solid var(--line); align-self: center; }
  .connectsign__icon { flex: none; width: 26px; height: 26px; color: var(--signal-text); }
  .connectsign:has([data-unsigned]) .connectsign__icon { color: var(--flag); }
  .connectsign__title { margin: 2px 0 4px; font-size: 14.5px; font-weight: 700; }
  .connectsign__text { margin: 0; color: var(--text-2); font-size: 13px; line-height: 1.5; }

  .connectcols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0; }
  .connectcol { min-width: 0; display: flex; flex-direction: column; }
  .connectcol + .connectcol { border-left: 1px solid var(--line); padding-left: 24px; margin-left: 24px; }
  .connectcol__title { margin: 0 0 2px; font-size: 14px; font-weight: 700; }
  .connectcol__sub { margin: 0 0 10px; color: var(--text-2); font-size: 13px; flex: 1 1 auto; }

  .connectpair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; margin-top: 16px; }
  .connectpair > .connectstep { margin-top: 0; }

  .connectuninstall { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 14px; }
  .connectuninstall__label { font-size: 13.5px; font-weight: 600; }

  .connectrotate { display: flex; align-items: center; flex-wrap: wrap; gap: 12px 14px; margin-top: 16px; padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--ink-850); }
  .connectrotate__icon { flex: none; width: 26px; height: 26px; color: var(--signal-text); }
  .connectrotate__body { flex: 1 1 240px; min-width: 0; }
  .connectrotate__title { margin: 0 0 2px; font-size: 14px; font-weight: 700; }
  .connectrotate__text { margin: 0; color: var(--text-2); font-size: 12.5px; line-height: 1.5; }
  .connectrotate__btn { flex: none; border-color: color-mix(in oklab, var(--signal) 45%, transparent); background: var(--signal-wash); color: var(--signal-text); }

  @media (max-width: 1180px) {
    .connectpair { grid-template-columns: minmax(0, 1fr); }
  }
  @media (max-width: 980px) {
    .connectstep__split { grid-template-columns: minmax(0, 1fr); padding-left: 0; }
    .connectsign { padding: 16px 0 0; border-left: 0; border-top: 1px solid var(--line); }
    .connectcols { grid-template-columns: minmax(0, 1fr); gap: 18px; }
    .connectcol + .connectcol { border-left: 0; padding-left: 0; margin-left: 0; }
  }
  @media (max-width: 720px) {
    .connectstep { padding: 18px 16px; }
    .connectstep__head { flex-wrap: wrap; }
    .connectstep__titles { flex-basis: calc(100% - 46px); }
    .connectrotate__body { flex-basis: calc(100% - 40px); }
    .connectstep__num { width: 32px; height: 32px; font-size: 15px; }
    .connectstep__action { width: 100%; min-height: 44px; }
    .ostab { flex: 1 1 100%; }
    .connectdl__btn { flex: 1 1 100%; min-height: 44px; }
    .connectfacts, .connectfacts--paths { grid-template-columns: minmax(0, 1fr); gap: 2px; }
    .connectfacts dd { margin-bottom: 8px; }
    .connectuninstall { grid-template-columns: minmax(0, 1fr); gap: 6px; }
    .connectrotate__btn { width: 100%; min-height: 44px; }
  }
}

/* Korax Connect policy after the PortalReview mockups (KoraxConnect01–04): a
   head card (shield tile · version · divider · fleet), then the tab card of
   Protection & policies with four tabs. Optional blocks put their "managed by
   this policy" switch in a left gutter; identity toggles are bordered rows;
   history rows end on an outlined Roll back. No new colour: tiles and the
   outlined button wear the signal wash and signal text used for "current". */
@layer components {
  .content:has(#policy-tabpanel) { max-width: 1440px; }
  .content:has(#policy-tabpanel) .page-head p { max-width: 82ch; }

  .policyhead { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: start; gap: 18px 20px; padding: 22px 24px; margin-bottom: 16px; }
  .policyhead__icon { display: grid; place-items: center; width: 46px; height: 46px; border-radius: 50%; background: var(--signal-wash); color: var(--signal-text); }
  .policyhead__icon svg { width: 24px; height: 24px; }
  .policyhead__icon--sm { width: 40px; height: 40px; flex: none; }
  .policyhead__icon--sm svg { width: 21px; height: 21px; }
  .policyhead__body { min-width: 0; }
  .policyhead__title { margin: 2px 0 6px; font-size: 17px; font-weight: 700; letter-spacing: -0.015em; }
  .policyhead__meta { margin: 0; color: var(--text-2); font-size: 13.5px; line-height: 1.5; }
  .policyhead__tenant { margin: 8px 0 0; color: var(--text-2); font-size: 13px; overflow-wrap: anywhere; }
  .policyhead__fleet { display: flex; align-items: flex-start; gap: 14px; min-width: 0; max-width: 300px; padding-left: 24px; border-left: 1px solid var(--line); align-self: stretch; }
  .policyhead__fleettext { margin: 0; font-size: 13px; color: var(--text-2); line-height: 1.45; }
  .policyhead__fleettext b { display: block; margin: 2px 0 4px; color: var(--text); font-size: 17px; letter-spacing: -0.015em; }

  .tabs--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .tab { position: relative; }
  .tab__err { width: 7px; height: 7px; border-radius: 50%; background: var(--block); flex: none; }
  .policytabs .protab__panel { padding: 24px 24px 22px; }

  .policysection { margin: 0 0 6px; font-size: 17px; font-weight: 700; letter-spacing: -0.015em; }
  .policysection .count { margin-left: 4px; color: var(--text-2); font-size: 14px; font-weight: 500; letter-spacing: 0; }
  .policysection__hint { margin: 0 0 16px; font-size: 13px; color: var(--text-2); }

  .policygrid { display: grid; gap: 12px; align-items: start; margin-bottom: 12px; min-width: 0; }
  .policygrid > .field { min-width: 0; margin: 0; }
  .policygrid--server { grid-template-columns: minmax(120px, 0.42fr) minmax(0, 1.4fr) 40px; }
  .policygrid--rule { grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr) 40px; }
  .policygrid--pin { grid-template-columns: minmax(0, 1fr) 40px; }
  .policygrid--two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .policygrid--three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .policygrid__labels { margin-bottom: 6px; font-size: 12.5px; font-weight: 600; color: var(--text-2); }
  .policygrid__label { display: block; margin-bottom: 6px; font-size: 12.5px; font-weight: 600; color: var(--text-2); }
  .policygrid__del { width: 40px; height: 42px; padding: 0; color: var(--text-2); }

  .addlink { display: inline-flex; align-items: center; gap: 10px; margin: 2px 0 0; padding: 6px 4px; border: 0; border-radius: var(--radius-sm); background: none; color: var(--signal-text); font: inherit; font-size: 14px; font-weight: 600; cursor: pointer; }
  .addlink svg { width: 22px; height: 22px; color: var(--signal); }
  .addlink:hover { text-decoration: underline; text-underline-offset: 3px; }
  .addlink:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }
  .addlink:disabled { opacity: .4; cursor: not-allowed; text-decoration: none; }

  .policyblock { display: grid; grid-template-columns: 50px minmax(0, 1fr); gap: 0 14px; padding: 20px 0; border-top: 1px solid var(--line); }
  .policyblock:first-of-type { padding-top: 0; border-top: 0; }
  .policyblock--rule { margin-top: 22px; }
  .policyblock--rule:first-of-type { padding-top: 20px; border-top: 1px solid var(--line); }
  .policyblock--lead { padding-bottom: 18px; }
  .policyblock__switch { align-self: start; margin-top: 1px; }
  .policyblock__title { display: block; font-size: 15px; color: var(--text); cursor: pointer; }
  .policyblock__title b { font-weight: 700; }
  .policyblock__hint { margin: 4px 0 0; }
  .policyblock__body > .policygrid:first-of-type, .policyblock__body > .policygrid__labels { margin-top: 14px; }
  .policyblock__sub { margin: 14px 0 12px; }

  .policytoggles { display: grid; gap: 10px; padding-top: 16px; border-top: 1px solid var(--line); }
  .policytoggle { display: flex; gap: 16px; padding: 14px 18px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--ink-850); font-size: 14px; font-weight: 500; color: var(--text); }
  .policytoggle:has(input:checked) { border-color: var(--line-2); background: var(--ink-800); }

  .policyfoot { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 12px 20px; margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--line); }
  .policyfoot .btn--primary { min-height: 44px; padding-inline: 22px; }

  .historylist { list-style: none; margin: 14px 0 0; padding: 0; border-top: 1px solid var(--line); }
  .historyrow { display: flex; align-items: center; justify-content: space-between; gap: 12px 16px; padding: 14px 0; border-bottom: 1px solid var(--line); }
  .historyrow__body { min-width: 0; }
  .historyrow__title { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 0 0 4px; font-size: 15px; font-weight: 700; }
  .historyrow__meta { margin: 0; color: var(--text-2); font-size: 13px; overflow-wrap: anywhere; }
  .btn--outline { flex: none; border-color: color-mix(in oklab, var(--signal) 55%, transparent); background: transparent; color: var(--signal-text); }
  .btn--outline:hover { border-color: var(--signal); background: var(--signal-wash); }
  .historyfoot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 20px; margin-top: 16px; }
  .historyfoot .field__hint { margin: 0; max-width: 80ch; }
  .historyfoot__withdraw { color: var(--block); }

  @media (max-width: 980px) {
    .policyhead { grid-template-columns: auto minmax(0, 1fr); }
    .policyhead__fleet { grid-column: 1 / -1; max-width: none; padding: 16px 0 0; border-left: 0; border-top: 1px solid var(--line); }
    .policygrid--three { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  }
  @media (max-width: 720px) {
    .policyhead { padding: 18px 16px; gap: 14px; }
    .policyhead__icon { width: 40px; height: 40px; }
    .policytabs .protab__panel { padding: 18px 14px 16px; }
    .policyblock { grid-template-columns: 46px minmax(0, 1fr); gap: 0 8px; }
    .policygrid--server, .policygrid--rule { grid-template-columns: minmax(0, 1fr) 40px; }
    .policygrid--server > .field:first-child, .policygrid--rule > .field:first-child { grid-column: 1 / -1; }
    .policygrid__labels { display: none; }
    .policygrid--two, .policygrid--three { grid-template-columns: minmax(0, 1fr); }
    .historyrow { flex-wrap: wrap; }
    .historyrow .btn--outline { width: 100%; min-height: 44px; }
    .policyfoot .btn { flex: 1 1 100%; min-height: 44px; }
  }
}

/* Portal: /audit after the PortalReview AuditTrails mockup: as wide as the dashboard,
   a head with the entry count, a full-width search beside the two filters, and
   the detail as an "Event details" panel beside the table (under it below
   1040 px). The row grid follows the log card's own width (a container query),
   so the same rules hold with the panel open or closed. No new colour: the
   selected row and the count wear the allow wash. */
@layer components {
  .content:has(.auditpage) { max-width: 1440px; }

  .audithead { display: flex; align-items: flex-start; gap: 18px 22px; flex-wrap: wrap; margin-bottom: 22px; }
  .audithead h1 { font-size: 30px; }
  .audithead p { margin-top: 6px; }
  .audithead__icon { display: grid; place-items: center; flex: none; width: 64px; height: 64px; border-radius: 16px; background: color-mix(in oklab, var(--allow) 14%, transparent); color: var(--allow); }
  .audithead__icon svg { width: 30px; height: 30px; }
  .audithead__text { min-width: 0; flex: 1 1 280px; }
  .audithead__count { align-self: center; margin-left: auto; padding: 10px 18px; border-radius: var(--radius-pill); background: color-mix(in oklab, var(--allow) 13%, transparent); color: var(--allow); font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }

  .auditpage { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; align-items: start; }
  .auditpage.has-detail { grid-template-columns: minmax(0, 1fr) 360px; }
  .auditlog { container-type: inline-size; min-width: 0; }

  .audittools { justify-content: flex-start; flex-wrap: wrap; gap: 12px; }
  .audittools__search { flex: 1 1 280px; width: auto; }
  .audittools__select { flex: 0 1 190px; width: auto; min-width: 150px; }

  .streamrow--audit { grid-template-columns: 150px minmax(0, 170px) 172px minmax(0, 1fr) 44px; border-radius: 0; border-bottom: 1px solid var(--line); cursor: pointer; }
  .streamrow--audit:last-child { border-bottom: 0; }
  .streamrow--audit.streamrow--head { cursor: default; background: var(--ink-800); border-radius: var(--radius-sm) var(--radius-sm) 0 0; padding-top: 12px; padding-bottom: 12px; }
  .streamrow--audit.streamrow--head .colhead { font-size: 12.5px; font-weight: 700; letter-spacing: 0; text-transform: none; color: var(--text); }
  .streamrow--audit.streamrow--head .colhead.is-sorted { color: var(--text); }
  .streamrow--audit .streamrow__time { display: block; color: var(--text-2); font-family: inherit; font-size: 13px; font-variant-numeric: tabular-nums; }
  .streamrow--audit .streamrow__what { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; line-height: 1.45; }
  .streamrow--audit.streamrow--head .streamrow__what { display: block; }
  .streamrow--audit.is-selected, .streamrow--audit.is-selected:hover { background: color-mix(in oklab, var(--allow) 11%, transparent); }
  .streamrow--audit.is-selected .streamrow__time { color: var(--text); font-weight: 700; }
  .streamrow--audit.is-selected .streamrow__what { color: var(--text); }
  .auditinfo { width: 36px; height: 36px; padding: 0; color: var(--allow); }
  .auditinfo svg { width: 21px; height: 21px; }

  .auditpill { gap: 6px; padding: 5px 11px; font-size: 12.5px; white-space: nowrap; }
  .auditpill svg { width: 14px; height: 14px; flex: none; }
  .pill.auditpill.is-block { color: var(--block); border-color: color-mix(in oklab, var(--block) 34%, transparent); background: color-mix(in oklab, var(--block) 10%, transparent); }
  .pill.auditpill:not(.allow, .is-block, .flag, .signal) { color: var(--text); background: var(--ink-850); }

  .auditpanel { position: sticky; top: 16px; padding: 22px 20px 20px; min-width: 0; }
  .auditpanel__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
  .auditpanel__head h2 { margin: 0; font-size: 18px; font-weight: 700; letter-spacing: -0.015em; }
  .auditpanel__close { width: 36px; height: 36px; padding: 0; }
  .auditpanel__close svg { width: 20px; height: 20px; }
  .auditpanel__pill { margin-bottom: 16px; }
  .auditpanel__pill .auditpill { padding: 8px 16px; font-size: 13.5px; }
  .auditpanel__pill .auditpill svg { width: 16px; height: 16px; }
  .auditpanel__sub { margin: 20px 0 4px; font-size: 13.5px; font-weight: 700; }

  .kvtable { margin: 0; border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; font-size: 13.5px; }
  .kvtable > div { display: grid; grid-template-columns: 104px minmax(0, 1fr); gap: 12px; padding: 12px 14px; border-bottom: 1px solid var(--line); }
  .kvtable > div:last-child { border-bottom: 0; }
  .kvtable dt { color: var(--text-2); }
  .kvtable dd { margin: 0; min-width: 0; overflow-wrap: anywhere; color: var(--text); }
  .kvtable__sub { display: block; margin-top: 2px; color: var(--text-3); font-size: 12px; }

  /* The log card narrows (panel open, small desk): the user column goes first —
     an audit row still answers "what changed, when" without it, and the panel
     names the user — then the details fold onto a line of their own under the
     time and the action, rather than being squeezed into a sliver. */
  @container (max-width: 860px) {
    .streamrow--audit { grid-template-columns: 140px 172px minmax(0, 1fr) 44px; }
    .streamrow--audit .streamrow__user { display: none; }
  }
  @container (max-width: 680px) {
    .streamrow--audit { grid-template-columns: max-content minmax(0, 1fr) 44px; gap: 6px 14px; }
    .streamrow--audit .streamrow__what { grid-column: 1 / -1; grid-row: 2; }
    .streamrow--audit.streamrow--head .streamrow__what { display: none; }
    .streamrow--audit .streamrow__acts { grid-column: 3; grid-row: 1; }
    .streamrow--audit .streamrow__time { font-size: 12.5px; }
    .streamrow--audit .auditpill { white-space: normal; }
    /* The search takes its own line and the two filters share the next, rather than one orphan. */
    .audittools__search { flex-basis: 100%; }
    .audittools__select { flex: 1 1 140px; }
  }

  @media (max-width: 1040px) {
    .auditpage.has-detail { grid-template-columns: minmax(0, 1fr); }
    .auditpanel { position: static; }
  }
  @media (max-width: 720px) {
    .audithead__icon { width: 48px; height: 48px; border-radius: 13px; }
    /* Phone: icon and title share the first line; the purpose line and the button run full width below. */
    .audithead { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 12px 14px; }
    .audithead__text { display: contents; }
    .audithead h1 { grid-column: 2; font-size: 26px; }
    .audithead__text > :not(h1) { grid-column: 1 / -1; }
    .audithead > :not(.audithead__icon, .audithead__text) { grid-column: 1 / -1; justify-self: start; }
    .audithead p { margin-top: 0; max-width: none; }
    .audithead__icon svg { width: 24px; height: 24px; }
    .audithead__count { margin-left: 0; padding: 7px 14px; font-size: 13.5px; }
    .kvtable > div { grid-template-columns: 92px minmax(0, 1fr); }
  }
}

/* /activity after the PortalReview RecentActivities mockup: as wide as the
   dashboard, a toolbar card (count · window, search, Filters), a table with a
   header band, a Status pill with its glyph (Blocked / Flagged — the feed
   carries no allowed answers), Source and Category as plain text, an icon
   "Add to whitelist" and a footer that pages with ‹ n ›. The row grid follows
   the card's own width (a container query), like the audit log. No new
   colour: block, flag and allow are the verdict tokens. */
@layer components {
  .content:has(.activitypage) { max-width: 1440px; }

  .activitylog { container-type: inline-size; min-width: 0; padding: 0; overflow: hidden; }
  .activitytools { margin: 0; padding: 16px 18px; border-bottom: 1px solid var(--line); }
  .activitytools__count { margin: 0; color: var(--text-2); font-size: 13.5px; }
  .activitytools__count b { color: var(--text); font-weight: 600; font-family: inherit; font-variant-numeric: tabular-nums; }
  .activitytools__right { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; flex: 1 1 auto; justify-content: flex-end; min-width: 0; }
  .activitytools__search { flex: 0 1 340px; width: auto; }
  .activitytools__filters { flex: none; }
  .activitytools__filters.is-open { border-color: color-mix(in oklab, var(--signal) 45%, transparent); background: var(--signal-wash); }
  .activityfilters { display: grid; gap: 8px; padding: 14px 18px; border-bottom: 1px solid var(--line); }
  .activitylog > .notice { margin-left: 18px !important; margin-right: 18px !important; }
  .activitylog > .empty { margin: 18px; }

  .activitystream { gap: 0; }
  .streamrow--activity { --acts: 64px; grid-template-columns: 76px minmax(0, 1.5fr) 118px minmax(0, 1fr) minmax(0, .9fr) minmax(0, .85fr) minmax(0, .85fr) minmax(0, .7fr) var(--acts); gap: 14px; padding: 12px 18px; border-radius: 0; border-bottom: 1px solid var(--line); font-size: 13.5px; }
  /* The dashboard-card mode puts "Why?" beside the whitelist button. */
  .streamrow--activity.streamrow--wide-acts { --acts: 132px; }
  .streamrow--activity:last-child { border-bottom: 0; }
  .streamrow--activity.streamrow--head { background: var(--ink-800); padding-top: 13px; padding-bottom: 13px; }
  .streamrow--activity.streamrow--head:hover { background: var(--ink-800); }
  .streamrow--activity.streamrow--head .colhead { font-size: 11.5px; font-weight: 700; letter-spacing: .04em; color: var(--text-2); white-space: nowrap; overflow: visible; }
  .streamrow--activity.streamrow--head .colhead.is-sorted { color: var(--text); }
  .streamrow--activity.streamrow--head .streamrow__acthead { justify-content: center; }
  .streamrow--activity .streamrow__time { display: block; color: var(--text-2); font-family: inherit; font-size: 13px; font-variant-numeric: tabular-nums; }
  .streamrow--activity .streamrow__domain { color: var(--text); font-weight: 500; }
  .streamrow--activity .streamrow__domain .linkout { margin-left: auto; }
  .streamrow--activity .streamrow__layer,
  .streamrow--activity .streamrow__cat { min-width: 0; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; }
  .streamrow--activity .streamrow__cat { white-space: nowrap; }
  .streamrow--activity .streamrow__layer small { display: block; margin-top: 3px; color: var(--text-3); font-size: 11.5px; }
  .streamrow--activity .streamrow__client { color: var(--text-2); font-family: inherit; font-size: 13px; font-variant-numeric: tabular-nums; }
  .streamrow--activity .streamrow__reported { color: var(--text-2); font-size: 13px; }
  .streamrow--activity .streamrow__acts { justify-content: center; }

  .statuspill { gap: 7px; padding: 5px 12px 5px 9px; border-radius: var(--radius-sm); font-size: 12.5px; white-space: nowrap; }
  .statuspill svg { width: 15px; height: 15px; flex: none; }
  .pill.statuspill.is-block { color: var(--block); border-color: color-mix(in oklab, var(--block) 34%, transparent); background: color-mix(in oklab, var(--block) 10%, transparent); }

  .allowbtn { width: 52px; height: 36px; padding: 0; gap: 0; color: var(--allow); background: var(--ink-850); border-color: var(--line-2); }
  .allowbtn:hover { border-color: color-mix(in oklab, var(--allow) 50%, transparent); background: color-mix(in oklab, var(--allow) 10%, transparent); }
  .allowbtn svg { width: 24px; height: 20px; }
  .allowbtn--done { display: inline-grid; place-items: center; border: 1px solid color-mix(in oklab, var(--allow) 34%, transparent); border-radius: var(--radius-sm); background: color-mix(in oklab, var(--allow) 10%, transparent); cursor: default; }
  .allowbtn--done:hover { background: color-mix(in oklab, var(--allow) 10%, transparent); }
  .allowbtn--done svg { width: 18px; height: 18px; }
  /* Portal #309: on the whitelist but paused or lapsed — a dashed edge, the same box. */
  .allowbtn--paused { border-style: dashed; color: var(--text-2); }

  .activitypager { margin: 0; padding: 14px 18px; }
  .activitypager .pager__count { margin: 0; color: var(--text-2); font-size: 13px; }
  .pager__arrow { width: 36px; height: 36px; padding: 0; }
  .pager__arrow svg { width: 18px; height: 18px; }
  .pager__page { display: inline-grid; place-items: center; min-width: 36px; height: 36px; padding: 0 8px; border-radius: var(--radius-sm); background: color-mix(in oklab, var(--allow) 13%, transparent); color: var(--allow); font-weight: 700; font-variant-numeric: tabular-nums; }

  /* The card narrows: the reported user goes first, then the device and the
     category — the row still says when, what, its status, who decided and
     who asked — and a phone stacks it: name and status on top, time ·
     source · client under it, the action on the right. */
  @container (max-width: 1100px) {
    .streamrow--activity { grid-template-columns: 72px minmax(0, 1.5fr) 112px minmax(0, 1fr) minmax(0, .9fr) minmax(0, .85fr) minmax(0, .85fr) var(--acts); gap: 12px; }
    .streamrow--activity .streamrow__user { display: none; }
  }
  @container (max-width: 900px) {
    .streamrow--activity { grid-template-columns: 70px minmax(0, 1.4fr) 112px minmax(0, 1fr) minmax(0, .9fr) var(--acts); }
    .streamrow--activity .streamrow__device, .streamrow--activity .streamrow__cat { display: none; }
  }
  @container (max-width: 680px) {
    .activitytools__search { flex-basis: 100%; }
    .activitytools__right { justify-content: flex-start; }
    .streamrow--activity { grid-template-columns: minmax(0, 1fr) auto auto; gap: 6px 12px; padding: 12px 14px; }
    .streamrow--activity.streamrow--head { display: none; }
    .streamrow--activity .streamrow__domain { grid-column: 1; grid-row: 1; }
    .streamrow--activity .streamrow__status { grid-column: 2; grid-row: 1; }
    .streamrow--activity .streamrow__acts { grid-column: 3; grid-row: 1 / 3; }
    .streamrow--activity .streamrow__time { grid-column: 1 / 3; grid-row: 2; font-size: 12px; }
    .streamrow--activity .streamrow__layer { grid-column: 1 / 3; grid-row: 3; font-size: 12.5px; }
    .streamrow--activity .streamrow__client { grid-column: 1 / 3; grid-row: 4; font-size: 12px; color: var(--text-3); }
  }
}

/* Korax Connect fleet (KoraxDB #790), laid out after the PortalReview
   KoraxConnectFleet mockup, as wide as the dashboard: five tinted tiles with a
   round glyph (a tile filters the list), then the "Connected devices" card —
   title and count, a search and three filters, a table with a header band.
   The row grid follows the card's own width (a container query). No new
   colour: current = allow, behind and silent = flag, rejected = block,
   unknown = neutral. */
@layer components {
  .content:has(.fleetpage) { max-width: 1440px; }

  .fleettiles { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 16px; }
  .fleettile { --tone: var(--text-2); display: flex; align-items: center; gap: 16px; min-width: 0; padding: 22px 20px; text-align: left; cursor: pointer; font: inherit; color: inherit;
    border-color: color-mix(in oklab, var(--tone) 22%, var(--line));
    background: linear-gradient(180deg, color-mix(in oklab, var(--tone) 7%, var(--ink-800)), color-mix(in oklab, var(--tone) 4%, var(--ink-850))); }
  .fleettile.is-allow { --tone: var(--allow); }
  .fleettile.is-flag { --tone: var(--flag); }
  .fleettile.is-block { --tone: var(--block); }
  .fleettile.is-neutral { --tone: var(--text-3); background: linear-gradient(180deg, var(--ink-800), var(--ink-850)); }
  .fleettile:hover { border-color: color-mix(in oklab, var(--tone) 45%, var(--line)); }
  .fleettile.is-selected { border-color: var(--tone); box-shadow: 0 0 0 1px var(--tone) inset; }
  .fleettile:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }
  .fleettile__icon { flex: none; display: grid; place-items: center; width: 48px; height: 48px; border-radius: 50%; color: var(--tone); background: color-mix(in oklab, var(--tone) 15%, transparent); }
  .fleettile.is-neutral .fleettile__icon { color: var(--text-2); background: var(--ink-780); }
  .fleettile__icon svg { width: 24px; height: 24px; }
  .fleettile__text { display: flex; flex-direction: column; min-width: 0; }
  .fleettile .stat__label { color: var(--text); font-size: 13.5px; font-weight: 500; }
  .fleettile .stat__value { margin-top: 8px; font-variant-numeric: tabular-nums; }

  .fleetlog { container-type: inline-size; min-width: 0; margin-top: 18px; padding: 0; overflow: hidden; }
  .fleettools { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px 16px; padding: 18px 18px 0; }
  .fleettools__title { margin: 0; font-size: 18px; font-weight: 700; letter-spacing: -0.01em; }
  .fleettools__count { margin: 0; color: var(--text-2); font-size: 13.5px; }
  .fleettools__count b { color: var(--text-2); font-weight: 500; font-variant-numeric: tabular-nums; }
  .fleetfilters { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; padding: 16px 18px; }
  .fleetfilters__search { flex: 2 1 260px; width: auto; max-width: none; min-width: 0; }
  .fleetfilters__select { flex: 1 1 150px; width: auto; min-width: 0; }
  .fleetfilters > .btn { flex: none; }
  .fleetlog > .empty { margin: 0 18px 18px; }

  .fleettable { margin: 0 18px 18px; border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; }
  .fleetrow { display: grid; grid-template-columns: minmax(0, 1.9fr) minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, .9fr); gap: 16px; align-items: center; padding: 13px 16px; border-bottom: 1px solid var(--line); font-size: 13.5px; }
  .fleetrow:last-child { border-bottom: 0; }
  .fleetrow--head { background: var(--ink-800); padding-top: 13px; padding-bottom: 13px; }
  .fleetrow--head .colhead { font-size: 11.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .fleetrow.is-silent { background: color-mix(in oklab, var(--flag) 11%, transparent); }
  .fleetrow.is-rejected { background: color-mix(in oklab, var(--block) 6%, transparent); }
  .fleetrow__device { display: flex; align-items: center; gap: 14px; min-width: 0; }
  .fleetrow__icon { flex: none; display: grid; place-items: center; width: 40px; height: 40px; border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--ink-850); color: var(--text-2); }
  .fleetrow__icon svg { width: 22px; height: 22px; }
  .fleetrow__name { display: flex; flex-direction: column; min-width: 0; }
  .fleetrow__name b { font-weight: 600; color: var(--text); overflow-wrap: anywhere; }
  .fleetrow__name small { margin-top: 3px; color: var(--text-3); font-size: 12px; }
  .fleetrow__status { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; min-width: 0; }
  .fleetrow__status small { color: var(--text-3); font-size: 12px; line-height: 1.4; }
  .fleetrow__policy, .fleetrow__agent, .fleetrow__seen { color: var(--text-2); font-variant-numeric: tabular-nums; }
  .fleetrow__token { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; min-width: 0; color: var(--text-2); overflow-wrap: anywhere; }
  .fleetrow__muted { color: var(--text-3); }

  .pill.fleetpill { display: inline-flex; width: fit-content; }
  .pill.statuspill.is-allow { color: var(--allow); border-color: color-mix(in oklab, var(--allow) 34%, transparent); background: color-mix(in oklab, var(--allow) 10%, transparent); }
  .pill.statuspill.is-flag { color: var(--flag); border-color: color-mix(in oklab, var(--flag) 34%, transparent); background: color-mix(in oklab, var(--flag) 10%, transparent); }
  .pill.statuspill.is-neutral { color: var(--text-2); border-color: var(--line-2); background: var(--ink-780); }
  .fleetrow__token .statuspill { padding: 2px 8px; font-size: 11.5px; }

  .fleetpager { padding: 0 18px 16px; }

  @media (max-width: 1180px) {
    .fleettiles { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  }
  @media (max-width: 640px) {
    .fleettiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
    .fleettile { gap: 12px; padding: 14px; }
    .fleettile__icon { width: 38px; height: 38px; }
    .fleettile__icon svg { width: 20px; height: 20px; }
  }

  /* The card narrows: the agent version goes first (it is also under the
     name), then the token; a phone stacks the row — name and status on top,
     the policy version and last seen under it. */
  @container (max-width: 880px) {
    .fleetrow { grid-template-columns: minmax(0, 1.9fr) minmax(0, 1.6fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, .9fr); }
    .fleetrow .fleetrow__agent { display: none; }
  }
  @container (max-width: 740px) {
    .fleetfilters__search { flex-basis: 100%; }
    .fleetrow { grid-template-columns: minmax(0, 1.7fr) minmax(0, 1.6fr) minmax(0, 1fr) minmax(0, .9fr); }
    .fleetrow .fleetrow__token { display: none; }
  }
  @container (max-width: 600px) {
    .fleetfilters__select { flex-basis: 100%; }
    .fleettable { margin: 0 12px 12px; }
    .fleetrow { grid-template-columns: minmax(0, 1fr) auto; gap: 8px 12px; padding: 12px; }
    .fleetrow--head { display: none; }
    .fleetrow__device { grid-column: 1 / -1; grid-row: 1; }
    .fleetrow__status { grid-column: 1 / -1; grid-row: 2; }
    /* The token comes back on its own line: a revoked one is what the badge is for. */
    .fleetrow .fleetrow__token { display: flex; grid-column: 1 / -1; grid-row: 3; font-size: 12.5px; }
    .fleetrow__policy { grid-column: 1; grid-row: 4; font-size: 12.5px; }
    .fleetrow__seen { grid-column: 2; grid-row: 4; font-size: 12.5px; text-align: right; }
  }
}

/* Ported from Portal: /reports after the PortalReview Report01 mockup, as wide as the dashboard:
   the page head carries the Generate report button; the Create report card
   folds (icon tile, title, chevron) and opens on a three-column form — name and
   format, the two report-type cards, the range chips and the two dates; then
   the Reports card with its search and a table with a header band. The row
   grid follows the card's own width (a container query). No new colour: the
   type pills are signal (custom), neutral (monthly) and flag (trial); the
   status pills reuse .statuspill. */
@layer components {
  .content:has(.reportspage) { max-width: 1440px; }

  .page-head--action { display: flex; align-items: flex-start; justify-content: space-between; flex-wrap: wrap; gap: 14px 24px; }
  .page-head--action > .btn { flex: none; padding: 12px 20px; font-size: 14.5px; }
  .page-head--action > .btn svg, .reportform .btn svg, .reportdl svg { width: 18px; height: 18px; }

  .reportform { padding: 0; margin-bottom: 18px; overflow: hidden; }
  .reportform__head { display: flex; align-items: center; gap: 16px; padding: 18px 20px; }
  .reportform.is-open .reportform__head { border-bottom: 1px solid var(--line); }
  .reportform__icon, .reporttools__icon { flex: none; display: grid; place-items: center; border-radius: var(--radius-sm); color: var(--signal); background: var(--signal-wash); }
  .reportform__icon { width: 44px; height: 44px; }
  .reportform__icon svg { width: 24px; height: 24px; }
  .reportform__title { flex: 1 1 auto; min-width: 0; }
  .reportform__title h2 { margin: 0; font-size: 17px; font-weight: 700; letter-spacing: -0.01em; }
  .reportform__title p { margin: 3px 0 0; color: var(--text-2); font-size: 13.5px; }
  .reportform__toggle { flex: none; display: grid; place-items: center; width: 36px; height: 36px; border-radius: var(--radius-sm); border: 1px solid transparent; background: transparent; color: var(--text-2); cursor: pointer; }
  .reportform__toggle:hover { border-color: var(--line-2); color: var(--text); }
  .reportform__toggle:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }
  .reportform__toggle svg { width: 20px; height: 20px; transition: rotate .18s var(--ease); }
  .reportform:not(.is-open) .reportform__toggle svg { rotate: 180deg; }

  .reportform__body { container-type: inline-size; padding: 20px; }
  .reportform__grid { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr) minmax(0, 1.2fr); gap: 20px 32px; align-items: start; }
  .reportform__col { display: grid; gap: 14px; min-width: 0; margin: 0; padding: 0; border: 0; }
  .reportform__col > legend { float: left; width: 100%; padding: 0; margin-bottom: 9px; }
  .reportform__col > legend + * { clear: left; }
  .reportform__col .field__title, .reportform__col legend { font-weight: 600; font-size: 13.5px; color: var(--text); }
  .reportform .input.is-invalid { border-color: var(--block); }
  .reportform__acts { display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 12px; margin-top: 20px; }
  .reportform__acts .btn { min-width: 104px; padding: 11px 20px; white-space: nowrap; }

  .choicepair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .choicecard { display: flex; align-items: center; gap: 10px; min-height: 46px; padding: 10px 14px; border-radius: var(--radius-sm); border: 1px solid var(--line-2); background: var(--ink-850); cursor: pointer; font-size: 13.5px; font-weight: 500; transition: border-color .16s var(--ease), background .16s var(--ease); }
  .choicecard:hover { border-color: color-mix(in oklab, var(--signal) 40%, var(--line-2)); }
  .choicecard:focus-within { box-shadow: 0 0 0 3px var(--signal-wash); }
  .choicecard.is-on { border-color: color-mix(in oklab, var(--signal) 55%, transparent); background: var(--signal-wash); }
  .choicecard__icon { flex: none; width: 20px; height: 20px; color: var(--text-2); }
  .choicecard.is-on .choicecard__icon { color: var(--signal); }
  .choicecard__label { flex: 1 1 auto; min-width: 0; }
  .choicecard__radio, .rangechip__radio { flex: none; width: 16px; height: 16px; border-radius: 50%; border: 1.5px solid var(--text-3); }
  .choicecard.is-on .choicecard__radio { border: 5px solid var(--signal); }

  .rangechips { display: flex; flex-wrap: wrap; gap: 8px; }
  .rangechip { display: inline-flex; align-items: center; gap: 8px; min-height: 42px; padding: 8px 14px; border-radius: var(--radius-sm); border: 1px solid var(--line-2); background: var(--ink-850); color: var(--text-2); font: inherit; font-size: 13.5px; cursor: pointer; transition: border-color .16s var(--ease), background .16s var(--ease); }
  .rangechip:hover { border-color: color-mix(in oklab, var(--signal) 40%, var(--line-2)); color: var(--text); }
  .rangechip:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }
  .rangechip.is-on { border-color: color-mix(in oklab, var(--signal) 55%, transparent); background: var(--signal-wash); color: var(--text); font-weight: 600; }
  .rangechip.is-on .rangechip__radio { border: 5px solid var(--signal); }
  .rangechip__icon { width: 18px; height: 18px; }
  .rangechip__check { display: none; place-items: center; width: 18px; height: 18px; margin-left: 4px; border-radius: 50%; background: var(--signal); color: var(--signal-ink); }
  .rangechip__check svg { width: 11px; height: 11px; }
  .rangechip.is-on .rangechip__check { display: grid; }
  .rangedates { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 10px; }
  .rangedates__arrow { width: 18px; height: 18px; color: var(--text-3); }
  .rangedates .input { min-width: 0; }

  .reportlog { container-type: inline-size; min-width: 0; padding: 0; overflow: visible; }
  .reporttools { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px 16px; padding: 18px 20px; }
  .reporttools__title { display: flex; align-items: center; gap: 12px; margin: 0; font-size: 18px; font-weight: 700; letter-spacing: -0.01em; }
  .reporttools__icon { width: 36px; height: 36px; }
  .reporttools__icon svg { width: 20px; height: 20px; }
  .reporttools__search { width: 300px; }
  .reportlog > .empty { margin: 0 20px 20px; }

  .reporttable { margin: 0 20px 20px; border: 1px solid var(--line); border-radius: var(--radius-sm); }
  .reportrow { display: grid; grid-template-columns: minmax(0, 1.7fr) minmax(0, .95fr) minmax(0, 1.6fr) minmax(0, .95fr) minmax(0, .9fr) minmax(0, 1.15fr) 40px; gap: 16px; align-items: center; padding: 14px 16px; border-bottom: 1px solid var(--line); font-size: 13.5px; }
  .reportrow:last-child { border-bottom: 0; }
  .reportrow--head { background: var(--ink-800); border-radius: var(--radius-sm) var(--radius-sm) 0 0; padding-top: 13px; padding-bottom: 13px; }
  .reportrow--head .colhead { font-size: 13px; font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .reportrow__name { display: flex; flex-direction: column; min-width: 0; }
  .reportrow__name b { font-weight: 600; color: var(--text); overflow-wrap: anywhere; }
  .reportrow__name small { margin-top: 3px; color: var(--text-3); font-size: 12px; }
  .reportrow__period, .reportrow__created { color: var(--text-2); font-variant-numeric: tabular-nums; }
  .reportrow__muted { color: var(--text-3); }
  .reportrow__more { justify-self: end; }

  .typepill { display: inline-flex; align-items: center; gap: 7px; width: fit-content; padding: 5px 12px; border-radius: 999px; border: 1px solid var(--line-2); background: var(--ink-780); color: var(--text-2); font-size: 12.5px; font-weight: 500; white-space: nowrap; }
  .typepill svg { width: 15px; height: 15px; }
  .typepill.is-custom { color: var(--signal-text); border-color: color-mix(in oklab, var(--signal) 34%, transparent); background: var(--signal-wash); }
  .typepill.is-trial { color: var(--flag); border-color: color-mix(in oklab, var(--flag) 34%, transparent); background: color-mix(in oklab, var(--flag) 10%, transparent); }
  .pill.statuspill.is-block { color: var(--block); border-color: color-mix(in oklab, var(--block) 34%, transparent); background: color-mix(in oklab, var(--block) 10%, transparent); }
  .reportrow__status .statuspill { width: fit-content; }

  .reportdl { padding: 8px 14px; font-size: 13px; white-space: nowrap; }

  .rowmenu { position: relative; }
  .rowmenu > summary { display: grid; place-items: center; width: 34px; height: 34px; border-radius: var(--radius-sm); color: var(--text-2); cursor: pointer; list-style: none; }
  .rowmenu > summary::-webkit-details-marker { display: none; }
  .rowmenu > summary:hover, .rowmenu[open] > summary { background: var(--ink-780); color: var(--text); }
  .rowmenu > summary:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }
  .rowmenu > summary svg { width: 18px; height: 18px; }
  .rowmenu__list { position: absolute; right: 0; top: calc(100% + 6px); z-index: 20; min-width: 230px; padding: 6px; border-radius: var(--radius-sm); border: 1px solid var(--line-2); background: var(--ink-850); box-shadow: var(--shadow-sm), 0 18px 40px -18px rgb(0 0 0 / .45); }
  .rowmenu__item { display: block; width: 100%; padding: 9px 12px; border: 0; border-radius: 8px; background: transparent; color: var(--text); font: inherit; font-size: 13.5px; text-align: left; cursor: pointer; }
  .rowmenu__item:hover, .rowmenu__item:focus-visible { background: var(--ink-780); outline: 0; }
  .rowmenu__item.is-danger { color: var(--block); }

  /* The form narrows: the range column goes under the other two, then one column. */
  @container (max-width: 980px) {
    .reportform__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .reportform__grid > :last-child { grid-column: 1 / -1; }
  }
  @container (max-width: 620px) {
    .reportform__grid { grid-template-columns: minmax(0, 1fr); }
    .choicepair { grid-template-columns: minmax(0, 1fr); }
    .reportform__acts .btn { flex: 1 1 0; }
  }

  /* The card narrows: Created goes first, then Type (it is in the name's
     line on a phone); a phone stacks the row — name and status on top, the
     period under it, the download and the menu at the bottom. */
  @container (max-width: 1100px) {
    .reportrow { grid-template-columns: minmax(0, 1.7fr) minmax(0, .95fr) minmax(0, 1.6fr) minmax(0, .9fr) minmax(0, 1.2fr) 40px; }
    .reportrow .reportrow__created { display: none; }
  }
  @container (max-width: 860px) {
    .reportrow { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1.5fr) minmax(0, .9fr) minmax(0, 1.25fr) 40px; }
    .reportrow .reportrow__type { display: none; }
  }
  @container (max-width: 640px) {
    .reporttools { padding: 14px; }
    .reporttools__search { width: 100%; }
    .reporttable { margin: 0 12px 12px; }
    .reportrow { grid-template-columns: minmax(0, 1fr) auto; gap: 8px 12px; padding: 12px; }
    .reportrow--head { display: none; }
    .reportrow__name { grid-column: 1; grid-row: 1; }
    .reportrow__status { grid-column: 2; grid-row: 1; justify-self: end; }
    .reportrow__period { grid-column: 1 / -1; grid-row: 2; font-size: 12.5px; }
    .reportrow__action { grid-column: 1; grid-row: 3; }
    .reportrow__more { grid-column: 2; grid-row: 3; }
  }
  @media (max-width: 640px) {
    .page-head--action > .btn { width: 100%; }
    .reportform__head { padding: 14px; gap: 12px; }
    .reportform__body { padding: 14px; }
  }
}

/* /api-tokens after the PortalReview APIToken mockup, as wide as the
   dashboard: the Audit-trails head (icon tile, title, one line) with the Add
   API token button; a summary bar — active tokens against the limit, and an
   Active / All switch; the table card with a header band; a note. The row
   grid follows the table card's own width (a container query). No new
   colour: active = allow, expired and refused = flag, revoked = neutral. */
@layer components {
  .content:has(.tokenpage) { max-width: 1440px; }

  .tokenhead__add, .audithead__action { flex: none; align-self: center; margin-left: auto; padding: 12px 20px; font-size: 14.5px; }
  .tokenhead__add svg, .audithead__action svg { width: 18px; height: 18px; }

  .tokenbar { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px 18px; padding: 14px 16px; margin-bottom: 18px; }
  .tokenbar__count { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px; min-width: 0; }
  .tokencount { display: inline-flex; align-items: center; gap: 9px; padding: 9px 16px; border-radius: var(--radius-sm); background: color-mix(in oklab, var(--allow) 13%, transparent); color: var(--text); font-size: 14.5px; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
  .tokencount__dot { width: 9px; height: 9px; border-radius: 50%; background: var(--allow); }
  .tokenbar__limit { color: var(--text-2); font-size: 14px; }
  .tokenfilter { border-radius: var(--radius-pill); }
  .tokenfilter button { min-width: 112px; justify-content: center; border-radius: var(--radius-pill); font-size: 14px; color: var(--text); font-variant-numeric: tabular-nums; }
  .tokenfilter button.active { background: color-mix(in oklab, var(--allow) 15%, var(--ink-800)); color: var(--text); }

  .tokenlog { container-type: inline-size; min-width: 0; padding: 16px; }
  .tokenlog > .empty { margin: 0; }
  .tokenlog .linkbtn { display: inline; padding: 0 2px; color: var(--signal-text); font-size: inherit; text-decoration: underline; }

  .tokentable { min-width: 0; }
  .tokenrow { display: grid; grid-template-columns: minmax(0, 2.4fr) minmax(0, 1.6fr) minmax(0, 1fr) minmax(0, 1.05fr) minmax(0, .85fr) minmax(0, .95fr) 64px; gap: 16px; align-items: center; padding: 13px 16px; border-bottom: 1px solid var(--line); font-size: 14px; }
  .tokenrow:last-child { border-bottom: 0; }
  .tokenrow--head { border: 0; border-radius: var(--radius-sm); background: var(--ink-780); padding-top: 12px; padding-bottom: 12px; }
  .tokenrow--head .colhead { font-size: 13.5px; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-transform: none; letter-spacing: 0; }
  .tokenrow.is-revoked .tokenrow__name b { color: var(--text-2); }
  .tokenrow__token { display: flex; align-items: center; gap: 14px; min-width: 0; }
  .tokenrow__icon { flex: none; display: inline-flex; color: var(--text); }
  .tokenrow__icon svg { width: 20px; height: 20px; }
  .tokenrow__name { display: flex; flex-direction: column; min-width: 0; }
  .tokenrow__name b { font-weight: 700; color: var(--text); overflow-wrap: anywhere; }
  .tokenrow__name small { margin-top: 3px; color: var(--text-3); font-size: 12px; }
  .tokenrow__name small > span { white-space: nowrap; }
  .tokenrow__added, .tokenrow__used, .tokenrow__expires { color: var(--text); font-variant-numeric: tabular-nums; }
  .tokenrow__status .statuspill { width: fit-content; }
  .tokenrow__acts { display: flex; justify-content: center; }
  .tokenrow--head .tokenrow__acts { justify-content: center; }

  .purposepill { display: inline-flex; align-items: center; gap: 8px; width: fit-content; max-width: 100%; padding: 6px 12px; border-radius: var(--radius-sm); border: 1px solid var(--line-2); background: var(--ink-850); color: var(--text); font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .purposepill svg { flex: none; width: 16px; height: 16px; }

  .tokennote { display: flex; align-items: flex-start; gap: 14px; margin-top: 18px; padding: 16px 20px; border-radius: var(--radius); border: 1px solid color-mix(in oklab, var(--signal) 16%, var(--line)); background: color-mix(in oklab, var(--signal) 6%, var(--ink-850)); color: var(--text-2); font-size: 14px; }
  .tokennote > svg { flex: none; width: 20px; height: 20px; margin-top: 1px; color: var(--text-2); }
  .tokennote p { margin: 0; }
  .tokennote .tokennote__more { margin-top: 6px; color: var(--text-3); font-size: 13px; overflow-wrap: anywhere; }

  /* The card narrows: the row tightens, then Expires goes, then Last used;
     a phone stacks the row — the token and its status on
     top, the purpose and the dates under it, the menu on the right. */
  @container (max-width: 1080px) {
    .tokenrow { grid-template-columns: minmax(0, 2fr) minmax(0, 1.75fr) minmax(0, 1fr) minmax(0, 1.1fr) minmax(0, .85fr) minmax(0, 1fr) 56px; gap: 12px; padding-left: 12px; padding-right: 12px; font-size: 13.5px; }
  }
  @container (max-width: 860px) {
    .tokenrow { grid-template-columns: minmax(0, 2fr) minmax(0, 1.6fr) minmax(0, 1fr) minmax(0, 1.1fr) minmax(0, 1fr) 48px; }
    .tokenrow .tokenrow__expires { display: none; }
  }
  @container (max-width: 720px) {
    .tokenrow { grid-template-columns: minmax(0, 2fr) minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1fr) 44px; }
    .tokenrow .tokenrow__used { display: none; }
  }
  @container (max-width: 620px) {
    .tokenrow { grid-template-columns: minmax(0, 1fr) auto auto; gap: 8px 12px; padding: 12px 4px; }
    .tokenrow--head { display: none; }
    .tokenrow__token { grid-column: 1; grid-row: 1; }
    .tokenrow__status { grid-column: 2; grid-row: 1; }
    .tokenrow__acts { grid-column: 3; grid-row: 1; }
    .tokenrow__purpose { grid-column: 1 / -1; grid-row: 2; }
    .tokenrow .tokenrow__added { grid-column: 1 / -1; grid-row: 3; font-size: 12.5px; color: var(--text-2); }
    .tokenrow .tokenrow__added::before { content: "Created "; }
  }
  @media (max-width: 640px) {
    .tokenhead__add, .audithead__action { width: 100%; }
    .tokenbar { padding: 12px; }
    .tokenfilter { width: 100%; }
    .tokenfilter button { flex: 1 1 0; min-width: 0; }
    .tokenlog { padding: 10px; }
    .tokennote { padding: 14px; }
  }
}

/* Ported from the Portal (Users like API tokens). /users laid out like API tokens, as wide as the dashboard: the same head,
   summary bar (logins, contacts, owners), table card and note; the row is the
   person (initials, name over address), the role, last sign-in, second factor,
   the status and a row menu. Inside the setup wizard (.userpage--embedded) the
   width is the wizard's. The row grid follows the table card's own width (a
   container query). No new colour: can sign in = allow, invited and not yet in
   = flag, contact only = neutral. */
@layer components {
  .content:has(.userpage) { max-width: 1440px; }

  .usertable { min-width: 0; }
  .userrow { display: grid; grid-template-columns: minmax(0, 2.6fr) minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) 72px; gap: 16px; align-items: center; padding: 13px 16px; border-bottom: 1px solid var(--line); font-size: 14px; }
  .userrow:last-child { border-bottom: 0; }
  .userrow--head { border: 0; border-radius: var(--radius-sm); background: var(--ink-780); padding-top: 12px; padding-bottom: 12px; }
  .userrow--head .colhead { font-size: 13.5px; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-transform: none; letter-spacing: 0; }
  .userrow__user { display: flex; align-items: center; gap: 14px; min-width: 0; }
  .userrow__avatar { flex: none; width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; font-weight: 700; font-size: 12.5px; color: var(--signal-text); background: var(--ink-780); border: 1px solid var(--line-2); }
  .userrow[data-user-state="contact"] .userrow__avatar { color: var(--text-3); }
  .userrow__name { display: flex; flex-direction: column; min-width: 0; }
  .userrow__name b { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; min-width: 0; font-weight: 700; color: var(--text); overflow-wrap: anywhere; }
  .userrow__name small { margin-top: 3px; color: var(--text-3); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .userrow__you { flex: none; padding: 2px 8px; border-radius: var(--radius-pill); border: 1px solid color-mix(in oklab, var(--signal) 34%, transparent); background: var(--signal-wash); color: var(--signal-text); font-size: 11.5px; font-weight: 600; }
  .userrow__select { width: auto; max-width: 100%; padding-top: 7px; padding-bottom: 7px; font-size: 13.5px; }
  .userrow__none, .userrow__last { color: var(--text-3); }
  .userrow__last { font-size: 12px; white-space: nowrap; }
  .userrow__login, .userrow__mfa { color: var(--text); font-variant-numeric: tabular-nums; }
  .userrow__factor { display: inline-flex; align-items: center; gap: 7px; color: var(--text-2); white-space: nowrap; }
  .userrow__factor.is-on { color: var(--text); }
  .userrow__factor svg { flex: none; width: 16px; height: 16px; color: var(--allow); }
  .userrow__status .statuspill { width: fit-content; white-space: nowrap; }
  .userrow__acts { display: flex; justify-content: center; }
  .userpage--embedded .tokenbar { margin-top: 4px; }

  /* The card narrows: the row tightens, then Second factor goes, then Last
     sign-in; a phone stacks the row — the person, status and menu on top, the
     role and the last sign-in under it. */
  @container (max-width: 1080px) {
    .userrow { grid-template-columns: minmax(0, 2.2fr) minmax(0, 1.25fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) 64px; gap: 12px; padding-left: 12px; padding-right: 12px; font-size: 13.5px; }
  }
  @container (max-width: 860px) {
    .userrow { grid-template-columns: minmax(0, 2.2fr) minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1fr) 64px; }
    .userrow .userrow__mfa { display: none; }
  }
  @container (max-width: 700px) {
    .userrow { grid-template-columns: minmax(0, 2fr) minmax(0, 1.3fr) minmax(0, 1fr) 60px; }
    .userrow .userrow__login { display: none; }
  }
  @container (max-width: 560px) {
    .userrow { grid-template-columns: minmax(0, 1fr) auto auto; gap: 8px 12px; padding: 12px 4px; }
    .userrow--head { display: none; }
    .userrow__user { grid-column: 1; grid-row: 1; }
    .userrow__status { grid-column: 2; grid-row: 1; }
    .userrow__acts { grid-column: 3; grid-row: 1; }
    .userrow__role { grid-column: 1 / -1; grid-row: 2; padding-left: 48px; display: flex; align-items: center; flex-wrap: wrap; gap: 6px 12px; }
    .userrow .userrow__login { display: block; grid-column: 1 / -1; grid-row: 3; padding-left: 48px; font-size: 12.5px; color: var(--text-2); }
    .userrow .userrow__login::before { content: "Last sign-in "; }
    /* No account yet (contact only, invited): no role, no sign-in to show. */
    .userrow[data-user-state="contact"] .userrow__role, .userrow[data-user-state="invited"] .userrow__role,
    .userrow[data-user-state="contact"] .userrow__login, .userrow[data-user-state="invited"] .userrow__login { display: none; }
  }
  @media (max-width: 640px) {
    .userpage--embedded .tokenbar > .btn { width: 100%; }
  }
}

/* Ported from the Portal (AI Discovery simplified). AI Discovery after the
   PortalReview AI Discovery spec and mockups 02–07, as
   wide as the dashboard: one menu entry, four tabs laid out like Protection &
   policies and Connect policy (the .tabs strip on top of one card, the page in
   its panel; links, so the current one is aria-current), four tiles with an icon
   tile, the template cards (Active = allow, Preview = signal), a read-only
   status → behaviour table, the application head with its back arrow, folded
   sections for the devices and the history. No new colour: the verdict
   tokens for statuses, the signal for selection only. */
@layer components {
  .content:has(.aitabs) { max-width: 1440px; }

  /* The tabs are links (each tab is its own URL): the current one wears the selected tab's look. */
  .tabs--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  a.tab { text-decoration: none; }
  .tab[aria-current="page"] { color: var(--text); font-weight: 700; border-bottom-color: var(--signal); background: var(--signal-wash); cursor: default; }
  .tab[aria-current="page"] svg { color: var(--signal); }
  .aitabs__panel { padding: 22px 22px 22px; }

  .aiwindow { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px 16px; margin-bottom: 16px; }
  .aiwindow__range { font-weight: 600; font-variant-numeric: tabular-nums; }

  .aikpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
  .aikpis--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .aikpi { display: flex; align-items: center; gap: 16px; padding: 20px; min-width: 0; }
  .aikpi__icon { flex: none; display: grid; place-items: center; width: 46px; height: 46px; border-radius: var(--radius-sm); color: var(--text-2); background: var(--ink-780); }
  .aikpi__icon svg { width: 24px; height: 24px; }
  .aikpi__icon.is-signal { color: var(--signal); background: var(--signal-wash); }
  .aikpi__icon.is-allow { color: var(--allow); background: color-mix(in oklab, var(--allow) 12%, transparent); }
  .aikpi__icon.is-flag { color: var(--flag); background: color-mix(in oklab, var(--flag) 12%, transparent); }
  .aikpi__icon.is-block { color: var(--block); background: color-mix(in oklab, var(--block) 12%, transparent); }
  .aikpi__text { min-width: 0; }
  .aikpi__label { color: var(--text-2); font-size: 13.5px; font-weight: 600; }
  .aikpi__value { margin-top: 2px; font-size: 28px; font-weight: 700; line-height: 1.15; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }
  .aikpi__hint { margin-top: 2px; color: var(--text-3); font-size: 12px; }

  .aipanel__title { margin: 0 0 14px; }
  .ailink, .ailist a.ailink { color: var(--text); font-weight: 600; text-decoration: none; }
  .ailink:hover, .ailist a.ailink:hover { text-decoration: underline; }
  .ailist--rows li > :first-child { flex: 1 1 140px; }
  .aichevlink { display: inline-grid; place-items: center; width: 26px; height: 26px; border-radius: 8px; color: var(--text-3); }
  .aichevlink:hover { color: var(--text); background: var(--ink-780); }
  .aichev { width: 16px; height: 16px; }
  .aichevbtn { display: inline-grid; place-items: center; width: 32px; height: 32px; border-radius: var(--radius-sm); border: 1px solid var(--line-2); color: var(--text-2); }
  .aichevbtn:hover { color: var(--text); background: var(--ink-780); }
  .aichevbtn svg { width: 16px; height: 16px; }
  .aitable__more { width: 48px; text-align: right; }
  .aiapps .aitable__name a { font-weight: 700; }

  .aiset { padding: 20px; min-width: 0; }
  .aiset + .aiset { margin-top: 16px; }
  .aiset__head { display: flex; align-items: flex-start; flex-wrap: wrap; gap: 12px 14px; margin-bottom: 16px; }
  .aiset__icon { flex: none; display: grid; place-items: center; width: 40px; height: 40px; border-radius: var(--radius-sm); color: var(--signal); background: var(--signal-wash); }
  .aiset__icon svg { width: 22px; height: 22px; }
  .aiset__title { flex: 1 1 260px; min-width: 0; }
  .aiset__title h2 { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin: 0; font-size: 17px; font-weight: 700; letter-spacing: -0.01em; }
  .aiset__title p { margin: 3px 0 0; color: var(--text-2); font-size: 13.5px; }
  .aiset__title b { display: block; font-size: 16px; }
  .aiset__title small { display: block; margin-top: 2px; color: var(--text-2); font-size: 13px; }
  .aiset__badges { display: flex; flex-wrap: wrap; gap: 8px; align-self: center; }
  .aiset__note { display: flex; align-items: flex-start; gap: 10px; margin: 14px 0 0; padding: 11px 14px; border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--ink-800); color: var(--text-2); font-size: 13px; }
  .aiset__note svg { flex: none; width: 18px; height: 18px; margin-top: 1px; color: var(--text-3); }
  .aiset__line { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px 16px; padding: 12px 0; border-bottom: 1px solid var(--line); }
  .aiset__line:first-child { padding-top: 0; }
  .aiset__line:last-child { padding-bottom: 0; border-bottom: 0; }

  .aitpl { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
  .aitpl__opt { display: flex; align-items: flex-start; gap: 12px; padding: 16px; text-align: left; color: var(--text); font: inherit; border-color: var(--line-2); transition: border-color .16s var(--ease), background .16s var(--ease); }
  .aitpl__opt:hover { border-color: color-mix(in oklab, var(--signal) 40%, var(--line-2)); background: var(--ink-800); }
  .aitpl__opt[aria-pressed="true"], .aitpl__opt.is-chosen { border-color: color-mix(in oklab, var(--signal) 55%, transparent); background: var(--signal-wash); }
  .aitpl__opt:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }
  .aitpl__radio { flex: none; width: 18px; height: 18px; margin-top: 2px; border-radius: 50%; border: 1.5px solid var(--text-3); }
  .aitpl__opt.is-chosen .aitpl__radio { border: 5px solid var(--signal); }
  .aitpl__body { display: grid; gap: 4px; min-width: 0; }
  .aitpl__name { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 6px; }
  .aitpl__name b { font-size: 15px; }
  .aitpl__text { color: var(--text-2); font-size: 13px; line-height: 1.45; }
  .aitpl__badge { padding: 2px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 700; }
  .aitpl__badge.is-active { color: var(--allow); background: color-mix(in oklab, var(--allow) 14%, transparent); }
  .aitpl__badge.is-preview { color: var(--flag); background: color-mix(in oklab, var(--flag) 14%, transparent); }

  .aiprev { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px; margin-top: 14px; padding: 10px 12px 10px 14px; border-radius: var(--radius-sm); border: 1px solid var(--line-2); background: var(--ink-800); }
  .aiprev__text { display: flex; align-items: center; gap: 10px; margin: 0; flex: 1 1 320px; min-width: 0; font-size: 13.5px; }
  .aiprev__text svg { flex: none; width: 18px; height: 18px; color: var(--signal); }
  .aiprev__acts { display: flex; flex-wrap: wrap; gap: 8px; }
  .aiaffected { margin-top: 12px; }
  .aiaffected > summary { cursor: pointer; color: var(--text-2); font-size: 13.5px; font-weight: 600; }
  .aiaffected__body { display: grid; gap: 10px; margin-top: 10px; }
  .aiaffected__group { display: grid; gap: 6px; }
  .aiaffected__apps { display: flex; flex-wrap: wrap; gap: 6px; }
  .aiaffected__apps > span:not(.count) { padding: 3px 10px; border-radius: 999px; border: 1px solid var(--line-2); font-size: 12.5px; }

  .aibehave { border: 1px solid var(--line); border-radius: var(--radius-sm); }
  .aibehave__row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); gap: 16px; align-items: center; padding: 10px 16px; border-bottom: 1px solid var(--line); font-size: 14px; }
  .aibehave__row:last-child { border-bottom: 0; }
  .aibehave__row--head { background: var(--ink-780); border-radius: var(--radius-sm) var(--radius-sm) 0 0; color: var(--text); font-size: 13.5px; font-weight: 700; }
  .aibehave__action { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; min-width: 0; }
  .aibehave__action svg { flex: none; width: 18px; height: 18px; color: var(--text-2); }
  .aibehave__action.is-allow svg { color: var(--allow); }
  .aibehave__action.is-log svg { color: var(--text-2); }
  .aibehave__action.is-alert svg { color: var(--flag); }
  .aibehave__action.is-block svg { color: var(--block); }

  .aiapphead { display: flex; align-items: center; flex-wrap: wrap; gap: 14px 18px; margin-bottom: 18px; }
  .aiapphead__back { flex: none; display: grid; place-items: center; width: 42px; height: 42px; border-radius: var(--radius-sm); border: 1px solid var(--line-2); background: var(--ink-850); color: var(--text); }
  .aiapphead__back:hover { background: var(--ink-780); }
  .aiapphead__back svg { width: 20px; height: 20px; }
  .aiapphead__text { flex: 1 1 260px; min-width: 0; }
  .aiapphead__text h1 { margin: 0; font-size: 30px; letter-spacing: -0.02em; overflow-wrap: anywhere; }
  .aiapphead__text p { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin: 4px 0 0; color: var(--text-2); }
  .aiapphead__status .pill { padding: 6px 14px; font-size: 14px; }

  .aigovcard { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 20px 28px; }
  .aigovcard__form { padding-left: 28px; border-left: 1px solid var(--line); min-width: 0; }
  .aigovcard__acts { display: flex; justify-content: flex-end; }
  .aifact { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px 16px; padding: 12px 14px; margin-top: 8px; border-radius: var(--radius-sm); background: var(--ink-800); font-size: 14px; }

  .aidomains { border: 1px solid var(--line); border-radius: var(--radius-sm); }
  .aidomains__row { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 0.6fr); gap: 16px; padding: 10px 16px; border-bottom: 1px solid var(--line); font-size: 14px; overflow-wrap: anywhere; }
  .aidomains__row:last-child { border-bottom: 0; }
  .aidomains__row--head { background: var(--ink-780); border-radius: var(--radius-sm) var(--radius-sm) 0 0; font-size: 13.5px; font-weight: 700; }

  .aifold { padding: 0; }
  .aifold__head { display: flex; align-items: center; gap: 14px; padding: 18px 20px; cursor: pointer; list-style: none; }
  .aifold__head::-webkit-details-marker { display: none; }
  .aifold__head:focus-visible { outline: 2px solid var(--signal); outline-offset: -2px; border-radius: var(--radius); }
  .aifold__chev { flex: none; width: 20px; height: 20px; margin-left: auto; color: var(--text-2); transition: rotate .18s var(--ease); }
  .aifold[open] .aifold__chev { rotate: 90deg; }
  .aifold__body { padding: 0 20px 20px; }

  .aireporttop { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); gap: 16px; }
  .aireporttop > .aiset + .aiset { margin-top: 0; }
  .aireportform { display: flex; align-items: flex-end; flex-wrap: wrap; gap: 12px; }
  .aireportform .field { flex: 1 1 200px; min-width: 0; }
  .aireportfacts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin: 0; }
  .aireportfacts > div { padding: 14px 16px; border-radius: var(--radius-sm); background: var(--signal-wash); }
  .aireportfacts dt { color: var(--text-2); font-size: 12.5px; }
  .aireportfacts dd { margin: 4px 0 0; font-size: 18px; font-weight: 700; }

  @media (max-width: 1100px) {
    .aikpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .aitpl { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  }
  @media (max-width: 900px) {
    .aigovcard { grid-template-columns: minmax(0, 1fr); }
    .aigovcard__form { padding-left: 0; padding-top: 18px; border-left: 0; border-top: 1px solid var(--line); }
    .aireporttop { grid-template-columns: minmax(0, 1fr); }
    .aikpis--3 { grid-template-columns: minmax(0, 1fr); }
  }
  @media (max-width: 640px) {
    .aikpis, .aitpl { grid-template-columns: minmax(0, 1fr); }
    .aitabs__panel { padding: 16px 12px 14px; }
    .aikpi { padding: 16px; }
    .aiset { padding: 16px; }
    .aibehave__row, .aidomains__row { grid-template-columns: minmax(0, 1fr); gap: 6px; padding: 10px 12px; }
    .aibehave__row--head, .aidomains__row--head { display: none; }
    .aiapphead__text h1 { font-size: 24px; }
    .aifold__head { padding: 14px 16px; }
    .aifold__body { padding: 0 16px 16px; }
    .aireportfacts { grid-template-columns: minmax(0, 1fr); }
  }
}

/* Notifications (PortalReview Notifications01/02): the inbox as a table at dashboard width —
   Domain / indicator · Detection · Status · Occurrences · Source · Last seen — under an
   Unread / All switch, and the detection details of one row: a summary strip, the related DNS
   events with removable filter chips, and why the member received it. */
@layer components {
  .content:has(.notifpage) { max-width: 1440px; }

  .notifcount { background: color-mix(in oklab, var(--flag) 16%, transparent); color: var(--flag); }
  .notifbar__markall { flex: none; padding: 11px 18px; font-size: 14.5px; font-weight: 600; color: var(--allow); }
  .notifbar__markall svg { width: 18px; height: 18px; }

  .notiflog { container-type: inline-size; min-width: 0; padding: 16px; }
  .notiflog > .empty { margin: 0; }
  .notiflog .linkbtn { display: inline; padding: 0 2px; color: var(--signal-text); font-size: inherit; text-decoration: underline; }
  .notifpager .pager { margin: 14px 4px 0; }

  .notiftable { min-width: 0; }
  .notifrow { --cols: minmax(0, 2.3fr) minmax(0, 1.55fr) minmax(0, .95fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, .8fr) 28px;
    display: grid; grid-template-columns: var(--cols); gap: 16px; align-items: center; padding: 16px 14px; border-bottom: 1px solid var(--line); color: var(--text); font-size: 14px; text-decoration: none; transition: background .15s var(--ease); }
  .notifrow:last-child { border-bottom: 0; }
  a.notifrow:hover { background: var(--ink-800); }
  a.notifrow:focus-visible { outline: 2px solid var(--signal); outline-offset: -2px; }
  .notifrow--head { padding-top: 12px; padding-bottom: 12px; border-bottom: 0; border-radius: var(--radius-sm); background: var(--ink-800); }
  .notifrow--head .colhead { cursor: default; color: var(--text-2); font-size: 12.5px; font-weight: 600; letter-spacing: 0; text-transform: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .notifrow__name { display: flex; align-items: center; gap: 14px; min-width: 0; }
  .notifrow__text { display: flex; flex-direction: column; min-width: 0; }
  .notifrow__name b { min-width: 0; font-weight: 700; overflow-wrap: anywhere; }
  .notifrow__sub { margin-top: 3px; color: var(--text-3); font-size: 12.5px; line-height: 1.4; overflow-wrap: anywhere; }
  .notifrow__name b.mono { font-family: inherit; }
  .notifrow--head .notifrow__name { padding-left: 24px; }
  .notifrow__dot { flex: none; width: 9px; height: 9px; border-radius: 50%; border: 1.5px solid var(--line-2); background: transparent; }
  .is-unread .notifrow__dot, .notifsum .notifrow__dot { border-color: transparent; background: var(--allow); box-shadow: 0 0 8px color-mix(in oklab, var(--allow) 45%, transparent); }
  .notifrow:not(.is-unread):not(.notifrow--head) .notifrow__name b { font-weight: 600; color: var(--text-2); }
  .notifrow__detection { min-width: 0; }
  .notifrow__occ, .notifrow__source, .notifrow__seen { color: var(--text-2); font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .notifrow__source.mono { font-family: inherit; }
  .notifrow__go { display: grid; place-items: center; color: var(--text-2); }
  .notifrow__go svg { width: 20px; height: 20px; }
  .notifrow__muted { color: var(--text-3); }
  .pill.notifpill { display: inline-flex; width: fit-content; padding: 5px 12px; font-size: 13px; font-weight: 600; white-space: nowrap; }

  .detchip { display: inline-flex; align-items: center; gap: 8px; max-width: 100%; padding: 6px 12px; border-radius: var(--radius-pill); border: 1px solid var(--line); background: var(--ink-850); color: var(--text); font-size: 13px; line-height: 1.3; }
  .detchip svg, .relrow__detection svg, .notifsum__val svg { flex: none; width: 18px; height: 18px; color: var(--text-2); }

  /* The detection details. */
  .notifsum { padding: 20px 22px 22px; }
  .notifsum__title { display: flex; align-items: center; gap: 14px; min-width: 0; }
  .notifsum__title h2 { margin: 0; min-width: 0; font-size: 24px; font-weight: 700; letter-spacing: -0.015em; overflow-wrap: anywhere; }
  .notifsum__title h2.mono { font-family: inherit; }
  .notifsum__body { margin: 8px 0 0 23px; color: var(--text-2); font-size: 13.5px; }
  .notifsum__cells { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); margin: 18px 0 0; padding-top: 18px; border-top: 1px solid var(--line); }
  .notifsum__cell { min-width: 0; padding: 0 20px; }
  .notifsum__cell:first-child { padding-left: 4px; }
  .notifsum__cell + .notifsum__cell { border-left: 1px solid var(--line); }
  .notifsum__cell dt { margin-bottom: 12px; color: var(--text-2); font-size: 11.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
  .notifsum__cell dd { margin: 0; min-width: 0; font-size: 14px; }
  .notifsum__val { display: inline-flex; align-items: center; gap: 9px; min-width: 0; overflow-wrap: anywhere; }
  .notifsum__val.mono { font-family: inherit; font-variant-numeric: tabular-nums; }

  .notifgrid { display: grid; grid-template-columns: minmax(0, 2.2fr) minmax(0, 1fr); gap: 18px; align-items: start; margin-top: 18px; }
  .notifgrid--solo { grid-template-columns: minmax(0, 1fr); }
  .notifcard__title { display: flex; align-items: center; gap: 12px; margin: 0; font-size: 19px; font-weight: 700; letter-spacing: -0.01em; }

  .notifrel { container-type: inline-size; min-width: 0; padding: 18px; }
  .relchips { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 14px 0 16px; }
  .relchip { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; padding: 6px 8px 6px 14px; border-radius: var(--radius-pill); border: 1px solid var(--line); background: var(--ink-850); color: var(--text-2); font-size: 13px; }
  .relchip b { min-width: 0; color: var(--text); font-weight: 500; overflow-wrap: anywhere; }
  .relchip b.mono { font-family: inherit; }
  .relchip.is-domain { border-color: color-mix(in oklab, var(--allow) 30%, var(--line)); background: color-mix(in oklab, var(--allow) 10%, var(--ink-850)); }
  .relchip button { display: grid; place-items: center; width: 24px; height: 24px; padding: 0; border: 0; border-radius: 50%; background: none; color: var(--text-2); cursor: pointer; }
  .relchip button:hover { background: var(--ink-780); color: var(--text); }
  .relchip button svg { width: 14px; height: 14px; }
  .relchips .linkbtn { color: var(--signal-text); font-size: 13px; text-decoration: underline; }

  .relrow { display: grid; grid-template-columns: minmax(0, .7fr) minmax(0, 1.25fr) minmax(0, 1.45fr) minmax(0, 1.55fr) minmax(0, .95fr) minmax(0, 1.1fr); gap: 12px; align-items: center; padding: 11px 10px; border-bottom: 1px solid var(--line); color: var(--text); font-size: 13px; text-decoration: none; }
  .relrow:last-child { border-bottom: 0; }
  a.relrow:hover { background: var(--ink-800); }
  .relrow.is-self { background: color-mix(in oklab, var(--allow) 7%, transparent); }
  .relrow--head { border-bottom: 0; border-radius: var(--radius-sm); background: var(--ink-800); }
  .relrow--head .colhead { cursor: default; color: var(--text-2); font-size: 12.5px; font-weight: 600; letter-spacing: 0; text-transform: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .relrow .mono { font-family: inherit; font-variant-numeric: tabular-nums; }
  .relrow__domain { font-weight: 600; overflow-wrap: anywhere; }
  .relrow__detection { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
  .relrow__source, .relrow__note { color: var(--text-2); }
  .relrow .pill.notifpill { max-width: 100%; padding: 4px 10px; font-size: 12px; white-space: normal; line-height: 1.3; }
  .notifrel__more { margin: 12px 4px 0; color: var(--text-3); font-size: 12.5px; }

  .notifwhy { padding: 18px 20px 20px; }
  .notifwhy .notifcard__title { padding-bottom: 16px; border-bottom: 1px solid var(--line); font-size: 18px; }
  .notifwhy__icon { display: grid; place-items: center; flex: none; width: 36px; height: 36px; border-radius: 50%; background: color-mix(in oklab, var(--allow) 14%, transparent); color: var(--allow); }
  .notifwhy__icon svg { width: 20px; height: 20px; }
  .notifwhy__list { display: grid; gap: 16px; margin: 18px 0 0; padding: 0; list-style: none; color: var(--text); font-size: 14px; line-height: 1.5; }
  .notifwhy__list li { display: flex; align-items: flex-start; gap: 12px; }
  .notifwhy__list svg { flex: none; width: 18px; height: 18px; margin-top: 2px; color: var(--allow); }
  .notifwhy__facts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin-top: 16px; }
  .notifwhy__facts:empty { display: none; }
  .notifwhy__fact { color: var(--text-3); font-family: var(--font-mono); font-size: 11.5px; }
  a.notifwhy__fact { color: var(--signal-text); }
  .notifwhy__acts { margin-top: 16px; }

  /* The list card narrows: Source goes first (a row is a group, so how many times matters more),
     then Occurrences; a phone stacks the row — the name and status on top, the detection and when
     under it, and how many times under that when it is more than once. */
  @container (max-width: 1100px) {
    .notifrow { --cols: minmax(0, 2.2fr) minmax(0, 1.6fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, .9fr) 24px; }
    .notifrow .notifrow__source { display: none; }
  }
  @container (max-width: 760px) {
    .notifrow { --cols: minmax(0, 2fr) minmax(0, 1.6fr) minmax(0, 1fr) minmax(0, .9fr) 24px; gap: 12px; }
    .notifrow .notifrow__occ { display: none; }
  }
  @container (max-width: 680px) {
    .notifrow { grid-template-columns: minmax(0, 1fr) auto 20px; gap: 8px 12px; padding: 14px 6px; }
    .notifrow--head { display: none; }
    .notifrow__name { grid-column: 1; grid-row: 1; }
    .notifrow__status { grid-column: 2; grid-row: 1; }
    .notifrow__go { grid-column: 3; grid-row: 1 / span 2; }
    .notifrow__detection { grid-column: 1; grid-row: 2; padding-left: 23px; }
    .notifrow__seen { grid-column: 2; grid-row: 2; justify-self: end; font-size: 12.5px; }
    .notifrow.is-repeat .notifrow__occ { display: block; grid-column: 1; grid-row: 3; padding-left: 23px; font-size: 12.5px; }
  }
  /* The related events narrow: the source goes, then the note; a phone stacks the row. */
  @container (max-width: 760px) {
    .relrow { grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr) minmax(0, 1.5fr) minmax(0, 1.4fr) minmax(0, 1.2fr); }
    .relrow .relrow__source { display: none; }
  }
  @container (max-width: 600px) {
    .relrow { grid-template-columns: 84px minmax(0, 1fr); gap: 6px 12px; align-items: start; }
    .relrow--head { display: none; }
    .relrow .relrow__note { display: none; }
    .relrow > :nth-child(n+3) { grid-column: 2; }
  }

  /* Below 1400 px the six summary cells take two lines and the Why panel goes under the related
     events, which keep the width their six columns need. */
  @media (max-width: 1400px) {
    .notifsum__cells { grid-template-columns: repeat(3, minmax(0, 1fr)); row-gap: 18px; }
    .notifsum__cell:nth-child(3n+1) { padding-left: 4px; border-left: 0; }
    .notifgrid { grid-template-columns: minmax(0, 1fr); }
  }
  @media (max-width: 640px) {
    .notifbar__markall { width: 100%; justify-content: center; }
    .notiflog, .notifrel { padding: 10px; }
    .notifsum { padding: 16px; }
    .notifsum__title h2 { font-size: 20px; }
    .notifsum__body { margin-left: 0; }
    .notifsum__cells { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .notifsum__cell, .notifsum__cell:nth-child(3n+1) { padding: 0 12px; border-left: 1px solid var(--line); }
    .notifsum__cell:nth-child(2n+1) { padding-left: 4px; border-left: 0; }
  }
  /* Your account (/profile): as wide as the dashboard, four tabs on the Protection & policies host
     (.protab). A one-card tab drops the card's chrome inside the panel, like Protection; Sign-in &
     security keeps its three cards — password | sign-in address, two-factor across the row below. */
  .content:has(#profile-tabpanel) { max-width: 1440px; }
  .accttab__panel--single > .card, .accttab__panel--single > div > .card { padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; }
  .acctgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; align-items: stretch; }
  .acctgrid > * { min-width: 0; }
  .acctgrid > .card { height: 100%; }
  .acctgrid__wide { grid-column: 1 / -1; }
  /* A switch stays at the end of its row, beside the text, however long the text runs. */
  .accttab .row:has(> .switch) { flex-wrap: nowrap; }
  .acctgrid .card { background: var(--ink-850); box-shadow: none; }
  @media (max-width: 1040px) {
    .acctgrid { grid-template-columns: minmax(0, 1fr); }
  }
}

/* -------------------------------------------------------------------------
   PortalReview Registration01–04 — the split guest shell, the registration
   stepper and its form details. Always dark (design-language.md "Guest
   pages"): the mockups' layout on the Night Watch tokens. No new colour.
   ------------------------------------------------------------------------- */
@layer components {
  /* The right half's darker ground is painted here, not on the panel, so the signal rings cross the seam above it. */
  /* Two capped, equal columns centred as a pair: the copy and the card stay close on any width, and the seam stays at 50 %. */
  .guest--split { display: grid; grid-template-columns: minmax(0, 640px) minmax(0, 640px); justify-content: center; place-items: stretch; padding: 0; overflow: hidden; background: linear-gradient(90deg, transparent 50%, color-mix(in oklab, var(--ink-900) 72%, transparent) 50%); }
  .guest__pitch { position: relative; z-index: 0; display: flex; flex-direction: column; justify-content: center; gap: 48px; min-width: 0; padding: 56px clamp(32px, 4vw, 56px) 48px clamp(32px, 4vw, 80px); }
  .guest__copy { position: relative; z-index: 1; max-width: 520px; }
  .guest__eyebrow { margin: 0 0 14px; font-family: var(--font-mono); font-size: 12px; font-weight: 600; letter-spacing: .18em; text-transform: uppercase; color: var(--signal-text); }
  .guest__headline { margin: 0; font-size: clamp(34px, 3.6vw, 52px); line-height: 1.06; font-weight: 750; letter-spacing: -0.035em; color: var(--text); text-wrap: balance; }
  .guest__lead { margin: 18px 0 0; max-width: 440px; font-size: 16px; line-height: 1.6; color: var(--text-2); }
  .guest__signal { position: absolute; right: -90px; top: 50%; width: min(640px, 78%); height: auto; transform: translateY(-4%); color: var(--text-3); pointer-events: none; z-index: 0; }
  .guest__arc { stroke: color-mix(in oklab, var(--signal) 55%, transparent); }
  .guest__dot { fill: color-mix(in oklab, var(--signal) 70%, transparent); filter: drop-shadow(0 0 18px var(--signal-glow)); }

  .trustrow { position: relative; z-index: 1; list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: nowrap; gap: 0; }
  .trustrow li { display: flex; align-items: center; gap: clamp(8px, 1vw, 12px); padding: 4px clamp(12px, 1.4vw, 26px); font-size: 13px; line-height: 1.35; color: var(--text-2); border-left: 1px solid var(--line-2); }
  .trustrow li:first-child { padding-left: 0; border-left: 0; }
  .trustrow svg { flex: none; width: 30px; height: 30px; color: var(--text); }

  .guest__panel { position: relative; z-index: 1; min-width: 0; display: grid; place-items: center; padding: 40px clamp(20px, 4vw, 56px); border-left: 1px solid var(--line); }
  .guest--split .guest__inner { max-width: 560px; }
  .guest__card { padding: 32px clamp(20px, 4vw, 48px); box-shadow: var(--shadow-lg); }
  .guest__card .guest__brand { justify-content: center; margin-bottom: 26px; }
  .guest__card .rulecard__title { font-size: 26px; letter-spacing: -0.03em; }
  .guest__card .rulecard__sub { font-size: 14.5px; line-height: 1.55; }
  .guest__foot { margin: 20px 0 0; text-align: center; font-size: 13.5px; color: var(--text-3); }
  .guest__foot .linkbtn { padding: 4px 6px; font-size: 13.5px; font-weight: 600; color: var(--signal-text); }

  @media (max-width: 960px) {
    .guest--split { grid-template-columns: minmax(0, 1fr); background: none; }
    .guest__pitch { display: none; }
    .guest__panel { border-left: 0; padding: 32px 16px; }
  }
  @media (max-width: 480px) {
    .guest__card { padding: 24px 18px; }
    .guest__card .rulecard__title { font-size: 22px; }
  }

  /* The stepper: dots on a line, labels under them; read-only. */
  .stepper { list-style: none; margin: 0 0 28px; padding: 0; display: grid; grid-template-columns: repeat(var(--steps, 4), minmax(0, 1fr)); }
  .stepper__step { position: relative; display: grid; justify-items: center; gap: 8px; min-width: 0; text-align: center; }
  .stepper__step + .stepper__step::before { content: ""; position: absolute; top: 15px; right: calc(50% + 20px); left: calc(-50% + 20px); height: 2px; border-radius: 2px; background: var(--line-2); }
  .stepper__step.is-done + .stepper__step::before,
  .stepper__step.is-done + .stepper__step.is-current::before { background: color-mix(in oklab, var(--signal) 55%, transparent); }
  .stepper__dot { position: relative; width: 32px; height: 32px; display: grid; place-items: center; border-radius: 50%; border: 1px solid var(--line-2); background: var(--ink-700); font-family: var(--font-mono); font-size: 12.5px; font-weight: 700; color: var(--text-3); }
  .stepper__dot svg { width: 15px; height: 15px; }
  .stepper__step.is-current .stepper__dot { background: var(--signal); border-color: var(--signal); color: var(--signal-ink); box-shadow: 0 0 0 4px var(--signal-wash); }
  .stepper__step.is-done .stepper__dot { background: var(--signal-wash); border-color: color-mix(in oklab, var(--signal) 50%, transparent); color: var(--signal-text); }
  .stepper__label { max-width: 100%; font-size: 12.5px; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .stepper__step.is-current .stepper__label { color: var(--text); font-weight: 600; }
  @media (max-width: 420px) {
    .stepper__step:not(.is-current) .stepper__label { visibility: hidden; }
    .stepper__step.is-current .stepper__label { overflow: visible; }
  }

  /* An input with a leading icon and, for passwords, a trailing show/hide toggle. */
  .inputicon { position: relative; }
  .inputicon > svg { position: absolute; left: 13px; top: 50%; width: 18px; height: 18px; transform: translateY(-50%); color: var(--text-3); pointer-events: none; }
  .inputicon > .input { min-height: 48px; padding-left: 42px; }
  .inputicon--toggle > .input { padding-right: 48px; }
  .inputicon__toggle { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); width: 40px; height: 40px; display: grid; place-items: center; border: 0; border-radius: var(--radius-xs); background: none; color: var(--text-3); cursor: pointer; }
  .inputicon__toggle:hover { color: var(--text); }
  .inputicon__toggle svg { width: 18px; height: 18px; }
  .inputicon__toggle [x-cloak] { display: none; }
  .inputicon > select.input { padding-left: 42px; }

  /* The password rule, ticked while typing. */
  .pwcheck { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 12.5px; color: var(--text-3); }
  .pwcheck svg { flex: none; width: 16px; height: 16px; }
  .pwcheck.is-met { color: var(--allow); }

  /* The registration actions: Back (a link) on the left, the one primary on the right. */
  .regactions { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 8px; }
  .regactions .btn--primary { flex: 0 1 62%; min-height: 50px; justify-content: center; gap: 10px; padding-inline: 22px; font-size: 15px; }
  /* Portal #294: a lone primary action sits on the card's centred axis, label + arrow centred inside it. */
  .regactions--center { justify-content: center; }
  .regactions--full .btn--primary { flex-basis: 100%; }
  .regactions .btn--primary svg { width: 18px; height: 18px; }
  .regback { min-height: 44px; padding: 8px 4px; border: 0; background: none; font: inherit; font-size: 15px; font-weight: 600; color: var(--signal-text); cursor: pointer; }

  /* The confirm-your-email and All set screens: one large round badge. */
  .regbadge { width: 120px; height: 120px; margin: 20px auto; display: grid; place-items: center; border-radius: 50%; background: radial-gradient(closest-side, var(--signal-wash), transparent), var(--ink-780); border: 1px solid var(--line-2); box-shadow: 0 0 0 14px color-mix(in oklab, var(--signal) 5%, transparent); color: var(--text); }
  .regbadge svg { width: 48px; height: 48px; }
  .regbadge--ok { color: var(--signal-text); }
  .regdone { text-align: center; }
  .regdone .rulecard__title { font-size: 32px; }
  .regdone .rulecard__sub { max-width: 380px; margin-inline: auto; }
  .reglinks { display: flex; align-items: center; justify-content: flex-end; gap: 12px; margin-top: 14px; }
  .reglinks .linkbtn { padding: 6px 4px; font-size: 14px; font-weight: 600; color: var(--signal-text); }

  /* The setup wizard's "Your organisation" step carries the Preferences answers under its facts. */
  .setup__subtitle { margin: 22px 0 12px; font-size: 15px; font-weight: 650; letter-spacing: -0.01em; }
}
