/* ============================================================
   TLN Hub — v2 design pilot ("Rail Console")
   Scoped to base_v2.html. Restyles the SAME class names used by
   existing templates (.card, .tbl, .badge, .btn, etc.) rather than
   introducing new ones — no template markup changes needed beyond
   {% extends "base_v2.html" %}.
   ============================================================ */

:root {
  --navy: #0A1A33;
  --navy-2: #16294a;
  --blue: #2C6FAC;
  --bg: #F6F8FB;
  --surface: #ffffff;
  --line: #E2E7EE;
  --text: #101826;
  --text-soft: #5B6572;
  --good: #1D8A57;
  --good-bg: #E4F3EA;
  --good-lt: #3DAE77;
  --warn: #B8791E;
  --warn-bg: #F7ECD8;
  --warn-lt: #E3A94A;
  --bad: #C13A2E;
  --bad-bg: #F8E3E0;
  --bad-lt: #DE6252;
  --blue-bg: #EAF1F8;
  --blue-lt: #5B93C4;
  --radius: 10px;
  /* Typography (revised 2026-09-22): was Lexend for literally everything
     (headings AND body copy AND table cells AND buttons), only money/dates/
     codes broke out into a system mono stack. Now a real 3-way split --
     Lexend stays where it always was doing real work (headings, nav, buttons,
     badges: brand continuity with the TLN logo, which is set in Lexend), a
     second family (Public Sans, chosen over Inter specifically to not read
     as "another Inter dashboard") takes over body copy/table cells/form
     inputs/labels, and --mono is now a real loaded webfont instead of a
     system stack, for every existing var(--mono) money/date/code usage. */
  --display: "Lexend", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --body: "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --mono: "Roboto Mono", ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;

  /* Aliases for the OLD tln.css custom property names — many templates
     reference these directly in inline styles (var(--tln-muted), etc.).
     Rather than hunt every inline usage across ~19 templates, alias them
     here so anything still using the old names resolves to the right v2
     value automatically. */
  --tln-navy: var(--navy);
  --tln-navy-2: var(--navy-2);
  --tln-gray: var(--bg);
  --tln-card: var(--surface);
  --tln-border: var(--line);
  --tln-text: var(--text);
  --tln-muted: var(--text-soft);
  --tln-accent: var(--blue);
  --tln-accent-2: #245a8a;
  --tln-bg-soft: var(--bg);
  --tln-dark: var(--navy);
  --success: var(--good);
  --success-bg: var(--good-bg);
  --success-border: #bfe3cd;
  --error: var(--bad);
  --error-bg: var(--bad-bg);
  --error-border: #f0c4bd;
  --warning: var(--warn);
  --warning-bg: var(--warn-bg);
  --warning-border: #eccd8f;
  --shadow: 0 1px 2px rgba(16,24,38,.04);
}

/* Dark mode -- PULLED BACK 2026-09-24 after shipping. The token system and
   toggle worked (verified in isolation with Chrome headless before
   shipping), but real pages surfaced problems that isolated verification
   didn't catch: table zebra-striping, module-card gradient washes, and
   the home greeting name all broke down visibly once seen live against
   real data. The 4-candidate "Tinted Navy" palette (Candidate A) is still
   the locked color decision; what's missing is a full pass over every
   component that currently assumes a light background (gradients/washes
   especially), not just the ~15-25 flagged hardcoded-hex spots. Token
   values and history are in git (this comment's own commit); the toggle
   button/JS/before-paint script were removed from base_v2.html in the
   same commit. Re-enabling this needs that fuller pass first, not just
   restoring these two blocks.
*/

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; padding: 0; }
button, a, .btn, [role="button"] { touch-action: manipulation; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--body);
  font-size: 15px;
  line-height: 1.5;
}
a { color: var(--blue); }

/* ── Shell / rail nav ─────────────────────────────────────────────
   Rail is fully expanded by default (232px) with a collapse button to
   icons-only (68px). No hover-expand (2026-09-21): the rail changes
   width only when that button is used, and the choice is remembered
   per browser (localStorage, applied as html.rail-collapsed by an
   inline <head> script before first paint so it never flashes).
   --rail-w is what .main offsets by, so content follows the rail.
   Mobile (<=860px) ignores all of this and uses the drawer. ───────── */
:root { --rail-collapsed: 68px; --rail-expanded: 232px; --rail-w: var(--rail-expanded); }
html.rail-collapsed { --rail-w: var(--rail-collapsed); }

.shell { min-height: 100vh; }
.rail {
  background: var(--navy);
  padding: 20px 10px;
  display: flex;
  flex-direction: column;
  position: fixed;
  top: 0; left: 0;
  height: 100vh;
  width: var(--rail-w);
  z-index: 100;
  overflow-x: hidden;
  transition: width .15s ease;
}

/* Nav links scroll independently so rail-footer (My Account / Logout)
   always stays pinned and reachable, even when the link list is taller
   than the viewport -- it doesn't get pushed off the bottom needing an
   extra scroll to find. min-height:0 is required for a flex child to
   actually shrink and scroll instead of growing to fit its content. */
.rail-nav { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.16) transparent; }
.rail-nav::-webkit-scrollbar { width: 6px; }
.rail-nav::-webkit-scrollbar-track { background: transparent; }
.rail-nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,.16); border-radius: 3px; }
.rail-nav::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.3); }

.rail-label { white-space: nowrap; transition: opacity .1s ease; }

