/* BIRT Portal component library. One system, reused everywhere. Requires tokens.css first. */

/* ---------------------------------------------------------------- impersonation banner */

/* Plain document flow (not fixed/sticky) -- it just sits above .app-shell
   and pushes everything else down, so there's no z-index/overlap fight
   with the header and it can never be scrolled past or hidden. Warning
   tone, deliberately not the brand green, so it reads as "support mode"
   at a glance and is unmistakable from ordinary navigation. */
.impersonation-banner {
  display: flex; align-items: center; justify-content: center; gap: var(--space-4);
  flex-wrap: wrap;
  padding: 10px var(--space-4);
  background: var(--warning-tint);
  border-bottom: 1px solid var(--warning);
  color: var(--text);
  font-size: 13px;
  text-align: center;
}
.impersonation-banner__text { display: flex; align-items: center; gap: 8px; }
.impersonation-banner__text svg { width: 16px; height: 16px; color: var(--warning); flex: 0 0 auto; }
.impersonation-banner__by { color: var(--text-muted); }
.impersonation-banner__exit { background: var(--warning); border-color: var(--warning); color: #1a1200; }
.impersonation-banner__exit:hover { opacity: 0.9; }
@media (max-width: 640px) {
  .impersonation-banner { flex-direction: column; gap: var(--space-2); padding: var(--space-3); }
  .impersonation-banner__by { display: block; }
}

/* ---------------------------------------------------------------- layout */

.app-shell {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
}

.app-header {
  height: var(--header-height);
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--space-6);
  padding: 0 var(--space-6);
  padding-top: env(safe-area-inset-top, 0);
  padding-left: max(var(--space-6), env(safe-area-inset-left, 0px));
  padding-right: max(var(--space-6), env(safe-area-inset-right, 0px));
  height: calc(var(--header-height) + env(safe-area-inset-top, 0px));
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: relative;
  z-index: 30;
}

.app-brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  text-decoration: none;
  color: var(--text);
  flex: 0 0 auto;
}

.app-brand__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  background: transparent;
  border: none;
  padding: 0;
}
.app-brand__mark img { width: 100%; height: 100%; object-fit: contain; }

/* The login page's own brand panel gets a larger, more "presented" mark
   than the standard header uses everywhere else in the portal -- this
   is the one place the logo is the actual focal point, not a small
   wayfinding icon next to a page title. */
.login-panel__logo {
  width: 192px;
  height: 192px;
  background: transparent;
  border: none;
  border-radius: 0;
  padding: 0;
}

.app-brand__text { display: flex; flex-direction: column; line-height: 1.2; }
.app-brand__product { font-size: 14px; font-weight: 700; }
.app-brand__meta {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--text-faint);
  text-transform: uppercase;
}

.app-nav { display: flex; align-items: center; gap: var(--space-1); flex: 1 0 auto; }
.app-nav__link {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-muted);
  text-decoration: none;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.app-nav__link:hover { color: var(--text); background: var(--surface-hover); }
.app-nav__link.is-active { color: var(--text); background: var(--brand-tint); }

.app-header__actions { display: flex; align-items: center; gap: var(--space-2); margin-left: auto; flex: 0 0 auto; }

.app-main { flex: 1 0 auto; }
.app-main--padded { position: relative; max-width: 1180px; margin: 0 auto; width: 100%; padding: var(--space-8) var(--space-6) var(--space-16); }

/* The report gets the entire remaining viewport, no card, no margin.
   dvh (not vh) so mobile browser chrome showing/hiding doesn't leave a
   gap or clip the bottom of the iframe; falls back to vh where dvh
   isn't supported. Subtracts the header's own safe-area inset so the
   two heights always sum to exactly the full viewport. */
.app-main--full-bleed {
  flex: 1 0 auto;
  height: calc(100vh - var(--header-height) - env(safe-area-inset-top, 0px));
  height: calc(100dvh - var(--header-height) - env(safe-area-inset-top, 0px));
  position: relative;
}
.report-frame-wrap { position: absolute; inset: 0; }
.report-frame {
  width: 100%;
  height: 100%;
  border: none;
  display: block;
  background: var(--surface);
}

.mobile-nav-toggle {
  display: none;
  align-items: center; justify-content: center;
  width: 44px; height: 44px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface-raised);
  color: var(--text-muted);
  cursor: pointer;
  flex: 0 0 auto;
}
.mobile-nav-toggle svg { width: 18px; height: 18px; }

@media (max-width: 860px) {
  .app-header {
    padding-left: max(var(--space-4), env(safe-area-inset-left, 0px));
    padding-right: max(var(--space-4), env(safe-area-inset-right, 0px));
    gap: var(--space-3);
  }
  .app-brand__product { font-size: 13px; }
  .mobile-nav-toggle { display: inline-flex; }
  .app-nav {
    display: none;
    position: absolute;
    top: 100%; left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    padding: var(--space-2);
    box-shadow: var(--shadow-md);
  }
  .app-nav.is-open { display: flex; }
  .app-nav__link { padding: 12px 14px; }
}

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 600;
  border-radius: var(--radius-sm);
  padding: 9px 16px;
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast), transform var(--transition-fast);
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

.btn--primary { background: var(--brand); border-color: var(--brand); color: var(--brand-contrast); }
.btn--primary:hover { background: var(--brand-hover); border-color: var(--brand-hover); }

.btn--secondary { background: var(--surface-raised); border-color: var(--border-strong); color: var(--text); }
.btn--secondary:hover { background: var(--surface-hover); }

.btn--ghost { background: transparent; border-color: transparent; color: var(--text-muted); }
.btn--ghost:hover { background: var(--surface-hover); color: var(--text); }

.btn--danger { background: var(--danger-tint); border-color: transparent; color: var(--danger); }
.btn--danger:hover { background: var(--danger); color: #fff; }

.btn--sm { padding: 6px 12px; font-size: 13px; }
.btn--icon { padding: 8px; border-radius: var(--radius-sm); }
.btn--block { width: 100%; }
.btn svg { width: 16px; height: 16px; flex: 0 0 auto; }
.btn.is-loading { opacity: 0.8; pointer-events: none; }
.btn__label { display: inline-flex; align-items: center; gap: 8px; }
.btn__spinner {
  width: 15px; height: 15px;
  border: 2px solid rgba(0,0,0,0.25);
  border-top-color: currentColor;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  flex: 0 0 auto;
}

/* Real touch hit areas on touch devices -- (pointer: coarse) targets
   actual touch input specifically, rather than just narrow viewports
   (a touch laptop keeps its mouse-sized targets if it reports fine
   pointer; a narrow desktop window doesn't get needlessly bumped). */
@media (pointer: coarse) {
  .btn { min-height: 44px; }
  .btn--sm { min-height: 38px; }
  .btn--icon { min-width: 44px; min-height: 44px; }
  .input-wrap .input-toggle { min-width: 44px; min-height: 44px; }
  .checkbox-row { min-height: 44px; }
  .checkbox-row input[type="checkbox"] { width: 20px; height: 20px; }
}

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

.field { display: flex; flex-direction: column; gap: 6px; }
.field__label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.field__link { font-size: 13px; font-weight: 600; color: var(--brand); text-decoration: none; }
.field__link:hover { color: var(--brand-hover); }
.field__hint { font-size: 12px; color: var(--text-faint); }

.input-wrap { position: relative; display: flex; align-items: center; }
.input-wrap svg.input-icon {
  position: absolute; left: 12px; width: 16px; height: 16px; color: var(--text-faint); pointer-events: none;
}
.input-wrap .input-toggle {
  position: absolute; right: 8px; background: none; border: none; color: var(--text-faint); cursor: pointer; padding: 6px;
  border-radius: var(--radius-sm);
  transition: color var(--transition-fast), background var(--transition-fast);
}
.input-wrap .input-toggle:hover { color: var(--text); background: var(--surface-hover); }
.input-wrap .input-toggle svg { width: 16px; height: 16px; display: block; }

.input, .select {
  width: 100%;
  font-family: var(--font-ui);
  /* 16px, not 15 -- anything smaller makes iOS Safari auto-zoom the
     page on focus, which then has to be manually pinched back out. */
  font-size: 16px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
@media (pointer: coarse) {
  .input, .select { min-height: 44px; }
}
.input-wrap .input.has-icon-left { padding-left: 38px; }
.input-wrap .input.has-icon-right { padding-right: 38px; }
.input::placeholder { color: var(--text-faint); }
.input:focus, .select:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-tint); }

