/* ============================================================
   ES-Management admin suite — Radar-style design system
   Dark-first, light-mode toggle via [data-theme="light"].
   Brand: Xerox red #D92231. Type: Space Grotesk / IBM Plex.
   ============================================================ */

:root {
  color-scheme: dark;

  /* surfaces — Radar-style layered, blue-tinted navy */
  --bg: #0b0f1e;
  --bg-inset: #080b16;
  --panel: #14192a;
  --panel-2: #1e2338;
  --panel-3: #282e48;
  --border: #222840;
  --border-strong: #2c324a;

  /* text */
  --text: #f5f6f8;
  --text-muted: #b0b5c0;
  --text-faint: #6a7080;

  /* brand */
  --accent: #d92231;
  --accent-hover: #e8323f;
  --accent-text: #ffffff;
  --accent-tint: rgba(217, 34, 49, 0.14);
  --accent-tint-strong: rgba(217, 34, 49, 0.24);
  --focus-ring: rgba(217, 34, 49, 0.55);

  /* status */
  --success: #3fb27f;
  --warning: #d98a2b;
  --danger: #e0524a;
  --info: #4a90d9;
  --success-tint: rgba(63, 178, 127, 0.14);
  --warning-tint: rgba(217, 138, 43, 0.14);
  --danger-tint: rgba(224, 82, 74, 0.14);
  --info-tint: rgba(74, 144, 217, 0.14);
  --neutral-tint: rgba(139, 144, 154, 0.16);

  /* elevation — Radar's layered depth: lit top edge (inset white ring) + soft
     ambient shadow; the drawer carries a deep left-cast shadow */
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(255, 255, 255, 0.06);
  --shadow-md: 0 4px 12px -2px rgba(0, 0, 0, 0.35), 0 2px 4px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(255, 255, 255, 0.06);
  --shadow-lg: 0 12px 32px -6px rgba(0, 0, 0, 0.3), 0 4px 8px rgba(0, 0, 0, 0.1);
  --shadow-drawer: -12px 0 36px rgba(0, 0, 0, 0.45), -4px 0 14px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.06);

  /* brand glow + selection + scrollbar + motion (Radar's signature feel) */
  --border-subtle: rgba(255, 255, 255, 0.04);
  --border-emphasis: rgba(255, 255, 255, 0.22);
  --bg-hover: #282e48;
  --bg-active: #1c2840;
  --glow-accent-sm: 0 0 8px rgba(217, 34, 49, 0.25);
  --glow-accent-md: 0 0 16px rgba(217, 34, 49, 0.25);
  --scrollbar-track: #0f1322;
  --scrollbar-thumb: #2c324a;
  --scrollbar-thumb-hover: #484c55;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-drawer: cubic-bezier(0.2, 0.8, 0.2, 1);

  /* sidebar stays dark in both themes (Radar look) */
  --sidebar-bg: #0e1014;
  --sidebar-bg-2: #121419;
  --sidebar-text: #c7cbd3;
  --sidebar-muted: #6d727c;
  --sidebar-border: #1e2128;
  --sidebar-hover: #1a1d24;
  --sidebar-active-bg: rgba(217, 34, 49, 0.14);
  --sidebar-active-text: #f4f5f7;

  /* metrics */
  --radius-sm: 6px;
  --radius: 8px;
  --radius-lg: 12px;
  --sidebar-width: 232px;
  --sidebar-rail: 64px;
  --topbar-height: 56px;
  --topbar-control-height: 34px;

  --font-display: "DM Sans", system-ui, sans-serif;
  --font-body: "DM Sans", system-ui, sans-serif;
  --font-mono: "DM Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

[data-theme="light"] {
  color-scheme: light;
  --bg: #f6f7f9;
  --bg-inset: #eef0f3;
  --panel: #ffffff;
  --panel-2: #f2f4f7;
  --panel-3: #e9ecf0;
  --border: #e4e7ec;
  --border-strong: #d0d5dd;

  --text: #16181d;
  --text-muted: #5b6068;
  --text-faint: #6b7078;

  --accent-hover: #c01d2b;
  --focus-ring: rgba(217, 34, 49, 0.35);

  --success: #12805c;
  --warning: #b54708;
  --danger: #b42318;
  --info: #175cd3;
  --success-tint: rgba(18, 128, 92, 0.1);
  --warning-tint: rgba(181, 71, 8, 0.1);
  --danger-tint: rgba(180, 35, 24, 0.09);
  --info-tint: rgba(23, 92, 211, 0.1);
  --neutral-tint: rgba(91, 96, 104, 0.1);

  --shadow-sm: 0 1px 3px rgba(16, 24, 40, 0.08), 0 1px 2px rgba(16, 24, 40, 0.04), 0 0 0 1px rgba(0, 0, 0, 0.06);
  --shadow-md: 0 4px 12px -2px rgba(16, 24, 40, 0.12), 0 2px 4px rgba(16, 24, 40, 0.06), 0 0 0 1px rgba(0, 0, 0, 0.06);
  --shadow-lg: 0 12px 32px -6px rgba(16, 24, 40, 0.16), 0 4px 8px rgba(16, 24, 40, 0.06);
  --shadow-drawer: -12px 0 36px rgba(16, 24, 40, 0.18), -4px 0 14px rgba(16, 24, 40, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.06);

  --border-subtle: rgba(0, 0, 0, 0.04);
  --border-emphasis: rgba(0, 0, 0, 0.18);
  --bg-hover: #e9ecf0;
  --bg-active: #eef0f3;
  --glow-accent-sm: 0 0 8px rgba(217, 34, 49, 0.18);
  --glow-accent-md: 0 0 16px rgba(217, 34, 49, 0.18);
  --scrollbar-track: #eef0f3;
  --scrollbar-thumb: #d0d5dd;
  --scrollbar-thumb-hover: #b0b5c0;
}

/* ---------- light mode: public auth + portal surfaces ----------
   The shared palette above already swaps every token (bg/panel/text/border/
   shadow), and the public + portal chrome is token-driven, so those pages
   inherit a complete light theme. This scoped block carries the small
   public-only refinements: the red .brand-panel stays identical in both
   themes (its gradient is literal, untouched), while the paper-white cards
   get a touch more elevation so they don't flatten against the white page. */
[data-theme="light"] .public-card,
[data-theme="light"] .login-card,
[data-theme="light"] .onboarding-card {
  box-shadow: var(--shadow-lg);
}

/* ---------- base ---------- */

* { box-sizing: border-box; }

html { height: 100%; }

/* Themed scrollbars (Radar's thin, tinted rails). */
* { scrollbar-width: thin; scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track); }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--scrollbar-track); }
::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); border-radius: 999px; border: 2px solid var(--scrollbar-track); }
::-webkit-scrollbar-thumb:hover { background: var(--scrollbar-thumb-hover); }

body {
  margin: 0;
  min-height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0;
}

/* Radar pairs a big bold display weight with a quiet body: page titles get a
   heavier, tighter treatment for strong size/weight contrast. */
h1 { font-weight: 700; letter-spacing: -0.02em; }

a { color: var(--info); text-decoration: none; transition: color 150ms ease; }
a:hover { color: var(--accent); }

code, .mono { font-family: var(--font-mono); font-size: 12.5px; font-variant-numeric: tabular-nums; }

:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 1px;
  border-radius: 4px;
}

/* ---------- app shell ---------- */

.app-shell {
  display: grid;
  grid-template-columns: var(--sidebar-width) 1fr;
  min-height: 100vh;
  transition: grid-template-columns 200ms ease;
}

body.sidebar-collapsed .app-shell { grid-template-columns: var(--sidebar-rail) 1fr; }

.app-main {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.app-content {
  padding: 24px 28px 48px;
  /* Every admin surface fills the content width like the Radar resources
     pages (registrations/organizations/users); no centered 1280px column. */
  max-width: none;
  width: 100%;
  margin: 0 auto;
}

.page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

.page-title { font-size: 26px; font-weight: 700; letter-spacing: -0.02em; }
.page-sub { color: var(--text-muted); font-size: 13px; margin-top: 2px; }

/* ---------- sidebar ---------- */

.sidebar {
  background: linear-gradient(180deg, var(--sidebar-bg) 0%, var(--sidebar-bg-2) 100%);
  border-right: 1px solid var(--sidebar-border);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
}

.sidebar-brand {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 10px;
  padding: 0 16px;
  height: var(--topbar-height);
  box-sizing: border-box;
  flex: none;
}

/* Official Xerox wordmark (app/static/xerox-logo.svg). Xerox red on
   transparent, so it reads on the dark sidebar and light cards alike. */

.brand-logo {
  display: block;
  height: 22px;
  width: auto;
  flex: none;
}

.brand-logo-on-red { height: 30px; filter: brightness(0) invert(1); }

/* On the red public panel the official wordmark (Xerox red on transparent)
   would vanish, so .brand-logo-on-red inverts it to white above. The wrap
   only handles placement and spacing — no chip background. */
.brand-logo-wrap {
  align-self: flex-start;
  display: inline-block;
  margin-bottom: 26px;
}

.sidebar-nav-wrap {
  flex: 1;
  min-height: 0;
  position: relative;
  display: flex;
  flex-direction: column;
}

.sidebar-nav {
  flex: 1;
  min-height: 0;
  padding: 14px 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow-y: auto;
  /* The scrollbar is hidden (scrolling fully preserved) — the more-below
     affordance replaces it as the scroll cue. */
  scrollbar-width: none;
}

.sidebar-nav::-webkit-scrollbar { display: none; }

/* More-below affordance: a fade-out gradient over the nav's bottom edge with
   a gently nudging chevron. Shown only while the nav is scrollable and NOT
   scrolled to the end (app.js toggles .visible on scroll/resize/collapse).
   pointer-events: none — it never blocks nav clicks. The fade ends on
   --sidebar-bg-2, the sidebar's bottom gradient stop, so it blends in both
   themes (the sidebar stays dark in light mode too). */
.sidebar-more-hint {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 56px;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding-bottom: 6px;
  background: linear-gradient(180deg, transparent 0%, var(--sidebar-bg-2) 78%);
  color: var(--sidebar-muted);
  pointer-events: none;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out);
}

.sidebar-more-hint.visible { opacity: 1; transform: none; }

.sidebar-more-hint svg { animation: sidebar-hint-nudge 1.6s ease-in-out infinite; }

@keyframes sidebar-hint-nudge {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(4px); }
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 8px 12px;
  border-radius: var(--radius);
  color: var(--sidebar-muted);
  font-weight: 500;
  font-size: 13.5px;
  position: relative;
  white-space: nowrap;
  transition: background 150ms ease, color 150ms ease;
  background: transparent;
  border: 0;
  cursor: pointer;
  font-family: inherit;
  text-align: left;
  width: 100%;
}

.nav-item svg { flex: none; opacity: 0.85; }

.nav-item:hover {
  background: var(--sidebar-hover);
  color: var(--sidebar-text);
}

.nav-item.active {
  background: var(--sidebar-active-bg);
  color: var(--sidebar-active-text);
}

.nav-item.active::before {
  content: "";
  position: absolute;
  left: -10px;
  top: 8px;
  bottom: 8px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--accent);
}

.nav-item.active svg { opacity: 1; }

.nav-label { overflow: hidden; text-overflow: ellipsis; }

.nav-count {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--sidebar-muted);
  background: rgba(255, 255, 255, 0.05);
  border-radius: 999px;
  padding: 1px 7px;
}

.nav-item.active .nav-count { color: var(--sidebar-active-text); background: rgba(255, 255, 255, 0.1); }

.nav-badge { color: var(--warning); background: var(--warning-tint); font-weight: 600; }

.nav-badge[data-nav-badge="registrations"] { color: var(--danger); background: var(--danger-tint); }

.nav-badge-info { color: var(--info); background: var(--info-tint); }

/* Consolidated nav apps: a labelled group of related menus. The group label is
   a small uppercase caption; its children are the regular .nav-item links. */
.nav-group { display: flex; flex-direction: column; gap: 2px; margin-top: 12px; }
.nav-group:first-of-type { margin-top: 6px; }
.nav-group-label {
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--sidebar-text-faint, var(--text-faint));
  padding: 0 12px 4px;
}

.sidebar-footer {
  padding: 10px;
  border-top: 1px solid var(--sidebar-border);
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* Drawer-only extras (global search + preferences): hidden on desktop; the
   off-canvas nav shows them at <=980px, where the topbar is a single dense
   row and cannot carry them. */
.drawer-extras { display: none; }

/* collapsed rail */
body.sidebar-collapsed .nav-label,
body.sidebar-collapsed .nav-count { display: none; }

body.sidebar-collapsed .nav-group-label { display: none; }
body.sidebar-collapsed .nav-group { margin-top: 8px; }

body.sidebar-collapsed .sidebar-brand { align-items: center; justify-content: center; padding: 0 8px; }
body.sidebar-collapsed .brand-logo { display: none; }
body.sidebar-collapsed .nav-item { justify-content: center; padding: 10px; }
body.sidebar-collapsed .nav-item.active::before { left: -6px; }

/* The collapse toggle's chevron always points the way the ACTION goes:
   collapsed → flip to point right (the expand direction), expanded →
   point left (the collapse direction). The arrow is currentColor, so it
   follows both themes automatically. */
#collapse-btn .collapse-arrow { transform-origin: center; transition: transform 150ms ease; }
body.sidebar-collapsed #collapse-btn .collapse-arrow { transform: scaleX(-1); }

/* ---------- top bar ---------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  height: var(--topbar-height);
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 20px;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
}

.scope-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: var(--topbar-control-height);
  box-sizing: border-box;
  padding: 0 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--panel);
  color: var(--text-muted);
  font-size: 12.5px;
  white-space: nowrap;
}
.scope-chip .mono { color: var(--text); }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Session-scoped CrushFTP instance selector in the topbar (replaces the static
   server-group chip). A native <select> posts to /admin/instances/select and
   re-renders the users view for the chosen instance. */
.instance-selector {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: var(--topbar-control-height);
  box-sizing: border-box;
  padding: 0 8px 0 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--panel);
  color: var(--text-muted);
  font-size: 12.5px;
  white-space: nowrap;
}
.instance-selector select {
  background: transparent;
  color: var(--text);
  border: none;
  font: inherit;
  font-family: var(--font-mono, monospace);
  max-width: 240px;
  cursor: pointer;
}
.instance-selector select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Instance edit row on /admin/instances reuses .domain-edit-row; the form wraps
   its six inputs + save button across the wide row. */
.instance-edit-form { margin-top: 0; flex-wrap: wrap; align-items: flex-start; }
.instance-edit-form > input { flex: 1 1 180px; }

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--text-faint);
  flex: none;
}

.status-dot[data-state="ok"] {
  background: var(--success);
  animation: dot-pulse 2.2s ease-in-out infinite;
}

.status-dot[data-state="warn"] { background: var(--warning); animation: dot-pulse-warn 1.6s ease-in-out infinite; }
.status-dot[data-state="down"] { background: var(--danger); animation: dot-pulse-down 1.2s ease-in-out infinite; }

@keyframes dot-pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--success) 45%, transparent); }
  50% { box-shadow: 0 0 0 5px transparent; }
}

@keyframes dot-pulse-warn {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--warning) 50%, transparent); }
  50% { box-shadow: 0 0 0 5px transparent; }
}
@keyframes dot-pulse-down {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--danger) 50%, transparent); opacity: 1; }
  50% { box-shadow: 0 0 0 5px transparent; opacity: 0.5; }
}

.session-timeout {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: var(--topbar-control-height);
  box-sizing: border-box;
  padding: 0 11px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--panel);
  color: var(--text-muted);
  font-size: 12.5px;
  white-space: nowrap;
}
.session-timeout .mono { color: var(--text); }

.session-timeout[data-state="warn"] {
  border-color: color-mix(in srgb, var(--warning) 55%, transparent);
  color: var(--warning);
}

.session-timeout[data-state="warn"] .mono { color: var(--warning); }

.session-timeout[data-state="danger"],
.session-timeout[data-state="expired"] {
  border-color: color-mix(in srgb, var(--danger) 55%, transparent);
  color: var(--danger);
}

.session-timeout[data-state="danger"] .mono,
.session-timeout[data-state="expired"] .mono { color: var(--danger); }

.command-search {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 10px;
  height: var(--topbar-control-height);
}

.command-search svg { flex: none; color: var(--text-faint); }

/* The wrap is the visual bar: the help icon sits inside it (right of the
   input, before the border). flex:1 grows it to fill the space between
   the left topbar controls and the right-pinned .topbar-actions — no
   max-width cap, so the bar fills all available width at any viewport. */
.command-search-wrap {
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--bg-inset);
  color: var(--text-faint);
  transition: border-color 150ms ease, background 150ms ease;
}

.command-search-wrap:focus-within {
  border-color: var(--accent);
  background: var(--panel);
}

.command-search-help {
  flex: none;
  width: 28px;
  height: 26px;
  margin-right: 5px;
  border: 0;
  background: transparent;
  color: var(--text-faint);
}

.command-search-help:hover { background: var(--bg-hover); color: var(--text); border-color: transparent; }

/* Higher specificity than the generic form-field rule below (which styles
   input[type="search"]) so the topbar input stays a borderless flex child
   inside the .command-search-wrap bar. width:0 lets flex:1 cleanly grow
   the input to fill all available space (width:auto resolves to the
   browser's intrinsic default ~150px and fights flex sizing on focus). */
.command-search-wrap .command-search input {
  flex: 1;
  min-width: 0;
  width: 0;
  padding: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text);
  font-family: var(--font-body);
  font-size: 13px;
}

.command-search input::placeholder { color: var(--text-faint); }

/* The outer .command-search-wrap:focus-within glow is the single focus
   indicator; suppress the global input:focus ring inside the command search. */
.command-search input:focus { outline: none; box-shadow: none; }

.kbd-chip {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--text-faint);
  border: 1px solid var(--border-strong);
  border-bottom-width: 2px;
  border-radius: 5px;
  padding: 1px 6px;
  background: var(--panel);
  white-space: nowrap;
}

/* ---------- live search typeahead ----------
   Grouped result rows rendered by GET /admin/search/live into the command
   palette's results group. Theme-aware (panel/border/accent tokens). */

.search-live-group + .search-live-group { border-top: 1px solid var(--border); margin-top: 6px; padding-top: 6px; }

.search-live-group-label {
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-faint);
  padding: 4px 8px;
}

.search-live-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 8px;
  border-radius: 6px;
  text-decoration: none;
  color: var(--text);
  cursor: pointer;
}

.search-live-item:hover,
.search-live-item.active { background: var(--bg-hover); }
.search-live-item.active { box-shadow: inset 2px 0 0 var(--accent); }

.search-live-type {
  flex: none;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
}
.search-live-type-reg { color: var(--info); background: var(--info-tint); }
.search-live-type-domain { color: var(--accent); background: var(--danger-tint); }
.search-live-type-user { color: var(--success); background: var(--success-tint); }

.search-live-text { display: flex; flex-direction: column; min-width: 0; }
.search-live-label { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.search-live-hint { font-size: 11.5px; color: var(--text-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.search-live-more {
  display: block;
  padding: 6px 8px;
  font-size: 12px;
  color: var(--accent);
  text-decoration: none;
}
.search-live-more:hover { text-decoration: underline; }

.search-live-empty { padding: 14px 10px; color: var(--text-faint); font-size: 13px; text-align: center; }

.topbar-actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 6px;
}

.icon-btn {
  display: inline-grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: var(--radius);
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease, transform 150ms ease, border-color 150ms ease;
}

.icon-btn:hover {
  background: var(--panel-2);
  color: var(--text);
  border-color: var(--border);
  transform: translateY(-1px);
}

/* ---------- Consolidated user menu (identity card + absorbed prefs) ----------
   ONE card button in the topbar (avatar + name + unread badge + chevron)
   opens a menu holding: identity header, notifications (the bell endpoints,
   lazy-loaded inline), language + theme segmented controls. Settings and
   sign out live in the icon-only topbar buttons BESIDE the card. Shared by
   the admin topbar and the portal topbar. */

/* Topbar icon-only actions (gear = user settings, exit = sign out) that sit
   BESIDE the user card. House icon-btn chrome, theme-aware hover/focus; the
   sign-out icon submits the hidden logout form (POST + CSRF on admin). */
.topbar-action-form { display: inline-flex; margin: 0; }
.topbar-action-btn {
  width: 36px;
  height: 36px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--text-muted);
  display: inline-grid;
  place-items: center;
  cursor: pointer;
  transition: background 160ms var(--ease-out), color 160ms var(--ease-out),
    border-color 160ms var(--ease-out), transform 160ms var(--ease-out),
    box-shadow 160ms var(--ease-out);
}
.topbar-action-btn:hover {
  background: var(--panel-2);
  color: var(--text);
  border-color: var(--border-strong);
  transform: translateY(-1px);
  box-shadow: var(--shadow-sm);
}
.topbar-action-btn:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}
.topbar-action-btn.danger:hover {
  color: var(--danger);
  border-color: var(--danger-tint);
  background: var(--danger-tint);
}
/* Settings-dialog extras (restored modal + the 528-added mute block). */
.portal-prefs-dialog-body { padding-bottom: 6px; }

.user-menu { position: relative; }

.user-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 10px 4px 5px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--text);
  cursor: pointer;
  font-family: var(--font-body);
  font-size: 13px;
  transition:
    border-color 150ms var(--ease-out),
    background 150ms var(--ease-out),
    box-shadow 150ms var(--ease-out);
}

.user-btn:hover { border-color: var(--border-strong); background: var(--panel-2); }
.user-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.user-menu.open .user-btn {
  border-color: var(--border-strong);
  background: var(--panel-2);
  box-shadow: var(--glow-accent-sm);
}

.user-avatar {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--accent-tint-strong);
  color: var(--accent);
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 12px;
  flex: none;
}

.user-avatar-lg {
  width: 36px;
  height: 36px;
  font-size: 15px;
}

.user-btn-name {
  font-weight: 600;
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.user-card-badge {
  position: absolute;
  top: -5px;
  right: -5px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--danger);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  pointer-events: none;
}

.user-chevron {
  color: var(--text-faint);
  transition: transform 200ms var(--ease-drawer);
}

.user-menu.open .user-chevron { transform: rotate(180deg); }

.user-dropdown {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  width: min(372px, 92vw);
  background: var(--panel);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 0;
  display: none;
  z-index: 70;
  transform-origin: top right;
}

.user-menu.open .user-dropdown {
  display: block;
  animation: user-menu-in 200ms var(--ease-drawer);
}

@keyframes user-menu-in {
  from { opacity: 0; transform: translateY(-6px) scale(0.98); }
  to { opacity: 1; transform: none; }
}

/* NO identity header in the flyout (v3): identity lives on the topbar card;
   the flyout is actions only. */

/* Menu action rows (Docs link, log off): icon + label, full-width hit area. */
.user-dropdown .dropdown-item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  text-align: left;
  border: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
  padding: 9px 14px;
  text-decoration: none;
}

