/* ==========================================================================
   VMS Intranet v2 — Application shell + page-template layout
   Implements docs/design-ia-shell.md. Layout-only classes built entirely on
   tokens.css — NO colour literals, no new token values. Loaded after main.css
   so equal-specificity overrides land here. Every existing class keeps working.
   ========================================================================== */

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

/* Inline-SVG icon defaults (self-hosted sprite; outlined line style) */
.icon, .nav-ico {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex-shrink: 0;
}
.icon { width: 20px; height: 20px; }

/* ---------- Topbar (upgraded: sticky, toggle, search, user menu) -------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  gap: var(--space-3);
}

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  min-height: 40px;
  padding: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--color-text);
  cursor: pointer;
}
.icon-btn:hover { background: var(--surface-sunken); border-color: var(--border-subtle); }

/* Global search */
.global-search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1 1 auto;
  max-width: 32rem;
  margin: 0;
}
.global-search .search-icon {
  position: absolute;
  left: 10px;
  width: 18px; height: 18px;
  color: var(--color-text-muted);
  pointer-events: none;
}
.global-search input {
  width: 100%;
  min-height: 38px;
  margin: 0;
  padding-left: 34px;
  padding-right: 30px;
  background: var(--surface-canvas);
}
.global-search .search-hint {
  position: absolute;
  right: 8px;
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  color: var(--color-text-muted);
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  padding: 0 var(--space-1);
  pointer-events: none;
}

/* User menu (native <details> — keyboard-operable without JS) */
.usermenu { position: relative; }
.usermenu summary {
  list-style: none;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 40px;
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.usermenu summary::-webkit-details-marker { display: none; }
.usermenu summary:hover { background: var(--surface-sunken); }
.usermenu summary:focus-visible { outline: 2px solid var(--focus-color); outline-offset: 2px; }
.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px; height: 28px;
  border-radius: var(--radius-pill);
  background: var(--vms-blue);
  color: var(--color-text-invert);
  font-size: var(--fs-small);
  font-weight: var(--fw-bold);
}
.usermenu .chevron { width: 16px; height: 16px; color: var(--color-text-muted); }
.usermenu[open] .chevron { transform: rotate(180deg); }
.admin-local { margin-left: var(--space-1); }
.usermenu-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  min-width: 13rem;
  background: var(--surface-card);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-2);
  padding: var(--space-1);
  z-index: 40;
}
.usermenu-panel a {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-size: var(--fs-body);
}
.usermenu-panel a:hover { background: var(--surface-sunken); text-decoration: none; }
.usermenu-panel a.danger { color: var(--status-error-fg); }
.usermenu-panel .icon { width: 18px; height: 18px; color: var(--color-text-muted); }
.usermenu-panel hr { margin: var(--space-1) 0; }

/* ---------- Build / demo pill (topbar, left of the user menu) -----------
   Same <details> pattern as the user menu. Amber is functional here, not
   brand: it marks "this is not the live system" (vms-style-guide — brand blue
   is never a status colour). Drops to the version alone once demo_mode is off
   at cutover, so the pill survives as the build readout. */
.buildmenu { position: relative; }
.buildmenu summary {
  list-style: none;
  display: flex;
  align-items: center;
  gap: var(--space-1);
  min-height: 40px;
  padding: 0 var(--space-2);
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-subtle);
  color: var(--color-text-muted);
  font-size: var(--fs-small);
  white-space: nowrap;
  cursor: pointer;
}
.buildmenu summary::-webkit-details-marker { display: none; }
.buildmenu summary:hover { background: var(--surface-sunken); }
.buildmenu summary:focus-visible { outline: 2px solid var(--focus-color); outline-offset: 2px; }
.buildmenu .icon { width: 14px; height: 14px; }
.buildmenu .build-ver { font-variant-numeric: tabular-nums; }
.buildmenu .build-demo { font-weight: var(--fw-bold); text-transform: uppercase; letter-spacing: 0.04em; }

