/* CareerCompass — hand-written from tokens.css. No frameworks. */
* { margin: 0; padding: 0; box-sizing: border-box; }
html { font-size: var(--fs-base); }
body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  font-size: var(--fs-base);
}
h1, h2, h3, h4 { letter-spacing: -0.01em; font-weight: 600; }
h1 { font-size: var(--fs-h1); }
a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hover); }
button { font-family: inherit; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
::selection { background: var(--accent-soft); }

/* ---------------- buttons ---------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  height: 40px; padding: 0 var(--sp-4);
  border-radius: var(--radius-card); border: 1px solid transparent;
  font-size: var(--fs-base); font-weight: 500; cursor: pointer;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
.btn svg { width: 16px; height: 16px; }
.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-hover); }
.btn-secondary { background: var(--surface); border-color: var(--border); color: var(--text); }
.btn-secondary:hover { border-color: var(--border-strong); }
.btn-ghost { background: transparent; color: var(--text-2); }
.btn-ghost:hover { color: var(--text); background: var(--surface-2); }
.btn-sm { height: 32px; padding: 0 var(--sp-3); font-size: var(--fs-small); border-radius: 8px; }
.btn:disabled, .btn[disabled] { opacity: .5; cursor: default; pointer-events: none; }
.btn-danger { background: var(--surface); border-color: var(--border); color: var(--danger); }
.btn-danger:hover { border-color: var(--danger); background: var(--danger-soft); }

/* ---------------- cards ---------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: var(--sp-4);
  box-shadow: var(--shadow-card);
  transition: border-color var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease);
}
.card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-pop); }
.card-static:hover { border-color: var(--border); box-shadow: var(--shadow-card); }
.card-title { font-size: var(--fs-base); font-weight: 500; }
.card-caption { font-size: var(--fs-small); color: var(--text-2); margin-top: var(--sp-1); }
.card-head { display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: var(--sp-3); }

/* ---------------- labels ---------------- */
.eyebrow {
  font-size: var(--fs-small); text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-2); font-weight: 500;
}

/* ---------------- tables ---------------- */
.table-wrap { overflow-x: auto; }
table.tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.tbl thead th {
  background: var(--surface-2); text-align: left; font-weight: 500; color: var(--text);
  padding: var(--sp-2) var(--sp-3); min-height: 40px;
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0;
}
/* FX3: table headers may wrap (nowrap was forcing min-content widths wider than their
   cards at every viewport — the TABLE-OVERFLOW class). */
/* FX3: secondary columns hide when the CARD itself is narrow (container query — the
   viewport size is irrelevant: right-column cards overflow at 1440 too). */
.card { container-type: inline-size; }
@container (max-width: 560px) { .tbl .col-optional { display: none; } }
/* tier 2: at very narrow cards, the second-order columns and annotation chips go;
   the primary data + action controls must always fit without sideways scroll. */
@container (max-width: 460px) { .tbl .col-optional2 { display: none; } }
@container (max-width: 700px) { .tbl thead th, .tbl tbody td { padding-left: var(--sp-2); padding-right: var(--sp-2); } .tbl .btn-sm { padding-left: var(--sp-2); padding-right: var(--sp-2); } }
/* action cells: buttons never touch — inline-block pairs keep an 8px column gap,
   and when they must wrap the taller line box gives the stacked rows a 4px gap
   (the touching-buttons ADJACENCY/OVERLAP class). */