.user-dropdown .dropdown-item svg { flex: 0 0 auto; color: var(--text-muted); }


.menu-divider {
  height: 1px;
  background: var(--border-subtle);
  margin: 6px 0;
}

/* Notifications inside the menu: the same rows the standalone bell served,
   now inline with a bounded scroll region (the global themed scrollbar). */
.user-notif { display: flex; flex-direction: column; }

.user-notif-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 14px 6px;
}

.user-notif-head .panel-title { font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-faint); font-weight: 700; }

.user-notif-body {
  max-height: 264px;
  overflow-y: auto;
  min-height: 44px;
  border-block: 1px solid var(--border-subtle);
}

.user-notif .notif-row { padding: 9px 14px; }
.user-notif .notif-day-label { padding: 8px 14px 4px; }

.user-notif-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 12px 12px;
}

/* Segmented controls (language EN/NL + theme Dark/Light). The language
   control reuses the .lang-switch form class so lang-switch.js's cookie
   mirror + stale-variant purge keep firing verbatim. */
.menu-segs {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 8px 14px;
}

.menu-seg-block { display: flex; flex-direction: column; gap: 6px; }

.menu-seg-label {
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-faint);
}

.menu-seg {
  display: flex;
  width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--bg-inset);
}

.menu-seg > button {
  flex: 1 1 0;
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.05em;
  padding: 6px 10px;
  cursor: pointer;
  transition: background 140ms var(--ease-out), color 140ms var(--ease-out);
}

.menu-seg > button:hover { background: var(--bg-hover); color: var(--text); }
.menu-seg > button.active { background: var(--accent-tint); color: var(--accent); }
.menu-seg > button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.user-dropdown .lang-switch { border: 0; overflow: visible; display: flex; }
.user-dropdown .lang-switch .lang-opt { border: 1px solid var(--border); }
.user-dropdown .lang-switch .lang-opt:first-child { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.user-dropdown .lang-switch .lang-opt:last-child { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; border-left: 0; }
.user-dropdown .lang-globe { display: none; }

.theme-switch { display: flex; }

.user-dropdown form { margin: 0; }
.user-dropdown .menu-logout { display: block; }
.user-dropdown .dropdown-item:hover { background: var(--bg-hover); }
.user-dropdown .dropdown-item.danger { color: var(--danger); }
.user-dropdown .dropdown-item.danger:hover { background: var(--danger-tint); }
.user-dropdown .menu-logout .dropdown-item { border-radius: 0 0 var(--radius-lg) var(--radius-lg); }

/* In-flyout settings panel (v4): the Settings row slides the flyout body
   from the main rows to the per-user settings fields (house easing); Back
   returns to the main rows. Same interaction grammar as the drawer. */
.user-dropdown { overflow: hidden; }
.user-dropdown .menu-settings-panel { display: none; }
.user-dropdown[data-view="settings"] .menu-main { display: none; }
.user-dropdown[data-view="settings"] .menu-settings-panel {
  display: block;
  animation: menu-settings-in 200ms var(--ease-drawer);
}
@keyframes menu-settings-in {
  from { opacity: 0; transform: translateX(24px); }
  to { opacity: 1; transform: none; }
}
.menu-settings-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border-subtle);
}
.menu-settings-back {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
}
.menu-settings-back:hover { background: var(--bg-hover); color: var(--text); }
.menu-settings-title {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
  font-weight: 700;
}
.menu-settings-body {
  padding: 12px 14px 14px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-height: 62vh;
  overflow-y: auto;
}
.menu-settings-section { display: flex; flex-direction: column; gap: 6px; }
.menu-settings-section .form-hint { margin: 0; }
.menu-settings .dropdown-item { border-radius: var(--radius-sm); }


.user-dropdown :is(a, button, [data-menu-item]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* The per-user settings page reuses the segmented controls in a wider
   layout (no card constraint). */
.profile-segs { flex-direction: row; flex-wrap: wrap; gap: 24px; }
.profile-segs .menu-seg { max-width: 240px; }
.profile-segs .menu-seg-block { min-width: 200px; }

@media (max-width: 980px) {
  /* The anchored dropdown becomes a near-full-width sheet under the topbar
     (mirrors the notification panel's mobile treatment). */
  .user-dropdown {
    position: fixed;
    top: 56px;
    left: 8px;
    right: 8px;
    width: auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  .user-dropdown { animation: none; }
  .user-chevron { transition: none; }
  .menu-seg > button { transition: none; }
}

/* ---------- panels & layout ---------- */

.panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.panel + .panel { margin-top: 20px; }

.panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}

.panel-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.panel-title {
  font-size: 14px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
}

.count-chip {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-muted);
  background: var(--panel-2);
  border-radius: 999px;
  padding: 1px 8px;
}

.panel-body { padding: 18px; }
.panel-body.flush { padding: 0; }

/* Email template preview: the full branded HTML document (its own background,
   600px content width) is rendered in a sandboxed iframe so its inline styles
   display faithfully without leaking into the admin chrome. */
.email-template-frame {
  display: block;
  width: 100%;
  height: 720px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: #f4f4f5;
}
.email-template-subject {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-muted);
  max-width: 60%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.grid-2 {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 18px;
  align-items: start;
}

/* ---------- stat tiles ---------- */

.stat-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 14px;
  margin-bottom: 22px;
}

.stat-tile {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 16px 18px 14px;
  position: relative;
  overflow: hidden;
  display: block;
  color: var(--text);
  transition: transform 160ms ease, border-color 160ms ease, box-shadow 160ms ease;
}

.stat-tile::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--tile-accent, var(--border-strong));
}

.stat-tile:hover {
  transform: translateY(-2px);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-md);
  color: var(--text);
}

.stat-value {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 2.4rem;
  line-height: 1.05;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.stat-label {
  margin-top: 6px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.tone-success { --tile-accent: var(--success); }
.tone-warning { --tile-accent: var(--warning); }
.tone-danger { --tile-accent: var(--danger); }
.tone-info { --tile-accent: var(--info); }
.tone-brand { --tile-accent: var(--accent); }
.tone-muted { --tile-accent: var(--text-faint); }

/* ---------- dashboard quick actions ---------- */

.quick-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.quick-actions .btn:hover { color: var(--text); }
.quick-actions .btn-primary:hover { color: var(--accent-text); }
.quick-actions .btn-danger:hover { color: var(--danger); }
.quick-actions .btn-success:hover { color: var(--success); }

/* ---------- stats bars ---------- */

.bar-row {
  display: grid;
  grid-template-columns: 110px 1fr 44px;
  align-items: center;
  gap: 12px;
  padding: 5px 0;
  font-size: 13px;
}

.bar-row .bar-label { color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bar-row .bar-count { text-align: right; font-family: var(--font-mono); font-size: 12.5px; }

.bar-track {
  background: var(--bg-inset);
  border-radius: 999px;
  height: 10px;
  overflow: hidden;
}

.bar-fill {
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
  min-width: 2px;
}

.bar-fill.fill-success { background: var(--success); }
.bar-fill.fill-warning { background: var(--warning); }
.bar-fill.fill-danger { background: var(--danger); }
.bar-fill.fill-info { background: var(--info); }
.bar-fill.fill-muted { background: var(--text-faint); }
.fill-success { background: var(--success); }
.fill-warning { background: var(--warning); }
.fill-danger { background: var(--danger); }
.fill-info { background: var(--info); }
.fill-muted { background: var(--text-faint); }

/* ---------- tables ---------- */

.table-wrap { overflow-x: auto; }

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.table th {
  text-align: left;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-faint);
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

.table td {
  padding: 11px 14px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}

.table tbody tr { transition: background 140ms ease; }
.table tbody tr:hover { background: var(--panel-2); }
.table tbody tr:last-child td { border-bottom: 0; }

.table .cell-main { font-weight: 500; }
.table .cell-muted { color: var(--text-muted); }
.table .cell-mono { font-family: var(--font-mono); font-size: 12.5px; }
.table .cell-actions { white-space: nowrap; text-align: right; }
.table .cell-ua { max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

tr.row-flash { animation: row-flash 1.4s ease-out 1; }

@keyframes row-flash {
  0% { background: var(--accent-tint-strong); }
  100% { background: transparent; }
}

.table-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}

.table-toolbar .spacer { flex: 1; }

.toolbar-check {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--text-muted);
  white-space: nowrap;
  cursor: pointer;
}

.field-inline {
  font-size: 12px;
  color: var(--text-muted);
  white-space: nowrap;
}
.export-toolbar { border-top: 1px solid var(--border); }
.export-toolbar .export-label { font-size: 12.5px; color: var(--text-muted); }
.export-toolbar .export-sep { color: var(--text-muted); }
.export-toolbar input[type="date"] { width: auto; }

.cell-check { width: 32px; text-align: center; }
.table th.cell-check, .table td.cell-check { padding-left: 14px; padding-right: 4px; }
.table input[type="checkbox"] { accent-color: var(--accent); width: 15px; height: 15px; cursor: pointer; }

.bulk-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--panel-2);
}
.bulk-bar[hidden] { display: none; }
.bulk-bar [data-bulk-count] { font-size: 12px; color: var(--text-muted); margin-right: auto; }

/* ---------- badges ---------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2.5px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.badge::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

.badge-success { background: var(--success-tint); color: var(--success); }
.badge-warning { background: var(--warning-tint); color: var(--warning); }
.badge-danger { background: var(--danger-tint); color: var(--danger); }
.badge-info { background: var(--info-tint); color: var(--info); }
.badge-neutral { background: var(--neutral-tint); color: var(--text-muted); }

.badge-pulse::before { animation: badge-blink 1.4s ease-in-out infinite; }

@keyframes badge-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.25; }
}

/* ---------- tag chips ---------- */

.tag-chips {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 5px;
}

.tag-chip {
  display: inline-flex;
  align-items: center;
  padding: 1.5px 9px;
  border-radius: 999px;
  background: var(--neutral-tint);
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  text-decoration: none;
}

a.tag-chip:hover {
  color: var(--text);
}

/* ---------- buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 7px 14px;
  border-radius: var(--radius);
  border: 1px solid var(--border-strong);
  background: var(--panel-2);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: background 150ms ease, border-color 150ms ease, transform 150ms ease, box-shadow 150ms ease;
}

.btn:hover { transform: translateY(-1px); box-shadow: var(--shadow-sm); border-color: var(--text-faint); }
.btn:active { transform: translateY(0); }
.btn:disabled { opacity: 0.55; cursor: not-allowed; transform: none; box-shadow: none; }

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-text);
}
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); box-shadow: var(--glow-accent-sm); }
.btn-primary:focus-visible { box-shadow: var(--glow-accent-md); }

/* Language switch + theme toggle float top-right on the full-bleed public
   pages (no topbar). The toggle pairs visually with the lang-switch box. */
.public-lang { position: fixed; top: 14px; right: 16px; z-index: 30; display: flex; align-items: center; gap: 8px; }

.public-lang .theme-toggle { background: var(--panel); border-color: var(--border); }

.btn-danger {
  background: var(--danger-tint);
  border-color: color-mix(in srgb, var(--danger) 45%, transparent);
  color: var(--danger);
}

.btn-danger:hover { background: color-mix(in srgb, var(--danger) 22%, transparent); border-color: var(--danger); }

.btn-success {
  background: var(--success-tint);
  border-color: color-mix(in srgb, var(--success) 45%, transparent);
  color: var(--success);
}

.btn-success:hover { background: color-mix(in srgb, var(--success) 22%, transparent); border-color: var(--success); }

.btn-sm { padding: 4px 10px; font-size: 12px; border-radius: var(--radius-sm); }
.btn-ghost { background: transparent; border-color: transparent; }
.btn-ghost:hover { background: var(--panel-2); border-color: var(--border); }

/* ---------- forms ---------- */

.form-field { display: flex; flex-direction: column; gap: 5px; margin-bottom: 14px; }

.form-field label, .form-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}

.form-field .hint { font-size: 11.5px; color: var(--text-faint); }

/* Consent checkbox on the public register form: label wraps the input so the
   whole line is clickable; the inline link opens the /terms page. */
.form-check label {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  letter-spacing: 0;
  cursor: pointer;
  line-height: 1.45;
}
.form-check input[type="checkbox"] {
  accent-color: var(--accent);
  width: 16px;
  height: 16px;
  margin-top: 2px;
  flex: 0 0 auto;
  cursor: pointer;
}
.form-check a { color: var(--accent); }

.code-block {
  margin: 0.75rem 0 0;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-inset);
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.5;
  overflow-x: auto;
  white-space: pre;
}

.input, .select, input[type="text"], input[type="email"], input[type="password"], input[type="search"], input[type="date"], select, textarea {
  width: 100%;
  padding: 8px 11px;
  border-radius: var(--radius);
  border: 1px solid var(--border-strong);
  background: var(--bg-inset);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 13.5px;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}

.input:focus, .select:focus, input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--focus-ring);
}

.input.mono, input.mono { font-family: var(--font-mono); font-size: 12.5px; }

select { appearance: auto; }

.form-error {
  font-size: 12px;
  color: var(--danger);
  display: flex;
  align-items: center;
  gap: 5px;
}

.domain-hint { font-size: 12px; display: flex; align-items: center; gap: 5px; }
.domain-hint[hidden] { display: none; }
.domain-hint[data-state="ok"] { color: var(--success); }
.domain-hint[data-state="bad"] { color: var(--danger); }
.domain-hint[data-state="new"] { color: var(--info); }

.password-meter { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.password-meter-track {
  flex: 1;
  height: 6px;
  border-radius: 3px;
  background: var(--border);
  overflow: hidden;
}
.password-meter-fill { height: 100%; width: 0; border-radius: 3px; transition: width 0.15s ease; }
.password-meter-label { font-size: 11.5px; font-weight: 600; min-width: 44px; text-align: right; }
.password-meter-message { font-size: 11.5px; color: var(--danger); }
.password-meter[data-state="weak"] .password-meter-fill,
.password-meter[data-state="weak"] .password-meter-label { background: var(--danger); color: var(--danger); }
.password-meter[data-state="fair"] .password-meter-fill,
.password-meter[data-state="fair"] .password-meter-label { background: var(--warning); color: var(--warning); }
.password-meter[data-state="good"] .password-meter-fill,
.password-meter[data-state="good"] .password-meter-label { background: var(--info); color: var(--info); }
.password-meter[data-state="strong"] .password-meter-fill,
.password-meter[data-state="strong"] .password-meter-label { background: var(--success); color: var(--success); }
.password-meter[data-state="invalid"] .password-meter-fill,
.password-meter[data-state="invalid"] .password-meter-label { background: var(--danger); color: var(--danger); }


/* Instance Email/SMTP editor (instance flyout): the inline fields wrap
   cleanly without cramping — each field keeps a comfortable minimum width
   and the full-width checkbox row + right-aligned save button sit on their
   own lines at 1280-1440px and below. */
.smtp-form { align-items: flex-end; row-gap: 12px; }
.smtp-form > .form-field { flex: 1 1 180px; min-width: 150px; margin: 0; }
.smtp-form > .form-field input { width: 100%; }
.smtp-form > .btn { align-self: flex-end; flex: none; }
.form-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 14px;
}

.inline-form { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.inline-form .input, .inline-form input { width: auto; flex: 1; min-width: 140px; }
.inline-form input[type="checkbox"] { width: auto; flex: 0 0 auto; min-width: 0; }

.checkbox-group { display: flex; flex-direction: column; gap: 6px; border: 0; padding: 0; margin: 0; }
.checkbox-group legend { font-size: 12px; font-weight: 600; color: var(--text-muted); letter-spacing: 0.02em; padding: 0; margin-bottom: 2px; }
.checkbox-inline { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 500; color: var(--text); margin-right: 12px; }

/* ---------- banners ---------- */

.banner {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 11px 14px;
  border-radius: var(--radius);
  border: 1px solid;
  font-size: 13px;
  margin-bottom: 16px;
  animation: banner-in 220ms ease-out;
}

@keyframes banner-in {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: translateY(0); }
}

.banner svg { flex: none; margin-top: 1px; }

.banner-success { background: var(--success-tint); border-color: color-mix(in srgb, var(--success) 40%, transparent); color: var(--success); }
.banner-error { background: var(--danger-tint); border-color: color-mix(in srgb, var(--danger) 40%, transparent); color: var(--danger); }
.banner-warning { background: var(--warning-tint); border-color: color-mix(in srgb, var(--warning) 40%, transparent); color: var(--warning); }
.banner-info { background: var(--info-tint); border-color: color-mix(in srgb, var(--info) 40%, transparent); color: var(--info); }

.banner-row td { padding: 8px 14px 0 !important; border-bottom: 0 !important; }
.banner-row .banner { margin-bottom: 0; }

.session-toast {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 90;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: 420px;
  padding: 12px 16px;
  border: 1px solid color-mix(in srgb, var(--warning) 45%, transparent);
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow: var(--shadow-md);
  color: var(--text);
  font-size: 13.5px;
}

/* The base rule above sets display:flex, which overrides the UA [hidden]{display:none};
   this higher-specificity rule restores hidden semantics so the empty toast never renders. */
.session-toast[hidden] { display: none; }

.session-toast > svg { color: var(--warning); flex: none; }

.session-toast-action {
  flex: none;
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
}

.session-toast-action:hover { text-decoration: underline; }

.announcement-banner {
  margin: 0;
  border-radius: 0;
  border-width: 0 0 1px;
  justify-content: center;
  text-align: center;
  font-weight: 500;
}

/* Public-page support/contact footer. Rendered only when SUPPORT_EMAIL or
   SUPPORT_URL is configured (see public_base.html). Fixed to the viewport
   bottom so it overlays the full-bleed .public-shell without disturbing its
   grid layout. */
.public-contact {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 5;
  padding: 8px 16px;
  text-align: center;
  font-size: 12.5px;
  color: var(--text-muted);
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(6px);
  border-top: 1px solid var(--border);
}

.public-contact a { color: var(--accent); text-decoration: none; }
.public-contact a:hover { text-decoration: underline; }

/* ---------- 14. Cookie consent (public pages) ----------
   A non-modal bottom strip + a native <dialog> preferences panel, styled on
   the shared tokens so both themes match the public design language. The
   banner is position:fixed (never pushes the form — no layout shift) and is
   revealed by cookie-consent.js only when a fresh decision is needed. */
.consent-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 14px 22px;
  background: color-mix(in srgb, var(--panel) 94%, transparent);
  backdrop-filter: blur(8px);
  border-top: 1px solid var(--border-strong);
  box-shadow: var(--shadow-lg);
  animation: esr-consent-rise 260ms var(--ease-out) both;
}
/* `display:flex` on the banner/dialog overrides the UA [hidden] rule (same
   sharp edge as .banner elsewhere) — restore hidden semantics explicitly. */
.consent-banner[hidden] { display: none; }
.consent-dialog:not([open]) { display: none; }

@keyframes esr-consent-rise {
  from { transform: translateY(12px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

.consent-banner-text { min-width: 0; }
.consent-banner-title { display: block; font-size: 13.5px; font-weight: 600; margin-bottom: 2px; }
.consent-banner-text p { margin: 0; font-size: 12.5px; color: var(--text-muted); max-width: 640px; }

.consent-banner-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.consent-policy-link {
  font-size: 12.5px;
  color: var(--accent);
  text-decoration: none;
  white-space: nowrap;
}
.consent-policy-link:hover { text-decoration: underline; }

/* The persistent "Cookie settings" affordance — a quiet chip bottom-right,
   hidden while the banner is pending a first decision (body.consent-pending,
   toggled by cookie-consent.js) so the two affordances never stack. */
.consent-footer-btn {
  position: fixed;
  right: 14px;
  bottom: 12px;
  z-index: 55;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  font-size: 12px;
  font-family: var(--font-body);
  color: var(--text-muted);
  background: color-mix(in srgb, var(--panel) 90%, transparent);
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  backdrop-filter: blur(6px);
  transition: color 120ms var(--ease-out), border-color 120ms var(--ease-out);
}
.consent-footer-btn:hover { color: var(--text); border-color: var(--border-strong); }
body.consent-pending .consent-footer-btn { display: none; }
/* Keep the chip above the fixed public-contact support line when present. */
body:has(.public-contact) .consent-footer-btn { bottom: 44px; }

/* Preferences dialog — native <dialog>, styled like the other modals
   (accent top border, panel surface, blurred backdrop). */
.consent-dialog {
  border: 1px solid var(--border-strong);
  border-top: 3px solid var(--accent);
  border-radius: var(--radius-lg);
  background: var(--panel);
  color: var(--text);
  width: min(560px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 20px 22px;
  box-shadow: var(--shadow-lg);
}
.consent-dialog-scroll { overflow-y: auto; min-height: 0; padding-right: 4px; }
.consent-dialog::backdrop {
  background: rgba(4, 6, 10, 0.6);
  backdrop-filter: blur(2px);
}
.consent-dialog-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.consent-dialog-head h2 { margin: 0; font-size: 16px; font-weight: 700; letter-spacing: -0.01em; }
.consent-dialog-lead { margin: 8px 0 14px; font-size: 13px; color: var(--text-muted); }

.consent-categories { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.consent-category {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-inset);
  padding: 12px 14px;
}
.consent-category-head { display: flex; align-items: center; gap: 10px; }
.consent-category-name { font-size: 13.5px; font-weight: 600; }
.consent-always { margin-left: auto; }
.consent-toggle { margin-right: 0; }
.consent-category-desc { margin: 6px 0 0; font-size: 12.5px; color: var(--text-muted); }

.consent-policy-note { margin: 14px 0 0; font-size: 12.5px; color: var(--text-faint); }
.consent-policy-note a { color: var(--accent); text-decoration: none; }
.consent-policy-note a:hover { text-decoration: underline; }
/* Inventory of first-party cookies/browser storage (dialog + terms table). */
.consent-inventory { margin: 14px 0 0; font-size: 12.5px; }
.consent-inventory summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--text-muted);
  padding: 4px 0;
}
.consent-inventory summary:hover { color: var(--text); }
.consent-inventory-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 8px;
  font-size: 12.5px;
}
.consent-inventory-table th,
.consent-inventory-table td {
  text-align: left;
  vertical-align: top;
  padding: 8px 10px;
  border-top: 1px solid var(--border);
}
.consent-inventory-table thead th {
  border-top: 0;
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-faint);
}
.consent-inventory-table tbody th { font-weight: 600; white-space: nowrap; }
.consent-inventory-table td { color: var(--text-muted); }

.terms-cookie-list .consent-inventory-table { margin: 10px 0 20px; }

.consent-dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  background: var(--panel);
  flex: none;
}

@media (max-width: 720px) {
  .consent-banner { flex-direction: column; align-items: stretch; gap: 10px; padding: 12px 16px; }
  .consent-banner-actions { justify-content: stretch; }
  .consent-banner-actions .btn { flex: 1 1 auto; }
  body:has(.public-contact) .consent-footer-btn { bottom: 44px; }
}