.checkbox-row { display: flex; align-items: center; gap: var(--space-2); font-size: 14px; color: var(--text); }
.checkbox-row input[type="checkbox"] { width: 17px; height: 17px; accent-color: var(--brand); }

.form-stack { display: flex; flex-direction: column; gap: var(--space-4); }
.form-row { display: flex; gap: var(--space-4); flex-wrap: wrap; align-items: flex-end; }
.form-row .field { flex: 1 1 200px; }

.form-error {
  background: var(--danger-tint);
  color: var(--danger);
  border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
  font-size: 13px;
  font-weight: 500;
}

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

.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  white-space: nowrap;
}
.badge--brand { background: var(--brand-tint); color: var(--brand); border-color: var(--brand-tint-strong); }
.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--neutral { background: var(--surface-hover); color: var(--text-muted); }

.status-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--success); display: inline-block; }
.status-dot--live { box-shadow: 0 0 0 0 var(--success-tint); animation: pulse-dot 2s infinite; }
@keyframes pulse-dot {
  0% { box-shadow: 0 0 0 0 var(--success-tint); }
  70% { box-shadow: 0 0 0 6px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* ---------------------------------------------------------------- cards */

.card {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.card--padded { padding: var(--space-6); }
.card__header { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-4); }
.card__title { font-size: 16px; font-weight: 700; margin: 0; }
.card__eyebrow {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-faint);
}

/* ---------------------------------------------------------------- avatar */

.avatar {
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--brand-tint);
  color: var(--brand);
  font-weight: 700;
  flex: 0 0 auto;
}
.avatar--sm { width: 26px; height: 26px; font-size: 11px; }
.avatar--md { width: 36px; height: 36px; font-size: 14px; }

/* ---------------------------------------------------------------- menu / switcher (dropdown panels) */

.menu, .switcher { position: relative; }
.menu__toggle, .switcher__toggle {
  display: flex; align-items: center; gap: var(--space-2);
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 6px 10px;
  cursor: pointer;
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
}
.menu__toggle:hover, .switcher__toggle:hover { background: var(--surface-hover); }
.menu__caret, .switcher__caret { color: var(--text-faint); font-size: 10px; }

.menu__panel, .switcher__panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  z-index: 40;
  overflow: hidden;
  opacity: 0;
  transform: translateY(-6px) scale(0.98);
  pointer-events: none;
  transition: opacity var(--transition-fast), transform var(--transition-fast);
}
.menu__panel.is-open, .switcher__panel.is-open {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}
.menu__panel { min-width: 200px; padding: var(--space-2); }
.switcher__panel { width: 280px; padding: var(--space-3); }

.menu__item {
  display: flex; align-items: center; gap: var(--space-2);
  padding: 8px 10px; border-radius: var(--radius-sm);
  color: var(--text); text-decoration: none; font-size: 14px;
  width: 100%; background: none; border: none; cursor: pointer; text-align: left;
}
.menu__item:hover { background: var(--surface-hover); }
.menu__divider { height: 1px; background: var(--border); margin: var(--space-2) 4px; }

.switcher__search { margin-bottom: var(--space-2); }
.switcher__list { list-style: none; margin: 0; padding: 0; max-height: 300px; overflow-y: auto; }
.switcher__item {
  display: flex; align-items: center; gap: var(--space-3);
  padding: 8px; border-radius: var(--radius-sm); cursor: pointer; text-decoration: none; color: var(--text);
}
.switcher__item:hover { background: var(--surface-hover); }
.switcher__item.is-current { background: var(--brand-tint); }
.switcher__item-name { font-size: 14px; font-weight: 600; flex: 1; }
.switcher__check { color: var(--brand); width: 16px; height: 16px; }
.switcher__item.is-loading, .account-card.is-loading { opacity: 0.55; pointer-events: none; }

/* ---------------------------------------------------------------- theme toggle */

.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface-raised);
  color: var(--text-muted);
  cursor: pointer;
}
.theme-toggle:hover { background: var(--surface-hover); color: var(--text); }
.theme-toggle svg { width: 17px; height: 17px; }
.theme-toggle .icon-moon { display: none; }
:root[data-theme="light"] .theme-toggle .icon-sun { display: none; }
:root[data-theme="light"] .theme-toggle .icon-moon { display: block; }

/* ---------------------------------------------------------------- notifications */

.notifications-toggle { position: relative; }
.notif-badge {
  position: absolute; top: -4px; right: -4px;
  min-width: 16px; height: 16px; padding: 0 4px;
  display: flex; align-items: center; justify-content: center;
  background: var(--danger); color: #fff;
  border-radius: var(--radius-pill);
  font-size: 10px; font-weight: 700; line-height: 1;
  border: 2px solid var(--bg);
}
.notifications-panel { width: 320px; padding: 0; }
.notifications-panel__header {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-3) var(--space-4);
  font-size: 13px; font-weight: 700;
  border-bottom: 1px solid var(--border);
}
.notifications-panel__mark-all {
  background: none; border: none; cursor: pointer;
  font-family: var(--font-ui); font-size: 12px; font-weight: 600; color: var(--brand);
  padding: 0;
}
.notifications-panel__mark-all:hover { color: var(--brand-hover); }
.notifications-panel__list { max-height: 340px; overflow-y: auto; }
.notification-item {
  display: flex; flex-direction: column; gap: 2px;
  width: 100%; text-align: left;
  padding: var(--space-3) var(--space-4);
  background: none; border: none; border-bottom: 1px solid var(--border);
  text-decoration: none; color: var(--text); cursor: pointer;
  font-family: var(--font-ui);
}
.notification-item:hover { background: var(--surface-hover); }
.notification-item.is-unread { position: relative; background: var(--brand-tint); }
.notification-item.is-unread::before {
  content: ""; position: absolute; left: 6px; top: 50%; transform: translateY(-50%);
  width: 6px; height: 6px; border-radius: 50%; background: var(--brand);
}
.notification-item.is-unread { padding-left: calc(var(--space-4) + 10px); }
.notification-item__title { font-size: 13px; font-weight: 600; }
.notification-item__body { font-size: 12px; color: var(--text-muted); }
.notification-item__time { font-size: 11px; color: var(--text-faint); margin-top: 2px; }
.notifications-panel__view-all {
  display: block; text-align: center;
  padding: var(--space-3) var(--space-4);
  font-size: 13px; font-weight: 600; color: var(--brand); text-decoration: none;
}
.notifications-panel__view-all:hover { color: var(--brand-hover); background: var(--surface-hover); }
@media (max-width: 640px) {
  .notifications-panel { width: 100%; }
  .notifications-panel__list { max-height: 50dvh; }
}