.tbl td.cell-actions { text-align: right; line-height: 36px; }
.tbl td.cell-actions .btn { vertical-align: middle; }
.tbl td.cell-actions .btn + .btn { margin-left: var(--sp-2); }
.tbl thead th.num, .tbl td.num { text-align: right; font-variant-numeric: tabular-nums; }
.tbl thead th.sortable { cursor: pointer; user-select: none; }
.tbl thead th.sortable:hover { color: var(--accent); }
.tbl .sort-ind { display: inline-block; margin-left: 4px; opacity: .45; font-size: 10px; }
.tbl tbody td { padding: 0 var(--sp-3); height: 44px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.tbl tbody tr { transition: background var(--dur-fast) var(--ease); }
.tbl tbody tr:hover { background: #F9FAFB; }
.tbl tbody tr.row-highlight { background: var(--accent-soft); transition: background 800ms var(--ease); }
.tbl tbody tr:last-child td { border-bottom: none; }
.tbl .cell-main { font-weight: 500; }
.tbl .cell-sub { font-size: var(--fs-small); color: var(--text-2); }

/* ---------------- forms ---------------- */
.field { display: flex; flex-direction: column; gap: var(--sp-1); margin-bottom: var(--sp-3); }
.field label { font-size: var(--fs-small); color: var(--text-2); }
.input, select.input, textarea.input {
  height: 40px; padding: 0 var(--sp-3);
  border: 1px solid var(--border); border-radius: var(--radius-input);
  font-family: inherit; font-size: 13px; color: var(--text); background: var(--surface);
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
  width: 100%;
}
textarea.input { height: auto; min-height: 56px; padding: var(--sp-2) var(--sp-3); resize: vertical; }
.input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px rgba(24, 24, 27, 0.12); }
.input::placeholder { color: var(--text-2); }
select.input { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; padding-right: 32px; }

/* ---------------- chips ---------------- */
.chip {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  border-radius: var(--radius-chip); padding: 0 var(--sp-3);
  font-size: var(--fs-small); font-weight: 500; line-height: 22px; white-space: nowrap;
}
.chip-success { background: var(--success-soft); color: var(--success); }
.chip-warning { background: var(--warning-soft); color: var(--warning); }
.chip-danger { background: var(--danger-soft); color: var(--danger); }
.chip-neutral { background: var(--surface-2); color: var(--text-2); }
.chip-ink { background: var(--accent-soft); color: var(--accent); }
.chip .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

/* ---------------- KPI ---------------- */
/* D6: captions sit on a common bottom baseline in every KPI row and clamp to 2 lines,
   so a long server delta never breaks the row's rhythm (layout.md › Visual hierarchy). */
.kpi { padding: var(--sp-4); display: flex; flex-direction: column; }
.kpi-label { font-size: var(--fs-small); color: var(--text-2); }
.kpi-value { font-size: var(--fs-kpi); font-weight: 600; letter-spacing: -0.02em; margin-top: var(--sp-1); font-variant-numeric: tabular-nums; }
.kpi-delta { font-size: var(--fs-small); margin-top: auto; padding-top: var(--sp-2); color: var(--text-2); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.kpi-delta.up { color: var(--success); }
.kpi-delta.down { color: var(--danger); }

/* ---------------- layout ---------------- */
/* MOBILE M1: full-height shell tracks 100dvh (Safari's collapsing URL bar never
   clips); the 100vh declaration stays as the fallback for older engines. */
.shell { display: flex; min-height: 100vh; min-height: 100dvh; }
.sidebar {
  width: var(--sidebar-w); flex: 0 0 var(--sidebar-w);
  background: var(--surface); border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; height: 100dvh;
}
.brand { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-4) var(--sp-4) var(--sp-1); }
.brand-glyph {
  width: 28px; height: 28px; border-radius: var(--radius-card);
  background: var(--accent); color: #fff; display: flex; align-items: center; justify-content: center; flex: 0 0 28px;
}
.brand-glyph svg { width: 16px; height: 16px; }
.brand-name { font-size: var(--fs-base); font-weight: 600; letter-spacing: -0.01em; }
.brand-tag { font-size: var(--fs-small); color: var(--text-2); }
.nav { flex: 1; overflow-y: auto; padding: 0 var(--sp-3); display: flex; flex-direction: column; } /* flex = no margin collapse: gaps sum to a steady 4/8/16 rhythm */
.nav-section { margin-top: var(--sp-4); margin-bottom: var(--sp-2); padding: 0 var(--sp-2); display: flex; flex-direction: column; gap: var(--sp-1); } /* 16 before header, 8 after, 4 between items (4px rhythm) */
.nav-item {
  position: relative; display: flex; align-items: center; gap: var(--sp-3);
  width: 100%; text-align: left; background: transparent; border: none; font-family: inherit;
  height: 36px; padding: 0 var(--sp-2); margin: 0;
  border-radius: 10px; cursor: pointer;
  color: var(--text); font-size: 13px;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.nav-item svg { width: 20px; height: 20px; color: var(--text-2); transition: color var(--dur-fast) var(--ease); flex: 0 0 20px; }
.nav-item:hover { background: var(--surface-2); }
.nav-item.active { background: var(--accent-soft); color: var(--accent); font-weight: 500; }
.nav-item.active svg { color: var(--accent); }
.nav-pill {
  position: absolute; left: calc(var(--sp-3) + var(--sp-2)); right: calc(var(--sp-3) + var(--sp-2)); height: 36px; /* D6: sit flush with the item box (20px), not 8px proud of it */
  background: var(--accent-soft); border-radius: 10px;
  transition: transform 200ms var(--ease);
  pointer-events: none; z-index: 0;
}
.nav-item { z-index: 1; }
.sidebar-foot { border-top: 1px solid var(--border); padding: var(--sp-4) calc(var(--sp-3) + var(--sp-2)); } /* D6: avatar/switch block shares the nav inset, off the edge */
.user-block { display: flex; align-items: center; gap: var(--sp-3); }
.avatar {
  width: 32px; height: 32px; border-radius: 8px; background: var(--accent-soft); color: var(--accent);
  display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 600; flex: 0 0 32px;
}
.user-name { font-size: 13px; font-weight: 500; }
.user-role { font-size: var(--fs-small); color: var(--text-2); }
.switch-role { margin-top: var(--sp-2); width: 100%; justify-content: flex-start; }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.topbar {
  height: var(--topbar-h); flex: 0 0 var(--topbar-h);
  background: var(--surface); border-bottom: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between;
  /* D6: on wide viewports the topbar controls align with the centered content column
     instead of hugging the viewport edge (sidebars.md/layout.md). */
  padding: 0 max(var(--sp-6), calc((100% - var(--content-max) - 48px) / 2));
  /* FX3 (ledger I-6): NOT sticky. A sticky topbar overlaps scrolled #view controls at
     swept positions (the STICKY-BAND class, 16 rows). Geometry fix, no chrome trick:
     chrome must never sit over content at any scroll position. The sidebar stays sticky
     (its rect never intersects #view controls). */
  position: relative; z-index: 20;
}
.crumb { font-size: var(--fs-small); color: var(--text-2); display: flex; align-items: center; gap: var(--sp-2); }
.crumb .cur { color: var(--text); font-weight: 600; }
.crumb svg { width: 14px; height: 14px; }
.topbar-right { display: flex; align-items: center; gap: var(--sp-3); }
.ai-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.ai-dot.up { background: var(--success); }
.ai-dot.down { background: var(--danger); }
.top-date { font-size: var(--fs-small); color: var(--text-2); }
.icon-btn {
  width: 32px; height: 32px; border-radius: 8px; border: none; background: transparent;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer; color: var(--text-2);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.icon-btn:hover { background: var(--surface-2); color: var(--text); }
.icon-btn svg { width: 18px; height: 18px; }
.seg { display: inline-flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.seg button {
  border: none; background: var(--surface); color: var(--text-2);
  font-size: var(--fs-small); font-weight: 500; padding: var(--sp-1) var(--sp-3); cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.seg button.active { background: var(--accent-soft); color: var(--accent); }
.user-chip { display: flex; align-items: center; gap: 8px; }
.user-chip .avatar { width: 28px; height: 28px; font-size: 11px; border-radius: 7px; }

.content { flex: 1; padding: var(--sp-6); max-width: calc(var(--content-max) + 48px); width: 100%; margin: 0 auto; }
/* FX3 (root of the ADJACENCY class): page sections stacked inside #view previously had
   ZERO distance between them (grid gaps live INSIDE a grid only), so the card at the
   bottom of one section sat flush on the card at the top of the next — 0px gaps even at
   1440x900. Adjacent-block margins (block-flow collapse keeps page-head rhythm at one
   --sp-6 gap) restore the vertical rhythm at every viewport, single-column included. */
.content > * + * { margin-top: var(--sp-6); }
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--sp-4); margin-bottom: var(--sp-6); flex-wrap: wrap; }
.page-head h1 { font-size: var(--fs-h1); font-weight: 600; }
.page-sub { color: var(--text-2); font-size: var(--fs-base); margin-top: var(--sp-1); }

.grid { display: grid; gap: var(--sp-4); }
/* grid children must not be forced wider than their track by table/card content
   (fixes horizontal page overflow at 1280 — .table-wrap scrolls internally instead) */
.grid > * { min-width: 0; }
.grid-kpi { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.admin-kpis { grid-template-columns: repeat(3, 1fr); } /* 6 admin KPIs -> two clean rows of three, no orphan card */
@media (max-width: 900px) { .admin-kpis { grid-template-columns: repeat(2, 1fr); } }
.grid-2-1 { grid-template-columns: 1.6fr 1fr; }
.grid-1-1 { grid-template-columns: 1fr 1fr; }
@media (max-width: 1000px) { .grid-2-1, .grid-1-1 { grid-template-columns: 1fr; } }
.stack { display: flex; flex-direction: column; gap: var(--sp-4); }

.chart-box { position: relative; height: 220px; }
.legend { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: var(--sp-3); }
.legend-row { display: flex; align-items: center; gap: 8px; font-size: var(--fs-small); color: var(--text-2); }
.legend-row .dot { width: 8px; height: 8px; border-radius: 2px; }
.legend-row .val { margin-left: auto; color: var(--text); font-variant-numeric: tabular-nums; }
.stacked-bar { display: flex; height: 8px; border-radius: 4px; overflow: hidden; margin: var(--sp-3) 0; background: var(--surface-2); }
.stacked-bar .seg-part { height: 100%; transition: width 600ms var(--ease); }

/* ---------------- role picker ---------------- */
.picker { min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; }
.picker-head { padding: var(--sp-12) var(--sp-6) var(--sp-6); max-width: 720px; margin: 0 auto; width: 100%; }
.picker-head h1 { font-size: 28px; letter-spacing: -0.02em; }
.picker-head p { color: var(--text-2); margin-top: var(--sp-2); }
.picker-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--sp-4); padding: 0 var(--sp-6) var(--sp-12); max-width: 1100px; margin: 0 auto; width: 100%; }
.role-card { padding: var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-3); cursor: default; min-height: 180px; } /* equal heights across picker rows */
.role-card .rc-top { display: flex; align-items: center; gap: var(--sp-3); }
.rc-glyph { width: 36px; height: 36px; border-radius: 10px; background: var(--accent-soft); color: var(--accent); display: flex; align-items: center; justify-content: center; flex: 0 0 36px; }
.rc-glyph svg { width: 20px; height: 20px; }
.rc-name { font-weight: 600; font-size: var(--fs-base); }
.rc-role { font-size: var(--fs-small); color: var(--text-2); }
.rc-desc { font-size: 13px; color: var(--text-2); flex: 1; }
.picker-foot { display: flex; align-items: center; justify-content: space-between; padding: 0 var(--sp-6) var(--sp-8); max-width: 1100px; margin: 0 auto; width: 100%; }
.replay-link { color: var(--text-2); font-size: 13px; cursor: pointer; background: none; border: none; }
.replay-link:hover { color: var(--accent); }

/* ---------------- assistant chat ---------------- */
.chat-view { position: absolute; inset: 0; display: flex; background: var(--bg); z-index: 30; }
.chat-rail { width: var(--sidebar-w); flex: 0 0 var(--sidebar-w); background: var(--surface); border-right: 1px solid var(--border); display: flex; flex-direction: column; } /* same width as the app sidebar — one rhythm */
.chat-rail-head { padding: var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-3); }
.conv-list { flex: 1; overflow-y: auto; padding: 0 var(--sp-2); display: flex; flex-direction: column; gap: var(--sp-1); }
.conv-item { padding: var(--sp-2) var(--sp-3); border-radius: 8px; cursor: pointer; transition: background var(--dur-fast) var(--ease); }
.conv-item:hover { background: var(--surface-2); }
.conv-item.active { background: var(--surface-2); }
.conv-title { font-size: 13px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.conv-time { font-size: 11px; color: var(--text-2); }
.chat-main { flex: 1; display: flex; flex-direction: column; min-width: 0; background: var(--surface); }
.chat-head { height: var(--topbar-h); flex: 0 0 var(--topbar-h); border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; padding: 0 var(--sp-6); }
.chat-head-left { display: flex; align-items: center; gap: var(--sp-3); }
.advisor-name { font-weight: 600; font-size: var(--fs-base); }
.advisor-cap { font-size: var(--fs-small); color: var(--text-2); }
.chat-msgs { flex: 1; overflow-y: auto; padding: var(--sp-6) 0; scroll-behavior: smooth; }
.msgs-inner { max-width: 720px; margin: 0 auto; padding: 0 var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-6); }
.msg { display: flex; flex-direction: column; gap: var(--sp-2); }
.msg.user { align-items: flex-end; }
.msg.user .bubble { background: var(--surface-2); border-radius: 16px; padding: var(--sp-3) var(--sp-4); max-width: 85%; white-space: pre-wrap; }
.msg.ai .bubble { background: transparent; max-width: 100%; line-height: 1.6; }
.msg.ai .bubble p { margin-bottom: 8px; }
.msg.ai .bubble p:last-child { margin-bottom: 0; }
.msg.ai .bubble ul, .msg.ai .bubble ol { margin: var(--sp-2) 0 var(--sp-2) 20px; }
.msg.ai .bubble code { background: var(--surface-2); padding: 0 var(--sp-1); border-radius: 4px; font-size: 12px; }
.msg.ai .bubble pre { background: var(--surface-2); border-radius: 8px; padding: 12px; overflow-x: auto; margin: 8px 0; }
.msg.ai .bubble pre code { background: none; padding: 0; }
.msg.ai .bubble strong { font-weight: 600; }
.tool-chip {
  display: inline-flex; align-items: center; gap: var(--sp-2); align-self: flex-start;
  background: var(--accent-soft); color: var(--accent); border-radius: 999px;
  font-size: 11px; padding: var(--sp-1) var(--sp-3); cursor: pointer; border: none; font-family: inherit;
  transition: opacity var(--dur-fast) var(--ease);
}
.tool-chip:hover { opacity: .8; }
.tool-chip svg { width: 12px; height: 12px; }
.tool-detail { display: none; margin: 4px 0 4px 4px; font-size: 12px; color: var(--text-2); background: var(--surface-2); border-radius: 8px; padding: var(--sp-2) var(--sp-3); max-height: 220px; overflow: auto; white-space: pre-wrap; font-family: ui-monospace, monospace; }
.tool-detail.open { display: block; animation: fadeUp var(--dur-base) var(--ease); }
.typing { display: inline-flex; gap: 4px; padding: 6px 0; }
.typing span { width: 4px; height: 4px; border-radius: 50%; background: var(--text-2); animation: typingPulse 1s infinite var(--ease); }
.typing span:nth-child(2) { animation-delay: 150ms; }
.typing span:nth-child(3) { animation-delay: 300ms; }
@keyframes typingPulse { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }
.caret { display: inline-block; width: 2px; height: 14px; background: var(--accent); vertical-align: -2px; margin-left: 1px; animation: blink 1s step-end infinite; }
@keyframes blink { 50% { opacity: 0; } }
.chat-foot { border-top: 1px solid var(--border); padding: var(--sp-3) var(--sp-4) var(--sp-4); }
.composer-wrap { max-width: 720px; margin: 0 auto; }
.quick-row { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: var(--sp-2); }
.quick-chip { background: var(--surface-2); border: none; border-radius: var(--radius-chip); padding: var(--sp-1) var(--sp-3); font-size: var(--fs-small); color: var(--text); cursor: pointer; font-family: inherit; transition: background var(--dur-fast) var(--ease); }
.quick-chip:hover { background: var(--accent-soft); }
.composer { display: flex; gap: var(--sp-2); align-items: flex-end; border: 1px solid var(--border); border-radius: var(--radius-input); padding: var(--sp-2); transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease); }
.composer:focus-within { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(24, 24, 27, 0.12); }
.composer textarea { flex: 1; border: none; resize: none; font-family: inherit; font-size: 13px; line-height: 1.5; max-height: 96px; background: transparent; }
.composer textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.composer .btn { height: 32px; }
.composer-note { font-size: 11px; color: var(--text-2); margin-top: var(--sp-2); }
.ai-banner {
  max-width: 720px; margin: 0 auto var(--sp-3);
  display: flex; align-items: center; gap: 8px;
  background: var(--danger-soft); color: var(--danger); border-radius: 8px; padding: 8px 12px; font-size: 13px;
}