/* Cookie consent settings panel: category summary list + version row. */
.settings-consent-categories { list-style: none; margin: 6px 0 0; padding: 0; font-size: 12.5px; color: var(--text-muted); }
.settings-consent-categories li { padding: 3px 0; }
.settings-consent-version {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

/* ---------- empty states ---------- */

.empty-state {
  padding: 44px 20px;
  text-align: center;
  color: var(--text-muted);
}

.empty-state .empty-icon {
  width: 44px;
  height: 44px;
  margin: 0 auto 12px;
  border-radius: 50%;
  background: var(--panel-2);
  display: grid;
  place-items: center;
  color: var(--text-faint);
}

.empty-state .empty-title { font-family: var(--font-display); font-weight: 600; color: var(--text); margin-bottom: 4px; }
.empty-state .empty-sub { font-size: 12.5px; max-width: 380px; margin: 0 auto; }

/* ---------- pagination ---------- */

.pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  border-top: 1px solid var(--border);
  font-size: 12.5px;
  color: var(--text-muted);
}

.pagination .pager { display: flex; gap: 6px; }

/* ---------- timeline ---------- */

.timeline { list-style: none; margin: 0; padding: 4px 0; }

.timeline li {
  position: relative;
  padding: 0 0 18px 26px;
}

.timeline li::before {
  content: "";
  position: absolute;
  left: 5px;
  top: 16px;
  bottom: -2px;
  width: 1px;
  background: var(--border-strong);
}

.timeline li:last-child::before { display: none; }

.timeline li::after {
  content: "";
  position: absolute;
  left: 0;
  top: 5px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--panel);
  border: 2px solid var(--accent);
}

.timeline .tl-label { font-weight: 500; }
.timeline .tl-note { color: var(--text-muted); font-size: 12.5px; }
.timeline .tl-time { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-faint); }

/* Timeline marker tones (shared `timeline(events)` macro). */
.timeline li.tl-success::after { border-color: var(--success); }
.timeline li.tl-warning::after { border-color: var(--warning); }
.timeline li.tl-danger::after { border-color: var(--danger); }
.timeline li.tl-info::after { border-color: var(--info); }

/* ---------- audit feed ---------- */

.feed { list-style: none; margin: 0; padding: 0; }

.feed li {
  display: flex;
  gap: 10px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
  font-size: 12.5px;
}

.feed li:last-child { border-bottom: 0; }

.feed .feed-action {
  font-family: var(--font-mono);
  font-size: 11px;
  padding: 1px 7px;
  border-radius: 5px;
  background: var(--panel-2);
  color: var(--text-muted);
  height: fit-content;
  white-space: nowrap;
}

.feed .feed-body { min-width: 0; }
.feed .feed-meta { color: var(--text-faint); font-family: var(--font-mono); font-size: 11px; margin-top: 2px; }

/* Scrollable activity log (shared `activity_log(scrollable=true)` macro). */
.feed-scroll { max-height: 320px; overflow-y: auto; padding-right: 4px; }

/* ---------- app page shell + tab bar (app-consolidation foundation) ----------
   Shared `app_shell` / `app_tabs` macros: a page header over an in-page tab bar
   that switches sub-views of one consolidated app. Reuses page-title/page-sub. */
.app-page { display: flex; flex-direction: column; gap: 16px; }
.app-page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.app-page-actions { display: flex; align-items: center; gap: 8px; flex: none; }

.tab-bar {
  display: flex;
  align-items: center;
  gap: 2px;
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
}
.tab {
  appearance: none;
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  padding: 9px 14px;
  margin-bottom: -1px;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  transition: color 120ms var(--ease-out, ease), border-color 120ms var(--ease-out, ease);
}
.tab:hover { color: var(--text); }
.tab.active { color: var(--text); border-bottom-color: var(--accent); }
.tab:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 4px 4px 0 0; }
/* Tab content wrapper (shared `_app_page.html` shell): a flex child of
   `.app-page`, so min-width:0 keeps wide data-tables from overflowing. */
.app-tab-content { min-width: 0; }

.note-history { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border); }
.note-history-title { font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); margin-bottom: 6px; }
.note-history-value { font-size: 13px; margin-top: 2px; }

/* ---------- settings ---------- */

.settings-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 20px;
  align-items: start;
}

.kv { margin: 0; }

.kv div {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
}

/* Editable settings forms: dense 2-3 column field grid + right-aligned save. */
.settings-form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 14px 18px;
  margin-bottom: 12px;
}
.settings-form-grid .form-field { margin: 0; }
.settings-form-grid .form-field-wide { grid-column: 1 / -1; }
.settings-form label.checkbox-inline { margin: 4px 0; }
.settings-form-actions { display: flex; justify-content: flex-end; margin-top: 12px; }

.kv div:last-child { border-bottom: 0; }
.kv dt { color: var(--text-muted); }
.kv dd { margin: 0; font-family: var(--font-mono); font-size: 12px; text-align: right; word-break: break-all; }

.config-ok { color: var(--success); }
.config-bad { color: var(--danger); }
/* Redesigned settings page: sticky in-page nav on the left, uniformly styled
   section cards in a single content column on the right. */
.settings-layout {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  gap: 20px;
  align-items: start;
}
.settings-nav {
  position: sticky;
  top: 72px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--panel);
}
.settings-nav-title {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 4px 8px 8px;
}
.settings-nav a {
  color: var(--text-muted);
  text-decoration: none;
  font-size: 13px;
  padding: 6px 8px;
  border-radius: 6px;
  border-left: 2px solid transparent;
}
.settings-nav a:hover { color: var(--text); background: var(--bg-hover); }
.settings-content { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.settings-content .panel { margin: 0; }
.settings-content .panel-header { padding: 12px 16px; }
.settings-content .panel-body + .panel-body { border-top: 1px solid var(--border); }

/* Email template manager: card actions row + the toggled editor form. */
.email-template-card .email-template-subject { margin: 0 0 10px; font-size: 12.5px; color: var(--text-muted); word-break: break-word; }
.email-template-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.email-template-inline { margin: 0; }
.email-template-edit-form { display: none; flex-direction: column; gap: 10px; margin-top: 8px; align-items: stretch; }
.email-template-edit-form.open { display: flex; }
.email-template-edit-form .form-field { margin: 0; }
.email-template-edit-form textarea { width: 100%; resize: vertical; min-height: 180px; font-size: 12px; line-height: 1.5; }
.email-template-edit-actions { display: flex; justify-content: flex-end; }

/* ---------- detail page ---------- */

.detail-grid {
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  gap: 18px;
  align-items: start;
}

.detail-fields {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 20px;
}

.detail-field .df-label {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 3px;
}

.detail-field .df-value { font-size: 13.5px; word-break: break-word; }
.detail-field .df-value.mono { font-family: var(--font-mono); font-size: 12.5px; }

.action-bar {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

/* ---------- reject inline form ---------- */

.reject-form {
  display: none;
  gap: 6px;
  margin-top: 6px;
}

.reject-form.open { display: flex; }
.reject-form input { flex: 1; min-width: 120px; }

/* The canned-reason dropdown keeps its natural width; only the free-text
   reason field stretches to fill the reject form. */
.reject-form select.reject-reason-select { flex: 0 0 auto; max-width: 220px; }

/* Domain VFS and API-token rename edit rows reuse .reject-form; the form
   sits alone in its table row, so it needs no top margin (unlike the reject
   form, which follows an inline button). */
.domain-edit-form,
.token-edit-form { margin-top: 0; }

/* The registration detail danger zone: a bordered block holding the
   type-to-confirm delete form. The form reuses .reject-form's show/hide
   toggle; it stacks vertically and the confirm button stays disabled until
   the typed email matches (app.js). */
.danger-zone { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
.delete-form { margin-top: 6px; flex-direction: column; align-items: stretch; gap: 8px; max-width: 520px; }
.delete-form-hint { margin: 0; font-size: 12.5px; color: var(--danger); }
.delete-form label { font-size: 12.5px; color: var(--text-muted); }
.delete-form input[type=text] { flex: none; width: 100%; }
.delete-form .form-check { margin-top: 2px; }
.delete-form .form-check label { display: flex; align-items: flex-start; gap: 8px; color: var(--text); }
.delete-form-actions { display: flex; gap: 6px; }

/* Webhook edit row reuses .reject-form; the URL input and the events
   checkbox group sit side by side and wrap on narrow viewports. */
.webhook-edit-form { margin-top: 0; flex-wrap: wrap; align-items: flex-start; }
.webhook-edit-form > input[type=text] { flex: 1 1 260px; }
.webhook-edit-events { flex: 2 1 320px; flex-direction: row; flex-wrap: wrap; align-items: center; }
.webhook-edit-events legend { flex-basis: 100%; }
.webhook-edit-domains { flex: 1 1 260px; margin-bottom: 0; }

/* Domain notes row also reuses .reject-form; the textarea needs a little
   height and the action buttons sit on their own line beneath it. */
.domain-notes-form { margin-top: 0; flex-direction: column; align-items: stretch; }
.domain-notes-form textarea { width: 100%; resize: vertical; min-height: 64px; }
.domain-notes-actions { display: flex; gap: 6px; }

/* Domain provisioning policy form: a multi-fieldset form with a responsive
   grid of labeled inputs. Each fieldset groups related fields (security,
   quotas, lifecycle, UX) and the grid wraps on narrow screens. */
.domain-policy-form { margin-top: 0; flex-direction: column; align-items: stretch; gap: 12px; }
.policy-fieldset {
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 10px 12px;
  margin: 0;
}
.policy-fieldset legend {
  font-weight: 600;
  font-size: 12.5px;
  color: var(--text-muted);
  padding: 0 6px;
}
.policy-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 10px;
  margin-top: 8px;
}
.policy-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.policy-field--wide { grid-column: 1 / -1; }
.policy-field > span {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
}
.policy-field input[type=text],
.policy-field input[type=number],
.policy-field textarea {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: var(--bg-inset);
  color: var(--text);
  font-size: 13px;
}
.policy-field textarea { resize: vertical; min-height: 48px; }
.policy-field .hint {
  font-size: 11px;
  color: var(--text-faint);
  line-height: 1.3;
}
.policy-field--check {
  flex-direction: row;
  align-items: center;
  gap: 8px;
}
.policy-field--check input[type=checkbox] {
  width: 16px;
  height: 16px;
  cursor: pointer;
}
.policy-field--check > span {
  font-size: 13px;
  font-weight: 400;
  color: var(--text);
  cursor: pointer;
}

/* Domain template edit row reuses .reject-form; the name/group/vfs inputs,
   the notes textarea, and the action buttons wrap across the wide row. */
.domain-template-edit-form { margin-top: 0; flex-wrap: wrap; align-items: flex-start; }
.domain-template-edit-form > input[type=text] { flex: 1 1 180px; }
.domain-template-edit-form > textarea { flex: 1 1 100%; resize: vertical; min-height: 48px; }
/* Domain ownership-verification hint row: a read-only DNS TXT record the
   operator publishes to prove they control the domain. The token itself is
   shown only once (at creation); this standing hint uses a <token> placeholder. */
.domain-verify-hint {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 8px 0;
  font-size: 12.5px;
}
.domain-verify-label { color: var(--text-muted); white-space: nowrap; }
.domain-verify-record {
  padding: 2px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-inset);
  color: var(--text);
  word-break: break-all;
}
/* Domain provisioning preview row: a read-only summary of the three-layer
   CrushFTP model (group template / group root user / per-user VFS) the service
   will create for the domain, resolved from its vfs_base_path + group. Toggled
   via .reject-form (hidden until the Preview button opens it). */
.domain-preview { padding: 8px 0; font-size: 12.5px; }
.domain-preview-title { color: var(--text-muted); margin-bottom: 8px; }
.domain-preview-grid {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 6px 16px;
  margin: 0;
}
.domain-preview-grid dt { color: var(--text-muted); white-space: nowrap; }
.domain-preview-grid dd { margin: 0; }
.domain-preview-grid code {
  padding: 1px 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-inset);
  color: var(--text);
  word-break: break-all;
}

/* Add-organization form: the common case (name + first email domain) stays
   visible; the provisioning defaults collapse into a native disclosure. */
.org-advanced { flex-basis: 100%; border: 0; margin: 0; }
.org-advanced > summary {
  cursor: pointer;
  color: var(--text-muted);
  font-size: 12px;
  user-select: none;
  padding: 2px 0;
}
.org-advanced > summary:hover { color: var(--text); }
.org-advanced-fields {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 8px;
}

/* Organization flyout: child email-domain rows (name / verification /
   created / per-domain actions) + the inline add-domain form. Actions
   refresh the whole flyout body (hx-target [data-flyout-body]). */
.org-domain-rows { display: flex; flex-direction: column; gap: 6px; margin: 0 0 10px; }
.org-domain-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-inset);
}
.org-domain-row .mono { word-break: break-all; }
.org-domain-meta { color: var(--text-muted); font-size: 11.5px; }
.org-domain-actions { display: flex; gap: 4px; margin-left: auto; flex-wrap: wrap; }
.org-domain-add { display: flex; align-items: flex-end; gap: 8px; flex-wrap: wrap; }
.org-domain-add .form-field { margin: 0; flex: 1; min-width: 180px; }
/* Robot / service-account rows in the org flyout: like org-domain rows but
   the name + badges + meta + actions wrap onto two lines, and the inline
   edit/keys/delete forms (.reject-form, div-based) stack their fields. */
.org-domain-row.robot-row { flex-wrap: wrap; }
.robot-edit-row { flex-direction: column; align-items: stretch; }
.robot-edit-row .form-field { width: 100%; }
.robot-edit-row textarea { min-height: 64px; resize: vertical; }
.robot-create-form { margin-top: 10px; }
.robot-create-form form { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
/* Portal service-account cards keep the key material + password blocks legible. */
.robot-card textarea[readonly] { width: 100%; resize: vertical; }
/* Registration list notes cell: a truncated preview (full note in the title
   tooltip) with an inline editor that reuses .reject-form. The editor stacks
   vertically inside the narrow cell; the toggle button sits beside the preview. */
.cell-notes { max-width: 220px; }
.notes-preview { display: inline-block; max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; }
.notes-edit-toggle { margin-left: 4px; }
.notes-edit-form { margin-top: 6px; flex-direction: column; align-items: stretch; }
.notes-edit-form textarea { width: 100%; resize: vertical; min-height: 56px; }
.notes-edit-actions { display: flex; gap: 6px; }

/* ---------- public pages ---------- */

.public-shell {
  min-height: 100vh;
  display: grid;
  grid-template-columns: minmax(340px, 44%) 1fr;
}

.brand-panel {
  position: relative;
  background:
    repeating-linear-gradient(
      -45deg,
      rgba(255, 255, 255, 0.045) 0 2px,
      transparent 2px 14px
    ),
    radial-gradient(circle at 20% 15%, rgba(255, 255, 255, 0.08), transparent 42%),
    linear-gradient(160deg, #e02535 0%, #a81622 55%, #7c0f19 100%);
  color: #fff;
  padding: 56px 52px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.brand-panel::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(255, 255, 255, 0.13) 1px, transparent 1px);
  background-size: 22px 22px;
  mask-image: linear-gradient(200deg, transparent 55%, black 100%);
  pointer-events: none;
}

.brand-panel > * { position: relative; z-index: 1; }

.brand-eyebrow {
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.72);
  font-weight: 600;
}

.brand-title {
  font-family: var(--font-display);
  font-size: clamp(30px, 3.4vw, 44px);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.02em;
  margin: 14px 0 12px;
}

.brand-lead {
  font-size: 15px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.85);
  max-width: 420px;
}

.steps {
  list-style: none;
  margin: auto 0 0;
  padding: 36px 0 0;
  display: flex;
  flex-direction: column;
  gap: 18px;
  counter-reset: step;
}

.steps li {
  counter-increment: step;
  display: flex;
  gap: 14px;
  align-items: flex-start;
  max-width: 420px;
}

.steps li::before {
  content: counter(step, decimal-leading-zero);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: var(--radius-sm);
  padding: 3px 7px;
  flex: none;
  margin-top: 1px;
}

.steps .step-title { font-weight: 600; font-size: 14px; }
.steps .step-sub { color: rgba(255, 255, 255, 0.72); font-size: 12.5px; }

.brand-foot {
  margin-top: 40px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: rgba(255, 255, 255, 0.55);
}

.public-form-side {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px 32px;
  background:
    radial-gradient(circle at 85% 10%, var(--accent-tint), transparent 40%),
    var(--bg);
}

.public-card {
  width: 100%;
  max-width: 480px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-top: 3px solid var(--accent);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: 34px 36px;
}

.public-card h1 {
  font-size: 24px;
  margin-bottom: 6px;
}

.public-card .public-sub { color: var(--text-muted); font-size: 13.5px; margin-bottom: 24px; }

.public-card .btn-primary { width: 100%; padding: 10px; font-size: 14px; margin-top: 6px; }

/* The /terms acceptable-use page: a wider prose card with readable headings. */
.public-card--prose { max-width: 620px; }
.terms-body h2 {
  font-size: 14.5px;
  margin: 20px 0 6px;
  color: var(--text);
}
.terms-body p {
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-muted);
  margin: 0;
}

.public-form-side--column { flex-direction: column; }

/* Anti-spam honeypot: rendered invisibly so real users never see or fill it,
   while naive bots that auto-fill every field trip the server-side check. */
.hp-field {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.public-faq {
  width: 100%;
  max-width: 480px;
  margin-top: 24px;
}

.public-faq-title {
  font-size: 15px;
  margin-bottom: 12px;
}
.inline-terms {
  margin-top: 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--panel);
}

.inline-terms summary {
  padding: 9px 12px;
  font-size: 12.5px;
  cursor: pointer;
  list-style: none;
  user-select: none;
  color: var(--text-faint);
}

.inline-terms summary::before {
  content: "▸ ";
}

.inline-terms[open] summary::before {
  content: "▾ ";
}

.inline-terms-body {
  padding: 0 12px 12px;
  font-size: 12.5px;
  color: var(--text);
}

.inline-terms-body p { margin: 0 0 8px; }

.inline-terms-body a { color: var(--accent); }


.faq-item {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 8px;
  overflow: hidden;
  transition: border-color 150ms ease;
}

.faq-item:hover { border-color: var(--border-strong); }

.faq-item[open] .faq-question { background: var(--panel-2); }

.faq-question {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 13px 16px;
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  list-style: none;
  user-select: none;
}

.faq-question::-webkit-details-marker { display: none; }

.faq-question::after {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  border-right: 2px solid var(--text-muted);
  border-bottom: 2px solid var(--text-muted);
  transform: rotate(45deg);
  transition: transform 150ms ease;
}

.faq-item[open] .faq-question::after { transform: rotate(-135deg); }

.faq-question:hover { color: var(--accent); }

.faq-answer {
  padding: 0 16px 14px;
  color: var(--text-muted);
  font-size: 13px;
  line-height: 1.55;
}

.faq-answer p { margin: 0; }

.result-icon {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  margin-bottom: 18px;
}

.result-icon.success { background: var(--success-tint); color: var(--success); }
.result-icon.info { background: var(--info-tint); color: var(--info); }
.result-icon.warning { background: var(--warning-tint); color: var(--warning); }
.result-icon.danger { background: var(--danger-tint); color: var(--danger); }

/* ---------- login ---------- */

.login-card {
  width: 100%;
  max-width: 400px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-top: 3px solid var(--accent);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: 32px 34px;
}

.login-card h1 { font-size: 24px; margin-bottom: 6px; }

.login-card .public-sub { color: var(--text-muted); font-size: 13.5px; margin-bottom: 24px; }

.login-card .btn-primary { width: 100%; padding: 10px; font-size: 14px; margin-top: 6px; }

/* ---------- instance login (unified XCS login) ---------- */

.login-card .instance-links {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 16px;
  font-size: 13px;
}

.login-card .instance-links a { color: var(--accent); text-decoration: none; }
.login-card .instance-links a:hover { text-decoration: underline; }
.login-card .instance-links-sep { color: var(--text-muted); }

.login-card .instance-switch { margin-top: 14px; text-align: center; font-size: 13px; }
.login-card .instance-switch a { color: var(--accent); text-decoration: none; }
.login-card .instance-switch a:hover { text-decoration: underline; }

.login-card .banner { margin-bottom: 16px; }

/* ---------- AVG (GDPR) acknowledgment notice ----------
   Shared chrome for the verbatim Dutch legal notice (_avg_notice.html):
   the login-card panel and the portal interstitial. Tokens only — theme
   aware, reduced-motion safe. */
.avg-notice {
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  background: var(--bg-inset);
  padding: 14px 16px;
  margin: 14px 0;
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-muted);
}
.avg-notice-title {
  margin: 0 0 8px;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
}
.avg-notice p { margin: 0 0 8px; }
.avg-notice p:last-child { margin-bottom: 0; }
.avg-language-note { margin-top: 10px; }
.avg-confirm-form { margin-top: 14px; }
.avg-decline-hint { margin-top: 10px; color: var(--text-faint); }
/* Portal Home acknowledgment state: the versioned evidence panel shown to
   every signed-in user (confirmation + UTC timestamp + collapsible notice).
   Tokens only — theme aware, reduced-motion safe. */
.avg-ack-details { margin-top: 10px; }
.avg-ack-details summary {
  cursor: pointer;
  color: var(--text-muted);
  font-size: 13px;
}
.avg-ack-details[open] summary { margin-bottom: 4px; }
.avg-panel .panel { max-width: 720px; margin: 0 auto; }

/* ---------- embedded portal panel (login-card portal transform) ----------
   After a successful instance login the card transforms in place into a
   compact self-service portal (the fourth server-rendered panel). The wider
   card carries a greeting + status head, the hero "Open files" action, and
   in-card section tabs sharing the /portal content partials. All tokens are
   theme-agnostic; motion is disabled by the global reduced-motion block. */

.login-card--portal { max-width: 720px; }

.login-card--portal .login-portal { animation: esr-portal-in 420ms var(--ease-out) both; }