.buildmenu.is-demo summary {
  background: var(--status-warn-bg);
  border-color: var(--status-warn-border);
  color: var(--status-warn-fg);
}
.buildmenu.is-demo summary:hover { background: var(--status-warn-bg); border-color: var(--status-warn-fg); }

.buildmenu-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  width: 20rem;
  background: var(--surface-card);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-2);
  padding: var(--space-3);
  z-index: 40;
}
.buildmenu-panel hr { margin: var(--space-3) 0; border: 0; border-top: 1px solid var(--border-subtle); }
.build-notice { margin: 0; font-size: var(--fs-small); line-height: 1.5; }
.build-notice strong { display: block; color: var(--status-warn-fg); }
.build-notice-link { margin: var(--space-2) 0 0; font-size: var(--fs-small); }
.build-notice-link .nav-ext { width: 12px; height: 12px; vertical-align: -1px; }

.build-facts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-1) var(--space-3);
  margin: 0;
  font-size: var(--fs-small);
}
.build-facts dt { color: var(--color-text-muted); }
.build-facts dd { margin: 0; font-variant-numeric: tabular-nums; }

/* ---------- App shell layout (topbar / sidebar + content) --------------- */
:root { --sidebar-w: 248px; } /* user-resizable via the divider; persisted in localStorage */

.appshell { display: flex; align-items: flex-start; }

.content-col { flex: 1 1 auto; min-width: 0; }

.sidebar {
  flex: 0 0 var(--sidebar-w);
  width: var(--sidebar-w);
  align-self: flex-start;
  position: sticky;
  top: var(--header-h);
  height: calc(100vh - var(--header-h));
  overflow-y: auto;
  /* Keep the menu's scroll to the menu: at either end, don't hand the remaining
     scroll to the page behind it. Matters most for the mobile drawer, but it is
     right on desktop too — a trackpad flick down the nav shouldn't move the
     document. */
  overscroll-behavior: contain;
  /* Momentum scrolling on older iOS, where overflow-y:auto alone scrolls in a
     single stiff jump. A no-op on anything current; harmless to keep. */
  -webkit-overflow-scrolling: touch;
  background: var(--surface-card);
  border-right: 1px solid var(--border-strong);
}

/* Drag divider between sidebar and content (desktop only) */
.sidebar-resizer {
  flex: 0 0 6px;
  margin-left: -6px;
  position: sticky;
  top: var(--header-h);
  height: calc(100vh - var(--header-h));
  cursor: col-resize;
  z-index: 5;
}
.sidebar-resizer:hover,
body.resizing-nav .sidebar-resizer { box-shadow: inset -2px 0 0 var(--vms-blue); }
.sidebar-resizer:focus-visible { outline: 2px solid var(--focus-color); outline-offset: -2px; }
body.resizing-nav { cursor: col-resize; user-select: none; }
html.nav-collapsed .sidebar-resizer { display: none; }

.nav { padding: var(--space-3) var(--space-2); }
.nav-group { margin-bottom: var(--space-3); }
.nav-group-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-1) var(--space-3);
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.nav-group-head:hover { background: var(--surface-sunken); }
.nav-group-head:focus-visible { outline: 2px solid var(--focus-color); outline-offset: -2px; }
.nav-group-label {
  font-size: var(--fs-small);
  font-weight: var(--fw-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.nav-group-dot { display: none; }
.nav-group-chevron {
  width: 16px; height: 16px;
  color: var(--color-text-muted);
  transition: transform 0.12s ease;
}
.nav-group.collapsed .nav-group-chevron { transform: rotate(-90deg); }
.nav-group.collapsed .nav-list { display: none; }

.nav-list { list-style: none; margin: 0; padding: 0; }
.nav-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--control-min-h);
  padding: var(--space-2) var(--space-3);
  border-left: 3px solid transparent;
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  color: var(--color-text);
  text-decoration: none;
  font-weight: var(--fw-regular);
}
.nav-item:hover { background: var(--surface-sunken); text-decoration: none; }
.nav-ico { width: 22px; height: 22px; color: var(--color-text-muted); }
.nav-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.nav-item[aria-current="page"] {
  background: var(--row-hover);
  border-left-color: var(--vms-blue);
  color: var(--color-text-strong);
  font-weight: var(--fw-bold);
}
.nav-item[aria-current="page"] .nav-ico { color: var(--vms-blue); }

