/* ─────────────────────────────────────────────────────────────────
   app.css — components + utilities (built on tokens.css)
   ──────────────────────────────────────────────────────────────── */

/* ─── Reset ─── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; }
a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-soft); }

/* ─── Base ─── */
body {
  font-family: var(--font-sans);
  font-size: var(--t-base);
  line-height: var(--leading-normal);
  color: var(--fg);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { font-weight: 600; line-height: var(--leading-tight); margin: 0 0 var(--s-3); }
h1 { font-size: var(--t-xl); }
h2 { font-size: var(--t-lg); }
h3 { font-size: var(--t-md); }
p { margin: 0 0 var(--s-3); }
small { font-size: var(--t-xs); color: var(--fg-muted); }

code, kbd, pre, .mono {
  font-family: var(--font-mono);
  font-size: 0.92em;
  font-variant-ligatures: contextual;
}

code:not(pre code) {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-2);
  padding: 1px 6px;
  font-size: 0.88em;
  color: var(--accent);
}

pre {
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--r-3);
  padding: var(--s-3) var(--s-4);
  overflow-x: auto;
  margin: 0 0 var(--s-3);
  font-size: var(--t-sm);
  line-height: 1.5;
  color: var(--fg);
}

hr {
  border: 0;
  border-top: 1px solid var(--border);
  margin: var(--s-6) 0;
}

/* ─── Focus (visible for keyboard) ─── */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-1);
}

/* ─── Layout ─── */
.l-shell { min-height: 100vh; display: flex; flex-direction: column; }
.l-header {
  height: var(--header-h);
  border-bottom: 1px solid var(--border);
  background: var(--bg-surface);
  display: flex; align-items: center;
  padding: 0 var(--s-6);
  position: sticky; top: 0; z-index: var(--z-sticky);
}
.l-header__brand {
  display: flex; align-items: center; gap: var(--s-2);
  font-weight: 600; font-size: var(--t-md);
  color: var(--fg);
}
.l-header__brand::before {
  content: ">"; color: var(--accent); font-family: var(--font-mono);
  font-weight: 400;
}
.l-header__nav { margin-left: auto; display: flex; gap: var(--s-4); align-items: center; }
.l-header__nav a {
  /* inline-flex + center matches the behaviour of .nav-dropdown__trigger
     so text inside <a> boxes sits at the box's vertical center, not the
     top. Without this, the avatar (32px, the tallest nav item) forces
     .l-header__nav's default stretch to grow <a> boxes to 32px, putting
     their top-aligned text ~half a row above the trigger's centered
     text — visually misaligned. */
  display: inline-flex;
  align-items: center;
  color: var(--fg-muted);
  font-size: var(--t-sm);
  text-transform: lowercase;
  letter-spacing: 0.02em;
  padding: var(--s-1) var(--s-2);
  border-radius: var(--r-2);
}
.l-header__nav a:hover { color: var(--fg); background: var(--bg-elevated); }

.l-main { flex: 1; max-width: var(--max-w); width: 100%; margin: 0 auto; padding: var(--s-6); }
.l-main--prose { max-width: var(--max-w-prose); }
/* Full-width variant for list / data views. Keeps the clamp() padding
   so the chrome has air, but lets the table fill the screen instead of
   stopping at 1280px. Narrow viewports scroll inside the panel. */
.l-main--wide  { max-width: none; }
.l-footer {
  border-top: 1px solid var(--border);
  padding: var(--s-4) var(--s-6);
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--fg-dim);
  text-align: center;
}

/* Two-column layout (Quick Actions) */
.l-split { display: grid; grid-template-columns: 1.5fr 1fr; gap: var(--s-6); }
.l-split > * { min-width: 0; }   /* allow grid columns to shrink past content min-width */
@media (max-width: 900px) { .l-split { grid-template-columns: 1fr; } }