.notification-item--full { padding: var(--space-4) var(--space-5); }
.notification-item--full:last-child { border-bottom: none; }
.notification-item--full .notification-item__title { font-size: 14px; }
.notification-item--full .notification-item__body { font-size: 13px; }

/* ---- report focus mode: mobile/tablet only -- desktop already has
   plenty of room, so the toggle doesn't even render there. ---- */
.focus-mode-toggle {
  display: none;
  align-items: center; justify-content: center;
  width: 44px; height: 44px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface-raised);
  color: var(--text-muted);
  cursor: pointer;
}
.focus-mode-toggle svg { width: 17px; height: 17px; }
.focus-mode-toggle:hover { background: var(--surface-hover); color: var(--text); }
@media (max-width: 1024px) {
  .focus-mode-toggle { display: inline-flex; }
}

.focus-mode-exit {
  display: none;
  position: fixed;
  top: max(12px, env(safe-area-inset-top, 0px));
  right: 12px;
  z-index: 50;
  align-items: center; gap: 6px;
  padding: 9px 14px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border);
  background: var(--surface-raised);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 13px; font-weight: 600;
  box-shadow: var(--shadow-md);
  cursor: pointer;
}
.focus-mode-exit svg { width: 14px; height: 14px; }

body.focus-mode .app-header { display: none; }
body.focus-mode .app-main--full-bleed {
  height: 100vh;
  height: 100dvh;
}
body.focus-mode .focus-mode-exit { display: inline-flex; }

@media (pointer: coarse) {
  .theme-toggle, .menu__toggle, .switcher__toggle { min-width: 44px; min-height: 44px; }
  .menu__item, .switcher__item { min-height: 44px; }
}

/* ---- mobile: switcher/user menu present as a bottom sheet instead of a
   small anchored dropdown -- same open/close JS (wireDropdown() in
   portal.js just toggles the .is-open class either way), only the
   presentation changes per breakpoint. */
.sheet-backdrop {
  display: none;
  position: fixed; inset: 0;
  background: var(--scrim);
  z-index: 39;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--transition-base);
}
.sheet-backdrop.is-open { opacity: 1; pointer-events: auto; }

@media (max-width: 640px) {
  .sheet-backdrop { display: block; }
  .menu__panel, .switcher__panel {
    position: fixed;
    left: 0; right: 0; bottom: 0; top: auto;
    width: auto;
    max-height: 80dvh;
    border-radius: 18px 18px 0 0;
    padding-bottom: max(var(--space-3), env(safe-area-inset-bottom, 0px));
    transform: translateY(100%);
    box-shadow: var(--shadow-lg);
  }
  .menu__panel.is-open, .switcher__panel.is-open { transform: translateY(0); }
  .switcher__list { max-height: 50dvh; }
  .menu__item, .switcher__item { padding: 12px; font-size: 15px; }
  .switcher__search { min-height: 44px; }
}

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

.table-wrap {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.table-scroll { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; min-width: 480px; }
.table th, .table td { text-align: left; padding: 12px var(--space-5); font-size: 14px; }
.table th {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--text-faint); font-weight: 600; border-bottom: 1px solid var(--border);
}
.table tbody tr { border-bottom: 1px solid var(--border); transition: background var(--transition-fast); }
.table tbody tr:last-child { border-bottom: none; }
.table tbody tr:hover { background: var(--surface-hover); }
.table code { font-family: var(--font-mono); font-size: 12px; background: var(--surface-hover); padding: 2px 6px; border-radius: 4px; }
.table-actions { display: flex; gap: var(--space-1); justify-content: flex-end; }

.table-cell-flex { display: flex; align-items: center; gap: 10px; min-width: 0; }
.table-cell-truncate {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}

/* ---- responsive tables: below tablet width, each row becomes a
   compact label/value record instead of forcing tiny unreadable
   columns. Tablet (641-1024px) keeps the real table -- only phones get
   the card treatment. Pure CSS + a data-label attribute already on
   each <td> in the markup; no separate mobile template. */
@media (max-width: 640px) {
  .table-scroll { overflow-x: visible; }
  .table { min-width: 0; }
  .table thead { display: none; }
  .table, .table tbody, .table tr, .table td { display: block; width: 100%; }
  .table tr {
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--border);
  }
  .table td {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: 6px 0;
    border: none;
    font-size: 14px;
  }
  .table td::before {
    content: attr(data-label);
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-faint);
    flex: 0 0 auto;
  }
  .table td.table-actions {
    justify-content: flex-start;
    flex-wrap: wrap;
    padding-top: var(--space-2);
  }
  .table td.table-actions::before { content: none; }
  .table td.table-actions .btn,
  .table td.table-actions form { min-height: 44px; }
  .table-cell-truncate { max-width: 55vw; }
}

.empty-state {
  text-align: center;
  padding: var(--space-12) var(--space-6);
  color: var(--text-muted);
}
.empty-state__icon {
  width: 44px; height: 44px; margin: 0 auto var(--space-4);
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-hover); border-radius: 50%; color: var(--text-faint);
}
.empty-state__title { font-size: 15px; font-weight: 700; color: var(--text); margin: 0 0 4px; }
.empty-state__desc { font-size: 13px; margin: 0 0 var(--space-4); }

/* ---------------------------------------------------------------- modal */

.modal-overlay {
  position: fixed; inset: 0; background: var(--scrim);
  display: flex; align-items: center; justify-content: center;
  z-index: 100; padding: var(--space-4);
  opacity: 0; pointer-events: none; transition: opacity var(--transition-base);
}
.modal-overlay.is-open { opacity: 1; pointer-events: auto; }
.modal {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  width: 100%; max-width: 420px;
  padding: var(--space-6);
  transform: translateY(8px) scale(0.98);
  transition: transform var(--transition-base);
}
.modal-overlay.is-open .modal { transform: translateY(0) scale(1); }
.modal__title { font-size: 17px; font-weight: 700; margin: 0 0 var(--space-2); }
.modal__body { font-size: 14px; color: var(--text-muted); margin: 0 0 var(--space-6); }
.modal__footer { display: flex; justify-content: flex-end; gap: var(--space-2); flex-wrap: wrap; }
.modal--detail { max-width: 560px; }
.modal--detail .settings-list dd { word-break: break-word; }

.audit-log-row { cursor: pointer; transition: background var(--transition-fast); }
.audit-log-row:hover, .audit-log-row:focus-visible { background: var(--surface-hover); outline: none; }

.health-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--space-4);
}
.health-card__row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.health-card__name { font-size: 14px; font-weight: 700; }

/* ---------------------------------------------------------------- pulse */

.pulse-header {
  display: flex; align-items: flex-start; justify-content: space-between; flex-wrap: wrap;
  gap: var(--space-5);
  margin-bottom: var(--space-5);
}
.pulse-header__titles h1 { margin: 0 0 4px; font-size: 22px; }
.pulse-header__stats { display: flex; gap: var(--space-3); flex-wrap: wrap; }
.pulse-stat {
  background: var(--surface-raised); border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  min-width: 140px;
}
.pulse-stat__label { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-faint); }
.pulse-stat__value { font-size: 20px; font-weight: 700; margin-top: 2px; }