@keyframes esr-portal-in {
  from { opacity: 0; transform: translateY(10px) scale(0.985); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.login-portal-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 16px;
}

.login-portal-id { display: flex; align-items: center; gap: 12px; min-width: 0; }

.login-portal-avatar {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: 50%;
  background: var(--accent-tint);
  color: var(--accent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent);
}

.login-portal-id-text { min-width: 0; }

.login-portal-title { font-size: 20px; margin: 0; line-height: 1.25; }

.login-portal-sub { margin: 2px 0 0; font-size: 12.5px; color: var(--text-muted); overflow-wrap: anywhere; }

/* Account status: a compact inline dot + label under the identity line (the
   head's top-right corner now belongs to the sign-out button). */
.login-portal-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 5px;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.login-portal-status .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.login-portal-status--success .dot { animation: dot-pulse 2.2s ease-in-out infinite; }

.login-portal-status--success { color: var(--success); background: var(--success-tint); }
.login-portal-status--danger { color: var(--danger); background: var(--danger-tint); }
.login-portal-status--neutral { color: var(--text-muted); background: var(--neutral-tint, var(--panel-2)); }

.login-portal-logout { margin: 0; flex: none; }

.login-portal-hero {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  border-radius: var(--radius);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  background: linear-gradient(
    135deg,
    color-mix(in srgb, var(--accent) 16%, transparent),
    color-mix(in srgb, var(--accent) 6%, transparent)
  );
  color: var(--text);
  text-decoration: none;
  transition: transform 160ms var(--ease-out), box-shadow 160ms var(--ease-out), border-color 160ms;
}

.login-portal-hero:hover,
.login-portal-hero:focus-visible {
  border-color: var(--accent);
  box-shadow: var(--glow-accent-sm, var(--shadow-md));
  transform: translateY(-1px);
}

.login-portal-hero:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.login-portal-hero-icon {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  flex: none;
  border-radius: var(--radius);
  background: var(--accent);
  color: #fff;
}

.login-portal-hero-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.login-portal-hero-title { font-family: var(--font-display); font-weight: 600; font-size: 15px; }

.login-portal-hero-sub { font-size: 12.5px; color: var(--text-muted); }

.login-portal-hero-arrow { margin-left: auto; flex: none; color: var(--text-muted); }

/* Sticky tab bar: the tabs sit ABOVE the scroll region, so they stay
   pinned while long panes (Account) scroll underneath them. */
.login-portal { display: flex; flex-direction: column; min-height: 0; }

.login-portal-tabs {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 16px 0 0;
  padding: 8px 0 10px;
  border-bottom: 1px solid var(--border);
  background: var(--panel);
}

.login-portal-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 13px;
  border-radius: var(--radius);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
  text-decoration: none;
  transition: color 140ms, background 140ms;
}
.login-portal-tab.is-active { color: var(--accent-text); background: var(--accent); }
.login-portal-tab:hover { color: var(--text); background: var(--panel-2); }

.login-portal-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Unread-count badge on the chat tab. */
.login-portal-tab-badge {
  min-width: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--info);
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}
.login-portal-tab.is-active .login-portal-tab-badge { background: rgba(255, 255, 255, 0.92); color: var(--accent); }

.login-portal-body {
  overflow-y: auto;
  max-height: min(430px, 62vh);
  padding: 14px 6px 4px 2px;
  scrollbar-width: thin;
}

.login-portal-pane { display: flex; flex-direction: column; gap: 14px; animation: esr-pane-in 200ms var(--ease-out) both; }

@keyframes esr-pane-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Compact the shared portal content inside the card. */
.login-portal .panel { margin: 0; }
.login-portal .p-grid-2 { grid-template-columns: 1fr; gap: 14px; }
.login-portal .p-fields { grid-template-columns: 1fr; }
.login-portal .p-status { padding: 12px 14px; }
.login-portal-pane[hidden] { display: none; }

/* ---- chat pane ----
   The chat fills the pane's visible height: header + scrollable message
   list + pinned composer, all on one screen (a real chat app never makes
   you page-scroll past the composer). `.login-portal-body` is the scroll
   region for the OTHER panes; the chat pane matches its height exactly. */
.login-portal-chat { display: flex; flex-direction: column; min-height: 0; height: 430px; max-height: 62vh; }

.login-portal-chat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 8px;
}

.login-portal-chat-title { font-weight: 600; font-size: 13.5px; }

.login-portal-msg-list {
  flex: 1;
  min-height: 120px;
  height: auto;
  max-height: none;
  margin: 0;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--panel-2) 40%, transparent);
}

.login-portal-composer textarea { font-size: 13px; }

.login-portal-composer .msg-composer-hint { font-size: 11px; }

/* Skeleton shimmer while the history loads (messaging.js removes the
   wrapper once the fetch settles). */
.msg-skeleton { list-style: none; display: flex; flex-direction: column; gap: 10px; padding: 4px; }

.msg-skeleton-bubble {
  display: block;
  height: 34px;
  width: 62%;
  border-radius: 12px;
  background: linear-gradient(90deg, var(--panel-2) 25%, color-mix(in srgb, var(--text-muted) 22%, var(--panel-2)) 50%, var(--panel-2) 75%);
  background-size: 300% 100%;
  animation: esr-skeleton 1.2s ease-in-out infinite;
}

.msg-skeleton-bubble--mine { margin-left: auto; }
.msg-skeleton-bubble--short { width: 38%; }

@keyframes esr-skeleton {
  from { background-position: 100% 0; }
  to { background-position: 0 0; }
}

.login-portal-chat-error {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 12px;
  border-radius: var(--radius);
  border: 1px solid var(--danger);
  background: var(--danger-tint);
  color: var(--text);
  font-size: 12.5px;
  margin-bottom: 10px;
}

.login-portal-chat-error[hidden] { display: none; }

.login-portal-chat-error p { margin: 0; }

.login-portal-chat-unavailable { margin: 0; padding: 8px 0; }

.login-portal .msg-new-pill { align-self: center; }

@media (max-width: 640px) {
  .login-card--portal { max-width: 100%; }
  .login-portal-head { flex-wrap: wrap; }
  .login-portal-logout { margin-left: auto; }
  .login-portal-body { max-height: none; overflow: visible; padding-right: 0; }
  .login-portal-tabs { position: static; flex-wrap: nowrap; overflow-x: auto; }
  .login-portal-chat { height: 400px; max-height: 58vh; }
  .login-portal-chat-error { flex-direction: column; align-items: flex-start; }
}

.portal-page--narrow { max-width: 520px; margin: 0 auto; }
.p-loading { display: flex; align-items: center; gap: 10px; color: var(--text-muted); font-size: 14px; }

/* ---------- keyboard shortcuts ---------- */

.shortcuts-hint[aria-expanded="true"] {
  color: var(--accent);
  border-color: var(--accent-tint-strong);
  background: var(--accent-tint);
}

.shortcuts-dialog {
  border: 1px solid var(--border-strong);
  border-top: 3px solid var(--accent);
  border-radius: var(--radius-lg);
  background: var(--panel);
  color: var(--text);
  padding: 0;
  width: min(560px, calc(100vw - 32px));
  box-shadow: var(--shadow-md);
}

.shortcuts-dialog::backdrop {
  background: rgba(4, 6, 10, 0.6);
  backdrop-filter: blur(2px);
}

.shortcuts-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 20px 12px;
  border-bottom: 1px solid var(--border);
}

.shortcuts-head h2 { font-size: 16px; }

.shortcuts-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px 28px;
  padding: 14px 20px 4px;
}

.shortcuts-group {
  font-family: var(--font-mono);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-faint);
  margin: 8px 0 2px;
}

.shortcut-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 5px 0;
  font-size: 13px;
  color: var(--text-muted);
  transition: color 120ms ease;
}

.shortcut-row:hover { color: var(--text); }

.shortcut-keys { display: flex; gap: 4px; flex: none; }

.shortcuts-dialog kbd {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--text-muted);
  border: 1px solid var(--border-strong);
  border-bottom-width: 2px;
  border-radius: 5px;
  padding: 1px 6px;
  background: var(--panel-2);
  white-space: nowrap;
}

.shortcuts-foot {
  margin: 0;
  padding: 12px 20px 16px;
  font-size: 12px;
  color: var(--text-faint);
}

@media (max-width: 560px) {
  .shortcuts-grid { grid-template-columns: 1fr; }
}

/* The per-user settings live in the user menu's IN-FLYOUT settings panel
   (v4) — the old <dialog> modal is gone; only the shared form + feedback
   rules remain. */
.profile-form { padding: 16px 20px 4px; }
.profile-form .form-field { margin-bottom: 12px; }
.profile-form .form-hint { font-size: 11.5px; color: var(--text-faint); margin: 2px 0 0; }
.profile-form .form-actions { display: flex; justify-content: flex-end; padding-bottom: 4px; }

#profile-feedback,
#profile-dialog-feedback { padding: 0 14px 10px; }
#profile-feedback:empty,
#profile-dialog-feedback:empty { display: none; }
#profile-feedback .banner,
#profile-dialog-feedback .banner { margin: 0; }

.dropdown-divider { height: 1px; background: var(--border); margin: 4px 0; }

/* ---------- 8. Dashboard redesign (Radar-style bento) ----------
   Role-tailored bento grids over the shared .panel/.stat-tile chrome.
   Pure CSS motion (entrance stagger, bar fills, hover lift, live pulse),
   all ≤ 400ms and disabled by the global prefers-reduced-motion block. */

.dash-grid {
  display: grid;
  gap: 18px;
  align-items: stretch;
  position: relative;
}
/* (ambient glow removed with the Radar-style hero redesign — flat panels only) */
.dash-grid > * { position: relative; z-index: 1; }
.dash-grid .panel { margin-top: 0; }
/* Cells stretch to their row's height and fill it with the panel card, so a
   short panel reads as a deliberate rectangle (Grafana-style) instead of a
   transparent void. The body grows to absorb the extra height. */
.dash-cell { min-width: 0; display: flex; }
.dash-cell > .panel { flex: 1 1 auto; display: flex; flex-direction: column; width: 100%; }
.dash-cell > .panel > .panel-body { flex: 1 1 auto; }

/* ---------- 8b. Card grid system (house standard) ----------
   Extracted from the dashboard bento above: ONE gap scale (18px desktop,
   14px ≤980px), stretch-aligned card cells (equal-height rows, Grafana-style),
   and one card base. Every card-bearing surface consumes these utilities
   instead of re-declaring its own grid; cards keep the shared .panel chrome. */

.card-grid {
  display: grid;
  gap: 18px;
  align-items: stretch;
}
.card-grid > * { min-width: 0; }
/* Cells stretch to their row's height; the card fills it as a column so a
   short card reads as a deliberate rectangle, never a floating stub. */
.card-grid > .panel,
.card-grid > .card,
.card-grid > article,
.card-grid > a {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.card-grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }
.card-grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); }

@media (max-width: 980px) {
  .card-grid { gap: 14px; }
}

.card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 16px;
  min-width: 0;
}


/* Entrance stagger: cells fade/rise once, delayed by their inline --d. */
.dash-reveal {
  animation: dash-rise 380ms var(--ease-out) both;
  animation-delay: var(--d, 0ms);
}
@keyframes dash-rise {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

/* ---- per-role bento layouts (named areas keep each role's shape distinct) ---- */

.dash-role-admin {
  grid-template-columns: repeat(12, 1fr);
  grid-template-areas:
    "actions actions actions actions actions actions actions actions overview overview overview overview"
    "attention attention attention attention attention attention attention attention activity activity activity activity"
    "reminders reminders reminders reminders reminders reminders recent recent recent recent recent recent"
    "instances instances instances instances instances instances instances status status status status status"
    "messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging";
}
.dash-role-admin > [style*="actions"] { grid-area: actions; }

.dash-role-support {
  grid-template-columns: repeat(12, 1fr);
  grid-template-areas:
    "reminders reminders reminders reminders reminders reminders reminders reminders status status status status"
    "failures failures failures failures failures failures failures failures recent recent recent recent"
    "messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging";
}

.dash-role-manager {
  grid-template-columns: repeat(12, 1fr);
  grid-template-areas:
    "domains domains domains domains domains domains domains domains domains domains domains domains"
    "pending pending pending pending pending pending failures failures failures failures failures failures"
    "recent recent recent recent recent recent recent recent recent recent recent recent"
    "messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging";
}

.dash-role-auditor {
  grid-template-columns: repeat(12, 1fr);
  grid-template-areas:
    "funnel funnel funnel funnel funnel funnel funnel compliance compliance compliance compliance compliance"
    "activity activity activity activity activity activity activity activity exports exports exports exports";
}

@media (max-width: 1180px) {
  .dash-role-admin {
    grid-template-areas:
      "actions actions actions actions actions actions actions actions actions actions actions actions"
      "overview overview overview overview overview overview overview overview overview overview overview overview"
      "attention attention attention attention attention attention attention attention attention attention attention attention"
      "reminders reminders reminders reminders reminders reminders reminders reminders reminders reminders reminders reminders"
      "recent recent recent recent recent recent recent recent recent recent recent recent"
      "instances instances instances instances instances instances instances instances instances instances instances instances"
      "status status status status status status status status status status status status"
      "messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging";
  }
  .dash-role-support {
    grid-template-areas:
      "reminders reminders reminders reminders reminders reminders reminders reminders reminders reminders reminders reminders"
      "failures failures failures failures failures failures failures failures failures failures failures failures"
      "status status status status status status status status status status status status"
      "recent recent recent recent recent recent recent recent recent recent recent recent"
      "messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging";
  }
  .dash-role-auditor {
    grid-template-areas:
      "funnel funnel funnel funnel funnel funnel funnel funnel funnel funnel funnel funnel"
      "compliance compliance compliance compliance compliance compliance compliance compliance compliance compliance compliance compliance"
      "activity activity activity activity activity activity activity activity activity activity activity activity"
      "exports exports exports exports exports exports exports exports exports exports exports exports";
  }
}

@media (max-width: 980px) {
  .dash-grid { gap: 14px; }
  .dash-role-manager {
    grid-template-areas:
      "domains domains domains domains domains domains domains domains domains domains domains domains"
      "pending pending pending pending pending pending pending pending pending pending pending pending"
      "failures failures failures failures failures failures failures failures failures failures failures failures"
      "recent recent recent recent recent recent recent recent recent recent recent recent"
      "messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging";
  }
}

/* ---- stacked status bar + legend ---- */

.dash-statusbar {
  display: flex;
  height: 14px;
  border-radius: 999px;
  overflow: hidden;
  background: var(--bg-inset);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.35);
}
.dash-statusbar-empty { border: 1px dashed var(--border-strong); background: transparent; box-shadow: none; }
.dash-statusbar-seg {
  height: 100%;
  min-width: 6px;
  transform-origin: left center;
  animation: dash-seg 460ms var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 60ms);
  transition: width 400ms var(--ease-out);
}
@keyframes dash-seg { from { transform: scaleX(0); } }
.dash-statusbar-seg + .dash-statusbar-seg { border-left: 1px solid color-mix(in srgb, var(--panel) 70%, transparent); }

.dash-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin-top: 12px;
}
.dash-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--text-muted);
  text-decoration: none;
  padding: 2px 4px;
  border-radius: var(--radius-sm);
  transition: background 140ms var(--ease-out), color 140ms var(--ease-out);
}
.dash-legend-item:hover { background: var(--bg-hover); color: var(--text); }
.dash-legend-count { font-family: var(--font-mono); font-size: 12px; color: var(--text); }

/* ---- 14-day sparkline (CSS bars) ---- */

.dash-spark-block {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
.dash-spark-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 8px;
}
.dash-spark-title {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.dash-spark-total { font-size: 12px; color: var(--text-muted); }
.dash-spark {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 44px;
}
.dash-spark-bar {
  flex: 1 1 0;
  min-width: 2px;
  border-radius: 2px 2px 0 0;
  background: var(--panel-3);
  transition: height 380ms var(--ease-out), background 140ms var(--ease-out);
}

/* ---- portal messaging overview (dashboard + stats share the tokens) ---- */

.dash-msg-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 10px;
}
.dash-msg-tile {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 14px 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.dash-msg-value {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.5rem;
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.dash-msg-label {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.dash-msg-tile.tone-warning {
  border-color: color-mix(in srgb, var(--warning) 45%, var(--border));
}
.dash-msg-tile.tone-warning .dash-msg-value { color: var(--warning); }
.count-chip-warn { background: var(--warning-tint); color: var(--warning); }
.dash-spark-bar.has-count { background: color-mix(in srgb, var(--accent) 62%, var(--panel-3)); }
.dash-spark-bar:hover { background: var(--accent); }

/* ---- compliance funnel ---- */

.dash-funnel { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.dash-funnel-stage {
  display: grid;
  grid-template-columns: 96px 1fr 40px 44px;
  align-items: center;
  gap: 10px;
  font-size: 13px;
}
.dash-funnel-label { color: var(--text-muted); }
.dash-funnel-track {
  height: 12px;
  border-radius: 999px;
  background: var(--bg-inset);
  overflow: hidden;
}
.dash-funnel-fill {
  display: block;
  height: 100%;
  width: var(--w, 0%);
  border-radius: 999px;
  background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 78%, var(--panel-3)), var(--accent));
  animation: dash-grow 400ms var(--ease-out) both;
  animation-delay: var(--d, 0ms);
}
@keyframes dash-grow { from { width: 0; } }
.dash-funnel-count { text-align: right; font-family: var(--font-mono); font-size: 12.5px; }
.dash-funnel-pct { text-align: right; color: var(--text-faint); font-family: var(--font-mono); font-size: 11.5px; }
.dash-funnel-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  font-size: 12.5px;
  color: var(--text-muted);
}
.dash-verify-summary { display: inline-flex; align-items: center; gap: 8px; }
.dash-verify-link { color: var(--warning); text-decoration: none; }
.dash-verify-link:hover { text-decoration: underline; }

/* ---- system health rows ---- */

.dash-health { list-style: none; margin: 0; padding: 0; }
.dash-health li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 0;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
}
.dash-health li:last-child { border-bottom: 0; }
.dash-health-name { flex: 1; color: var(--text-muted); }

/* ---- org-manager domain health cards ---- */

.dash-domain-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
  gap: 12px;
}
.dash-domain-card {
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: 13px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--panel-2);
  color: var(--text);
  text-decoration: none;
  transition: transform 160ms var(--ease-out), border-color 160ms var(--ease-out), box-shadow 160ms var(--ease-out);
}
.dash-domain-card:hover {
  transform: translateY(-2px);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-md);
  color: var(--text);
}
.dash-domain-card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.dash-domain-name { font-weight: 600; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-domain-card-meta { display: flex; flex-wrap: wrap; gap: 6px; }
.dash-domain-card-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  font-size: 12px;
  color: var(--text-muted);
  border-top: 1px solid var(--border);
  padding-top: 8px;
}
.dash-domain-card-stats strong { color: var(--text); font-family: var(--font-mono); font-weight: 500; }
.dash-warn { color: var(--warning); }
.dash-warn strong { color: var(--warning); }
.dash-danger { color: var(--danger); }
.dash-danger strong { color: var(--danger); }

/* ---- instance summary cards ---- */

.dash-instance-cards { display: flex; flex-direction: column; gap: 10px; }
.dash-instance-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 13px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--panel-2);
  color: var(--text);
  text-decoration: none;
  transition: transform 160ms var(--ease-out), border-color 160ms var(--ease-out), box-shadow 160ms var(--ease-out);
}
.dash-instance-card:hover {
  transform: translateY(-2px);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-md);
  color: var(--text);
}
.dash-instance-card > svg { color: var(--text-faint); flex: none; }
.dash-instance-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.dash-instance-name { font-weight: 600; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-instance-group { font-size: 11px; color: var(--text-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-instance-users { text-align: right; flex: none; }
.dash-instance-users strong { display: block; font-family: var(--font-display); font-size: 18px; font-weight: 600; line-height: 1.1; }
.dash-instance-users span { font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-faint); }

/* ---------- responsive ---------- */

@media (max-width: 1180px) {
  .grid-2, .detail-grid { grid-template-columns: 1fr; }
}


/* ---------- onboarding progress page ---------- */

.onboarding-side { align-items: center; }

.onboarding-card {
  position: relative;
  overflow: hidden;
  width: 100%;
  max-width: 560px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-top: 3px solid var(--accent);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: 34px 38px 30px;
}

/* Ambient layered background: a soft radial accent glow plus a fine grid built
   from existing tokens (not aurora blobs or glassmorphism). It fades downward
   so the text below stays clean. */
.onboarding-card::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 90% -12%, var(--accent-tint-strong), transparent 52%);
  pointer-events: none;
}

.onboarding-card::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(color-mix(in srgb, var(--border) 60%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--border) 60%, transparent) 1px, transparent 1px);
  background-size: 30px 30px;
  opacity: 0.3;
  -webkit-mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0.5), transparent 62%);
  mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0.5), transparent 62%);
  pointer-events: none;
}

.onboarding-card > * { position: relative; z-index: 1; }

.onboarding-head { margin-bottom: 26px; }

.onboarding-eyebrow {
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 600;
  margin-bottom: 8px;
}

.onboarding-heading {
  font-size: clamp(24px, 3vw, 30px);
  line-height: 1.12;
  margin-bottom: 10px;
}

.onboarding-lead {
  color: var(--text-muted);
  font-size: 14px;
  line-height: 1.55;
  margin: 0 0 16px;
  max-width: 46ch;
}

.onboarding-meta { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

.onboarding-email {
  font-size: 12.5px;
  color: var(--text-faint);
  background: var(--bg-inset);
  border: 1px solid var(--border);
  padding: 3px 8px;
  border-radius: var(--radius-sm);
}

.onboarding-live {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text-muted);
}

.onboarding-live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--success); }

.onboarding-live[data-state="live"] .onboarding-live-dot { animation: onboarding-pulse 2s ease-in-out infinite; }

.onboarding-live[data-state="done"] .onboarding-live-dot { background: var(--text-faint); animation: none; }

@keyframes onboarding-pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--success) 45%, transparent); }
  50% { box-shadow: 0 0 0 5px transparent; }
}

/* Vertical stepper */
.stepper { list-style: none; margin: 0; padding: 4px 0 0; }

.stepper-step {
  position: relative;
  display: grid;
  grid-template-columns: 34px 1fr;
  gap: 16px;
  padding-bottom: 26px;
}

.stepper-step:last-child { padding-bottom: 4px; }

/* Connecting rail between markers */
.stepper-step::before {
  content: "";
  position: absolute;
  left: 16px;
  top: 36px;
  bottom: -4px;
  width: 2px;
  background: var(--border);
  transition: background 300ms ease;
}

.stepper-step:last-child::before { display: none; }

.stepper-step.is-complete::before { background: color-mix(in srgb, var(--success) 55%, transparent); }

.stepper-marker {
  position: relative;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--bg-inset);
  border: 2px solid var(--border-strong);
  color: var(--text-faint);
  z-index: 1;
  transition: background 300ms ease, border-color 300ms ease, color 300ms ease;
}

.stepper-marker .mk-check,
.stepper-marker .mk-alert { display: none; }

.stepper-marker .mk-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.5;
}

/* Complete: success tint + check */
.stepper-step.is-complete .stepper-marker { background: var(--success-tint); border-color: var(--success); color: var(--success); }
.stepper-step.is-complete .mk-check { display: block; }
.stepper-step.is-complete .mk-dot { display: none; }