/* ─── Panel / Card ─── */
.panel {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-4);
  margin-bottom: var(--s-5);
  overflow: hidden;
  min-width: 0;          /* prevent panel from forcing grid column to its min-content */
}
.panel__head {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--border);
}
.panel__head h2 {
  margin: 0; font-size: var(--t-sm); font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--fg-muted);
}
.panel__head__actions { display: flex; gap: var(--s-2); }
.panel__body { padding: var(--s-4); }
.panel__body--flush { padding: 0; }
/* Panels that wrap a wide table: allow horizontal scroll instead of
   clipping the rightmost column. `:has()` is supported in all modern
   browsers (Chrome 105+ / Safari 15.4+ / Firefox 121+). The default
   `overflow: hidden` on .panel stays in place for non-table panels. */
.panel:has(> .panel__body > .tbl) { overflow-x: auto; overflow-y: hidden; }

/* ─── Buttons ─── */
.btn {
  display: inline-flex; align-items: center; gap: var(--s-2);
  padding: 6px var(--s-3);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-2);
  color: var(--fg);
  font-size: var(--t-sm);
  line-height: 1.2;
  font-weight: 500;
  white-space: nowrap;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.btn:hover { background: var(--bg-input); border-color: var(--border-strong); }
.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #042f2e;     /* high contrast on teal */
}
.btn--primary:hover {
  background: var(--accent-soft);
  border-color: var(--accent-soft);
  color: #042f2e;     /* override global a:hover which would make text same as bg */
}
.btn--danger {
  background: transparent; border-color: var(--danger); color: var(--danger);
}
.btn--danger:hover { background: var(--danger-dim); }
.btn--ghost { background: transparent; border-color: transparent; color: var(--fg-muted); }
.btn--ghost:hover { color: var(--fg); background: var(--bg-elevated); }
.btn--sm { padding: 3px 8px; font-size: var(--t-xs); }
.btn--block { display: flex; width: 100%; justify-content: center; }

/* Icon-only button (square) */
.btn--icon { width: 28px; height: 28px; padding: 0; justify-content: center; }

/* ─── Form ─── */
.form-row { margin-bottom: var(--s-4); }
.form-row label {
  display: block;
  font-size: var(--t-xs);
  color: var(--fg-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: var(--s-1);
}
.form-row input[type=text],
.form-row input[type=password],
.form-row input[type=number],
.form-row input:not([type]),
.form-row select {
  width: 100%;
  max-width: 360px;
  padding: 8px 10px;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--r-2);
  color: var(--fg);
  font-size: var(--t-base);
  font-family: var(--font-mono);
  transition: border-color var(--dur-fast) var(--ease);
}
.form-row input:focus,
.form-row select:focus { border-color: var(--accent); outline: none; }
.form-row__hint { font-size: var(--t-xs); color: var(--fg-dim); margin-top: var(--s-1); }

/* Checkboxes — custom */
.form-row .checkboxes label {
  display: inline-flex; align-items: center; gap: var(--s-1);
  text-transform: none; letter-spacing: 0;
  color: var(--fg); font-size: var(--t-base);
  padding: 4px 10px;
  border: 1px solid var(--border);
  border-radius: var(--r-2);
  background: var(--bg-elevated);
  margin-right: var(--s-2);
  margin-bottom: var(--s-1);
  cursor: pointer;
  user-select: none;
}
.form-row .checkboxes input[type=checkbox] {
  width: 14px; height: 14px;
  margin: 0;
  accent-color: var(--accent);
  cursor: pointer;
}
.form-row .checkboxes label:has(input:checked) {
  background: var(--accent-dim);
  border-color: var(--accent);
  color: var(--accent);
}

