@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&family=Manrope:wght@400;500;600;700;800&display=swap');

:root {
  --bg: #f4f7f2;
  --bg-strong: #e8efe5;
  --surface: rgba(255, 255, 255, 0.88);
  --surface-strong: #ffffff;
  --border: rgba(18, 38, 32, 0.1);
  --text: #14221c;
  --muted: #5d6f66;
  --accent: #0f8f74;
  --accent-strong: #0a6a57;
  --accent-soft: rgba(15, 143, 116, 0.12);
  --warm: #ef8e5b;
  --warn-soft: rgba(239, 142, 91, 0.16);
  --danger: #c0563d;
  --shadow: 0 24px 60px rgba(20, 34, 28, 0.08);
  --radius-xl: 28px;
  --radius-lg: 20px;
  --radius-md: 16px;
  --sidebar-width: 240px;
  --mobile-topbar-height: 72px;
}

* {
  box-sizing: border-box;
}

/* ── Cross-document navigation: hold the old page's pixels until the new one is ready. ──
   Each /app/* screen is a full document load, so between "old page unloaded" and "new page
   first paint" the browser shows a blank white frame (~1 frame, but visible). This tells
   Chrome/Edge to keep the previous page on screen and cross-fade to the new one instead of
   flashing white. Safari/Firefox ignore it (unchanged from before). It's a paint effect
   only — no impact on layout, scroll, forms, JS, or which document loads. Now safe to use
   because the gate-blank and per-nav asset revalidation that made it fade to a half-built
   page are both fixed (see rbac.js fast-reveal + server.js /assets caching). */
@view-transition {
  navigation: auto;
}
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 0.16s;
}
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

html, body {
  margin: 0;
  min-height: 100vh;
  background:
    radial-gradient(circle at top left, rgba(15, 143, 116, 0.12), transparent 30%),
    radial-gradient(circle at top right, rgba(239, 142, 91, 0.14), transparent 32%),
    linear-gradient(180deg, #f8faf7 0%, var(--bg) 48%, #eef4ec 100%);
  color: var(--text);
  font-family: 'Manrope', sans-serif;
  scroll-behavior: smooth;
}

a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; }
body { overflow-x: hidden; }

/* ── APP SHELL ── */
.app-shell {
  display: flex;
  min-height: 100vh;
  align-items: stretch;
}

/* ── SIDEBAR ── */
.sidebar {
  position: fixed;
  top: 0;
  left: 0;
  width: var(--sidebar-width);
  height: 100vh;
  background: rgba(255,255,255,0.92);
  backdrop-filter: blur(20px);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  z-index: 50;
  overflow-y: hidden;
  transition: transform 0.24s ease, box-shadow 0.24s ease;
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 20px 16px 16px;
  border-bottom: 1px solid var(--border);
}

.brand-mark {
  height: 36px;
  width: auto;
  display: block;
  flex-shrink: 0;
}

.sidebar-brand-text {
  display: flex;
  flex-direction: column;
}

.sidebar-brand-text strong {
  font-size: 0.92rem;
  font-weight: 800;
  line-height: 1.2;
}

.sidebar-brand-text span {
  font-size: 0.72rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.sidebar-nav {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 12px 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.nav-section-label {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
  padding: 10px 8px 4px;
  font-weight: 700;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 12px;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
  text-decoration: none;
  position: relative;
}

.nav-item:hover {
  background: var(--accent-soft);
  color: var(--accent-strong);
}

/* Previously identical to :hover — nothing distinguished "the page you're actually on" from
   "whatever you're currently mousing over," so the sidebar gave no persistent sense of
   location. A left accent bar + bold weight stays visible with the mouse anywhere else,
   unlike the shared soft-background/text-color treatment both states still share. */
.nav-item.active {
  background: var(--accent-soft);
  color: var(--accent-strong);
  font-weight: 800;
  box-shadow: inset 0 0 0 1px rgba(15, 143, 116, 0.1);
}

.nav-item.active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 58%;
  border-radius: 0 3px 3px 0;
  background: var(--accent-strong);
}

.nav-item svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  opacity: 0.7;
}