/* ---------------- toasts ---------------- */
.toasts { position: fixed; bottom: var(--sp-6); right: var(--sp-6); display: flex; flex-direction: column; gap: var(--sp-2); z-index: 100; }
.toast {
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow-pop);
  padding: var(--sp-3) var(--sp-4); font-size: 13px; display: flex; align-items: center; gap: 8px;
  animation: toastIn 250ms var(--ease);
}
.toast.out { opacity: 0; transform: translateY(8px); transition: opacity 200ms var(--ease), transform 200ms var(--ease); }
.toast svg { width: 16px; height: 16px; flex: 0 0 16px; }
.toast.ok svg { color: var(--success); }
.toast.err svg { color: var(--danger); }
@keyframes toastIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* ---------------- modal ---------------- */
.modal-back { position: fixed; inset: 0; background: rgba(17, 24, 39, 0.35); z-index: 90; display: flex; align-items: center; justify-content: center; transition: opacity 200ms var(--ease); }
.modal-back.out { opacity: 0; }
.modal { background: var(--surface); border-radius: 12px; box-shadow: var(--shadow-pop); padding: var(--sp-6); width: 440px; max-width: calc(100vw - 48px); animation: modalIn var(--dur-base) var(--ease); }
/* MOBILE M3 ledger: dialog widths move out of inline styles so the phone tier
   can override them (full-width bottom sheet). Same numbers as before. */