/* ─── Table ─── */
.tbl {
  width: 100%;
  table-layout: fixed;        /* allow cells to shrink past min-content so long tokens don't blow out the row */
  border-collapse: collapse;
  font-size: var(--t-sm);
}
.tbl th {
  text-align: left;
  font-weight: 500;
  color: var(--fg-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: var(--t-xs);
  padding: var(--s-2) var(--s-3);
  border-bottom: 1px solid var(--border);
  background: var(--bg-surface);
}
.tbl th, .tbl td { min-width: 0; }    /* let cells shrink past min-content */
.tbl th, .tbl td { white-space: nowrap; }  /* prevent date/status/role from wrapping */
.tbl td code { white-space: normal; word-break: break-all; }  /* long client_ids still break */
.tbl .col-created { width: 120px; }       /* 2026-06-17 fits */
.tbl .col-status  { width: 90px; }
.tbl .actions-col { width: 220px; }       /* header cell — fits 2 buttons */
.tbl td.actions   { width: 220px; }       /* body cell */
.tbl td.actions > * + * { margin-left: 0; }  /* let flex handle gap */
.tbl td {
  padding: var(--s-2) var(--s-3);
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  overflow-wrap: anywhere;    /* break long client_id values inside <code> */
}
.tbl tr:last-child td { border-bottom: 0; }
.tbl tr:hover td { background: var(--bg-elevated); }
.tbl tr.is-selected td {
  background: var(--accent-dim);
  box-shadow: inset 2px 0 0 var(--accent);
}

/* Action cell — inline-block buttons so the td's vertical-align: middle
   applies cleanly. (display: flex here breaks the cell's vertical
   alignment with the rest of the row.) */
.tbl td.actions { white-space: nowrap; }
.tbl td.actions a + a { margin-left: 4px; }

/* ─── Status pill (SIGNATURE element) ─── */
.status {
  display: inline-flex; align-items: center;
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.status::before { content: "["; opacity: 0.5; margin-right: 2px; }
.status::after { content: "]"; opacity: 0.5; margin-left: 2px; }
.status--active { color: var(--status-active); }
.status--revoked { color: var(--status-revoked); }
.status--pending { color: var(--status-pending); }
.status--muted { color: var(--fg-muted); }

/* ─── KV (key + value + copy) ─── */
.kv { display: flex; align-items: stretch; gap: var(--s-2); margin: var(--s-2) 0; }
.kv__code {
  flex: 1; margin: 0;
  white-space: pre-wrap; word-break: break-all;
  font-size: var(--t-sm);
  padding: var(--s-3) var(--s-4);
  min-height: 40px;
  display: flex; align-items: center;
}
.kv__copy {
  flex-shrink: 0;
  padding: 0 var(--s-3);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-2);
  color: var(--fg-muted);
  font-size: var(--t-xs);
  font-family: var(--font-mono);
  transition: all var(--dur-fast) var(--ease);
}
.kv__copy:hover { color: var(--accent); border-color: var(--accent); }
.kv__copy.is-copied { color: var(--ok); border-color: var(--ok); }

/* ─── Banner (2FA reminder) ─── */
.banner {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  background: var(--warn-dim);
  border: 1px solid var(--warn);
  border-radius: var(--r-3);
  margin-bottom: var(--s-5);
  font-size: var(--t-sm);
}
.banner__icon { color: var(--warn); font-size: var(--t-lg); }
.banner__body { flex: 1; }
.banner__title { font-weight: 600; color: var(--warn); }
.banner__desc { color: var(--fg-muted); margin-top: 2px; font-size: var(--t-xs); }
.banner__actions { display: flex; gap: var(--s-2); }

/* ─── Stat cards (dashboard) ─── */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--s-3);
  margin-bottom: var(--s-5);
}
.stat {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-4);
  padding: var(--s-4);
}
.stat__label {
  font-size: var(--t-xs);
  color: var(--fg-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: var(--s-2);
}
.stat__value {
  font-family: var(--font-mono);
  font-size: var(--t-2xl);
  font-weight: 600;
  line-height: 1;
  color: var(--fg);
  display: flex; align-items: baseline; gap: 6px;
}
.stat__value small { font-size: var(--t-md); color: var(--fg-muted); font-weight: 400; }
.stat--warn .stat__value { color: var(--warn); }
.stat--ok .stat__value { color: var(--ok); }

/* ─── Empty state ─── */
.empty {
  padding: var(--s-8) var(--s-4);
  text-align: center;
  color: var(--fg-dim);
  font-family: var(--font-mono);
  font-size: var(--t-sm);
}

/* ─── Toast (action result feedback) ─── */
.toast-host { position: fixed; top: var(--s-4); right: var(--s-4); z-index: var(--z-toast); display: flex; flex-direction: column; gap: var(--s-2); }
.toast {
  padding: var(--s-3) var(--s-4);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-3);
  font-size: var(--t-sm);
  min-width: 240px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  animation: toast-in var(--dur) var(--ease);
}
.toast--ok { border-left-color: var(--ok); }
.toast--warn { border-left-color: var(--warn); }
.toast--danger { border-left-color: var(--danger); }
@keyframes toast-in {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ─── Activity feed (dashboard bottom) ─── */
.feed { font-family: var(--font-mono); font-size: var(--t-sm); }
.feed tr td:first-child { color: var(--fg-dim); width: 80px; }
.feed .action { color: var(--accent); }

/* ─── Disclosure (used by 2FA backup code "Need recovery?" toggle) ─── */
.recovery {
  margin: var(--s-3) 0 var(--s-4);
  border: 1px solid var(--border);
  border-radius: var(--r-3);
  background: var(--bg-elevated);
}
.recovery > summary {
  padding: var(--s-2) var(--s-3);
  cursor: pointer;
  font-size: var(--t-sm);
  color: var(--fg-muted);
  user-select: none;
  list-style: none;
  display: flex; align-items: center; gap: var(--s-1);
}
.recovery > summary::-webkit-details-marker { display: none; }
.recovery > summary::before {
  content: "›";
  font-family: var(--font-mono);
  color: var(--accent);
  font-size: var(--t-md);
  transition: transform var(--dur-fast) var(--ease);
  display: inline-block;
}
.recovery[open] > summary::before { transform: rotate(90deg); }
.recovery > summary:hover { color: var(--fg); }
.recovery[open] > summary { border-bottom: 1px solid var(--border); }
.recovery[open] > *:not(summary) { padding: var(--s-3); }

/* ─── 2FA specific ─── */
.totp-frame {
  display: inline-block; padding: var(--s-3);
  background: white; border-radius: var(--r-3);
  box-shadow: 0 0 0 1px var(--border);
}
.totp-frame img { display: block; width: 200px; height: 200px; }
.backup-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s-1) var(--s-3);
  font-family: var(--font-mono); font-size: var(--t-sm);
  padding: var(--s-3);
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--r-3);
  margin: var(--s-3) 0;
}
.backup-grid code { color: var(--accent); background: none; border: 0; padding: 2px 0; }