.nav-item.active svg, .nav-item:hover svg {
  opacity: 1;
}

.nav-badge {
  margin-left: auto;
  font-size: 0.68rem;
  font-weight: 800;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--warn-soft);
  color: #8f5623;
}

.sidebar-footer {
  flex-shrink: 0;
  padding: 12px 10px;
  border-top: 1px solid var(--border);
}

.sidebar-user {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 12px;
  background: rgba(20,34,28,0.04);
}

.sidebar-user-avatar {
  width: 32px;
  height: 32px;
  border-radius: 999px;
  background: linear-gradient(135deg, #0f8f74, #0d5f7d);
  display: grid;
  place-items: center;
  color: white;
  font-weight: 800;
  font-size: 0.78rem;
  flex-shrink: 0;
}

.sidebar-user-info {
  flex: 1;
  min-width: 0;
}

.sidebar-user-info strong {
  display: block;
  font-size: 0.82rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sidebar-user-info span {
  font-size: 0.72rem;
  color: var(--muted);
}

.sidebar-signout {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--muted);
  padding: 4px;
  border-radius: 8px;
  display: grid;
  place-items: center;
  transition: color 0.15s;
}

.sidebar-signout:hover { color: var(--danger); }

/* The bottom user row is now a real <button> (was a plain div) — reset default button chrome
   so it keeps looking exactly like the row it always was, just clickable/keyboard-focusable. */
.sidebar-user {
  width: 100%;
  border: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.sidebar-user:hover { background: rgba(20,34,28,0.07); }

.sidebar-user-popup-wrap { position: relative; }

/* Opens upward, anchored to the row's own top edge — this sits at the very bottom of the
   viewport, so a normal downward dropdown would be clipped by the window edge. */
.sidebar-user-popup {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(100% + 8px);
  background: var(--surface-strong);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 12px 32px rgba(15, 23, 20, 0.18);
  padding: 6px;
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity 0.14s ease, transform 0.14s ease, visibility 0.14s;
  z-index: 40;
}
.sidebar-user-popup.open {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.sidebar-user-popup-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 10px 12px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--border);
}

.sidebar-user-avatar-lg {
  width: 38px;
  height: 38px;
  border-radius: 999px;
  background: linear-gradient(135deg, #0f8f74, #0d5f7d);
  display: grid;
  place-items: center;
  color: white;
  font-weight: 800;
  font-size: 0.9rem;
  flex-shrink: 0;
  overflow: hidden;
}

.sidebar-user-popup-id { min-width: 0; }
.sidebar-user-popup-id strong {
  display: block;
  font-size: 0.85rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sidebar-user-popup-id span {
  display: block;
  font-size: 0.72rem;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sidebar-user-popup-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 10px;
  border-radius: 9px;
  border: none;
  background: none;
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text);
  text-decoration: none;
  cursor: pointer;
  box-sizing: border-box;
}
.sidebar-user-popup-item:hover { background: rgba(20,34,28,0.06); }
.sidebar-user-popup-item svg { flex-shrink: 0; color: var(--muted); }
.sidebar-user-popup-item.danger:hover { background: rgba(192, 86, 61, 0.1); color: var(--danger); }
.sidebar-user-popup-item.danger:hover svg { color: var(--danger); }

.sidebar-user-popup-divider { height: 1px; margin: 4px 6px; background: var(--border); }

.shell-mobile-bar,
.sidebar-backdrop {
  display: none;
}

/* ── MAIN CONTENT ── */
.page-shell {
  margin-left: var(--sidebar-width);
  flex: 1;
  min-width: 0;
  min-height: 100vh;
  /* Bottom padding needs to clear .payroll-ai-launcher's full footprint (ai-assistant.css:
     position:fixed, bottom:22px, plus its own ~50px button height) — 44px wasn't enough, so
     whatever page content naturally ended up at the bottom of the scrollable area (a banner
     that wrapped to a second line, a table's last row, a form's submit button) could render
     underneath the floating launcher instead of above it. This is every page that includes
     both this stylesheet and ai-assistant.css, not any one page's layout bug. */
  padding: 28px 32px 104px;
}

.page-header {
  margin-bottom: 24px;
}

.page-header .eyebrow {
  margin-bottom: 4px;
}

.eyebrow {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
  margin-bottom: 6px;
}

.title {
  margin: 0;
  font-size: clamp(1.4rem, 1.8vw, 2rem);
  line-height: 1.1;
}

.subtitle {
  margin: 6px 0 0;
  color: var(--muted);
  max-width: 720px;
}

/* legacy topbar — hidden now, kept for compat */
.topbar { display: none; }
.toolbar { display: none; }

.badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border-radius: 999px;
  border: 1px solid rgba(15, 143, 116, 0.16);
  background: var(--accent-soft);
  color: var(--accent-strong);
  font-size: 0.92rem;
  font-weight: 700;
}

.pulse-dot {
  width: 9px;
  height: 9px;
  border-radius: 999px;
  background: linear-gradient(135deg, #0f8f74, #3ab897);
  box-shadow: 0 0 0 6px rgba(15, 143, 116, 0.12);
}

.button {
  appearance: none;
  border: none;
  border-radius: 14px;
  padding: 12px 16px;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
  transition: transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease;
}

.button:hover {
  transform: translateY(-1px);
}

.button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}
.button:disabled:hover {
  transform: none;
}

.button-primary {
  color: white;
  background: linear-gradient(135deg, #0f8f74, #0d5f7d);
  box-shadow: 0 16px 28px rgba(13, 95, 125, 0.2);
}

.button-secondary {
  color: var(--text);
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid var(--border);
}

.button-ghost {
  color: var(--accent-strong);
  background: var(--accent-soft);
}

.button-sm {
  padding: 8px 12px;
  border-radius: 10px;
  font-size: 0.82rem;
}

/* Compact per-row action menu — keeps table rows a consistent height instead of a variable
   number of buttons wrapping onto extra lines. Trigger is a small "⋯" button; the menu is an
   absolutely positioned popover toggled open/closed by JS (see loans.html for usage). */
.action-menu {
  position: relative;
  display: inline-block;
}

.action-menu-trigger {
  width: 34px;
  height: 34px;
  padding: 0;
  border-radius: 10px;
  font-size: 1.1rem;
  line-height: 1;
}

.action-menu-list {
  display: none;
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  min-width: 210px;
  /* Solid, not var(--surface) — that token is intentionally translucent (88% opacity) for
     panels sitting over the page background, but a popover menu sits over arbitrary page
     content (e.g. an activity list) and translucency lets that content bleed through and
     become unreadable underneath the menu items. */
  background: var(--surface-strong);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--shadow);
  padding: 6px;
  z-index: 40;
}

/* Variant for triggers sitting at the bottom of a scrollable container (e.g. a modal footer) —
   the menu would otherwise render below the trigger and get clipped by the modal's overflow:auto. */
.action-menu-list.open-up {
  top: auto;
  bottom: calc(100% + 6px);
}

.action-menu.open .action-menu-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.action-menu-list button {
  appearance: none;
  border: none;
  background: transparent;
  text-align: left;
  padding: 9px 10px;
  border-radius: 8px;
  font-weight: 600;
  font-size: 0.86rem;
  color: var(--text);
  white-space: nowrap;
  cursor: pointer;
}

.action-menu-list button:hover {
  background: rgba(20, 34, 28, 0.06);
}

.hero {
  margin-top: 22px;
  display: grid;
  /* minmax(0, ...) stops a column from being forced wider than its fr share by its own content
     (e.g. several non-wrapping buttons in a panel-header) — without it, one side's content can
     silently squeeze the other column narrower than intended, which is exactly what happened to
     tax-verification.html's mini-stat metrics once its buttons stopped wrapping their text. */
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 0.95fr);
  gap: 18px;
}