/* Collapsed icon rail */
html.nav-collapsed .sidebar { flex-basis: 56px; width: 56px; }
html.nav-collapsed .nav { padding: var(--space-3) var(--space-1); }
html.nav-collapsed .nav-group-label { display: none; }
html.nav-collapsed .nav-group + .nav-group { border-top: 1px solid var(--border-subtle); padding-top: var(--space-2); }
html.nav-collapsed .nav-group.has-active .nav-group-dot {
  display: block;
  width: 6px; height: 6px;
  margin: var(--space-1) auto;
  border-radius: var(--radius-pill);
  background: var(--vms-blue);
}
html.nav-collapsed .nav-group-head { justify-content: center; padding: var(--space-1); pointer-events: none; }
html.nav-collapsed .nav-group-chevron { display: none; }
/* The rail shows every item — a collapsed group would just be confusing dots. */
html.nav-collapsed .nav-group.collapsed .nav-list { display: block; }
html.nav-collapsed .nav-item { justify-content: center; gap: 0; padding-left: 0; padding-right: 0; }
html.nav-collapsed .nav-label {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

/* Mobile off-canvas drawer */
.nav-scrim {
  position: fixed;
  inset: var(--header-h) 0 0 0;
  /* Same iOS layout-viewport trap as the drawer: `inset: … 0` alone leaves the
     scrim short of the visible bottom once the URL bar hides. Pin the height
     explicitly so the dimmed area always covers the page. */
  height: calc(100vh - var(--header-h));
  height: calc(100dvh - var(--header-h));
  background: rgba(0, 0, 0, 0.35);
  z-index: 25;
  /* A drag on the scrim is a drag on nothing — without this iOS scrolls the page
     behind it, so dismissing the menu with a stray swipe moves the page too. */
  touch-action: none;
}

/* ==========================================================================
   Page templates
   ========================================================================== */

/* ---- tmpl-dashboard (Home) -------------------------------------------- */
.dash-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-5);
}
.dash-head h1 { margin: 0 0 var(--space-1); }
.dash-context { color: var(--color-text-muted); font-size: var(--fs-body); margin: 0; }
.dash-head-side { display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-2); }

.status-dot { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--fs-small); }
.status-dot::before {
  content: ""; width: 9px; height: 9px; border-radius: var(--radius-pill);
  background: var(--color-text-muted); flex-shrink: 0;
}
.status-dot[data-state="draft"]::before     { background: var(--status-info-fg); }
.status-dot[data-state="submitted"]::before { background: var(--status-warn-fg); }
.status-dot[data-state="approved"]::before  { background: var(--status-success-fg); }

.home-grid {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: var(--space-4);
  align-items: start;
}
.home-col { display: flex; flex-direction: column; gap: var(--space-4); }

.panel {
  background: var(--surface-card);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
}
.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.panel-head h2, .panel-head h3 { margin: 0; font-size: var(--fs-h4); }
.panel-head .view-all { font-size: var(--fs-small); font-weight: var(--fw-regular); }
.count-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 var(--space-1);
  border-radius: var(--radius-pill);
  background: var(--vms-blue); color: var(--color-text-invert);
  font-size: var(--fs-small); font-weight: var(--fw-bold);
}
.count-badge.zero { background: var(--status-success-bg); color: var(--status-success-fg); }

.needs-list { list-style: none; margin: 0; padding: 0; }
.needs-list li {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--border-subtle);
}
.needs-list li:last-child { border-bottom: 0; }
.needs-list .needs-icon { width: 20px; height: 20px; color: var(--color-text-muted); }
.needs-list a { font-weight: var(--fw-bold); }