/* ─── Login centering ─── */
.login-shell { min-height: 100vh; display: grid; place-items: center; padding: var(--s-4); }
.login-card {
  width: 100%; max-width: 360px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-4);
  padding: var(--s-6);
}
.login-card h1 { font-size: var(--t-lg); }
.login-card__notice {
  padding: var(--s-3) var(--s-4);
  background: var(--accent-dim);
  border: 1px solid var(--accent);
  border-radius: var(--r-3);
  margin-bottom: var(--s-4);
  font-size: var(--t-sm);
  color: var(--fg);
}
.login-card__hint {
  margin-top: var(--s-4);
  padding: var(--s-3);
  background: var(--bg-input);
  border-radius: var(--r-2);
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--fg-dim);
}

/* ─── Header user / avatar menu ─── */
.l-header__user { position: relative; display: inline-flex; align-items: center; margin-left: var(--s-1); }
:root {
  --avatar-bg-0: #6b7280; --avatar-bg-1: #b45309; --avatar-bg-2: #047857;
  --avatar-bg-3: #1d4ed8; --avatar-bg-4: #6d28d9; --avatar-bg-5: #be185d;
  --avatar-bg-6: #0e7490; --avatar-bg-7: #a16207;
}
.avatar {
  width: 32px; height: 32px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--avatar-bg, var(--accent));
  color: #0b0b0c;
  font-weight: 600;
  font-family: var(--font-mono);
  font-size: var(--t-sm);
  text-transform: uppercase;
  border: 1px solid var(--border);
  cursor: pointer;
  padding: 0;
  user-select: none;
}
.avatar:hover { filter: brightness(1.1); }
.avatar:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.avatar-menu {
  position: absolute;
  right: 0;
  top: calc(100% + var(--s-2));
  min-width: 220px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-3);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  z-index: 150;
  padding: var(--s-2);
}
.avatar-menu[hidden] { display: none; }
.avatar-menu__head {
  padding: var(--s-2) var(--s-3);
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--s-2);
  display: flex; align-items: center; gap: var(--s-2);
}
.avatar-menu__head code { color: var(--fg); font-size: var(--t-sm); }
.avatar-menu__head .role-badge {
  display: inline-block; padding: 2px 6px;
  border-radius: var(--r-2);
  background: var(--bg-elevated);
  color: var(--fg-muted);
  font-size: var(--t-xs);
  text-transform: lowercase;
  font-family: var(--font-mono);
}
.avatar-menu a {
  display: block;
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-2);
  color: var(--fg);
  font-size: var(--t-sm);
  text-decoration: none;
}
.avatar-menu a:hover { background: var(--bg-elevated); color: var(--fg); }
.avatar-menu a.danger { color: var(--danger); }
.avatar-menu hr { border: 0; border-top: 1px solid var(--border); margin: var(--s-2) 0; }