.modal-wide { width: 600px; max-width: calc(100vw - 32px); }
.modal-back.out .modal { transform: scale(0.98) translateY(6px); transition: transform 200ms var(--ease); }
.modal h3 { font-size: 16px; margin-bottom: var(--sp-2); }
.modal p { color: var(--text-2); font-size: 13px; margin-bottom: var(--sp-4); }
.modal-actions { display: flex; justify-content: flex-end; gap: var(--sp-2); }
@keyframes fadeUp { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes modalIn { from { opacity: 0; transform: scale(0.98) translateY(6px); } to { opacity: 1; transform: none; } }

/* ---------------- page swap (D4 — motion.md > Providing feedback) ----------------
   Previous page eases out (fade + 6px rise, ~200ms) and the new page overlaps it
   with its entrance stagger — no snap, no blank gap (skeletons cover the fetch). */
#view { transition: opacity 200ms var(--ease), transform 200ms var(--ease); }
#view.view-out { opacity: 0; transform: translateY(-6px); }

/* ---------------- upload flow ---------------- */
.flow-body { min-height: 200px; }
.upload-drop {
  border: 1px dashed var(--border-strong); border-radius: var(--radius-card);
  padding: var(--sp-8) var(--sp-6); text-align: center; color: var(--text-2);
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.upload-drop:hover { border-color: var(--accent); background: var(--accent-soft); }
.upload-drop svg { width: 24px; height: 24px; color: var(--text-2); }
.extracting { display: flex; flex-direction: column; align-items: center; gap: var(--sp-3); padding: var(--sp-8) 0; color: var(--text-2); }
.spinner { width: 16px; height: 16px; border: 2px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: spin 800ms linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.conf-high { background: var(--success-soft); color: var(--success); }
.conf-mid { background: var(--warning-soft); color: var(--warning); }
.conf-low { background: var(--danger-soft); color: var(--danger); }
.row-unmatched { background: var(--danger-soft); }
/* FX1: external (ignored) upload rows — kept for audit, excluded from confirm */
/* FX1: external (ignored) upload rows — kept for audit, excluded from confirm */
.row-ignored { background: var(--surface-2); opacity: .7; }
.mk-rejected { background: var(--danger-soft); border-radius: var(--radius-card); }
.mk-rejected h4 { color: var(--danger); }
.mk-rejected svg { color: var(--danger); }

/* ---------------- kanban ---------------- */
.kanban { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-3); align-items: start; }
@media (max-width: 1100px) { .kanban { grid-template-columns: repeat(2, 1fr); } }
.kcol { background: var(--surface-2); border-radius: var(--radius-card); padding: var(--sp-2); min-height: 200px; transition: background var(--dur-fast) var(--ease); }
.kcol.drag-over { background: var(--accent-soft); }
.kcol-head { display: flex; align-items: center; justify-content: space-between; padding: var(--sp-1) var(--sp-2) var(--sp-2); font-size: var(--fs-small); font-weight: 600; color: var(--text-2); text-transform: uppercase; letter-spacing: 0.05em; }
.kcard { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: var(--sp-3); margin-bottom: var(--sp-2); cursor: grab; box-shadow: var(--shadow-card); transition: box-shadow var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease); }
.kcard:active { cursor: grabbing; }
.kcard:hover { border-color: var(--border-strong); }
.kcard.dragging { opacity: .5; box-shadow: var(--shadow-pop); }
.kcard .kc-name { font-weight: 500; font-size: 13px; }
.kcard .kc-sub { font-size: var(--fs-small); color: var(--text-2); margin-top: var(--sp-1); }
.kcard .kc-meta { display: flex; gap: var(--sp-2); margin-top: var(--sp-2); flex-wrap: wrap; }
.kmove { display: flex; gap: 4px; margin-top: var(--sp-2); }
.kmove button { flex: 1; }

/* ---------------- skeletons (D3 — loading.md > Best practices) ----------------
   Real page structure with transparent placeholder ink over the surface-2 fill;
   footprint matches the final content, so nothing jumps when data lands.
   Token colors only; calm opacity pulse — no gradient shimmer. */
.skel {
  background: var(--surface-2);
  color: transparent !important;
  border-radius: 4px;
  user-select: none;
  animation: skelPulse 1.4s var(--ease) infinite;
}
@keyframes skelPulse { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }

/* ---------------- empty states ---------------- */
.empty { display: flex; flex-direction: column; align-items: center; gap: var(--sp-3); padding: var(--sp-8) var(--sp-4); color: var(--text-2); text-align: center; }
.empty svg { width: 24px; height: 24px; color: var(--border-strong); }
.empty h4 { color: var(--text); font-size: var(--fs-base); }
.empty p { font-size: 13px; max-width: 380px; }

/* ---------------- onboarding checklist ---------------- */
.checklist { display: flex; flex-direction: column; gap: var(--sp-2); }
.check-row { display: flex; align-items: center; gap: var(--sp-3); font-size: 13px; }
.check-row .ck { width: 18px; height: 18px; border-radius: 50%; border: 1.5px solid var(--border-strong); display: flex; align-items: center; justify-content: center; flex: 0 0 18px; }
.check-row.done .ck { background: var(--success); border-color: var(--success); color: #fff; }
.check-row.done .ck svg { width: 11px; height: 11px; }
.check-row.done { color: var(--text-2); }

/* ---------------- entrance animation (8.5-A) ---------------- */
.anim-item { opacity: 0; transform: translateY(8px); transition: opacity 300ms var(--ease), transform 300ms var(--ease); }
.anim-item.in { opacity: 1; transform: none; }
.anim-item.table-row { transition-duration: 250ms; transform: translateY(4px); }
.anim-item.static { transition: opacity 300ms var(--ease); transform: none; }
.shell-anim { opacity: 0; transition: opacity 150ms var(--ease); }
.shell-anim.in { opacity: 1; }
.chart-anim { opacity: 0; transition: opacity 200ms var(--ease); }
.chart-anim.in { opacity: 1; }
.row-new { animation: rowNew 800ms var(--ease); }
@keyframes rowNew { from { background: var(--accent-soft); } to { background: transparent; } }

/* ---------------- reduced motion (8.5-F) ----------------
   NOTE: the later rules (.rc-glyph at ~line 560, .welcome-* at ~533, inline stagger
   delays) must NOT win here — !important + zeroed delays keep welcome/intro/travel
   as short cross-fades with no transform, per 8.5-F. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
  .anim-item { opacity: 1; transform: none; transition-delay: 0ms !important; }
  .shell-anim, .chart-anim { opacity: 1; }
  .caret { animation: none; }
  .typing span { animation: none; opacity: .6; }
  .rc-glyph { opacity: 1 !important; animation: none !important; animation-delay: 0ms !important; }
  .welcome-mark circle, .welcome-mark polygon { animation-delay: 0ms !important; }
  .welcome-word, .welcome-tag, .welcome-begin, .welcome-skip { animation-delay: 0ms !important; }
  .tour-ov { transition-duration: 1ms !important; }
  .chat-msgs { scroll-behavior: auto; }
}
@media (prefers-contrast: more) {
  :root {
    --border: #9CA3AF;
    --text-2: #374151;
    --surface-2: #E5E7EB;
  }
  .card { box-shadow: none; }
}

/* ---------------- icon base (Lucide sprite) ---------------- */
svg.ic { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.nav { position: relative; }

/* ---------------- activity list ---------------- */
.act-list { display: flex; flex-direction: column; }
.act-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); padding: var(--sp-2) 0; border-bottom: 1px solid var(--border); }
.act-row:last-child { border-bottom: none; }
.act-when { white-space: nowrap; }

/* ---------------- chips with x ---------------- */
.skill-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip-x { border: none; background: none; color: inherit; cursor: pointer; font-size: 13px; margin-left: 2px; opacity: .7; line-height: 1; width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; vertical-align: middle; } /* FX3: real 24x24 hit area (was 19x13 with a pseudo-element) */
.chip-x:hover { opacity: 1; }
.add-row { display: flex; gap: var(--sp-2); margin-top: var(--sp-3); }
.add-row .input { flex: 1; }

/* ---------------- generic layout helpers ---------------- */
.btn-block { width: 100%; justify-content: center; }
.page-right { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.actions-card .act-btn { width: 100%; justify-content: flex-start; margin-top: var(--sp-2); }
.actions-card .act-btn:first-child { margin-top: 0; }
.grid-3col { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 1000px) { .grid-3col { grid-template-columns: 1fr; } }
.search-row { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: var(--sp-3); }
.search-row .input { flex: 1; min-width: 160px; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--sp-3); margin-bottom: var(--sp-3); }
@media (max-width: 700px) { .form-grid { grid-template-columns: 1fr; } }
.list-plain { display: flex; flex-direction: column; }
.list-plain li { padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 13px; }
.list-plain li:last-child { border-bottom: none; }

/* ---------------- chat host (assistant page) ---------------- */
.chat-host { padding: 0 !important; max-width: none !important; }
.chat-host .chat-view { position: relative; inset: auto; height: calc(100vh - var(--topbar-h)); height: calc(100dvh - var(--topbar-h)); }
/* FX3 (the CRAMPED class): below 900px the 240px conversation rail squeezed the reading
   column under 300px at the swept viewports, and at short heights the empty state was
   taller than the message box. The rail is a wide-surface affordance; on narrow screens
   the chat itself gets the width and the empty state gets a compact rhythm. */
@media (max-width: 900px) { .chat-rail { display: none; } }
@media (max-height: 560px) {
  .chat-empty { padding: var(--sp-4) var(--sp-3); }
  .chat-foot { padding: var(--sp-2) var(--sp-3) var(--sp-3); }
  .quick-row { margin-bottom: var(--sp-1); }
  .composer-note { margin-top: var(--sp-1); }
}
.tool-row { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; margin-bottom: 4px; }
.tool-row:empty { display: none; }
.conv-item { position: relative; }
.conv-del { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); border: none; background: none; color: var(--text-2); cursor: pointer; opacity: 0; transition: opacity var(--dur-fast) var(--ease); padding: 2px; }
.conv-del::before { content: ""; position: absolute; inset: -4px; } /* hit area >= 24px */
.conv-item:hover .conv-del { opacity: .8; }
.conv-del svg { width: 14px; height: 14px; }
.conv-del:hover { color: var(--danger); opacity: 1; }
/* roomy empty-state rhythm — but only when the viewport is actually tall enough
   for it (the max-height:560px block above sets the compact version). */