.pulse-list { display: flex; flex-direction: column; gap: var(--space-4); }
.pulse-card {
  padding: var(--space-5);
  border-left: 3px solid var(--border-strong);
}
.pulse-card--urgent { border-left-color: var(--danger); }
.pulse-card--warning { border-left-color: var(--warning); }
.pulse-card--info { border-left-color: var(--text-faint); }
.pulse-card__meta { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-3); }
.pulse-card__age { font-size: 12px; color: var(--text-faint); }
.pulse-card__title { margin: 0 0 var(--space-2); font-size: 16px; font-weight: 700; }
.pulse-card__desc { margin: 0 0 var(--space-3); font-size: 14px; color: var(--text-muted); line-height: 1.6; }
.pulse-card__facts { display: flex; gap: var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-4); }
.pulse-card__fact { font-size: 13px; color: var(--text-muted); }
.pulse-card__fact strong { color: var(--text); }
.pulse-card__actions { display: flex; gap: var(--space-2); flex-wrap: wrap; padding-top: var(--space-3); border-top: 1px solid var(--border); }
.pulse-card__action-form { display: flex; gap: 6px; }
.pulse-card__select { width: auto; padding: 8px 10px; font-size: 13px; }

.pulse-empty { display: flex; flex-direction: column; align-items: center; text-align: center; }
.pulse-empty__dot {
  display: block; width: 10px; height: 10px; border-radius: 50%;
  background: var(--success); margin-bottom: var(--space-3);
  box-shadow: 0 0 0 6px var(--success-tint);
}

@media (max-width: 640px) {
  .pulse-card__actions { flex-direction: column; align-items: stretch; }
  .pulse-card__action-form { flex-direction: column; }
  .pulse-card__action-form .btn { width: 100%; }
  .pulse-card__select { width: 100%; }
}
@media (pointer: coarse) {
  .pulse-card__select { min-height: 44px; }
}

/* ---- detail pages: shared header + tab bar for User Detail and Account
   Detail. Server-rendered tabs (plain links, one page load per tab) --
   matches this app's existing convention (no client-side tab-switching
   framework anywhere else), not a new pattern just for these pages. */
.detail-header { margin-bottom: var(--space-5); }
.detail-header__title-row { display: flex; align-items: center; gap: var(--space-3); }
.detail-header__title-row h1 { margin: 0; font-size: 22px; }
.detail-header__badges { display: flex; gap: 6px; margin-top: 6px; flex-wrap: wrap; }
.detail-header__meta { margin: var(--space-2) 0 0; color: var(--text-muted); font-size: 14px; }

.detail-tabs {
  display: flex; gap: var(--space-1);
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--space-6);
  overflow-x: auto;
}
.detail-tab {
  padding: 10px 14px;
  font-size: 14px; font-weight: 600; color: var(--text-muted);
  text-decoration: none; white-space: nowrap;
  border-bottom: 2px solid transparent;
  transition: color var(--transition-fast), border-color var(--transition-fast);
}
.detail-tab:hover { color: var(--text); }
.detail-tab.is-active { color: var(--brand); border-bottom-color: var(--brand); }
@media (pointer: coarse) {
  .detail-tab { min-height: 44px; display: flex; align-items: center; }
}

.detail-section { display: flex; flex-direction: column; gap: var(--space-5); }
.detail-section .card + .card { margin-top: 0; }

@media (pointer: coarse) {
  .modal__footer .btn { min-height: 44px; }
}

/* Near-full-width and top-aligned (not vertically centered) on phones,
   with its own scroll -- centering a fixed-size dialog breaks the moment
   the on-screen keyboard opens (the "center" of the visible area jumps),
   and a tall confirm/form dialog needs to scroll internally rather than
   push its buttons off the bottom of the screen. */
@media (max-width: 640px) {
  .modal-overlay {
    align-items: flex-start;
    padding: var(--space-4) var(--space-3);
    padding-top: max(var(--space-8), env(safe-area-inset-top, 0px));
    overflow-y: auto;
  }
  .modal {
    max-width: none;
    max-height: calc(100dvh - var(--space-12));
    overflow-y: auto;
    padding: var(--space-5);
  }
}

/* ---------------------------------------------------------------- toasts */

.toast-region {
  position: fixed; bottom: var(--space-6); right: var(--space-6);
  display: flex; flex-direction: column; gap: var(--space-2);
  z-index: 200; width: min(340px, calc(100vw - 2 * var(--space-6)));
}
.toast {
  display: flex; align-items: flex-start; gap: var(--space-3);
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-left: 3px solid var(--text-faint);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
  padding: var(--space-3) var(--space-4);
  font-size: 14px;
  animation: toast-in var(--transition-base);
}
.toast--success { border-left-color: var(--success); }
.toast--error { border-left-color: var(--danger); }
@keyframes toast-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }

/* ---------------------------------------------------------------- skeleton */

.skeleton {
  background: linear-gradient(90deg, var(--surface-hover) 25%, var(--border) 37%, var(--surface-hover) 63%);
  background-size: 400% 100%;
  animation: skeleton-shimmer 1.4s ease infinite;
  border-radius: var(--radius-sm);
}
@keyframes skeleton-shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

.report-loading {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--report-bg);
  opacity: 1;
  transition: opacity 0.4s cubic-bezier(.16,1,.3,1);
}
.report-loading.is-hidden { opacity: 0; pointer-events: none; }
.report-loading__spinner {
  width: 28px; height: 28px;
  border: 3px solid var(--border-strong);
  border-top-color: var(--brand);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .report-loading { transition: none; }
  .report-loading__spinner { animation-duration: 1.4s; }
}
@keyframes spin { to { transform: rotate(360deg); } }

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

/* A brief, one-time-per-visit reveal: the logo presents centered, holds,
   then fades away as the real page fades/settles in underneath. Kept
   short (~1.1s total) and skipped entirely for reduced-motion -- this is
   a welcome moment, not a loading screen, so it never blocks or delays
   the form actually being usable. */
.login-intro {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  animation: login-intro-overlay 1.1s ease forwards;
}
.login-intro__logo {
  width: min(30vw, 220px);
  height: auto;
  opacity: 0;
  transform: scale(0.82);
  animation: login-intro-logo 1.1s ease forwards;
}

@keyframes login-intro-logo {
  0%   { opacity: 0; transform: scale(0.82); }
  32%  { opacity: 1; transform: scale(1); }
  78%  { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.06); }
}
@keyframes login-intro-overlay {
  0%   { opacity: 1; }
  78%  { opacity: 1; }
  100% { opacity: 0; pointer-events: none; }
}

/* #login-shell itself stays un-animated -- the cascading reveal happens
   at the more granular .login-panel__content / .feature-tile / .login-card
   level below, so each piece presents in its own turn instead of the
   whole page fading as one flat block. */

@media (prefers-reduced-motion: reduce) {
  .login-intro { display: none; }
  .login-panel__content > *,
  .feature-tile,
  .login-card {
    animation: none; opacity: 1; transform: none;
  }
}

/* A failed-login or session-expired re-render is the same /login page,
   re-rendered -- the visitor needs to see the error immediately, not
   wait through the presenting-logo splash and staggered reveal again. */
.login-shell.no-intro .login-panel__content > *,
.login-shell.no-intro .feature-tile,
.login-shell.no-intro .login-card {
  animation: none; opacity: 1; transform: none;
}

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

