/* ============================================================================
   KinetiqAF — canonical component layer  (refactor/design-coherence)
   ----------------------------------------------------------------------------
   ONE component DNA for the two PRODUCT surfaces (/app + /admin) on top of the
   already-shared token layer (public/styles/design-tokens.css). Loaded LAST in
   <head> on app.html + admin.html (and index.html) so it is authoritative — it
   reconciles the component-level drift that had accumulated between the two
   portals' inline stylesheets.

   Per the 2026-07-08 cross-surface inventory, the two portals already AGREE on
   most components (secondary button, page-header, form inputs, modal, toast,
   empty state, nav/notif badges). The genuine drift reconciled here — canonical
   = the client portal's newer clinical-blue pass (docs/UX_RUBRIC.md):

     • card        — flat "Editorial Calm" card (was elevated + white on /admin)
     • pill status — clinical teal / amber (was legacy --green/--red on /admin)
     • btn-gold    — hover keeps the warm CTA readable (--ink, not #fff)
     • tab bar     — .kaf-subtabbar standardized on var(--primary)

   Built strictly from existing design tokens. Scoped per-portal overrides
   (e.g. `.portal-main .card`) keep their higher specificity and still layer on
   top of these bases — intentional. cog-simplified overrides live inline in
   app.html at higher specificity and are unaffected.

   FOLLOW-UP (deferred, see docs/UX_BACKLOG.md FU-component-drift-meta): remove
   the now-superseded inline copies of these rules from app.html (defined twice —
   blocks A + C) once a careful dedup pass can verify no scoped override depends
   on them; migrate the remaining already-identical components + the legacy
   per-feature tab bars (.exh-tab / .session-tab / …) onto these classes.
   ========================================================================== */

/* ── Z-index ladder — the ONE documented stacking scale ───────────────────────
   Every fixed / overlay layer references one of these tokens so nothing ever
   opens into a hidden layer. This is the fix for the PR-616 sheet-under-logger and
   the 2026-07-10 drawer-modal-stacking class: a modal launched from INSIDE the
   client drawer must render ABOVE it and be hit-testable, never trapped beneath.

   Ladder (low → high) — read it as a promise about what covers what:
     --z-chrome   sidebar, sticky headers, in-page dropdowns / overlays
     --z-drawer   the full-height client drawer (body-level side panel)
     --z-modal    modal-overlay, sheets, drawer-launched side panels — ALWAYS
                  above the drawer so a modal opened from within it is visible
     --z-modal-top a layer that must sit over an open modal (photo lightbox)
     --z-toast    toasts / notifications — above everything

   Rule of thumb for new overlays: pick the token for the tier, never a bare
   number. If two things at the same tier need ordering, rely on DOM order
   (later sibling wins) rather than inventing an in-between number. */
:root {
  --z-chrome: 200;
  --z-drawer: 1200;
  --z-modal: 1300;
  --z-modal-top: 1400;
  --z-toast: 9999;
}

/* ── Card — flat Editorial-Calm (Sprint 12B), canonical from /app ─────────── */
.card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 1.5rem;
  margin-bottom: 1.25rem;
  box-shadow: none;
}
.card--featured {
  background: var(--paper-2);
  border: 1px solid var(--line);
  box-shadow: 0 1px 2px rgba(45, 36, 25, .04);
  transition: box-shadow var(--d-base) var(--ease-out),
              transform var(--d-base) var(--ease-out);
}
.card--featured:hover {
  box-shadow: 0 4px 12px rgba(45, 36, 25, .08), 0 1px 2px rgba(45, 36, 25, .04);
  transform: translateY(-1px);
}