@media (min-height: 561px) { .chat-empty { padding: var(--sp-12) var(--sp-6); } }

/* ---------------- attendance grid ---------------- */
.status-seg { display: inline-flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.stbtn { border: none; background: var(--surface); color: var(--text-2); font-size: var(--fs-small); font-weight: 500; padding: var(--sp-1) var(--sp-3); cursor: pointer; font-family: inherit; transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease); }
.stbtn + .stbtn { border-left: 1px solid var(--border); }
.stbtn:hover { background: var(--surface-2); }
.stbtn.on-present { background: var(--success-soft); color: var(--success); }
.stbtn.on-late { background: var(--warning-soft); color: var(--warning); }
.stbtn.on-absent { background: var(--danger-soft); color: var(--danger); }
.stbtn:disabled { opacity: .5; cursor: default; }

/* ---------------- test taking ---------------- */
.exam-wrap { max-width: 760px; }
.exam-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); margin-bottom: var(--sp-4); flex-wrap: wrap; }
.exam-timer { font-size: var(--fs-kpi); font-weight: 600; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.exam-timer.warn { color: var(--danger); }
.qcard { margin-bottom: var(--sp-4); }
.qtext { font-weight: 500; margin-bottom: var(--sp-3); }
.opt { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2) var(--sp-3); border: 1px solid var(--border); border-radius: var(--radius-input); margin-bottom: 8px; cursor: pointer; transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease); }
.opt:hover { border-color: var(--border-strong); }
.opt.sel { border-color: var(--accent); background: var(--accent-soft); }
.opt .radio { width: 14px; height: 14px; border-radius: 50%; border: 1.5px solid var(--border-strong); flex: 0 0 14px; display: flex; align-items: center; justify-content: center; }
.opt.sel .radio { border-color: var(--accent); }
.opt.sel .radio::after { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }
.opt.correct { border-color: var(--success); background: var(--success-soft); }
.opt.wrong { border-color: var(--danger); background: var(--danger-soft); }
.result-hero { display: flex; align-items: center; gap: var(--sp-4); flex-wrap: wrap; }
.result-hero .big { font-size: var(--fs-kpi); font-weight: 600; letter-spacing: -0.02em; }