/* Three explicit grid items -- brand content, the feature list, and the
   form -- rather than nesting the features inside the brand panel. On
   desktop they're placed back into exactly today's look (brand content
   and features stacked in the left column, form spanning the right);
   below 980px .login-shell becomes a plain flex column and DOM order
   alone gives the mobile flow the brief asks for (branding -> headline
   -> form -> trust line -> condensed capabilities) with no `order`
   trickery needed, since that's also the order these three sit in the
   markup. */
.login-shell {
  position: relative;
  overflow: hidden;
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  grid-template-rows: auto 1fr;
  background: var(--bg);
}
.login-panel--brand { grid-column: 1; grid-row: 1; }
.login-features { grid-column: 1; grid-row: 2; align-self: start; }
.login-panel--form { grid-column: 2; grid-row: 1 / 3; }

@media (max-width: 980px) {
  .login-shell {
    display: flex;
    flex-direction: column;
    min-height: auto;
  }
  .login-panel--brand,
  .login-features,
  .login-panel--form {
    grid-column: auto; grid-row: auto;
  }
}

/* ---- living aurora background: shared across both panels, so the page
   reads as one environment rather than stopping at the divider. Only
   `transform` and `opacity` are animated (GPU-friendly, no layout
   thrashing); colors are drawn only from the existing brand ramp plus
   two deeper emerald/teal tones, never an off-palette hue. Blobs a/b sit
   toward the left (brand panel) at higher opacity; c/d sit toward the
   right (form panel) at lower opacity, so the form side stays calmer. */
.login-aurora {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.login-aurora__blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(80px);
  will-change: transform;
}
.login-aurora__blob--a {
  width: 620px; height: 620px;
  left: -140px; top: -160px;
  background: radial-gradient(circle, var(--brand-500) 0%, transparent 70%);
  opacity: 0.30;
  animation: aurora-drift-a 26s ease-in-out infinite;
}
.login-aurora__blob--b {
  width: 520px; height: 520px;
  left: 26%; top: 6%;
  background: radial-gradient(circle, #1F6B52 0%, transparent 70%);
  opacity: 0.22;
  animation: aurora-drift-b 32s ease-in-out infinite;
}
.login-aurora__blob--c {
  width: 480px; height: 480px;
  right: -120px; bottom: -150px;
  background: radial-gradient(circle, #0D3B30 0%, transparent 70%);
  opacity: 0.18;
  animation: aurora-drift-c 22s ease-in-out infinite;
}
.login-aurora__blob--d {
  width: 380px; height: 380px;
  right: 6%; top: 28%;
  background: radial-gradient(circle, var(--brand-600) 0%, transparent 72%);
  opacity: 0.14;
  animation: aurora-drift-d 30s ease-in-out infinite;
}
@keyframes aurora-drift-a {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%      { transform: translate(60px, 40px) scale(1.08); }
}
@keyframes aurora-drift-b {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%      { transform: translate(-50px, 55px) scale(0.95); }
}
@keyframes aurora-drift-c {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%      { transform: translate(-40px, -45px) scale(1.05); }
}
@keyframes aurora-drift-d {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  50%      { transform: translate(30px, -35px) rotate(8deg); }
}
@media (prefers-reduced-motion: reduce) {
  .login-aurora__blob { animation: none; }
}

/* Lighter on phones: drop the two least-visible blobs entirely (less to
   composite), shrink and soften the remaining two, lower blur radius --
   stays premium at a fraction of the GPU cost for lower-end devices. */
@media (max-width: 640px) {
  .login-aurora__blob--c, .login-aurora__blob--d { display: none; }
  .login-aurora__blob { filter: blur(50px); }
  .login-aurora__blob--a { width: 380px; height: 380px; opacity: 0.22; }
  .login-aurora__blob--b { width: 320px; height: 320px; opacity: 0.16; }
}

.login-panel--brand {
  position: relative;
  z-index: 1;
  overflow: hidden;
}

/* ---- portal-wide background: a richer, full-viewport version of the
   login page's living-aurora technique (reuses its aurora-drift-*
   keyframes) -- fixed, so it spans the whole background area behind
   the header rather than being confined to the centered content
   column, plus a slow diagonal light sweep layered on top so it reads
   as continuous motion rather than four static soft circles. Brand
   green/emerald tones only, same discipline as the login page's own
   aurora. Rendered by base.html around every page's content EXCEPT the
   report view (app-main--full-bleed -- the report already owns its own
   full-viewport background/theme) and the login page (its own aurora,
   never wrapped by base.html at all). */
.page-aurora {
  position: fixed;
  top: calc(var(--header-height) + env(safe-area-inset-top, 0px));
  left: 0; right: 0; bottom: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.page-aurora__blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(110px);
  will-change: transform;
}
.page-aurora__blob--a {
  width: 640px; height: 640px;
  left: -160px; top: -180px;
  background: radial-gradient(circle, var(--brand-500) 0%, transparent 70%);
  opacity: 0.22;
  animation: aurora-drift-a 26s ease-in-out infinite;
}
.page-aurora__blob--b {
  width: 560px; height: 560px;
  right: -140px; top: 8%;
  background: radial-gradient(circle, #1F6B52 0%, transparent 70%);
  opacity: 0.18;
  animation: aurora-drift-b 32s ease-in-out infinite;
}
.page-aurora__blob--c {
  width: 500px; height: 500px;
  left: 28%; bottom: -220px;
  background: radial-gradient(circle, var(--brand-600) 0%, transparent 72%);
  opacity: 0.16;
  animation: aurora-drift-c 22s ease-in-out infinite;
}
.page-aurora__blob--d {
  width: 420px; height: 420px;
  right: 8%; bottom: 6%;
  background: radial-gradient(circle, var(--brand-400) 0%, transparent 72%);
  opacity: 0.14;
  animation: aurora-drift-d 30s ease-in-out infinite;
}
/* Moving light sweep -- a wide diagonal band animated purely via
   background-position (GPU-friendly, the same technique BIRT-Usman's
   own report uses for its ambient sheen), layered over the blobs. */
.page-aurora__sheen {
  position: absolute;
  inset: -20% -20%;
  background: linear-gradient(115deg, transparent 35%, var(--brand-tint-strong) 49%, transparent 63%);
  background-size: 250% 250%;
  animation: page-aurora-sheen-sweep 18s ease-in-out infinite;
}
@keyframes page-aurora-sheen-sweep {
  0%   { background-position: 15% 20%; }
  50%  { background-position: 85% 80%; }
  100% { background-position: 15% 20%; }
}
@media (prefers-reduced-motion: reduce) {
  .page-aurora__blob, .page-aurora__sheen { animation: none; }
}
@media (max-width: 640px) {
  .page-aurora__blob--c, .page-aurora__blob--d { display: none; }
  .page-aurora__blob { filter: blur(70px); }
  .page-aurora__sheen { display: none; }
}

.page-content { position: relative; z-index: 1; }

/* .login-panel--brand (row 1, auto height) and .login-features (row 2,
   fills the rest) are two separate grid items on purpose -- it's what
   lets mobile's flex-column fallback reorder the form ahead of the
   features by plain DOM order, with no `order` trickery. But that split
   meant the divider and background texture used to live only on
   .login-panel--brand, so they visibly stopped at the row 1/row 2
   seam instead of running the full height of the panel next to the
   form -- a real layout bug, not a style choice. A generated pseudo
   -element is still a grid item, so it can be placed across BOTH rows
   independently of the two real content pieces, giving one continuous
   panel behind them without merging their markup (which would break
   the mobile reorder). */
.login-shell::before {
  content: "";
  grid-column: 1;
  grid-row: 1 / 3;
  position: relative;
  z-index: 0;
  pointer-events: none;
  border-right: 1px solid var(--border);
  background-image:
    radial-gradient(circle at 15% 12%, var(--brand-tint-strong), transparent 42%),
    radial-gradient(circle at 88% 90%, var(--brand-tint), transparent 40%),
    radial-gradient(var(--border-strong) 1px, transparent 1px);
  background-size: auto, auto, 28px 28px;
  opacity: 0.5;
  animation: motif-breathe 16s ease-in-out infinite;
}
:root[data-theme="light"] .login-shell::before { opacity: 0.35; }
@keyframes motif-breathe {
  0%, 100% { opacity: 0.5; }
  50% { opacity: 0.68; }
}
@media (prefers-reduced-motion: reduce) {
  .login-shell::before { animation: none; }
}
@media (max-width: 980px) {
  /* Becomes a flex item once .login-shell drops to a column layout below
     -- hidden outright rather than repositioned, since mobile has no
     "left panel" for it to sit behind. */
  .login-shell::before { display: none; }
}

.login-panel__content {
  position: relative;
  z-index: 1;
  min-height: 100%;
  padding: var(--space-16) var(--space-12);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-8);
}
.login-panel--brand h1 { font-size: 34px; line-height: 1.15; margin: var(--space-4) 0 var(--space-2); }
.login-panel--brand .lede { font-size: 15px; color: var(--text-muted); max-width: 46ch; line-height: 1.6; }

/* Same horizontal rhythm as .login-panel__content above it, so the
   features read as a continuation of the brand panel on desktop even
   though they're now a separate grid item (needed so mobile can reorder
   them after the form independently -- see .login-shell above). */
.login-features {
  position: relative;
  z-index: 1;
  padding: 0 var(--space-12) var(--space-12);
}
@media (max-width: 980px) {
  .login-features { padding: var(--space-6) var(--space-6) var(--space-10); }
}

.feature-list { display: flex; flex-direction: column; gap: var(--space-2); }
@media (max-width: 600px) {
  /* Condensed 2x2 on phones instead of four full-width stacked rows --
     less scrolling, and the tiles read as a compact grid rather than a
     list once the layout is this narrow. */
  .feature-list { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); }
  .feature-tile { flex-direction: column; text-align: center; align-items: center; padding: var(--space-3); }
  .feature-tile__desc { display: none; }
}
.feature-tile {
  display: flex; align-items: flex-start; gap: var(--space-3);
  background: color-mix(in srgb, var(--surface-raised) 65%, transparent);
  border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  transition: transform var(--transition-fast), border-color var(--transition-fast), background var(--transition-fast);
}
.feature-tile:hover {
  transform: translateY(-1px);
  border-color: var(--brand-tint-strong);
  background: var(--surface-raised);
}
.feature-tile__icon {
  width: 30px; height: 30px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  background: var(--brand-tint); color: var(--brand); border-radius: var(--radius-sm);
  transition: box-shadow var(--transition-fast);
}
.feature-tile:hover .feature-tile__icon { box-shadow: 0 0 0 5px var(--brand-tint); }
.feature-tile__icon svg { width: 16px; height: 16px; }
.feature-tile__title { font-size: 13px; font-weight: 700; display: flex; align-items: center; gap: var(--space-2); }
.feature-tile__desc { font-size: 12.5px; color: var(--text-muted); margin-top: 2px; line-height: 1.5; }

.login-stat-row { display: flex; gap: var(--space-3); flex-wrap: wrap; }
.login-stat {
  flex: 1 1 140px;
  background: var(--surface-raised); border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
}
.login-stat__label { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-faint); }
.login-stat__value { font-size: 14px; font-weight: 700; margin-top: 2px; }