.hero-card,
.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow);
  backdrop-filter: blur(12px);
}

.hero-card {
  padding: 28px;
  position: relative;
  overflow: hidden;
}

.interactive-card,
.quick-link,
.list-item,
.tab-chip,
.button,
.sidebar-signout,
.nav-item {
  transition:
    transform 0.18s ease,
    box-shadow 0.18s ease,
    background 0.18s ease,
    color 0.18s ease,
    border-color 0.18s ease;
}

.interactive-card:hover,
.quick-link:hover,
.list-item:hover {
  transform: translateY(-2px);
  box-shadow: 0 20px 40px rgba(20, 34, 28, 0.09);
}

.hero-card::after {
  content: '';
  position: absolute;
  inset: auto -20% -35% auto;
  width: 280px;
  height: 280px;
  border-radius: 999px;
  background: radial-gradient(circle, rgba(15, 143, 116, 0.14), transparent 66%);
}

.hero-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
  margin-top: 22px;
}

.mini-stat,
.stat-card {
  padding: 18px;
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.84);
  border: 1px solid rgba(20, 34, 28, 0.08);
}

.stat-value {
  font-size: 1.85rem;
  font-weight: 800;
  margin-top: 10px;
}

.mono {
  font-family: 'IBM Plex Mono', monospace;
}