/* Active: accent + pulsing dot */
.stepper-step.is-active .stepper-marker { background: var(--accent-tint); border-color: var(--accent); color: var(--accent); }
.stepper-step.is-active .mk-dot { opacity: 1; animation: stepper-pulse 1.6s ease-in-out infinite; }
.stepper-step.is-active .stepper-title { color: var(--accent); }

@keyframes stepper-pulse {
  0%, 100% { box-shadow: 0 0 0 0 var(--accent-tint-strong); transform: scale(1); }
  50% { box-shadow: 0 0 0 6px transparent; transform: scale(1.18); }
}

/* Provisioning step gets a rotating "working" arc while active */
.stepper-step[data-step="provisioning"].is-active .stepper-marker::after {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  border: 2px solid transparent;
  border-top-color: var(--accent);
  animation: stepper-spin 1s linear infinite;
}

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

/* Blocked: danger + alert */
.stepper-step.is-blocked .stepper-marker { background: var(--danger-tint); border-color: var(--danger); color: var(--danger); }
.stepper-step.is-blocked .mk-alert { display: block; }
.stepper-step.is-blocked .mk-dot { display: none; }
.stepper-step.is-blocked .stepper-title { color: var(--danger); }

/* Pending: dimmed */
.stepper-step.is-pending { opacity: 0.55; }
.stepper-step.is-pending .stepper-title { color: var(--text-muted); }

.stepper-body { display: flex; flex-direction: column; gap: 3px; padding-top: 4px; }

.stepper-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 15px;
  color: var(--text);
  transition: color 300ms ease;
}

.stepper-desc { font-size: 13px; color: var(--text-muted); line-height: 1.45; }

.stepper-time { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-faint); margin-top: 2px; }
.stepper-time[hidden] { display: none; }

.onboarding-note { margin-top: 22px; }
.onboarding-note[hidden] { display: none; }

.onboarding-resend {
  margin-top: 22px;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-inset);
}
.onboarding-resend[hidden] { display: none; }
.onboarding-resend-lead { margin: 0 0 12px; font-size: 13.5px; color: var(--text-muted); line-height: 1.5; }
.onboarding-resend-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.onboarding-resend-status { font-size: 12.5px; color: var(--text-faint); }
.onboarding-resend-status[hidden] { display: none; }
.onboarding-resend-status[data-state="success"] { color: var(--success); }
.onboarding-resend-status[data-state="error"] { color: var(--danger); }

.onboarding-success {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  margin-top: 24px;
  padding: 18px;
  border: 1px solid color-mix(in srgb, var(--success) 40%, transparent);
  background: var(--success-tint);
  border-radius: var(--radius-lg);
}

.onboarding-success[hidden] { display: none; }
.onboarding-success .result-icon { flex-shrink: 0; margin: 0; }
.onboarding-success-body h2 { font-size: 16px; color: var(--success); margin-bottom: 6px; }
.onboarding-success-body p { margin: 0; font-size: 13.5px; color: var(--text-muted); line-height: 1.55; }

.onboarding-foot { margin-top: 26px; padding-top: 18px; border-top: 1px solid var(--border); }
.onboarding-foot .hint { margin: 0; color: var(--text-faint); font-size: 12.5px; line-height: 1.5; }

/* Tracking CTA on the register result page */
.onboarding-track-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 18px;
  transition: transform 150ms ease, box-shadow 150ms ease;
}

.onboarding-track-link:hover { transform: translateY(-1px); box-shadow: 0 6px 18px var(--accent-tint-strong); }

/* Copy/share tracking-link button (register result + onboarding pages) */
.copy-link-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 10px;
  transition: transform 150ms ease, box-shadow 150ms ease, background 150ms ease, border-color 150ms ease, color 150ms ease;
}
.copy-link-btn[data-copy-state="copied"] {
  background: var(--success-tint);
  border-color: color-mix(in srgb, var(--success) 45%, transparent);
  color: var(--success);
}

@media (max-width: 640px) {
  .onboarding-card { padding: 26px 22px 24px; }
}

/* ---------- motion prefs ---------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---------- print ---------- */

@media print {
  /* paper-friendly palette regardless of the on-screen theme */
  :root {
    color-scheme: light;
    --bg: #ffffff;
    --bg-inset: #ffffff;
    --panel: #ffffff;
    --panel-2: #ffffff;
    --panel-3: #ffffff;
    --border: #c8ccd2;
    --border-strong: #9aa0a8;
    --text: #000000;
    --text-muted: #3f444c;
    --text-faint: #5b6068;
    --shadow-sm: none;
    --shadow-md: none;
  }

  body { background: #ffffff; font-size: 12px; }
  a { color: inherit; text-decoration: none; }

  /* chrome that never belongs on paper */
  .sidebar,
  .topbar,
  .no-print,
  .action-bar,
  .reject-form,
  .danger-zone,
  #detail-feedback,
  .banner,
  .session-toast,
  #notes-panel form { display: none !important; }

  .app-shell { display: block; min-height: 0; }
  .app-content { max-width: none; padding: 0; }

  .page-head { display: block; margin-bottom: 16px; }
  .page-title { font-size: 20px; }

  /* stack the detail columns; keep panels from splitting across pages */
  .detail-grid { display: block; }
  .panel { border-radius: 0; box-shadow: none; margin-top: 14px; break-inside: avoid; }
  .panel + .panel { margin-top: 14px; }
  .panel-body { padding: 12px 0; }

  .detail-fields { gap: 10px 24px; }
  .feed li, .timeline li { break-inside: avoid; }

  .badge { border: 1px solid var(--border-strong); }
}

/* ---------- end-user portal ---------- */

.portal-shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.portal-topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 28px;
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
}

.portal-brand {
  display: flex;
  align-items: center;
  gap: 10px;
}

.portal-brand-label {
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--text-muted);
  font-size: 14px;
}

.portal-topbar-actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 14px;
}

.portal-user {
  font-size: 13px;
  color: var(--text-muted);
  font-family: var(--font-mono);
}

.portal-logout-form { margin: 0; }

.portal-main {
  width: 100%;
  max-width: 960px;
  margin: 0 auto;
  padding: 32px 28px 64px;
  flex: 1;
}

.portal-home { display: flex; flex-direction: column; gap: 24px; }

.portal-welcome h1 { margin: 0 0 6px; }

.portal-account { padding: 20px 22px; }

.portal-account-status {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 4px 0 16px;
}

.portal-footer {
  width: 100%;
  max-width: 960px;
  margin: 0 auto;
  padding: 18px 24px 30px;
  color: var(--text-muted);
  font-size: 12.5px;
  text-align: center;
  white-space: pre-line;
}

.portal-account-meta { font-size: 12.5px; color: var(--text-muted); }

.portal-sections {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
}

.portal-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.portal-card:hover {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-md);
}

.portal-card-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
}

.portal-card-sub {
  margin: 0;
  font-size: 12.5px;
  color: var(--text-muted);
  flex: 1;
}

/* ---------- portal: nav + pages ---------- */

.portal-brand { text-decoration: none; color: inherit; }

.portal-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 10px 28px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-inset);
  position: sticky;
  top: 49px;
  z-index: 20;
}

.portal-nav-link {
  padding: 6px 14px;
  border-radius: var(--radius);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
  text-decoration: none;
  transition: background 0.12s ease, color 0.12s ease;
}

.portal-nav-link:hover { color: var(--text); background: var(--panel-2); }

.portal-nav-link.is-active {
  color: var(--accent-text);
  background: var(--accent);
}

.portal-page { display: flex; flex-direction: column; gap: 22px; }

.portal-head h1 { margin: 0 0 6px; font-size: 26px; }

.portal-head .public-sub { color: var(--text-muted); font-size: 14px; margin: 0; }

.p-grid-2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 18px;
  align-items: start;
}

.p-panel { margin: 0; }

.p-muted { color: var(--text-muted); font-size: 13px; margin: 0; }

.p-pad { padding: 18px; }

/* status banner */

.p-status {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 16px 20px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  background: var(--panel);
}

.p-status-icon {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: var(--radius);
  flex: none;
}

.p-status-title { font-family: var(--font-display); font-weight: 600; font-size: 15px; margin-bottom: 2px; }
.p-status-sub { margin: 0; font-size: 13px; color: var(--text-muted); }

.p-status--success { border-color: color-mix(in srgb, var(--success) 40%, transparent); background: var(--success-tint); }
.p-status--success .p-status-icon { background: var(--success-tint); color: var(--success); }
.p-status--danger { border-color: color-mix(in srgb, var(--danger) 45%, transparent); background: var(--danger-tint); }
.p-status--danger .p-status-icon { background: var(--danger-tint); color: var(--danger); }
.p-status--neutral .p-status-icon { background: var(--neutral-tint); color: var(--text-muted); }

/* stat cards */

.p-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 14px;
}

.p-stat {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 18px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  background: var(--panel);
  transition: border-color 0.12s ease, box-shadow 0.12s ease, transform 0.12s ease;
}

.p-stat:hover { border-color: var(--border-strong); box-shadow: var(--shadow-md); transform: translateY(-1px); }

.p-stat-icon {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: var(--radius);
  background: var(--neutral-tint);
  color: var(--text-muted);
  flex: none;
}

.p-stat--accent .p-stat-icon { background: var(--accent-tint); color: var(--accent); }

.p-stat-label { font-size: 12px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; }

.p-stat-value {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 22px;
  line-height: 1.2;
  margin-top: 2px;
  word-break: break-word;
}

.p-stat-sub { font-size: 12px; color: var(--text-faint); margin-top: 2px; }

/* progress bars */

.p-usage-row { margin-bottom: 18px; }
.p-usage-row:last-child { margin-bottom: 0; }

.p-usage-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 7px; }
.p-usage-label { font-weight: 500; font-size: 13.5px; }
.p-usage-value { font-family: var(--font-mono); font-size: 12.5px; }
.p-usage-of { color: var(--text-faint); }

.p-progress {
  height: 10px;
  border-radius: 999px;
  background: var(--panel-3);
  overflow: hidden;
}

.p-progress-fill {
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
  transition: width 0.4s ease;
}

.p-progress-fill--warning { background: var(--warning); }
.p-progress-fill--danger { background: var(--danger); }
.p-progress--flat .p-progress-fill { background: var(--neutral-tint); }

.p-usage-pct { font-size: 12px; color: var(--text-muted); margin-top: 6px; }
.p-usage-pct--muted { color: var(--text-faint); }
.p-usage-divider { height: 1px; background: var(--border); margin: 20px 0; }

/* bar chart */

.p-barchart {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 48px;
  padding: 8px 0 4px;
}

.p-barchart-col { display: flex; flex-direction: column; align-items: center; gap: 8px; width: 120px; }
.p-barchart-value { font-family: var(--font-mono); font-size: 12.5px; color: var(--text-muted); }

.p-barchart-track {
  width: 64px;
  height: 140px;
  display: flex;
  align-items: flex-end;
  border-radius: var(--radius) var(--radius) 0 0;
  background: var(--panel-3);
  overflow: hidden;
}

.p-barchart-fill { width: 100%; border-radius: var(--radius) var(--radius) 0 0; transition: height 0.4s ease; min-height: 3px; }
.p-barchart-fill--upload { background: var(--accent); }
.p-barchart-fill--download { background: var(--info); }
.p-barchart-label { font-size: 12.5px; color: var(--text-muted); }

/* field lists */

.p-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px 24px; margin: 0; }
.p-field { display: flex; flex-direction: column; gap: 3px; }
.p-field dt { font-size: 12px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.p-field dd { margin: 0; font-size: 14px; word-break: break-word; }
.p-field dd.mono { font-family: var(--font-mono); font-size: 13px; }

/* callout */

.p-callout {
  display: flex;
  gap: 12px;
  margin-top: 18px;
  padding: 14px 16px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--bg-inset);
}

.p-callout-icon { color: var(--accent); flex: none; padding-top: 1px; }
.p-callout-title { font-weight: 600; font-size: 13.5px; margin-bottom: 3px; }
.p-callout-sub { margin: 0; font-size: 12.5px; color: var(--text-muted); }

/* quick links / help links */

.p-quick-links, .p-help-links { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }

.p-quick-links a, .p-help-links a {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 12px;
  border-radius: var(--radius);
  color: var(--text);
  text-decoration: none;
  font-size: 13.5px;
  transition: background 0.12s ease;
}

.p-quick-links a:hover, .p-help-links a:hover { background: var(--panel-2); }
.p-quick-links svg, .p-help-links svg { color: var(--text-muted); flex: none; }

/* rights list */

.p-rights-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }

.p-right {
  padding: 14px 16px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--bg-inset);
}

.p-right--invisible { opacity: 0.72; }

.p-right-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.p-right-path { display: inline-flex; align-items: center; gap: 8px; font-weight: 500; }
.p-right-path svg { color: var(--accent); }
.p-right-path code { font-size: 13px; }

.p-right-caps {
  list-style: none;
  margin: 12px 0 0;
  padding: 12px 0 0;
  border-top: 1px solid var(--border);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 8px 16px;
}

.p-cap { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--text-muted); }
.p-cap svg { color: var(--success); flex: none; }

/* reports */

.p-report-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 16px; }
.p-report-actions .btn { gap: 8px; }

.p-check-list { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 8px; font-size: 13px; color: var(--text-muted); }

/* faq */

.p-faq { margin: 0; }
.p-faq dt { font-weight: 600; font-size: 13.5px; margin-top: 14px; }
.p-faq dt:first-child { margin-top: 0; }
.p-faq dd { margin: 4px 0 0; font-size: 13px; color: var(--text-muted); }

/* printable report */

.p-report-doc {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--panel);
  padding: 28px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.p-report-doc-head { display: flex; align-items: center; gap: 16px; padding-bottom: 18px; border-bottom: 1px solid var(--border); }
.p-report-doc-title { font-family: var(--font-display); font-weight: 700; font-size: 18px; }
.p-report-doc-sub { font-size: 12.5px; color: var(--text-muted); }
.p-report-block h2 { font-size: 15px; margin-bottom: 12px; }

.portal-head.p-no-print { flex-direction: row; align-items: center; justify-content: space-between; }

@media print {
  .portal-nav { top: 57px; padding: 8px 16px; }
}

/* ---------- 5.1 portal overhaul: dashboard cards, files, badges, mobile ---------- */

.banner-danger { background: var(--danger-tint); border-color: color-mix(in srgb, var(--danger) 45%, transparent); color: var(--danger); }

/* unread badge (nav + quick cards) */
.portal-nav-badge {
  display: inline-grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  margin-left: 7px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--accent);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1;
}
.portal-nav-link.is-active .portal-nav-badge { background: rgba(255, 255, 255, 0.25); }

/* home quick-action cards: grid chrome comes from the shared card-grid
   utilities (portal_home.html renders p-quick-cards card-grid card-grid--3). */
.p-quick-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-height: 44px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--panel);
  text-decoration: none;
  color: var(--text);
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.p-quick-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-md); transform: translateY(-1px); }
.p-quick-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.p-quick-card-icon {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 9px;
  background: var(--accent-tint);
  color: var(--accent);
}
.p-quick-card-title { font-family: var(--font-display); font-weight: 600; font-size: 14px; display: inline-flex; align-items: center; }
.p-quick-card-sub { font-size: 12.5px; color: var(--text-muted); }

/* home recent-uploads mini list */
.p-file-mini-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.p-file-mini {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 6px;
  border-radius: var(--radius);
}
.p-file-mini:hover { background: var(--panel-2); }
.p-file-mini-icon { color: var(--text-muted); flex: none; display: grid; place-items: center; }
.p-file-mini-name { flex: 1; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.p-file-mini-meta { font-size: 11.5px; color: var(--text-faint); flex: none; }

/* connect steps */
.p-connect-steps { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; font-size: 13.5px; }
.p-connect-step-num {
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  margin-right: 8px;
  border-radius: 50%;
  background: var(--accent-tint);
  color: var(--accent-text);
  font-family: var(--font-mono);
  font-size: 11.5px;
  font-weight: 600;
}

/* files table */
.p-files-table svg { color: var(--text-muted); vertical-align: -2px; margin-right: 4px; }
.p-files-table .cell-action { white-space: nowrap; }
.p-files-table .btn { gap: 6px; min-height: 36px; }

/* empty state (files list, messages) */
.p-empty-state { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 34px 18px; text-align: center; }
.p-empty-state-icon {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: var(--accent-tint);
  color: var(--accent);
}
.p-empty-state-title { font-family: var(--font-display); font-weight: 600; font-size: 14.5px; margin: 4px 0 0; }
.p-empty-state-sub { margin: 0; font-size: 13px; color: var(--text-muted); max-width: 460px; }

/* progressive disclosure accordions (account subsections) */
.p-accordion { margin-top: 14px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-inset); }
.p-accordion > summary {
  cursor: pointer;
  list-style: none;
  padding: 11px 14px;
  font-weight: 600;
  font-size: 13.5px;
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.p-accordion > summary::-webkit-details-marker { display: none; }
.p-accordion > summary::before {
  content: "▸";
  color: var(--text-muted);
  transition: transform 0.15s ease;
}
.p-accordion[open] > summary::before { transform: rotate(90deg); }
.p-accordion > summary:hover { background: var(--panel-2); }
.p-accordion > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--radius); }
.p-accordion > form, .p-accordion > p, .p-accordion > table { padding: 4px 14px 14px; }
.p-accordion > table { width: calc(100% - 28px); }
.p-fields--tight { margin-bottom: 6px; }

/* account anchor targets: clear the sticky portal topbar when jumping */
.portal-page .panel[id] { scroll-margin-top: 120px; }

/* panel header action link */
.panel-link { font-size: 12.5px; color: var(--accent-text); text-decoration: none; }
.panel-link:hover { text-decoration: underline; }
.panel-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

/* messages friendlier empty state */
.msg--empty { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 26px 12px; text-align: center; }
.msg-empty-icon { color: var(--text-muted); }
.msg-empty-title { font-weight: 600; font-size: 13.5px; margin: 6px 0 0; color: var(--text); }
.msg-empty-sub { margin: 0; font-size: 12.5px; color: var(--text-muted); max-width: 420px; }

/* mobile-first: cards stack, the files table becomes stacked cards */
@media (max-width: 640px) {
  .portal-main { padding: 18px 14px 40px; }
  .portal-head h1 { font-size: 22px; }
  .p-grid-2 { grid-template-columns: 1fr; }
  .portal-nav { gap: 2px; overflow-x: auto; flex-wrap: nowrap; padding-bottom: 4px; }
  .portal-nav-link { padding: 10px 12px; font-size: 13.5px; white-space: nowrap; }
  .p-quick-cards { grid-template-columns: 1fr; }
  .p-files-table thead { display: none; }
  .p-files-table, .p-files-table tbody, .p-files-table tr, .p-files-table td { display: block; width: 100%; }
  .p-files-table tr {
    padding: 12px 4px;
    border-bottom: 1px solid var(--border-subtle);
  }
  .p-files-table td { border: 0; padding: 3px 4px; }
  .p-files-table td.cell-action { padding-top: 8px; }
  .p-files-table .btn { width: 100%; justify-content: center; min-height: 44px; }
  .p-file-mini-meta { display: none; }
}
/* ---------- 5a. right-side flyout drawer ---------- */

.flyout-scrim {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  z-index: 55;
  opacity: 0;
  transition: opacity 200ms var(--ease-out);
}
.flyout-scrim.open { opacity: 1; }
.flyout-scrim[hidden] { display: none; }

.flyout {
  position: fixed;
  top: var(--topbar-height);
  right: 0;
  height: calc(100% - var(--topbar-height));
  width: min(440px, 92vw);
  max-width: 92vw;
  background: var(--panel);
  border-left: 1px solid var(--border);
  box-shadow: var(--shadow-drawer);
  display: flex;
  flex-direction: column;
  z-index: 60;
  transform: translateX(100%);
  opacity: 0;
  transition: transform 260ms var(--ease-drawer), opacity 260ms var(--ease-drawer),
    width 260ms var(--ease-drawer), height 260ms var(--ease-drawer);
  will-change: transform;
}
.flyout.open { transform: none; opacity: 1; }
.flyout[hidden] { display: none; }

/* Expanded full view: the drawer grows into a near-full-page overlay panel
   (page dims under the existing scrim) with a two-column layout — sections
   on the left, a rail (activity/audit feeds) on the right. Toggled via
   [data-flyout-expand]/[data-flyout-collapse] in app.js; ESC collapses
   first, then closes. */
.flyout--expanded {
  top: calc(var(--topbar-height) + 10px);
  bottom: 10px;
  left: 16px;
  right: 16px;
  width: auto;
  /* The drawer's 92vw cap must not survive the expansion: with it, a wide
     viewport keeps a dead gutter to the right of the panel. */
  max-width: none;
  height: auto;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
}
.flyout--expanded .flyout-inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 380px);
  grid-template-rows: auto minmax(0, 1fr);
}
.flyout--expanded .flyout-head { grid-column: 1 / -1; }
.flyout--expanded .flyout-body {
  overflow-y: auto;
  padding-right: 4px;
}
[data-flyout-rail] { display: none; }
.flyout--expanded [data-flyout-rail] {
  display: block;
  overflow-y: auto;
  min-height: 0;
  border-left: 1px solid var(--border);
  padding: 18px;
}
.flyout-rail-slot { min-height: 0; min-width: 0; }
/* Full-view tab row (Overview / Logs …) — shown only when expanded; in the
   collapsed drawer the panels stack instead. */