.login-panel--form {
  position: relative;
  z-index: 1;
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-8);
}
/* Dampens the shared aurora on this side -- the form stays the calm,
   readable focal point while the environment behind it stays alive. */
.login-panel--form::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--bg);
  opacity: 0.55;
  pointer-events: none;
}
/* A slow, independent ambient glow specifically behind the card --
   breathes gently rather than tracking the outer aurora blobs 1:1. */
.login-panel--form::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image: radial-gradient(circle at 50% 42%, var(--brand-tint-strong), transparent 55%);
  opacity: 0.6;
  pointer-events: none;
  animation: card-glow-pulse 24s ease-in-out infinite;
}
@keyframes card-glow-pulse {
  0%, 100% { opacity: 0.4; transform: scale(1); }
  50%      { opacity: 0.75; transform: scale(1.08); }
}
@media (prefers-reduced-motion: reduce) {
  .login-panel--form::after { animation: none; opacity: 0.55; }
}

.login-card {
  position: relative;
  z-index: 1;
  width: 100%; max-width: 440px;
  display: flex; flex-direction: column; gap: var(--space-6);
  padding: var(--space-10);
  border-radius: var(--radius-lg);
  border: 1px solid var(--border-strong);
  /* Depth without heavy glassmorphism: a hairline light-green highlight
     along the top edge (the "glass" cue), a soft wide ambient glow at
     low opacity, then the ordinary elevation shadow underneath. */
  box-shadow:
    inset 0 1px 0 0 rgba(140, 255, 170, 0.14),
    0 0 70px -16px var(--brand-tint-strong),
    var(--shadow-lg);
  /* Solid fallback first, then a light glass effect where color-mix()
     and backdrop-filter are supported -- degrades to a plain card
     everywhere else, never an invisible/unstyled one. */
  background: var(--surface-raised);
  background: color-mix(in srgb, var(--surface-raised) 80%, transparent);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);

  opacity: 0;
  transform: translateY(16px) scale(0.97);
  animation: login-card-in 0.65s cubic-bezier(.16,1,.3,1) 0.7s forwards;
}
@keyframes login-card-in {
  to { opacity: 1; transform: translateY(0) scale(1); }
}
.login-card h1 { font-size: 26px; margin: 0 0 4px; }
.login-card .lede { font-size: 14px; color: var(--text-muted); margin: 0; }
.login-footer { font-size: 12px; color: var(--text-faint); text-align: center; }
.login-footer__link { color: var(--brand); font-weight: 600; text-decoration: none; transition: color var(--transition-fast); }
.login-footer__link:hover { color: var(--brand-hover); text-decoration: underline; }

.login-trust {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  font-size: 12px; color: var(--text-faint);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border);
}
.login-trust svg { width: 13px; height: 13px; flex: 0 0 auto; color: var(--text-faint); }

.login-copyright {
  position: absolute;
  left: var(--space-6);
  bottom: var(--space-5);
  z-index: 1;
  font-size: 11px;
  color: var(--text-faint);
  letter-spacing: 0.01em;
}
@media (max-width: 980px) { .login-copyright { display: none; } }

/* Cascading reveal for the brand panel: its top-level blocks (logo,
   headline, feature list) fade up one after another, and the feature
   tiles inside that list cascade again on their own -- a nested,
   staggered "presenting" feel rather than one flat fade. */
.login-panel__content > * {
  opacity: 0;
  transform: translateY(10px);
  animation: login-fade-up 0.55s cubic-bezier(.16,1,.3,1) forwards;
}
.login-panel__content > *:nth-child(1) { animation-delay: 0.66s; }
.login-panel__content > *:nth-child(2) { animation-delay: 0.74s; }
.login-panel__content > *:nth-child(3) { animation-delay: 0.82s; }