/* My week strip */
.week-days { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--space-2); align-items: end; }
.week-day { display: flex; flex-direction: column; align-items: center; gap: var(--space-1); }
.week-bar {
  width: 100%; height: 48px;
  display: flex; align-items: flex-end;
  background: var(--surface-sunken);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.week-bar > span {
  width: 100%;
  height: calc(var(--pct, 0) * 1%);
  background: var(--vms-blue);
  display: block;
}
.week-day.today .week-bar { outline: 2px solid var(--vms-blue); outline-offset: 1px; }
.week-day-label { font-size: var(--fs-small); color: var(--color-text-muted); }
.week-day-hours { font-size: var(--fs-small); color: var(--color-text); }
.week-meta { display: flex; justify-content: space-between; gap: var(--space-3); margin-top: var(--space-3); color: var(--color-text-muted); font-size: var(--fs-small); }

/* Quick actions */
.quick-actions { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); }
.quick-actions .button { width: 100%; min-height: 44px; }

/* Role-gated extras + register-count strip */
.home-extras { display: flex; flex-direction: column; gap: var(--space-4); margin-top: var(--space-4); }
.extra-panel .extra-lines { display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: center; }
.extra-figure { display: flex; flex-direction: column; }
.extra-figure b { font-size: var(--fs-h3); color: var(--vms-blue); line-height: 1.1; }
.extra-figure span { font-size: var(--fs-small); color: var(--color-text-muted); }

.count-strip { display: flex; gap: var(--space-3); flex-wrap: wrap; margin-top: var(--space-5); }
.count-chip {
  display: flex; align-items: baseline; gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-card);
  color: var(--color-text);
}
.count-chip:hover { border-color: var(--vms-blue); text-decoration: none; box-shadow: var(--shadow-1); }
.count-chip b { font-size: var(--fs-h4); color: var(--vms-blue); }
.count-chip span { font-size: var(--fs-small); color: var(--color-text-muted); }

/* ---- tmpl-register ----------------------------------------------------- */
.page-actions { display: flex; gap: var(--space-2); }
.filter-bar {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: var(--space-3);
  max-width: none;
}
/* Direct children only: the grow rule is for bare search boxes. A descendant
   selector reached into column-flex .fld labels, where flex-basis 16rem becomes
   HEIGHT — giant date inputs (bit profitability + billings, fixed 20 Jul). */
.filter-bar > input { flex: 1 1 16rem; }
.filter-actions { margin-left: auto; display: flex; gap: var(--space-2); }
.result-count { color: var(--color-text-muted); font-size: var(--fs-small); margin: 0 0 var(--space-3); }
.pager { display: flex; gap: var(--space-1); align-items: center; justify-content: flex-end; margin-top: var(--space-3); }
.th-sort { cursor: pointer; }
.th-sort::after { content: " \2195"; color: var(--color-text-muted); }

.empty-state {
  text-align: center;
  padding: var(--space-8) var(--space-5);
  color: var(--color-text-muted);
  background: var(--surface-card);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-lg);
}
.empty-state.calm { border-style: solid; border-color: var(--status-success-border); background: var(--status-success-bg); color: var(--status-success-fg); }
.empty-state h2 { margin: 0 0 var(--space-2); font-size: var(--fs-h4); color: inherit; }

/* ---- tmpl-detail ------------------------------------------------------- */
.crumbs {
  display: flex; align-items: center; gap: var(--space-2);
  font-size: var(--fs-small); color: var(--color-text-muted);
  margin-bottom: var(--space-3);
}
.crumbs .sep { color: var(--grey-smoke); }
.crumbs .current { color: var(--color-text); }

.record-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--space-4); flex-wrap: wrap;
}
.record-head h1 { margin: 0; display: inline-flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.record-actions { display: flex; gap: var(--space-2); align-items: center; }
.orgchip {
  display: inline-flex; align-items: center;
  padding: 0 var(--space-2);
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-strong);
  background: var(--surface-sunken);
  color: var(--color-text-muted);
  font-size: var(--fs-small); font-weight: var(--fw-bold);
  vertical-align: middle;
}

.tabs { display: flex; gap: var(--space-1); border-bottom: 1px solid var(--border-strong); margin: var(--space-4) 0; }
.tab {
  padding: var(--space-2) var(--space-3);
  margin-bottom: -1px;
  border-bottom: 2px solid transparent;
  color: var(--color-text-muted);
  font-weight: var(--fw-bold);
  text-decoration: none;
}
.tab:hover { color: var(--color-text); text-decoration: none; }
.tab[aria-selected="true"] { color: var(--color-text-strong); border-bottom-color: var(--vms-blue); }