/* ── Badge / pill — clinical status palette, canonical from /app ──────────── */
.pill-blue  { background: var(--frost);          color: var(--sky); border: 1px solid var(--mist); }
.pill-gold  { background: var(--goldfaint);      color: var(--amber); }
.pill-green { background: var(--teal-50, #e1f5ee); color: var(--teal-800, #085041); } /* success → brand teal */
.pill-red   { background: rgba(224, 149, 74, .16); color: var(--accent-warm-deep, #985e15); } /* overdue → amber */
.pill-gray  { background: var(--parchment);      color: var(--muted); }

/* ── Primary warm CTA — hover keeps text readable on the warm fill ────────── */
.btn-gold:hover { color: var(--ink); }

/* ── Tab bar — the #619 primitive, standardized on var(--primary) ─────────── */
.kaf-subtab.is-active         { color: var(--ink); border-bottom-color: var(--primary); }
.kaf-subtab:focus-visible     { outline: 2px solid var(--primary); outline-offset: 2px; }

/* ── Page-header italic-accent voice (refactor/design-coherence-3) ─────────── */
/* The brand's page-header voice — an italicized, sky-accented word — is already
   the standard on .page-title (landing + admin). Extend it to the client portal's
   shared PageHeader (.kaf-ph-title) so BOTH header systems carry one voice. The
   accent word is opt-in per header via renderPageHeader({ accent }); a header with
   a single-word title simply carries no <em> (most client sections). Gated OFF in
   cog-simplified mode — that overlay wants plain, high-legibility text, not a
   decorative italic (mirrors the .page-title em gating). */
.kaf-page-header h1.kaf-ph-title em { font-style: italic; color: var(--sky); }
body.cognitive-simplified .kaf-page-header h1.kaf-ph-title em { font-style: normal; color: inherit; }

/* ── Table / list skin — the approved mock (feat/table-skin-refresh, 2026-07-11) ────
   "Same page, new skin." REPLACES the dark-header table treatment (deleted from the
   admin.html + app.html inline blocks). No dark header bar, no outer chrome box,
   hairline row separators, quiet hover, and hover-revealed QUIET-OUTLINE row actions.
   FILLED buttons are banned inside rows — at most ONE filled-primary per view, in the
   page header. Numbers are the mock's, verbatim. The arbiter for "does this match?" is
   docs/design-refs/table-skin-reference.html (built from these exact classes). */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }  /* structural scroll only — no border/radius box */

table { width: 100%; border-collapse: collapse; font-size: var(--t-small); }

/* Header — no background bar, no border of its own. */
thead tr { background: transparent; }
thead th {
  background: transparent; border: none;
  padding: 6px 8px; text-align: left; white-space: nowrap;
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  font-weight: 600; color: var(--muted);           /* #5a6b73 ≈ 4.9:1 on #fff — AA for 11px bold caps */
}

/* Data row — transparent, hairline top separator, quiet hover. NO zebra, NO box. */
tbody tr {
  background: transparent;
  border-top: 1px solid var(--frost);
  transition: background 140ms ease-out;
}
tbody tr:first-child { border-top: none; }
tbody tr:hover, tbody tr:focus-within { background: var(--surface-alt); border-radius: 8px; }

tbody td { padding: 13px 8px; vertical-align: middle; font-size: 13px; color: var(--muted-strong); }  /* target row ≈ 48–52px */
tbody td.cell-primary { font-size: 14px; font-weight: 600; color: var(--ink); }   /* name */
tbody td.cell-muted, .td-muted { font-size: 13px; color: var(--muted); }          /* muted / empty ("—") */
.td-num { font-family: var(--mono); font-size: 13px; }
.cell-lead-icon { width: 18px; height: 18px; color: var(--muted-strong); }        /* leading icon — never ink-black / brand-filled */

/* Row actions (the restraint rule). Resting: hidden/quiet. Reveal on hover/focus-within
   (keyboard-reachable, not hover-only). Touch: always shown. */
.row-actions { display: inline-flex; align-items: center; gap: .4rem; opacity: 0; transition: opacity 140ms ease-out; }
tbody tr:hover .row-actions, tbody tr:focus-within .row-actions, .row-actions:focus-within { opacity: 1; }
@media (hover: none) { .row-actions { opacity: 1; } }

/* Primary row action — a QUIET OUTLINE (transparent fill, never a filled button).
   Visual = 12px + 5px 12px padding; the 44px touch target is an inset hit-area that
   doesn't inflate the row height. */
.row-action-primary {
  position: relative; font-size: 12px; padding: 5px 12px; font-weight: 600;
  border: 1px solid var(--line); background: transparent; color: var(--ink-soft);
  border-radius: var(--r-chip); cursor: pointer; font-family: var(--sans); white-space: nowrap;
}
.row-action-primary:hover { border-color: var(--ink-faint); }
.row-action-primary:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.row-action-primary::after { content: ''; position: absolute; inset: -11px 0; }   /* → ≥44px touch height */
/* Secondary row actions — ghost text, no border. */
.row-action-ghost {
  position: relative; font-size: 12px; padding: 5px 8px;
  border: none; background: transparent; color: var(--muted-strong);
  cursor: pointer; font-family: var(--sans); white-space: nowrap;
}
.row-action-ghost:hover { color: var(--ink); }
.row-action-ghost:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.row-action-ghost::after { content: ''; position: absolute; inset: -11px 0; }
@media (prefers-reduced-motion: reduce) { tbody tr, .row-actions { transition: none; } }

/* ── Toast (migrated from app.html blocks A/C) ────────────────────────────── */
#toast {
  position:fixed; bottom:2rem; right:2rem;
  background:var(--ink); color:var(--white);
  padding:.8rem 1.2rem; border-radius:var(--r-card);
  font-size:var(--t-small); z-index:9999;
  transform:translateY(100px); opacity:0;
  transition:.3s cubic-bezier(.22,.68,0,1.2);
  max-width:300px; box-shadow:var(--elev-3);
}
#toast.show { transform:translateY(0); opacity:1; }
#toast.success { border-left:3px solid var(--green); }
#toast.error { border-left:3px solid var(--red); }

/* ── Empty state (migrated from app.html blocks A/C) ── */
.empty { text-align:center; padding:3rem 1rem; color:var(--muted); }
.empty-icon { font-size:var(--t-display-md); margin-bottom:.65rem; opacity:.3; }
.empty-text { font-size:var(--t-small); }

/* ── Badges (migrated from app.html blocks A/C) ── */
.nav-badge {
  margin-left:auto; background:var(--gold); color:#fff;
  font-size:var(--t-micro); font-weight:700; padding:.1rem .45rem; border-radius:99px;
}
.notif-badge {
  display:inline-flex; align-items:center; justify-content:center;
  min-width:18px; height:18px; padding:0 5px;
  background:var(--red); color:var(--white);
  font-size:var(--t-micro); font-weight:700; border-radius:99px;
  margin-left:auto; flex-shrink:0;
  animation:badge-pop .2s cubic-bezier(.22,.68,0,1.4) both;
}

/* ── Buttons (migrated from app.html blocks A/C) ── */
.btn {
  display:inline-flex; align-items:center; gap:.38rem;
  padding:.62rem 1.2rem; border-radius:var(--r-chip);
  font-family:var(--sans); font-size:var(--t-tiny); font-weight:700;
  letter-spacing:.04em; cursor:pointer;
  border:1px solid transparent;
  text-decoration:none; white-space:nowrap; user-select:none;
  transition: background var(--d-fast) var(--ease-out),
              color var(--d-fast) var(--ease-out),
              border-color var(--d-fast) var(--ease-out),
              box-shadow var(--d-fast) var(--ease-out),
              transform var(--d-fast) var(--ease-out);
}
.btn:focus { outline:none; }
.btn:focus-visible { outline:none; box-shadow: var(--focus-ring); }
.btn:disabled, .btn[aria-disabled="true"] {
  opacity:.5; cursor:not-allowed; pointer-events:none;
}
.btn-primary {
  background: var(--gold); color:#fff;
  border-color: var(--gold-deep);
  box-shadow: var(--shadow-1);
}
.btn-primary:hover {
  background: var(--gold2);          /* slightly brighter (var(--gold2)) */
  transform: translateY(-1px);
  box-shadow: var(--shadow-2);
}
.btn-primary:active {
  background: var(--gold-deep); color: var(--paper);
  transform: translateY(0);
  box-shadow: var(--shadow-1);
}
.btn-gold {
  background: var(--gold); color:#fff;
  border-color: var(--gold-deep);
  box-shadow: var(--shadow-1);
}
.btn-gold:hover {
  background: var(--gold2); color: var(--ink);
  transform: translateY(-1px);
  box-shadow: var(--shadow-2);
}
.btn-gold:active {
  background: var(--gold-deep); color: var(--paper);
  transform: translateY(0);
  box-shadow: var(--shadow-1);
}
.btn-secondary {
  background: var(--paper); color: var(--ink-soft);
  border-color: var(--line); border-width: 1.5px;
}
.btn-secondary:hover {
  background: var(--paper-2);
  border-color: var(--ink-faint); color: var(--ink);
}
.btn-secondary:active { background: var(--paper-3); border-color: var(--ink-faint); }
.btn-tertiary {
  background: transparent; color: var(--ink-soft);
  border-color: transparent;
}
.btn-tertiary:hover { background: var(--paper-2); color: var(--ink); }
.btn-tertiary:active { background: var(--paper-3); }
.btn-danger {
  background: transparent; color: var(--danger);
  border-color: transparent;
}
.btn-danger:hover { background: var(--redf); color: var(--danger-strong); }
.btn-danger:active { background: #f5cccc; }
.btn-danger-strong {
  background: var(--danger); color: var(--paper);
  border-color: var(--danger-strong);
  box-shadow: var(--shadow-1);
}
.btn-danger-strong:hover {
  background: var(--danger-strong);
  transform: translateY(-1px);
  box-shadow: var(--shadow-2);
}
.btn-danger-strong:active {
  background: #6b1f23; transform: translateY(0);
  box-shadow: var(--shadow-1);
}
.btn-sm { padding:.45rem .85rem; font-size:var(--t-micro); min-height:32px; }
.btn-group { display:flex; gap:.5rem; flex-wrap:wrap; margin-top:1rem; }

/* ── Form inputs (migrated from app.html blocks A/C) ── */
.form-group { display:flex; flex-direction:column; gap:.28rem; margin-bottom:.75rem; }
.form-group.full { grid-column:1/-1; }
.form-group label { font-size:var(--t-micro); font-weight:700; letter-spacing:.11em; text-transform:uppercase; color:var(--muted); }
.form-group input,
.form-group select,
.form-group textarea {
  padding:.72rem .95rem;
  border:1.5px solid rgba(12,21,33,.11);
  border-radius:var(--r-chip);
  font-family:var(--sans); font-size:var(--t-small);
  color:var(--body); background:var(--paper); transition:.18s; outline:none;
}
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  border-color:var(--sky); background:var(--white);
  box-shadow:0 0 0 3px rgba(42,125,181,.1);
}
.form-group textarea { resize:vertical; min-height:80px; line-height:1.5; }

/* ── Modal (migrated from app.html blocks A/C) ── */
.modal-overlay {
  position:fixed; inset:0; z-index:var(--z-modal); /* ladder: ALWAYS above the drawer */
  background:rgba(7,16,28,.7); backdrop-filter:blur(6px);
  display:none; align-items:center; justify-content:center; padding:1rem;
}
.modal-overlay.open { display:flex; }
.modal {
  background:var(--white); border-radius:var(--r-lg);
  width:100%; max-width:680px; max-height:90vh; overflow-y:auto;
  box-shadow:var(--elev-4);
  animation:modal-in .2s cubic-bezier(.22,.68,0,1.15) both;
}
.modal-header {
  padding:1.5rem; border-bottom:1px solid var(--parchment);
  display:flex; align-items:center; justify-content:space-between;
  position:sticky; top:0; background:var(--white); z-index:1;
}
.modal-title { font-family:var(--serif); font-size:var(--t-h2); font-weight:700; color:var(--ink); }
.modal-close {
  min-width:44px; min-height:44px; border-radius:50%;
  background:var(--paper); border:none; font-size:var(--t-h2);
  color:var(--muted); cursor:pointer; transition:.2s;
  display:flex; align-items:center; justify-content:center;
}
.modal-close:hover { background:var(--redf); color:var(--red); }
.modal-close:focus-visible { outline:2px solid var(--sky); outline-offset:2px; }
.modal-body { padding:1.5rem; }
.modal-footer {
  padding:1rem 1.5rem; border-top:1px solid var(--parchment);
  display:flex; justify-content:flex-end; gap:.5rem;
  position:sticky; bottom:0; background:var(--white);
}

/* ── Form section heading (migrated from app.html blocks A/C) ──────────────────
   A section-divider LABEL — NOT an input. The #625 dedup erroneously fused this
   heading style into the .form-group input/select selector list; restored as its
   own rule so inputs keep their input typography. */
.form-section {
  font-size:var(--t-micro); font-weight:700; letter-spacing:.15em; text-transform:uppercase;
  color:var(--sky); padding:.5rem 0; border-bottom:1px solid var(--frost);
  margin:1.25rem 0 .75rem;
}

/* ── Page title (migrated from app.html blocks A/C) ── */
.page-title {
  /* Sprint 12B-1: page-title uses --t-display-md (2rem ≈ 32px).
     Was 1.9rem hardcoded — the type scale's 1.2 ratio bumps this
     to 2rem, which reads as a more confident headline at the
     editorial-calm tone. Letter-spacing stays tight per the
     research brief (serif headings, tight tracking). */
  font-family:var(--serif); font-size:var(--t-display-md); font-weight:700;
  color:var(--ink); margin:0 0 .2rem; letter-spacing:-.03em; line-height:1.15;
}
.page-title em { font-style:italic; color:var(--sky); }

/* ── Page subtitle (migrated from app.html blocks A/C) ── */
.page-sub { font-size:var(--t-small); color:var(--muted); margin-bottom:1.75rem; line-height:1.5; }

/* ── Card hero + title (migrated from app.html blocks A/C) ──────────────────
   .card / .card--featured / .card--featured:hover already canonical above.
   Cascade note: the Sprint-16 `.card--featured` box-shadow override and the
   `body:not(.cognitive-simplified) .card--hero` gradient stay inline in
   app.html — they layer on top of these base rules exactly as before. */
.card--hero {
  /* Sprint 13 PR 1 (2026-05-22) — hero stops being a container.
     Per the portal-polish-proposal: "the hero is the typography
     + the breathing room. Default cards keep their hairline (they
     are still cards), but the hero stops competing visually by
     escaping the box."

     Pre-13 hero: gradient bg + border + 4px accent stripe + heavy
     shadow + generous padding. Read as "biggest card on the page"
     not as "the focal point." The boxes-on-boxes feeling persisted.

     Sprint 13 PR 1 hero: transparent, borderless, shadowless. Lives
     on paper directly. Hierarchy comes from typography weight,
     generous vertical rhythm (3rem bottom margin), and the
     restraint of having no peers vying for the same visual layer.

     Structural note for future PR: left-aligned typography in a
     container that can later become a 2-col grid (coach photo +
     content) without HTML restructuring. The hero's children stack
     vertically by default; a future modifier class can split the
     hero into a photo column + content column. No structural
     commitment to that grid in PR 1 — just keeping the door open. */
  background: transparent;
  border: none;
  border-radius: 0;
  padding: 1.5rem 0 2rem;
  margin-bottom: 3rem;
  box-shadow: none;
  position: relative;
  overflow: visible;
}
.card--hero::before {
  /* Accent stripe retired per the portal-polish-proposal: section-
     accent variety reads "dashboard." Single warm accent (clay) is
     reserved for primary CTAs, not for visual decoration on every
     hero card. */
  display: none;
}
.card--hero > .card-title,
.card--hero .card-title:first-child {
  /* Hero title is the section anchor: BIG serif, near-black, tight
     letter-spacing. The same display-md size from Phase 1.5 carries
     over — what changed is the container around it. */
  font-family: var(--serif);
  font-size: var(--t-display-md);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -.02em;
  border-bottom: none;
  padding-bottom: 0;
  margin-bottom: 1rem;
  color: var(--ink);
}
@media (max-width: 640px) {
  .card--hero {
    padding: 1rem 0 1.5rem;
    margin-bottom: 2rem;
  }
  .card--hero > .card-title,
  .card--hero .card-title:first-child {
    font-size: var(--t-h1);
  }
}
.card-title {
  /* Sprint 12B-1: card-title uses --t-h2 (1.25rem ≈ 20px) — was
     1rem (16px), which read as body-weight. Bumping to --t-h2
     restores the visual hierarchy card title → card body. */
  font-family:var(--serif); font-size:var(--t-h2); font-weight:700;
  color:var(--ink); margin:0 0 1rem; padding-bottom:.65rem;
  border-bottom:1px solid var(--parchment);
  display:flex; align-items:center; gap:.5rem;
}
.card-title .badge {
  font-family:var(--sans); font-size:var(--t-micro); font-weight:700;
  padding:.18rem .5rem; border-radius:99px;
  background:var(--frost); color:var(--sky);
  letter-spacing:.07em; text-transform:uppercase;
}
.card-title .badge.gold { background:var(--goldfaint); color:var(--amber); }

/* ── Pill base + icon (migrated from app.html blocks A/C) ───────────────────
   Merge of the two inline `.pill` rules: the base (layout + font-size:t-micro
   + font-weight:700) and a dead `.pill { font-weight:600 }` that the later
   block-C base already overrode to 700. Canonical keeps 700 (today's computed
   result). .pill-* colour variants already canonical above. */
.pill {
  display:inline-flex; align-items:center; gap:.3rem; /* designv2 PHASE 5: gap for an optional Lucide leading icon (no effect on text-only pills) */
  padding:.18rem .65rem; border-radius:99px;
  font-size:var(--t-micro); font-weight:700; letter-spacing:.05em; text-transform:uppercase;
}
.pill svg.lucide-icon { flex:0 0 auto; width:12px; height:12px; }

/* ── Auth / login card (migrated from app.html blocks A/C) ──────────────────
   Dark login surface shared by /app + /admin. Canonical = the block-C winner
   (block A's heavier .auth-err was dead). admin.html keeps its own inline
   copies (load after → win) until it adopts the canon; index doesn't use it.
   Includes @keyframes rise (was duplicated in both blocks). */
.auth-box {
  background: rgba(18,32,50,.94);
  backdrop-filter: blur(32px) saturate(1.4);
  border: 1px solid rgba(255,255,255,.08);
  border-radius: var(--r-lg);
  padding: 3.5rem 3rem;
  width: 100%; max-width: 420px;
  box-shadow: var(--elev-4);
  animation: rise .45s cubic-bezier(.22,.68,0,1.15) both;
}
@keyframes rise {
  from { opacity:0; transform: translateY(20px) scale(.98); }
}
.auth-logo {
  font-family: var(--serif);
  font-size: var(--ds-36); font-weight: 700;
  color: var(--white); margin-bottom: .15rem;
  letter-spacing: -.03em; text-align: center;
}
.auth-logo span { color: var(--gold); font-style: italic; }
.auth-sub {
  font-size: var(--t-micro); color: rgba(255,255,255,.3);
  letter-spacing: .2em; text-transform: uppercase;
  text-align: center; margin-bottom: 2.5rem;
}
.auth-tabs { display:flex; margin-bottom:1.75rem; border:1px solid rgba(255,255,255,.08); border-radius:var(--r-chip); overflow:hidden; }
.auth-tab { flex:1; padding:.55rem; font-size:var(--t-micro); font-weight:600; letter-spacing:.07em; text-transform:uppercase; cursor:pointer; border:none; background:transparent; color:rgba(255,255,255,.3); transition:.2s; }
.auth-tab.active { background:var(--steel); color:var(--white); }
.auth-field { margin-bottom:1.1rem; }
.auth-field label { display:block; font-size:var(--t-micro); font-weight:700; letter-spacing:.12em; text-transform:uppercase; color:rgba(255,255,255,.3); margin-bottom:.45rem; }
.auth-field input {
  width:100%; padding:.8rem 1rem; min-height:48px;
  background:rgba(255,255,255,.05); border:1px solid rgba(255,255,255,.09);
  border-radius:var(--r-chip); color:var(--white); font-size:var(--t-small); outline:none; transition:.2s;
}
.auth-field input:focus { border-color:rgba(44,125,160,.5); background:rgba(255,255,255,.08); box-shadow:0 0 0 3px rgba(44,125,160,.12); }
.auth-field input::placeholder { color:rgba(255,255,255,.18); }
.auth-btn {
  width:100%; padding:.88rem 1rem; margin-top:.5rem; min-height:48px;
  background: var(--gold);
  /* WCAG: white-on-primary (#FFF on var(--primary) ≈ 4.6:1) — the prior dark-ink
     text worked on gold but fails on the blue primary. */
  color: #fff; border:none; border-radius:var(--r-chip);
  font-family:var(--sans); font-size:var(--t-small); font-weight:700;
  letter-spacing:.1em; text-transform:uppercase; cursor:pointer; transition:.2s;
  box-shadow: 0 4px 20px rgba(44,125,160,.3);
}
.auth-btn:hover { background:var(--gold2); box-shadow:0 6px 28px rgba(44,125,160,.42); transform:translateY(-1px); }
.auth-btn:active { transform:translateY(0); }
.auth-err { font-size:var(--t-tiny); color:#f87171; margin-top:.75rem; min-height:1.1rem; text-align:center; }
.auth-note { font-size:var(--t-micro); color:rgba(255,255,255,.18); margin-top:.75rem; text-align:center; }

/* ── Page grammar primitives (feat/page-grammar, 2026-07) ─────────────────────
   The admin portal's design grammar: one job statement · one context sentence ·
   one hero zone · ONE primary action · everything else quiet. Canonical here so
   every page inherits ONE density standard + ONE microinteraction standard.
   Spacing is an 8px-based rhythm; whitespace (not borders) separates. Admin stays
   dense AND calm (Carbon/Lightning). WCAG AA + 44px targets + reduced-motion. */

/* kaf-pagehead — title + context sentence + ONE primary action (right-aligned). */
.kaf-pagehead {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-bottom: 1.5rem;
}
.kaf-pagehead-main { min-width: 0; }
.kaf-pagehead-context {
  font-size: var(--t-small); color: var(--muted);
  margin-top: .35rem; line-height: 1.5; max-width: 60ch;
}
.kaf-pagehead-actions { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; flex-shrink: 0; }

/* kaf-hero — the page's dominant first zone; senior via whitespace, not a box. */
.kaf-hero { margin: .25rem 0 2rem; }
.kaf-hero-label {
  font-size: var(--t-micro); font-weight: 700; text-transform: uppercase;
  letter-spacing: .1em; color: var(--muted); margin-bottom: .6rem;
  display: flex; align-items: center; justify-content: space-between; gap: .75rem;
}

/* Shared row primitives — ONE density standard (56px rows, 8px rhythm, hairlines). */
.kaf-list { display: flex; flex-direction: column; }
.kaf-queue-row, .kaf-person-row {
  display: flex; align-items: center; gap: .85rem;
  /* feat/table-skin-refresh — aligned to the ONE row standard: --frost hairline
     separator + --surface-alt hover with an 8px radius (was --primary-a08 / --primary-a05);
     min-height 52px to hit the mock's 48–52px target. Padding stays .5rem — with the
     36px avatar that already lands on the target height (a td's 13px 8px is for
     text-only cells). */
  padding: .5rem .5rem; min-height: 52px;
  border-bottom: 1px solid var(--frost);
  transition: background 140ms ease-out;
}
.kaf-queue-row:last-child, .kaf-person-row:last-child { border-bottom: none; }
.kaf-queue-row:hover, .kaf-person-row:hover, .kaf-person-row:focus-within { background: var(--surface-alt); border-radius: 8px; }
.kaf-person-row { cursor: pointer; }

/* Avatar (shared) — 36px initials circle. */
.kaf-row-avatar {
  flex: 0 0 auto; width: 36px; height: 36px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--ink), var(--ink4)); color: var(--gold);
  font-size: var(--t-micro); font-weight: 700;
}

/* kaf-queue-row — avatar + name + one-line reason + ONE contextual action. */
.kaf-queue-body { flex: 1; min-width: 0; }
.kaf-queue-name { font-size: var(--t-small); font-weight: 700; color: var(--ink); }
.kaf-queue-reason { font-size: var(--t-micro); color: var(--muted); margin-top: .1rem; line-height: 1.4; }
.kaf-queue-row > .btn { flex: 0 0 auto; }

/* kaf-person-row — avatar + name/type + insight | right metric | hover actions. */
.kaf-person-main { flex: 1; min-width: 0; }
.kaf-person-nameline { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.kaf-person-name { font-size: var(--t-small); font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kaf-person-insight { font-size: var(--t-micro); color: var(--muted); margin-top: .12rem; line-height: 1.4; }
.kaf-person-metric { flex: 0 0 auto; text-align: right; font-size: var(--t-micro); color: var(--muted); line-height: 1.4; }
.kaf-person-actions { flex: 0 0 auto; display: flex; gap: .35rem; align-items: center; opacity: 0; transition: opacity .14s ease-out; }
.kaf-person-row:hover .kaf-person-actions,
.kaf-person-row:focus-within .kaf-person-actions { opacity: 1; }
/* Touch devices have no hover — keep row actions + select always reachable. */
@media (hover: none) { .kaf-person-actions { opacity: 1; } }

/* Microinteraction standard — pressed states on canonical buttons. */
.btn:active { transform: translateY(.5px); }

/* Reduced-motion: drop every grammar transition/transform. */
@media (prefers-reduced-motion: reduce) {
  .kaf-queue-row, .kaf-person-row, .kaf-person-actions, .btn { transition: none; }
  .btn:active { transform: none; }
}