.feature-tile {
  opacity: 0;
  transform: translateY(8px);
  animation: login-fade-up 0.5s cubic-bezier(.16,1,.3,1) forwards;
}
.feature-tile:nth-child(1) { animation-delay: 0.92s; }
.feature-tile:nth-child(2) { animation-delay: 1.00s; }
.feature-tile:nth-child(3) { animation-delay: 1.08s; }
.feature-tile:nth-child(4) { animation-delay: 1.16s; }

@keyframes login-fade-up {
  to { opacity: 1; transform: translateY(0); }
}

/* Mobile: the brand panel is no longer hidden (see .login-shell's mobile
   flow above), so the form panel no longer needs to be forced to full
   viewport height -- it just sizes to its own content like every other
   block in the stacked mobile flow. */
@media (max-width: 980px) {
  .login-panel--form { padding: var(--space-8) var(--space-5); }
}

/* ---------------------------------------------------------------- dashboard */

.dashboard-header { margin-bottom: var(--space-6); }
.dashboard-header .card__eyebrow { margin: 0 0 6px; }
.dashboard-header h1 { margin: 0 0 4px; font-size: 22px; }
.dashboard-header p { margin: 0; color: var(--text-muted); font-size: 14px; }

.account-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--space-4);
  margin-top: var(--space-5);
}
.account-card {
  display: flex; align-items: center; gap: var(--space-3);
  background: var(--surface-raised); border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: var(--space-4); text-decoration: none; color: var(--text);
  transition: border-color var(--transition-fast), transform var(--transition-fast);
}
.account-card:hover { border-color: var(--brand); transform: translateY(-1px); }
.account-card__name { font-size: 14px; font-weight: 700; }
.account-card__arrow { margin-left: auto; color: var(--text-faint); flex: 0 0 auto; }

/* ---- Admin Workspace: summary row, filters, and the richer account
   card used only on the multi-account dashboard for an Admin (not a
   Super Admin). Reuses .login-stat/.account-card as a base rather than
   inventing a parallel set of tokens/components. */
.workspace-toolbar {
  display: flex; align-items: center; gap: var(--space-4);
  flex-wrap: wrap;
}

.filter-chips { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.filter-chip {
  font-family: var(--font-ui); font-size: 13px; font-weight: 600;
  padding: 7px 14px; border-radius: var(--radius-pill);
  background: var(--surface-raised); border: 1px solid var(--border); color: var(--text-muted);
  cursor: pointer; white-space: nowrap;
  transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}
.filter-chip:hover { background: var(--surface-hover); color: var(--text); }
.filter-chip.is-active { background: var(--brand-tint); border-color: var(--brand-tint-strong); color: var(--brand); }

.account-card--rich {
  flex-direction: column;
  align-items: stretch;
  cursor: default;
  gap: var(--space-3);
}
.account-card--rich:hover { transform: none; }
.account-card__header {
  display: flex; align-items: center; gap: var(--space-3);
  text-decoration: none; color: var(--text);
  border-radius: var(--radius-sm);
}
.account-card__header:hover .account-card__name { color: var(--brand); }
.account-card__title { display: flex; flex-direction: column; gap: 5px; flex: 1 1 auto; min-width: 0; }
.account-card__badges { display: flex; gap: 6px; flex-wrap: wrap; }
.account-card__stats {
  display: flex; gap: var(--space-4);
  font-size: 12px; color: var(--text-muted);
  padding-top: var(--space-3); border-top: 1px solid var(--border);
}
.account-card__actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.account-card__actions .btn { flex: 1 1 auto; }

@media (max-width: 640px) {
  .workspace-toolbar { flex-direction: column; align-items: stretch; }
  .workspace-toolbar .input-wrap { max-width: none !important; }
  .filter-chips { overflow-x: auto; flex-wrap: nowrap; padding-bottom: 2px; }
  .login-stat-row { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 2px; }
  .login-stat { flex: 1 1 128px; }
}
@media (pointer: coarse) {
  .filter-chip { min-height: 40px; }
}

/* ---------------------------------------------------------------- admin pages */

.page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-6); flex-wrap: wrap; gap: var(--space-3); }
.page-header h1 { margin: 0; font-size: 22px; }
.page-header__actions { display: flex; gap: var(--space-2); }

.toolbar { display: flex; gap: var(--space-3); margin-bottom: var(--space-4); flex-wrap: wrap; }
.toolbar .input-wrap { flex: 1 1 240px; }

.form-page { max-width: 480px; }
.credential-card {
  background: var(--brand-tint); border: 1px solid var(--brand-tint-strong); border-radius: var(--radius-md);
  padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-3);
}
.credential-card dt { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-faint); }
.credential-card dd { margin: 2px 0 0; font-size: 15px; font-weight: 600; }

/* ---- premium admin forms (create user, etc.) -- wider than the plain
   .form-page (settings, account form) since these carry more hierarchy:
   breadcrumb, stacked header, sectioned card. */

.breadcrumb { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-faint); margin-bottom: var(--space-3); }
.breadcrumb a { color: var(--text-faint); text-decoration: none; transition: color var(--transition-fast); }
.breadcrumb a:hover { color: var(--text-muted); }
.breadcrumb__current { color: var(--text-muted); font-weight: 600; }
.breadcrumb__sep { color: var(--text-faint); }

.form-page--user { max-width: 720px; }

.admin-form-shell {
  position: relative;
  background:
    radial-gradient(ellipse 640px 220px at 20% -80px, var(--brand-tint) 0%, transparent 70%),
    radial-gradient(ellipse 420px 320px at 100% 40px, var(--brand-tint) 0%, transparent 65%);
  background-repeat: no-repeat;
}

.page-header--stacked { display: block; }
.page-header__titles { display: flex; flex-direction: column; gap: 6px; }
.page-header__title-row { display: flex; align-items: center; gap: 10px; }
.page-header__icon {
  display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; flex: 0 0 auto;
  border-radius: var(--radius-sm);
  background: var(--brand-tint); color: var(--brand);
}
.page-header__icon svg { width: 18px; height: 18px; }
.page-header__desc { margin: 0; font-size: 14px; color: var(--text-muted); max-width: 60ch; }

.card--ambient { position: relative; box-shadow: var(--shadow-sm), 0 0 0 1px transparent; }

.form-section { display: flex; flex-direction: column; gap: var(--space-4); }
.form-section + .form-section { margin-top: var(--space-6); padding-top: var(--space-6); border-top: 1px solid var(--border); }
.form-section-header { display: flex; flex-direction: column; gap: 2px; }
.form-section-header__title { font-size: 14px; font-weight: 700; color: var(--text); margin: 0; }
.form-section-header__desc { font-size: 12px; color: var(--text-muted); margin: 0; }

.field__error { font-size: 12px; color: var(--danger); margin: 2px 0 0; }
.input.has-error, .input.has-error:focus { border-color: var(--danger); box-shadow: 0 0 0 3px var(--danger-tint); }