/* ---- tmpl-workspace ---------------------------------------------------- */
main.workspace { max-width: none; }
.workspace-toolbar {
  position: sticky;
  top: var(--header-h);
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding: var(--space-2) var(--space-3);
  margin-bottom: var(--space-4);
  background: var(--surface-card);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
}
.workspace-toolbar .toolbar-title { font-weight: var(--fw-bold); color: var(--color-text-strong); white-space: nowrap; }
.workspace-toolbar .toolbar-actions { display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; }

/* ==========================================================================
   tmpl-workqueue — Approvals two-pane (design-approvals-inbox.md §3.2, §6)
   ========================================================================== */
.queue {
  display: grid;
  grid-template-columns: minmax(18rem, 22rem) 1fr;
  gap: var(--space-4);
  align-items: start;
}

.queue-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  background: var(--surface-card);
  overflow: hidden;
  position: sticky;
  top: calc(var(--header-h) + var(--space-3));
}
.queue-item {
  display: block;
  padding: var(--space-3) var(--space-4);
  border-left: 3px solid transparent;
  border-bottom: 1px solid var(--border-subtle);
  color: var(--color-text);
  text-decoration: none;
  cursor: pointer;
}
.queue-list li:last-child .queue-item { border-bottom: 0; }
.queue-item:hover { background: var(--surface-sunken); text-decoration: none; }
.queue-item[aria-current="true"] {
  background: var(--row-hover);
  border-left-color: var(--vms-blue);
}
.queue-item .qi-name {
  display: flex; align-items: center; gap: var(--space-2);
  font-weight: var(--fw-bold); color: var(--color-text-strong);
}
.queue-item .qi-meta {
  margin-top: 2px;
  font-size: var(--fs-small);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}
.qi-flag { width: 14px; height: 14px; color: var(--status-warn-fg); flex-shrink: 0; }