/* ---------------- kanban extras ---------------- */
.kcol-cards { min-height: 60px; }
.kcard { touch-action: none; }

/* ---------------- directory / filters ---------------- */
.filter-chip { border: 1px solid var(--border); background: var(--surface); border-radius: var(--radius-chip); padding: var(--sp-1) var(--sp-3); font-size: var(--fs-small); cursor: pointer; color: var(--text-2); font-family: inherit; transition: all var(--dur-fast) var(--ease); }
.filter-chip:hover { border-color: var(--border-strong); }
.filter-chip.on { background: var(--accent-soft); color: var(--accent); border-color: transparent; }

/* ---------------- settings ---------------- */
/* D6: uniform set-row height so chips, values and inline notes never vary the block's
   rhythm or the skeleton footprint (lists-and-tables.md › Style). */
.set-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); padding: var(--sp-2) 0; border-bottom: 1px solid var(--border); font-size: 13px; min-height: 40px; }
.set-row:last-child { border-bottom: none; }
.set-row .k { color: var(--text-2); }
.set-row .v { font-weight: 500; text-align: right; word-break: break-all; }

/* ---------------- one-shot pulse (tour beat) ---------------- */
.pulse-once { animation: rowNew 800ms var(--ease); }

/* ---------------- picker extras ---------------- */
.role-card .btn { width: 100%; }
.picker-brand { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-6); }