.role-select { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.role-card {
  position: relative;
  display: flex; align-items: flex-start; gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface);
  cursor: pointer;
  transition: border-color var(--transition-fast), background var(--transition-fast);
}
.role-card:hover { border-color: var(--text-faint); }
.role-card input { position: absolute; opacity: 0; width: 0; height: 0; }
.role-card:has(input:focus-visible) { outline: 2px solid var(--brand); outline-offset: 2px; }
.role-card:has(input:checked) { border-color: var(--brand); background: var(--brand-tint); }
.role-card__icon {
  display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; flex: 0 0 auto;
  border-radius: var(--radius-sm);
  background: var(--surface-hover); color: var(--text-muted);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.role-card__icon svg { width: 17px; height: 17px; }
.role-card:has(input:checked) .role-card__icon { background: var(--brand-tint-strong); color: var(--brand); }
.role-card__body { display: flex; flex-direction: column; gap: 3px; flex: 1; }
.role-card__title { font-size: 14px; font-weight: 700; color: var(--text); }
.role-card__desc { font-size: 12px; color: var(--text-muted); line-height: 1.45; }
.role-card__check { width: 18px; height: 18px; flex: 0 0 auto; color: var(--brand); opacity: 0; margin-top: 2px; }
.role-card:has(input:checked) .role-card__check { opacity: 1; }
@media (max-width: 640px) {
  .role-select { grid-template-columns: 1fr; }
}

.form-notice {
  display: flex; gap: var(--space-3); align-items: flex-start;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-size: 13px; line-height: 1.55;
  border: 1px solid transparent;
  color: var(--text-muted);
}
.form-notice svg { width: 18px; height: 18px; flex: 0 0 auto; margin-top: 1px; }
.form-notice__title { display: block; font-weight: 700; color: var(--text); margin-bottom: 2px; }
.form-notice--warning { display: none; background: var(--warning-tint); border-color: var(--warning-tint); color: var(--text); }
.form-notice--warning svg { color: var(--warning); }
.form-notice--warning .form-notice__title { color: var(--warning); }
.form-notice--info { background: var(--surface); border-color: var(--border); }
.form-notice--info svg { color: var(--text-faint); }
#role-select:has(input[value="on"]:checked) ~ #super-admin-warning { display: flex; }
#role-select:has(input[value="on"]:checked) ~ #account-access-notice { display: none; }
#role-select:has(input[value="on"]:checked) ~ #account-picker { display: none; }

.link-btn {
  background: none; border: none; padding: 0; margin: 0;
  font-size: 13px; font-weight: 600; color: var(--brand);
  cursor: pointer; transition: color var(--transition-fast);
}
.link-btn:hover { color: var(--brand-hover); }

.account-picker {
  display: flex; flex-direction: column; gap: var(--space-3);
  animation: login-fade-up 0.3s cubic-bezier(.16,1,.3,1) forwards;
}
.account-picker__toolbar { display: flex; gap: var(--space-4); flex-wrap: wrap; align-items: flex-end; }
.account-picker__search { flex: 1 1 220px; }
.account-picker__role { flex: 0 0 180px; }
.account-picker__actions { display: flex; align-items: center; gap: var(--space-3); }
.account-picker__actions .field__hint { margin-left: auto; }
.account-picker__list {
  display: flex; flex-direction: column; gap: 2px;
  max-height: 260px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: var(--space-2);
  background: var(--surface);
}
.account-picker__item {
  padding: 8px var(--space-2); border-radius: var(--radius-sm);
  transition: background var(--transition-fast);
  cursor: pointer;
}
.account-picker__item:hover { background: var(--surface-hover); }

.form-footer-actions { display: flex; justify-content: flex-end; gap: var(--space-3); padding-top: var(--space-2); }
@media (max-width: 640px) {
  .form-footer-actions { flex-direction: column-reverse; }
  .form-footer-actions .btn { width: 100%; }
}

.btn:disabled, .btn[disabled] { opacity: 0.5; cursor: not-allowed; pointer-events: none; }

/* ---- password setup (create user) -- reveals the manual password fields
   only when that card is selected; same :has()-driven pattern as the
   role selector and its warning/info panels above. */
#manual-password-fields { display: none; flex-direction: column; gap: var(--space-4); }
#password-setup-select:has(input[value="manual"]:checked) ~ #manual-password-fields { display: flex; }

.role-card__badge {
  font-family: var(--font-mono); font-size: 10px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--brand); background: var(--brand-tint); border-radius: var(--radius-pill);
  padding: 2px 8px; margin-left: 8px;
}

/* ---- password strength meter -- shared by create-user (manual), invite
   accept, and reset-password. Purely a visual hint on top of the one
   real server-side floor (8+ characters); it doesn't imply or enforce
   any additional rule the backend doesn't also check. */
.password-strength { display: flex; gap: 4px; margin-top: 8px; }
.password-strength__bar { height: 4px; flex: 1; border-radius: 2px; background: var(--border-strong); transition: background var(--transition-fast); }
.password-strength[data-strength="1"] .password-strength__bar:nth-child(1) { background: var(--danger); }
.password-strength[data-strength="2"] .password-strength__bar:nth-child(-n+2) { background: var(--warning); }
.password-strength[data-strength="3"] .password-strength__bar:nth-child(-n+3) { background: var(--brand-hover); }
.password-strength[data-strength="4"] .password-strength__bar:nth-child(-n+4) { background: var(--brand); }
.password-strength__label { display: block; font-size: 11px; color: var(--text-faint); margin-top: 6px; min-height: 14px; }

/* ---- standalone auth pages: invite accept, forgot password, reset
   password. Not logged in yet, so no header/nav -- reuses the login
   page's own card + aurora background components at a smaller, single
   -card scale instead of the full split-screen layout, so it still
   reads as the same product. */
.auth-page {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-6);
  padding: var(--space-6);
  background: var(--bg);
  overflow: hidden;
}
.auth-page__brand { position: relative; z-index: 1; display: flex; align-items: center; gap: 10px; }
.auth-page__brand img { width: 36px; height: 36px; }
.auth-page__brand-text { font-weight: 700; font-size: 15px; color: var(--text); }
.auth-page .login-card { position: relative; z-index: 1; width: 100%; max-width: 440px; animation-delay: 0.05s; }
@media (prefers-reduced-motion: reduce) {
  .auth-page .login-card { animation: none; opacity: 1; transform: none; }
}

.settings-list { display: flex; flex-direction: column; gap: 14px; margin: 0; }
.settings-list dt { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-faint); }
.settings-list dd { margin: 2px 0 0; font-size: 14px; font-weight: 600; }

.settings-subhead { font-size: 13px; font-weight: 700; margin: 0 0 var(--space-3); }
.session-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.session-item {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-2) var(--space-3);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.session-item__device { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; }
.session-item__meta { display: block; font-size: 12px; color: var(--text-faint); margin-top: 2px; }

.theme-segmented {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.theme-segmented button {
  padding: 8px 18px;
  background: var(--surface);
  border: none;
  border-right: 1px solid var(--border);
  cursor: pointer;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.theme-segmented button:last-child { border-right: none; }
.theme-segmented button:hover { background: var(--surface-hover); }
.theme-segmented button.is-active { background: var(--brand-tint); color: var(--brand); }

/* ---------------------------------------------------------------- error pages */

.error-page {
  min-height: calc(100vh - var(--header-height));
  display: flex; align-items: center; justify-content: center; text-align: center; padding: var(--space-6);
}
.error-page__code { font-family: var(--font-mono); color: var(--brand); font-size: 14px; letter-spacing: 0.08em; }
.error-page h1 { font-size: 26px; margin: var(--space-2) 0 var(--space-3); }
.error-page p { color: var(--text-muted); max-width: 46ch; margin: 0 auto var(--space-6); }

/* ---------------------------------------------------------------- utility */

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.visually-hidden[hidden] { display: none !important; }