[data-flyout-tabs] {
  display: flex;
  gap: 2px;
  border-bottom: 1px solid var(--border);
  padding: 0 18px;
}
[data-flyout-tab] {
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  padding: 9px 12px;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
[data-flyout-tab]:hover { color: var(--text); background: var(--bg-hover); }
[data-flyout-tab].active { color: var(--text); border-bottom-color: var(--accent); }
.flyout-managed {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 9px;
  white-space: nowrap;
}
[data-flyout-back], [data-flyout-copy] { margin-right: 4px; }
.flyout-rail-title {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 8px;
}
/* The expanded header shows a breadcrumb (kind / name) instead of the drawer's
   badge row, plus a collapse affordance instead of the expand one. */
.onboarding-review-actions { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.flyout-breadcrumb {
  display: none;
  align-items: center;
  gap: 8px;
  min-width: 0;
  font-size: 13px;
}
.flyout-breadcrumb .fb-kind {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--text-faint);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.flyout-breadcrumb .fb-sep { color: var(--text-faint); }
.flyout-breadcrumb .fb-name {
  color: var(--text);
  font-weight: 600;
  font-family: var(--font-mono);
  font-size: 12.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.flyout--expanded .flyout-breadcrumb { display: flex; }
.flyout--expanded .flyout-head .flyout-badges { display: none; }
.flyout--expanded [data-flyout-expand] { display: none; }
[data-flyout-collapse] { display: none; }
.flyout--expanded [data-flyout-collapse] { display: inline-flex; }
@media (max-width: 980px) {
  .flyout--expanded { left: 8px; right: 8px; }
  .flyout--expanded .flyout-inner { grid-template-columns: 1fr; }
  .flyout--expanded [data-flyout-rail] { border-left: 0; border-top: 1px solid var(--border); }
}

.flyout-resize { position: absolute; left: 0; top: 0; bottom: 0; width: 6px; cursor: ew-resize; z-index: 2; }
.flyout-resize:hover { background: var(--accent-tint); }

.flyout-inner { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.flyout-head {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 10px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
  flex: none;
}
.flyout-badges { display: flex; align-items: center; gap: 8px; min-width: 0; flex-wrap: wrap; }
.flyout-actions { display: flex; align-items: center; gap: 4px; flex: none; margin-left: auto; }
/* Expanded-only header chrome: the breadcrumb, copy button, managed-by chip
   and header badges render only in the full view; the collapsed drawer keeps
   its single badge row + actions. */
.flyout-head .flyout-badges,
.flyout-back,
.flyout-head [data-flyout-copy],
.flyout-managed { display: none; }
.flyout--expanded .flyout-head .flyout-badges { display: flex; }
.flyout--expanded .flyout-back:not([hidden]) { display: inline-flex; }
.flyout--expanded .flyout-head [data-flyout-copy]:not([hidden]) { display: inline-flex; }
.flyout--expanded .flyout-managed:not([hidden]) { display: inline-flex; }

.flyout-body { padding: 18px; overflow-y: auto; min-height: 0; flex: 1; }
/* Dense information grid for flyout sections: small uppercase dt over the
   value, auto-fitting 2-3 columns depending on drawer width. */
.kv-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 12px 18px;
  margin: 0;
}
.kv-grid > div { min-width: 0; }
.kv-grid dt {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 2px;
}
.kv-grid dd { margin: 0; font-size: 13px; word-break: break-word; }
.kv-grid dd.mono { font-family: var(--font-mono); font-size: 12px; font-variant-numeric: tabular-nums; }
.kv-grid dd .badge { vertical-align: middle; }
/* A full-width cell inside a kv-grid (spanning every column). */

/* ---------- Radar-style command palette ----------
   Opening darkens the page (scrim) and drops a command panel DOWNWARD from
   the topbar's global search control: the panel's top edge is flush with
   the searchbar's top edge, its left edge aligns with the searchbar's left
   edge, and its width equals the searchbar's rendered width. Never a
   centered modal, never a full-width bar, clamped 320–720px for readability.
   Grouped sections: Views, Actions, then live resource results.
   JS (app.js positionPalette) anchors the panel to the live searchbar rect
   on open and resize; the CSS left/width are the static fallback. */
.palette-scrim {
  position: fixed;
  inset: 0;
  background: #00000080;
  z-index: 80;
  backdrop-filter: blur(2px);
}
.palette-scrim[hidden] { display: none; }
.palette {
  position: fixed;
  top: 0;
  left: var(--sidebar-width);
  width: min(720px, calc(100vw - var(--sidebar-width) - 40px));
  min-width: 320px;
  max-height: min(70vh, 620px);
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  z-index: 85;
  overflow: hidden;
}
body.sidebar-collapsed .palette { left: var(--sidebar-rail); width: min(720px, calc(100vw - var(--sidebar-rail) - 40px)); min-width: 320px; }
.palette[hidden] { display: none; }
.palette-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
}
.palette-head svg { color: var(--text-muted); flex: none; }
.palette-head input {
  flex: 1;
  border: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 14px;
  outline: none;
}
.palette-head input::placeholder { color: var(--text-faint); }
.palette-body { overflow-y: auto; padding: 8px; min-height: 0; flex: 1; }
.palette-group { margin-bottom: 10px; }
.palette-group:last-child { margin-bottom: 0; }
.palette-group-title {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-faint);
  padding: 6px 8px 4px;
}
.palette-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 8px;
  border-radius: calc(var(--radius-sm));
  color: var(--text);
  text-decoration: none;
  font-size: 13px;
  cursor: pointer;
}
.palette-item:hover, .palette-item.active { background: var(--bg-hover); }
.palette-item.active { box-shadow: inset 2px 0 0 var(--accent); }
.palette-item svg { color: var(--text-muted); flex: none; }
.palette-item-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.palette-item-type { font-size: 11px; color: var(--text-faint); flex: none; }

/* ---- narrow palette (sidebar-rail width, ~64px) ----
   The icon rail collapses the sidebar to 64px; the palette follows and
   becomes a compact icon + truncated-label list. Everything decorative or
   redundant hides (type chips, kbd hints, group titles) so the rows keep
   one icon + one truncated line and nothing overflows or clips mid-word. */
body.palette-narrow .palette-head { padding: 8px; gap: 6px; }
body.palette-narrow .palette-head input { font-size: 12px; }
body.palette-narrow .palette-head .kbd-chip { display: none; }
body.palette-narrow .palette-body { padding: 4px; }
body.palette-narrow .palette-group-title { display: none; }
body.palette-narrow .palette-item { gap: 4px; padding: 6px 4px; }
/* Live search rows at rail width: the type badge (R/D/U) identifies the
   group, so the uppercase group labels and the wrapping "see all" links
   hide; the label + hint keep their two-line truncated shape. */
body.palette-narrow .palette .search-live-group-label { display: none; }
body.palette-narrow .palette .search-live-more { display: none; }
body.palette-narrow .palette .search-live-item { gap: 4px; padding: 6px 4px; }
body.palette-narrow .palette .search-live-type { width: 16px; height: 16px; font-size: 9px; border-radius: 4px; }
body.palette-narrow .palette-item-type { display: none; }
/* The kbd hint row is decorative; at rail width it would wrap into three
   cramped lines, so drop it entirely (the Esc key still closes). */
body.palette-narrow .palette-foot { display: none; }
/* Live search rows are already icon + label + hint; the hint wraps to a
   second truncated line so the 64px width stays usable (compact two-line
   rows). */
.palette .search-live-text { flex: 1; }
.palette-foot {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 16px;
  padding: 8px 14px;
  border-top: 1px solid var(--border);
  font-size: 11px;
  color: var(--text-faint);
}
.palette-hint { display: inline-flex; align-items: center; gap: 4px; }
.palette-hint kbd {
  font-family: var(--font-mono);
  font-size: 10px;
  padding: 1px 4px;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: var(--bg-inset);
}
body.palette-open { overflow: hidden; }
@media (max-width: 560px) {
  .palette-foot { flex-wrap: wrap; gap: 10px; }
}
.kv-grid > .kv-wide { grid-column: 1 / -1; }

/* Collapsible flyout sections (accordion). */
.flyout-section { border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: 12px; overflow: hidden; }
.flyout-section:last-child { margin-bottom: 0; }
.flyout-section > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 14px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 13px;
  color: var(--text);
  background: var(--panel-2);
  transition: background 140ms var(--ease-out);
}
.flyout-section > summary::-webkit-details-marker { display: none; }
.flyout-section > summary:hover { background: var(--bg-hover); }
.flyout-section > summary::after {
  content: "";
  width: 7px;
  height: 7px;
  border-right: 1.6px solid var(--text-muted);
  border-bottom: 1.6px solid var(--text-muted);
  transform: rotate(45deg);
  transition: transform 160ms var(--ease-out);
  flex: none;
}
.flyout-section[open] > summary::after { transform: rotate(-135deg); }
.flyout-section .sec-body { padding: 14px; }
.flyout-section .sec-body > :first-child { margin-top: 0; }
.flyout-section .sec-body > :last-child { margin-bottom: 0; }

/* ---------- 5b. kebab row-menu ---------- */

.row-menu { position: relative; display: inline-block; }
.row-menu-list {
  display: none;
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  min-width: 184px;
  z-index: 50;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 4px;
  box-shadow: var(--shadow-md);
  max-height: 60vh;
  overflow-y: auto;
}
.row-menu.open .row-menu-list { display: block; }
/* Flip upward when there is not enough room below. app.js sets this while it
   hoists the open list to position:fixed (anchored to the toggle's viewport
   rect, so a scrollable .table-wrap can never clip it); the class also works
   on its own as a pure-CSS fallback. */
.row-menu-list--up {
  top: auto;
  bottom: calc(100% + 4px);
}
.row-menu-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  text-align: left;
  white-space: nowrap;
  padding: 7px 10px;
  border: 0;
  background: transparent;
  color: var(--text);
  border-radius: calc(var(--radius) - 2px);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
  transition: background 140ms var(--ease-out), color 140ms var(--ease-out);
}
.row-menu-item:hover { background: var(--bg-hover); }
.row-menu-item--danger { color: var(--danger); }
.row-menu-item--danger:hover { background: var(--danger-tint); }
.row-menu-item--attention { color: var(--warning); font-weight: 600; }
.row-menu-item--attention:hover { background: var(--warning-tint); }
.row-menu-sep { height: 1px; background: var(--border); margin: 4px 6px; }

/* ---------- 5c. list layout: filter rail + search + data-table ---------- */

.list-layout { display: grid; grid-template-columns: 220px 1fr; gap: 18px; align-items: start; }
.list-main { min-width: 0; }

.filter-rail { position: sticky; top: calc(var(--topbar-height) + 12px); }
.filter-group { margin-bottom: 14px; }
.filter-group > .fg-title {
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-faint);
  padding: 6px 8px;
  font-weight: 600;
}
.filter-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 6px 8px;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  font-size: 13px;
  cursor: pointer;
  text-decoration: none;
  transition: background 140ms var(--ease-out), color 140ms var(--ease-out);
}
.filter-item:hover { background: var(--bg-hover); color: var(--text); }
.filter-item.active { background: var(--accent-tint); color: var(--text); }
.filter-item .fi-count {
  font-family: var(--font-mono);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--text-faint);
  background: var(--bg-hover);
  border-radius: 999px;
  padding: 0 7px;
}
.filter-item.active .fi-count { color: var(--text); }

/* Mobile filter rail: on narrow viewports the desktop filter rail collapses
   into one "Filters" disclosure above the table so the data table sits near
   the top. The page search stays visible above it — it is the primary
   control. Styled at all sizes; the media query only flips `display`. */
.filter-rail-mobile { display: none; margin-bottom: 12px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--panel); }
.filter-rail-mobile > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 9px;
  min-height: 44px;
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  user-select: none;
}
.filter-rail-mobile > summary::-webkit-details-marker { display: none; }
.filter-rail-mobile > summary::before {
  content: "";
  width: 14px;
  height: 14px;
  flex: none;
  background: var(--text-muted);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 3H2l8 9.46V19l4 2v-8.54L22 3z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 3H2l8 9.46V19l4 2v-8.54L22 3z'/%3E%3C/svg%3E") center / contain no-repeat;
}
.filter-rail-mobile > summary::after {
  content: "";
  margin-left: auto;
  width: 7px;
  height: 7px;
  flex: none;
  border-right: 1.5px solid var(--text-muted);
  border-bottom: 1.5px solid var(--text-muted);
  transform: rotate(45deg);
  transition: transform 160ms var(--ease-out);
}
.filter-rail-mobile[open] > summary::after { transform: rotate(-135deg); }
.filter-rail-mobile .frm-chips { display: flex; flex-wrap: wrap; gap: 6px; padding: 2px 14px 14px; }
.filter-rail-mobile .filter-item { border: 1px solid var(--border); }

.list-toolbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.list-tools { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-wrap: wrap; }

.search-bar {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: 1 1 240px;
  max-width: 420px;
  padding: 7px 12px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-muted);
  transition: border-color 140ms var(--ease-out), box-shadow 140ms var(--ease-out);
}
.search-bar:focus-within { border-color: var(--accent); box-shadow: var(--glow-accent-sm); }
.search-bar svg { flex: none; }
.search-bar input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 13px;
  padding: 0;
}
.search-bar input:focus { outline: none; box-shadow: none; }
.search-bar input:focus-visible { outline: none; }
.search-bar input::placeholder { color: var(--text-faint); }

.data-table { width: 100%; border-collapse: collapse; font-size: 13px; }
/* Compact variant (domains list): the table sizes to its content instead of
   stretching edge-to-edge on wide screens; the VFS column stays capped by
   .cell-ellipsis so long paths truncate instead of inflating the width. */