/* scrollbars (subtle) */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 5px; border: 2px solid var(--surface); }
::-webkit-scrollbar-track { background: transparent; }

/* app.js motion: the sliding .nav-pill is the sole active highlight (avoids double-paint under the pill) */
.nav-item.active { background: transparent; }

/* ---------------- welcome overlay (once per session) ---------------- */
.welcome {
  position: fixed; inset: 0; z-index: 200; background: var(--bg);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 24px;
}
.welcome.out { opacity: 0; transform: scale(1.035); transition: opacity 260ms var(--ease), transform 260ms var(--ease); }
.welcome-mark { width: 64px; height: 64px; color: var(--accent); margin-bottom: var(--sp-4); }
.welcome-mark circle, .welcome-mark polygon { stroke-dasharray: 100; stroke-dashoffset: 100; }
.welcome-mark circle { animation: wdraw 700ms var(--ease) 100ms forwards; }
.welcome-mark polygon { animation: wdraw 700ms var(--ease) 350ms forwards; }
@keyframes wdraw { to { stroke-dashoffset: 0; } }
.welcome-word { font-size: 26px; font-weight: 600; letter-spacing: -0.02em; opacity: 0; animation: wrise 450ms var(--ease) 650ms forwards; }
.welcome-tag { color: var(--text-2); margin-top: var(--sp-2); font-size: var(--fs-base); opacity: 0; animation: wrise 450ms var(--ease) 850ms forwards; }
.welcome-begin { margin-top: var(--sp-6); opacity: 0; animation: wrise 450ms var(--ease) 1050ms forwards; }
.welcome-skip {
  position: absolute; bottom: var(--sp-4); background: none; border: none; color: var(--text-2);
  font-size: 12px; cursor: pointer; padding: var(--sp-2) var(--sp-3); border-radius: 6px; font-family: inherit;
  opacity: 0; animation: wrise 450ms var(--ease) 1050ms forwards;
  transition: color 150ms var(--ease), background 150ms var(--ease);
}
.welcome-skip:hover { color: var(--text); background: var(--surface-2); }
@keyframes wrise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* ---------------- role-tab entry curtain (WP2, motion-only) ---------------- */
.entry-curtain {
  position: fixed; inset: 0; z-index: 190; background: var(--surface);
  display: flex; align-items: center; justify-content: center;
  opacity: 1; transition: opacity var(--dur-base) var(--ease); pointer-events: none; /* purely visual — never blocks the page */
}
.entry-curtain .entry-mark { width: 64px; height: 64px; color: var(--accent); transform: scale(0.94); transition: transform var(--dur-base) var(--ease); }
.entry-curtain.in .entry-mark { transform: scale(1); }
.entry-curtain.out { opacity: 0; }

/* ---------------- picker interactivity ---------------- */
.role-card { will-change: transform; }
.role-card:hover { transform: translateY(-2px); box-shadow: 0 10px 24px rgba(24, 24, 27, 0.10); }
.role-card:active { transform: translateY(-1px) scale(0.999); }
.rc-glyph { opacity: 0; animation: rcGlyphIn 420ms var(--ease) forwards; animation-delay: 300ms; }
@keyframes rcGlyphIn { from { opacity: 0; transform: scale(0.86) rotate(-8deg); } to { opacity: 1; transform: none; } }
.role-card .rc-glyph svg { transition: transform 220ms var(--ease); }
.role-card:hover .rc-glyph svg { transform: scale(1.1) rotate(-3deg); }
.btn .arr { transition: transform 180ms var(--ease); }
.btn:hover .arr { transform: translateX(2px); }
/* launch feedback on picker cards (WP2 motion-only): clicked card lifts, siblings dim */
.role-card.launch { transform: translateY(-4px); border-color: var(--accent); box-shadow: var(--shadow-pop); transition: transform var(--dur-base) var(--ease), border-color var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease); }
.role-card.launch .rc-glyph svg { transform: scale(1.12); }
.role-card.dimmed { opacity: 0.4; transition: opacity var(--dur-base) var(--ease); }
.seg button { transition: background 150ms var(--ease), color 150ms var(--ease); }
.seg button:not(.active):hover { background: var(--surface-2); }
.replay-link { padding: 4px 8px; border-radius: 6px; transition: color 150ms var(--ease), background 150ms var(--ease); }
.replay-link:hover { background: var(--surface-2); }

/* scope cut: disabled (view-only) controls */
.ro-disabled { opacity: 0.55; cursor: not-allowed; }
/* F-d affordance: the reason lives in the control, not in a hover the freeze forbids */
.ro-disabled .ro-note { font-weight: 400; font-size: 10px; opacity: .85; margin-left: var(--sp-2); }

/* ============================================================
   MOBILE tier (branch mobile — M1/M3).
   <=700px the left sidebar is replaced by a thumb-reachable bottom
   tab bar (top-4 pages + More sheet); fixed chrome respects
   env(safe-area-inset-*); coarse pointer gets 44pt HIG targets and
   16px input fonts (iOS zoom-on-focus guard). Tokens only —
   nav-pill motion, sp scale, surface/border colors. No new hexes.
   ============================================================ */
:root { --tab-h: 60px; }
.tabbar { display: none; }
.topbar { padding-top: env(safe-area-inset-top, 0px); height: calc(var(--topbar-h) + env(safe-area-inset-top, 0px)); flex-basis: calc(var(--topbar-h) + env(safe-area-inset-top, 0px)); }