.grid-3,
.grid-2,
.grid-4 {
  display: grid;
  gap: 18px;
  margin-top: 18px;
}

.grid-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.grid-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.grid-4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.panel {
  padding: 24px;
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  margin-bottom: 18px;
}

.panel-title {
  margin: 0;
  font-size: 1.08rem;
  font-weight: 800;
}

.panel-copy {
  margin: 6px 0 0;
  color: var(--muted);
  font-size: 0.96rem;
}

.quick-links,
.stack {
  display: grid;
  gap: 12px;
}

.quick-link,
.list-item {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 18px;
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.82);
  border: 1px solid rgba(20, 34, 28, 0.08);
}

.quick-link:hover,
.list-item:hover {
  border-color: rgba(15, 143, 116, 0.18);
}

/* .list-item's lift/shadow hover is meant for clickable navigational rows (e.g. claim history) —
   wrong for a row that's just a static form field wrapper, where hovering to reach the input
   shouldn't make the row jump. Add this alongside .list-item to keep the row's look but drop
   the hover motion. */
.list-item.static-row:hover {
  transform: none;
  box-shadow: none;
  border-color: rgba(20, 34, 28, 0.08);
}

.quick-link strong,
.list-item strong {
  display: block;
  margin-bottom: 4px;
}

.muted {
  color: var(--muted);
}

/* Initials avatar — promoted from teams.html's local copy into a shared class, since other
   admin pages (e.g. tax-verification.html) need the same "who is this" visual and this file's
   pages don't use Tailwind, unlike employees.html's separate rounded-full avatar. */
.avatar {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  display: grid;
  place-items: center;
  font-weight: 800;
  font-size: 0.8rem;
  color: white;
  background: linear-gradient(135deg, #0f8f74, #0d5f7d);
  flex-shrink: 0;
}

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 800;
  white-space: nowrap;
}

.status-pill.success {
  color: var(--accent-strong);
  background: var(--accent-soft);
}

/* warning and danger used to both read as shades of the same orange-brown (#8f5623 on a
   peachy background vs #c0563d, a rust-red, on an almost identical pale background) — at
   pill size, with no other visual cue, "REQUESTED" and "REJECTED" were genuinely hard to
   tell apart at a glance. warning now reads unambiguously amber/yellow; danger now reads
   unambiguously red — different hue families, not just different shades of one. */
.status-pill.warning {
  color: #92400e;
  background: rgba(245, 158, 11, 0.18);
}

.status-pill.neutral {
  color: #345046;
  background: rgba(20, 34, 28, 0.08);
}

.status-pill.danger {
  color: #b91c1c;
  background: rgba(220, 38, 38, 0.14);
}

/* Dense contexts (table rows, list rows in a popup) put a pill next to several other pieces
   of text on the same line — the default pill's size and 800 weight, fine as a standalone
   badge, reads as louder than everything around it once a long multi-word status ("Awaiting
   Rate Acceptance") sits beside short ones ("Cancelled") in the same column. compact trims
   padding/font-size/weight so length differences stop reading as importance differences. */