.queue-detail {
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  background: var(--surface-card);
  min-width: 0;
}
.queue-detail-head {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
  background: var(--surface-sunken);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.queue-detail-head h2 { margin: 0; font-size: var(--fs-h4); }
.queue-detail-head .qd-mix { margin-top: 2px; font-size: var(--fs-small); color: var(--color-text-muted); }
.qd-head-row { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.queue-detail-body { padding: var(--space-3) var(--space-4); overflow-x: auto; }
.queue-detail-body table { border: 0; margin: 0; box-shadow: none; }
.queue-detail-body .weekend-row td { background: var(--surface-sunken); }
.qd-ref { font-weight: var(--fw-bold); color: var(--color-text-strong); white-space: nowrap; }
.resolve-row > td { background: var(--status-warn-bg); }

/* Actor chip (agent vs human — icon + word, never colour alone) */
.actor {
  display: inline-flex; align-items: center; gap: var(--space-1);
  font-size: var(--fs-small); white-space: nowrap;
}
.actor .icon { width: 15px; height: 15px; }
.actor.agent { color: var(--status-info-fg); }
.actor.human { color: var(--color-text-muted); }
.actor-lock { width: 14px; height: 14px; color: var(--color-text-muted); }

/* Advisory anomaly chip (warn token; text label always present) */
.anomaly {
  display: inline-flex; align-items: center; gap: 2px;
  padding: 0 var(--space-1);
  border-radius: var(--radius-pill);
  background: var(--status-warn-bg);
  color: var(--status-warn-fg);
  border: 1px solid var(--status-warn-border);
  font-size: var(--fs-small); white-space: nowrap;
}

.queue-actions {
  position: sticky;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--border-strong);
  background: var(--surface-card);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}
.queue-actions .qa-count { margin-right: auto; font-size: var(--fs-small); color: var(--color-text-muted); }
.queue-actions .reveal-form { width: 100%; margin: 0; }

/* Inbox helpers (stacked .panel sections — design §4) */
.inbox-reason {
  margin: var(--space-1) 0 var(--space-2);
  padding-left: var(--space-3);
  border-left: 2px solid var(--border-subtle);
  color: var(--color-text-muted);
  font-size: var(--fs-small);
}
.task-undo {
  display: inline-flex; align-items: center; gap: var(--space-2);
  color: var(--status-success-fg); font-size: var(--fs-small);
}
.recent-decisions { margin-top: var(--space-4); }
.recent-decisions > summary { list-style: none; cursor: pointer; }
.recent-decisions > summary::-webkit-details-marker { display: none; }
.recent-decisions[open] > summary { margin-bottom: var(--space-2); }

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 899px) {
  /* Approvals two-pane stacks: list over detail (design §6). */
  .queue { grid-template-columns: 1fr; }
  .queue-list { position: static; max-height: 40vh; overflow-y: auto; }

  /* Sidebar becomes an off-canvas drawer opened by the topbar toggle. */
  .sidebar {
    position: fixed;
    top: var(--header-h);
    left: 0;
    /* NOT `bottom: 0; height: auto` — that is what stopped the menu scrolling on
       iOS (Ryan, 17 Jul, Edge/iOS: the menu wouldn't scroll and the page moved
       underneath instead). iOS resolves `bottom` against the LAYOUT viewport,
       which is taller than the visible area while the URL bar is showing. The
       drawer's box therefore ran off the bottom of the screen, its content fit
       inside that too-tall box, nothing overflowed — so it never became a scroll
       container at all, and the touch went to the nearest thing that was one:
       the page. An explicit height fixes it because it cannot be over-resolved.
       Desktop never showed it: there is no dynamic URL bar. */
    bottom: auto;
    height: calc(100vh - var(--header-h));   /* fallback: pre-dvh browsers */
    height: calc(100dvh - var(--header-h));  /* dvh tracks the URL bar; iOS 15.4+ */
    width: min(var(--sidebar-w), 84vw); flex-basis: auto;
    transform: translateX(-100%);
    transition: transform 0.18s ease;
    z-index: 30;
    box-shadow: var(--shadow-2);
  }
  html.nav-open .sidebar { transform: translateX(0); }
  /* Hold the page still behind the open drawer. Without this, flicking past the
     end of the menu hands the momentum to the page, so you close the drawer and
     find you've scrolled somewhere else. overscroll-behavior on .sidebar stops
     the chaining; this stops the body moving at all. */
  html.nav-open, html.nav-open body { overflow: hidden; }
  .sidebar-resizer { display: none; }
  /* Ignore the icon-rail collapse on mobile — the drawer shows full labels
     and group collapse works normally. */
  html.nav-collapsed .sidebar { width: min(var(--sidebar-w), 84vw); flex-basis: auto; }
  html.nav-collapsed .nav { padding: var(--space-3) var(--space-2); }
  html.nav-collapsed .nav-group-label { display: block; }
  html.nav-collapsed .nav-item { justify-content: flex-start; gap: var(--space-3); padding: var(--space-2) var(--space-3); }
  html.nav-collapsed .nav-label { position: static; width: auto; height: auto; clip: auto; }
  html.nav-collapsed .nav-group + .nav-group { border-top: 0; padding-top: 0; }
  html.nav-collapsed .nav-group-head { justify-content: space-between; padding: var(--space-1) var(--space-3); pointer-events: auto; }
  html.nav-collapsed .nav-group-chevron { display: block; }
  html.nav-collapsed .nav-group.collapsed .nav-list { display: none; }
  html.nav-collapsed .nav-group.external-group { display: block; }

  .home-grid { grid-template-columns: 1fr; }
  .global-search .search-hint { display: none; }
}

@media (max-width: 640px) {
  .topbar { flex-wrap: nowrap; gap: var(--space-2); }
  .topbar .brand-name { display: none; }
  .usermenu .who { display: none; }
  /* Tight topbar: the "Demo" marker is the part that must survive, so the
     version drops out beside it (still in the panel). With demo_mode off the
     version IS the pill, so it stays. */
  .buildmenu.is-demo .build-ver { display: none; }
  .buildmenu-panel { width: auto; min-width: 16rem; max-width: calc(100vw - var(--space-4) * 2); }
  .quick-actions { grid-template-columns: 1fr; }
  .week-days { grid-template-columns: repeat(7, 1fr); gap: var(--space-1); }
}