/* ─── Profile page ─── */
.profile-card {
  display: flex; align-items: center; gap: var(--s-5);
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-4);
  padding: var(--s-6);
  margin-bottom: var(--s-5);
}
.profile-card .avatar { width: 80px; height: 80px; font-size: var(--t-lg); }
.profile-card__info { flex: 1; min-width: 0; }
.profile-card__info dl { display: grid; grid-template-columns: 120px 1fr; gap: var(--s-2) var(--s-4); margin: 0; font-size: var(--t-sm); }
.profile-card__info dt { color: var(--fg-muted); }
.profile-card__info dd { margin: 0; color: var(--fg); font-family: var(--font-mono); }

.profile-actions { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--s-4); }
.profile-action {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-4);
  padding: var(--s-4) var(--s-5);
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
  color: var(--fg);
  text-decoration: none;
}
.profile-action:hover { border-color: var(--accent); }
.profile-action__label { font-size: var(--t-sm); }
.profile-action__badge {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  padding: 2px 8px;
  border-radius: var(--r-2);
  background: var(--bg-elevated);
  color: var(--fg-muted);
}
.profile-action__badge.is-on  { background: var(--ok-dim);  color: var(--ok); }
.profile-action__badge.is-off { background: var(--warn-dim); color: var(--warn); }

/* ─── Dynamic spacing (v5) ─── */
.l-main { padding: clamp(var(--s-4), 4vw, var(--s-8)); }
.panel { padding: 0; }
.panel__body { padding: clamp(var(--s-3), 2vw, var(--s-5)); }
.panel__head { padding: clamp(var(--s-3), 2vw, var(--s-5)); }
.tbl { font-size: clamp(var(--t-xs), 0.6vw + 0.7rem, var(--t-sm)); }
.tbl th, .tbl td { padding: clamp(var(--s-2), 1.2vw, var(--s-3)) clamp(var(--s-2), 1.2vw, var(--s-4)); }
.stat-grid { gap: clamp(var(--s-3), 2vw, var(--s-5)); }