.data-table-compact { width: auto; }
.data-table th {
  text-align: left;
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
  font-weight: 600;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.data-table td { padding: 10px 14px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.data-table tbody tr { transition: background 140ms var(--ease-out); }
.data-table tbody tr:hover { background: var(--panel-2); }
.data-table tbody tr:last-child td { border-bottom: 0; }
/* Whole-row flyout trigger: any table row carrying data-flyout opens the
   drawer on click/Enter (app.js). Interactive children keep their own
   behaviour — the handler ignores clicks that land on them. */
.data-table tbody tr[data-flyout] { cursor: pointer; }
.data-table tbody tr[data-flyout]:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.data-table .cell-main { font-weight: 500; }
.data-table .cell-muted { color: var(--text-muted); }
.data-table .cell-mono { font-family: var(--font-mono); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.data-table .cell-actions { white-space: nowrap; text-align: right; }
.data-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.data-table th.num { text-align: right; }
.data-table .cell-ellipsis { max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Sortable header: a plain link so it works without JS; the active column
   carries an arrow. Server-driven via ?sort=&dir=. */
.sort-link { color: inherit; text-decoration: none; display: inline-flex; align-items: center; gap: 4px; }
.sort-link:hover { color: var(--text); }
.sort-link .sort-arrow { font-size: 9px; opacity: 0.9; }
.sort-link.is-sorted { color: var(--accent-text); }
th.is-sorted { color: var(--text); }

/* ---------- 4. language switch (segmented control) ---------- */

.lang-switch {
  display: inline-flex;
  align-items: center;
  height: var(--topbar-control-height);
  box-sizing: border-box;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--panel);
}
.lang-switch-label { padding: 0 2px 0 8px; font-size: 12px; line-height: 1; color: var(--text-muted); }
.lang-globe {
  flex: none;
  align-self: stretch;
  height: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 9px;
  background: var(--bg-inset);
  color: var(--text-muted);
}
.lang-globe svg { display: block; }
.lang-opt {
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  padding: 0 9px;
  align-self: stretch;
  cursor: pointer;
  transition: background 140ms var(--ease-out), color 140ms var(--ease-out);
}
.lang-opt:hover { background: var(--bg-hover); color: var(--text); }
.lang-opt.active { background: var(--accent-tint); color: var(--accent); }

/* ---------- 5e. status dots + count chips ---------- */

.dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; flex: none; }
.dot-success { background: var(--success); }
.dot-warning { background: var(--warning); }
.dot-danger { background: var(--danger); }
.dot-info { background: var(--info); }
.dot-muted { background: var(--text-faint); }
.dot-pulse { animation: dot-pulse-soft 2.4s ease-in-out infinite; }
@keyframes dot-pulse-soft { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }

.count-chip { font-variant-numeric: tabular-nums; }

/* ---------- 5d. responsive shell: burger + off-canvas sidebar ---------- */

.topbar-burger { display: none; }
.sidebar-scrim {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  z-index: 64;
  opacity: 0;
  transition: opacity 200ms var(--ease-out);
}
.sidebar-scrim.open { opacity: 1; }
.sidebar-scrim[hidden] { display: none; }

/* X mark in the brand lockups (sidebar + portal + public). */
.brand-mark { flex: none; border-radius: 6px; }
.brand-lockup { display: flex; align-items: center; gap: 10px; min-width: 0; }

/* Sidebar collapses to an icon rail at ≤1080px. */
@media (max-width: 1080px) {
  .app-shell { grid-template-columns: var(--sidebar-rail) 1fr; }
  body.sidebar-collapsed .app-shell { grid-template-columns: var(--sidebar-rail) 1fr; }
  .sidebar .brand-logo,
  .sidebar .nav-label,
  .sidebar .nav-count { display: none; }
  .sidebar .nav-group-label { display: none; }
  .sidebar .nav-group { margin-top: 8px; }
  .sidebar-brand { align-items: center; justify-content: center; padding: 0 8px; }
  .sidebar .nav-item { justify-content: center; padding: 10px; }
  .sidebar .nav-item.active::before { left: -6px; }
  #collapse-btn { display: none; }
}


/* ============================================================
   Mobile shell (<=980px) — one coherent model:

   - The six-app sidebar becomes an off-canvas drawer over a scrim
     (burger in the topbar, closes on scrim click / Escape / nav tap,
     >=44px tap targets, full grouped nav + drawer-only extras).
   - The topbar is a SINGLE dense row: [burger] [instance] [search] [menu].
     The language switch, theme toggle, API-docs link, shortcuts hint and
     the session timer move into the drawer / user menu instead of
     wrapping the header into 3-4 rows above the content.
   - Exactly ONE visible search control per screen: list surfaces keep
     their page `.search-bar` (it filters the list) and the topbar's
     global search hides (body.page-list); every other page keeps the
     topbar search.
   - The floating session toast becomes a full-width bottom banner so it
     never overlaps cards/rows at 375px.
   - The filter rail + tag filter + export controls collapse into one
     "Filters" disclosure so the data table sits near the top.
   ============================================================ */
@media (max-width: 980px) {
  /* ---- F1: off-canvas nav drawer ---- */
  .app-shell { grid-template-columns: 1fr; }
  body.sidebar-collapsed .app-shell { grid-template-columns: 1fr; }

  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: min(300px, 84vw);
    height: 100vh;
    height: 100dvh;
    z-index: 70;
    transform: translateX(-100%);
    transition: transform 260ms var(--ease-drawer);
  }
  body.sidebar-open .sidebar { transform: none; box-shadow: var(--shadow-drawer); }
  /* The drawer shows the FULL grouped nav, so restore every label the
     collapsed rail hides, and give items a comfortable 44px tap target. */
  .sidebar .nav-label,
  .sidebar .nav-count { display: inline; }
  .sidebar .nav-group-label { display: block; }
  .sidebar-brand { align-items: center; justify-content: flex-start; padding: 0 16px; }
  .sidebar .brand-logo { display: block; width: 76px; height: auto; }
  .sidebar .nav-item { justify-content: flex-start; padding: 11px 12px; min-height: 44px; }
  .sidebar .nav-item.active::before { left: -10px; }
  .sidebar .nav-group { margin-top: 12px; }
  #collapse-btn { display: none; }
  .drawer-extras {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 12px 10px 14px;
    border-top: 1px solid var(--sidebar-border);
  }
  .drawer-search {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 0 12px;
    height: 44px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    background: var(--bg-inset);
    color: var(--text-faint);
  }
  .drawer-search:focus-within { border-color: var(--accent); background: var(--panel); }
  .drawer-search svg { flex: none; }
  .drawer-search input {
    flex: 1;
    min-width: 0;
    border: 0;
    outline: 0;
    background: transparent;
    color: var(--text);
    font-family: var(--font-body);
    font-size: 13.5px;
    padding: 0;
  }
  .drawer-search input::placeholder { color: var(--text-faint); }
  /* The drawer keeps the search + the labelled API-docs link; language,
     theme and notifications live under the topbar's user card. */
  .drawer-docs {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    color: var(--sidebar-muted);
    font-size: 13px;
    text-decoration: none;
  }
  .drawer-docs:hover { color: #fff; background: var(--bg-hover); }

  /* ---- F3: single-row dense topbar ---- */
  .topbar {
    flex-wrap: nowrap;
    height: var(--topbar-height);
    padding: 0 12px;
    gap: 10px;
  }
  .topbar-burger { display: inline-flex; width: 44px; height: 44px; flex: none; }
  .topbar > .status-dot { display: none; }
  .topbar > .session-timeout { display: none; }
  .topbar-actions { gap: 4px; }
  .topbar-actions > .shortcuts-hint,
  .topbar-actions > a[href="/docs"] { display: none; }
  /* The consolidated user card is the ONLY remaining actions control: it
     collapses to the avatar (+ unread badge); its menu carries the absorbed
     language/theme/notifications/settings controls. */
  .user-btn { padding: 4px 8px 4px 5px; min-height: 44px; }
  .user-btn > .user-btn-name { display: none; }
  .user-btn > .user-chevron { display: none; }

  /* ---- F2: exactly one visible search per screen ----
     List surfaces carry their own page search (the primary control);
     there the topbar's global search hides. Every other page keeps the
     topbar search as its only search affordance. */
  body.page-list .topbar-search { display: none; }
  /* On phones the bar fills its single-row topbar: the desktop 520px cap
     drops so the control keeps growing with the viewport here. */
  .command-search-wrap { flex: 1 1 auto; min-width: 0; max-width: none; }
  .command-search .kbd-chip { display: none; }

  /* The palette drops from the searchbar; the sidebar is off-canvas here,
     so the panel spans the full viewport width. */
  .palette,
  body.sidebar-collapsed .palette { left: 0; width: 100vw; border-radius: 0; }

  /* ---- F4: compact instance selector, full name in the tooltip ---- */
  .instance-selector { padding: 0 8px 0 10px; gap: 6px; min-width: 0; }
  .instance-selector select { max-width: 118px; font-size: 12px; }
  .scope-chip { padding: 0 9px; }
  .scope-chip .mono {
    max-width: 120px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* ---- F5: session toast as a full-width bottom banner ---- */
  .session-toast {
    left: 0;
    right: 0;
    bottom: 0;
    max-width: none;
    border-radius: 0;
    border-left: 0;
    border-right: 0;
    border-bottom: 0;
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
  }

  /* ---- F7: filters + tag filter + export collapse into one disclosure ----
     The disclosure (`.filter-rail-mobile`) carries the status/source chips,
     a mobile copy of the tag filter and the export controls; the desktop
     copies (the toolbar tag input + the standalone export form) hide here
     so each control exists exactly once per viewport. */
  .list-layout { grid-template-columns: 1fr; }
  .filter-rail { display: none; }
  .filter-rail-mobile { display: block; }
  .list-toolbar { gap: 10px; }
  .list-toolbar .search-bar { flex: 1 1 100%; max-width: none; }
  .list-tools { margin-left: 0; flex: 1 1 100%; }
  .list-tools > input[name="tag"] { display: none; }
  .list-main > .export-toolbar { display: none; }
  .bulk-bar { flex-wrap: wrap; }

  /* Mobile filter/export forms inside the disclosure. */
  .mobile-filter-form {
    display: flex;
    align-items: flex-end;
    gap: 8px;
    padding: 0 14px 12px;
  }
  .mobile-filter-field { display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 0; }
  .mobile-filter-field > span { font-size: 11px; font-weight: 600; color: var(--text-muted); }
  .mobile-filter-field > input { width: 100%; }
  .mobile-export-form {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0 14px 14px;
    padding: 12px 0 0;
    border-top: 1px solid var(--border);
    border-bottom: 0;
  }
  .mobile-export-form input[type="date"] { flex: 1 1 130px; min-width: 0; width: auto; }
  .mobile-export-form .export-label { font-size: 12px; color: var(--text-muted); }
  .mobile-export-form .export-sep { color: var(--text-muted); }

  /* ---- layout audit: no horizontal overflow ---- */
  .app-content { padding: 18px 14px 40px; max-width: none; }
  .app-main, .app-content, .app-page, .app-tab-content,
  .panel, .panel-body, .list-main, .table-wrap,
  .grid-2, .detail-grid, .settings-grid { min-width: 0; }
  /* Grid/flex children default to min-width:auto, so a wide unbreakable cell
     (a long email/URL) can push a panel past the viewport — clamp them. */
  .grid-2 > *, .detail-grid > *, .settings-grid > *,
  .stat-tiles > *, .p-stats > * { min-width: 0; }
  .page-title { overflow-wrap: anywhere; }
  .kv div { flex-wrap: wrap; }
  .kv dd { word-break: break-word; }
  .feed li { flex-wrap: wrap; }
  .feed .feed-action { flex: none; }
  .domain-preview-grid { grid-template-columns: 1fr; gap: 2px; }
  .domain-preview-grid dt { white-space: normal; }
  .domain-preview-grid dd { margin-bottom: 8px; }
  .reject-form { flex-wrap: wrap; }
  .reject-form .btn { flex: none; }
  .inline-form > .form-field { flex: 1 1 100%; min-width: 0 !important; }
  .inline-form > .btn { flex: none; align-self: flex-end; }
  .app-page-head { align-items: stretch; }
  .app-page-actions { flex-wrap: wrap; min-width: 0; max-width: 100%; }
  .panel-header { padding: 12px 14px; }
  .panel-body { padding: 14px; }
  .tab { padding: 10px 12px; }
  .pagination { flex-wrap: wrap; }
  .stat-tiles { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; }
  .stat-value { font-size: 1.9rem; }
  .bar-row { grid-template-columns: 88px 1fr 40px; gap: 8px; }
  .data-table .cell-ellipsis { max-width: 150px; }
  .cell-notes { max-width: 150px; }
  .notes-preview { max-width: 110px; }
  .settings-grid { grid-template-columns: 1fr; }
  .settings-layout { grid-template-columns: 1fr; }
  .settings-nav { position: static; flex-direction: row; flex-wrap: wrap; }
  .settings-nav-title { display: none; }
  .detail-grid { grid-template-columns: 1fr; }

  /* Sticky identity column so horizontal table scroll keeps context. */
  .table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .data-table td:first-child,
  .data-table th:first-child { position: sticky; left: 0; background: var(--panel); z-index: 1; }
  .data-table tbody tr:hover td:first-child { background: var(--panel-2); }

  /* Flyout becomes a full-height sheet on phones. */
  .flyout { top: 0; height: 100%; width: 100vw; max-width: 100vw; }

  /* Public pages keep their own stacking (shared with the old 900px block). */
  .public-shell { grid-template-columns: 1fr; }
  /* The form column is a grid item; its default min-width:auto lets a
     wide min-content descendant (the login-card portal tab row) inflate
     the whole page past the viewport on phones. */
  .public-form-side { min-width: 0; }
  .brand-panel { padding: 36px 28px; min-height: 0; }
  .steps { display: none; }
  .brand-foot { display: none; }
  .public-faq { margin-top: 28px; }
}
/* ---------- 9. Dashboard hero (Radar-style, understated) ----------
   The admin dashboard opens with ONE full-width hero panel: identity +
   live status left, three thin ring gauges center, thin utilization bars
   right, then an inline icon-chip row and a compact ghost quick-action
   row. No big-number card grid, no glows; flat panels, 1px borders,
   small-caps labels, tabular numerals. */

.dash-hero {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--panel);
  padding: 22px 24px 14px;
  margin-bottom: 18px;
}
.dash-hero-top {
  display: grid;
  grid-template-columns: minmax(220px, 1.1fr) minmax(340px, 1.2fr) minmax(240px, 1fr);
  gap: 28px;
  align-items: start;
}
.dash-hero-kicker {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.dash-hero-title {
  margin: 6px 0 2px;
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
}
.dash-hero-sub { color: var(--text-muted); font-size: 13px; }
.dash-hero-live {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  font-size: 12px;
  color: var(--text-muted);
}
.dash-hero-refresh {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-faint);
  transition: color 140ms var(--ease-out), border-color 140ms var(--ease-out);
}
.dash-hero-refresh:hover { color: var(--text); border-color: var(--border-strong); }

/* ---- ring gauges (thin SVG donuts) ---- */

.dash-hero-rings {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: flex-start;
  gap: 12px 24px;
}
/* Equal flex basis gives every gauge the same column (equal gaps, same
   baseline); the min-width lets the trio wrap to centered rows on narrow
   viewports instead of squeezing. */
.dash-ring {
  flex: 1 1 0;
  min-width: 96px;
  max-width: 180px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.dash-ring-svg { position: relative; width: 84px; height: 84px; }
.dash-ring-svg svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.dash-ring-track { fill: none; stroke: var(--panel-3); stroke-width: 6; }
.dash-ring-arc {
  fill: none;
  stroke-width: 6;
  stroke-linecap: round;
  transition: stroke-dasharray 400ms var(--ease-out);
}
.dash-ring-arc.tone-success { stroke: var(--success); }
.dash-ring-arc.tone-warning { stroke: var(--warning); }
.dash-ring-arc.tone-danger { stroke: var(--danger); }
.dash-ring-value {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 20px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.dash-ring-label {
  margin-top: 8px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.dash-ring-sub { font-family: var(--font-mono); font-size: 11.5px; }
.dash-ring-sub.tone-success { color: var(--success); }
.dash-ring-sub.tone-warning { color: var(--warning); }
.dash-ring-sub.tone-danger { color: var(--danger); }

/* ---- utilization bars (thin, per status) ---- */

.dash-hero-util { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.dash-hero-util-title {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 2px;
}
.dash-util-row { min-width: 0; }
.dash-util-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 4px;
}
.dash-util-label { font-size: 12px; color: var(--text-muted); }
.dash-util-pct { font-size: 11.5px; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.dash-util-track { height: 5px; border-radius: 999px; background: var(--bg-inset); overflow: hidden; }
.dash-util-fill { display: block; height: 100%; border-radius: 999px; }
.dash-util-row-value .dash-util-head { margin-bottom: 0; }
.dash-util-value {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.dash-util-row .dash-util-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- hero foot: inline icon chips + browse link ---- */

.dash-hero-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
.dash-hero-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 18px; }
.dash-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 2px 4px;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  font-size: 12.5px;
  text-decoration: none;
  transition: background 140ms var(--ease-out), color 140ms var(--ease-out);
}
.dash-chip:hover { background: var(--bg-hover); color: var(--text); }
.dash-chip svg { color: var(--text-faint); flex: none; }
.dash-chip strong {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.dash-chip-attention {
  padding: 4px 10px;
  border: 1px solid color-mix(in srgb, var(--warning) 45%, transparent);
  background: color-mix(in srgb, var(--warning) 12%, transparent);
  color: var(--warning);
}
.dash-chip-attention svg { color: var(--warning); }
.dash-chip-attention strong { color: var(--warning); }
.dash-chip-attention:hover {
  background: color-mix(in srgb, var(--warning) 20%, transparent);
  color: var(--warning);
}
.dash-hero-browse { white-space: nowrap; color: var(--text-muted); font-size: 13px; text-decoration: none; }
.dash-hero-browse:hover { color: var(--text); }

/* ---- quick actions: compact ghost row (no card chrome) ---- */

.dash-hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.dash-quick-label {
  margin-right: 6px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-faint);
}

/* ---- active-issues list (needs attention) ---- */

.dash-issues { list-style: none; margin: 0; padding: 0; }
.dash-issues li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 2px;
  border-bottom: 1px solid var(--border);
}
.dash-issues li:last-child { border-bottom: 0; }
.dash-issues .dot { margin-top: 6px; flex: none; }
.dash-issue-body { flex: 1; min-width: 0; }
.dash-issue-title {
  display: block;
  font-weight: 500;
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Card height discipline: dashboard-card feeds never wrap into tall blocks —
   long audit notes / issue hints clamp to one line with an ellipsis. */
.dash-cell .timeline .tl-note {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dash-cell .timeline .tl-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dash-issue-hint {
  color: var(--text-faint);
  font-size: 12px;
  font-family: var(--font-mono);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dash-issue-age { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-faint); white-space: nowrap; }

/* ---- overview strip: status bar + legend beside the sparkline ---- */

.dash-overview-flex { display: flex; align-items: stretch; gap: 24px; }
.dash-overview-main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 12px;
}
.dash-overview-main .dash-statusbar { height: 8px; }
.dash-overview-flex .dash-spark-block {
  flex: 0 0 220px;
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

/* ---- admin grid areas (hero replaces the quick-actions/overview cells) ---- */

.dash-role-admin {
  grid-template-columns: repeat(12, 1fr);
  grid-template-areas:
    "attention attention attention attention attention attention attention activity activity activity activity activity"
    "reminders reminders reminders reminders reminders reminders recent recent recent recent recent recent"
    "overview overview overview overview overview overview overview overview overview overview overview overview"
    "instances instances instances instances instances instances status status status status status status"
    "messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging";
}

@media (max-width: 1180px) {
  .dash-role-admin {
    grid-template-areas:
      "attention attention attention attention attention attention attention attention attention attention attention attention"
      "activity activity activity activity activity activity activity activity activity activity activity activity"
      "reminders reminders reminders reminders reminders reminders reminders reminders reminders reminders reminders reminders"
      "recent recent recent recent recent recent recent recent recent recent recent recent"
      "overview overview overview overview overview overview overview overview overview overview overview overview"
      "instances instances instances instances instances instances instances instances instances instances instances instances"
      "status status status status status status status status status status status status"
      "messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging messaging";
  }
  .dash-hero-top { grid-template-columns: 1fr 1fr; }
  .dash-hero-util { grid-column: 1 / -1; }
}

@media (max-width: 980px) {
  .dash-hero { padding: 18px 16px 10px; }
  .dash-hero-top { grid-template-columns: 1fr; gap: 20px; }
  .dash-hero-rings { justify-content: flex-start; }
  .dash-hero-foot { flex-direction: column; align-items: flex-start; }
  .dash-overview-flex { flex-direction: column; }
  .dash-overview-flex .dash-spark-block { flex: none; }
}

/* ---------- 10. Observability (Radar-style timeline / logging / metrics / issues) ---------- */

.obs-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 10px; }
.obs-chips-label {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-right: 4px;
}
.obs-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: transparent;
  color: var(--text-muted);
  font-size: 12px;
  text-decoration: none;
  transition: border-color 150ms ease, color 150ms ease, background 150ms ease;
}
.obs-chip:hover { border-color: var(--border-strong); color: var(--text); }
.obs-chip.active { border-color: var(--accent); color: var(--text); background: var(--danger-tint); }
.obs-chip .count-chip { color: var(--text-faint); font-size: 11px; }

/* vertical event stream */
.obs-stream { list-style: none; margin: 6px 0 0; padding: 0; }
.obs-stream li {
  display: grid;
  grid-template-columns: 12px minmax(0, 1fr) auto auto auto;
  align-items: baseline;
  gap: 12px;
  padding: 9px 2px;
  border-bottom: 1px solid var(--border);
}
.obs-stream li:last-child { border-bottom: 0; }
.obs-stream .dot { align-self: center; }
.obs-event-title { font-weight: 500; font-size: 13px; overflow-wrap: anywhere; }
.obs-event-note { color: var(--text-muted); font-size: 12px; overflow-wrap: anywhere; }
.obs-event-entity { color: var(--info); text-decoration: none; }
.obs-event-entity:hover { color: var(--accent); }
.obs-event-actor { color: var(--text-muted); font-size: 12px; }
.obs-event-time { color: var(--text-faint); font-size: 11.5px; white-space: nowrap; }

/* logging */
.obs-log-table td, .obs-log-table th { font-size: 12px; }
.obs-log-table .obs-log-row td { font-family: var(--font-mono); }
.obs-log-table .obs-log-row td.cell-main { font-family: var(--font-sans); }
.obs-log-payload-row td { background: var(--panel-2); padding: 10px 14px; }
.obs-log-payload-label {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 6px;
}
.obs-log-payload-row pre { margin: 0; max-height: 260px; overflow: auto; }

/* metrics */
.obs-cache-note { color: var(--text-faint); font-size: 11.5px; }
.obs-metric-section { min-width: 0; }
.obs-metric-section--platform { border-style: dashed; }
.obs-metric-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 10px;
}
.obs-metric-section-title {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.obs-metric-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border-subtle, #ffffff0a);
}
.obs-metric-row:last-child { border-bottom: 0; }
.obs-metric-label {
  font-size: 12.5px;
  color: var(--text-muted);
  min-width: 0;
}
.obs-metric-def {
  display: block;
  font-size: 11px;
  color: var(--text-faint);
  font-weight: 400;
  letter-spacing: 0;
  margin-top: 1px;
}
.obs-metric-row .obs-metric-value {
  font-size: 16px;
  margin: 0;
  flex-shrink: 0;
}
.obs-metric-spark { margin-top: 8px; color: var(--tile-accent, var(--text-faint)); }
.obs-spark { display: block; width: 100%; height: 26px; }
.obs-scope-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 2px 0 10px;
}
.obs-scope-label {
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.obs-scope-chip {
  font-size: 12px;
  color: var(--text);
  background: var(--bg-hover);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 10px;
}
.obs-window-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-bottom: 16px;
}
.obs-window-bar .fg-title { padding: 6px 8px 6px 0; }
.obs-window-bar .filter-item { padding: 4px 10px; }

.obs-funnel { margin-top: 22px; display: flex; flex-direction: column; gap: 8px; max-width: 640px; }
.obs-funnel-row { display: grid; grid-template-columns: 110px 1fr 48px; align-items: center; gap: 12px; }
.obs-funnel-label { color: var(--text-muted); font-size: 12.5px; }
.obs-funnel-count { text-align: right; font-variant-numeric: tabular-nums; }

/* issues */
.obs-issues-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 14px;
}
.obs-issue {
  border: 1px solid var(--border);
  border-left-width: 3px;
  border-radius: var(--radius);
  background: var(--panel-2);
  padding: 14px 16px;
  min-width: 0;
}
.obs-issue.sev-danger { border-left-color: var(--danger); }
.obs-issue.sev-warning { border-left-color: var(--warning); }
.obs-issue.sev-info { border-left-color: var(--info); }
.obs-issue.sev-success { border-left-color: var(--success); }
.obs-issue-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.obs-issue-title { font-size: 14px; font-weight: 600; margin: 0; flex: 1; min-width: 0; }
.obs-issue-why, .obs-issue-fix { margin: 0 0 6px; font-size: 12.5px; color: var(--text-muted); line-height: 1.5; }
.obs-issue-why strong, .obs-issue-fix strong { color: var(--text); font-weight: 600; }
.obs-issue-items { list-style: none; margin: 8px 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.obs-issue-items a {
  display: inline-block;
  padding: 2px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--panel);
  color: var(--text-muted);
  font-size: 11.5px;
}
.obs-issue-items a:hover { color: var(--info); border-color: var(--border-strong); }
.obs-issue-viewall { font-size: 12px; color: var(--text-muted); text-decoration: none; }
.obs-issue-viewall:hover { color: var(--text); }

.obs-all-clear {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 42px 20px;
  text-align: center;
}
.obs-all-clear h2 { margin: 0; font-size: 16px; color: var(--success); }
.obs-all-clear p { margin: 0; max-width: 460px; color: var(--text-muted); font-size: 13px; line-height: 1.55; }

/* checks inventory (comprehensive subsystem view above the issue groups) */
.obs-checks-table th, .obs-checks-table td { font-size: 12px; }
.obs-checks-table .obs-check-status-col { width: 22px; padding-right: 0; }
.obs-check .dot { vertical-align: middle; }
.obs-check-title { font-weight: 500; font-size: 12.5px; color: var(--text); text-decoration: none; }
a.obs-check-title:hover { color: var(--info); }
.obs-check-scope { margin-left: 8px; color: var(--text-muted); font-size: 11.5px; }
.obs-check-detail { color: var(--text-muted); }
.obs-check-time { color: var(--text-faint); font-size: 11.5px; white-space: nowrap; }
.obs-checks-note { margin: 10px 0 0; color: var(--text-faint); font-size: 11.5px; }

@media (max-width: 980px) {
  .obs-stream li { grid-template-columns: 12px minmax(0, 1fr); }
  .obs-event-entity, .obs-event-actor, .obs-event-time { grid-column: 2; }
  .obs-funnel-row { grid-template-columns: 90px 1fr 44px; }
}

/* ---------- 11. Radar resources-page list anatomy ----------
   The standard list-page look (registrations / organizations / users and the
   secondary list surfaces): no card chrome around the table, a flat page
   header, a Radar toolbar (search + view controls + live auto-update chip),
   an icon filter rail with count/warning badges, and a dense sortable table
   with status pills, mono identifiers, utilization bars and compact ages.
   Scoped under body.page-list / .radar-* classes so other surfaces are
   untouched. */

/* Flat page header (title left, actions right) — replaces the app shell. */
.radar-page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 14px; }
.radar-page-head .page-title { font-size: 20px; }
.radar-page-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* List surfaces drop the card chrome: the table sits directly on the page
   background with hairline separators, like Radar's resources tables. */
body.page-list .panel { background: transparent; border: 0; box-shadow: none; border-radius: 0; }
body.page-list .panel + .panel { margin-top: 24px; }
body.page-list .panel-header { padding: 0 0 10px; border-bottom: 1px solid var(--border); }
body.page-list .panel-body { padding: 0; }
body.page-list .list-layout { gap: 22px; }

/* Filter rail: Radar-style items = icon + label + count badge + warn badge. */
.filter-item .fi-icon { display: inline-flex; flex: none; color: var(--text-faint); }
.filter-item.active .fi-icon { color: var(--accent-text); }
.filter-item .fi-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.filter-item .fi-warn {
  font-family: var(--font-mono);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--danger);
  background: var(--danger-tint);
  border-radius: 999px;
  padding: 0 7px;
}

/* Radar toolbar: search left, view controls + live chip right. */
.radar-toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.radar-toolbar .search-bar {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: 1 1 260px;
  max-width: 460px;
  padding: 6px 10px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-muted);
  transition: border-color 140ms var(--ease-out), box-shadow 140ms var(--ease-out), max-width 200ms var(--ease-out);
}
.radar-toolbar .search-bar:focus-within { border-color: var(--accent); box-shadow: var(--glow-accent-sm); }
.radar-toolbar .search-bar input { flex: 1; min-width: 0; border: 0; background: transparent; color: var(--text); font: inherit; font-size: 13px; padding: 0; }
.radar-toolbar .search-bar input:focus, .radar-toolbar .search-bar input:focus-visible { outline: none; box-shadow: none; }
.radar-toolbar .search-bar input::placeholder { color: var(--text-faint); }
.radar-toolbar .search-bar .radar-search-expand { opacity: 0.65; }
.radar-toolbar .search-bar .radar-search-expand:hover { opacity: 1; }
.radar-toolbar .search-bar.radar-search--wide { max-width: 720px; }
.radar-tools { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-wrap: wrap; }
/* Users surface chrome: instance tabs (directory folded in) + the cache
   meta row ("data as of" stamp, refreshing chip, manual refresh). */
.users-instance-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.users-instance-tab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-muted);
  background: var(--panel);
  font-size: 12.5px;
  text-decoration: none;
  transition: border-color 140ms var(--ease-out), color 140ms var(--ease-out), background 140ms var(--ease-out);
}
.users-instance-tab:hover { border-color: var(--border-emphasis); color: var(--text); }
.users-instance-tab.active {
  border-color: var(--accent);
  color: var(--text);
  background: color-mix(in srgb, var(--accent) 12%, var(--panel));
}
.users-instance-tab .count-chip { margin-left: 0; }
.users-cache-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 10px;
  font-size: 12px;
}
.users-cache-meta .users-refreshing { display: inline-flex; align-items: center; gap: 6px; }
.users-refresh-form { display: inline-flex; margin-left: auto; }

/* View toggle (table/grid) segmented pair. */
.radar-view-toggle { display: inline-flex; align-items: center; gap: 2px; padding: 2px; background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.radar-view-btn { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 24px; border: 0; border-radius: 4px; background: transparent; color: var(--text-faint); cursor: pointer; transition: background 140ms var(--ease-out), color 140ms var(--ease-out); }
.radar-view-btn:hover { color: var(--text); }
.radar-view-btn.active { background: var(--bg-active); color: var(--text); }

/* Live auto-updating indicator: green dot, pulses on each refresh tick. */
.radar-live { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--success); white-space: nowrap; }
.radar-live-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--success); box-shadow: 0 0 0 0 var(--success-tint); }
.radar-live.is-pulsing .radar-live-dot { animation: radar-live-pulse 900ms var(--ease-out); }
@keyframes radar-live-pulse {
  0% { box-shadow: 0 0 0 0 rgba(63, 178, 127, 0.5); }
  100% { box-shadow: 0 0 0 9px rgba(63, 178, 127, 0); }
}
@media (prefers-reduced-motion: reduce) { .radar-live.is-pulsing .radar-live-dot { animation: none; } }

/* Dense table: ~48px rows, hairline separators, tighter header. */
body.page-list .data-table { font-size: 12.5px; }
body.page-list .data-table th { padding: 8px 12px; font-size: 10px; }
body.page-list .data-table tbody tr[data-flyout] td { padding: 8px 12px; height: 48px; }
body.page-list .data-table tbody tr:not([data-flyout]) td { height: auto; padding-top: 0; }
body.page-list .data-table tbody tr:hover { background: var(--bg-hover); }
body.page-list .data-table .cell-mono { font-size: 12px; }

/* Status pills (Radar): dot + label, toned, no box. */
.pill { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 500; white-space: nowrap; }
.pill-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.pill-success { color: var(--success); } .pill-success .pill-dot { background: var(--success); }
.pill-warning { color: var(--warning); } .pill-warning .pill-dot { background: var(--warning); }
.pill-danger { color: var(--danger); } .pill-danger .pill-dot { background: var(--danger); }
.pill-info { color: var(--info); } .pill-info .pill-dot { background: var(--info); }
.pill-neutral { color: var(--text-muted); } .pill-neutral .pill-dot { background: var(--text-faint); }
.pill-pulse .pill-dot { animation: pill-pulse 1.6s ease-in-out infinite; }
@keyframes pill-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) { .pill-pulse .pill-dot { animation: none; } }

/* Compact inline-flex cell (tags count etc.). Lists never render
   horizontal utilization bars — keep rows dense. */
.util-cell { display: inline-flex; align-items: center; gap: 8px; }

/* Numeric emphasis (restarts-style): amber when non-zero. */
.num-warn { color: var(--warning); font-weight: 600; }