.status-pill.compact {
  padding: 4px 9px;
  font-size: 0.7rem;
  font-weight: 700;
}

/* Small hover-for-detail icon — folds an explainer paragraph that would otherwise sit
   permanently under every panel title into an on-demand tooltip. Uses a real CSS tooltip off
   `data-tooltip` (not the native `title` attribute) — `title` has a ~1s hover delay before the
   browser's own unstyled bubble appears, easy to miss and easy to mistake for "not working".
   This one shows instantly, is keyboard-reachable (:focus, via tabindex="0" on the element),
   and matches the app's own visual language instead of the OS's tooltip styling. */
.info-icon {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  margin-left: 6px;
  border-radius: 999px;
  background: rgba(20, 34, 28, 0.08);
  color: var(--muted);
  font-size: 0.7rem;
  font-style: normal;
  line-height: 1;
  cursor: help;
  vertical-align: middle;
}
.info-icon:hover,
.info-icon:focus {
  background: var(--accent-soft);
  color: var(--accent-strong);
  outline: none;
}
.info-icon::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 9px);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  width: max-content;
  max-width: 260px;
  background: #1f2937;
  color: #fff;
  font-size: 0.72rem;
  font-weight: 500;
  line-height: 1.45;
  white-space: normal;
  text-align: left;
  padding: 9px 12px;
  border-radius: 10px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.2);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.14s ease, transform 0.14s ease;
  z-index: 60;
}
.info-icon::before {
  content: '';
  position: absolute;
  bottom: calc(100% + 4px);
  left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: #1f2937;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.14s ease;
  z-index: 60;
}
.info-icon:hover::after,
.info-icon:focus::after {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}
.info-icon:hover::before,
.info-icon:focus::before {
  opacity: 1;
  visibility: visible;
}

/* Applied by ui-utils.js when the icon is too close to the viewport's top edge for the
   tooltip to fit above it — flips the bubble (and its arrow) to open downward instead. */
.info-icon.tooltip-below::after {
  bottom: auto;
  top: calc(100% + 9px);
  transform: translateX(-50%) translateY(-4px);
}
.info-icon.tooltip-below::before {
  bottom: auto;
  top: calc(100% + 4px);
  border-top-color: transparent;
  border-bottom-color: #1f2937;
}
.info-icon.tooltip-below:hover::after,
.info-icon.tooltip-below:focus::after {
  transform: translateX(-50%) translateY(0);
}

.table {
  width: 100%;
  border-collapse: collapse;
}

/* .table defaults to width:100%, which is right for a data-dense list like the Bonus Ledger
   but looks broken for a short, few-column table (like the wellness score-history) sitting in
   a wide panel — the browser stretches every column evenly to fill the panel, leaving huge dead
   gaps around short cell content ("87", "16%") instead of columns hugging their own content. */
.table-auto {
  width: auto;
  min-width: 0;
}
.table-auto th,
.table-auto td {
  padding-right: 28px;
  white-space: nowrap;
}

.table th,
.table td {
  text-align: left;
  padding: 14px 10px;
  border-bottom: 1px solid rgba(20, 34, 28, 0.08);
  vertical-align: top;
}

.table th {
  color: var(--muted);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
}

.empty-state {
  padding: 28px;
  border-radius: 20px;
  text-align: center;
  border: 1px dashed rgba(20, 34, 28, 0.14);
  background: rgba(255, 255, 255, 0.54);
  color: var(--muted);
}

.tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.tab-chip {
  border: 1px solid rgba(20, 34, 28, 0.08);
  background: rgba(255, 255, 255, 0.72);
  color: var(--muted);
  padding: 11px 14px;
  border-radius: 999px;
  cursor: pointer;
  font-weight: 700;
}

.tab-chip.active {
  color: white;
  background: linear-gradient(135deg, #0f8f74, #0d5f7d);
  box-shadow: 0 12px 20px rgba(13, 95, 125, 0.18);
}

.view {
  display: none;
}

.view.active {
  display: block;
}

.page-toolbar,
.section-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
}

.page-toolbar {
  margin-bottom: 12px;
}