/* ─── 2FA setup re-verification steps (login.html) ─── */
.login-card__steps {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  margin-bottom: var(--s-5);
  padding: var(--s-3) var(--s-4);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-3);
}
.login-card__step {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  font-size: var(--t-sm);
  color: var(--fg-muted);
}
.login-card__step.is-active { color: var(--fg); }
.login-card__step.is-done { color: var(--fg-dim); text-decoration: line-through; }
.login-card__step-num {
  width: 24px; height: 24px;
  border-radius: 50%;
  background: var(--bg-input);
  border: 1px solid var(--border);
  color: var(--fg-muted);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: var(--t-xs);
  font-family: var(--font-mono);
  font-weight: 600;
  flex-shrink: 0;
}
.login-card__step.is-active .login-card__step-num {
  background: var(--accent);
  border-color: var(--accent);
  color: #042f2e;
}
.login-card__step.is-done .login-card__step-num {
  background: var(--ok-dim);
  border-color: var(--ok);
  color: var(--ok);
}

/* ─── Nav dropdown (header top bar) ─── */
/* Visually consistent with .avatar-menu — same panel chrome + same item
   hover. Only the trigger is different (text button + caret, vs avatar
   circular button). Mutual exclusion handled by JS in base.html. */

.nav-dropdown {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.nav-dropdown__trigger {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: var(--s-1) var(--s-2);
  background: transparent;
  border: 0;
  color: var(--fg-muted);
  font: inherit;
  font-size: var(--t-sm);
  font-weight: 400;
  /* No `line-height: 1` — sibling <a> tags use default `normal` (≈1.2),
     so the trigger would render shorter and visually misalign with
     "仪表盘" / "en". The caret still centers vertically via the
     inline-flex + align-items: center above. */
  cursor: pointer;
  border-radius: var(--r-2);
  text-transform: lowercase;
  letter-spacing: 0.02em;
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.nav-dropdown__trigger:hover,
.nav-dropdown__trigger:focus-visible {
  color: var(--fg);
  background: var(--bg-elevated);
  outline: none;
}
.nav-dropdown__trigger[aria-expanded="true"] { color: var(--accent); }

.nav-dropdown__caret {
  display: inline-block;
  font-size: 10px;
  line-height: 1;
  opacity: 0.75;
  transition: transform var(--dur-fast) var(--ease);
}
.nav-dropdown__trigger[aria-expanded="true"] .nav-dropdown__caret {
  transform: rotate(180deg);
}

.nav-dropdown__menu {
  position: absolute;
  top: calc(100% + var(--s-2));
  right: 0;
  min-width: 200px;
  margin: 0;
  padding: var(--s-2);
  list-style: none;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-3);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  z-index: 150;
}
.nav-dropdown__menu[hidden] { display: none; }

/* Menu items — same look as .avatar-menu a (rounded rect, hover bg-elevated) */
.nav-dropdown__menu a {
  display: block;
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-2);
  color: var(--fg);
  font-size: var(--t-sm);
  text-decoration: none;
}
.nav-dropdown__menu a:hover { background: var(--bg-elevated); color: var(--fg); }

@media (prefers-reduced-motion: reduce) {
  .nav-dropdown__caret,
  .nav-dropdown__trigger { transition: none; }
}

/* ─── Status pill: info variant (DCR badge etc.) ─── */
.status--info { color: var(--status-info); }

/* ─── Table: Type column (M2M / DCR badge) ─── */
.tbl .col-type { width: 80px; }

/* ─── Table column widths ─── */
/* DCR table — 9 columns: type, client_id, name, owner, scopes,
   last_used, status, created, actions. Long client_id (≈22 chars,
   e.g. "kPkFDgDN36DQufQ") needs the most room. */
.tbl .col-client-id { width: 220px; }
.tbl .col-name      { width: 180px; }
.tbl .col-owner     { width: 120px; }
.tbl .col-scopes    { width: 120px; }
.tbl .col-last-used { width: 150px; }