.rail-bottom { flex-shrink: 0; padding-top: 10px; }
.rail-toggle { appearance: none; display: flex; align-items: center; width: 100%; padding: 10px; background: none; border: none; border-radius: 8px; color: #8ea3c4; cursor: pointer; }
.rail-toggle:hover { background: #12213e; color: #fff; }
.rail-toggle svg { width: 20px; height: 20px; flex-shrink: 0; }
html.rail-collapsed .rail-toggle-arrow { transform: rotate(180deg); transform-origin: 14.2px 12px; }
@media (min-width: 861px) {
  html.rail-collapsed .rail-label,
  html.rail-collapsed .rail-sub-link { opacity: 0; pointer-events: none; }
}
@media (max-width: 860px) { .rail-bottom { display: none; } }

.rail-tip { position: fixed; z-index: 2100; transform: translateY(-50%); background: #05101f; color: #fff; font-size: 12.5px; font-weight: 600; padding: 6px 11px; border-radius: 7px; white-space: nowrap; pointer-events: none; box-shadow: 0 6px 18px rgba(0,0,0,.35); }
.rail-tip[hidden] { display: none; }
.rail-tip::before { content: ''; position: absolute; left: -4px; top: 50%; width: 8px; height: 8px; background: #05101f; transform: translateY(-50%) rotate(45deg); }

.topbar-user-wrap { position: relative; }
.topbar-avatar-btn { appearance: none; padding: 0; border: 2px solid var(--line); border-radius: 50%; background: none; cursor: pointer; width: 38px; height: 38px; overflow: hidden; display: flex; }
.topbar-avatar-btn:hover { border-color: var(--blue); }
.topbar-avatar-img { width: 100%; height: 100%; object-fit: cover; }
.topbar-avatar-chip { width: 100%; height: 100%; background: var(--blue); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 700; font-family: var(--display); }
.topbar-user-menu { min-width: 200px; }
/* Account menu profile header (2026-09-24) -- photo/initials + name + email
   replaces the old plain name line and the "QUICK ACCESS" eyebrow label
   (both removed as dead chrome once this gives the menu a real visual
   anchor), matching a reference the user pointed to directly. */
.topbar-menu-profile { display: flex; align-items: center; gap: 10px; padding: 10px 10px 12px; }
.topbar-menu-profile-photo { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.topbar-menu-profile-chip { width: 40px; height: 40px; border-radius: 50%; background: var(--blue); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 14px; font-weight: 700; font-family: var(--display); flex-shrink: 0; }
.topbar-menu-profile-copy { min-width: 0; }
.topbar-menu-profile-name { font-family: var(--display); font-size: 14px; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar-menu-profile-email { font-family: var(--body); font-size: 12px; color: var(--text-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 1px; }
.topbar-menu-logout { appearance: none; display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; background: none; border: none; font-family: var(--body); font-size: 13.5px; font-weight: 500; color: var(--bad); padding: 8px 10px; border-radius: 7px; cursor: pointer; }
.topbar-menu-logout:hover { background: var(--bad-bg); }
.topbar-menu-logout svg { width: 15px; height: 15px; flex-shrink: 0; }

.rail-brand { padding: 4px 6px 20px; }
.rail-brand a { display: flex; align-items: center; gap: 10px; color: #fff; text-decoration: none; overflow: hidden; }
.rail-mark { flex-shrink: 0; width: 32px; height: 32px; border-radius: 8px; background: var(--blue); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 700; font-family: var(--display); }
.rail-brand-text { font-weight: 600; font-size: 15px; }
.rail-brand-text small { display: block; font-size: 10px; font-weight: 400; color: #8ea3c4; letter-spacing: .1em; text-transform: uppercase; margin-top: 2px; }

.rail-link { display: flex; align-items: center; gap: 14px; color: #b7c4dc; text-decoration: none; font-size: 13.5px; font-weight: 500; padding: 10px; border-radius: 8px; margin-bottom: 2px; overflow: hidden; position: relative; }
.rail-link:hover { background: #12213e; color: #fff; }
.rail-link svg { width: 19px; height: 19px; opacity: .85; flex-shrink: 0; }
.rail-link.current { background: var(--navy-2); color: #fff; font-weight: 600; }
.rail-link.current svg { opacity: 1; }

/* Sidebar accordion sub-menus + attention badges (added 2026-09-04).
   The parent .rail-link stays a real, single-click link to its module's
   own default page exactly as before -- .rail-chev-btn is a SEPARATE
   click target (stopPropagation) that only toggles the sub-list, so
   existing one-click navigation habits don't change for anyone. */
.rail-chev-btn { appearance: none; background: none; border: none; padding: 4px; margin: -4px -6px -4px auto; color: #7f92b3; cursor: pointer; flex-shrink: 0; display: flex; }
.rail-chev { width: 15px; height: 15px; transition: transform .15s; }
.rail-group.open .rail-chev { transform: rotate(180deg); }
.rail-group.open > .rail-link { background: var(--navy-2); color: #fff; font-weight: 600; }

.rail-sublist { max-height: 0; overflow: hidden; display: flex; flex-direction: column; gap: 1px; }
.rail-group.open .rail-sublist { max-height: 600px; padding: 2px 0 6px 30px; }
html.rail-collapsed .rail-group.open .rail-sublist { max-height: 0; padding: 0; }
.rail-sub-link { display: flex; align-items: center; justify-content: space-between; gap: 6px; padding: 8px 8px 8px 12px; border-radius: 7px; color: #b7c4dc; text-decoration: none; font-size: 13px; font-weight: 500; white-space: nowrap; overflow: hidden; transition: opacity .1s ease; }
.rail-sub-link:hover { background: #12213e; color: #fff; }
.rail-sub-link.current { background: var(--navy-2); color: #fff; font-weight: 600; }

/* Small always-visible corner badge on the collapsed icon -- unlike
   .rail-label, this is NOT opacity-gated, so staff notice something
   needs attention without having to hover the rail open at all. */
.rail-badge-dot { position: absolute; top: 0px; left: 25px; min-width: 18px; height: 18px; padding: 0 4px; border-radius: 9px; background: var(--bad); color: #fff; font-size: 11.5px; font-weight: 700; display: flex; align-items: center; justify-content: center; border: 2px solid var(--navy); line-height: 1; font-family: var(--display); }
.rail-badge-inline { background: var(--bad); color: #fff; font-size: 11px; font-weight: 700; padding: 2px 7px; border-radius: 9px; flex-shrink: 0; }

@media (max-width: 860px) {
  .rail-group.open .rail-sublist, html.rail-collapsed .rail-group.open .rail-sublist { max-height: 600px; padding: 2px 0 6px 30px; }
}

/* Quick external links (Webmail/Helpdesk/TLN Website) -- smaller and
   dimmer than the main module links since these leave the app entirely,
   sitting just above the user/logout footer. */
.rail-quicklinks { margin-top: 10px; padding-top: 10px; border-top: 1px solid #1f3255; }
.rail-section-label { padding: 4px 10px 6px; font-size: 10.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: #6d7fa0; }
.rail-link-sm { padding: 6px 10px; font-size: 12px; color: #8ea0c2; gap: 12px; }
.rail-link-sm svg { width: 15px; height: 15px; }
.rail-link-sm:hover { color: #fff; }

/* Global search trigger + modal (backlog #9). The trigger sits in the
   content topbar above the page; clicking it (or Ctrl/Cmd+K anywhere) opens
   the modal, styled independently of the rail's dark theme since it overlays
   the whole app, not just the sidebar. */
.search-modal-backdrop {
  position: fixed; inset: 0; background: rgba(16, 24, 38, .45);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  z-index: 500; display: flex; align-items: flex-start; justify-content: center;
  padding: 10vh 20px 20px;
}
/* Real bug found live: display:flex above has the same specificity as the
   browser's own [hidden]{display:none}, and author-stylesheet origin beats
   user-agent origin regardless of order -- so the modal's hidden attribute
   was silently never taking effect, showing it open on every page load.
   Same fix already used elsewhere in this file (.actions-menu[hidden],
   .prorate-btn[hidden]). */
.search-modal-backdrop[hidden] { display: none; }
.search-modal {
  /* 8px (down from 12px, 2026-09-24 modal-radius pass) -- shared base for
     search, FAQ (.faq-modal) and idle-timeout (.idle-warning-modal), which
     add their own sizing/layout but never their own radius. */
  background: var(--surface); border-radius: 8px; width: 100%; max-width: 640px;
  max-height: 70vh; display: flex; flex-direction: column; overflow: hidden;
  box-shadow: 0 20px 60px rgba(16,24,38,.35);
}
.search-modal-input-row { display: flex; align-items: center; gap: 10px; padding: 14px 18px; border-bottom: 1px solid var(--line); flex-shrink: 0; }
.search-modal-input-row svg { width: 18px; height: 18px; color: var(--text-soft); flex-shrink: 0; }
.search-modal-input-row input { flex: 1; border: none; outline: none; font-size: 15px; background: transparent; color: var(--text); }
.search-modal-input-row button { background: none; border: none; cursor: pointer; color: var(--text-soft); padding: 4px; display: flex; }
.search-modal-input-row button:hover { color: var(--text); }
.search-modal-input-row button svg { width: 16px; height: 16px; }
.search-modal-results { overflow-y: auto; padding: 8px 0; }
.search-modal-empty { padding: 28px 18px; text-align: center; color: var(--text-soft); font-size: 13.5px; }
.search-modal-heading { padding: 10px 18px 2px; font-size: 12px; font-weight: 600; color: var(--text-soft); }
.search-result-group { padding: 6px 0; }
.search-result-group-label { font-size: 10.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--text-soft); padding: 6px 18px; }
.search-result-item { display: block; padding: 8px 18px; text-decoration: none; color: var(--text); }
.search-result-item:hover { background: var(--bg); }
.search-result-title { font-size: 14px; font-weight: 500; }
.search-result-subtitle { font-size: 12px; color: var(--text-soft); margin-top: 1px; }

/* Content topbar (redesigned 2026-09-24 -- "unified bar", the final pick
   after a dedicated shape mockup over the pill-island and full-navy
   alternatives): ONE bordered/shadowed rounded-rect card holding the
   search field and the icon cluster together, sitting with real margin
   from the page edge rather than bleeding full-bleed. Every color here is
   a real token (--surface/--line), so it participates in the light/dark
   toggle for free -- no separate dark-mode CSS needed for this component,
   confirmed in the mockup that settled this design. backdrop-filter is
   gone (solid --surface instead of a translucent blur), which also
   removes the stacking-context trap that used to force #new-menu/
   #user-menu out to be siblings of body -- that JS positioning still
   works fine and is left as-is, just no longer strictly required. */
.content-topbar {
  position: sticky; top: 14px; z-index: 60;
  display: flex; align-items: center; gap: 12px;
  margin: 0 0 22px; padding: 9px 14px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 2px 10px rgba(16,24,38,.06);
}
.topbar-search-trigger {
  display: flex; align-items: center; gap: 10px; flex: 1; max-width: 420px;
  background: none; border: none; border-radius: 7px;
  padding: 8px 10px; cursor: pointer; font: inherit; color: var(--text-soft); text-align: left;
}
.topbar-search-trigger:hover { background: var(--bg); color: var(--text); }
.topbar-search-trigger svg { width: 17px; height: 17px; flex-shrink: 0; }
.topbar-search-trigger span { flex: 1; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topbar-bar-divider { width: 1px; align-self: stretch; margin: 2px 0; background: var(--line); flex-shrink: 0; }
.topbar-search-kbd {
  font-family: var(--mono); font-size: 10.5px; color: var(--text-soft);
  background: var(--bg); border: 1px solid var(--line); border-radius: 5px; padding: 2px 6px; flex-shrink: 0;
}
.topbar-actions { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.topbar-icon-btn {
  position: relative; width: 36px; height: 36px; border-radius: 50%; border: 1px solid var(--line); background: var(--surface);
  color: var(--text-soft); font-family: var(--display); font-weight: 700; font-size: 15px;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  transition: background .15s, color .15s, transform .08s ease;
}
.topbar-icon-btn:hover { background: var(--bg); color: var(--text); }
.topbar-icon-btn svg { width: 16px; height: 16px; }
.topbar-icon-badge {
  position: absolute; top: -3px; right: -3px; min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 999px; background: var(--bad); color: #fff; font-family: var(--body); font-size: 10.5px;
  font-weight: 700; display: flex; align-items: center; justify-content: center; border: 2px solid var(--surface);
}
/* Help & FAQ trigger (2026-09-24, third look): a filled icon-only chip
   still read as too small/easy to miss once it was sitting inside the
   unified bar next to a full "+ New" button -- promoted to a real .btn
   matching New's own shape (the direct ask), using .btn-light instead of
   .btn-primary so it doesn't compete with New's call-to-action weight.
   svg sizing only; .btn/.btn-light already provide the shape/color. */
/* .btn.topbar-help-btn (not just .topbar-help-btn): .btn's own rule sits
   FURTHER DOWN this file and ties on specificity (one class each), so
   without the extra class here .btn's display:inline-block/line-height:1.4
   silently won the cascade on source order alone -- the display:flex and
   line-height:1 below were never actually applying. This is the real cause
   of the icon/text vertical-alignment issue reported after the icon swap.
   "New" no longer needs this fix (2026-09-26): it moved to icon-only
   .topbar-icon-btn, same shape as the new Alerts button, when the "New"
   label was retired to make room for Alerts in the topbar. */
.btn.topbar-help-btn { display: flex; align-items: center; gap: 6px; line-height: 1; }
.topbar-help-btn svg { width: 16px; height: 16px; flex-shrink: 0; }
/* Mobile-only icon-only variant (round 6): the "Help" label is hidden and
   the pill collapses to a circle (matching the avatar button's own shape)
   to buy back the width New/Help/avatar need in a single mobile row --
   see the media query below. */
.topbar-new-wrap, .topbar-alerts-wrap { position: relative; }
.topbar-new-menu {
  /* position: fixed + JS-set top/left (see base_v2.html's script) rather
     than absolute + CSS offsets -- these are no longer DOM descendants of
     .topbar-new-wrap/.topbar-user-wrap (moved to real siblings of body so
     .content-topbar's backdrop-filter can't trap them in its own stacking
     context; see the HTML comment where they're now defined). */
  position: fixed; min-width: 220px; z-index: 1200;
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 12px 32px rgba(16,24,38,.18); padding: 6px; display: flex; flex-direction: column;
  /* Open/close fade+scale (2026-09-26): [hidden] itself can't transition
     (display:none has no intermediate state), so JS removes [hidden] first,
     then adds .popover-visible a frame later on open, and removes it before
     re-adding [hidden] on close -- see window.tlnOpenPopover/tlnClosePopover
     in base_v2.html. This is the "closed" resting state both before the
     class is added and after it's removed. */
  opacity: 0; transform: translateY(-6px) scale(.98); pointer-events: none;
  transition: opacity .14s ease, transform .14s ease;
}
.topbar-new-menu.popover-visible { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; }
.topbar-new-menu[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) {
  .topbar-new-menu { transition: opacity .14s ease; transform: none; }
  .topbar-new-menu.popover-visible { transform: none; }
}
.topbar-new-menu a, .topbar-new-menu button:not(.topbar-menu-logout) { padding: 8px 10px; border-radius: 7px; text-decoration: none; color: var(--text); font-size: 13.5px; font-weight: 500; display: block; width: 100%; text-align: left; background: none; border: none; cursor: pointer; font-family: var(--body); }
.topbar-new-menu a:hover, .topbar-new-menu button:not(.topbar-menu-logout):hover { background: var(--bg); }
.topbar-new-divider { height: 1px; background: var(--line); margin: 5px 4px; }
.topbar-alerts-menu { min-width: 340px; max-width: 380px; padding: 0; }
.topbar-alerts-head { display: flex; align-items: center; justify-content: space-between; padding: 12px 14px; border-bottom: 1px solid var(--line); font-family: var(--display); font-size: 13px; font-weight: 600; }
.topbar-alerts-head .btn-link { font-family: var(--body); font-size: 12px; font-weight: 600; }
/* Own scrollbar (2026-09-28): many unread alerts made the panel taller than
   the viewport with no way to reach the bottom ones. overscroll-behavior keeps
   a scroll at the list's end from chaining to the page (which would also close
   the menu via the global scroll-to-close handler). */
.topbar-alerts-list { max-height: min(60vh, 420px); overflow-y: auto; overscroll-behavior: contain; }
.topbar-alert-row {
  display: flex; align-items: flex-start; gap: 10px; padding: 11px 14px; border-bottom: 1px solid var(--line);
  max-height: 200px; overflow: hidden;
  transition: max-height .22s ease, opacity .18s ease, padding .22s ease, border-color .22s ease;
}
.topbar-alert-row:last-child { border-bottom: none; }
/* Dismiss animation (2026-09-26): JS adds .is-leaving after the background
   POST resolves, then removes the node once the transition ends -- see the
   "Alerts dismiss" script block in base_v2.html. */
.topbar-alert-row.is-leaving { max-height: 0; opacity: 0; padding-top: 0; padding-bottom: 0; border-bottom-color: transparent; }
.topbar-icon-badge.badge-pulse { animation: topbar-badge-pulse .32s ease; }
@keyframes topbar-badge-pulse { 0% { transform: scale(1); } 45% { transform: scale(1.35); } 100% { transform: scale(1); } }
@media (prefers-reduced-motion: reduce) {
  .topbar-alert-row { transition: none; }
  .topbar-icon-badge.badge-pulse { animation: none; }
}
.topbar-alert-icon { width: 26px; height: 26px; border-radius: 8px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; color: #fff; }
.topbar-alert-icon svg { width: 13px; height: 13px; }
.topbar-alert-warning { background: linear-gradient(135deg, var(--warn-lt), var(--warn)); }
.topbar-alert-info { background: linear-gradient(135deg, var(--blue-lt), var(--blue)); }
.topbar-alert-danger { background: linear-gradient(135deg, var(--bad-lt), var(--bad)); }
.topbar-alert-body { flex: 1; min-width: 0; }
.topbar-alert-text { font-size: 12.5px; line-height: 1.5; color: var(--text); }
.topbar-alert-text a { color: var(--blue); font-weight: 600; text-decoration: none; white-space: nowrap; }
.topbar-alert-x { flex-shrink: 0; background: none; border: none; color: var(--text-soft); cursor: pointer; padding: 2px; display: flex; width: auto !important; }
.topbar-alert-x svg { width: 14px; height: 14px; }
.topbar-alert-x:hover { color: var(--bad); background: none !important; }
/* "Mark resolved" on a failed-job alert. Must out-rank the generic
   .topbar-new-menu button rule (block, full width, padded, grey hover). */
.topbar-new-menu button.topbar-alert-resolve:not(.topbar-menu-logout) { display: inline-block; width: auto; padding: 4px 10px; border: 1px solid var(--line); border-radius: 6px; background: var(--surface); color: var(--text); font-family: var(--display); font-size: 11.5px; font-weight: 600; }
.topbar-new-menu button.topbar-alert-resolve:not(.topbar-menu-logout):hover { background: var(--bg); border-color: var(--text-soft); }
.topbar-alerts-empty { padding: 24px 14px; text-align: center; font-size: 13px; color: var(--text-soft); }
@media (max-width: 860px) {
  /* Back to a single row (2026-09-24, round 6): the two-row layout solved
     the collision but wasn't the preferred look. Instead, Help drops its
     label and becomes an icon-only circle (same footprint class as the
     avatar button), which buys back enough width that search, Help, New
     and the avatar can share one row again on real phone widths without
     the Search label collapsing or the row overflowing. Search itself
     keeps its full "Search everything..." text and just truncates with
     ellipsis when space is tight -- the word "Search" itself always
     renders first, which is the part that matters, per direct instruction. */
  .content-topbar { margin: 0 0 18px; padding: 8px 10px; position: static; }
  .topbar-search-kbd { display: none; }
  .topbar-search-trigger { max-width: none; min-width: 120px; }
  .btn.topbar-help-btn { width: 40px; height: 40px; padding: 0; border-radius: 50%; justify-content: center; gap: 0; flex-shrink: 0; }
  .topbar-help-btn svg { width: 19px; height: 19px; }
  .topbar-help-label { display: none; }
}

/* Help & FAQ modal -- reuses .search-modal's card chrome, taller and with a
   scrollable accordion body instead of a results list. */
.faq-modal { max-width: 560px; max-height: 78vh; display: flex; flex-direction: column; }
.faq-modal-header { display: flex; align-items: center; gap: 10px; padding: 14px 18px; border-bottom: 1px solid var(--line); flex-shrink: 0; }
.faq-modal-header button { background: none; border: none; cursor: pointer; color: var(--text-soft); padding: 4px; display: flex; }
.faq-modal-header button:hover { color: var(--text); }
.faq-modal-header button svg { width: 18px; height: 18px; }
.faq-back-btn { width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--line) !important; flex-shrink: 0; align-items: center; justify-content: center; transition: opacity .15s, width .15s, margin .15s; }
.faq-back-btn:hover { border-color: var(--blue) !important; color: var(--blue) !important; }
.faq-back-btn.hidden-back { opacity: 0; pointer-events: none; width: 0; border: none !important; margin-right: -10px; }
.faq-modal-title-wrap { flex: 1; min-width: 0; }
.faq-modal-eyebrow { font-size: 10px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--blue); margin-bottom: 1px; }
.faq-modal-title-wrap h2 { margin: 0; font-size: 18px; font-family: var(--display); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#faq-modal-close { margin-left: 0; }
.faq-modal-body { overflow: hidden; position: relative; flex: 1; min-height: 320px; }
.faq-view { overflow-y: auto; max-height: 100%; padding: 14px 20px 20px; position: absolute; inset: 0; transition: transform .22s cubic-bezier(.2,.8,.2,1), opacity .18s ease; }
.faq-view-hidden-left { transform: translateX(-20px); opacity: 0; pointer-events: none; }
.faq-view-hidden-right { transform: translateX(20px); opacity: 0; pointer-events: none; }
.faq-cat-search { display: flex; align-items: center; gap: 9px; background: var(--bg); border: 1px solid var(--line); border-radius: 9px; padding: 9px 13px; margin-bottom: 14px; }
.faq-cat-search svg { width: 15px; height: 15px; color: var(--text-soft); flex-shrink: 0; }
.faq-cat-search input { border: none; background: none; outline: none; font: inherit; font-size: 14.5px; width: 100%; color: var(--text); }
.faq-cat-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 9px; }
@media (max-width: 480px) { .faq-cat-grid { grid-template-columns: 1fr; } }
.faq-cat-card { display: flex; align-items: flex-start; gap: 11px; text-align: left; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 13px 14px; cursor: pointer; font: inherit; transition: border-color .12s, background .12s; }
.faq-cat-card:hover { border-color: var(--blue); background: var(--blue-bg); }
.faq-cat-card[hidden] { display: none; }
/* Refined Grid (2026-09-24): per-topic accent, same mc-* scheme as
   Welcome/Admin Tools -- .faq-cat-icon joins the shared .tile-icon /
   .tool-tile-data-icon color rules below instead of a new set. */
.faq-cat-icon { width: 36px; height: 36px; border-radius: 9px; background: var(--blue-bg); color: var(--blue); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.faq-cat-icon svg { width: 18px; height: 18px; }
.faq-cat-card:hover .faq-cat-icon { background: var(--blue); color: #fff; }
.faq-cat-name { display: block; font-family: var(--display); font-size: 14.5px; font-weight: 600; color: var(--text); }
.faq-cat-count { display: block; font-size: 12px; color: var(--text-soft); margin-top: 2px; font-family: var(--mono); }
.faq-cat-empty { padding: 26px 10px; text-align: center; color: var(--text-soft); font-size: 14px; }
.faq-section-label { font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--text-soft); padding: 14px 0 6px; }
.faq-item { border-bottom: 1px solid var(--line); padding: 10px 0; }
.faq-item summary { cursor: pointer; font-size: 15.5px; font-weight: 500; color: var(--text); list-style: none; }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::before { content: '+'; display: inline-block; width: 16px; color: var(--blue); font-weight: 700; }
.faq-item[open] summary::before { content: '\2212'; }
.faq-item p { margin: 8px 0 2px 16px; font-size: 14.5px; color: var(--text-soft); line-height: 1.5; }
.faq-link { display: inline-block; margin: 4px 0 2px 16px; font-size: 13.5px; font-weight: 600; color: var(--blue); text-decoration: none; }
.faq-link:hover { text-decoration: underline; }

.idle-warning-modal { max-width: 380px; }
.idle-warning-body { padding: 28px 26px; text-align: center; }
.idle-warning-body h2 { margin: 0 0 10px; font-size: 18px; font-family: var(--display); }
.idle-warning-body p { margin: 0 0 20px; font-size: 13.5px; color: var(--text-soft); line-height: 1.5; }
.idle-warning-body strong { font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--bad); font-size: 15px; }

.rail-footer { margin-top: auto; padding-top: 14px; border-top: 1px solid #1f3255; }
.rail-user-toggle { display: flex; align-items: center; gap: 10px; color: #dbe4f2; font-size: 12.5px; font-weight: 500; padding: 6px; border-radius: 8px; overflow: hidden; margin-bottom: 2px; }
.rail-avatar-chip { width: 30px; height: 30px; border-radius: 50%; background: var(--blue); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700; flex-shrink: 0; }
.rail-avatar-img { width: 30px; height: 30px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.rail-user-name { text-overflow: ellipsis; }

.main {
  margin-left: calc(var(--rail-w) + max(0px, (100vw - var(--rail-w) - 1440px) / 2));
  margin-right: auto;
  padding: 28px 32px 60px;
  max-width: 1440px;
  transition: margin-left .15s ease;
}

/* No rail present (logged-out pages, e.g. login) — center content instead of offsetting for a rail that isn't there. */
.shell.no-rail .main {
  margin-left: auto;
  padding: 60px 32px;
}

/* ── Mobile top bar (hidden on desktop) ──────────────────────
   Below the breakpoint, the hover-expand rail makes no sense (no
   hover on touch) and permanently eating 68px of a ~375px screen is
   too costly. Rail becomes a full off-canvas drawer, toggled by this
   bar, sliding in from the left with a backdrop — same rail markup
   and same icon+label rows as desktop, just always "expanded" while
   open, so there's one nav visual language, not two. ───────────── */
.mobile-topbar { display: none; }
.rail-backdrop { display: none; }

@media (max-width: 860px) {
  :root { --mobile-topbar-h: 56px; }

  .mobile-topbar {
    display: flex; align-items: center; justify-content: space-between;
    position: fixed; top: 0; left: 0; right: 0; height: var(--mobile-topbar-h);
    background: var(--navy); padding: 0 16px; z-index: 1230;
  }
  .mobile-brand { display: flex; align-items: center; gap: 10px; color: #fff; text-decoration: none; font-weight: 600; font-size: 15px; }
  .mobile-nav-toggle { appearance: none; background: none; border: none; width: 36px; height: 36px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; cursor: pointer; }
  .mobile-nav-toggle span { display: block; width: 20px; height: 2px; background: #fff; border-radius: 2px; }

  .rail-backdrop.open {
    display: block; position: fixed; inset: 0; background: rgba(10,26,51,.45); z-index: 1210;
  }

  /* Drawer stack sits above the 1200 popover layer (.topbar-new-menu,
     .actions-menu) so no menu can ever paint over the open sidebar. */
  .rail {
    z-index: 1220;
    top: 0; width: var(--rail-expanded) !important; overflow-x: hidden;
    transform: translateX(-100%);
    transition: transform .2s ease;
    padding-top: calc(var(--mobile-topbar-h) + 16px);
    /* 100vh can be taller than what's actually visible once a mobile
       browser's address bar is factored in, pushing rail-footer below
       the fold. 100dvh tracks the real visible viewport; the 100vh
       line above is the fallback for browsers that don't support it. */
    height: 100dvh;
  }
  .rail.open { transform: translateX(0); }
  .main {
    margin-left: 0 !important;
    margin-top: var(--mobile-topbar-h);
    padding: 20px 16px 48px;
    max-width: 100%;
  }
}

/* ── Flash message ────────────────────────────────────────── */
.msg { margin: 0 0 20px; padding: 11px 16px; border-radius: 8px; border: 1px solid var(--blue); background: var(--surface); font-size: 14px; font-weight: 600; box-shadow: 0 1px 3px rgba(16,24,38,.05); }

/* Back-to-top button (added 2026-09-04) -- fades in after scrolling about a
   quarter of the way down a page long enough to need it. Fixed to the
   viewport, not the page, so its bottom-right position holds regardless of
   scroll position or page length. */
#back-to-top {
  position: fixed; right: 24px; bottom: 24px; z-index: 90;
  width: 44px; height: 44px; border-radius: 50%; border: none;
  background: var(--navy); color: #fff; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 14px rgba(10,26,51,.28);
  opacity: 0; pointer-events: none; transform: translateY(8px);
  transition: opacity .2s ease, transform .2s ease, background .15s ease;
}
#back-to-top.visible { opacity: 1; pointer-events: auto; transform: translateY(0); }
#back-to-top:hover { background: var(--navy-2); }
#back-to-top svg { width: 20px; height: 20px; }
@media (max-width: 860px) {
  #back-to-top { right: 16px; bottom: 16px; }
}

/* ── Page headers ─────────────────────────────────────────── */
/* Breadcrumb trail (2026-09-24) -- bordered pill, home icon root, chevron
   separators, muted ancestors / bold current page. Sits above .page-header,
   never replaces it. See _breadcrumbs.html for the macro and scoping notes. */
.breadcrumbs { display: inline-flex; align-items: center; gap: 7px; background: var(--surface); border: 1px solid var(--line); border-radius: 999px; padding: 7px 14px; margin-bottom: 14px; font-size: 13px; font-family: var(--display); }
.breadcrumb-home { display: flex; color: var(--text-soft); flex-shrink: 0; }
.breadcrumb-home:hover { color: var(--blue); }
.breadcrumb-home svg { width: 15px; height: 15px; }
.breadcrumb-sep { width: 13px; height: 13px; color: var(--line); flex-shrink: 0; }
.breadcrumb-link { color: var(--text-soft); text-decoration: none; font-weight: 500; white-space: nowrap; }
.breadcrumb-link:hover { color: var(--blue); text-decoration: underline; }
.breadcrumb-current { color: var(--text); font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 260px; }
.breadcrumb-mobile-back { display: none; }
@media (max-width: 640px) {
  /* A pill trail with 3+ segments doesn't have room on a phone width, and
     wrapping it breaks the pill shape -- collapse to a single "back to
     immediate parent" link instead, same idea as Inventory's existing
     "<- Change Library" pattern elsewhere in the app. */
  .breadcrumbs { display: none; }
  .breadcrumb-mobile-back { display: inline-flex; align-items: center; gap: 5px; color: var(--text-soft); text-decoration: none; font-size: 13.5px; font-weight: 600; margin-bottom: 14px; }
  .breadcrumb-mobile-back:hover { color: var(--blue); }
}
.page-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; flex-wrap: wrap; margin-bottom: 22px; }
.page-header h1, .page-header h2 { margin: 0; }
.page-title { margin: 0; font-size: 24px; font-weight: 600; letter-spacing: -.01em; }
.page-sub { margin: 4px 0 0; font-size: 15px; color: var(--text-soft); }
.section-title { margin: 0; font-size: 16px; font-weight: 600; }
/* Home greeting header -- revised 2026-09-25: "Good morning" itself moved
   from Lexend to Public Sans at a heavier weight (700, up from Lexend's
   500) -- direct feedback that Lexend specifically was the miss, not the
   overall pairing. The name stays in Instrument Serif italic/navy scaled
   up 1.11em (relative to this element's own font-size, so it tracks if the
   base size ever changes) to visually balance the serif's smaller x-height
   against the sans weight next to it. */
.home-greeting-eyebrow { font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--text-soft); }
.home-greeting-title { margin: 4px 0 0; font-family: var(--body); font-size: 32px; font-weight: 700; letter-spacing: -.01em; color: var(--text); }
/* Instrument Serif ships one weight (regular) with no bold -- fine against
   a real mixed-case name, but a short all-caps string (e.g. a test account
   literally named "TLN") exposes just how thin that single weight is next
   to the bold Lexend text beside it. A hairline stroke adds a touch of
   optical weight without switching fonts or faking a bold via scale. */
.home-greeting-name { font-family: 'Instrument Serif', serif; font-style: italic; font-weight: 400; font-size: 1.11em; color: var(--navy); -webkit-text-stroke: 0.4px var(--navy); }
/* Larger + bold vs. .page-sub -- staff feedback (2026-08-xx) flagged the
   New Invoice/PO Request subtitle as too small/light to read at a glance. */
.form-request-subtitle { margin: 0 0 16px; font-size: 14.5px; font-weight: 700; color: var(--text); }
.page-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }

/* ── Buttons ──────────────────────────────────────────────── */
.btn { display: inline-block; padding: 9px 16px; border-radius: 8px; border: 1px solid transparent; cursor: pointer; font-weight: 600; font-size: 13.5px; font-family: var(--display); line-height: 1.4; text-decoration: none; transition: background .15s, transform .08s ease; user-select: none; white-space: nowrap; }
/* Press feedback (2026-09-26): a small scale-down on :active reads as
   "responsive" on essentially every button in the app for one shared rule.
   Excludes anything mid-drag/disabled implicitly -- :active doesn't fire
   for those. */
.btn:active, .topbar-icon-btn:active { transform: scale(0.96); }
@media (prefers-reduced-motion: reduce) {
  .btn { transition: background .15s; }
  .topbar-icon-btn { transition: background .15s, color .15s; }
  .btn:active, .topbar-icon-btn:active { transform: none; }
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--blue); color: #fff; }
.btn-primary:hover { background: var(--tln-accent-2); }
.btn-secondary { background: var(--surface); color: var(--text); border-color: var(--line); }
.btn-secondary:hover { background: var(--bg); }
.btn-light { background: var(--blue-bg); color: var(--blue); }
.btn-light:hover { filter: brightness(0.96); }
.btn-danger { background: var(--bad); color: #fff; }
.btn-danger:hover { background: #a02f25; }
.btn-warning { background: var(--warn); color: #fff; }
.btn-warning:hover { background: #9c6519; }
.btn-sm { padding: 6px 12px; font-size: 12.5px; }
.btn-lg { padding: 12px 22px; font-size: 14px; }
.btn-link { background: none; border: none; padding: 0; font-size: 13px; font-weight: 600; color: var(--blue); cursor: pointer; text-decoration: underline; font-family: var(--display); }
.btn-link:hover { color: var(--tln-accent-2); }
.btn-link.danger { color: var(--bad); }
.btn-link.danger:hover { color: #a02f25; }

/* ── Cards / panels ───────────────────────────────────────── */
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: 0 1px 2px rgba(16,24,38,.04); padding: 20px 24px; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.form-card-narrow { max-width: 640px; margin: 0 auto; }

/* ── Divided stat row (totals) ────────────────────────────── */
.totals-card { padding: 4px 0; background: transparent; border: none; box-shadow: none; }
.totals-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 16px; }
.total-item { padding: 4px 16px 4px 0; display: flex; flex-direction: column; gap: 4px; }
.total-item .total-label { font-size: 11.5px; font-weight: 500; color: var(--text-soft); text-transform: none; letter-spacing: 0; }
.total-item .total-value { font-family: var(--mono); font-size: 25px; font-weight: 600; font-variant-numeric: tabular-nums; line-height: 1; color: var(--text); }
.total-item-highlight .total-label, .total-item-highlight .total-value { color: var(--blue); }
.total-item-highlight .total-label { color: var(--blue); font-weight: 600; }
.total-item-highlight .total-value { color: var(--text); font-size: 25px; }

/* ── Tables ───────────────────────────────────────────────── */
.tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.tbl th, .tbl td { padding: 11px 16px; border-bottom: 1px solid var(--line); vertical-align: top; text-align: left; }
.tbl th { font-size: 10.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--text-soft); background: transparent; border-bottom: 1px solid var(--line); }
.tbl tbody tr:nth-child(even) { background: transparent; }
.tbl tbody tr:hover td { background: #FAFBFC; }

/* Sticky first column: only meaningful inside a horizontally-scrolling
   .tbl-scroll wrapper (a table that already fits on screen never needs
   it). Keeps the row's identifying column in view while scrolling right
   through a wide table -- most useful on mobile.
   Known caveat: position:sticky + border-collapse:collapse can drop
   borders on the sticky cells in older Safari -- flagged for review,
   not worked around here since it'd mean touching every .tbl's border
   model to fix a browser-specific edge case. */
.tbl-scroll table.tbl th:first-child,
.tbl-scroll table.tbl td:first-child { position: sticky; left: 0; z-index: 2; background: var(--surface); }
.tbl-scroll table.tbl tbody tr:hover td:first-child { background: #FAFBFC; }
.num { text-align: right; font-variant-numeric: tabular-nums; }
td.num { font-family: var(--mono); }
.desc { max-width: 220px; }
code { font-family: var(--mono); font-size: 12.5px; background: var(--bg); border: 1px solid var(--line); border-radius: 4px; padding: 2px 6px; }

/* ── Badges / status pills ───────────────────────────────── */
.badge { display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px; border-radius: 20px; font-weight: 600; font-size: 11px; border: none; white-space: nowrap; font-family: var(--display); }
.badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex-shrink: 0; }
.badge-ok, .badge-active { background: var(--good-bg); color: var(--good); }
.badge-warning { background: var(--warn-bg); color: var(--warn); }
.badge-inactive { background: #EEF0F3; color: var(--text-soft); }
.badge-inactive::before { display: none; }
.badge-admin { background: var(--blue-bg); color: var(--text); }
.badge-info { background: var(--blue-bg); color: var(--blue); }
.badge-danger { background: var(--bad-bg); color: var(--bad); }

.month-bar-tip {
  position: absolute; bottom: 100%; margin-bottom: 6px;
  background: var(--navy); color: #fff;
  font-size: 11px; font-weight: 600; white-space: nowrap;
  padding: 3px 8px; border-radius: 6px;
  opacity: 0; pointer-events: none; transition: opacity .12s;
}
.month-bar:hover .month-bar-tip { opacity: 1; }
.badge-gray { display: inline-block; padding: 1px 8px; border-radius: 20px; font-size: 10.5px; font-weight: 600; background: #EEF0F3; color: var(--text-soft); vertical-align: middle; margin-left: 4px; font-family: var(--display); }

/* ── Forms ────────────────────────────────────────────────── */
.row { display: flex; gap: 16px; flex-wrap: wrap; }
.col { flex: 1 1 300px; min-width: 240px; }
.field-group { margin-bottom: 16px; }
.field-label { display: block; font-weight: 600; margin: 0 0 6px; font-size: 12.5px; color: var(--text); }
.field-label-sm { display: block; font-weight: 600; margin: 0 0 4px; font-size: 12px; color: var(--text-soft); }
.field-hint, .hint { font-size: 11.5px; color: var(--text-soft); margin: 5px 0 0; }
.req { color: var(--bad); margin-left: 2px; }
.input { width: 100%; padding: 9px 12px; border: 1px solid var(--line); border-radius: 8px; font-size: 13.5px; font-family: var(--mono); background: var(--surface); color: var(--text); transition: border-color .15s; box-sizing: border-box; }
.input:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(44,111,172,.14); }
.input-sm { padding: 7px 10px; font-size: 12.5px; }
select.input, input[type="text"].input, input[type="email"].input, textarea.input { font-family: var(--body); }
.form-actions { display: flex; gap: 10px; margin-top: 20px; flex-wrap: wrap; }
.check-label { display: flex; align-items: center; gap: 8px; font-weight: 500; font-size: 13.5px; cursor: pointer; margin: 0; font-family: var(--body); }
.check-label input[type="checkbox"] { width: auto; margin: 0; }

/* ── Autocomplete ─────────────────────────────────────────── */
.autocomplete-wrap { position: relative; }
.suggestions { border: 1px solid var(--line); border-radius: 8px; background: var(--surface); max-height: 220px; overflow: auto; margin-top: 4px; box-shadow: 0 4px 12px rgba(16,24,38,.09); }
.suggestions:empty { display: none; }
.suggestion-item { padding: 9px 12px; cursor: pointer; font-size: 13.5px; display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.suggestion-item:hover { background: var(--bg); }
.suggestion-item.no-results { color: var(--text-soft); cursor: default; }
.sug-code { font-size: 11px; font-weight: 600; color: var(--text-soft); font-family: var(--mono); background: var(--bg); border-radius: 4px; padding: 1px 6px; flex-shrink: 0; }

/* ── Row actions / empty state ───────────────────────────── */
/* Plain table-cell on purpose: display:flex on a td breaks border-collapse
   row alignment (the divider line steps down under this column). */
.row-actions { white-space: nowrap; }
.row-actions a { display: inline-flex; align-items: center; gap: 4px; font-size: 13px; font-weight: 600; color: var(--blue); text-decoration: none; }
.row-actions a:hover { text-decoration: underline; }
.row-actions > * + * { margin-left: 10px; }
/* Icon + text link for a standalone action outside .row-actions (a
   dedicated table column like Invoice History's "PDF" column) -- not the
   no-icon convention that applies specifically to .actions-menu dropdown
   items, this is a single always-visible link. */
.icon-link { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; font-weight: 600; color: var(--blue); text-decoration: none; }
.icon-link:hover { text-decoration: underline; }
.icon-link svg { width: 14px; height: 14px; flex-shrink: 0; }
.empty-state { text-align: center; padding: 48px 24px; color: var(--text-soft); }
.empty-state p { font-size: 14px; margin: 0 0 16px; }

/* ── Utility ──────────────────────────────────────────────── */
.mt-1 { margin-top: 8px; }
.mt-2 { margin-top: 16px; }
.text-muted { color: var(--text-soft); font-size: 13.5px; }

/* ============================================================
   Rollout pass 2 — bare-element fallbacks + remaining classes used
   by the "simple" pages (login, admin, home, history, profile, new
   request). Mileage/Timesheets intentionally NOT covered here — see
   commit message / conversation for why those are a separate pass.
   ============================================================ */

/* Bare form elements — many templates use unclassed <input>/<label>,
   relying on v1's global defaults rather than the .input/.field-label
   classes. Replicate the same fallback layer here. */
label { display: block; font-weight: 600; margin: 10px 0 6px; font-size: 13.5px; }
input, select, textarea {
  width: 100%; padding: 9px 12px; border: 1px solid var(--line); border-radius: 8px;
  font-size: 13.5px; font-family: var(--display); background: var(--surface); color: var(--text);
  transition: border-color .15s, box-shadow .15s; box-sizing: border-box;
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(44,111,172,.14);
}
textarea { min-height: 90px; resize: vertical; }
input[type="checkbox"], input[type="radio"] { width: auto; }
/* Narrow line-item table columns (Type, Qty, Fee?) can't spare the default
   12px horizontal input/select padding without clipping their own content
   -- a 2-3 character value plus a native select's arrow chrome needs the
   room back more than a comfortable margin does at this width. */
.tbl-compact { padding-left: 6px; padding-right: 6px; }
h1, h2, h3 { color: var(--text); margin: 0 0 8px; font-family: var(--display); }

.label-inline { display: flex; align-items: center; gap: 8px; margin: 0; font-weight: 600; cursor: pointer; font-family: var(--body); }
.label-inline input[type="checkbox"] { width: auto; margin: 0; }
.field-error input, .field-error select, .field-error textarea { border-color: var(--bad); }
.field-error-text { color: var(--bad); font-size: 12.5px; margin-top: 4px; }

/* Password show/hide toggle (login, change password) */
.pw-wrap { position: relative; }
.pw-wrap input { padding-right: 44px; }
.pw-eye { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); background: none; border: none; cursor: pointer; padding: 4px; color: var(--text-soft); line-height: 1; }
.pw-eye:hover { color: var(--text); }
.pw-eye svg { width: 20px; height: 20px; display: block; }

/* Stat / module / library cards (admin dashboard, home) */
.stat-card { flex: 1 1 240px; border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 18px; background: var(--surface); }
.stat-value { font-size: 26px; font-weight: 700; margin-top: 6px; color: var(--text); line-height: 1.1; font-family: var(--mono); font-variant-numeric: tabular-nums; }
/* Basis dropped 240px->210px (2026-09-25): at the app's typical desktop
   content width (rail expanded, ~1200px), 240px basis landed on exactly 4
   per row with a 5th just barely too wide to fit -- leaving Home's 10
   cards (and Admin Panel's 6) with a lonely trailing row. 210px fits 5
   comfortably at that same width without changing the mobile 2-column
   wrap, which .module-card's flex-shrink already handles independent of
   this basis value. */
.module-card { flex: 1 1 210px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px 18px; }
.lib-card { border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 18px; margin-top: 14px; background: var(--surface); }

/* Admin Panel: KPI ledger + Admin Tools tile grid (2026-08-26 redesign --
   Admin Tools used to be squeezed into one stat-card; now it's the page's
   own section, sized for what it actually is). */
.section-label { font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--text-soft); margin: 0 0 12px; }
.kpi-groups { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 30px; }
.kpi-group { background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 18px 18px; }
/* auto-fit, not a fixed repeat(3, ...): today's Admin Panel board rollout
   moved most kpi-group content up into the status-board, leaving this
   card with only 2 .kpi children where it used to have 3 -- a fixed
   3-column grid left a dead empty column same as .kpi-groups did one
   level up. auto-fit sizes to however many children actually exist,
   so this doesn't just move the same bug rather than fix it. */
.kpi-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; }
.kpi-label { font-size: 12px; color: var(--text-soft); margin-bottom: 4px; }
.kpi-delta { display: inline-flex; align-items: center; gap: 3px; margin-top: 6px; font-size: 11.5px; font-weight: 600; color: var(--good); background: var(--good-bg); padding: 2px 7px; border-radius: 999px; }
.kpi-delta.is-negative { color: var(--bad); background: var(--bad-bg); }
.kpi-delta svg { width: 10px; height: 10px; }

.tools-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 12px; }
.tool-tile {
  display: flex; flex-direction: column; gap: 10px; background: var(--surface); border: 1px solid var(--line);
  border-radius: 12px; padding: 16px 16px 14px; text-decoration: none; color: var(--text);
  transition: border-color .15s, transform .15s, box-shadow .15s;
}
.tool-tile:hover { border-color: var(--blue); box-shadow: 0 4px 14px rgba(16,24,38,.06); transform: translateY(-1px); }
.tool-tile:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.tool-icon { width: 34px; height: 34px; border-radius: 9px; background: var(--blue-bg); color: var(--blue); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.tool-icon svg { width: 18px; height: 18px; }
.tool-name { font-size: 14.5px; font-weight: 600; }
.tool-meta { font-size: 12px; color: var(--text-soft); font-family: var(--mono); font-variant-numeric: tabular-nums; }
.tool-tile.attn { border-color: #E9CE9E; background: var(--warn-bg); }
.tool-tile.attn .tool-icon { background: #F1DCAF; color: var(--warn); }
.tool-tile.attn .tool-name { color: #7A5311; }
.tool-tile.attn .tool-meta { color: var(--warn); font-family: var(--display); font-weight: 700; }

@media (max-width: 820px) { .kpi-groups { grid-template-columns: 1fr; } }

/* Compact Grid catalog tiles (2026-08-26, Products & Pricing) -- each tile
   is a native <details>/<summary> so expand/collapse needs no JS and is
   keyboard-accessible for free. Reusable anywhere a long always-open list
   of edit-forms needs a scannable collapsed state instead. */
.tile-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }
.tile { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
.tile.is-missing { border-style: dashed; border-color: #E9CE9E; }
.tile-summary {
  list-style: none; cursor: pointer; padding: 14px 15px; display: flex; flex-direction: column; gap: 8px;
}
.tile-summary::-webkit-details-marker { display: none; }
.tile-summary:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }
.tile-fam { font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-soft); }
.tile-name { font-size: 14.5px; font-weight: 600; color: var(--text); line-height: 1.3; }
.tile-chips { display: flex; gap: 5px; flex-wrap: wrap; min-height: 18px; }
.tile-bottom { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-top: 2px; }
.tile-price { font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 600; font-size: 19px; color: var(--text); }
.tile-price-missing { font-size: 12.5px; font-weight: 600; color: var(--warn); }
.tile-unit { font-size: 11px; color: var(--text-soft); }
.tile-detail-body { padding: 0 15px 16px; border-top: 1px solid var(--line); padding-top: 14px; }
.tile[open] .tile-summary { border-bottom: 1px solid var(--line); }

.chip { display: inline-flex; align-items: center; gap: 4px; font-size: 10.5px; font-weight: 700; letter-spacing: .02em; padding: 3px 8px; border-radius: 999px; white-space: nowrap; }
.chip-gold { background: var(--warn-bg); color: #96650F; }
.chip-silver { background: #EEF0F3; color: #545C68; }
.chip-inactive { background: #EEF0F3; color: var(--text-soft); }
.chip-term { background: var(--blue-bg); color: var(--blue); }

/* Mid-FY proration calculator (Quote Request line items, 2026-08-26) */
.prorate-cell { position: relative; display: flex; align-items: center; gap: 4px; }
.prorate-cell input[name="unit_price[]"] { flex: 1; min-width: 0; }
.prorate-btn { flex-shrink: 0; width: 26px; height: 26px; padding: 0; display: flex; align-items: center; justify-content: center; border: 1px solid var(--line); border-radius: 6px; background: var(--surface); color: var(--text-soft); cursor: pointer; }
.prorate-btn[hidden] { display: none; }
.prorate-btn:hover { border-color: var(--blue); color: var(--blue); }
.prorate-btn svg { width: 14px; height: 14px; }
.prorate-popover { position: fixed; z-index: 1200; width: 230px; background: var(--surface); border: 1px solid var(--line); border-radius: 8px; padding: 10px; box-shadow: 0 6px 18px rgba(16,24,38,.14); }
.prorate-popover select { width: 100%; margin-top: 4px; }
.prorate-preview { font-size: 12px; }

/* Row-level "Quick Actions" menu (renewal worksheets list, 2026-08-29) --
   collapses Download/Inventory/Send/Remind into one control so a wide
   action set doesn't wrap a table row onto multiple lines. Same fixed-
   position-via-JS technique as .prorate-popover above, so it escapes
   .tbl-scroll's overflow clipping instead of getting cut off mid-menu. */
.actions-cell { position: relative; display: inline-block; }
/* Actions trigger (reverted 2026-09-02: a three-dot icon-only button was
   tried and found too small/hard to see -- back to a labeled button, but
   as a real button component (bordered pill) instead of the original bare
   text link, so it reads as clearly clickable at a glance. */
.actions-trigger { display: inline-flex; align-items: center; gap: 5px; padding: 6px 12px; border-radius: 7px; background: var(--bg); border: 1px solid var(--line); font-size: 12.5px; font-weight: 500; color: var(--text); cursor: pointer; font-family: var(--display); white-space: nowrap; }
.actions-trigger:hover, .actions-trigger:focus-visible { background: #EAF1F8; border-color: var(--blue); color: var(--blue); outline: none; }
.actions-trigger svg { width: 11px; height: 11px; flex-shrink: 0; }

/* Menu polish pass (2026-09-02, second round) -- larger padding and radius,
   a stronger shadow so it reads as clearly floating above the row, and
   icons per item (reusing the exact icons the old inline Hotspots buttons
   had, restoring the quick visual-scan cue the plain-text dropdown lost). */
.actions-menu { position: fixed; z-index: 1200; min-width: 170px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 8px; box-shadow: 0 10px 28px rgba(16,24,38,.16); display: flex; flex-direction: column; gap: 2px; }
.actions-menu[hidden] { display: none; }
.actions-menu a, .actions-menu button { display: flex; align-items: center; gap: 9px; width: 100%; text-align: left; padding: 9px 11px; border-radius: 7px; font-size: 13.5px; font-weight: 500; color: var(--text); text-decoration: none; background: none; border: none; cursor: pointer; font-family: var(--body); white-space: nowrap; }
.actions-menu a:hover, .actions-menu button:hover { background: var(--bg); }
.actions-menu a svg, .actions-menu button svg { width: 15px; height: 15px; flex-shrink: 0; color: var(--text-soft); }
.actions-menu form { margin: 0; }
/* Destructive item (Hotspots' Mark Lost/Mark Fallen Out) -- without this
   every item in the menu read the same as Edit/Suspend, losing the red
   "this is different" signal the old inline buttons had. A dedicated
   divider element (not a border on the danger item itself) separates it
   from the status-transition actions above it -- a border-top on the
   danger button fought with that button's own border-radius, giving the
   hover fill a slightly squared-off top corner instead of a clean
   rounded rectangle matching every other item in the menu. */
.actions-menu-divider { height: 1px; background: var(--line); margin: 5px 4px; }
.actions-menu a.danger, .actions-menu button.danger { color: var(--bad); }
.actions-menu a.danger:hover, .actions-menu button.danger:hover { background: var(--bad-bg); }
.actions-menu a.danger svg, .actions-menu button.danger svg { color: var(--bad); }
/* Wider variant for menus with longer labels than Renewal Worksheets'
   original ("Reactivate Replacement" wraps at the default 150px). */
.actions-menu-wide { min-width: 220px; }

/* Page-header sync-tool dropdown (Inventory page, 2026-08-29) -- CrowdStrike
   and Meraki each had 3 flat buttons crammed into .page-actions alongside
   everything else, easy to overlook. Groups each integration's aliases/
   coverage/sync-now actions behind one labeled <details> toggle. Reuses
   .actions-menu's look but positions absolute (not fixed) since this never
   sits inside a scroll-clipped table like the row-level version above. */
.dropdown { position: relative; display: inline-block; }
/* No font-family override here on purpose (2026-09-24) -- this trigger is
   a real .btn (Lexend, like every other button app-wide) while the
   .actions-menu it opens is Public Sans (content). That's the same
   header/button-vs-item split the account menu itself uses ("TLN Tech" /
   "QUICK ACCESS" labels in Lexend, the actual links in Public Sans) --
   not a mixed-font bug, a deliberate two-tier pattern. Roboto Mono stays
   reserved for numeric/KPI data, never menu text either way. */
.dropdown > summary { list-style: none; }
.dropdown > summary::-webkit-details-marker, .dropdown > summary::marker { display: none; }
.dropdown .actions-menu { position: absolute; top: calc(100% + 4px); right: 0; }

/* Tile quick-peek (2026-08-26): a tile's expanded state is a short
   read-only summary, not the full edit form -- editing happens on its
   own page via .tile-edit-link. Keeps the grid condensed even expanded. */
.tile-hist { font-size: 12.5px; }
.hist-row { display: flex; justify-content: space-between; padding: 3px 0; color: var(--text-soft); }
.hist-row strong { font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--text); font-weight: 600; }
.tile-edit-link { display: inline-block; margin-top: 8px; font-size: 12.5px; font-weight: 600; color: var(--blue); text-decoration: none; }
.tile-edit-link:hover { text-decoration: underline; }

/* Filter bar (admin list pages) */
.filter-bar { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; margin-bottom: 16px; }
.filter-bar .filter-field { min-width: 220px; }
.filter-field label { margin: 0 0 4px; font-size: 12.5px; }

/* Status badges / dots (mileage report status, invoice status, etc.) */
.status-badge { display: inline-block; padding: 3px 10px; border-radius: 20px; font-size: 12px; font-weight: 600; white-space: nowrap; font-family: var(--display); }
.status-badge.status-draft { background: #EEF0F3; color: var(--text-soft); }
.status-badge.status-submitted { background: var(--blue-bg); color: var(--text); }
.status-badge.status-approved, .status-badge.status-complete { background: var(--good-bg); color: var(--good); }
.status-badge.status-rejected { background: var(--bad-bg); color: var(--bad); }
.status-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; vertical-align: middle; }
.status-dot-draft { background: var(--text-soft); }
.status-dot-complete { background: var(--good); }
.trip-flag { color: var(--text-soft); }

/* Role badges (admin user list, profile) */
.role-badge { display: inline-block; padding: 2px 9px; border-radius: 20px; font-size: 11px; font-weight: 600; margin-top: 3px; border: 1px solid transparent; font-family: var(--display); }
.role-badge.role-admin { background: var(--blue-bg); border-color: var(--blue); color: var(--text); }
.role-badge.role-supervisor { background: var(--good-bg); border-color: #bfdbfe; color: var(--good); }
.role-badge.role-staff { background: #EEF0F3; border-color: var(--line); color: var(--text-soft); }
.role-badge.role-read_only { background: #EEF0F3; border-color: var(--line); color: var(--text-soft); }

/* Alert bar (home dashboard nudges) */
.alert-bar { border-radius: 8px; padding: 10px 14px; font-size: 14.5px; margin-bottom: 8px; }
.tile-title { font-size: 17px; font-weight: 700; }
.tile-desc { font-size: 14px; color: var(--text-soft); line-height: 1.45; }
.tile-icon { width: 36px; height: 36px; border-radius: 10px; background: var(--blue-bg); color: var(--blue); display: flex; align-items: center; justify-content: center; margin-bottom: 12px; }
.tile-icon svg { width: 19px; height: 19px; }
/* Smaller companion for compact stat-tiles (label + big number): sits
   top-right next to the label rather than above the title, since there's
   no room for a full-size tile-icon in a ~170px-wide card. */
.tile-icon-sm { width: 26px; height: 26px; border-radius: 8px; background: var(--blue-bg); color: var(--blue); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.tile-icon-sm svg { width: 14px; height: 14px; }
/* Analytics redesign (2026-09-25): each section (Billing/Renewal/Assets)
   moved from a bare <h2> + fluid-wrapping .row of tiles straight on the
   page background, into a real .card with a deliberate grid inside --
   TLN-Managed Assets in particular used to land on an uneven 6-then-2
   wrap depending on viewport width. */
.tile-grid { display: grid; gap: 14px; }
.tile-grid-3 { grid-template-columns: repeat(3, 1fr); }
.tile-grid-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 860px) { .tile-grid-3, .tile-grid-4 { grid-template-columns: repeat(2, 1fr); } }
.alert-bar-warning { background: #FBF3E4; border: 1px solid var(--warn); color: #8a5f14; }
.alert-bar-info { background: var(--blue-bg); border: 1px solid var(--blue); color: var(--text); }
.alert-bar-danger { background: var(--bad-bg); border: 1px solid var(--bad); color: var(--bad); }
.msg-error { border-color: var(--bad); background: var(--bad-bg); color: var(--bad); }

/* Renewal-due callout (Inventory Overview, 2026-08-29) -- deliberately
   heavier than a standard .alert-bar since Meraki renewals don't land on
   a shared schedule per library and are a real recurring pain point. */
.renewal-callout { border-radius: 10px; padding: 18px 20px; margin-bottom: 16px; border: 2px solid var(--warn); background: var(--warn-bg); }
.renewal-callout.is-overdue { border-color: var(--bad); background: var(--bad-bg); }
.renewal-callout-title { font-size: 19px; font-weight: 700; color: #8a5f14; margin: 0 0 4px; font-family: var(--display); }
.renewal-callout.is-overdue .renewal-callout-title { color: var(--bad); }
.renewal-callout-sub { font-size: 13.5px; color: var(--text-soft); margin: 0 0 12px; }

/* The .tbl inside here is the one place in the app where a table sits on
   a colored box instead of a plain white card -- the shared .tbl rules
   assume white (sticky first column: var(--surface); row hover: a
   near-white #FAFBFC), which showed as a permanently white first column
   plus a bright near-white flash on hover, both looking like a rendering
   bug against this box's tan/red tint. Scoped override instead of
   touching the shared .tbl rules other tables correctly rely on. */
.renewal-callout .tbl-scroll table.tbl th:first-child,
.renewal-callout .tbl-scroll table.tbl td:first-child { background: var(--warn-bg); }
.renewal-callout.is-overdue .tbl-scroll table.tbl th:first-child,
.renewal-callout.is-overdue .tbl-scroll table.tbl td:first-child { background: var(--bad-bg); }
.renewal-callout .tbl tbody tr:hover td { background: color-mix(in srgb, var(--warn-bg) 88%, black 12%); }
.renewal-callout.is-overdue .tbl tbody tr:hover td { background: color-mix(in srgb, var(--bad-bg) 88%, black 12%); }
.renewal-callout .tbl-scroll table.tbl tbody tr:hover td:first-child { background: color-mix(in srgb, var(--warn-bg) 88%, black 12%); }
.renewal-callout.is-overdue .tbl-scroll table.tbl tbody tr:hover td:first-child { background: color-mix(in srgb, var(--bad-bg) 88%, black 12%); }
.msg-success { border-color: var(--good); background: var(--good-bg); color: var(--good); }

/* Profile avatar */
.profile-avatar { width: 72px; height: 72px; border-radius: 50%; background: var(--blue); color: #fff; font-size: 24px; font-weight: 700; display: flex; align-items: center; justify-content: center; flex-shrink: 0; font-family: var(--display); }
.profile-photo { width: 72px; height: 72px; border-radius: 50%; object-fit: cover; flex-shrink: 0; border: 2px solid var(--line); }

/* Standalone totals (not nested in .total-item — e.g. invoice grand total) */
.total-block { margin-left: auto; display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.total-label { font-size: 11px; color: var(--text-soft); text-transform: uppercase; letter-spacing: .05em; font-weight: 600; }
.total-value { font-size: 20px; font-weight: 700; color: var(--text); line-height: 1.1; font-family: var(--mono); font-variant-numeric: tabular-nums; }

.btn-block { display: block; width: 100%; text-align: center; }
.tbl-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; position: relative; }
.td-actions { display: flex; gap: 6px; flex-wrap: wrap; }

/* Scroll-position-aware affordances for every .tbl-scroll table, driven by
   the is-scrollable/is-scrolled/at-end classes table-tools.js toggles.
   Right-edge fade signals "more to scroll" and disappears once you reach
   the actual end, instead of sitting there permanently. The frozen first
   column only grows its boundary shadow once there's real content hidden
   behind it (scrolled away from the start) -- a table that never scrolls,
   or hasn't been scrolled yet, shows no seam at all. */
.tbl-scroll.is-scrollable:not(.at-end)::after {
  content: "";
  position: absolute; top: 0; right: 0; bottom: 0; width: 28px;
  background: linear-gradient(to right, transparent, rgba(16,24,38,.10));
  pointer-events: none;
}
.tbl-scroll.is-scrolled table.tbl th:first-child,
.tbl-scroll.is-scrolled table.tbl td:first-child { box-shadow: 2px 0 4px rgba(16,24,38,.08); }

/* Toggle switch (invoice fee toggle) */
.toggle-switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; user-select: none; font-weight: 600; font-size: 14px; margin: 0; font-family: var(--display); }
.toggle-switch input[type="checkbox"] { position: absolute; opacity: 0; width: 0; height: 0; }
.toggle-track { width: 44px; height: 24px; background: var(--line); border-radius: 12px; position: relative; flex-shrink: 0; transition: background .2s; }
.toggle-switch input:checked + .toggle-track { background: var(--blue); }
.toggle-thumb { position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; background: #fff; border-radius: 50%; box-shadow: 0 1px 4px rgba(0,0,0,.22); transition: transform .2s; }
.toggle-switch input:checked + .toggle-track .toggle-thumb { transform: translateX(20px); }

.form-footer { margin-top: 18px; border-top: 1px solid var(--line); padding-top: 16px; display: flex; flex-direction: column; gap: 12px; }
.fee-toggle-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.form-actions-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

/* Stacked subtotal/fee breakdown -- mirrors the PDF's summary block (label
   rows, thin divider, Grand Total) instead of a single middot-separated
   line. Used on request/quote forms and their detail pages. */
.money-summary { margin-left: auto; width: 300px; max-width: 100%; }
.money-summary-row { display: flex; justify-content: space-between; gap: 12px; padding: 3px 0; font-size: 13.5px; color: var(--text-soft); }
/* An author-stylesheet display rule and the browser's own [hidden]{display:
   none} rule have EQUAL specificity, and author origin beats user-agent
   origin regardless -- so .money-summary-row's display:flex above silently
   overrode the hidden attribute on #feeRow/#poSubtotalRow/#invoiceSubtotalRow
   the entire time (found while fixing the identical bug on the new search
   modal below). .actions-menu[hidden] and .prorate-btn[hidden] elsewhere in
   this file already use this exact override -- this one was just missed. */
.money-summary-row[hidden] { display: none; }
.money-summary-row strong { font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--text); font-weight: 600; }
.money-summary-divider { border-top: 1px solid var(--line); margin: 8px 0 2px; }

/* Plain-text table cells (no <input>) inherit vertical-align: top from
   .tbl td, which visually sits above center in rows whose other cells are
   taller due to input padding (e.g. a Line Total $ next to Unit Price/Qty
   inputs). Center just those. */
.tbl td.money-cell { vertical-align: middle; }

/* Table search + sort (table-tools.js) */
/* .table-search is class="input table-search" everywhere it's used, so
   .input's own font-family: var(--mono) (meant for money/code fields) was
   winning by source order -- these searches were rendering in monospace
   with no visual cue distinguishing them from a plain label. */
.table-search {
  max-width: 280px;
  font-family: var(--display);
  background-color: var(--bg);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235B6572' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 10px center;
  background-size: 14px 14px;
  padding-left: 32px;
}
.table-search:focus { background-color: var(--surface); }
.table-search-empty { padding: 18px 4px; color: var(--text-soft); font-size: 13.5px; display: none; }
.tbl th.sortable { cursor: pointer; user-select: none; position: relative; padding-right: 18px; }
.tbl th.sortable:hover { color: var(--navy); }
.tbl th.sortable::after { content: "\2195"; position: absolute; right: 4px; opacity: .35; font-size: 11px; }
.tbl th.sortable.sort-asc::after { content: "\2191"; opacity: 1; color: var(--blue); }
.tbl th.sortable.sort-desc::after { content: "\2193"; opacity: 1; color: var(--blue); }

/* ============================================================
   Mileage module
   ============================================================ */
.month-nav { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.month-label { font-weight: 600; font-size: 14px; min-width: 120px; text-align: center; font-family: var(--display); }

.report-status-bar { padding: 10px 16px; border-radius: 8px; font-size: 14px; border: 1px solid var(--line); background: var(--bg); margin-bottom: 4px; }
.report-status-bar.status-draft { border-color: var(--line); background: var(--bg); }
.report-status-bar.status-complete { border-color: var(--good); background: var(--good-bg); }
.report-status-bar.status-submitted { border-color: var(--blue); background: #EAF1F8; }
.report-status-bar.status-approved { border-color: var(--good); background: var(--good-bg); }

.deduction { color: var(--bad); font-weight: 700; }
tr.has-deduction > td { border-top: 2px solid var(--line); }
.date-cell { white-space: nowrap; color: var(--text-soft); font-size: 13.5px; }

.mileage-summary-row { display: grid; grid-template-columns: 1fr 260px; gap: 16px; align-items: start; }
@media (max-width: 860px) { .mileage-summary-row { grid-template-columns: 1fr; } }

.complete-action-card { text-align: center; padding: 20px; }
.complete-icon { font-size: 32px; color: var(--good); margin-bottom: 6px; line-height: 1; }
.complete-icon.incomplete { color: var(--text-soft); }
.complete-label { font-weight: 700; font-size: 14.5px; margin-bottom: 6px; font-family: var(--display); }
.complete-hint { font-size: 13px; color: var(--text-soft); margin: 0 0 14px; line-height: 1.5; }

.pill-selector { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.pill { padding: 8px 18px; border-radius: 999px; border: 1.5px solid var(--line); background: var(--surface); color: var(--text); font-size: 14px; font-weight: 600; font-family: var(--display); cursor: pointer; transition: all .15s; }
.pill:hover { border-color: var(--blue); color: var(--blue); }
.pill-active { background: var(--blue); border-color: var(--blue); color: #fff; }
.pill-active:hover { background: var(--navy-2); border-color: var(--navy-2); color: #fff; }

.dest-field { margin-top: 6px; }
.odo-row { display: flex; gap: 16px; flex-wrap: wrap; }
.odo-row > div { flex: 1 1 180px; }
@media (max-width: 720px) { .odo-row { flex-direction: column; } .month-nav { flex-wrap: wrap; } .totals-grid { grid-template-columns: 1fr 1fr; } }

.check-group { display: flex; flex-direction: column; gap: 8px; margin-top: 6px; }

.details-summary { cursor: pointer; user-select: none; list-style: none; display: inline-flex; align-items: center; gap: 6px; color: var(--blue); font-size: 13.5px; font-weight: 600; font-family: var(--display); padding: 4px 0; margin: 0; border: none; background: none; }
.details-summary::-webkit-details-marker { display: none; }
.odo-toggle-icon { font-size: 16px; line-height: 1; font-weight: 400; transition: transform .15s; display: inline-block; }
details[open] .odo-toggle-icon { transform: rotate(45deg); }
.optional-tag { font-size: 12px; font-weight: 500; color: var(--text-soft); margin-left: 2px; }

@media (max-width: 720px) {
  .col { min-width: 100%; }
  .page-header { flex-direction: column; }
  .filter-bar { flex-direction: column; align-items: stretch; }
  .filter-bar .filter-field { min-width: auto; }
}

/* ── Info affordance + popover (promoted from portal.css, 2026-09-01) ──────
   Was portal-only ("product tooltips"); Hotspots is the first staff-facing
   (base_v2.html) page to need it, so it lives here now instead of being
   duplicated. portal.css keeps its own copy untouched -- not worth the risk
   of a cross-file refactor to de-duplicate for one shared component. */
.info-btn { width: 18px; height: 18px; border-radius: 999px; border: 1px solid var(--line); background: var(--bg); color: var(--text-soft); font-size: 11px; font-weight: 700; font-family: var(--mono); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; flex-shrink: 0; position: relative; padding: 0; transition: background .12s, color .12s, border-color .12s; }
.info-btn:hover, .info-btn:focus-visible { background: var(--blue); border-color: var(--blue); color: #fff; outline: none; }
.info-pop { position: absolute; z-index: 1200; top: calc(100% + 8px); left: 0; width: 250px; max-width: calc(100vw - 32px); background: var(--navy); color: #dbe6f3; font-weight: 400; font-size: 12.5px; line-height: 1.45; border-radius: 8px; padding: 10px 12px; box-shadow: 0 8px 24px rgba(10,26,51,.14); display: none; text-align: left; }
.info-pop strong { color: #fff; }
.info-btn:hover .info-pop, .info-btn:focus-visible .info-pop { display: block; }

/* ── Hotspot Management (Module 11, added 2026-09-01) ──────────────────────
   Library-grouped accordion -- same <details>/<summary> collapsible-card
   mechanism as .tile/.tile-summary (Products & Pricing), but a horizontal
   header row (icon + name + count on the left, status chips on the right)
   instead of .tile's vertical stack, so it needed its own class set. */
.lib-group { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; margin-bottom: 12px; overflow: hidden; }
.lib-summary { list-style: none; cursor: pointer; padding: 15px 18px; display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.lib-summary::-webkit-details-marker { display: none; }
.lib-summary:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }
.lib-summary-left { display: flex; align-items: center; gap: 12px; }
.lib-toggle-icon { width: 18px; height: 18px; color: var(--text-soft); transition: transform .15s; flex-shrink: 0; }
.lib-group[open] .lib-toggle-icon { transform: rotate(90deg); }
.lib-name { font-size: 15px; font-weight: 600; color: var(--text); }
.lib-count { font-size: 12.5px; color: var(--text-soft); }
.lib-chips { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.lib-group[open] .lib-summary { border-bottom: 1px solid var(--line); }
.lib-body { padding: 4px 18px 14px; }

.add-lib-btn { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border-radius: 7px; border: 1px solid var(--line); background: var(--surface); color: var(--blue); cursor: pointer; flex-shrink: 0; }
.add-lib-btn:hover { background: var(--bg); border-color: var(--blue); }
.add-lib-btn svg { width: 15px; height: 15px; }

.chip-good { background: var(--good-bg); color: var(--good); }
.chip-warn { background: var(--warn-bg); color: var(--warn); }
.chip-bad { background: var(--bad-bg); color: var(--bad); }

.countdown { display: block; font-size: 10.5px; color: var(--warn); font-weight: 600; margin-top: 3px; }
.countdown.is-urgent { color: var(--bad); }
.last-action { display: block; font-size: 10.5px; color: var(--text-soft); margin-top: 3px; }

.toolbar-row { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; flex-wrap: wrap; }
.toggle-all-btn { margin-left: auto; background: none; border: none; color: var(--blue); font-size: 12.5px; font-weight: 600; font-family: var(--display); cursor: pointer; padding: 4px 0; text-decoration: underline; }

.action-panel { display: none; margin-top: 8px; padding: 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--bg); }
.action-panel.open { display: block; }
.action-panel .field-group { margin-bottom: 8px; }

/* .row-actions already existed (Maintenance/Renewal Worksheets), styling only
   its <a> children -- Hotspots is the first page to put <button> triggers in
   it too, so those need their own reset (the bare <button> UA-default fallback
   further up this file, "input, select, textarea", doesn't touch <button> at
   all, but the browser's own default button chrome does), plus a size for the
   action icons that every other .row-actions usage in the app doesn't have. */
.row-actions button { display: inline-flex; align-items: center; gap: 4px; font-size: 13px; font-weight: 600; color: var(--blue); background: none; border: none; padding: 0; cursor: pointer; font-family: var(--display); }
.row-actions button:hover { text-decoration: underline; }
.row-actions button.danger { color: var(--bad); }
.row-actions svg { width: 13px; height: 13px; flex-shrink: 0; }
/* The bare-button reset above is a plain descendant selector, so it also
   matches every <button> nested inside an .actions-menu dropdown sitting
   inside the same td.row-actions (Hotspots/Renewal Worksheets/Admin Users)
   -- hijacking Suspend/Resend/Mark Lost/Unmark Received and the "Actions"
   trigger itself into blue-or-red bold Lexend link styling, while <a>
   items (Download/Edit/Inventory) were unaffected since that selector
   only targets <button>. That's the "mix-match" reported live
   (2026-09-24). Fixed with higher-specificity scoped overrides here
   rather than editing the legacy rule, since other pages still rely on
   its original bare-button behavior for buttons that AREN'T inside a
   dropdown. */
.row-actions .actions-trigger { display: inline-flex; align-items: center; gap: 5px; padding: 6px 12px; border-radius: 7px; background: var(--bg); border: 1px solid var(--line); font-size: 12.5px; font-weight: 500; color: var(--text); font-family: var(--display); }
.row-actions .actions-trigger:hover { text-decoration: none; }
.row-actions .actions-menu a, .row-actions .actions-menu button { display: flex; align-items: center; gap: 9px; width: 100%; text-align: left; padding: 9px 11px; border-radius: 7px; font-size: 13.5px; font-weight: 500; color: var(--text); text-decoration: none; background: none; border: none; font-family: var(--body); white-space: nowrap; }
.row-actions .actions-menu a:hover, .row-actions .actions-menu button:hover { background: var(--bg); text-decoration: none; }
.row-actions .actions-menu a.danger, .row-actions .actions-menu button.danger { color: var(--bad); }
.row-actions .actions-menu a.danger:hover, .row-actions .actions-menu button.danger:hover { background: var(--bad-bg); }

/* Quick-filter stat tiles (Hotspots fleet summary, added 2026-09-01) -- the
   same .stat-card look, but a real <a> so a tile doubles as a status filter
   instead of only being a read-only count. Bottom-accent treatment (picked
   2026-09-02 over a left-border/tinted-fill option): a colored bar along the
   bottom edge via ::after, clipped to the card's own radius by overflow:hidden
   on the tile itself, number stays neutral navy instead of tinting per status. */
a.stat-tile { text-decoration: none; color: inherit; display: block; cursor: pointer; position: relative; overflow: hidden; transition: box-shadow .15s, border-color .15s, transform .15s; }
a.stat-tile::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px; }
a.stat-tile:hover { box-shadow: 0 4px 12px rgba(16,24,38,.10); transform: translateY(-1px); }
a.stat-tile.is-selected { box-shadow: 0 0 0 3px rgba(44,111,172,.14); }

/* Stat-tile status colors (added 2026-09-02) -- matches the same badge
   colors used in the table's Status column, so the tile a viewer clicks
   visually maps to what they'll see filtered in. Hover border-color uses
   the same accent as that tile's bottom bar (added 2026-09-02, follow-up:
   the box-shadow-only hover read as too subtle to feel clickable). */
.stat-tile-active::after { background: var(--good); }
.stat-tile-active:hover { border-color: var(--good); }
.stat-tile-active.is-selected { background: var(--good-bg); }
.stat-tile-suspended::after { background: var(--warn); }
.stat-tile-suspended:hover { border-color: var(--warn); }
.stat-tile-suspended.is-selected { background: var(--warn-bg); }
.stat-tile-fallen::after { background: var(--bad); }
.stat-tile-fallen:hover { border-color: var(--bad); }
.stat-tile-fallen.is-selected { background: var(--bad-bg); }
.stat-tile-lost::after { background: var(--text-soft); }
.stat-tile-lost:hover { border-color: var(--text-soft); }
.stat-tile-lost.is-selected { background: #EEF0F3; }

/* Generic tone modifiers (added 2026-09-04, first use: Renewal Worksheets) --
   same bottom-accent .stat-tile treatment as Hotspots, but named by tone
   instead of a bespoke per-status name, so any future stat-tile row can
   reuse these directly instead of inventing new modifier classes each time. */
.stat-tile-good::after { background: var(--good); }
.stat-tile-good:hover { border-color: var(--good); }
.stat-tile-warn::after { background: var(--warn); }
.stat-tile-warn:hover { border-color: var(--warn); }
.stat-tile-bad::after { background: var(--bad); }
.stat-tile-bad:hover { border-color: var(--bad); }
.stat-tile-neutral::after { background: var(--text-soft); }
.stat-tile-neutral:hover { border-color: var(--text-soft); }

/* Fixed, shared column widths across every per-library table on the
   Hotspots dashboard (added 2026-09-02) -- each library renders its own
   <table>, so the browser's default auto-layout sized every table's
   columns independently off that table's own content, which made the
   same column land at a different x-position table to table as you
   scrolled down the page. table-layout:fixed + a shared <colgroup> in
   every table (dashboard.html) forces identical widths everywhere. */
.hotspot-tbl { table-layout: fixed; }
.hotspot-tbl td.clip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.btn-tmobile { background: #E20074; color: #fff; display: inline-flex; align-items: center; gap: 6px; }
.btn-tmobile:hover { background: #C10063; }
.btn-tmobile svg { width: 14px; height: 14px; }

/* CrowdStrike Falcon console link -- dark gray + orange per the user's own
   branding call, echoing (not reproducing) CrowdStrike's real palette. Same
   external-portal-link pattern as .btn-tmobile above. */
.btn-crowdstrike { background: #2B2B2E; color: #fff; display: inline-flex; align-items: center; gap: 6px; }
.btn-crowdstrike:hover { background: #1A1A1C; }
.btn-crowdstrike svg { width: 14px; height: 14px; stroke: #FC4C02; }

/* Cisco Meraki's real brand teal, same external-portal-link pattern. */
.btn-meraki { background: #04859D; color: #fff; display: inline-flex; align-items: center; gap: 6px; }
.btn-meraki:hover { background: #036A7E; }
.btn-meraki svg { width: 14px; height: 14px; }

/* ── Mileage (added 2026-09-02): table + a dark "Total Reimbursement"
   tile side by side on desktop, matching the mockup direction the user
   picked over the plain totals-grid card. Collapses to one column at
   tablet width so the tile naturally falls below the table instead of
   squeezing beside it -- the same design also picked for mobile. */
.mileage-layout { display: grid; grid-template-columns: 1fr 300px; gap: 20px; align-items: start; }
.mileage-sidebar { display: flex; flex-direction: column; gap: 16px; }
.mileage-total-tile { background: var(--navy); border-radius: var(--radius); padding: 22px; color: #fff; }
.mileage-total-label { font-size: 11.5px; color: #9fb0c9; text-transform: uppercase; letter-spacing: .04em; margin-bottom: 6px; }
.mileage-total-value { font-family: var(--mono); font-size: 32px; font-weight: 700; font-variant-numeric: tabular-nums; }
.mileage-total-breakdown { display: flex; justify-content: space-between; margin-top: 16px; padding-top: 16px; border-top: 1px solid #1f3255; font-size: 12.5px; color: #c7d3e6; }
.mileage-total-breakdown + .mileage-total-breakdown { margin-top: 6px; padding-top: 0; border-top: none; }
.mileage-total-breakdown span:last-child { font-weight: 600; color: #fff; font-variant-numeric: tabular-nums; }
@media (max-width: 860px) {
  .mileage-layout { grid-template-columns: 1fr; }
}

/* ── Add Trip distance calculator (added 2026-09-03): form stays left-
   aligned, inline Google Map + Calculate Distance panel sits to the
   right instead of the old "opens a popup window" button. Only rendered
   when GOOGLE_MAPS_EMBED_KEY is configured -- see entry_form.html. */
.trip-layout { display: grid; grid-template-columns: 1fr 380px; gap: 20px; align-items: start; }
.trip-layout .form-card-narrow { max-width: none; margin: 0; }
.trip-map-panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px; position: sticky; top: 20px; }
.trip-map-panel-title { margin: 0 0 16px; font-size: 15px; font-weight: 700; color: var(--text); }
.trip-map-panel .field-group { margin-bottom: 12px; }
.trip-map-frame { margin-top: 14px; border-radius: 8px; overflow: hidden; background: var(--bg); min-height: 320px; }
.trip-map-frame iframe { display: block; }
.trip-map-frame-empty { display: flex; align-items: center; justify-content: center; height: 320px; color: var(--text-soft); font-size: 13px; text-align: center; padding: 0 20px; }
@media (max-width: 860px) {
  .trip-layout { grid-template-columns: 1fr; }
  .trip-map-panel { position: static; }
}

/* Mileage table -> card list on phones, same technique as .hotspot-tbl:
   thead hidden, each td relabeled via data-label + ::before, tr becomes
   a fixed-area CSS grid instead of a table row. Date and Actions stay
   unlabeled (self-explanatory, matching the Hotspots precedent). */
@media (max-width: 720px) {
  .mileage-tbl thead { display: none; }
  .mileage-tbl, .mileage-tbl tbody { display: block; width: 100%; }
  .mileage-tbl tr {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "date date"
      "destination destination"
      "miles deduction"
      "parking parking"
      "description description"
      "actions actions";
    gap: 8px;
    border: 1px solid var(--line); border-radius: 10px;
    padding: 14px; margin-bottom: 10px; background: var(--surface);
  }
  .mileage-tbl tr > * { border: none; padding: 0; white-space: normal; }
  .mileage-tbl tr > *:nth-child(1) { grid-area: date; font-weight: 600; color: var(--text); }
  .mileage-tbl tr > *:nth-child(2) { grid-area: destination; }
  .mileage-tbl tr > *:nth-child(3) { grid-area: miles; }
  .mileage-tbl tr > *:nth-child(4) { grid-area: deduction; }
  .mileage-tbl tr > *:nth-child(5) { grid-area: parking; }
  .mileage-tbl tr > *:nth-child(6) { grid-area: description; }
  .mileage-tbl tr > *:nth-child(7) {
    grid-area: actions; border-top: 1px solid var(--line);
    padding-top: 10px; margin-top: 4px;
  }
  .mileage-tbl td.num { text-align: left; }
  .mileage-tbl td[data-label]::before {
    content: attr(data-label);
    display: block; font-size: 10px; font-weight: 700; text-transform: uppercase;
    letter-spacing: .03em; color: var(--text-soft); margin-bottom: 2px;
  }
}

/* ── Mobile/tablet table + touch polish (added 2026-09-02) ──────────
   .tbl-scroll's horizontal scroll (defined near line 527) has been the
   app's ONLY responsive strategy for tables, on every table-bearing
   page, since the app was built -- nothing signals there's more to
   scroll, and .row-actions controls have zero padding (fine for a
   mouse pointer, too small a hit target for a finger). This block is
   deliberately placed at the END of the file: several rules here
   override earlier same-specificity declarations (.row-actions button's
   padding:0 in particular), and CSS resolves an exact specificity tie
   by source order, so this has to sort after everything it touches.
   Scoped to the same 860px breakpoint the rail nav already collapses
   at, and applies automatically to every .tbl-scroll/.tbl/.row-actions
   already in the app -- no template changes required anywhere. */
@media (max-width: 860px) {
  /* The right-edge "more to scroll" fade and the frozen-column boundary
     shadow are now universal (scroll-position-aware, defined near line
     543 via table-tools.js's is-scrollable/is-scrolled/at-end classes),
     not mobile-only static rules -- nothing mobile-specific needed here
     for that anymore.

     Slightly denser table so more columns are visible before a viewer
     needs to scroll at all, without going small enough to hurt legibility. */
  .tbl { font-size: 12.5px; }
  .tbl th, .tbl td { padding: 9px 12px; }

  /* Real tap targets. Desktop keeps padding:0 (mouse pointers don't need
     this and the denser look reads better with a cursor); this only
     changes hit-target size on touch-scale viewports. */
  .row-actions button, .row-actions a { padding: 8px 4px; min-height: 40px; }
  .row-actions > * + * { margin-left: 14px; }
}

/* ── Hotspots table -> card list on phones (added 2026-09-02) ───────
   First page in the app converted from "scroll a wide table sideways"
   to an actual mobile layout: below 720px the 8-column .hotspot-tbl
   renders as one card per device instead of a table row, the standard
   responsive-table pattern (thead hidden, each td relabeled via
   data-label + ::before, tr switched to a flex column so field order
   can be promoted with `order` independent of the source column order
   the sortable-header JS and colgroup still rely on above 720px).
   Deliberately scoped to .hotspot-tbl only, not .tbl generally --
   every other table in the app keeps the horizontal-scroll pattern
   from the block above until it gets its own pass. */
@media (max-width: 720px) {
  .tbl-scroll:has(.hotspot-tbl) { overflow-x: visible; }
  .tbl-scroll.is-scrollable:has(.hotspot-tbl):not(.at-end)::after { display: none; }

  .hotspot-tbl thead { display: none; }
  .hotspot-tbl, .hotspot-tbl tbody { display: block; width: 100%; }
  .hotspot-tbl tr {
    display: flex; flex-direction: column; gap: 7px;
    border: 1px solid var(--line); border-radius: 10px;
    padding: 14px; margin-bottom: 12px; background: var(--surface);
  }
  .hotspot-tbl td {
    display: block; border-bottom: none; padding: 0; position: static;
  }
  .hotspot-tbl td.clip { white-space: normal; overflow: visible; text-overflow: clip; }
  .hotspot-tbl td::before {
    content: attr(data-label);
    display: block; font-size: 10px; font-weight: 700; letter-spacing: .04em;
    text-transform: uppercase; color: var(--text-soft); margin-bottom: 2px;
  }
  /* Mobile Number and Status are what a staff member scans for first --
     promoted to the top of the card regardless of the table's real
     (desktop) column order. */
  .hotspot-tbl td[data-label="Mobile Number"] { order: -3; font-size: 15px; font-weight: 600; }
  .hotspot-tbl td[data-label="Status"] { order: -2; }
  .hotspot-tbl td.row-actions {
    order: 99; white-space: normal; padding-top: 10px; margin-top: 2px;
    border-top: 1px solid var(--line); display: flex; flex-wrap: wrap; gap: 10px 16px;
  }
  /* Flex gap already spaces these -- without this, the base
     .row-actions > * + * { margin-left: 14px } rule (860px block above)
     still applies too, since these elements are still .row-actions
     children, and would stack an extra 14px on top of the gap. */
  .hotspot-tbl td.row-actions > * + * { margin-left: 0; }
  .hotspot-tbl td.row-actions::before { display: none; }
  .hotspot-tbl td.row-actions .action-panel { flex-basis: 100%; }
}

/* Activity Log feed (Module 15). Mirrors the .rail-avatar-chip initials
   treatment for the actor avatar, and the .chip/.badge verb-color mapping
   already used elsewhere (good=complete/approve, warn=modify, bad=void/
   delete, info=create) rather than inventing a new palette. */
.activity-feed { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: 0 1px 2px rgba(16,24,38,.04); overflow: hidden; }
.activity-day-label { padding: 12px 22px 6px; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-soft); background: #FAFBFC; border-bottom: 1px solid var(--line); }
.activity-row { display: flex; gap: 13px; padding: 14px 22px; border-bottom: 1px solid var(--line); }
.activity-row:last-child { border-bottom: none; }
.activity-avatar { width: 32px; height: 32px; border-radius: 50%; background: var(--blue); color: #fff; display: flex; align-items: center; justify-content: center; font-family: var(--display); font-size: 11.5px; font-weight: 700; flex-shrink: 0; margin-top: 1px; }
.activity-body { flex: 1; min-width: 0; }
.activity-line { font-size: 13.5px; color: var(--text); }
.activity-line a { color: var(--blue); text-decoration: none; font-weight: 600; }
.activity-line a:hover { text-decoration: underline; }
.activity-meta { display: flex; align-items: center; gap: 8px; margin-top: 4px; flex-wrap: wrap; }
.activity-time { font-family: var(--mono); font-size: 11.5px; color: var(--text-soft); }
.activity-module-tag { font-size: 11.5px; color: var(--text-soft); }
.verb-chip {
  display: inline-flex; align-items: center; gap: 4px; font-family: var(--display);
  font-size: 10px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
  padding: 2px 8px; border-radius: 999px;
}
.verb-chip::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.verb-created { background: var(--blue-bg); color: var(--blue); }
.verb-modified { background: var(--warn-bg); color: var(--warn); }
.verb-completed, .verb-approved, .verb-restored { background: var(--good-bg); color: var(--good); }
.verb-voided, .verb-deleted { background: var(--bad-bg); color: var(--bad); }
.verb-sent_back { background: #EEF0F3; color: var(--text-soft); }
.verb-synced { background: var(--blue-bg); color: var(--blue); }
.verb-failed { background: var(--bad-bg); color: var(--bad); }
.verb-resolved { background: var(--good-bg); color: var(--good); }
.verb-login_failed { background: var(--bad-bg); color: var(--bad); }
.verb-password_changed, .verb-password_reset { background: var(--good-bg); color: var(--good); }
.verb-reset_requested { background: var(--warn-bg); color: var(--warn); }
.activity-detail {
  margin-top: 7px; font-size: 12.5px; color: var(--text-soft); background: var(--bg);
  border: 1px solid var(--line); border-radius: 7px; padding: 8px 11px; font-family: var(--mono);
  white-space: pre-line;
}
.activity-empty { padding: 40px 22px; text-align: center; color: var(--text-soft); font-size: 13.5px; }
.activity-load-more { text-align: center; padding: 16px; }

/* Activity Log mobile card fix (2026-09-23): this feed predates the generic
   .tbl-cards mobile-card treatment (2026-09-07) and was never brought in
   line with it -- .activity-row only ever had a bottom border, like a plain
   list, so on a narrow screen the avatar+text flex row squeezed and wrapped
   into what read as two disconnected rows instead of one card. Matches
   .tbl-cards' actual look now: each row is its own bordered, rounded,
   floating card, not a continuous bordered list. Also tightened padding and
   the avatar/detail sizing -- flagged as taking more space than it needs. */
@media (max-width: 720px) {
  .activity-feed { background: none; border: none; box-shadow: none; overflow: visible; }
  .activity-day-label { padding: 4px 2px 8px; background: none; border-bottom: none; }
  .activity-row {
    border: 1px solid var(--line); border-radius: 10px; background: var(--surface);
    padding: 12px; margin-bottom: 10px; gap: 10px;
  }
  .activity-row:last-child { border-bottom: 1px solid var(--line); margin-bottom: 10px; }
  .activity-avatar { width: 26px; height: 26px; font-size: 10px; }
  .activity-line { font-size: 13px; }
  .activity-detail { font-size: 12px; padding: 7px 10px; margin-top: 6px; }
}

/* Branded error pages: 403, 404, 500, and the portal-shelled 403 variant
   all share this same card/icon/actions treatment. */
.error-page { max-width: 480px; margin: 60px auto; padding: 40px 32px; text-align: center; }
.error-icon { width: 64px; height: 64px; margin: 0 auto 18px; border-radius: 50%; background: var(--bad-bg); color: var(--bad); display: flex; align-items: center; justify-content: center; }
.error-icon svg { width: 32px; height: 32px; }
.error-actions { display: flex; justify-content: center; gap: 10px; margin-top: 22px; }

/* Generic mobile-card table (added 2026-09-07). Extends the .hotspot-tbl
   technique (thead hidden, each td relabeled via data-label + ::before, tr
   becomes a card) to ANY table via a shared class instead of one bespoke
   CSS block per table -- add class="tbl-cards" alongside the existing
   "tbl" class, and data-label="Column Name" on each <td> (omit it on a
   column that's self-explanatory or already a .row-actions cell). Rolled
   out 2026-09-07 to every list table in the app except Timesheets history
   (deliberately kept horizontal-scroll-only, user's call) and Mileage/
   Hotspots (already had their own bespoke pre-existing treatment). */
@media (max-width: 720px) {
  .tbl-scroll:has(.tbl-cards) { overflow-x: visible; }
  .tbl-scroll.is-scrollable:has(.tbl-cards):not(.at-end)::after { display: none; }

  .tbl-cards thead { display: none; }
  .tbl-cards, .tbl-cards tbody { display: block; width: 100%; }
  .tbl-cards tr {
    display: flex; flex-direction: column; gap: 7px;
    border: 1px solid var(--line); border-radius: 10px;
    padding: 14px; margin-bottom: 12px; background: var(--surface);
  }
  .tbl-cards td {
    display: block; border-bottom: none; padding: 0; position: static;
    white-space: normal;
  }
  .tbl-cards td::before {
    content: attr(data-label);
    display: block; font-size: 10px; font-weight: 700; letter-spacing: .04em;
    text-transform: uppercase; color: var(--text-soft); margin-bottom: 2px;
  }
  .tbl-cards td:not([data-label])::before,
  .tbl-cards td[data-label=""]::before { content: none; margin-bottom: 0; }
  .tbl-cards td.row-actions {
    order: 99; padding-top: 10px; margin-top: 2px;
    border-top: 1px solid var(--line); display: flex; flex-wrap: wrap; gap: 10px 16px;
  }
  .tbl-cards td.row-actions > * + * { margin-left: 0; }
  .tbl-cards td.row-actions::before { display: none; }
  .tbl-cards td.money-cell, .tbl-cards td.num { text-align: left; }
  /* A single-column colspan row (an empty-state message) shouldn't get
     card chrome or a label -- it isn't a real record. */
  .tbl-cards tr:has(td[colspan]) { border: none; padding: 0; background: none; margin-bottom: 0; }
  .tbl-cards tr:has(td[colspan]) td { padding: 14px 0; }

  /* Two real bugs found live on real devices 2026-09-08:
     1. `.tbl-scroll table.tbl td:first-child { position: sticky; z-index: 2; }`
        (defined outside this media query, applying at every width) is MORE
        specific than the `.tbl-cards td { position: static }` rule above --
        classes .tbl-scroll+.tbl+:first-child (3) beats .tbl-cards alone (1)
        -- so it silently never cleared in card mode. A leftover sticky,
        z-indexed first cell inside a flex-column card is exactly the kind
        of thing that can end up compositing above other sticky elements
        (like the topbar) depending on scroll position -- !important is the
        pragmatic fix here, not a specificity rewrite, since the rule that
        needs beating was already winning by accident, not by design.
     2. `.renewal-callout`'s hover-darken and the base `.tbl` row-hover
        (line ~402) have no reason to fire in card mode: there's no "row"
        left to hover, just a card with one inline link, and on a touch
        screen the simulated :hover state visibly sticks on whichever
        card was last tapped instead of clearing, reading as a stray
        highlighted card. */
  .tbl-cards td:first-child { position: static !important; z-index: auto !important; }
  .tbl-cards tr:hover td,
  .tbl-cards tr:hover td:first-child,
  .renewal-callout .tbl-cards tr:hover td,
  .renewal-callout .tbl-cards tr:hover td:first-child,
  .renewal-callout.is-overdue .tbl-cards tr:hover td,
  .renewal-callout.is-overdue .tbl-cards tr:hover td:first-child {
    background: var(--surface) !important;
  }
}

/* ============================================================
   "Warm Glow" design trial (2026-09-08), scoped to Home, Activity
   Log, and Hotspots only, per the user's request to see it live on
   a few real pages before deciding on a full rollout -- these are
   ADDITIVE modifier classes (stat-tile-glow / module-card-glow /
   alert-bar-glow) layered on top of the existing stat-tile/
   module-card/alert-bar classes, so every other page is completely
   unaffected. See the reviewed canvas for the reference design.
   ============================================================ */

/* --- Stat tiles: Activity Log (good/warn/bad/neutral) and Hotspots
   (active/suspended/fallen/lost, which map onto the same 4 hues) --- */
a.stat-tile.stat-tile-glow {
  border-radius: 16px; padding: 18px 20px 20px; isolation: isolate; overflow: hidden;
}
a.stat-tile.stat-tile-glow::after { display: none; }
.stat-tile-glow.stat-tile-good, .stat-tile-glow.stat-tile-active { background: linear-gradient(135deg, #fff 55%, var(--good-bg)); }
.stat-tile-glow.stat-tile-warn, .stat-tile-glow.stat-tile-suspended { background: linear-gradient(135deg, #fff 55%, var(--warn-bg)); }
.stat-tile-glow.stat-tile-bad, .stat-tile-glow.stat-tile-fallen { background: linear-gradient(135deg, #fff 55%, var(--bad-bg)); }
.stat-tile-glow.stat-tile-neutral, .stat-tile-glow.stat-tile-lost { background: linear-gradient(135deg, #fff 55%, #EEF0F3); }

.tile-glow-blob { position: absolute; width: 90px; height: 90px; border-radius: 50%; right: -30px; top: -30px; filter: blur(2px); opacity: .5; z-index: -1; pointer-events: none; }
.stat-tile-glow.stat-tile-good .tile-glow-blob, .stat-tile-glow.stat-tile-active .tile-glow-blob { background: radial-gradient(circle, var(--good-lt), transparent 70%); }
.stat-tile-glow.stat-tile-warn .tile-glow-blob, .stat-tile-glow.stat-tile-suspended .tile-glow-blob { background: radial-gradient(circle, var(--warn-lt), transparent 70%); }
.stat-tile-glow.stat-tile-bad .tile-glow-blob, .stat-tile-glow.stat-tile-fallen .tile-glow-blob { background: radial-gradient(circle, var(--bad-lt), transparent 70%); }
.stat-tile-glow.stat-tile-neutral .tile-glow-blob, .stat-tile-glow.stat-tile-lost .tile-glow-blob { background: radial-gradient(circle, #9aa4b2, transparent 70%); }

.tile-glow-icon { width: 34px; height: 34px; border-radius: 10px; display: flex; align-items: center; justify-content: center; color: #fff; margin-bottom: 12px; }
.tile-glow-icon svg { width: 17px; height: 17px; }
.stat-tile-glow.stat-tile-good .tile-glow-icon, .stat-tile-glow.stat-tile-active .tile-glow-icon { background: linear-gradient(135deg, var(--good-lt), var(--good)); }
.stat-tile-glow.stat-tile-warn .tile-glow-icon, .stat-tile-glow.stat-tile-suspended .tile-glow-icon { background: linear-gradient(135deg, var(--warn-lt), var(--warn)); }
.stat-tile-glow.stat-tile-bad .tile-glow-icon, .stat-tile-glow.stat-tile-fallen .tile-glow-icon { background: linear-gradient(135deg, var(--bad-lt), var(--bad)); }
.stat-tile-glow.stat-tile-neutral .tile-glow-icon, .stat-tile-glow.stat-tile-lost .tile-glow-icon { background: linear-gradient(135deg, #9aa4b2, var(--text-soft)); }

/* Hotspots' click-to-filter is-selected state used to swap the whole tile
   background to a solid tint -- the glow variant's background is already
   doing gradient work, so selected state becomes an inset ring instead. */
.stat-tile-glow.is-selected { transform: none; }
.stat-tile-glow.stat-tile-active.is-selected { box-shadow: 0 0 0 2px var(--good) inset; }
.stat-tile-glow.stat-tile-suspended.is-selected { box-shadow: 0 0 0 2px var(--warn) inset; }
.stat-tile-glow.stat-tile-fallen.is-selected { box-shadow: 0 0 0 2px var(--bad) inset; }
.stat-tile-glow.stat-tile-lost.is-selected { box-shadow: 0 0 0 2px var(--text-soft) inset; }

/* --- Home page quick-action tiles (module-card): these are plain nav
   tiles, not status tiles, so one uniform blue accent, not per-module
   semantic color -- there's no "good/warn/bad" being reported here. --- */
.module-card.module-card-glow {
  position: relative; overflow: hidden; isolation: isolate; border-radius: 16px;
  background: linear-gradient(135deg, #fff 60%, var(--blue-bg));
  transition: box-shadow .15s, transform .15s;
}
.module-card.module-card-glow:hover { box-shadow: 0 4px 12px rgba(16,24,38,.10); transform: translateY(-1px); }
.module-card-glow .tile-glow-blob { background: radial-gradient(circle, var(--blue-lt), transparent 70%); }
.module-card-glow .tile-glow-icon { background: linear-gradient(135deg, var(--blue-lt), var(--blue)); }

/* --- Home page alert banners --- */
.alert-bar.alert-bar-glow {
  display: flex; align-items: center; gap: 14px; border-radius: 14px; padding: 12px 16px;
  background: var(--surface); border: 1px solid var(--line); box-shadow: 0 1px 3px rgba(16,24,38,.06);
}
.alert-bar-glow .alert-glow-badge { width: 34px; height: 34px; border-radius: 10px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; color: #fff; }
.alert-bar-glow .alert-glow-badge svg { width: 17px; height: 17px; }
.alert-bar-glow.alert-bar-warning .alert-glow-badge { background: linear-gradient(135deg, var(--warn-lt), var(--warn)); box-shadow: 0 4px 10px -3px rgba(184,121,30,.55); }
.alert-bar-glow.alert-bar-info .alert-glow-badge { background: linear-gradient(135deg, var(--blue-lt), var(--blue)); box-shadow: 0 4px 10px -3px rgba(44,111,172,.5); }
.alert-bar-glow.alert-bar-danger .alert-glow-badge { background: linear-gradient(135deg, var(--bad-lt), var(--bad)); box-shadow: 0 4px 10px -3px rgba(193,58,46,.5); }
.alert-glow-body { flex: 1; }

/* --- "Soft Edge" tile variant (swapped in 2026-09-08 to compare against
   Warm Glow on the same three trial pages): the flat bottom stripe becomes
   a soft gradient wash across the top of the card instead, larger radius,
   no icon chip -- closer to today's real look than Warm Glow is. --- */
.stat-tile.stat-tile-soft, .module-card.module-card-soft {
  border-radius: 14px; position: relative; overflow: hidden;
}
.module-card.module-card-soft { padding: 20px 18px; }
a.stat-tile.stat-tile-soft::after { display: none; }
.stat-tile.stat-tile-soft::before, .module-card.module-card-soft::before {
  content: ""; position: absolute; left: 0; top: 0; right: 0; height: 64px; opacity: .55; pointer-events: none; z-index: 0;
}
.stat-tile-soft.stat-tile-good::before, .stat-tile-soft.stat-tile-active::before { background: linear-gradient(180deg, var(--good-bg) 0%, transparent); }
.stat-tile-soft.stat-tile-warn::before, .stat-tile-soft.stat-tile-suspended::before { background: linear-gradient(180deg, var(--warn-bg) 0%, transparent); }
.stat-tile-soft.stat-tile-bad::before, .stat-tile-soft.stat-tile-fallen::before { background: linear-gradient(180deg, var(--bad-bg) 0%, transparent); }
.stat-tile-soft.stat-tile-neutral::before, .stat-tile-soft.stat-tile-lost::before { background: linear-gradient(180deg, #EEF0F3 0%, transparent); }
.module-card-soft::before { background: linear-gradient(180deg, var(--blue-bg) 0%, transparent); }
.stat-tile.stat-tile-soft > *, .module-card.module-card-soft > * { position: relative; z-index: 1; }

/* Hotspots' click-to-filter is-selected state, same inset-ring approach as
   the Warm Glow variant, for the same reason (the top wash is already
   doing color work, so selection becomes a ring rather than a bg swap). */
.stat-tile-soft.stat-tile-active.is-selected { box-shadow: 0 0 0 2px var(--good) inset; }
.stat-tile-soft.stat-tile-suspended.is-selected { box-shadow: 0 0 0 2px var(--warn) inset; }
.stat-tile-soft.stat-tile-fallen.is-selected { box-shadow: 0 0 0 2px var(--bad) inset; }
.stat-tile-soft.stat-tile-lost.is-selected { box-shadow: 0 0 0 2px var(--text-soft) inset; }

.loader-overlay { position: fixed; inset: 0; z-index: 2000; display: flex; align-items: center; justify-content: center; padding: 16px; background: rgba(246, 248, 251, 0.6); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.loader-overlay[hidden] { display: none; }
.loader-card { width: 100%; max-width: 460px; background: var(--surface); border-radius: 8px; padding: 30px 30px 24px; text-align: center; box-shadow: 0 20px 60px rgba(10, 26, 51, 0.18), 0 2px 8px rgba(10, 26, 51, 0.08); }
.loader-eyebrow { font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-soft); font-weight: 600; margin-bottom: 14px; }
.loader-card h2 { margin: 0 0 8px; font-family: var(--display); font-size: 22px; color: var(--text); }
.loader-card p { margin: 0 0 20px; font-size: 14px; color: var(--text-soft); line-height: 1.5; }
.loader-bar { height: 8px; border-radius: 999px; background: var(--line); overflow: hidden; position: relative; }
.loader-bar.indeterminate::after { content: ''; position: absolute; top: 0; bottom: 0; width: 35%; border-radius: 999px; background: var(--blue); animation: loader-slide 1.3s ease-in-out infinite; }
.loader-bar-fill { height: 100%; width: 0%; border-radius: 999px; background: var(--blue); transition: width .35s ease; }
@keyframes loader-slide { 0% { left: -35%; } 100% { left: 100%; } }
.loader-progress-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 10px 0 18px; font-size: 13px; color: var(--text-soft); }
#loader-progress-count { font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--text); font-weight: 600; }
#loader-progress-count:empty { display: none; }
.loader-elapsed span { font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--text); }
.loader-note { background: var(--bg); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; font-size: 13px; color: var(--text-soft); line-height: 1.5; }
body.loader-open { overflow: hidden; }
@media (prefers-reduced-motion: reduce) { .loader-bar::after { animation-duration: 3s; } }

/* Confirm dialog (2026-09-24) -- "shell-match + risk accent" per direct
   feedback: same card chrome as .loader-card (radius, shadow, centered
   text) so a confirm that leads into the loader reads as one flow, with a
   colored icon badge (reusing .alert-glow-badge's own gradient treatment)
   as the only thing that changes per risk level. See confirm-dialog.js. */
.confirm-modal-backdrop { z-index: 2050; }
.confirm-modal-card { width: 100%; max-width: 420px; background: var(--surface); border-radius: 8px; padding: 28px 28px 22px; text-align: center; box-shadow: 0 20px 60px rgba(10, 26, 51, 0.18), 0 2px 8px rgba(10, 26, 51, 0.08); }
.confirm-modal-icon { width: 44px; height: 44px; border-radius: 12px; margin: 0 auto 14px; display: flex; align-items: center; justify-content: center; color: #fff; }
.confirm-modal-icon svg { width: 21px; height: 21px; }
.confirm-modal-card.confirm-risk-danger .confirm-modal-icon { background: linear-gradient(135deg, var(--bad-lt), var(--bad)); box-shadow: 0 4px 10px -3px rgba(193,58,46,.5); }
.confirm-modal-card.confirm-risk-warn .confirm-modal-icon { background: linear-gradient(135deg, var(--warn-lt), var(--warn)); box-shadow: 0 4px 10px -3px rgba(184,121,30,.55); }
.confirm-modal-card.confirm-risk-info .confirm-modal-icon { background: linear-gradient(135deg, var(--blue-lt), var(--blue)); box-shadow: 0 4px 10px -3px rgba(44,111,172,.5); }
#confirm-modal-title { margin: 0 0 8px; font-family: var(--display); font-size: 20px; color: var(--text); }
#confirm-modal-message { margin: 0 0 4px; font-size: 14px; color: var(--text-soft); line-height: 1.5; }
#confirm-modal-message:last-of-type { margin-bottom: 20px; }
/* Preview line (e.g. "43 organizations") uses the exact same mono/tabular
   treatment as #loader-progress-count -- flagged directly as a risk to
   watch for, since this is the one spot in the dialog carrying a number
   that must visually match the loader it's about to hand off to. */
.confirm-modal-preview { background: var(--bg); border: 1px solid var(--line); border-radius: 12px; padding: 10px 14px; margin: 0 0 20px; font-size: 13px; color: var(--text-soft); line-height: 1.5; }
.confirm-modal-preview strong { font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 600; color: var(--text); }
.confirm-modal-actions { display: flex; gap: 10px; justify-content: center; }
.confirm-modal-actions .btn { flex: 1 1 0; }

.signed-cell { display: flex; align-items: center; gap: 8px; margin-top: 4px; }
.signed-upload-form { display: inline; margin: 0; }
.signed-thumb { appearance: none; padding: 0; width: 34px; height: 44px; border: 1px solid var(--line); border-radius: 4px; background: var(--bg); overflow: hidden; cursor: pointer; flex-shrink: 0; }
.signed-thumb:hover { border-color: var(--blue); }
.signed-thumb img { width: 100%; height: 100%; object-fit: cover; object-position: top; display: block; }
.signed-thumb span { font-size: 10px; color: var(--text-soft); }
.signed-modal { position: fixed; inset: 0; z-index: 1900; background: rgba(10, 26, 51, 0.6); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); display: flex; align-items: center; justify-content: center; padding: 16px; }
.signed-modal[hidden] { display: none; }
.signed-modal-card { background: var(--surface); border-radius: 8px; width: 100%; max-width: 860px; max-height: 94vh; display: flex; flex-direction: column; overflow: hidden; }
.signed-modal-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--line); }
.signed-modal-head strong { font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.signed-modal-actions { display: flex; gap: 8px; flex-shrink: 0; }
.signed-modal-body { overflow: auto; background: var(--bg); padding: 12px; text-align: center; flex: 1 1 auto; }
.signed-modal-body img { max-width: 100%; height: auto; box-shadow: 0 2px 10px rgba(10, 26, 51, 0.15); background: #fff; }
.signed-modal-pager { display: flex; justify-content: center; align-items: center; gap: 14px; padding: 10px; border-top: 1px solid var(--line); font-size: 13px; color: var(--text-soft); }

.filter-chips { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
/* Full-width status-tab row (2026-09-25): a segmented-control-style bar
   for pages whose filter is a small, fixed set of status tabs (Admin
   Corrections is the first) -- spans the full row instead of bunching
   left as plain .page-actions buttons with a lot of dead space beside
   them. Equal-width cells regardless of label length, the standard
   segmented-control convention. */
.tab-bar { display: flex; gap: 8px; flex-wrap: wrap; }
.tab-bar > .btn { flex: 1 1 0; text-align: center; }
.filter-chip { appearance: none; display: flex; align-items: center; gap: 6px; padding: 7px 13px; border-radius: 999px; border: 1px solid var(--line); background: var(--surface); color: var(--text-soft); font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; }
.filter-chip span { font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 700; color: var(--text-soft); background: var(--bg); border-radius: 999px; padding: 1px 7px; font-size: 11.5px; }
.filter-chip:hover { border-color: #c7d1e0; color: var(--text); }
.filter-chip.active { background: var(--navy); border-color: var(--navy); color: #fff; }
.filter-chip.active span { background: rgba(255,255,255,.18); color: #fff; }
.filter-chip-attn.active { background: var(--bad); border-color: var(--bad); }

/* ---- Renewal Worksheets: compact table redesign (2026-09-22) ----
   Scoped to #rwTable rather than touching the shared .tbl rules every other
   table in the app relies on (see the .renewal-callout precedent above for
   the same scoping approach). Bounded height + position:sticky on thead only
   works with a real scrolling ancestor, so .rw-scroll gets its own
   overflow-y instead of relying on the page's own scroll. */
.tbl-scroll.rw-scroll { max-height: 640px; overflow-y: auto; }
#rwTable { font-size: 13px; }
#rwTable thead th { position: sticky; top: 0; background: var(--surface); z-index: 4; padding: 10px 14px; }
#rwTable tbody td { padding: 9px 14px; }
#rwTable tbody tr:nth-child(even) td { background: #FBFCFD; }
#rwTable tbody tr:hover td { background: var(--blue-bg); }
.tbl-scroll.rw-scroll table.tbl tbody tr:hover td:first-child { background: var(--blue-bg); }
#rwTable .rw-libname { font-weight: 600; }
#rwTable .rw-libcode { font-family: var(--mono); font-size: 11px; color: var(--text-soft); margin-left: 6px; }

.rw-chip { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; padding: 3px 9px; border-radius: 999px; white-space: nowrap; }
.rw-chip .rw-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.rw-st-notgenerated { color: var(--text-soft); background: rgba(91, 101, 114, .09); }
.rw-st-notgenerated .rw-dot { background: var(--text-soft); }
.rw-st-generated { color: var(--blue); background: var(--blue-bg); }
.rw-st-generated .rw-dot { background: var(--blue); }
.rw-st-sent { color: var(--good); background: var(--good-bg); }
.rw-st-sent .rw-dot { background: var(--good); }
.rw-st-failed { color: var(--bad); background: var(--bad-bg); }
.rw-st-failed .rw-dot { background: var(--bad); }
.rw-comm-label { display: inline-block; font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .02em; padding: 2px 7px; border-radius: 5px; margin-right: 4px; }
.rw-comm-sent { color: var(--good); background: var(--good-bg); }
.rw-comm-corrected { color: var(--blue); background: var(--blue-bg); }
.rw-comm-reminded { color: var(--warn); background: var(--warn-bg); }
.rw-comm-finalnotice { color: var(--bad); background: var(--bad-bg); }

.rw-warn-flag { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; font-weight: 600; color: var(--warn); background: var(--warn-bg); border-radius: 999px; padding: 2px 8px 2px 6px; margin-left: 6px; }
.rw-warn-flag svg { width: 11px; height: 11px; }

.rw-recv { display: flex; align-items: center; gap: 6px; flex-wrap: nowrap; white-space: nowrap; }
.rw-recv-pill { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; padding: 3px 5px 3px 10px; border-radius: 999px; border: none; cursor: pointer; font-family: inherit; }
.rw-recv-pill.is-pending { background: var(--bg); border: 1px solid var(--line); color: var(--text-soft); }
.rw-recv-pill.is-pending:hover { border-color: var(--blue); color: var(--blue); }
.rw-recv-pill.is-received { background: var(--good-bg); color: var(--good); }
.rw-recv-pill .rw-go { width: 16px; height: 16px; border-radius: 50%; background: rgba(255,255,255,.65); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.rw-recv-pill .rw-go svg { width: 9px; height: 9px; }
.rw-icon-btn { appearance: none; width: 26px; height: 26px; border-radius: 7px; border: 1px solid var(--line); background: var(--surface); color: var(--text-soft); display: flex; align-items: center; justify-content: center; cursor: pointer; flex-shrink: 0; }
.rw-icon-btn:hover { border-color: var(--blue); color: var(--blue); }
.rw-icon-btn svg { width: 13px; height: 13px; }

/* ---- Renewal Worksheets: action toolbar redesign (2026-09-22) ----
   Real near-miss reported: every selection button except "Send Selected"
   was .btn-light (a light BLUE tint, not neutral gray -- see .btn-light's
   own rule above), so the whole row read as "shades of blue" and the one
   solid-blue button acted as a magnet for the click regardless of intent,
   most dangerously when the intent was Remind, not a real resend of the
   original worksheet. Fix is per-action semantic color + icon, grouped by
   consequence (prep/no-email vs the two email-sending actions), not one
   arbitrary "primary" button among identical grays. */
.btn-good { background: var(--good); color: #fff; }
.btn-good:hover { background: #166b47; }
/* Soft-tint variants (2026-09-25) for the renewal-worksheet toolbar merge
   below: same hue-coding as .btn-good/.btn-warning (still NOT identical
   colors -- see the near-miss comment above this block), just a lighter
   fill to read calmer next to the now-merged filter chips. Send stays
   solid .btn-primary on purpose: it's the one real worksheet-email send,
   worth staying the most visually weighted action in the row. */
.btn-good-light { background: var(--good-bg); color: var(--good); }
.btn-good-light:hover { filter: brightness(0.96); }
.btn-warn-light { background: var(--warn-bg); color: var(--warn); }
.btn-warn-light:hover { filter: brightness(0.96); }
.btn-danger-light { background: var(--bad-bg); color: var(--bad); }
.btn-danger-light:hover { filter: brightness(0.96); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.rw-toolbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; padding: 10px 12px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; }
.rw-toolbar .filter-chips { margin-bottom: 0; }
.rw-toolbar-group { display: flex; align-items: center; gap: 8px; }
.rw-toolbar-divider { width: 1px; align-self: stretch; background: var(--line); margin: 2px 2px; }
.rw-toolbar .btn svg { width: 13px; height: 13px; margin-right: 2px; flex-shrink: 0; }
.rw-selcount { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 12px; color: var(--text-soft); white-space: nowrap; }
.rw-selcount b { color: var(--text); }

.actions-trigger-icon { padding: 0; width: 30px; height: 30px; justify-content: center; background: none; border: 1px solid transparent; }
.actions-trigger-icon:hover, .actions-trigger-icon:focus-visible { background: var(--bg); border-color: var(--line); color: var(--navy); }
.actions-trigger-icon svg { width: 16px; height: 16px; margin: 0; }

/* Mobile stat-tile grid, standardized to 2 columns everywhere (2026-09-23) --
   .stat-card defaults to a 240px flex-basis, which only fits one tile per
   row on a phone; some pages (Activity Log, Admin Analytics) happened to
   set a per-tile inline style="flex:1 1 170px" that fits two, others
   (Maintenance, Hotspots) didn't, so mobile spacing was inconsistent
   page to page. User liked the 2-up look and asked for it everywhere.
   !important is required to beat that inline style where it's set --
   the only way an external stylesheet can override inline CSS -- and is
   scoped narrowly to this one selector under this one breakpoint. */
@media (max-width: 720px) {
  .row > .stat-card { flex: 1 1 calc(50% - 8px) !important; min-width: 0; }
}

/* "Status board" header (2026-09-23) -- built for Maintenance from the
   winning mockup direction (a dark summary band putting an overdue/urgent
   count and the page's KPIs on equal footing as one status readout, in the
   same navy the rail already uses), written as a genuinely reusable
   component (not page-specific classes) since the user wants this pattern
   considered for other stat-header/KPI pages later, not just this one. */
.status-board { background: var(--navy); border-radius: 14px; padding: 20px 24px; color: #fff; }
.status-board-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.status-board-title { font-family: var(--display); font-size: 25px; font-weight: 600; color: #fff; margin: 0; }
.status-board-sub { font-size: 14px; color: #aebada; margin: 4px 0 0; }
.status-board-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.status-board-fy-tabs { display: flex; background: rgba(255,255,255,.08); border-radius: 8px; padding: 3px; gap: 2px; }
.status-board-fy-tabs a { font-family: var(--mono); font-size: 12.5px; font-weight: 600; color: #aebada; text-decoration: none; padding: 6px 11px; border-radius: 6px; }
.status-board-fy-tabs a:hover { color: #fff; }
.status-board-fy-tabs a.current { background: #fff; color: var(--navy); }
.status-board-icon-btn { display: flex; align-items: center; gap: 6px; background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.12); color: #dbe4f2; border-radius: 8px; padding: 7px 12px; font-size: 12.5px; font-weight: 600; text-decoration: none; }
.status-board-icon-btn:hover { background: rgba(255,255,255,.15); color: #fff; }
.status-board-icon-btn svg { width: 15px; height: 15px; flex-shrink: 0; }
.status-board-divider { height: 1px; background: rgba(255,255,255,.12); margin: 18px 0; }
.status-board-kpis { display: flex; align-items: center; gap: 0; flex-wrap: wrap; }
.status-board-overdue { padding-right: 28px; margin-right: 28px; border-right: 1px solid rgba(255,255,255,.12); }
.status-board-overdue-num { font-family: var(--mono); font-size: 42px; font-weight: 700; color: var(--warn-lt); line-height: 1; }
.status-board-overdue-label { font-size: 13.5px; color: #aebada; margin-top: 4px; line-height: 1.35; }
.status-board-overdue-link { display: inline-block; margin-top: 6px; font-size: 12px; font-weight: 600; color: #8ec3f5; text-decoration: underline; }
/* flex:1 (not just min-width) so the KPI row actually spreads across the
   card's full width instead of clumping at the left with dead space to the
   right -- the divider between each block (border-right, removed on the
   last one) is what makes that spread read as intentional columns rather
   than random gaps. */
.status-board-kpi { min-width: 110px; flex: 1 1 0; padding: 0 18px; border-right: 1px solid rgba(255,255,255,.12); }
.status-board-kpi:first-child { padding-left: 0; }
.status-board-kpi:last-child { border-right: none; padding-right: 0; }
/* PC/Network Hours carry a much longer value ("1219.00 / 2030.00") than
   Total Visits/Avg. Hrs ("161", "7.6") -- equal flex:1 on all four left
   the long ones cramped and the short ones sitting on dead space. Weight
   the split toward content instead of splitting the row evenly. */
.status-board-kpi-wide { flex: 1.8 1 0; }
.status-board-kpi-narrow { flex: 0.7 1 0; }
@media (max-width: 720px) {
  /* Grid items default to min-width:auto (won't shrink below their content's
     intrinsic width), so a long label or a wide mono number forced the
     whole grid -- and .status-board with it -- wider than the viewport
     instead of wrapping. */
  .status-board-kpi, .status-board-overdue { min-width: 0; }
  .status-board-kpi-label { white-space: normal; }
  /* A right-border divider makes sense in the desktop single row; in the
     2-col grid it would land on odd cells only (col boundary) and even
     cells (container edge) inconsistently, so drop it in favor of the
     grid's own gap for separation. */
  .status-board-kpi { border-right: none; padding: 0; }
}
.status-board-kpi-label { font-size: 13.5px; color: #aebada; margin-bottom: 5px; }
.status-board-kpi-value { font-family: var(--mono); font-size: 27px; font-weight: 700; color: #fff; font-variant-numeric: tabular-nums; }
.status-board-kpi-value span { font-size: 18px; font-weight: 500; color: #8b9bbd; }
.status-board-progress { height: 5px; border-radius: 999px; background: rgba(255,255,255,.14); overflow: hidden; margin-top: 7px; max-width: 160px; }
.status-board-progress > div { height: 100%; background: var(--blue-lt); border-radius: 999px; }
.status-board-rank { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 6px; background: var(--blue-bg); color: var(--blue); font-family: var(--mono); font-size: 11px; font-weight: 700; flex-shrink: 0; }
/* Admin Panel's Export Year field, living in the status-board's dark
   header (2026-09-25): a plain number input styled to match the other
   status-board-actions chips. Font is Public Sans, not mono -- the
   placeholder/label text is prose, a real typed year still reads mono
   via the browser's own default number-input rendering. */
.status-board-export-input { background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.16); color: #fff; border-radius: 8px; padding: 7px 10px; font-size: 12.5px; width: 80px; font-family: var(--body); }
.status-board-export-input::placeholder { color: #8b9bbd; }
.status-board-actions .info-btn { background: rgba(255,255,255,.12); border-color: rgba(255,255,255,.2); color: #dbe4f2; }
.status-board-actions .info-btn:hover, .status-board-actions .info-btn:focus-visible { background: #fff; border-color: #fff; color: var(--navy); }
/* Secondary toolbar (2026-09-25): the app-wide follow-up to the status-
   board's header actions -- when a page has more controls than the 1-2
   core exports (external portal links, sync dropdowns, etc.), those live
   here instead of crowding the dark header. First used on Inventory. */
.secondary-toolbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 12px; padding: 10px 12px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; }
/* Interactive status-board KPI tile (2026-09-25): a real click-to-filter
   control living in the dark header, first built for Hotspots. A pale
   background tint (the light-theme .stat-tile-soft convention) would wash
   out on navy, so each tile's semantic color is a top-down fade wash
   instead (color-mix, same technique already used for .renewal-callout's
   hover row); the active one gets a colored inset ring plus a small
   checkmark badge rather than a solid fill swap. Set --accent inline per
   tile (a var(--good-lt)-style dark-safe color, not the light-theme
   --good/--warn/--bad tokens, which read too dark against navy). */
.status-board-kpi-tile { flex: 1 1 0; min-width: 130px; display: block; text-decoration: none; padding: 12px 14px; border-radius: 10px; background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 16%, transparent) 0%, transparent 75%); border: 1px solid rgba(255,255,255,.1); position: relative; }
@media (min-width: 721px) {
  /* .status-board-kpis has gap:0 (divider-style KPIs separate themselves with
     border-right), so bordered tiles sat edge to edge. Desktop only: the
     mobile grid already supplies its own gap. */
  .status-board-kpi-tile + .status-board-kpi-tile { margin-left: 14px; }
}
.status-board-kpi-tile:hover { background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 24%, transparent) 0%, transparent 75%); }
.status-board-kpi-tile.selected { box-shadow: 0 0 0 2px var(--accent) inset; }
.status-board-kpi-tile-label { font-size: 13px; color: #aebada; margin-bottom: 6px; }
.status-board-kpi-tile-value { font-family: var(--mono); font-size: 24px; font-weight: 700; color: #fff; font-variant-numeric: tabular-nums; }
.status-board-kpi-check { position: absolute; top: 10px; right: 10px; width: 16px; height: 16px; border-radius: 50%; background: var(--accent); display: flex; align-items: center; justify-content: center; }
.status-board-kpi-check svg { width: 10px; height: 10px; color: var(--navy); }
/* Brand-colored status-board action buttons: NOT combined with the
   existing .btn-tmobile/.btn-primary classes -- those tie on specificity
   with .status-board-icon-btn (one class each), and .status-board-icon-btn
   sits later in this file, so it would silently win the background/color
   properties regardless of which page's markup loads first. Same class of
   bug as the topbar icon/text alignment fix earlier this session. */
.status-board-icon-btn.status-board-btn-primary { background: var(--blue); border-color: var(--blue); color: #fff; }
.status-board-icon-btn.status-board-btn-tmobile { background: #E20074; border-color: #E20074; color: #fff; }
.status-board-icon-btn.status-board-btn-tmobile:hover { background: #C10063; }
@media (max-width: 720px) {
  .status-board { padding: 16px; }
  .status-board-header { flex-direction: column; align-items: stretch; }
  .status-board-actions { justify-content: flex-start; }
  .status-board-kpis { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 18px 16px; }
  .status-board-overdue { grid-column: 1 / -1; border-right: none; border-bottom: 1px solid rgba(255,255,255,.12); padding: 0 0 14px; }
}

/* Service-card grid refinement (2026-09-24) -- picked "data-forward" from
   the module-card-grid mockup pass (https://claude.ai/artifact/KFhbnu5eucYcWLB9ZtTCrb):
   real per-module color instead of every card washing the same uniform pale
   blue, Admin Tools' live count becomes the visually prominent element, and
   a lift+shadow hover with no border-color swap (the icon chip already
   carries the module's color at rest, so a border swap on hover was
   redundant). Colors reuse the app's existing semantic tokens rather than
   inventing a new palette: blue for primary/financial-adjacent modules,
   good (green) for money/time modules, warn (amber) for Renewal Worksheets
   (shared across both grids, since it's the one module in both), neutral
   for infrastructure/admin modules that don't need a color accent. */
.module-card-soft.mc-good::before { background: linear-gradient(180deg, var(--good-bg) 0%, transparent); }
.module-card-soft.mc-warn::before { background: linear-gradient(180deg, var(--warn-bg) 0%, transparent); }
.module-card-soft.mc-bad::before { background: linear-gradient(180deg, var(--bad-bg) 0%, transparent); }
.module-card-soft.mc-neutral::before { background: linear-gradient(180deg, #EEF0F3 0%, transparent); }
.mc-good .tile-icon, .mc-good .tool-tile-data-icon, .faq-cat-card.mc-good .faq-cat-icon { background: var(--good-bg); color: var(--good); }
.mc-warn .tile-icon, .mc-warn .tool-tile-data-icon, .faq-cat-card.mc-warn .faq-cat-icon { background: var(--warn-bg); color: var(--warn); }
.mc-bad .tile-icon, .mc-bad .tool-tile-data-icon, .faq-cat-card.mc-bad .faq-cat-icon { background: var(--bad-bg); color: var(--bad); }
.mc-neutral .tile-icon, .mc-neutral .tool-tile-data-icon, .faq-cat-card.mc-neutral .faq-cat-icon { background: #EEF0F3; color: var(--text-soft); }
.faq-cat-card.mc-good:hover .faq-cat-icon { background: var(--good); color: #fff; }
.faq-cat-card.mc-warn:hover .faq-cat-icon { background: var(--warn); color: #fff; }
.faq-cat-card.mc-neutral:hover .faq-cat-icon { background: var(--text-soft); color: #fff; }
.module-card.module-card-soft { transition: transform .15s, box-shadow .15s; }
.module-card.module-card-soft:hover { transform: translateY(-2px); box-shadow: 0 10px 22px rgba(16,24,38,.09); }

/* Welcome grid's "quieter" adaptation -- no live count to lead with, so
   just a smaller icon and the secondary action (History, My Reports, ...)
   demoted to a text link instead of a second button; the primary action
   (New Request, Log a Trip, ...) stays a real button since it's the main
   thing this card exists to do. */
.tile-icon-quiet { width: 30px; height: 30px; border-radius: 9px; margin-bottom: 10px; }
.tile-icon-quiet svg { width: 16px; height: 16px; }
.tile-secondary-link { margin-left: 12px; font-size: 13px; font-weight: 600; color: var(--blue); text-decoration: none; }
.tile-secondary-link:hover { text-decoration: underline; }

/* Admin Tools' "data-forward" card -- the live count/status is the visual
   anchor (large tabular-mono digits), module name demoted to a small
   label, action becomes a text link instead of a full-width button, so
   cards read as status tiles rather than static nav buttons. */
.tool-tile-data-head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.tool-tile-data-icon { width: 30px; height: 30px; border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.tool-tile-data-icon svg { width: 16px; height: 16px; }
.tool-tile-data-name { font-size: 14px; font-weight: 700; letter-spacing: .01em; color: var(--text); }
.tool-tile-data-stat-row { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.tool-tile-data-stat { font-family: var(--mono); font-size: 28px; font-weight: 700; color: var(--text); line-height: 1.1; font-variant-numeric: tabular-nums; }
.tool-tile-data-stat.is-text { font-family: var(--body); font-size: 15px; font-weight: 600; color: var(--text); line-height: 1.4; }
.tool-tile-data-label { font-size: 13px; color: var(--text-soft); }
.tool-tile-data-flag { display: inline-flex; margin-top: 8px; font-size: 11.5px; font-weight: 700; color: var(--warn); background: var(--warn-bg); padding: 3px 9px; border-radius: 999px; }
.tool-tile-data-divider { height: 1px; background: var(--line); margin: 14px 0 12px; }
.tool-tile-data-action { display: inline-block; font-size: 13.5px; font-weight: 600; color: var(--blue); text-decoration: none; }
.tool-tile-data-action:hover { text-decoration: underline; }
.module-card.module-card-soft.mc-tool { padding: 22px 20px; }

/* ---- Module 17: first-login welcome wizard + walkthrough list (2026-10-01) ----
   Card chrome matches .loader-card / the confirm dialog; the header strip is the
   dark status-board navy. Body text Public Sans, headings/buttons Lexend per the
   typography rules. */
.ob-backdrop { position: fixed; inset: 0; z-index: 1900; display: flex; align-items: center; justify-content: center; padding: 16px; background: rgba(10, 26, 51, 0.45); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); }
.ob-backdrop[hidden] { display: none; }
body.ob-open { overflow: hidden; }
.ob-card { width: 100%; max-width: 620px; max-height: calc(100vh - 32px); display: flex; flex-direction: column; background: var(--surface); border-radius: 8px; overflow: hidden; box-shadow: 0 20px 60px rgba(10, 26, 51, 0.28), 0 2px 8px rgba(10, 26, 51, 0.1); }
.ob-header { display: flex; align-items: center; justify-content: space-between; padding: 14px 24px; background: var(--navy); color: #fff; }
.ob-eyebrow { font-family: var(--display); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; font-weight: 600; opacity: 0.85; }
.ob-dots { display: flex; gap: 8px; }
.ob-dot { width: 8px; height: 8px; border-radius: 50%; background: rgba(255, 255, 255, 0.28); }
.ob-dot.is-done { background: rgba(255, 255, 255, 0.7); }
.ob-dot.is-active { background: #fff; transform: scale(1.25); }
.ob-body { padding: 24px 28px 8px; overflow-y: auto; }
.ob-body h2 { margin: 0 0 10px; font-family: var(--display); font-size: 24px; color: var(--text); }
.ob-body p { margin: 0 0 14px; font-size: 14.5px; line-height: 1.55; color: var(--text-soft); }
.ob-field { margin-bottom: 14px; }
.ob-label { display: block; margin-bottom: 6px; font-family: var(--display); font-size: 12px; font-weight: 600; letter-spacing: 0.04em; color: var(--text); }
.ob-input { width: 100%; padding: 10px 12px; font: inherit; font-size: 14px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); color: var(--text); }
.ob-input:focus { outline: 2px solid var(--blue); outline-offset: 1px; }
.ob-static { padding: 10px 12px; font-size: 14px; border: 1px dashed var(--line); border-radius: 8px; background: var(--bg); color: var(--text); }
.ob-hint { margin-top: 5px; font-size: 12.5px; line-height: 1.5; color: var(--text-soft); }
.ob-error { margin: 4px 0 12px; padding: 10px 12px; border-radius: 8px; font-size: 13px; background: #fdecec; color: #8f2020; border: 1px solid #f3c4c4; }
.ob-error[hidden] { display: none; }
.ob-media-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 8px; }
.ob-media-card { border: 1px solid var(--line); border-radius: 8px; padding: 12px; background: var(--bg); }
.ob-media-name { font-family: var(--display); font-weight: 600; font-size: 14px; color: var(--text); margin-bottom: 4px; }
.ob-media-card .ob-media-line { font-size: 13px; margin-bottom: 10px; }
.ob-media-slot[hidden] { display: none; }
.ob-media-slot img, .ob-media-slot video, .wt-media { width: 100%; height: auto; display: block; border-radius: 6px; border: 1px solid var(--line); background: #fff; }
.ob-others { font-size: 13.5px; }
.ob-footer { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 28px 22px; }
.ob-skip { background: none; border: 0; padding: 6px 2px; font: inherit; font-size: 13px; color: var(--text-soft); cursor: pointer; text-decoration: underline; }
.ob-skip:hover { color: var(--text); }
.ob-nav { display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }
/* .btn sets its own display, which beats the [hidden] attribute (same class-collision as the CrowdStrike/Meraki dropdown bug) */
.ob-card [hidden] { display: none !important; }
.wt-group { margin: 14px 0 6px; font-family: var(--display); font-size: 12px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-soft); }
.wt-group:first-child { margin-top: 0; }
.wt-media-wrap { margin-top: 10px; }
@media (max-width: 560px) {
  .ob-media-grid { grid-template-columns: 1fr; }
  .ob-body { padding: 20px 18px 6px; }
  .ob-footer { padding: 14px 18px 18px; flex-direction: column-reverse; align-items: stretch; }
  .ob-nav { justify-content: stretch; }
  .ob-nav .btn { flex: 1; }
}

/* ---- Invoice & PO History: type badges + total column (2026-10-01) ---- */
.history-type-invoice { background: var(--blue-bg); color: var(--blue); }
.history-type-po { background: var(--warn-bg); color: var(--warn); }
.history-total { font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
.history-total-note { margin-left: 3px; color: var(--text-soft); cursor: help; font-family: var(--body); }

/* ---- Renewal Quantities Review workspace (2026-10-02) ---- */
.rv-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 24px; flex-wrap: wrap; margin-bottom: 14px; }
.rv-back { font-size: 13px; color: var(--text-soft); text-decoration: none; }
.rv-back:hover { color: var(--text); }
.rv-code { font-family: var(--mono); font-size: 14px; font-weight: 600; color: var(--text-soft); margin-left: 6px; }
.rv-sub { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 14px; color: var(--text-soft); }
.rv-status { padding: 3px 10px; border-radius: 999px; font-size: 11.5px; font-weight: 700; font-family: var(--display); background: #EEF0F3; color: var(--text-soft); }
.rv-status-done { background: var(--good-bg); color: var(--good); }
.rv-status-followup { background: var(--warn-bg); color: var(--warn); }
.rv-saved { font-size: 12.5px; }
.rv-head-side { min-width: 260px; }
.rv-pos { font-size: 13px; color: var(--text-soft); margin-bottom: 6px; text-align: right; }
.rv-pos strong { font-family: var(--mono); color: var(--text); }
.rv-prog { height: 8px; border-radius: 999px; background: var(--line); overflow: hidden; }
.rv-prog span { display: block; height: 100%; background: var(--good); border-radius: 999px; transition: width .35s ease; }
.rv-prog-text { font-size: 12px; color: var(--text-soft); margin-top: 5px; text-align: right; }
.rv-banner { padding: 11px 14px; border-radius: 10px; font-size: 13.5px; background: var(--blue-bg); color: var(--text); border: 1px solid var(--line); margin-bottom: 12px; }
.rv-banner-warn { background: var(--warn-bg); border-color: #f0d9a8; }
.rv-grid { display: grid; grid-template-columns: minmax(300px, 4fr) minmax(480px, 7fr); gap: 16px; align-items: start; padding-bottom: 96px; }
.rv-viewer { position: sticky; top: 12px; padding: 14px; }
.rv-viewer-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.rv-viewer-head .btn { margin-left: auto; }
.rv-viewer-head .rv-pager { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--text-soft); margin-left: auto; }
.rv-viewer-head .rv-pager + .btn { margin-left: 0; }
.rv-viewer-body { max-height: calc(100vh - 190px); overflow: auto; border: 1px solid var(--line); border-radius: 8px; background: #fff; }
.rv-viewer-body img { width: 100%; height: auto; display: block; }
.rv-viewer-empty { padding: 28px 16px; font-size: 14px; line-height: 1.55; color: var(--text-soft); border: 1px dashed var(--line); border-radius: 8px; }
.rv-form { padding: 14px; }
.rv-tbl-wrap { overflow-x: auto; }
.rv-tbl { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.rv-tbl th { text-align: left; font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-soft); padding: 8px 8px; border-bottom: 1px solid var(--line); white-space: nowrap; }
.rv-tbl th.num, .rv-tbl td.num { text-align: right; font-variant-numeric: tabular-nums; }
.rv-tbl td { padding: 7px 8px; border-bottom: 1px solid #EEF1F5; vertical-align: middle; }
.rv-sent { font-family: var(--mono); color: var(--text-soft); white-space: nowrap; }
.rv-newamt { font-family: var(--mono); white-space: nowrap; }
.rv-prod { max-width: 260px; }
.rv-flat { font-size: 10.5px; padding: 1px 7px; border-radius: 999px; background: #EEF0F3; color: var(--text-soft); white-space: nowrap; }
.rv-in-h { width: 92px; }
.rv-in input, .rv-reason-row input { width: 100%; box-sizing: border-box; padding: 7px 8px; font: inherit; font-size: 13.5px; border: 1px solid var(--line); border-radius: 7px; background: #fff; }
.rv-in input { text-align: right; font-family: var(--mono); }
.rv-in input:focus, .rv-reason-row input:focus, #rv-notes:focus { outline: 2px solid var(--blue); outline-offset: 1px; }
.rv-row.is-changed td { background: #F3F8FD; }
.rv-row.is-misc td { border-top: 2px solid var(--line); }
.rv-reason-row td { padding-top: 0; }
.rv-reason-row[hidden] { display: none; }
.rv-totals { display: flex; justify-content: flex-end; gap: 28px; flex-wrap: wrap; margin: 14px 4px 8px; font-size: 13.5px; color: var(--text-soft); }
.rv-totals > div { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; }
.rv-totals strong { font-family: var(--mono); font-size: 17px; color: var(--text); }
.rv-up { color: var(--bad) !important; }
.rv-down { color: var(--good) !important; }
.rv-notes { margin-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.rv-chk { display: flex; align-items: flex-start; gap: 8px; font-size: 13.5px; }
.rv-lbl { font-size: 12px; font-weight: 600; color: var(--text); }
#rv-notes { width: 100%; box-sizing: border-box; padding: 9px 10px; font: inherit; font-size: 13.5px; border: 1px solid var(--line); border-radius: 8px; resize: vertical; }
.rv-error { margin-top: 10px; padding: 10px 12px; border-radius: 8px; font-size: 13px; background: #fdecec; color: #8f2020; border: 1px solid #f3c4c4; }
.rv-error[hidden] { display: none; }
.rv-bar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 40; background: rgba(255,255,255,.96); border-top: 1px solid var(--line); backdrop-filter: blur(6px); }
.rv-bar-in { max-width: 1400px; margin: 0 auto; padding: 12px 24px 12px 232px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.rv-bar-msg { margin-right: auto; font-size: 13px; color: var(--text-soft); }
.rv-bar-msg.is-saving::before { content: ''; display: inline-block; width: 12px; height: 12px; margin-right: 8px; vertical-align: -2px; border-radius: 50%; border: 2px solid var(--line); border-top-color: var(--blue); animation: rv-spin .8s linear infinite; }
.rv-bar-msg.is-saved { color: var(--good); font-weight: 600; }
.rv-bar-msg.is-error { color: var(--bad); font-weight: 600; }
.btn.is-disabled { opacity: .45; pointer-events: none; }
@keyframes rv-spin { to { transform: rotate(360deg); } }
@media (max-width: 1100px) { .rv-grid { grid-template-columns: 1fr; } .rv-viewer { position: static; } .rv-bar-in { padding-left: 16px; } }
@media (prefers-reduced-motion: reduce) { .rv-bar-msg.is-saving::before { animation-duration: 2.4s; } }

/* Renewal Worksheets list: quantities review link + progress strip (2026-10-02) */
.rw-rv-link { display: inline-flex; align-items: center; height: 26px; padding: 0 12px; border-radius: 999px; font-size: 12px; font-weight: 700; font-family: var(--display); text-decoration: none; border: 1px solid var(--line); color: var(--blue); background: #fff; white-space: nowrap; }
.rw-rv-link:hover { border-color: var(--blue); }
.rw-rv-done { background: var(--good-bg); color: var(--good); border-color: transparent; }
.rw-rv-followup { background: var(--warn-bg); color: var(--warn); border-color: transparent; }
.rw-rv-strip { display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap; padding: 14px 18px; }
.rw-rv-strip-main { flex: 1; min-width: 280px; }
.rw-rv-strip-title { font-weight: 700; margin-bottom: 8px; }
.rw-rv-strip-text { font-size: 13px; color: var(--text-soft); margin-top: 6px; }
.rw-rv-strip-text strong { font-family: var(--mono); color: var(--text); }
.rw-rv-strip-actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* Provenance note: where an inventory number came from (2026-10-02, migration 066) */
.prov-note { display: block; margin-top: 2px; max-width: 260px; font-family: var(--body); font-size: 11px; font-weight: 500; line-height: 1.35; color: var(--good); white-space: normal; text-align: left; cursor: help; }
.prov-note .prov-meta { display: block; color: var(--text-soft); font-weight: 400; }
.rv-tier-row td { padding: 0 8px 8px; font-size: 13px; color: var(--text-soft); }
.rv-tier-row[hidden] { display: none; }
.rv-tier-msg { margin-right: 8px; }

/* confirm dialog extras: text prompt + third button (2026-10-02) */
.confirm-modal-input { width: 100%; box-sizing: border-box; margin: 4px 0 14px; padding: 10px 12px; font: inherit; font-size: 14px; border: 1px solid var(--line); border-radius: 8px; resize: vertical; }
.confirm-modal-input:focus { outline: 2px solid var(--blue); outline-offset: 1px; }
.confirm-modal-input[hidden], #confirm-modal-alt[hidden], #confirm-modal-cancel[hidden] { display: none; }

/* ---- Review workspace round 2 (2026-10-02): action tray, jump box, zoom, prominent strip ---- */
.rv-bar { left: var(--rail-w); background: var(--navy); border-top: 3px solid var(--blue-lt); box-shadow: 0 -10px 28px rgba(10, 26, 51, .22); backdrop-filter: none; }
.rv-bar-in { max-width: none; margin: 0; padding: 12px 28px; gap: 14px; flex-wrap: nowrap; }
.rv-bar-nav, .rv-bar-actions { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.rv-bar-msg { flex: 1; min-width: 0; margin: 0; color: #C9D6EA; font-size: 13px; white-space: normal; }
.rv-bar-msg.is-saved { color: #7BE0B0; }
.rv-bar-msg.is-error { color: #FFB4AA; }
.rv-bar-msg.is-saving::before { border-color: rgba(255,255,255,.3); border-top-color: #fff; }
.rv-bar-link { color: #BFD3EE; font-size: 13px; text-decoration: underline; white-space: nowrap; margin-right: 6px; }
.rv-bar-link:hover { color: #fff; }
.rv-bar-link[hidden] { display: none; }
.rv-btn { display: inline-flex; align-items: center; justify-content: center; height: 42px; padding: 0 18px; border-radius: 10px; border: 1.5px solid transparent; font-family: var(--display); font-size: 14px; font-weight: 600; text-decoration: none; cursor: pointer; white-space: nowrap; }
.rv-btn:disabled { opacity: .55; cursor: not-allowed; }
.rv-btn-green { background: var(--good-lt); color: #06281A; border-color: var(--good-lt); }
.rv-btn-green:hover:not(:disabled) { background: #52C28C; }
.rv-btn-blue { background: #fff; color: var(--navy); border-color: #fff; }
.rv-btn-blue:hover:not(:disabled) { background: #E8F0FA; }
.rv-btn-ghost { background: transparent; color: #fff; border-color: rgba(255,255,255,.45); }
.rv-btn-ghost:hover:not(:disabled) { background: rgba(255,255,255,.12); }
.rv-btn-outline { background: rgba(255,255,255,.08); color: #fff; border-color: rgba(255,255,255,.35); }
.rv-btn-outline:hover { background: rgba(255,255,255,.18); }
.rv-btn.is-disabled { opacity: .35; pointer-events: none; }
body:has(.rv-bar) #back-to-top { bottom: 96px; }
body:has(.rv-bar) .main { padding-bottom: 92px; }
@media (max-width: 1100px) { .rv-bar { left: 0; } .rv-bar-in { flex-wrap: wrap; padding: 10px 14px; } .rv-bar-msg { order: 3; flex-basis: 100%; } }

.rv-jump { position: relative; margin-bottom: 10px; }
.rv-jump input { width: 100%; box-sizing: border-box; height: 38px; padding: 0 12px; font: inherit; font-size: 13.5px; border: 1px solid var(--line); border-radius: 9px; background: #fff; }
.rv-jump input:focus { outline: 2px solid var(--blue); outline-offset: 1px; }
.rv-jump-results { position: absolute; z-index: 60; top: 42px; left: 0; right: 0; max-height: 340px; overflow-y: auto; background: #fff; border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 14px 40px rgba(10,26,51,.18); }
.rv-jump-results[hidden] { display: none; }
.rv-jump-item { display: grid; grid-template-columns: 1fr auto auto; gap: 10px; align-items: center; padding: 9px 12px; text-decoration: none; color: var(--text); font-size: 13.5px; border-bottom: 1px solid #F0F3F7; }
.rv-jump-item:hover, .rv-jump-item:focus { background: var(--blue-bg); }
.rv-jump-code { font-family: var(--mono); font-size: 11.5px; color: var(--text-soft); }
.rv-jump-empty { padding: 12px; font-size: 13px; color: var(--text-soft); }

.rv-viewer-body { position: relative; }
.rv-viewer-body img { cursor: zoom-in; }
.rv-zoom-btn { position: absolute; top: 10px; right: 10px; z-index: 2; width: 38px; height: 38px; border-radius: 10px; border: 0; background: var(--navy); color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer; opacity: .88; box-shadow: 0 4px 12px rgba(10,26,51,.3); }
.rv-zoom-btn:hover { opacity: 1; }
.rv-zoom-btn svg { width: 20px; height: 20px; }
.rv-zoom { position: fixed; inset: 0; z-index: 2100; display: flex; flex-direction: column; background: rgba(10, 26, 51, .92); }
.rv-zoom[hidden] { display: none; }
.rv-zoom-bar { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; padding: 12px 20px; color: #fff; }
.rv-zoom-ctl { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.rv-zoom-ctl .rv-btn { height: 38px; padding: 0 14px; }
.rv-zoom-body { flex: 1; overflow: auto; padding: 0 20px 24px; text-align: center; }
.rv-zoom-body img { background: #fff; border-radius: 6px; max-width: none; box-shadow: 0 10px 40px rgba(0,0,0,.4); }

/* Quantities review hero on the Renewal Worksheets list */
.rw-rv-hero { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; margin-top: 16px; padding: 22px 26px; border-radius: 16px; color: #fff; background: linear-gradient(135deg, #2C6FAC 0%, #1F5A93 100%); box-shadow: 0 14px 34px rgba(31, 90, 147, .28); }
.rw-rv-hero.is-done { background: linear-gradient(135deg, #1D8A57 0%, #15724A 100%); box-shadow: 0 14px 34px rgba(21, 114, 74, .26); }
.rw-rv-hero.is-waiting { background: #fff; color: var(--text); border: 1px dashed #B7C2D0; box-shadow: none; }
.rw-rv-hero-icon { width: 54px; height: 54px; border-radius: 16px; background: rgba(255,255,255,.18); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.rw-rv-hero.is-waiting .rw-rv-hero-icon { background: var(--blue-bg); color: var(--blue); }
.rw-rv-hero-icon svg { width: 28px; height: 28px; }
.rw-rv-hero-main { flex: 1; min-width: 300px; }
.rw-rv-hero-eyebrow { font-size: 11px; font-weight: 700; letter-spacing: .14em; opacity: .85; }
.rw-rv-hero h2 { margin: 4px 0 6px; font-size: 22px; line-height: 1.25; color: inherit; }
.rw-rv-hero p { margin: 0 0 14px; font-size: 14.5px; line-height: 1.55; opacity: .95; max-width: 760px; }
.rw-rv-hero .rv-prog { height: 12px; background: rgba(255,255,255,.28); }
.rw-rv-hero .rv-prog span { background: #fff; }
.rw-rv-hero.is-waiting .rv-prog { background: var(--line); }
.rw-rv-hero.is-waiting .rv-prog span { background: var(--good); }
.rw-rv-hero-stats { margin-top: 8px; font-size: 13.5px; opacity: .95; }
.rw-rv-hero-stats strong { font-family: var(--mono); font-size: 15px; }
.rw-rv-hero-actions { display: flex; flex-direction: column; gap: 10px; align-items: stretch; min-width: 220px; }
.rw-rv-hero-actions form { margin: 0; display: block; }
.rw-rv-hero-actions .btn { width: 100%; justify-content: center; }
.btn-hero { background: #fff; color: #17406B; border: 0; height: 46px; font-size: 15px; font-weight: 700; }
.btn-hero:hover { background: #EAF1F8; }
.rw-rv-hero.is-done .btn-hero { color: #0F5A39; }
.btn-hero-ghost { background: rgba(255,255,255,.14); color: #fff; border: 1px solid rgba(255,255,255,.4); }
.btn-hero-ghost:hover { background: rgba(255,255,255,.24); }
.rw-rv-hero.is-waiting .btn-hero { background: var(--blue); color: #fff; }
.rw-rv-hero.is-waiting .btn-hero-ghost { background: var(--blue-bg); color: var(--blue); border-color: transparent; }

/* ---- Review tray polish + wider three-button dialog (2026-10-02, round 3) ---- */
.confirm-modal-card.has-alt { max-width: 640px; padding: 30px 32px 26px; }
.confirm-modal-card.has-alt p { max-width: 520px; margin-left: auto; margin-right: auto; }
.confirm-modal-card.has-alt .confirm-modal-actions { gap: 12px; flex-wrap: wrap; }
.confirm-modal-card.has-alt .confirm-modal-actions .btn { flex: 1 1 150px; white-space: nowrap; min-height: 44px; }
.rv-bar-in { padding: 14px 28px; gap: 16px; }
.rv-bar-msg { font-size: 13.5px; line-height: 1.4; }
.rv-seg { display: inline-grid; grid-template-columns: 1fr 1fr; flex-shrink: 0; }
.rv-seg-btn { display: inline-flex; align-items: center; justify-content: center; height: 44px; padding: 0 18px; border: 1.5px solid rgba(255,255,255,.35); background: rgba(255,255,255,.08); color: #fff; font-family: var(--display); font-size: 14px; font-weight: 600; text-decoration: none; white-space: nowrap; cursor: pointer; }
.rv-seg-btn:first-child { border-radius: 10px 0 0 10px; }
.rv-seg-btn:last-child { border-radius: 0 10px 10px 0; margin-left: -1.5px; }
.rv-seg-btn:hover { background: rgba(255,255,255,.2); position: relative; }
.rv-seg-btn.is-disabled { opacity: .35; pointer-events: none; }
.rv-bar-sep { align-self: stretch; width: 1px; min-height: 28px; margin: 4px 2px; background: rgba(255,255,255,.2); flex-shrink: 0; }
.rv-bar-actions { align-items: center; gap: 12px; }
.rv-btn { height: 44px; }
.rv-btn-doc { gap: 8px; background: rgba(255,255,255,.1); color: #fff; border-color: rgba(255,255,255,.4); }
.rv-btn-doc svg { width: 18px; height: 18px; }
.rv-btn-doc:hover:not(.is-disabled) { background: rgba(255,255,255,.22); }
.rv-btn-doc.is-disabled { opacity: .4; pointer-events: none; }

/* ---- Quantities review hero, direction B "Bold tiles" (confirmed 2026-10-02) ---- */
.rw-rv-hero { display: block; padding: 26px 30px; border-radius: 18px; background: linear-gradient(135deg, #17406B 0%, #2C6FAC 100%); box-shadow: 0 16px 36px rgba(31, 90, 147, .30); }
.rw-rv-hero.is-done { background: linear-gradient(135deg, #0F5A39 0%, #1D8A57 100%); box-shadow: 0 16px 36px rgba(21, 114, 74, .28); }
.rw-rv-hero.is-waiting { background: #fff; color: var(--text); border: 1px dashed #B7C2D0; box-shadow: none; }
.rw-rv-hero-top { display: flex; justify-content: space-between; gap: 30px; align-items: flex-start; flex-wrap: wrap; }
.rw-rv-hero-copy { flex: 1 1 420px; max-width: 660px; }
.rw-rv-hero-eyebrow { font-size: 11.5px; font-weight: 700; letter-spacing: .14em; opacity: .85; }
.rw-rv-hero h2 { margin: 8px 0 8px; font-size: 26px; line-height: 1.2; color: inherit; }
.rw-rv-hero p { margin: 0; font-size: 14.5px; line-height: 1.55; opacity: .95; max-width: 640px; }
.rw-rv-tiles { display: flex; gap: 12px; flex: 0 1 500px; min-width: 300px; }
.rw-rv-tile { flex: 1; min-width: 100px; padding: 16px 18px; border-radius: 14px; background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.22); }
.rw-rv-tile-num { font-family: var(--mono); font-size: 34px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.rw-rv-tile-label { font-size: 12.5px; margin-top: 7px; opacity: .92; }
.rw-rv-tile.is-done .rw-rv-tile-num { color: #7BE0B0; }
.rw-rv-tile.is-followup .rw-rv-tile-num { color: #F3C86B; }
.rw-rv-hero.is-done .rw-rv-tile.is-done .rw-rv-tile-num { color: #fff; }
.rw-rv-hero.is-waiting .rw-rv-tile { background: var(--bg); border-color: var(--line); }
.rw-rv-hero.is-waiting .rw-rv-tile.is-done .rw-rv-tile-num { color: var(--good); }
.rw-rv-hero.is-waiting .rw-rv-tile.is-followup .rw-rv-tile-num { color: var(--warn); }
.rw-rv-hero-bottom { display: flex; align-items: center; gap: 22px; margin-top: 22px; flex-wrap: wrap; }
.rw-rv-hero-bar { flex: 1 1 320px; min-width: 240px; }
.rw-rv-seg { display: flex; height: 12px; border-radius: 999px; overflow: hidden; background: rgba(255,255,255,.26); }
.rw-rv-seg .seg-done { background: #7BE0B0; transition: width .35s ease; }
.rw-rv-seg .seg-followup { background: #F3C86B; transition: width .35s ease; }
.rw-rv-hero.is-done .rw-rv-seg .seg-done { background: #fff; }
.rw-rv-hero.is-waiting .rw-rv-seg { background: var(--line); }
.rw-rv-hero.is-waiting .rw-rv-seg .seg-done { background: var(--good); }
.rw-rv-hero-caption { font-size: 12.5px; opacity: .92; margin-top: 7px; }
.rw-rv-hero-cta { display: flex; align-items: center; gap: 10px; position: relative; }
.rw-rv-hero-cta .btn-hero { width: auto; height: 48px; padding: 0 24px; border-radius: 12px; font-family: var(--display); font-size: 15px; font-weight: 600; display: inline-flex; align-items: center; text-decoration: none; }
.rw-rv-more { position: relative; }
.rw-rv-more > summary { list-style: none; height: 48px; padding: 0 20px; border-radius: 12px; display: inline-flex; align-items: center; border: 1.5px solid rgba(255,255,255,.5); background: transparent; color: #fff; font-family: var(--display); font-size: 14px; font-weight: 600; cursor: pointer; }
.rw-rv-more > summary::-webkit-details-marker { display: none; }
.rw-rv-more > summary::after { content: ''; margin-left: 8px; width: 7px; height: 7px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg) translateY(-2px); }
.rw-rv-hero.is-waiting .rw-rv-more > summary { color: var(--blue); border-color: var(--line); background: var(--blue-bg); }
.rw-rv-more-menu { position: absolute; z-index: 30; right: 0; top: 54px; min-width: 260px; padding: 6px; background: #fff; border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 16px 40px rgba(10,26,51,.2); }
.rw-rv-more-menu form { margin: 0; }
.rw-rv-more-menu button { display: block; width: 100%; text-align: left; padding: 11px 14px; border: 0; background: none; border-radius: 8px; font: inherit; font-size: 13.5px; color: var(--text); cursor: pointer; }
.rw-rv-more-menu button:hover { background: var(--blue-bg); }
.rw-rv-hero.is-waiting .btn-hero { background: var(--blue); color: #fff; }
@media (max-width: 760px) { .rw-rv-tiles { flex-basis: 100%; } .rw-rv-hero-cta { width: 100%; } }

/* FY selector set apart from the action buttons (2026-10-04): it is the first decision on these
   pages, so it gets its own labeled spot at the top right of the header and an amber highlight
   that no other control uses. Actions drop to their own row. */
.status-board-header.has-fy .status-board-actions { flex: 1 1 100%; }
.status-board-fy { display: flex; flex-direction: column; align-items: flex-end; gap: 5px; }
.status-board-fy-label { font-family: var(--display); font-size: 11px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: #F3C86B; }
.status-board-fy .status-board-fy-tabs { background: rgba(243, 200, 107, .10); border: 1.5px solid rgba(243, 200, 107, .55); padding: 3px; }
.status-board-fy .status-board-fy-tabs a { color: #e9d9ae; padding: 7px 14px; }
.status-board-fy .status-board-fy-tabs a:hover { color: #fff; }
.status-board-fy .status-board-fy-tabs a.current { background: #F3C86B; color: var(--navy); box-shadow: 0 2px 10px rgba(243, 200, 107, .35); }
@media (max-width: 720px) { .status-board-fy { align-items: flex-start; } }

/* ==== FY switch (light pages) + breadcrumb design pass (2026-10-04) ==== */
/* FY switch: same amber language as .status-board-fy on navy headers (_fy_switch.html). */
.fy-switch { display: inline-flex; flex-direction: column; align-items: flex-start; gap: 5px; margin: 0 0 16px; }
.fy-switch-label { font-family: var(--display); font-size: 11px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: #9A6A00; }
.fy-switch-tabs { display: flex; gap: 2px; padding: 3px; border-radius: 8px; background: #FFF6DC; border: 1.5px solid #E3B849; }
.fy-switch-tabs a { font-family: var(--mono); font-size: 12.5px; font-weight: 600; color: #6B4E00; text-decoration: none; padding: 7px 14px; border-radius: 6px; }
.fy-switch-tabs a:hover { background: rgba(227, 184, 73, .25); }
.fy-switch-tabs a:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.fy-switch-tabs a.current { background: #F3C86B; color: var(--navy); box-shadow: 0 2px 8px rgba(227, 184, 73, .45); }
.page-actions .fy-switch { margin: 0; }

/* Breadcrumbs: read as navigation, not page chrome. */
.breadcrumbs { background: #fff; border: 1px solid #B9C6D6; box-shadow: 0 1px 3px rgba(10, 26, 51, .10); padding: 5px 16px 5px 6px; gap: 8px; }
.breadcrumbs .breadcrumb-home { align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 50%; background: var(--blue-bg, #E8F0F9); color: var(--blue); }
.breadcrumbs .breadcrumb-home:hover { background: var(--blue); color: #fff; }
.breadcrumbs .breadcrumb-home svg { width: 16px; height: 16px; }
.breadcrumbs .breadcrumb-sep { width: 14px; height: 14px; color: #7C8DA3; }
.breadcrumbs .breadcrumb-link { color: var(--blue); font-weight: 600; }
.breadcrumbs .breadcrumb-link:hover { color: #1D5287; text-decoration: underline; text-underline-offset: 3px; }
.breadcrumbs .breadcrumb-home:focus-visible, .breadcrumbs .breadcrumb-link:focus-visible, .breadcrumb-mobile-back:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; border-radius: 6px; }
.breadcrumbs .breadcrumb-current { color: var(--navy); font-weight: 700; }
@media (max-width: 720px) {
  .breadcrumb-mobile-back { min-height: 44px; color: var(--blue); font-weight: 600; }
}

/* ---- Review workspace: Library list panel + Next not started (2026-10-04) ---- */
.rv-head-tools { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.rv-head-tools .rv-jump { flex: 1 1 auto; margin-bottom: 0; min-width: 0; }
.rv-list-btn.rv-btn { flex-shrink: 0; height: 40px; padding: 0 14px; display: inline-flex; align-items: center; gap: 8px; background: #fff; color: var(--navy); border: 1.5px solid var(--line); border-radius: 10px; font-family: var(--display); font-size: 13.5px; font-weight: 600; cursor: pointer; }
.rv-list-btn.rv-btn:hover { border-color: var(--blue); color: var(--blue); }
.rv-list-btn svg { width: 17px; height: 17px; }
.rv-seg { grid-template-columns: repeat(3, auto); }
.rv-seg-btn:not(:first-child):not(:last-child) { border-radius: 0; margin-left: -1.5px; }
.rv-seg-pending { background: rgba(243, 200, 107, .16); border-color: rgba(243, 200, 107, .6); color: #F3C86B; }
.rv-seg-pending:hover { background: rgba(243, 200, 107, .28); }

.rv-list-backdrop { position: fixed; inset: 0; z-index: 1190; background: rgba(10, 26, 51, .45); }
.rv-list { position: fixed; z-index: 1200; top: 0; right: 0; bottom: 0; width: 420px; max-width: 100vw; display: flex; flex-direction: column; background: #fff; box-shadow: -18px 0 50px rgba(10, 26, 51, .28); font-family: var(--body); }
.rv-list[hidden], .rv-list-backdrop[hidden] { display: none; }
.rv-list-head { display: flex; align-items: center; justify-content: space-between; padding: 18px 20px 10px; }
.rv-list-head h2 { margin: 0; font-family: var(--display); font-size: 19px; font-weight: 600; color: var(--navy); }
.rv-list-close { width: 40px; height: 40px; border: 0; border-radius: 10px; background: var(--blue-bg); color: var(--navy); font-size: 24px; line-height: 1; cursor: pointer; }
.rv-list-tools { padding: 0 20px 12px; border-bottom: 1px solid var(--line); }
.rv-list-tools input[type="search"] { width: 100%; box-sizing: border-box; height: 42px; padding: 0 12px; border: 1.5px solid var(--line); border-radius: 10px; font: inherit; font-size: 14px; }
.rv-list-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.rv-chip { height: 32px; padding: 0 12px; border: 1.5px solid var(--line); border-radius: 999px; background: #fff; color: var(--text-soft); font-family: var(--display); font-size: 12.5px; font-weight: 600; cursor: pointer; }
.rv-chip span { font-family: var(--mono); font-weight: 600; margin-left: 4px; }
.rv-chip.is-on { background: var(--navy); border-color: var(--navy); color: #fff; }
.rv-list-body { flex: 1 1 auto; overflow-y: auto; padding: 6px 10px 20px; }
.rv-list-row { display: grid; grid-template-columns: 12px minmax(0, 1fr) auto auto; align-items: center; gap: 10px; padding: 10px 10px; border-radius: 10px; color: var(--text); text-decoration: none; font-size: 14px; }
.rv-list-row:hover { background: var(--blue-bg); }
.rv-list-row.is-current { background: #E8F0FA; box-shadow: inset 0 0 0 1.5px var(--blue); font-weight: 600; }
.rv-list-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rv-list-code { font-size: 12px; color: var(--text-soft); }
.rv-dot { width: 10px; height: 10px; border-radius: 50%; background: #B7C2D0; }
.rv-dot-done { background: var(--good); }
.rv-dot-followup { background: #E0A100; }
.rv-list-empty { padding: 24px 12px; color: var(--text-soft); font-size: 14px; }
body.rv-list-open { overflow: hidden; }
@media (max-width: 720px) {
  .rv-head-tools { flex-wrap: wrap; }
  .rv-list { width: 100vw; }
  .rv-seg { grid-template-columns: 1fr; }
  .rv-seg-btn:not(:first-child):not(:last-child), .rv-seg-btn:first-child, .rv-seg-btn:last-child { border-radius: 10px; margin-left: 0; margin-top: -1.5px; }
}


/* ---- Welcome Tour (Module 17 addendum, 2026-10-04): Getting started card + spotlight ---- */
.tour-card { background: #fff; border: 1px solid var(--line); border-radius: 16px; padding: 20px 20px 12px; box-shadow: 0 8px 28px rgba(10, 26, 51, .08); }
.tour-card-head { display: flex; align-items: center; gap: 14px; margin-bottom: 12px; }
.tour-ring { position: relative; flex-shrink: 0; }
.tour-ring-num { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-family: var(--mono); font-size: 13px; font-weight: 600; color: var(--navy); }
.tour-card-title { font-family: var(--display); font-size: 18px; font-weight: 600; color: var(--navy); }
.tour-card-sub { font-family: var(--body); font-size: 13.5px; color: var(--text-soft); margin-top: 3px; }
.tour-note { font-family: var(--body); font-size: 14px; line-height: 1.55; color: var(--text); background: #FFF8E6; border-radius: 10px; padding: 10px 12px; margin-bottom: 10px; }
.tour-item { display: flex; gap: 12px; padding: 12px 0; border-top: 1px solid #EDF1F6; }
.tour-check { width: 26px; height: 26px; border-radius: 50%; border: 2px solid #B7C2D0; flex-shrink: 0; box-sizing: border-box; display: flex; align-items: center; justify-content: center; }
.tour-check.is-active { border-color: var(--blue); }
.tour-check.is-done { background: #2C9A6A; border-color: #2C9A6A; }
.tour-item-body { flex: 1 1 auto; min-width: 0; }
.tour-item-title { all: unset; cursor: pointer; font-family: var(--body); font-size: 15px; font-weight: 700; color: var(--navy); }
.tour-item-title.is-done { color: var(--text-soft); }
.tour-item-title:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; border-radius: 4px; }
.tour-item-desc { font-family: var(--body); font-size: 13.5px; line-height: 1.5; color: var(--text-soft); margin-top: 4px; }
.tour-item-btns { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.tour-btn { font-family: var(--display); height: 40px; padding: 0 18px; border-radius: 10px; border: 0; font-size: 14px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.tour-btn:disabled { opacity: .6; cursor: default; }
.tour-btn-primary { background: var(--blue); color: #fff; }
.tour-btn-soft { background: #EEF1F6; color: var(--blue); }
.tour-btn-dark { background: var(--navy); color: #fff; }
.tour-btn:focus-visible, .tour-link:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.tour-link { all: unset; cursor: pointer; font-family: var(--body); font-size: 13px; color: var(--text-soft); text-decoration: underline; }
.tour-link:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; border-radius: 4px; }
.tour-item-body .tour-link { display: inline-block; margin-top: 8px; }
.tour-contact { font-family: var(--body); font-size: 13.5px; color: var(--text); border-top: 1px solid #EDF1F6; padding: 12px 0 4px; }
.tour-contact-label { color: var(--text-soft); }
.tour-card-foot { display: flex; justify-content: space-between; border-top: 1px solid #EDF1F6; padding: 12px 0 6px; margin-top: 8px; }
.tour-media-wrap { margin-top: 10px; }
.tour-media { display: block; width: 100%; max-height: 220px; object-fit: contain; border-radius: 10px; background: #E9EEF5; }

.tour-overlay { position: fixed; inset: 0; z-index: 9000; }
.tour-scrim { position: absolute; inset: 0; background: transparent; }
.tour-overlay.is-dim .tour-scrim { background: rgba(10, 26, 51, .66); }
.tour-ring-hl { position: fixed; border-radius: 11px; box-shadow: 0 0 0 3px #F5B83D, 0 0 0 4000px rgba(10, 26, 51, .66); pointer-events: none; transition: left .2s ease, top .2s ease, width .2s ease, height .2s ease; }
.tour-tip { position: fixed; z-index: 9001; background: #fff; border-radius: 16px; padding: 22px 24px 20px; box-sizing: border-box; box-shadow: 0 18px 50px rgba(0, 0, 0, .35); max-height: calc(100vh - 24px); overflow: auto; }
.tour-tip-arrow { position: absolute; width: 16px; height: 16px; background: #fff; transform: rotate(45deg); }
.tour-tip[data-mode="right"] .tour-tip-arrow { left: -8px; }
.tour-tip[data-mode="left"] .tour-tip-arrow { right: -8px; }
.tour-tip[data-mode="below"] .tour-tip-arrow { top: -8px; }
.tour-tip[data-mode="above"] .tour-tip-arrow { bottom: -8px; }
.tour-tip-step { font-family: var(--display); font-size: 11px; font-weight: 600; letter-spacing: .14em; color: #B7791F; }
.tour-tip-title { font-family: var(--display); font-size: 22px; font-weight: 600; color: var(--navy); margin: 6px 0 8px; }
.tour-tip-text { font-family: var(--body); font-size: 14.5px; line-height: 1.55; color: #4B5563; margin-bottom: 14px; }
.tour-tip-actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.tour-tip-right { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.tour-pill { position: fixed; left: 16px; bottom: 20px; z-index: 9001; display: flex; align-items: center; gap: 10px; background: #fff; border-radius: 999px; padding: 8px 16px 8px 8px; box-shadow: 0 8px 24px rgba(0, 0, 0, .28); font-family: var(--display); font-size: 13px; font-weight: 600; color: var(--navy); }
.tour-pill .tour-ring-num { font-size: 10px; }
@media (max-width: 720px) {
  .tour-tip { left: 12px !important; right: 12px; width: auto !important; border-radius: 18px; padding: 20px; }
  .tour-pill { left: 12px; bottom: auto; top: 12px; }
  .tour-btn { height: 44px; }
}

.tour-celebrate { position: fixed; inset: 0; z-index: 9100; background: rgba(10, 26, 51, .66); display: flex; align-items: center; justify-content: center; padding: 16px; }
.tour-celebrate-card { position: relative; overflow: hidden; background: #fff; border-radius: 18px; padding: 36px 32px 28px; max-width: 420px; text-align: center; box-shadow: 0 18px 50px rgba(0, 0, 0, .35); }
.tour-celebrate-card h2 { font-family: var(--display); font-size: 24px; color: var(--navy); margin: 0 0 10px; }
.tour-celebrate-card p { font-family: var(--body); font-size: 14.5px; line-height: 1.55; color: #4B5563; margin: 0 0 20px; }
.tour-confetti span { position: absolute; top: -12px; width: 8px; height: 14px; border-radius: 2px; opacity: 0; animation: tour-fall 1.8s ease-in forwards; }
.tour-confetti .c0 { background: #2C9A6A; } .tour-confetti .c1 { background: #F5B83D; } .tour-confetti .c2 { background: #2C6FAC; } .tour-confetti .c3 { background: #E07A5F; }
@keyframes tour-fall { 0% { transform: translateY(0) rotate(0); opacity: 1; } 100% { transform: translateY(260px) rotate(300deg); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .tour-confetti span { animation: none; display: none; } .tour-ring-hl { transition: none; } }

/* ---- Users, Edit User, Create User (direction A, 2026-10-04) ---- */
.usr-toolbar { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin: 16px 0 12px; }
.usr-search { flex: 1 1 260px; max-width: 360px; margin: 0; }
.usr-search input { width: 100%; height: 42px; margin: 0; border-radius: 12px; }
.usr-chips { margin: 0; }
.usr-chips .filter-chip.is-on { background: var(--blue-bg); border-color: var(--blue); color: var(--blue); }
.usr-card { padding: 0; overflow: hidden; }
.usr-tbl th { font-family: var(--display); font-size: 11.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-soft); }
.usr-person { display: flex; align-items: center; gap: 12px; }
.usr-avatar { width: 36px; height: 36px; border-radius: 50%; background: var(--blue); color: #fff; font-family: var(--display); font-weight: 600; font-size: 13px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.usr-avatar-lg { width: 56px; height: 56px; font-size: 20px; }
.usr-name { font-weight: 600; color: var(--navy); text-decoration: none; }
.usr-name:hover { text-decoration: underline; }
.usr-sub { font-size: 12.5px; color: var(--text-soft); }
.usr-flag { font-size: 11.5px; font-weight: 600; color: var(--warn); margin-top: 2px; }
.usr-pill { display: inline-block; font-family: var(--display); font-weight: 600; font-size: 11.5px; padding: 4px 10px; border-radius: 999px; background: #EEF1F6; color: var(--text-soft); white-space: nowrap; }
.usr-pill-admin { background: var(--blue-bg); color: var(--blue); }
.usr-pill-supervisor { background: #EAE6F8; color: #5B3FA8; }
.usr-pill-active { background: var(--good-bg); color: var(--good); }
.usr-pill-off { background: #EEF0F3; color: var(--text-soft); }
.usr-row-off { opacity: .6; }
.usr-toggle-form { margin: 0; }
.usr-switch { appearance: none; border: 0; padding: 0; width: 40px; height: 22px; border-radius: 999px; background: #CBD5E1; position: relative; cursor: pointer; transition: background .2s; }
.usr-switch.is-on { background: var(--good); }
.usr-switch:disabled { cursor: not-allowed; opacity: .55; }
.usr-switch-thumb { position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: #fff; transition: transform .2s; }
.usr-switch.is-on .usr-switch-thumb { transform: translateX(18px); }
.usr-switch:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.usr-head { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-bottom: 18px; }
.usr-head-main { flex: 1 1 260px; min-width: 0; }
.usr-head-name { font-family: var(--display); font-weight: 600; font-size: 24px; color: var(--navy); margin: 0; }
.usr-head-sub { font-size: 13.5px; color: var(--text-soft); margin-top: 2px; }
.usr-grid { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); gap: 16px; align-items: start; }
.usr-stack { display: flex; flex-direction: column; gap: 16px; }
.usr-narrow { max-width: 720px; }
.usr-card-sec { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 20px 22px; }
.usr-sec-title { font-family: var(--display); font-weight: 600; font-size: 16px; color: var(--navy); margin: 0; }
.usr-sec-sub { font-size: 13px; color: var(--text-soft); margin: 3px 0 14px; }
.usr-mods { display: grid; grid-template-columns: 1fr 1fr; gap: 0 28px; }
.usr-mod { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 0; border-bottom: 1px solid #F1F4F8; font-size: 14px; color: var(--text); }
.usr-mod .toggle-switch { gap: 0; }
.usr-always { font-size: 12px; color: var(--text-soft); }
.usr-acct { display: flex; flex-wrap: wrap; gap: 10px; }
.usr-acct form { margin: 0; }
.usr-danger { color: var(--bad); }
@media (max-width: 900px) { .usr-grid { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 720px) {
  .usr-mods { grid-template-columns: 1fr; }
  .usr-head .btn { flex: 1 1 auto; }
}

/* ---- Users pages follow-up (2026-10-04): profile photos, edit layout, security card ---- */
.usr-avatar { position: relative; overflow: hidden; }
.usr-avatar-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
.usr-avatar-ini { position: relative; z-index: 0; }
.usr-avatar-img + .usr-avatar-ini { visibility: hidden; }
form.usr-grid { margin: 0; }
.usr-activity { display: flex; flex-wrap: wrap; gap: 8px 28px; margin: 0 0 14px; padding: 10px 14px; border-radius: 10px; background: var(--bg); border: 1px solid var(--line); }
.usr-activity div { display: flex; flex-direction: column; gap: 2px; font-size: 12.5px; color: var(--text-soft); }
.usr-activity strong { font-size: 13.5px; color: var(--navy); font-weight: 600; }
.usr-temp-pw { display: none; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }
.usr-temp-pw.is-open { display: block; }
.usr-temp-pw .btn { margin-top: 12px; }
.usr-check { display: flex; align-items: center; gap: 10px; margin-top: 10px; font-weight: 500; cursor: pointer; }
.usr-check input { width: auto; margin: 0; }

/* ---- Motion pass 2 (2026-10-04): page entrance, button feel, rows, flashes, modals, page transitions ----
   Everything here is decoration: it is switched off entirely under prefers-reduced-motion, uses only
   opacity/transform (no layout), and animations end at the natural state (fill backwards) so nothing
   is left with a transform that would trap position:fixed or sticky descendants. */
@keyframes tln-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes tln-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes tln-pop { from { opacity: 0; transform: scale(.96) translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes tln-slide-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: no-preference) {
  .main > .breadcrumbs { animation: tln-fade .22s ease backwards; }
  .main > .status-board, .main > .page-header, .main > .rw-rv-hero { animation: tln-rise .32s cubic-bezier(.2, .7, .2, 1) backwards; }
  .main > .stat-card, .main .row > .stat-card, .main .module-card, .main .usr-card, .main .rv-card { animation: tln-rise .34s cubic-bezier(.2, .7, .2, 1) backwards; }
  .main .row > .stat-card:nth-child(2), .main .module-card:nth-child(2) { animation-delay: .04s; }
  .main .row > .stat-card:nth-child(3), .main .module-card:nth-child(3) { animation-delay: .08s; }
  .main .row > .stat-card:nth-child(4), .main .module-card:nth-child(4) { animation-delay: .12s; }
  .main .row > .stat-card:nth-child(n+5), .main .module-card:nth-child(n+5) { animation-delay: .16s; }
  .main tbody tr { animation: tln-fade .26s ease backwards; }
  .main tbody tr:nth-child(2) { animation-delay: .02s; } .main tbody tr:nth-child(3) { animation-delay: .04s; }
  .main tbody tr:nth-child(4) { animation-delay: .06s; } .main tbody tr:nth-child(5) { animation-delay: .08s; }
  .main tbody tr:nth-child(6) { animation-delay: .10s; } .main tbody tr:nth-child(n+7) { animation-delay: .12s; }
  .alert-glow, .alert-bar, .msg { animation: tln-slide-in .28s ease backwards; }
  .confirm-modal-card, .faq-modal, .tour-card { animation: tln-pop .22s cubic-bezier(.2, .7, .2, 1) backwards; }
  .confirm-modal-backdrop { animation: tln-fade .18s ease backwards; }

  .btn { transition: background .15s, color .15s, border-color .15s, box-shadow .18s, transform .12s ease; }
  .btn:not(:disabled):hover { transform: translateY(-1px); box-shadow: 0 6px 14px -6px rgba(10, 26, 51, .35); }
  .btn:not(:disabled):active { transform: translateY(0) scale(.98); box-shadow: none; transition-duration: .06s; }
  .btn:focus-visible, .input:focus-visible, .usr-switch:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; transition: outline-offset .12s ease; }
  .btn.is-busy, .btn[aria-busy="true"] { position: relative; pointer-events: none; opacity: .85; }
  .btn.is-busy::after, .btn[aria-busy="true"]::after { content: ""; width: 13px; height: 13px; margin-left: 8px; border-radius: 50%; border: 2px solid currentColor; border-right-color: transparent; display: inline-block; vertical-align: -2px; animation: rv-spin .7s linear infinite; }
  .status-board-icon-btn, .topbar-icon-btn, .rail-link, .rail-sub-link { transition: background .15s, color .15s, transform .12s ease; }
  .status-board-icon-btn:hover, .topbar-icon-btn:hover { transform: translateY(-1px); }
  .status-board-icon-btn:active, .topbar-icon-btn:active { transform: scale(.96); }
  .status-board-fy-tabs a, .fy-switch a { transition: background .18s, color .18s, box-shadow .18s; }
  .toggle-thumb, .usr-switch-thumb { transition: transform .18s cubic-bezier(.3, .7, .3, 1), left .18s cubic-bezier(.3, .7, .3, 1); }
  .toggle-track, .usr-switch { transition: background .18s ease; }
  .rv-prog span, .rw-rv-seg span, .loader-bar-fill { transition: width .5s cubic-bezier(.2, .7, .2, 1); }
  .stat-tile, .module-card, .stat-card { transition: transform .15s, box-shadow .15s, border-color .15s; }
  .tbl-cards tr, .main tbody tr { transition: background .12s ease; }

}
@view-transition { navigation: auto; }
.rail { view-transition-name: tln-rail; }
.content-topbar { view-transition-name: tln-topbar; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: .16s; animation-timing-function: ease; }
@media (prefers-reduced-motion: reduce) { ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; } }

/* ---- Top bar: icon-only, no circles, hover tooltips (design direction (d), confirmed 2026-10-05) ---- */
.topbar-actions { gap: 4px; }
.topbar-actions .topbar-icon-btn { width: 44px; height: 44px; border: 0; border-radius: 12px; background: transparent; color: var(--text); position: relative; box-shadow: none; display: inline-flex; align-items: center; justify-content: center; }
.topbar-actions .topbar-icon-btn svg { width: 22px; height: 22px; stroke-width: 1.75; }
.topbar-actions .topbar-icon-btn:hover, .topbar-actions .topbar-icon-btn[aria-expanded="true"] { background: rgba(44, 111, 172, .09); color: var(--navy); }
.topbar-actions .topbar-icon-badge { top: 4px; right: 3px; box-shadow: 0 0 0 2px var(--surface); }
.topbar-avatar-btn { position: relative; margin-left: 6px; }
[data-tip] { position: relative; }
[data-tip]::after { content: attr(data-tip); position: absolute; top: calc(100% + 8px); left: 50%; transform: translate(-50%, -4px); padding: 6px 10px; border-radius: 8px; background: var(--navy); color: #fff; font-family: var(--body); font-size: 12px; font-weight: 500; line-height: 1; white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity .14s ease, transform .14s ease; z-index: 2200; }
.topbar-actions [data-tip]:hover::after, .topbar-actions [data-tip]:focus-visible::after { opacity: 1; transform: translate(-50%, 0); transition-delay: .35s; }
.topbar-actions [data-tip][aria-expanded="true"]::after { opacity: 0; }
.topbar-actions .topbar-user-wrap:last-child [data-tip]::after, .topbar-actions > div:last-child [data-tip]::after { left: auto; right: 0; transform: translate(0, -4px); }
.topbar-actions > div:last-child [data-tip]:hover::after, .topbar-actions > div:last-child [data-tip]:focus-visible::after { transform: translate(0, 0); }
@media (max-width: 720px) { .topbar-actions .topbar-icon-btn { width: 44px; height: 44px; } [data-tip]::after { display: none; } }
@media (prefers-reduced-motion: reduce) { [data-tip]::after { transition: none; } }

/* ---- Z-index scale and popover stacking (2026-10-04) ----
   ONE scale for every layer. New components must use var(--z-*), never a bare number.
   Order, low to high:
     --z-row-sticky   4     sticky table header / first column cells
     --z-sticky       40    sticky bars inside a page (review tray)
     --z-back-to-top  90    floating back-to-top button
     --z-topbar       60    sticky content topbar (its menus live on <body>, see below)
     --z-rail         100   sidebar (desktop)
     --z-search       500   global search modal
     --z-dropdown     1200  every menu / popover / drawer that must beat page content
     --z-modal        1900  full-screen dialogs (signed copy, onboarding)
     --z-loader       2000  loading overlay
     --z-confirm      2050  confirm/alert/prompt (must beat the loader and any modal)
     --z-tooltip      2100  rail tooltips, enlarge view
     (2200 is the [data-tip] bubble, the one layer above everything but the tour)
     --z-tour         9000  Welcome Tour overlay, tips, pill (9100 celebration)
   Rules that keep menus from being covered:
   1. A menu that can sit inside a table row, card or header is PORTALED to <body> while open
      (actions-menu.js), so no ancestor stacking context (animation, transform, opacity, filter,
      isolation, backdrop-filter, overflow) can trap it.
   2. Never give rows, cells, cards or .main children an animation with fill-mode both/forwards or
      a persistent transform/opacity: it keeps a stacking context alive (check_stylesheet.py fails).
   3. CSS-only popovers that stay inside their parent (.info-pop, .dropdown, the renewal "More"
      menu) are lifted above their siblings with :has() below while open or hovered. */
:root {
  --z-row-sticky: 4; --z-sticky: 40; --z-topbar: 60; --z-back-to-top: 90; --z-rail: 100; --z-search: 500;
  --z-dropdown: 1200; --z-modal: 1900; --z-loader: 2000; --z-confirm: 2050; --z-tooltip: 2100; --z-tour: 9000;
}
#rwTable thead th { z-index: var(--z-row-sticky); }
.rv-bar { z-index: var(--z-sticky); }
.content-topbar { z-index: var(--z-topbar); }
#back-to-top { z-index: var(--z-back-to-top); }
.rail { z-index: var(--z-rail); }
.search-modal-backdrop { z-index: var(--z-search); }
.actions-menu, .prorate-popover, .info-pop, .rv-list, .topbar-new-menu, .rw-rv-more-menu, .rv-jump-results { z-index: var(--z-dropdown); }
.rv-list-backdrop { z-index: calc(var(--z-dropdown) - 10); }
.signed-modal, .ob-backdrop { z-index: var(--z-modal); }
.loader-overlay { z-index: var(--z-loader); }
.confirm-modal-backdrop { z-index: var(--z-confirm); }
.rail-tip, .rv-zoom { z-index: var(--z-tooltip); }
.tour-overlay { z-index: var(--z-tour); }
.tour-tip, .tour-pill { z-index: calc(var(--z-tour) + 1); }
.tour-celebrate { z-index: calc(var(--z-tour) + 100); }

/* Portaled row menu: fixed on <body>, so it only needs the scale and a tidy edge. */
body > .actions-menu { position: fixed; z-index: var(--z-dropdown); max-height: calc(100vh - 24px); overflow-y: auto; }

/* In-place popovers: lift the whole host above later siblings while the popover is showing. */
.stat-card:has(.info-btn:hover), .stat-card:has(.info-btn:focus-visible),
.stat-tile:has(.info-btn:hover), .stat-tile:has(.info-btn:focus-visible),
.module-card:has(.info-btn:hover), .module-card:has(.info-btn:focus-visible),
.status-board:has(.info-btn:hover), .status-board:has(.info-btn:focus-visible),
.status-board-kpi:has(.info-btn:hover), .status-board-kpi:has(.info-btn:focus-visible),
.status-board:has(details[open]), .rw-rv-hero:has(details[open]), .dropdown[open],
.autocomplete-wrap:focus-within, .rv-head:has(.rv-jump-results:not([hidden])) {
  position: relative; z-index: var(--z-dropdown);
}


/* ---- Navigation polish (2026-10-05) -- append AFTER the "Motion pass 2" block ----
   Replaces the permanent view-transition-names (they made .rail and .content-topbar stacking
   contexts, which can trap topbar popovers behind page content). nav.js names the regions only
   while a navigation runs. Sidebar and topbar stay still; only the content region moves. */
.rail { view-transition-name: none; }
.content-topbar { view-transition-name: none; }
::view-transition-old(root), ::view-transition-new(root) { animation: none; }
::view-transition-group(tln-rail), ::view-transition-group(tln-topbar) { animation-duration: 0s; }
::view-transition-old(tln-rail), ::view-transition-new(tln-rail),
::view-transition-old(tln-topbar), ::view-transition-new(tln-topbar) { animation: none; mix-blend-mode: normal; }
::view-transition-group(tln-content) { animation-duration: .18s; animation-timing-function: cubic-bezier(.2, .7, .2, 1); }
::view-transition-old(tln-content) { animation: tln-vt-out .1s ease-in both; }
::view-transition-new(tln-content) { animation: tln-vt-in .2s cubic-bezier(.2, .7, .2, 1) .04s both; }
@keyframes tln-vt-out { to { opacity: 0; } }
@keyframes tln-vt-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}

/* Thin progress bar, only added to the page after a navigation has taken over 150 ms. */
#tln-nav-bar { position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: var(--z-progress); pointer-events: none; opacity: 0; background: linear-gradient(90deg, var(--blue), #7BB2E6); transform-origin: left; transform: scaleX(0); }
#tln-nav-bar.is-running { opacity: 1; animation: tln-nav-run 8s cubic-bezier(.1, .6, .2, 1) forwards; }
@keyframes tln-nav-run { 0% { transform: scaleX(0); } 30% { transform: scaleX(.55); } 100% { transform: scaleX(.92); } }
@media (prefers-reduced-motion: reduce) { #tln-nav-bar { display: none; } }
:root { --z-progress: 3000; }

/* ---- Requests: Invoice/PO, Quote and Project Scope pages (2026-10-05) ----
   Form language from the approved Batch 1 mockup: type switch + section cards + summary rail +
   sticky action bar; lists use the status-board header; line items stay <table>s (the page JS
   builds <tr>s) and turn into cards on phones. No left-accent stripes, no z-index except the
   documented --z-* scale, no animation fill-mode both/forwards. */
.rq-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; flex-wrap: wrap; margin: 4px 0 16px; }
.rq-head-main { min-width: 0; flex: 1 1 420px; }
.rq-title-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.rq-title { font-family: var(--display); font-weight: 600; font-size: 26px; color: var(--text); margin: 0; }
.rq-sub { font-size: 14px; color: var(--text-soft); margin: 6px 0 0; max-width: 760px; line-height: 1.5; }
.rq-head-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.rq-switch { display: inline-flex; background: #EEF1F6; border-radius: 10px; padding: 3px; gap: 2px; }
.rq-seg { appearance: none; border: 0; background: transparent; font-family: var(--display); font-weight: 600; font-size: 13px; padding: 8px 14px; border-radius: 8px; color: var(--text-soft); cursor: pointer; transition: background .18s ease, color .18s ease, box-shadow .18s ease; }
.rq-seg:hover { color: var(--text); }
.rq-seg.is-active { background: #fff; color: var(--text); box-shadow: 0 1px 2px rgba(16, 24, 38, .12); }
.rq-seg:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

.rq-layout { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 16px; align-items: start; }
.rq-main { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.rq-rail { display: flex; flex-direction: column; gap: 16px; position: sticky; top: 88px; min-width: 0; }
.rq-lines-card { margin-top: 16px; }

.rq-card { background: var(--surface); border: 1px solid #E2E7EE; border-radius: 14px; padding: 20px; box-sizing: border-box; min-width: 0; }
.rq-card-title { font-family: var(--display); font-weight: 600; font-size: 16px; color: var(--text); }
.rq-card-sub { font-size: 13px; color: var(--text-soft); margin: 3px 0 14px; line-height: 1.5; }
.rq-card-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
.rq-card-head > div { min-width: 0; flex: 1 1 320px; }
.rq-prose { font-size: 14px; line-height: 1.6; color: var(--text); margin: 10px 0 0; white-space: pre-wrap; }
.rq-list { margin: 10px 0 0; padding-left: 20px; font-size: 14px; line-height: 1.6; }

.rq-field { margin-bottom: 14px; min-width: 0; }
.rq-field:last-child { margin-bottom: 0; }
.rq-field > label { font-family: var(--display); font-size: 12px; font-weight: 600; color: var(--text-soft); margin: 0 0 6px; }
.rq-card input:not([type="checkbox"]):not([type="radio"]), .rq-card select { height: 42px; padding: 0 14px; border: 1px solid #CBD5E1; border-radius: 10px; font-family: var(--body); font-size: 14px; }
.rq-card textarea { padding: 10px 14px; border: 1px solid #CBD5E1; border-radius: 10px; font-family: var(--body); font-size: 14px; }
.rq-card input:disabled { background: var(--bg); color: var(--text); opacity: 1; }
.rq-grid { display: grid; gap: 14px; margin-bottom: 14px; }
.rq-grid > .rq-field { margin-bottom: 0; }
.rq-grid-ts { grid-template-columns: 2fr 3fr; }
.rq-grid-half { grid-template-columns: 1fr 1fr; }
.rq-hint { font-size: 12px; color: var(--text-soft); margin-top: 5px; line-height: 1.45; }
.rq-opt { font-weight: 400; color: var(--text-soft); }
.rq-narrow { max-width: 280px; margin-top: 14px; }
.rq-card .suggestions button { display: block; width: 100%; text-align: left; padding: 9px 12px; border: 0; background: none; font-family: var(--body); font-size: 13.5px; cursor: pointer; }
.rq-card .suggestions button:hover { background: var(--bg); }

.rq-type-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.rq-type-card { appearance: none; text-align: left; background: var(--bg); border: 1px solid #D5DCE6; border-radius: 12px; padding: 18px; cursor: pointer; display: flex; flex-direction: column; gap: 4px; transition: border-color .15s ease, background .15s ease, transform .12s ease; }
.rq-type-card:hover { border-color: var(--blue); background: var(--blue-bg); }
.rq-type-card:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.rq-type-name { font-family: var(--display); font-weight: 600; font-size: 15px; color: var(--text); }
.rq-type-hint { font-size: 13px; color: var(--text-soft); }

/* line items (table markup is kept: the page scripts append <tr>s) */
.rq-lines-wrap { overflow-x: auto; }
table.rq-lines { width: 100%; border-collapse: collapse; }
.rq-lines thead th { font-family: var(--display); font-size: 11.5px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--text-soft); padding: 6px 8px; text-align: left; background: transparent; border-bottom: 1px solid #EDF1F6; }
.rq-lines td { padding: 10px 8px; border-top: 1px solid #EDF1F6; vertical-align: top; border-bottom: 0; }
.rq-lines tbody tr:first-child td { border-top: 0; }
.tbl-scroll table.tbl.rq-lines td:first-child, .tbl-scroll table.tbl.rq-lines th:first-child, .tbl-scroll table.tbl.rq-lines tbody tr:hover td:first-child { position: static; background: transparent; }
.rq-lines input, .rq-lines select { height: 40px; padding: 0 12px; border: 1px solid #D5DCE6; border-radius: 10px; font-family: var(--body); font-size: 14px; }
.rq-lines input[name*="unit_price"], .rq-lines input[name*="qty"] { font-family: var(--mono); font-variant-numeric: tabular-nums; text-align: right; }
.rq-lines .tbl-compact { padding-left: 10px; padding-right: 10px; }
.rq-c-num { width: 36px; text-align: center; color: var(--text-soft); }
.rq-lines td.rq-c-num { padding-top: 19px; }
.rq-c-price { width: 124px; }
.rq-c-qty { width: 76px; }
.rq-c-total { width: 112px; text-align: right; }
.rq-lines td.money-cell { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 600; padding-top: 19px; }
.rq-c-x { width: 44px; }
.rq-lines td.rq-c-x { padding-top: 12px; }
.rq-x { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0; border: 0; border-radius: 8px; background: transparent; color: #94A3B8; cursor: pointer; transition: background .15s ease, color .15s ease; }
.rq-x:hover { background: var(--bad-bg); color: var(--bad); }
.rq-x:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.rq-x svg { width: 15px; height: 15px; }
.rq-lines-view td.num, .rq-lines-view th.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; }
.rq-lines-view td { padding: 11px 8px; font-size: 14px; vertical-align: top; }
.rq-add { margin-top: 12px; }
.rq-add-btn { display: inline-flex; align-items: center; gap: 8px; height: 40px; padding: 0 16px; font-family: var(--display); font-weight: 600; font-size: 13.5px; }
.rq-add-btn svg { width: 16px; height: 16px; }
.rq-bullets { margin-top: 4px; }
.rq-bullet-row { display: flex; gap: 8px; align-items: center; margin-top: 8px; }
.rq-bullet-row input { flex: 1; height: 40px; padding: 0 12px; border: 1px solid #D5DCE6; border-radius: 10px; font-family: var(--body); font-size: 14px; }

/* quote lines: ten fields per item are laid out as a two-line card at every width */
table.rq-lines-quote, .rq-lines-quote tbody { display: block; width: 100%; }
.rq-lines-quote thead { display: none; }
.rq-lines-quote tr.itemRow { display: grid; grid-template-columns: 32px 108px minmax(0, 1fr) 128px 72px 104px 36px; gap: 8px 10px; padding: 14px 0; border-top: 1px solid #EDF1F6; align-items: start; }
.rq-lines-quote tbody tr.itemRow:first-child { border-top: 0; padding-top: 4px; }
.rq-lines-quote tr.itemRow > td { display: block; padding: 0; border: 0; min-width: 0; }
.rq-lines-quote tr.itemRow > td[data-label]::before { content: attr(data-label); display: block; margin-bottom: 4px; font-family: var(--display); font-size: 10.5px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--text-soft); }
.rq-lines-quote tr.itemRow > td.rq-c-num { padding-top: 26px; width: auto; }
.rq-lines-quote tr.itemRow > td.rq-c-num::before { content: none; }
.rq-lines-quote tr.itemRow > td:nth-child(2) { grid-column: 2; grid-row: 1; }
.rq-lines-quote tr.itemRow > td:nth-child(3) { grid-column: 3; grid-row: 1; }
.rq-lines-quote tr.itemRow > td:nth-child(4) { grid-column: 4; grid-row: 1; }
.rq-lines-quote tr.itemRow > td:nth-child(5) { grid-column: 5; grid-row: 1; }
.rq-lines-quote tr.itemRow > td:nth-child(6) { grid-column: 6; grid-row: 1; width: auto; text-align: right; padding-top: 0; line-height: 40px; }
.rq-lines-quote tr.itemRow > td:nth-child(6)::before { line-height: 1.2; }
.rq-lines-quote tr.itemRow > td:nth-child(10) { grid-column: 7; grid-row: 1; padding-top: 22px; width: auto; }
.rq-lines-quote tr.itemRow > td:nth-child(7) { grid-column: 2 / 4; grid-row: 2; }
.rq-lines-quote tr.itemRow > td:nth-child(8) { grid-column: 4 / 6; grid-row: 2; }
.rq-lines-quote tr.itemRow > td:nth-child(9) { grid-column: 6 / 8; grid-row: 2; }
.rq-lines-quote tr.itemRow > td.prorate-cell { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 6px; align-items: center; position: relative; }
.rq-lines-quote tr.itemRow > td.prorate-cell::before { grid-column: 1 / -1; }
.rq-lines-quote .prorate-btn { width: 32px; height: 32px; border-radius: 8px; }
.rq-lines-quote .prorate-btn svg { width: 15px; height: 15px; }

/* summary rail and totals */
.rq-sum-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 6px 0; font-size: 14px; color: var(--text); }
.rq-sum-row[hidden] { display: none; }
.rq-sum-row strong, .rq-sum-total strong { font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 500; }
.rq-sum-toggle .toggle-switch { font-family: var(--body); font-weight: 500; }
.rq-summary .rq-card-title { margin-bottom: 8px; }
.rq-summary .rq-card-sub { margin-top: -4px; }
.rq-sum-total { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding-top: 12px; margin-top: 8px; border-top: 1px solid #E2E7EE; font-family: var(--display); font-weight: 600; font-size: 15px; color: var(--text); }
.rq-sum-total strong { font-size: 22px; font-weight: 600; }
.rq-sum-inline { margin: 14px 0 0 auto; max-width: 340px; }
.rq-help details > summary { font-family: var(--display); font-weight: 600; font-size: 13px; color: var(--blue); cursor: pointer; }
.rq-help p { font-size: 12.5px; color: var(--text-soft); margin: 8px 0 0; line-height: 1.55; }
.rq-meta { margin: 12px 0 0; display: flex; flex-direction: column; gap: 12px; }
.rq-meta dt { font-family: var(--display); font-size: 11.5px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--text-soft); margin: 0 0 3px; }
.rq-meta dd { margin: 0; font-size: 14px; color: var(--text); overflow-wrap: anywhere; }
.rq-inline-form { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.rq-inline-form .rq-field { margin: 0; min-width: 200px; }
.rq-convert { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line); }
.rq-convert .field-hint { margin: 0 0 10px; }

/* sticky action bar */
.rq-bar { position: sticky; bottom: 12px; z-index: var(--z-sticky); margin-top: 16px; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 20px; background: var(--surface); border: 1px solid #E2E7EE; border-radius: 14px; box-shadow: 0 -4px 16px rgba(16, 24, 38, .06); }
.rq-bar-hint { font-size: 13px; color: var(--text-soft); }
.rq-bar-total { display: flex; align-items: baseline; gap: 10px; font-family: var(--display); font-weight: 600; font-size: 14px; color: var(--text-soft); }
.rq-bar-total strong { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 20px; color: var(--text); font-weight: 600; }
.rq-bar-actions { display: flex; gap: 10px; margin-left: auto; }

/* lists */
.rq-toolbar { display: flex; gap: 12px 16px; flex-wrap: wrap; align-items: center; margin: 16px 0 12px; }
.rq-toolbar .filter-chips { margin-bottom: 0; }
.rq-search { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin: 0 0 0 auto; }
.rq-search-field { position: relative; width: 340px; max-width: 100%; }
.rq-search-field svg { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); width: 17px; height: 17px; color: var(--text-soft); pointer-events: none; }
.rq-search-field input { height: 42px; margin: 0; padding: 0 14px 0 38px; border-radius: 12px; font-family: var(--body); font-size: 14px; }
.rq-voided { margin: 0; }
.rq-list-card { padding: 0; overflow: hidden; }
.rq-list-card .tbl th { font-family: var(--display); font-size: 11.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-soft); }

@media (max-width: 900px) {
  .rq-layout { grid-template-columns: minmax(0, 1fr); }
  .rq-rail { position: static; }
  .rq-grid-ts, .rq-grid-half, .rq-type-cards { grid-template-columns: minmax(0, 1fr); }
  .rq-search { margin-left: 0; width: 100%; }
  .rq-search-field { width: 100%; flex: 1 1 220px; }
}
@media (max-width: 720px) {
  .rq-title { font-size: 22px; }
  .rq-card { padding: 16px; }
  .rq-list-card { padding: 12px; overflow: visible; }
  .rq-lines td.rq-c-num::before { content: none; }
  .rq-lines td.rq-c-num, .rq-lines td.money-cell, .rq-lines td.rq-c-x { padding-top: 0; text-align: left; width: auto; }
  .rq-lines td.rq-c-x { align-self: flex-end; }
  .rq-lines input, .rq-lines select { width: 100%; }
  .rq-lines-quote tr.itemRow { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); border: 1px solid var(--line); border-radius: 12px; padding: 14px; margin-bottom: 12px; gap: 10px; }
  .rq-lines-quote tbody tr.itemRow:first-child { padding-top: 14px; }
  .rq-lines-quote tr.itemRow > td.rq-c-num { display: none; }
  .rq-lines-quote tr.itemRow > td:nth-child(2) { grid-column: 1; grid-row: 1; }
  .rq-lines-quote tr.itemRow > td:nth-child(10) { grid-column: 2; grid-row: 1; justify-self: end; padding-top: 20px; }
  .rq-lines-quote tr.itemRow > td:nth-child(3) { grid-column: 1 / -1; grid-row: 2; }
  .rq-lines-quote tr.itemRow > td:nth-child(4) { grid-column: 1; grid-row: 3; }
  .rq-lines-quote tr.itemRow > td:nth-child(5) { grid-column: 2; grid-row: 3; }
  .rq-lines-quote tr.itemRow > td:nth-child(6) { grid-column: 1; grid-row: 4; text-align: left; }
  .rq-lines-quote tr.itemRow > td:nth-child(9) { grid-column: 2; grid-row: 4; }
  .rq-lines-quote tr.itemRow > td:nth-child(7) { grid-column: 1; grid-row: 5; }
  .rq-lines-quote tr.itemRow > td:nth-child(8) { grid-column: 2; grid-row: 5; }
  .rq-bar { bottom: 8px; padding: 10px 14px; }
  .rq-bar-hint { display: none; }
  .rq-bar-actions { width: 100%; }
  .rq-bar-actions .btn { flex: 1 1 0; }
  .rq-bar-total { flex: 1 1 auto; }
  .rq-bar:has(.rq-bar-total) .rq-bar-actions { width: auto; flex: 0 0 auto; }
}

/* ---- Motion picks (confirmed 2026-10-05): buttons C, toggles D, flash B, dialogs D (desktop/landscape) and B (phone/portrait) ---- */
@keyframes tln-flash-in { from { opacity: 0; transform: scale(.97); } to { opacity: 1; transform: none; } }
@keyframes tln-sheet-up { from { transform: translateY(100%); } to { transform: none; } }
@keyframes tln-sheet-down { from { transform: none; } to { transform: translateY(100%); } }
@keyframes tln-fade-out { from { opacity: 1; } to { opacity: 0; } }
:root { --tln-wipe-primary: #1F5A93; --tln-wipe-light: #D3E3F4; --tln-wipe-secondary: #EEF1F6; --tln-wipe-danger: #A02F25; --tln-wipe-danger-light: #F3D4CF; }

/* Buttons C: the hover colour wipes in from the left; press scales. */
.btn-primary, .btn-light, .btn-secondary, .btn-danger, .btn-danger-light { transition: background-size .3s ease, color .15s, border-color .15s, transform .12s ease; }
.btn-primary { background: linear-gradient(var(--tln-wipe-primary), var(--tln-wipe-primary)) no-repeat left center / 0% 100% var(--blue); }
.btn-light { background: linear-gradient(var(--tln-wipe-light), var(--tln-wipe-light)) no-repeat left center / 0% 100% var(--blue-bg); }
.btn-secondary { background: linear-gradient(var(--tln-wipe-secondary), var(--tln-wipe-secondary)) no-repeat left center / 0% 100% var(--surface); }
.btn-danger { background: linear-gradient(var(--tln-wipe-danger), var(--tln-wipe-danger)) no-repeat left center / 0% 100% var(--bad); }
.btn-danger-light { background: linear-gradient(var(--tln-wipe-danger-light), var(--tln-wipe-danger-light)) no-repeat left center / 0% 100% var(--bad-bg); }
.btn-primary:not(:disabled):hover { background: linear-gradient(var(--tln-wipe-primary), var(--tln-wipe-primary)) no-repeat left center / 100% 100% var(--blue); }
.btn-light:not(:disabled):hover { background: linear-gradient(var(--tln-wipe-light), var(--tln-wipe-light)) no-repeat left center / 100% 100% var(--blue-bg); filter: none; }
.btn-secondary:not(:disabled):hover { background: linear-gradient(var(--tln-wipe-secondary), var(--tln-wipe-secondary)) no-repeat left center / 100% 100% var(--surface); }
.btn-danger:not(:disabled):hover { background: linear-gradient(var(--tln-wipe-danger), var(--tln-wipe-danger)) no-repeat left center / 100% 100% var(--bad); }
.btn-danger-light:not(:disabled):hover { background: linear-gradient(var(--tln-wipe-danger-light), var(--tln-wipe-danger-light)) no-repeat left center / 100% 100% var(--bad-bg); filter: none; }
@media (prefers-reduced-motion: no-preference) {
  .btn:not(:disabled):hover { transform: none; box-shadow: none; }
  .btn:not(:disabled):active { transform: scale(.98); }
}
@media (prefers-reduced-motion: reduce) { .btn-primary, .btn-light, .btn-secondary, .btn-danger, .btn-danger-light { transition: none; } }

/* Toggles D: the thumb slides and a check fades in on the thumb. */
.toggle-thumb::after, .usr-switch-thumb::after { content: ""; position: absolute; inset: 0; border-radius: 50%; opacity: 0; transition: opacity .2s ease; background: center / 11px 11px no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232C6FAC' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='5 12.5 10 17.5 19 7.5'/%3E%3C/svg%3E"); }
.usr-switch-thumb::after { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232C9A6A' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='5 12.5 10 17.5 19 7.5'/%3E%3C/svg%3E"); }
.toggle-switch input:checked + .toggle-track .toggle-thumb::after, .usr-switch.is-on .usr-switch-thumb::after { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .toggle-thumb::after, .usr-switch-thumb::after { transition: none; } }

/* Flash messages B: fade and scale in, then fade out on a timer (motion.js adds .is-leaving). */
@media (prefers-reduced-motion: no-preference) {
  .alert-bar-glow { animation: tln-flash-in .24s ease backwards; transition: opacity .24s ease, transform .24s ease, max-height .24s ease, margin .24s ease, padding .24s ease; }
}
.alert-bar-glow.is-leaving { opacity: 0; transform: scale(.98); max-height: 0 !important; margin-top: 0 !important; margin-bottom: 0 !important; padding-top: 0; padding-bottom: 0; overflow: hidden; }

/* Dialogs: pure fade with a blurred backdrop on desktop and landscape tablets. */
.confirm-modal-backdrop { -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
@media (prefers-reduced-motion: no-preference) {
  .confirm-modal-backdrop { animation: tln-fade .25s ease backwards; }
  .confirm-modal-card { animation: tln-fade .25s ease backwards; }
  .confirm-modal-backdrop.is-closing { animation: tln-fade-out .18s ease forwards; }
}
/* Dialogs on phones and portrait tablets: a sheet that slides up from the bottom. */
@media (max-width: 767px), (orientation: portrait) and (max-width: 1100px) {
  .confirm-modal-backdrop { align-items: flex-end; padding: 0; }
  .confirm-modal-card { max-width: 100%; width: 100%; border-radius: 16px 16px 0 0; padding-bottom: calc(22px + env(safe-area-inset-bottom, 0px)); }
}
@media (prefers-reduced-motion: no-preference) and ((max-width: 767px), (orientation: portrait) and (max-width: 1100px)) {
  .confirm-modal-card { animation: tln-sheet-up .3s cubic-bezier(.2, .8, .2, 1) backwards; }
  .confirm-modal-backdrop.is-closing .confirm-modal-card { animation: tln-sheet-down .22s ease forwards; }
}



/* ---- Fix 2026-10-05: tablet/phone drawer. The popover audit's global `.rail { z-index: var(--z-rail) }` (100)
   overrode the mobile drawer's 1220, so the open backdrop (1210) sat OVER the sidebar and swallowed taps on the
   module links. The drawer stack lives on the scale now: backdrop < drawer < mobile topbar, all above the 1200 menus. */
:root { --z-drawer-backdrop: 1210; --z-drawer: 1220; --z-mobile-topbar: 1230; }
@media (max-width: 860px) {
  .rail { z-index: var(--z-drawer); }
  .rail-backdrop.open { z-index: var(--z-drawer-backdrop); }
  .mobile-topbar { z-index: var(--z-mobile-topbar); }
}

/* ---- Module 18: Review Queue (rvq-*), 2026-10-05. No left-accent stripes, no bare z-index, no animation fill-mode both/forwards. ---- */
.rvq-tabs { margin: 16px 0 12px; }
.rvq-tabs .filter-chip { text-decoration: none; }
.rvq-card { padding: 0; overflow: hidden; margin-bottom: 18px; }
.rvq-tbl td { vertical-align: middle; }
.rvq-actions { display: flex; align-items: center; gap: 8px; justify-content: flex-end; flex-wrap: wrap; }
.rvq-inline { display: inline-block; margin: 0; }
.rvq-kind { display: inline-block; font-family: var(--display); font-size: 11.5px; font-weight: 600; padding: 3px 9px; border-radius: 999px; margin-right: 6px; background: var(--blue-bg); color: var(--blue); }
.rvq-kind-mileage { background: #E4F5EC; color: #1F7A52; }
.rvq-kind-invoice { background: #FBF3E4; color: #8a5f14; }
.rvq-age { font-family: var(--display); font-size: 12.5px; font-weight: 600; color: var(--text-soft); }
.rvq-age.is-overdue { color: #8a5f14; background: #FBF3E4; border: 1px solid var(--warn); padding: 3px 9px; border-radius: 999px; }
.rvq-decision { font-family: var(--display); font-size: 12px; font-weight: 600; padding: 3px 10px; border-radius: 999px; }
.rvq-decision-approved { background: #E4F5EC; color: #1F7A52; }
.rvq-decision-sent_back { background: #FBF3E4; color: #8a5f14; }
.rvq-section-title { font-family: var(--display); font-size: 17px; font-weight: 600; margin: 22px 0 10px; color: var(--text); }
.rvq-empty { padding: 34px 24px; text-align: center; color: var(--text-soft); }
.rvq-empty-title { font-family: var(--display); font-size: 17px; font-weight: 600; color: var(--text); margin-bottom: 6px; }
.rvq-empty p { margin: 0; font-size: 14px; }
.rvq-home-card { display: flex; align-items: center; gap: 16px; padding: 16px 20px; margin: 0 0 20px; border-radius: 14px; background: #FBF3E4; border: 1px solid var(--warn); color: var(--text); text-decoration: none; transition: background .15s, border-color .15s; }
.rvq-home-card:hover { background: #F8EBD0; }
.rvq-home-count { font-family: var(--mono); font-size: 28px; font-weight: 700; color: #8a5f14; min-width: 36px; text-align: center; font-variant-numeric: tabular-nums; }
.rvq-home-text { display: flex; flex-direction: column; flex: 1; font-size: 13.5px; color: var(--text-soft); }
.rvq-home-text strong { font-family: var(--display); font-size: 15.5px; color: var(--text); }
.rvq-home-go { font-family: var(--display); font-weight: 600; font-size: 13.5px; color: var(--blue); white-space: nowrap; }
@media (max-width: 720px) { .rvq-home-card { flex-wrap: wrap; } .rvq-home-go { width: 100%; } .rvq-actions { justify-content: flex-start; } }


/* ---- Timesheet page header, callouts and instructions (2026-10-05). Only the region above the time-entry table. ---- */
.ts-head .page-title { margin-bottom: 4px; }
.ts-head-meta { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; color: var(--text-soft); font-size: 14px; }
.ts-period { font-family: var(--body); font-weight: 500; color: var(--text); }
.ts-status.status-pill { font-family: var(--display); font-size: 11.5px; font-weight: 600; letter-spacing: .06em; padding: 4px 12px; border-radius: 999px; }
.ts-status-draft { background: #EEF1F6; color: var(--text-soft); }
.ts-status-complete { background: var(--blue-bg); color: var(--blue); }
.ts-status-approved { background: var(--good-bg); color: var(--good); }
.ts-callout { margin: 0 0 14px; padding: 12px 16px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--surface); font-size: 14px; line-height: 1.5; }
.ts-callout strong { font-family: var(--display); font-weight: 600; margin-right: 4px; }
.ts-callout-sub { display: block; margin-top: 2px; color: var(--text-soft); font-size: 13px; }
.ts-callout-warn { border-color: var(--warn); background: var(--warn-bg); color: #6b4a0f; }
.ts-callout-good { border-color: var(--good); background: var(--good-bg); color: var(--good); }
.ts-callout-bad { border-color: var(--bad); background: var(--bad-bg); color: var(--bad); }
.ts-how { padding: 0; margin-bottom: 12px; overflow: hidden; }
.ts-how > summary { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; padding: 13px 18px; cursor: pointer; list-style: none; }
.ts-how > summary::-webkit-details-marker { display: none; }
.ts-how > summary::before { content: ""; width: 7px; height: 7px; border-right: 2px solid var(--blue); border-bottom: 2px solid var(--blue); transform: rotate(-45deg); transition: transform .18s ease; margin-right: 2px; align-self: center; flex-shrink: 0; }
.ts-how[open] > summary::before { transform: rotate(45deg); }
.ts-how-title { font-family: var(--display); font-weight: 600; font-size: 15px; color: var(--text); }
.ts-how-line { font-size: 13.5px; color: var(--text-soft); }
.ts-steps { list-style: none; margin: 0; padding: 4px 18px 16px; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 24px; border-top: 1px solid var(--line); padding-top: 14px; }
.ts-steps li { display: flex; gap: 12px; font-size: 14px; line-height: 1.5; color: var(--text); }
.ts-steps li strong { font-family: var(--display); font-weight: 600; }
.ts-step-n { flex: 0 0 26px; height: 26px; border-radius: 50%; background: var(--blue-bg); color: var(--blue); font-family: var(--display); font-weight: 600; font-size: 12.5px; display: inline-flex; align-items: center; justify-content: center; }
.ts-keycard { padding: 12px 18px; }
.ts-key-title { font-family: var(--display); font-weight: 600; font-size: 14px; color: var(--text); display: block; margin-bottom: 8px; }
.ts-chips { display: flex; flex-wrap: wrap; gap: 6px 8px; }
.ts-chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px; background: var(--bg); border: 1px solid var(--line); font-size: 12.5px; color: var(--text-soft); white-space: nowrap; }
.ts-chip b { font-family: var(--display); font-weight: 600; color: var(--blue); }
@media (max-width: 720px) { .ts-steps { grid-template-columns: 1fr; } .ts-how-line { flex-basis: 100%; } }


/* ---- Mileage month view and Add/Edit trip, shared form language (2026-10-05) ----
   Section cards, a quiet header with the status pill, a "this trip" summary rail and a sticky action bar.
   No left-accent stripes, no bare z-index (uses --z-sticky), no animation fill-mode both/forwards. */
.mq-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 14px; }
.mq-head-main { min-width: 0; }
.mq-title-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.mq-title { margin: 0; font-family: var(--display); font-size: 25px; font-weight: 600; letter-spacing: -.01em; color: var(--text); }
.mq-sub { margin: 4px 0 0; font-size: 13.5px; color: var(--text-soft); }
.mq-head-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.mq-month-nav { display: inline-flex; gap: 8px; }
.mq-note { margin: 0 0 12px; padding: 12px 16px; border-radius: 12px; font-size: 14px; line-height: 1.5; border: 1px solid var(--line); background: var(--surface); }
.mq-note-warn { border-color: var(--warn); background: var(--warn-bg); color: #6f4a0f; }
.mq-status-line { margin: 0 0 14px; }
.mq-status-line .field-hint { margin: 0; }

.mq-layout { grid-template-columns: minmax(0, 1fr) 300px; gap: 16px; }
.mq-table-card { border-radius: 14px; }
.mq-table-card .tbl thead th { font-family: var(--display); font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--text-soft); background: #F8FAFC; }
.mq-table-card .tbl tbody td.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.mq-rail .mileage-total-tile { border-radius: 14px; }
.mq-rail .complete-action-card { border-radius: 14px; }

/* Add / Edit trip */
.mq-trip { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 16px; align-items: start; }
.mq-main { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.mq-card { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 20px; box-sizing: border-box; }
.mq-card-title { margin: 0 0 14px; font-family: var(--display); font-size: 15.5px; font-weight: 600; color: var(--text); }
.mq-card-sub { margin: -8px 0 12px; font-size: 12.5px; color: var(--text-soft); }
.mq-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.mq-inline { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.mq-card .field-label { font-family: var(--display); font-size: 12px; color: var(--text-soft); }
.mq-card .input { border-color: #CBD5E1; border-radius: 10px; min-height: 42px; }
.mq-card .input.input-sm { min-height: 38px; }
.mq-card input.input:not([type="number"]):not([type="date"]) { font-family: var(--body); font-size: 14px; }
.mq-num { max-width: 180px; font-family: var(--mono); }

/* Destination segmented control: the same .pill buttons the script toggles */
.pill-selector.mq-seg { display: flex; gap: 0; background: #EEF1F6; border-radius: 10px; padding: 3px; min-height: 42px; box-sizing: border-box; }
.mq-seg .pill { flex: 1; padding: 0 12px; border: 0; border-radius: 8px; background: transparent; color: var(--text-soft); font-size: 13px; transition: background .2s ease, color .2s ease, box-shadow .2s ease; }
.mq-seg .pill:hover { background: rgba(255, 255, 255, .6); color: var(--text); border: 0; }
.mq-seg .pill.pill-active, .mq-seg .pill.pill-active:hover { background: #fff; color: var(--navy); box-shadow: 0 1px 3px rgba(16, 24, 38, .14); }

/* Commute deduction: checkboxes drawn as switches */
.mq-switch-list { display: flex; flex-direction: column; }
.mq-switch-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; width: 100%; padding: 10px 0; border-top: 1px solid #F1F4F8; font-family: var(--body); font-weight: 500; font-size: 14px; }
.mq-switch-row:first-child { border-top: 0; }
.mq-switch-row input:focus-visible + .toggle-track { outline: 2px solid var(--blue); outline-offset: 2px; }

/* This trip summary + rail */
.mq-rail-trip { display: flex; flex-direction: column; gap: 14px; min-width: 0; position: sticky; top: 76px; }
.mq-rail-trip .trip-map-panel { position: static; }
.mq-summary-label { font-family: var(--display); font-size: 11.5px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--text-soft); }
.mq-summary-value { margin: 6px 0 8px; font-family: var(--mono); font-size: 28px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text); }
.mq-unit { font-family: var(--body); font-size: 14px; font-weight: 500; color: var(--text-soft); }
.mq-summary-rows { margin: 0; }
.mq-summary-rows > div { display: flex; justify-content: space-between; gap: 12px; padding: 7px 0; border-top: 1px solid #F1F4F8; font-size: 13px; color: var(--text-soft); }
.mq-summary-rows dt { font-weight: 400; }
.mq-summary-rows dd { margin: 0; font-family: var(--mono); font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text); }

/* Action bar: sticky under the form on desktop, the phone bar on the month view */
.mq-bar-form { position: sticky; bottom: 0; z-index: var(--z-sticky); display: flex; gap: 10px; align-items: center; padding: 12px 16px; margin-top: 2px; background: var(--surface); border: 1px solid var(--line); border-radius: 14px; box-shadow: 0 -6px 16px -10px rgba(10, 26, 51, .25); }
.mq-bar:not(.mq-bar-form) { display: none; }
.mq-bar form { margin: 0; }

@media (max-width: 860px) {
  .mq-layout, .mq-trip { grid-template-columns: 1fr; }
  .mq-rail-trip { position: static; order: -1; }
  .mq-rail-trip .trip-map-panel { order: 2; }
  .mq-head-actions .btn { flex: 1 1 auto; text-align: center; }
  .mq-layout { margin-bottom: 76px; }
  .mq-bar:not(.mq-bar-form) { display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-sticky); gap: 10px; padding: 10px 16px calc(10px + env(safe-area-inset-bottom, 0px)); background: var(--surface); border-top: 1px solid var(--line); box-shadow: 0 -8px 20px -12px rgba(10, 26, 51, .35); }
  .mq-bar:not(.mq-bar-form) .btn, .mq-bar:not(.mq-bar-form) form { flex: 1 1 0; }
  .mq-bar:not(.mq-bar-form) form .btn { width: 100%; }
  .mq-bar:not(.mq-bar-form) .btn { text-align: center; justify-content: center; min-height: 44px; }
}
@media (max-width: 720px) {
  .mq-grid-2 { grid-template-columns: 1fr; }
  .mq-title { font-size: 22px; }
  .mq-bar-form { position: sticky; bottom: 0; border-radius: 12px 12px 0 0; }
  .mq-bar-form .btn { flex: 1 1 0; text-align: center; min-height: 44px; }
}

/* ---- New request control: one always-visible two-part button, "+ Invoice | + Purchase order" (2026-10-05) ----
   Two plain links at every width: no trigger, no menu, no morph, no JS. Nothing in the header row moves. */
.nrc { --nrc-h: 44px; display: inline-flex; align-items: stretch; vertical-align: middle; }
.nrc-sm { --nrc-h: 36px; }
.nrc .nrc-seg { position: relative; display: inline-flex; align-items: stretch; overflow: hidden; border-radius: 10px; background: #3F6FA8; }
.nrc .nrc-opt { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: var(--nrc-h); padding: 0 22px; color: #fff; text-decoration: none; font-family: var(--display); font-weight: 600; font-size: 14px; white-space: nowrap; transition: background .18s ease; }
.nrc .nrc-opt-inv { border-right: 1px solid rgba(255, 255, 255, .32); }
.nrc .nrc-opt:hover, .nrc .nrc-opt:active { background: #2F5C93; }
.nrc .nrc-opt:focus-visible { outline: none; box-shadow: inset 0 0 0 2px #fff; }
.nrc-sm .nrc-opt { padding: 0 16px; font-size: 13px; }
@media (max-width: 560px) {
  .status-board-actions .nrc { flex: 1 1 100%; }
  .nrc { display: flex; width: 100%; }
  .nrc .nrc-seg { display: flex; width: 100%; }
  .nrc .nrc-opt { flex: 1 1 0; padding: 0 12px; }
}
@media (prefers-reduced-motion: reduce) { .nrc .nrc-opt { transition: none; } }

/* Home tile fit (2026-10-05): the two-part button must fit a narrow card, so the compact variant says "PO" and
   the halves share the width instead of overflowing. */
.nrc-short { display: none; }
.nrc-sm { display: flex; width: 100%; max-width: 100%; }
.nrc-sm .nrc-seg { display: flex; width: 100%; }
.nrc-sm .nrc-opt { flex: 1 1 0; min-width: 0; padding: 0 10px; white-space: nowrap; }
.nrc-sm .nrc-full { display: none; }
.nrc-sm .nrc-short { display: inline; }




/* ---- Welcome Tour floating launcher, option C (2026-10-05) ----
   The checklist lives in a launcher fixed at the bottom right of Home so the module tiles keep their full
   width. Active: a "Getting started" pill toggles a slide-up panel. Snoozed: a small round ring button with an
   amber dot (solid tint plus 1.5px blue border so it does not blend into the page). The spotlight overlay,
   modals and the confirm dialog stay above it (--z-tour / --z-modal / --z-confirm). */
.tour-layout { display: block; }
.tour-launcher { position: fixed; right: 20px; bottom: 20px; z-index: var(--z-dropdown); display: flex; flex-direction: column; align-items: flex-end; gap: 12px; margin: 0; }
.tour-launcher[hidden] { display: none; }
.tour-launch { display: inline-flex; align-items: center; gap: 10px; height: 52px; padding: 0 16px 0 9px; border: 0; border-radius: 999px; background: var(--blue); color: #fff; font-family: var(--display); font-size: 14px; font-weight: 600; cursor: pointer; box-shadow: 0 12px 28px -10px rgba(10, 26, 51, .55); transition: background .18s ease, box-shadow .18s ease, transform .12s ease; }
.tour-launch:hover { background: #1F5A93; box-shadow: 0 14px 30px -10px rgba(10, 26, 51, .65); }
.tour-launch:active { transform: scale(.98); }
.tour-launch:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; }
.tour-launch .tour-ring { background: #fff; border-radius: 50%; }
.tour-launch .tour-ring-num { font-size: 10px; }
.tour-launch-chev { display: inline-flex; margin-left: 2px; opacity: .9; }
.tour-launch.is-snoozed { position: relative; width: 52px; height: 52px; padding: 0; justify-content: center; border: 1.5px solid var(--blue); background: #E8F0FA; color: var(--navy); box-shadow: 0 10px 24px -10px rgba(44, 111, 172, .6); }
.tour-launch.is-snoozed:hover { background: #D3E3F4; }
.tour-launch.is-snoozed .tour-ring { background: transparent; }
.tour-launch-dot { position: absolute; top: 2px; right: 2px; width: 13px; height: 13px; border-radius: 50%; background: #F3A83B; border: 2px solid #fff; }
.tour-panel { position: relative; width: min(380px, calc(100vw - 32px)); max-height: min(72vh, calc(100vh - 120px)); overflow-y: auto; background: #fff; border-radius: 16px; box-shadow: 0 22px 54px -12px rgba(10, 26, 51, .45); border: 1px solid var(--line); }
.tour-panel:focus { outline: none; }
.tour-panel .tour-card { border: 0; box-shadow: none; border-radius: 16px; animation: none; }
.tour-panel-x { position: absolute; top: 10px; right: 10px; z-index: 1; width: 32px; height: 32px; border: 0; border-radius: 50%; background: #EEF1F6; color: var(--navy); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transition: background .15s ease; }
.tour-panel-x:hover { background: #DDE5F0; }
.tour-panel-x:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
@keyframes tour-panel-in { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: no-preference) {
  .tour-panel { animation: tour-panel-in .26s cubic-bezier(.2, .8, .2, 1) backwards; }
}
@media (prefers-reduced-motion: reduce) { .tour-launch, .tour-panel-x { transition: none; } }
@media (max-width: 720px) {
  .tour-launcher { right: 16px; bottom: calc(16px + env(safe-area-inset-bottom, 0px)); }
  .tour-panel { position: fixed; left: 0; right: 0; bottom: 0; width: 100%; max-height: 78vh; border-radius: 16px 16px 0 0; border-bottom: 0; padding-bottom: env(safe-area-inset-bottom, 0px); }
  .tour-panel .tour-card { border-radius: 16px 16px 0 0; }
  .tour-launcher.is-open .tour-launch { display: none; }
}