.toolbar-actions,
.section-jumps {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.dashboard-shell {
  display: flex;
  flex-direction: column;
}

/* Was a 2-column grid (hero-card + a "Jump into work" shortcuts panel) — that panel was
   removed as a duplicate of the sidebar's own navigation, so the hero card now spans the
   full width alone. */
.dashboard-hero {
  margin-top: 8px;
  grid-template-columns: 1fr;
}

.hero-card-dashboard {
  display: flex;
  flex-direction: column;
  gap: 22px;
}

/* Constrained to 10ch back when the hero card only had ~57% of the row's width (the other
   43% went to "Jump into work") — full width now, so the title can breathe instead of
   wrapping early and leaving the rest of the row empty. */
.dashboard-hero-title {
  max-width: 32ch;
}

.compact-links .quick-link {
  padding: 14px 16px;
}

.dashboard-stat-grid {
  margin-top: 20px;
}

.section-header {
  margin-top: 24px;
  margin-bottom: 2px;
}

.section-title {
  margin: 0;
  font-size: clamp(1.15rem, 1.5vw, 1.45rem);
}

.dashboard-link-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.list-metrics {
  text-align: right;
  flex-shrink: 0;
}

.form-grid {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.field {
  display: grid;
  gap: 8px;
}

.field label {
  font-size: 0.88rem;
  font-weight: 700;
  color: var(--muted);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 13px 14px;
  border-radius: 14px;
  border: 1px solid rgba(20, 34, 28, 0.12);
  background: rgba(255, 255, 255, 0.92);
  color: var(--text);
}

.field textarea {
  min-height: 110px;
  resize: vertical;
}

/* Rupee-amount number input: hides the native increment/decrement spinner (a ₹2,200-style
   amount is typed, not stepped one at a time) so the value doesn't render crowded up against
   the browser's default arrow buttons. */
.currency-input {
  -moz-appearance: textfield;
}
.currency-input::-webkit-outer-spin-button,
.currency-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* Wraps a number input to show its unit (%, ₹) inside the field itself instead of the
   browser's native spin-button arrows — the unit is a clearer, more compact affordance than a
   stepper nobody uses to count up to a percentage or a rupee amount one click at a time. */
.field-suffixed {
  position: relative;
}
.field-suffixed input {
  padding-right: 40px !important;
  -moz-appearance: textfield;
}
.field-suffixed input::-webkit-outer-spin-button,
.field-suffixed input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.field-suffixed .suffix {
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 600;
  pointer-events: none;
}

.span-2 {
  grid-column: span 2;
}

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(8, 14, 12, 0.38);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 120;
  padding: 16px;
}

.modal-backdrop.open {
  display: flex;
}

.modal {
  width: min(720px, 100%);
  max-height: calc(100vh - 32px);
  overflow: auto;
  background: white;
  border-radius: 28px;
  border: 1px solid rgba(20, 34, 28, 0.1);
  box-shadow: 0 32px 80px rgba(20, 34, 28, 0.22);
  padding: 26px;
}

.modal-wide {
  width: min(980px, 100%);
}

/* Click-toggle help popover — same interaction pattern as .vh-emp-picker's dropdown (sidebar.js):
   a small trigger button, an absolutely-positioned floating card, closed on outside click. Used
   for reference content too long for a hover tooltip (e.g. the Bulk Upload column reference)
   instead of an always-open accordion permanently taking up modal height. */
.help-popover-wrap {
  position: relative;
  display: inline-flex;
  vertical-align: middle;
  margin-left: 8px;
}
.help-toggle-btn {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid rgba(20, 34, 28, 0.18);
  background: rgba(255, 255, 255, 0.9);
  color: var(--accent-strong);
  font-weight: 800;
  font-size: 0.78rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  line-height: 1;
}
.help-toggle-btn:hover,
.help-toggle-btn.open {
  background: var(--accent-strong);
  border-color: var(--accent-strong);
  color: white;
}
/* position:fixed (viewport-relative) rather than absolute — the modal itself has
   overflow:auto (so it can scroll its own long content), which clips any *absolutely*
   positioned descendant that extends past the modal's box. Fixed positioning escapes that
   clipping ancestor entirely, so the popover can float freely above the modal instead of being
   squeezed to fit inside it. Position (top/left) and size are computed in JS at open-time from
   the trigger's real getBoundingClientRect() and the viewport size, not the modal's rect. */
.help-popover {
  display: none;
  position: fixed;
  box-sizing: border-box;
  width: min(620px, 80vw);
  max-width: 620px;
  max-height: 60vh;
  overflow: auto;
  background: white;
  border: 1px solid rgba(20, 34, 28, 0.12);
  border-radius: 18px;
  box-shadow: 0 24px 56px rgba(20, 34, 28, 0.22);
  padding: 18px 20px;
  z-index: 500;
  font-size: 0.86rem;
  color: var(--muted);
}
.help-popover.open {
  display: block;
}
.help-popover p {
  margin: 0 0 10px;
}
.col-ref-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
}
.col-ref-table th,
.col-ref-table td {
  text-align: left;
  padding: 8px 10px;
  border-bottom: 1px solid rgba(20, 34, 28, 0.08);
  vertical-align: top;
}
.col-ref-table th {
  color: var(--muted);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.col-ref-table code {
  background: rgba(20, 34, 28, 0.06);
  padding: 1px 6px;
  border-radius: 5px;
  font-size: 0.78rem;
}
.col-ref-required {
  color: var(--danger);
  font-weight: 700;
  font-size: 0.74rem;
}
.col-ref-optional {
  color: var(--muted);
  font-size: 0.74rem;
}

.mono-textarea {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace !important;
  font-size: 0.82rem !important;
  white-space: pre;
  overflow-x: auto;
}

/* Real dropzone replacing the raw native <input type=file> (which renders as an unstyled
   "Choose file" button + "No file chosen" text that looks out of place next to the rest of the
   app). The native input still exists underneath (triggered via its <label>) so no custom file
   dialog needs reinventing — only its visible presentation changes. */
.file-dropzone {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px;
  border: 1.5px dashed rgba(20, 34, 28, 0.22);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.6);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.file-dropzone:hover,
.file-dropzone.dragover {
  border-color: var(--accent-strong);
  background: rgba(15, 143, 116, 0.06);
}
.file-dropzone-icon {
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 12px;
  background: rgba(15, 143, 116, 0.1);
  color: var(--accent-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
}
.file-dropzone-text {
  font-size: 0.85rem;
  color: var(--text);
  line-height: 1.5;
}
.file-dropzone-text strong {
  color: var(--accent-strong);
}
.file-dropzone-name {
  margin-left: auto;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--accent-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 220px;
}

/* Editable grid used by the "Edit as table" popup — a lightweight <table> of real <input>s
   rather than a spreadsheet-library dependency; each cell syncs back into an in-memory 2D array
   that gets serialized to tab-separated text on Apply. */
.grid-editor-wrap {
  border: 1px solid rgba(20, 34, 28, 0.1);
  border-radius: 16px;
  overflow: auto;
  max-height: 52vh;
}
.grid-editor-table {
  border-collapse: collapse;
  font-size: 0.82rem;
}
.grid-editor-table th,
.grid-editor-table td {
  border: 1px solid rgba(20, 34, 28, 0.08);
  padding: 0;
}
.grid-editor-table th {
  background: #f8faf7;
}
.grid-editor-table input {
  width: 140px;
  box-sizing: border-box;
  border: none;
  outline: none;
  background: transparent;
  padding: 9px 10px;
  font: inherit;
  color: var(--text);
}
.grid-editor-table th input {
  font-weight: 700;
  color: var(--accent-strong);
}
.grid-editor-table input:focus {
  background: rgba(15, 143, 116, 0.08);
}
.grid-editor-row-num {
  color: var(--muted);
  font-size: 0.74rem;
  text-align: center;
  background: #f8faf7;
  padding: 0 8px !important;
}
.grid-editor-row-del {
  border: none;
  background: none;
  color: var(--muted);
  cursor: pointer;
  padding: 6px !important;
  font-size: 0.9rem;
}
.grid-editor-row-del:hover {
  color: var(--danger);
}

.upload-preview-summary {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-size: 0.82rem;
  color: var(--muted);
  margin-bottom: 8px;
}
.upload-preview-wrap {
  border: 1px solid rgba(20, 34, 28, 0.1);
  border-radius: 16px;
  overflow: auto;
  max-height: 260px;
}
.upload-preview-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
  white-space: nowrap;
}
.upload-preview-table th,
.upload-preview-table td {
  text-align: left;
  padding: 9px 12px;
  border-bottom: 1px solid rgba(20, 34, 28, 0.06);
}
.upload-preview-table th {
  position: sticky;
  top: 0;
  background: #f8faf7;
  color: var(--muted);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.upload-preview-row-error {
  background: rgba(192, 86, 61, 0.07);
}
.upload-preview-row-error td:first-child {
  border-left: 3px solid var(--danger);
}
.upload-preview-error-text {
  color: var(--danger);
  font-size: 0.74rem;
  font-weight: 600;
  white-space: normal;
}

.notice {
  padding: 14px 16px;
  border-radius: 16px;
  background: rgba(15, 143, 116, 0.08);
  color: var(--accent-strong);
}

.notice.error {
  background: rgba(192, 86, 61, 0.12);
  color: var(--danger);
}

.notice.warning {
  background: var(--warn-soft);
  color: #8f5623;
}

@media (max-width: 1024px) {
  .page-shell {
    margin-left: 0;
    padding: calc(var(--mobile-topbar-height) + 18px) 20px 96px;
  }
  .shell-mobile-bar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: var(--mobile-topbar-height);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 18px;
    background: rgba(248, 250, 247, 0.92);
    backdrop-filter: blur(20px);
    border-bottom: 1px solid var(--border);
    z-index: 70;
  }
  .mobile-bar-brand {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
  }
  .mobile-bar-copy {
    min-width: 0;
  }
  .mobile-bar-copy strong,
  .mobile-bar-copy span {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .mobile-bar-copy strong {
    font-size: 0.9rem;
  }
  .mobile-bar-copy span {
    font-size: 0.72rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.12em;
  }
  .mobile-nav-toggle {
    appearance: none;
    border: 1px solid var(--border);
    background: rgba(255, 255, 255, 0.96);
    width: 44px;
    height: 44px;
    border-radius: 14px;
    display: inline-grid;
    place-items: center;
    color: var(--text);
    cursor: pointer;
    box-shadow: 0 12px 24px rgba(20, 34, 28, 0.08);
  }
  .sidebar {
    width: min(320px, calc(100vw - 28px));
    transform: translateX(-100%);
    box-shadow: 0 36px 90px rgba(20, 34, 28, 0.18);
  }
  .sidebar-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(8, 14, 12, 0.34);
    z-index: 60;
  }
  body.sidebar-open .sidebar {
    transform: translateX(0);
  }
  body.sidebar-open .sidebar-backdrop {
    display: block;
  }
  .hero,
  .grid-4,
  .grid-3,
  .grid-2,
  .form-grid {
    grid-template-columns: 1fr;
  }
  .hero-grid {
    grid-template-columns: 1fr;
  }
  .dashboard-link-grid {
    grid-template-columns: 1fr;
  }
  .page-toolbar,
  .section-header {
    flex-direction: column;
  }
}

@media (max-width: 768px) {
  .page-shell {
    padding: calc(var(--mobile-topbar-height) + 14px) 14px 84px;
  }
  .quick-link,
  .list-item,
  .panel-header,
  .toolbar-actions {
    flex-direction: column;
  }
  .quick-link,
  .list-item {
    align-items: stretch;
  }
  .list-metrics {
    text-align: left;
  }
  .panel,
  .hero-card {
    padding: 18px;
  }
  .stat-card,
  .mini-stat {
    padding: 16px;
  }
  .tab-chip {
    width: 100%;
    justify-content: center;
    text-align: center;
  }
  .section-jumps {
    width: 100%;
  }
  .span-2 {
    grid-column: auto;
  }
}