/* Grid view: the dense table reflows into cards. */
body.page-list .radar-list[data-view="grid"] .table-wrap { overflow: visible; }
body.page-list .radar-list[data-view="grid"] .data-table thead { display: none; }
body.page-list .radar-list[data-view="grid"] .data-table,
body.page-list .radar-list[data-view="grid"] .data-table tbody { display: block; }
body.page-list .radar-list[data-view="grid"] .data-table tbody { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px; }
body.page-list .radar-list[data-view="grid"] .data-table tr[data-flyout] {
  display: flex; flex-direction: column; gap: 6px;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--panel); padding: 12px 14px;
}
body.page-list .radar-list[data-view="grid"] .data-table tr[data-flyout] td { display: flex; align-items: center; gap: 8px; border: 0; padding: 2px 0; height: auto; }
body.page-list .radar-list[data-view="grid"] .data-table tr[data-flyout] td.cell-main { font-size: 13px; }
body.page-list .radar-list[data-view="grid"] .data-table .reject-row,
body.page-list .radar-list[data-view="grid"] .data-table .domain-edit-row,
body.page-list .radar-list[data-view="grid"] .data-table .domain-verify-row,
body.page-list .radar-list[data-view="grid"] .data-table .domain-preview-row { display: none; }

@media (max-width: 980px) {
  .radar-page-head { margin-bottom: 10px; }
  .radar-toolbar { gap: 8px; }
  .radar-toolbar .search-bar { max-width: none; }
  body.page-list .data-table td { height: auto; }
}

/* Dense-list refinements: keep chips inline and rows ~48-54px on wide and
   1280px viewports (the table must not wrap its inline controls). */
body.page-list .tag-chips { display: inline-flex; flex-wrap: nowrap; gap: 4px; vertical-align: middle; max-width: 140px; overflow: hidden; }
body.page-list .tag-chip { white-space: nowrap; }
body.page-list .cell-notes { max-width: 170px; }
body.page-list .notes-preview { max-width: 96px; }
body.page-list .notes-edit-toggle { margin-left: 2px; padding: 2px 6px; font-size: 11px; }
body.page-list .data-table td.cell-main .cell-muted { font-size: 11.5px; }
body.page-list .util-cell { gap: 6px; }
body.page-list .radar-toolbar .search-bar { flex: 0 1 420px; }
body.page-list .export-toolbar { margin-bottom: 10px; }
@media (max-width: 1440px) {
  body.page-list .data-table td { padding: 8px 10px; }
  body.page-list .data-table th { padding: 8px 10px; }
  body.page-list .cell-notes { max-width: 130px; }
  body.page-list .notes-preview { max-width: 70px; }
  body.page-list .tag-chips { max-width: 110px; }
}

/* Radar dense tables: the inline expand rows (reject / edit / notes / policy /
   verify / preview) collapse to zero height until their toggle opens them, so
   the table reads as one continuous dense list. Scoped to the list panels. */
#registrations-panel tr.reject-row,
#domains-panel tr.domain-edit-row,
#domains-panel tr.domain-verify-row { display: none; }
#registrations-panel tr.reject-row:has(.reject-form.open),
#domains-panel tr.domain-edit-row:has(.reject-form.open),
#domains-panel tr.domain-verify-row.open { display: table-row; }

/* 1280-1440px: trim secondary columns so the row kebab stays visible without
   horizontal scrolling (the trimmed data remains in the rail / flyout). */
@media (max-width: 1440px) {
  #registrations-panel .data-table thead th:nth-child(7),
  #registrations-panel .data-table tr[data-flyout] > td:nth-child(7),
  #registrations-panel .data-table thead th:nth-child(9),
  #registrations-panel .data-table tr[data-flyout] > td:nth-child(9) { display: none; }
  #domains-panel .data-table thead th:nth-child(5),
  #domains-panel .data-table tr[data-flyout] > td:nth-child(5),
  #domains-panel .data-table thead th:nth-child(8),
  #domains-panel .data-table tr[data-flyout] > td:nth-child(8) { display: none; }
}

/* ---------- 12. Messaging (portal ↔ admin threads, chat-style redesign) ---------- */
.msg-layout {
  display: grid;
  grid-template-columns: minmax(280px, 360px) 1fr;
  gap: 16px;
  align-items: stretch;
}
@media (max-width: 980px) {
  .msg-layout { grid-template-columns: 1fr; }
}
.msg-thread-list { display: flex; flex-direction: column; max-height: calc(100vh - 190px); min-height: 420px; overflow: hidden; }
.msg-search { padding: 10px 12px 4px; border-bottom: 1px solid var(--border-subtle); }
.msg-search input { width: 100%; }
.msg-thread-scroll { overflow-y: auto; flex: 1; }
.msg-thread-items { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.msg-thread-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 12px;
  border-radius: 8px;
  border: 1px solid transparent;
  color: var(--text);
  text-decoration: none;
  transition: background 120ms var(--ease-out);
}
.msg-thread-item:hover { background: var(--bg-hover); }
.msg-thread-item.is-active { background: var(--bg-active); border-color: var(--border-subtle); }
.msg-thread-avatar {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-muted);
  background: var(--panel-2);
  border: 1px solid var(--border-subtle);
}
.msg-thread-avatar-lg { width: 36px; height: 36px; font-size: 14px; }
.msg-thread-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.msg-thread-topline { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.msg-thread-name { font-size: 12.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msg-thread-org { font-size: 11px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msg-thread-preview { font-size: 12px; color: var(--text-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msg-preview-you { color: var(--text-muted); }
.msg-thread-age { font-size: 10.5px; color: var(--text-faint); flex: 0 0 auto; }
.msg-thread-empty { padding: 12px; color: var(--text-faint); font-size: 13px; }
.msg-thread-item.has-unread .msg-thread-name { color: var(--text); }
.msg-thread-item.has-unread .msg-thread-preview { color: var(--text-muted); font-weight: 500; }
.msg-unread-chip {
  flex: 0 0 auto;
  align-self: center;
  min-width: 18px;
  padding: 1px 6px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 700;
  text-align: center;
  color: var(--info);
  background: var(--info-tint);
}
.msg-thread-item.has-unread .msg-thread-avatar { border-color: color-mix(in srgb, var(--info) 45%, var(--border-subtle)); }
.msg-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 12px;
  border-top: 1px solid var(--border-subtle);
}
.msg-thread-header { gap: 10px; align-items: center; }
.msg-thread-identity { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.msg-live-chip { margin-left: auto; flex: 0 0 auto; }
.msg-panel-body { display: flex; flex-direction: column; position: relative; }
.msg-list {
  list-style: none;
  margin: 0 0 12px;
  padding: 6px 4px;
  height: 440px;
  max-height: 60vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.msg { display: flex; max-width: 78%; }
.msg--mine { align-self: flex-end; justify-content: flex-end; }
.msg--theirs { align-self: flex-start; }
/* Legacy side classes (old server renders / tests) keep the same alignment:
   the portal user's messages sit left in the admin view and right in the
   portal view, so the templates drive the real classes; these stay for the
   dashboard-era markup. */
.msg--portal { align-self: flex-start; }
.msg--admin { align-self: flex-end; }
.msg-bubble {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.msg--mine .msg-bubble { align-items: flex-end; }
.msg-body {
  padding: 8px 12px;
  border-radius: 12px;
  font-size: 13.5px;
  line-height: 1.45;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  max-width: 100%;
}
.msg--theirs .msg-body {
  background: var(--panel-2);
  border: 1px solid var(--border-subtle);
  border-bottom-left-radius: 4px;
}
.msg--mine .msg-body {
  background: color-mix(in srgb, var(--accent) 16%, var(--panel-2));
  border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--border-subtle));
  border-bottom-right-radius: 4px;
}
.msg-meta { display: flex; align-items: center; gap: 8px; font-size: 10.5px; color: var(--text-faint); flex-wrap: wrap; }
.msg--mine .msg-meta { justify-content: flex-end; }
.msg-meta .msg-sender { color: var(--text-muted); font-weight: 600; letter-spacing: 0.02em; }
.msg-day-sep { align-self: center; list-style: none; display: flex; }
.msg-day-sep span {
  font-size: 10.5px;
  color: var(--text-faint);
  background: var(--panel-2);
  border: 1px solid var(--border-subtle);
  border-radius: 999px;
  padding: 2px 10px;
}
.msg-new-pill {
  position: sticky;
  bottom: 8px;
  align-self: center;
  z-index: 2;
  border: 1px solid var(--border-subtle);
  border-radius: 999px;
  background: var(--panel-2);
  color: var(--text);
  font-size: 12px;
  padding: 5px 14px;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
}
.msg-new-pill:hover { background: var(--bg-hover); }
.msg--empty { color: var(--text-faint); font-size: 13px; padding: 8px 4px; max-width: none; }
.msg-composer { display: flex; flex-direction: column; gap: 6px; border-top: 1px solid var(--border-subtle); padding-top: 12px; }
.msg-composer textarea {
  width: 100%;
  resize: none;
  min-height: 44px;
  max-height: 220px;
  overflow-y: auto;
}
.msg-composer-actions { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.msg-composer-hint { flex: 1; min-width: 140px; }
.msg-draft-note { color: var(--text-faint); }
.msg-counter { flex: 0 0 auto; color: var(--text-faint); font-size: 11px; }
.msg-counter.is-warn { color: var(--warning); font-weight: 600; }
.settings-section-subtitle {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  margin: 4px 0 8px;
}
.portal-password-form { display: flex; flex-direction: column; gap: 14px; max-width: 460px; }
@media print {
  .msg-composer, .msg-thread-list { display: none; }
}

/* ---------- 13. Scope picker (admin accounts) ---------- */
/* `.banner` is display:flex, which overrides the UA [hidden]{display:none};
   the scope-picker warning toggles hidden in JS, so restore hidden semantics
   inside it (same sharp edge as .session-toast[hidden]). */
.scope-picker-warning[hidden] { display: none; }

.scope-picker {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-inset);
  padding: 12px;
}
.scope-picker-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.scope-picker-count {
  font-size: 12px;
  color: var(--text-muted);
  margin-right: auto;
}
.scope-picker-count strong { color: var(--text); font-weight: 600; }
.scope-picker-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 240px;
  overflow-y: auto;
  padding-right: 4px;
}
.scope-picker-item { margin-right: 0; }
.scope-picker-warning { margin-top: 10px; margin-bottom: 0; }

.account-scope-chips { max-width: 260px; }
.account-scope-chips .tag-chip { overflow: hidden; text-overflow: ellipsis; max-width: 140px; }

.account-create-form {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  flex-wrap: wrap;
}
.account-create-form .form-field { min-width: 180px; }
.account-scope-details { width: 100%; border: 0; }
.account-scope-details[hidden] { display: none; }
.account-scope-details summary { cursor: pointer; font-size: 13px; font-weight: 600; }
.account-scope-details .scope-picker { margin-top: 8px; }
/* ---------- CSP utility classes (auto-generated; replace inline style attrs) ----------
   Enforced Content-Security-Policy forbids inline style attributes. Each unique
   former style="..." value maps to one class. Do not edit by hand. ---------- */
.su-03b6501a { display: inline-flex; align-items: center; gap: 7px; }
.su-045aac89 { margin-bottom: 16px; }
.su-082f6e5d { margin-top: 6px; }
.su-097d766c { --d:190ms; grid-area: activity; }
.su-0af04112 { padding: 18px; }
.su-0b2a28da { display: inline; margin: 0; }
.su-116e7aa6 { padding-left: 0; padding-right: 0; }
.su-17d8c5ec { white-space: pre-wrap; }
.su-1c93056d { margin: 0; flex: 1.6; min-width: 280px; }
.su-1fdc68b9 { --d:60ms; grid-area: domains; }
.su-217a0384 { color: var(--text-faint); font-size: 12.5px; margin-top: 10px; }
.su-27e4afda { margin: 0; flex: 1; min-width: 200px; }
.su-2d847d26 { margin: 0; flex: 0.8; min-width: 180px; }
.su-2d98adf5 { margin-bottom: 10px; }
.su-2e70955c { width: 100%; margin-top: 12px; text-align: center; }
.su-30ccd9bd { width: 100%; padding: 10px; font-size: 14px; }
.su-31526477 { align-self: flex-end; }
.su-342d988c { margin-top: 0.75rem; }
.su-35208e02 { margin: 0 0 14px; }
.su-36ca0aff { margin-top: 8px; }
.su-3728cf3d { --d:330ms; grid-area: recent; }
.su-384c5cb3 { margin: 0; flex: 1; min-width: 220px; }
.su-3907588b { margin-bottom: 14px; }
.su-3a08a48b { margin: 0; flex: 0.5; min-width: 90px; }
.su-3f2f2324 { --d:60ms; grid-area: reminders; }
.su-4379f268 { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; padding: 4px 0 8px; }
.su-4880b78e { margin: 0; flex: 1.4; min-width: 200px; }
.su-48eceef3 { margin: 0; flex: 1; min-width: 140px; }
.su-4feedf8e { margin-bottom: 6px; }
.su-508e5700 { margin: 0 0 10px; }
.su-52fd16b2 { margin: 0; flex: 1; min-width: 160px; }
.su-54a4ec42 { --d:130ms; grid-area: pending; }
.su-54d32d80 { margin-top: 10px; }
.su-5685054f { margin: 0; padding-left: 1.2em; }
.su-57947bfa { --d:470ms; grid-area: instances; }
.su-5a2ddf45 { --d:610ms; grid-area: messaging; }
.su-5cd864ec { margin: 6px 0 0; }
.su-5e342f3c { --d:130ms; grid-area: compliance; }
.su-5eaf8cb5 { color: var(--text-faint); font-size: 12.5px; margin-top: 18px; }
.su-5eee5111 { padding: 18px 18px 0; }
.su-6468396c { width: 100%; padding: 10px; }
.su-693434c7 { display: flex; gap: 8px; }
.su-696b8a28 { flex-wrap: wrap; }
.su-69d66e5b { width: 100%; }
.su-6b82cf24 { display: flex; }
.su-6c63b477 { margin: 4px 0 0; }
.su-6cc9ca22 { margin: 0; flex: 1.4; min-width: 220px; }
.su-6f50c177 { max-width: 140px; }
.su-72d6c38e { margin-bottom: 12px; }
.su-78a38cdd { margin: 0; white-space: pre-wrap; }
.su-7beda6e8 { --d:200ms; grid-area: status; }
.su-81a8278d { margin: 0; flex: 1.2; min-width: 200px; }
.su-825ff003 { flex-direction: column; align-items: flex-start; gap: 8px; }
.su-83682381 { margin: 4px 0 12px; }
.su-8d1f4ab8 { max-width: 200px; }
.su-8eb78c30 { display: flex; align-items: center; gap: 4px; margin-top: 12px; font-size: 11px; color: var(--text-muted); }
.su-91ab1f31 { --d:60ms; grid-area: funnel; }
.su-9293e652 { --d:540ms; grid-area: status; }
.su-97e3f640 { --d:130ms; grid-area: failures; }
.su-98ff738f { padding: 12px 18px; }
.su-99bbdd6a { --d:200ms; grid-area: failures; }
.su-9c9cee20 { margin-top: 12px; }
.su-9eecdd02 { --d:200ms; grid-area: activity; }
.su-a03fcec0 { --d:270ms; grid-area: exports; }
.su-a1e40f7c { color: var(--text-muted); font-size: 13px; }
.su-a39ddebf { margin: 0; flex-basis: 100%; flex-direction: row; align-items: center; gap: 18px; }
.su-a7dc9bf6 { flex: 2; min-width: 320px; }
.su-a9cd8e0e { padding-top: 0; border-bottom: 1px solid var(--border); }
.su-ad0821fa { margin: 12px 0 0; }
.su-af383d3e { max-width: 420px; }
.su-b1230a0e { margin: 0; flex: 1.4; min-width: 260px; }
.su-b26aeceb { margin-top: 14px; }
.su-b57afc0a { margin-bottom: 0.75rem; }
.su-c05fb4d9 { font-size: 11.5px; margin-bottom: 0.25rem; }
.su-c3122899 { margin-top: 0; }
.su-c5935419 { --d:40ms; }
.heatmap { display: grid; grid-template-rows: repeat(7, 13px); grid-auto-flow: column; grid-auto-columns: 13px; gap: 3px; justify-content: start; }
.su-cc6bade1 { --d:120ms; grid-area: attention; }
.su-cdeaae65 { margin: 6px 0; }
.su-ce7fde71 { margin: 0; flex: 1.4; min-width: 180px; }
.su-d1be7e7c { --d:260ms; grid-area: reminders; }
.su-d2f3f473 { white-space: pre-wrap; margin-bottom: 14px; }
.su-d3409764 { margin: 0; flex: 1.4; min-width: 240px; }
.su-d3b40963 { --d:60ms; }
.su-d40474f3 { flex-wrap: wrap; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); }
.su-d4f98a42 { --d:340ms; grid-area: messaging; }
.su-d5b43342 { grid-column: 1 / -1; }
.su-de2395bf { max-width: 160px; }
.su-e1c153d2 { margin: 0; flex: 1; min-width: 240px; }
.su-e3a52ac7 { --d:270ms; grid-area: recent; }
.su-e40c8fc4 { margin: 0 0 12px; }
.su-e527aefa { margin: 0; flex: 1; min-width: 180px; }
.su-e9e0e4af { font-size: 11px; }
.su-eefff2f8 { font-size: 13px; }
.su-f1cc36d6 { color: var(--text-faint); font-size: 12.5px; margin-top: 14px; }
.su-f46470eb { margin: 10px 0 0; }
.su-f5a84850 { --d:400ms; grid-area: overview; }
.su-f608dc7e { border-bottom: 1px solid var(--border); }
.su-f75d63c1 { color: var(--danger); }
.su-fe21d42a { max-width: 120px; }
.su-fe81f59b { color: var(--text-faint); font-size: 12.5px; }
.su-ff227d06 { margin: 0; }
.su-ffbfccfe { margin: 8px 0 0; }
/* CSP companion classes for the data-attr driven dynamic styles
   (app/static/ui-metrics.js applies the values over the CSSOM). */
.p-barchart-fill--muted { opacity: 0.35; }
.stats-heat-cell { width: 13px; height: 13px; border-radius: 3px; background: var(--bg-inset); }

/* The theme toggle icons hide via the `hidden` attribute (CSP-safe: inline
   style="display:none" is not allowed; theme-toggle.js toggles CSSOM
   style.display which wins over the attribute). The UA stylesheet only hides
   [hidden] for block-level boxes, and <svg> is inline — make the attribute
   effective here too. */
svg[hidden] { display: none; }

/* ---------- 12. Notification center (bells, panels, preferences) ---------- */
/* ONE shared component for the admin topbar + the portal topbar. Dark-first
   with light-theme parity via the shared tokens; 44px tap targets; reduced-
   motion safe. */

.notif-bell-wrap {
  position: relative;
  display: inline-flex;
}

.notif-bell {
  position: relative;
  width: 44px;
  height: 44px;
}

.notif-badge {
  position: absolute;
  top: 4px;
  right: 4px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--danger);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  pointer-events: none;
}

.notif-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: min(360px, 92vw);
  max-height: min(480px, 70vh);
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow-lg, 0 12px 32px rgb(0 0 0 / 35%));
  z-index: 60;
}

.notif-panel[hidden] {
  display: none;
}

.notif-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border-subtle, var(--border));
}

.notif-panel-body {
  overflow-y: auto;
  min-height: 48px;
}

.notif-panel-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 12px;
  border-top: 1px solid var(--border-subtle, var(--border));
}

.notif-day-label {
  padding: 8px 12px 4px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.notif-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 9px 12px;
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--border-subtle, var(--border));
}

.notif-row:hover {
  background: var(--bg-hover);
}

.notif-row .dot {
  flex: none;
  margin-top: 5px;
}

.notif-row-main {
  min-width: 0;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.notif-row-title {
  font-weight: 600;
  font-size: 13px;
}

.notif-row.is-unread .notif-row-title {
  color: var(--text);
}

.notif-row.is-unread {
  background: color-mix(in srgb, var(--accent) 7%, transparent);
}

.notif-row-body {
  font-size: 12.5px;
  color: var(--text-faint);
  overflow-wrap: anywhere;
}

.notif-row-time {
  flex: none;
  font-size: 11px;
  color: var(--text-faint);
}

.notif-empty {
  padding: 24px 16px;
  text-align: center;
}

.notif-empty-title {
  margin: 0;
  font-weight: 600;
}

/* Preferences */
.notif-prefs-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 460px;
}

.notif-pref-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* The portal topbar buttons sit in a flex row — keep the panel aligned. */
.portal-topbar-actions .notif-panel {
  right: 0;
}

@media (max-width: 980px) {
  .notif-panel {
    position: fixed;
    top: 56px;
    right: 8px;
    left: 8px;
    width: auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  .notif-panel,
  .notif-row {
    transition: none;
  }
}

/* ---------- 12. Observability workbench (unified stream, status strip, tiles) ---------- */

/* Status strip: checks-summary chips deep-linking into the filtered stream. */
.obs-status-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}
.obs-chip.obs-chip-success .dot { box-shadow: 0 0 6px var(--success); }
.obs-chip.obs-chip-warning .dot { box-shadow: 0 0 6px var(--warning); }
.obs-chip.obs-chip-danger .dot { box-shadow: 0 0 6px var(--danger); }

/* Stat tiles: compact Radar tiles, tabular-nums, whole tile is a deep link. */
.obs-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}
.obs-tile {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--panel-2);
  text-decoration: none;
  color: var(--text);
  transition: background 140ms var(--ease-out), border-color 140ms var(--ease-out),
    box-shadow 140ms var(--ease-out);
}
.obs-tile:hover {
  background: var(--bg-hover);
  border-color: var(--border-strong);
  box-shadow: var(--glow-accent-sm);
}
.obs-tile-label {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.obs-tile-value {
  font-size: 22px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.obs-tile-sub {
  font-size: 11.5px;
  color: var(--text-muted);
}
.obs-tile .bar-track { height: 4px; margin-top: 4px; }
.obs-tile.tone-success .obs-tile-value { color: var(--success); }
.obs-tile.tone-warning .obs-tile-value { color: var(--warning); }
.obs-tile.tone-danger .obs-tile-value { color: var(--danger); }
.obs-tile.tone-info .obs-tile-value { color: var(--info); }

/* Stream table: the logging page's density carried over. */
.obs-kind-chip {
  display: inline-block;
  padding: 1px 8px;
  border: 1px solid var(--border-subtle);
  border-radius: 999px;
  background: var(--bg-hover);
  color: var(--text-muted);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.obs-workbench .obs-log-table td { padding-top: 7px; padding-bottom: 7px; }
.obs-workbench .obs-log-row { cursor: pointer; }
.obs-workbench .obs-log-row:hover { background: var(--bg-hover); }
.obs-workbench .obs-log-row:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: -2px;
}

@media (max-width: 980px) {
  .obs-tiles { grid-template-columns: repeat(2, 1fr); }
  .obs-status-strip { gap: 6px; }
}