@media (max-width: 700px) {
  html { scroll-padding-bottom: calc(var(--tab-h) + env(safe-area-inset-bottom, 0px)); }
  /* the fixed bar never sits over content: the shell reserves its height */
  .shell { padding-bottom: calc(var(--tab-h) + env(safe-area-inset-bottom, 0px)); }
  .content { padding: var(--sp-4) var(--sp-3); }
  .page-head { margin-bottom: var(--sp-4); }
  .page-head h1 { font-size: var(--fs-h1); }
  .grid-kpi { grid-template-columns: repeat(2, 1fr); }
  .grid { gap: var(--sp-3); }
  .kanban { grid-template-columns: 1fr; }
  .kcol { min-height: 60px; }
  .top-date { display: none; }
  .picker-head { padding: var(--sp-6) var(--sp-4) var(--sp-4); }
  .picker-cards { padding: 0 var(--sp-4) var(--sp-8); gap: var(--sp-3); }
  .picker-foot { padding: 0 var(--sp-4) var(--sp-6); }
  .toasts { left: var(--sp-4); right: var(--sp-4); bottom: calc(var(--sp-4) + var(--tab-h) + env(safe-area-inset-bottom, 0px)); max-width: 100%; }
  .welcome-skip { bottom: max(var(--sp-4), env(safe-area-inset-bottom, 0px)); }
  .chat-host .chat-view { height: calc(100vh - var(--topbar-h) - var(--tab-h)); height: calc(100dvh - var(--topbar-h) - env(safe-area-inset-top, 0px) - var(--tab-h) - env(safe-area-inset-bottom, 0px) - var(--kb, 0px)); }
  .empty p { max-width: none; }

  /* bottom tab bar — same nav-pill motion token as the sidebar pill */
  .tabbar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
    display: flex; align-items: stretch;
    height: calc(var(--tab-h) + env(safe-area-inset-bottom, 0px));
    padding-bottom: env(safe-area-inset-bottom, 0px);
    background: var(--surface); border-top: 1px solid var(--border);
  }
  .tab-item {
    position: relative; z-index: 1; flex: 1; min-width: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: var(--sp-1); padding: var(--sp-1) var(--sp-1) 0;
    min-height: 44px; background: transparent; border: none; font-family: inherit;
    color: var(--text-2); font-size: var(--fs-small); line-height: 1.25; cursor: pointer;
    transition: color var(--dur-fast) var(--ease);
  }
  .tab-item svg { width: 20px; height: 20px; flex: none; }
  .tab-item.active { color: var(--accent); font-weight: 500; }
  .tabbar .nav-pill {
    left: 0; right: auto; top: var(--sp-1); width: 0; height: calc(var(--tab-h) - var(--sp-2));
    transition: transform 200ms var(--ease), width 200ms var(--ease);
  }

  /* More sheet: reuses the modal sheet primitives (motion tokens) + nav items */
  .more-sheet .nav-item.active { background: var(--accent-soft); }
  .sheet-user { margin-bottom: var(--sp-4); }
  .sheet-user + .switch-role { width: 100%; justify-content: flex-start; margin-bottom: var(--sp-4); }
  .more-nav { padding: 0; }

  /* M3: modals become full-width bottom sheets at phone width */
  .modal-back { align-items: flex-end; padding: 0; }
  .modal {
    width: 100%; max-width: 100%; border-radius: var(--radius-card) var(--radius-card) 0 0;
    max-height: calc(100vh - var(--sp-6)); max-height: calc(100dvh - var(--sp-6));
    overflow: auto; padding-bottom: max(var(--sp-6), env(safe-area-inset-bottom, 0px));
    animation: sheetIn var(--dur-base) var(--ease);
  }
  .modal-back.out .modal { transform: translateY(12px); }
  @keyframes sheetIn { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
  /* sticky header inside the scrolling sheet (M3) */
  .modal > h3:first-child, .modal > .card-title:first-child {
    position: sticky; top: calc(var(--sp-6) * -1); z-index: 3;
    background: var(--surface); padding: var(--sp-6) 0 var(--sp-2); margin: calc(var(--sp-6) * -1) 0 var(--sp-2);
    border-bottom: 1px solid var(--border);
  }
  .modal-x {
    position: sticky; top: calc(var(--sp-6) * -1); float: right; z-index: 4;
    margin: calc(var(--sp-6) * -1) 0 0 var(--sp-2);
  }
}
.modal-x { display: none; }
@media (min-width: 701px) { .modal-x { display: none !important; } }
@media (max-width: 700px) { .modal-x { display: inline-flex; } }

/* coarse pointer (phones/tablets; deep_audit emulates it via hasTouch): HIG 44pt */
@media (pointer: coarse) {
  .btn { height: 44px; }
  .btn-sm { height: 44px; min-width: 44px; padding: 0 var(--sp-3); border-radius: var(--radius-input); }
  .btn-xs { height: 44px; }
  .icon-btn { width: 44px; height: 44px; }
  .seg button { min-height: 44px; min-width: 44px; padding: var(--sp-2) var(--sp-3); }
  .stbtn { min-height: 44px; padding-left: var(--sp-3); padding-right: var(--sp-3); }
  .quick-chip { min-height: 44px; padding: var(--sp-2) var(--sp-3); }
  .filter-chip { min-height: 44px; min-width: 44px; padding: var(--sp-2) var(--sp-3); }
  .chip-x { width: 44px; height: 44px; }
  .nav-item { height: 44px; }
  .opt { min-height: 44px; }
  .tool-chip { min-height: 44px; }
  .replay-link { min-height: 44px; display: inline-flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2) var(--sp-3); }
  .narrator-skip { min-height: 44px; }
  .conv-item { min-height: 44px; }
  .conv-del { width: 44px; height: 44px; padding: 0; }
  .tour-tip-actions .narrator-skip, #tour-tip-skip, #tour-tip-explore { min-height: 44px; }
  .input, select.input, textarea.input { height: 44px; min-width: 44px; font-size: 16px; }
  .composer textarea { font-size: 16px; min-height: 44px; }
  .composer .btn { height: 44px; }
  /* table-inline controls (were fixed 32px-height inline styles in app.js) */
  .input-cell { width: 84px; }
  .input-marks { width: 72px; }
  .input-link { width: 170px; }
  /* compare checkboxes: 13px native boxes fail 44pt — draw a sized control */
  .cmp {
    appearance: none; width: 44px; height: 44px; border: 1px solid var(--border-strong);
    border-radius: var(--radius-input); background: var(--surface); cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center; flex: none;
  }
  .cmp:checked { background: var(--accent); border-color: var(--accent); }
  .cmp:checked::after { content: "✓"; color: var(--surface); font-size: 18px; line-height: 1; }
  .kcard { cursor: pointer; }
}