/* ==========================================================================
   Print — hide the shell chrome, keep the content column
   ========================================================================== */
@media print {
  .sidebar, .sidebar-resizer, .nav-scrim, .global-search, .usermenu, .buildmenu, .nav-toggle, .workspace-toolbar { display: none !important; }
  .appshell { display: block; }
  .content-col { width: 100%; }
  main.workspace { max-width: none; }
}

/* Link-outs to adjacent services ("Other services" group) */
.nav-ext {
  width: 14px; height: 14px;
  margin-left: auto;
  fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
  color: var(--color-text-muted);
  flex-shrink: 0;
}
/* The rail is for app destinations — link-outs only show expanded. */
html.nav-collapsed .nav-group.external-group { display: none; }

/* Coming-soon nav items (nav.PREVIEW_UNBUILT development preview) */
.nav-item.soon { opacity: 0.62; }
.nav-item.soon:hover { opacity: 0.85; }
.nav-soon {
  margin-left: auto; padding: 0 var(--space-1);
  font-size: 0.62rem; line-height: 1.5; letter-spacing: 0.03em;
  border-radius: var(--radius-pill); border: 1px solid var(--border-strong);
  color: var(--color-text-muted); background: var(--surface-sunken);
}
.nav-collapsed .nav-soon { display: none; }

/* ---------- "View as {role}" ------------------------------------------------
   A system_admin previewing the app through another role's permissions.

   Amber for the same reason the demo pill is amber: it marks "this is not the
   normal state", and per vms-style-guide brand blue is never a status colour.
   The bar sits under the topbar, full width, on every page — not tucked in the
   user menu. This state changes what you see everywhere, it is easy to forget
   you are in it, and the way out must never be somewhere you have to remember
   to look. It is the visual sibling of the demo pill, one level louder. */
.viewas-bar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  background: var(--status-warn-bg);
  border-bottom: 1px solid var(--status-warn-border);
  color: var(--status-warn-fg);
  font-size: var(--fs-small);
}
.viewas-icon { width: 18px; height: 18px; flex: none; }
.viewas-msg { margin: 0; flex: 1; min-width: 0; }
.viewas-bar form { margin: 0; flex: none; }
.viewas-exit {
  min-height: 32px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-sm);
  border: 1px solid var(--status-warn-fg);
  background: transparent;
  color: var(--status-warn-fg);
  font-size: var(--fs-small);
  font-weight: var(--fw-bold);
  white-space: nowrap;
  cursor: pointer;
}
.viewas-exit:hover { background: var(--status-warn-fg); color: var(--status-warn-bg); }
.viewas-exit:focus-visible { outline: 2px solid var(--focus-color); outline-offset: 2px; }

/* Role picker inside the user menu. Buttons (each its own POST form) styled to
   sit flush with the menu's anchors above them. */
.usermenu-heading {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  padding: var(--space-2) var(--space-3) var(--space-1);
  color: var(--color-text-muted);
  font-size: var(--fs-small);
  font-weight: var(--fw-bold);
}
.usermenu-panel form { margin: 0; }
.usermenu-hint {
  margin: 0;
  padding: 0 var(--space-3) var(--space-2);
  max-width: 15rem;
  color: var(--color-text-muted);
  font-size: var(--fs-small);
  line-height: 1.45;
}
.usermenu-role {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text);
  font-size: var(--fs-body);
  text-align: left;
  cursor: pointer;
}
.usermenu-role:hover { background: var(--surface-sunken); }
.usermenu-role:focus-visible { outline: 2px solid var(--focus-color); outline-offset: -2px; }
.usermenu-role.is-current { font-weight: var(--fw-bold); }

/* The bar is a control, not content — it has no place on a printed page. */
@media print { .viewas-bar { display: none; } }
