/* ============================================================
   GrassrootsTerminal - Evergreen UI redesign
   App shell + design tokens + component recipes.

   Lifted from the design handoff prototype (styles.css + styles2.css),
   then namespaced so it NEVER touches out-of-scope app content:
   every rule targets a shell class (app, sidebar, topbar, content,
   sb- and tb- prefixes) or a NEW component class (dcard, doc-card,
   cs-row, seg, form-card, status, stat, grid). The only global
   recolors are the brand token + the brand button classes.

   Loaded LAST in _Layout head so shell selectors win.
   ============================================================ */

:root {
  /* Brand */
  --brand: #6BAA27;          /* === existing --groots-green; kept in sync */
  --brand-strong: #588f1f;
  --brand-soft: #eef5e2;
  --magenta: #c5144a;
  --magenta-soft: #fbe6ec;

  /* Neutrals — warm, faintly green-tinted */
  --bg: #f4f6f0;
  --surface: #ffffff;
  --surface-2: #fafbf7;
  --border: #e6e9df;
  --border-strong: #d6dacb;
  --ink: #1b2415;
  --ink-soft: #586051;
  --muted: #8b9281;

  /* Sidebar (dark evergreen) */
  --sb-bg: #14231a;
  --sb-bg-2: #102017;
  --sb-text: #c4d2c2;
  --sb-text-dim: #7e9080;
  --sb-hover: rgba(255,255,255,.06);
  --sb-active-bg: rgba(107,170,39,.18);
  --sb-active-text: #b6e07e;

  /* Department accents (flat, harmonised) */
  --c-quality: #5a9d2e;
  --c-finance: #2f7dc4;
  --c-safety:  #d44a3e;
  --c-engineering: #e0742a;
  --c-stock:   #cf971c;
  --c-logistics: #8a7a23;
  --c-dispatch: #9a6b3f;
  --c-projects: #d24d86;
  --c-breakdowns: #d9534f;
  --c-hr:      #8a5cc4;
  --c-learning: #1d7a4f;
  --c-marketing: #1f9e8f;
  --c-it:      #46586b;
  --c-security: #3a6ea5;
  --c-support: #c5144a;

  /* Shape & motion */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-xl: 22px;
  --shadow-sm: 0 1px 2px rgba(27,36,21,.05), 0 1px 3px rgba(27,36,21,.04);
  --shadow-md: 0 2px 6px rgba(27,36,21,.06), 0 8px 24px rgba(27,36,21,.07);
  --shadow-lg: 0 12px 40px rgba(27,36,21,.14);

  /* Density (default = compact) — tuned down from the earlier "comfortable"
     18px to ~80% of that scale, so the UI renders at true 100% browser zoom
     the way it used to look zoomed out to ~80%. Padding/gap/row-height/sidebar
     scale together with the font so the density stays balanced; see the
     [data-density] variants below to go larger (comfortable) per page. */
  --pad: 14px;
  --row-h: 44px;
  --gap: 14px;
  --fs: 14px;

  --sidebar-w: 240px;
  --sidebar-w-collapsed: 64px;
}

/* density variants (optional, theme-driven) */
[data-density="compact"] { --pad: 14px; --row-h: 42px; --gap: 14px; --fs: 14px; }

/* corner variants (optional) */
[data-corners="sharp"]  { --r-sm: 2px; --r-md: 3px; --r-lg: 4px; --r-xl: 6px; }
[data-corners="subtle"] { --r-sm: 5px; --r-md: 7px; --r-lg: 9px; --r-xl: 12px; }

/* light sidebar variant (optional) */
[data-sidebar="light"] {
  --sb-bg: #ffffff;
  --sb-bg-2: #f7f9f3;
  --sb-text: #3d4636;
  --sb-text-dim: #9aa291;
  --sb-hover: #f0f4e9;
  --sb-active-bg: var(--brand-soft);
  --sb-active-text: var(--brand-strong);
}

/* ============================================================
   Base — body restyle (font + background). Global but harmless:
   it only changes typeface + page background, which every page
   benefits from and which Bootstrap component internals don't read.
   ============================================================ */
body {
  font-family: "Figtree", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  background: var(--bg);
  color: var(--ink);
  font-size: var(--fs);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* the legacy shell pinned a 60px bottom margin for an absolute footer;
     the grid shell owns layout now, so neutralise it. */
  margin-bottom: 0;
}

.mono { font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace; }

::selection { background: var(--brand-soft); }

/* ============================================================
   App layout — sidebar + main grid
   ============================================================ */
.app {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  height: 100vh;
  /* dvh = the CURRENTLY visible viewport, excluding the browser's dynamic
     toolbars (mobile address/nav bars). Plain 100vh measures the viewport as if
     those toolbars were hidden, so the bottom slice of .app — where a page's
     last element (e.g. a form's submit button) lives — renders behind them and
     is unreachable at max scroll for some users. The 100vh line above is the
     fallback for browsers without dvh; on desktop the two are identical. */
  height: 100dvh;
  overflow: hidden;
  transition: grid-template-columns .18s ease;
}
/* First-paint guard: the early inline script applies the collapsed rail with
   this class in place so the grid width snaps instantly instead of animating
   open→collapsed on every navigation. The bottom-of-body script removes it on
   the next frame, restoring the transition for user-initiated toggles. */
.app.app-no-anim { transition: none; }
/* Collapsed: sidebar shrinks to a narrow icon-only rail (toggle to expand). */
.app.sb-collapsed { grid-template-columns: var(--sidebar-w-collapsed) 1fr; }

/* ---------- Sidebar ---------- */
.sidebar {
  background: var(--sb-bg);
  color: var(--sb-text);
  display: flex;
  flex-direction: column;
  border-right: 1px solid rgba(0,0,0,.06);
  overflow: hidden;
  /* Grid items default to min-height:auto — without this, any state where the sidebar
     is not a scroll container (the collapsed rail sets overflow:visible) makes its full
     nav height the row minimum, blowing .app past 100dvh: the page then clips below the
     window edge with NO scrollbar on every app whenever the window is shorter than the
     rail (~950px for users with many nav items). min-height:0 caps the row at the
     viewport in every state. */
  min-height: 0;
  position: relative;   /* anchor for the collapse toggle */
}
[data-sidebar="light"] .sidebar { border-right: 1px solid var(--border); }

/* ---------- Sidebar collapse toggle (desktop) ---------- */
.sb-collapse-btn {
  position: absolute; top: 16px; right: 12px;
  width: 28px; height: 28px; border-radius: var(--r-sm);
  border: 1px solid transparent; background: var(--sb-hover);
  color: var(--sb-text); cursor: pointer;
  display: grid; place-items: center; font-size: 14px;
  transition: background .12s, color .12s; z-index: 2;
}
.sb-collapse-btn:hover { background: var(--sb-active-bg); color: var(--sb-active-text); }
.sb-collapse-btn .bi { transition: transform .18s ease; }
.app.sb-collapsed .sb-collapse-btn .bi { transform: rotate(180deg); }
/* hidden on mobile (the topbar hamburger drives the overlay there instead) */
@media (max-width: 900px) { .sb-collapse-btn { display: none; } }

/* ===== Collapsed-rail rules: icon-only, labels & sub-trees hidden ===== */
.app.sb-collapsed .sidebar { overflow: visible; }       /* allow flyout room if added later */
/* Brand: show just the leaf mark (centered), hide the wordmark logo. Leave room
   below for the toggle so nothing overlaps the nav. */
.app.sb-collapsed .sb-brand { justify-content: center; padding: 16px 0 8px; }
.app.sb-collapsed .sb-logo { display: none; }
.app.sb-collapsed .sb-brand::after {
  content: ""; width: 34px; height: 34px; border-radius: 10px;
  background: var(--brand); display: block;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='white'%3E%3Cpath d='M8 1C4 3 2 6 2 9a6 6 0 0 0 12 0c0-3-2-6-6-8z'/%3E%3C/svg%3E") center/20px no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='white'%3E%3Cpath d='M8 1C4 3 2 6 2 9a6 6 0 0 0 12 0c0-3-2-6-6-8z'/%3E%3C/svg%3E") center/20px no-repeat;
  box-shadow: 0 4px 12px rgba(107,170,39,.35);
}
/* Toggle: take it OUT of absolute positioning in the rail so it can't overlap
   the nav icons. Make it a static, full-width centered row between the leaf
   and the nav. */
.app.sb-collapsed .sb-collapse-btn {
  position: static; right: auto; top: auto; transform: none;
  margin: 0 auto 6px; display: grid;
}
.app.sb-collapsed .sb-collapse-btn:hover { transform: none; }
/* Nav items: center the icon, hide the text label, counts, dots, chevrons */
.app.sb-collapsed .sb-item { justify-content: center; padding: 10px 0; gap: 0; font-size: 0; }
.app.sb-collapsed .sb-item .sb-ico { font-size: 19px; width: auto; }
.app.sb-collapsed .sb-item .sb-count,
.app.sb-collapsed .sb-item .sb-chev,
.app.sb-collapsed .sb-dot { display: none; }
/* Section labels (DEPARTMENTS) collapse to a thin divider */
.app.sb-collapsed .sb-section-label { font-size: 0; padding: 10px 0 6px; }
.app.sb-collapsed .sb-section-label::before {
  content: ""; display: block; height: 1px; margin: 0 14px; background: rgba(255,255,255,.1);
}
[data-sidebar="light"] .app.sb-collapsed .sb-section-label::before { background: var(--border); }
/* Department dots: in the rail show the colored dot centered as the glyph */
.app.sb-collapsed .sb-item .sb-dot {
  display: block; width: 9px; height: 9px; margin: 0 auto;
}
/* Collapsible group bodies (Apps/Reports + their nested subgroups) never open in the rail */
.app.sb-collapsed .sb-group-body,
.app.sb-collapsed .sb-subgroup-body { display: none !important; }
/* User chip: avatar only */
.app.sb-collapsed .sb-user { justify-content: center; padding: 8px 0; }
.app.sb-collapsed .sb-user-meta,
.app.sb-collapsed .sb-user .bi-three-dots { display: none; }
.app.sb-collapsed .sb-scroll { padding: 6px 8px 18px; }

.sb-brand {
  display: flex;
  align-items: center;
  padding: 20px 20px 16px;
  text-decoration: none;
}
/* Original Grassroots Group wordmark logo (wide ~3:1). Scale to the sidebar
   width; height follows the aspect ratio. */
.sb-logo {
  width: 100%;
  max-width: 220px;
  height: auto;
  display: block;
}

/* Legacy leaf-tile + text brand (kept for any markup still using them). */
.sb-leaf {
  width: 44px; height: 44px;
  border-radius: 12px;
  background: var(--brand);
  display: grid; place-items: center;
  flex-shrink: 0;
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(107,170,39,.35);
}
.sb-leaf i { color: #fff; font-size: 23px; }
.sb-leaf img { width: 100%; height: 100%; object-fit: contain; }
.sb-brand-text { display: flex; flex-direction: column; line-height: 1.08; }
.sb-brand-name { font-weight: 700; font-size: 18px; color: var(--sb-text); letter-spacing: -.01em; }
[data-sidebar="light"] .sb-brand-name { color: var(--ink); }
.sb-brand-sub { font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--sb-text-dim); font-weight: 600; }

.sb-scroll { flex: 1; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 6px 12px 18px; }
.sb-scroll::-webkit-scrollbar { width: 8px; }
.sb-scroll::-webkit-scrollbar-thumb { background: rgba(255,255,255,.08); border-radius: 8px; }
[data-sidebar="light"] .sb-scroll::-webkit-scrollbar-thumb { background: var(--border-strong); }

/* NavigationMenu emits a plain <ul>; strip list chrome inside the rail */
.sb-scroll ul { list-style: none; margin: 0; padding: 0; }

.sb-section-label {
  font-size: 10.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--sb-text-dim);
  font-weight: 700;
  padding: 16px 12px 7px;
}

.sb-item {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 11px 13px;
  border-radius: var(--r-md);
  color: var(--sb-text);
  cursor: pointer;
  font-weight: 500;
  font-size: 16px;
  border: none;
  background: none;
  width: 100%;
  text-align: left;
  text-decoration: none;
  transition: background .13s ease, color .13s ease;
  position: relative;
}
.sb-item:hover { background: var(--sb-hover); color: var(--sb-text); }
.sb-item .sb-ico { font-size: 19px; width: 24px; text-align: center; flex-shrink: 0; opacity: .92; }
.sb-item.active { background: var(--sb-active-bg); color: var(--sb-active-text); font-weight: 600; }
.sb-item.active .sb-ico { opacity: 1; }
.sb-item .sb-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.sb-item .sb-count {
  margin-left: auto;
  font-size: 11px;
  font-weight: 700;
  background: rgba(255,255,255,.1);
  color: var(--sb-text);
  padding: 1px 8px;
  border-radius: 20px;
}
[data-sidebar="light"] .sb-item .sb-count { background: var(--border); color: var(--ink-soft); }
.sb-item.active .sb-count { background: var(--brand); color: #fff; }
.sb-item .sb-chev { margin-left: auto; font-size: 12px; transition: transform .15s ease; opacity: .7; }

/* collapsible section (Reports, Apps) — hidden checkbox toggle, no JS */
.sb-group { display: contents; }
.sb-group-toggle { display: none; }
.sb-group-body { display: none; padding-left: 8px; }
.sb-group-toggle:checked ~ .sb-group-body { display: block; }
.sb-group-toggle:checked + .sb-item .sb-chev { transform: rotate(90deg); }
.sb-sublink {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 12px 7px 22px; border-radius: var(--r-sm);
  color: var(--sb-text); font-size: 13.5px; font-weight: 500;
  text-decoration: none; transition: background .12s, color .12s;
}
.sb-sublink:hover { background: var(--sb-hover); color: var(--sb-text); }
.sb-sublink.active { color: var(--sb-active-text); }

/* Nested collapsible (Apps > Department > links). Same checkbox-toggle pattern,
   one level deeper: a .sb-subgroup row (department) inside an .sb-group-body,
   revealing its own .sb-subgroup-body of links. No JS. */
.sb-subgroup-toggle { display: none; }
.sb-subgroup-label {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 12px 7px 22px; border-radius: var(--r-sm);
  color: var(--sb-text); font-size: 13.5px; font-weight: 600;
  cursor: pointer; transition: background .12s, color .12s;
}
.sb-subgroup-label:hover { background: var(--sb-hover); }
.sb-subgroup-label .sb-chev { margin-left: auto; font-size: 11px; transition: transform .15s ease; opacity: .7; }
.sb-subgroup-body { display: none; }
.sb-subgroup-toggle:checked ~ .sb-subgroup-body { display: block; }
.sb-subgroup-toggle:checked + .sb-subgroup-label .sb-chev { transform: rotate(90deg); }
/* second-level links sit a touch deeper */
.sb-subgroup-body .sb-sublink { padding-left: 38px; font-weight: 500; }
.sb-subgroup-body .sb-sublink-divider { height: 1px; background: rgba(255,255,255,.07); margin: 5px 22px 5px 38px; }
[data-sidebar="light"] .sb-subgroup-body .sb-sublink-divider { background: var(--border); }

.sb-foot {
  padding: 12px;
  border-top: 1px solid rgba(255,255,255,.07);
}
[data-sidebar="light"] .sb-foot { border-top: 1px solid var(--border); }
.sb-user {
  display: flex; align-items: center; gap: 11px;
  padding: 8px 10px; border-radius: var(--r-sm);
  cursor: pointer;
  color: var(--sb-text);
  text-decoration: none;
  width: 100%; border: none; background: none; text-align: left;
}
.sb-user:hover { background: var(--sb-hover); color: var(--sb-text); }
.sb-avatar {
  width: 34px; height: 34px; border-radius: 50%;
  background: linear-gradient(135deg, var(--brand), var(--brand-strong));
  color: #fff; display: grid; place-items: center; font-weight: 700; font-size: 13px;
  flex-shrink: 0;
}
.sb-user-meta { line-height: 1.2; min-width: 0; }
.sb-user-name { font-size: 13.5px; font-weight: 600; color: var(--sb-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
[data-sidebar="light"] .sb-user-name { color: var(--ink); }
.sb-user-role { font-size: 11px; color: var(--sb-text-dim); }
/* The user-menu drop-UP uses Bootstrap's .dropdown-menu. Do NOT pin it to
   width:100% — when the sidebar is collapsed to the icon rail (~64px on /Apps/*
   pages) that 100% shrinks the menu to the rail width, so its content (the
   email address, "Admin Dashboard", etc.) wraps and overflows the panel. Give
   it a content-driven min-width instead so it sizes correctly whether the
   sidebar is expanded or collapsed. */
.sb-foot .dropdown-menu { min-width: 230px; }

/* ---------- Main column ---------- */
.main {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-width: 0;
}

/* ---------- Topbar ---------- */
.topbar {
  height: 66px;
  flex-shrink: 0;
  background: rgba(255,255,255,.82);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 28px;
  z-index: 20;
}
.tb-hamburger {
  display: none;
  width: 40px; height: 40px;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--ink-soft);
  place-items: center; cursor: pointer; font-size: 18px;
}
.tb-crumbs { display: flex; align-items: center; gap: 8px; font-size: 13.5px; color: var(--muted); min-width: 0; flex-wrap: wrap; }
.tb-crumbs a { color: var(--muted); text-decoration: none; cursor: pointer; }
.tb-crumbs a:hover { color: var(--brand-strong); text-decoration: underline; }
.tb-crumbs .crumb-here { color: var(--ink); font-weight: 600; }
.tb-crumbs i { font-size: 11px; }

.tb-search {
  margin-left: auto;
  position: relative;
  width: 420px;
  max-width: 40vw;
}
.tb-search > i { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--muted); font-size: 15px; pointer-events: none; }
.tb-search input {
  width: 100%;
  height: 42px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  border-radius: var(--r-md);
  padding: 0 38px 0 40px;
  font-size: 14.5px;
  font-family: inherit;
  color: var(--ink);
  outline: none;
  transition: border-color .15s, box-shadow .15s, background .15s;
}
.tb-search input:focus { border-color: var(--brand); background: #fff; box-shadow: 0 0 0 3px rgba(107,170,39,.16); }
.tb-search input::placeholder { color: var(--muted); }
.tb-search-clear {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  width: 28px; height: 28px; border: none; background: transparent;
  border-radius: var(--r-sm); color: var(--muted); cursor: pointer;
  display: grid; place-items: center; font-size: 13px;
}
.tb-search-clear:hover { background: var(--border); color: var(--ink); }

/* ---------- Global search dropdown (consumed by search.js) ---------- */
.search-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  left: 0; right: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  max-height: 440px;
  overflow-y: auto;
  z-index: 1080;                 /* above topbar (20) and content */
  box-shadow: var(--shadow-lg);
}
.search-category {
  padding: 8px 14px 6px;
  font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--muted); background: var(--surface-2);
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
}
.search-category--first { border-top: none; }
.search-result-item {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px; text-decoration: none; color: var(--ink);
  border-bottom: 1px solid var(--border); transition: background 0.1s;
}
.search-result-item:last-child { border-bottom: none; }
.search-result-item:hover,
.search-result-item.active { background: var(--brand-soft); color: var(--ink); text-decoration: none; }
.search-result-icon { font-size: 1.2rem; color: var(--brand-strong); min-width: 1.5rem; text-align: center; flex-shrink: 0; }
.search-result-body { min-width: 0; }
.search-result-title { font-weight: 550; font-size: 0.92rem; line-height: 1.3; }
.search-result-desc { font-size: 0.8rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.search-no-results { padding: 24px; text-align: center; color: var(--muted); font-size: 0.92rem; }

.tb-actions { display: flex; align-items: center; gap: 10px; }
.tb-icon-btn {
  width: 40px; height: 40px;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--ink-soft);
  display: grid; place-items: center;
  cursor: pointer;
  font-size: 17px;
  position: relative;
  text-decoration: none;
  transition: background .13s, color .13s, border-color .13s;
}
.tb-icon-btn:hover { background: #fff; color: var(--ink); border-color: var(--border-strong); }
/* the notification bell keeps its Bootstrap dropdown + IDs; this just frames it */
.tb-bell .tb-icon-btn .bi-bell { font-size: 18px; }
.tb-badge {
  position: absolute; top: -3px; right: -3px;
  min-width: 17px; height: 17px; padding: 0 4px;
  background: var(--magenta); color: #fff;
  border-radius: 20px; font-size: 10px; font-weight: 700;
  display: grid; place-items: center;
  border: 2px solid var(--surface);
  line-height: 1;
}

/* ---------- Content scroll ---------- */
.content {
  flex: 1;
  overflow-y: auto;
  /* Flex column so the footer (a child, after .content-inner) is pushed to the
     bottom when the page is short, and flows at the natural end of the content
     — scrolling away with the page — when it's tall. */
  display: flex;
  flex-direction: column;
  /* Horizontal padding fills the open space on large monitors; the page body
     keeps its own top padding, the footer provides the bottom spacing. */
  padding: 34px clamp(28px, 4vw, 72px) 0;
}
/* Widened from the prototype's 1180px so cards/hero fill more of the open
   space on wide screens, while still capping on ultra-wide so lines stay
   readable. flex:1 0 auto makes it grow to fill, pushing the footer down on
   short pages without ever shrinking below its content. */
.content-inner { max-width: 1600px; margin: 0 auto; width: 100%; flex: 1 0 auto; }

/* Sticky footer: lives inside the scroll region, sits at the end of content. */
.content > .footer {
  flex: 0 0 auto;
  margin-top: 28px;
  max-width: 1600px;
  width: 100%;
  margin-left: auto; margin-right: auto;
}

/* Many existing pages wrap their body in Bootstrap's .container (a NARROW,
   centered, fixed-max-width box). Inside the new shell, .content-inner already
   provides the centered max-width column + side padding, so a page's own
   .container double-constrains it — leaving a pinched column with dead space
   (e.g. Approvals). Neutralise that inner constraint so the page fills the
   content column; .content-inner still governs the overall max width. */
.content-inner > .container,
.content-inner > .container-sm,
.content-inner > .container-md,
.content-inner > .container-lg,
.content-inner > .container-xl,
.content-inner > .container-xxl,
.content-inner > .container-fluid {
  max-width: none;
  width: 100%;
  padding-left: 0;
  padding-right: 0;
  margin-left: 0;
  margin-right: 0;
}
/* full-bleed opt-out (ViewData["FullBleed"]) */
body.full-bleed .content { padding: 0; }
body.full-bleed .content-inner { max-width: none; margin: 0; }

/* page header pattern */
.page-head { margin-bottom: 26px; }
.page-head.row { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.page-head-main { display: flex; align-items: center; gap: 16px; }
.page-head-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.page-eyebrow { font-size: 13.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--brand-strong); margin-bottom: 8px; }
.page-title { font-size: 36px; font-weight: 700; letter-spacing: -.02em; margin: 0 0 6px; color: var(--ink); text-wrap: pretty; }
.page-sub { font-size: 17.5px; color: var(--ink-soft); margin: 0; max-width: 60ch; text-wrap: pretty; }

.section-label {
  display: flex; align-items: center; gap: 10px;
  font-size: 13px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--muted); margin: 6px 0 16px;
}
.section-label::after { content: ""; flex: 1; height: 1px; background: var(--border); }

/* ============================================================
   Home — search hero
   ============================================================ */
.hero {
  background: linear-gradient(135deg, #1c3322, #16271b 60%, #1a3024);
  border-radius: var(--r-xl);
  padding: 34px 36px;
  color: #fff;
  position: relative;
  /* NOTE: no `overflow: hidden` here — it would clip the search dropdown.
     The decorative glow/leaf are contained by an inner .hero-deco layer. */
  margin-bottom: 30px;
}
/* Decoration layer carries the clip so the rounded corners stay clean while
   the hero itself lets the search results overflow. */
.hero::before {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  overflow: hidden;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(circle 280px at calc(100% + 40px) -60px, rgba(107,170,39,.45), transparent 70%);
}
.hero-leaf {
  position: absolute; right: 34px; bottom: 8px;
  font-size: 150px; color: rgba(107,170,39,.12); line-height: 1;
  transform: rotate(-12deg); pointer-events: none;
  z-index: 0;
}
.hero h1 { font-size: 28px; font-weight: 700; margin: 0 0 6px; letter-spacing: -.02em; position: relative; z-index: 1; }
.hero p { margin: 0 0 22px; color: rgba(255,255,255,.7); font-size: 15px; position: relative; z-index: 1; }
.hero-search { position: relative; max-width: 560px; z-index: 5; }
.hero-search > i { position: absolute; left: 18px; top: 50%; transform: translateY(-50%); color: var(--muted); font-size: 18px; z-index: 2; pointer-events: none; }
.hero-search input {
  width: 100%; height: 54px;
  border-radius: var(--r-md);
  border: none;
  background: #fff;
  padding: 0 18px 0 50px;
  font-size: 15.5px; font-family: inherit;
  color: var(--ink);
  outline: none;
  box-shadow: 0 6px 22px rgba(0,0,0,.18);
}
.hero-search input:focus { box-shadow: 0 6px 22px rgba(0,0,0,.18), 0 0 0 3px rgba(107,170,39,.5); }
.hero-search input::placeholder { color: var(--muted); }

/* ============================================================
   Department / app card grid
   ============================================================ */
.card-grid {
  display: grid;
  /* Bigger min so cards are large and ~4 fit per row on a wide screen
     (not 6). Collapses to fewer columns as the window narrows. */
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: var(--gap);
}

.dcard {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--pad);
  cursor: pointer;
  text-decoration: none;
  color: inherit;
  display: flex;
  flex-direction: column;
  gap: 12px;
  position: relative;
  overflow: hidden;
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
  box-shadow: var(--shadow-sm);
}
.dcard::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--accent, var(--brand));
  opacity: 0;
  transition: opacity .16s ease;
}
.dcard:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
  border-color: color-mix(in srgb, var(--accent, var(--brand)) 45%, var(--border));
  color: inherit;
}
.dcard:hover::before { opacity: 1; }

.dcard-top { display: flex; align-items: center; justify-content: space-between; }
.dcard-ico {
  width: 56px; height: 56px;
  border-radius: var(--r-md);
  display: grid; place-items: center;
  font-size: 28px;
  color: var(--accent, var(--brand));
  background: color-mix(in srgb, var(--accent, var(--brand)) 13%, #fff);
}
.dcard-arrow {
  color: var(--muted);
  font-size: 20px;
  transition: transform .16s ease, color .16s ease;
}
.dcard:hover .dcard-arrow { transform: translateX(3px); color: var(--accent, var(--brand)); }
.dcard-title { font-size: 21px; font-weight: 650; letter-spacing: -.01em; margin: 0; }
.dcard-desc { font-size: 15.5px; color: var(--ink-soft); margin: 0; line-height: 1.5; }
.dcard-foot {
  margin-top: auto; padding-top: 14px;
  display: flex; align-items: center; gap: 8px;
  font-size: 14.5px; color: var(--muted); font-weight: 500;
  border-top: 1px solid var(--border);
}

/* ============================================================
   Checksheet switchboard cards (title + doc/rev + New Entry / Reports)
   ============================================================ */
.doc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); gap: var(--gap); }
.doc-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: var(--pad); box-shadow: var(--shadow-sm); display: flex; flex-direction: column; gap: 6px;
  transition: box-shadow .15s, border-color .15s, transform .15s;
}
.doc-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.doc-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.doc-title { font-size: 18.5px; font-weight: 650; margin: 0; letter-spacing: -.01em; line-height: 1.25; }
.doc-code { font-size: 13.5px; color: var(--muted); margin: 2px 0 0; }
.doc-actions { margin-top: 14px; display: flex; gap: 8px; }
.doc-actions .btn-shell { flex: 1; }
.doc-flag {
  width: 34px; height: 34px; border-radius: var(--r-sm); flex-shrink: 0;
  display: grid; place-items: center; font-size: 16px;
  background: var(--brand-soft); color: var(--brand-strong);
}

/* ============================================================
   Badges & status pills
   ============================================================ */
.badge-dept {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 600;
  padding: 3px 9px;
  border-radius: 20px;
  background: color-mix(in srgb, var(--accent, var(--brand)) 13%, #fff);
  color: color-mix(in srgb, var(--accent, var(--brand)) 75%, #000);
}
.status {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 600;
  padding: 4px 11px;
  border-radius: 20px;
  white-space: nowrap;
}
.status::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.status.pending  { background: #fef3e0; color: #b5751a; }
.status.approved { background: var(--brand-soft); color: var(--brand-strong); }
.status.rejected { background: var(--magenta-soft); color: var(--magenta); }
.status.draft    { background: #eef0ea; color: #6b7361; }
.status.review   { background: #e4eefb; color: #2f6fc0; }
.status.overdue  { background: var(--magenta-soft); color: var(--magenta); }
.status.duesoon  { background: #fef3e0; color: #b5751a; }
.status.ontime   { background: var(--brand-soft); color: var(--brand-strong); }
.status.nodata   { background: #eef0ea; color: #6b7361; }
.status.acknowledged { background: #fdebd0; color: #af6c10; }
.status.intransit { background: #e4eefb; color: #2f6fc0; }
.status.received  { background: var(--brand-soft); color: var(--brand-strong); }

/* ============================================================
   Buttons (new namespaced .btn-* used by in-scope pages only)
   ============================================================ */
.btn-shell {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 46px; padding: 0 20px;
  border-radius: var(--r-sm);
  font-family: inherit; font-size: 15.5px; font-weight: 600;
  border: 1px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  transition: background .13s, border-color .13s, color .13s, transform .08s;
}
.btn-shell:active { transform: translateY(1px); }
.btn-primary-shell { background: var(--brand); color: #fff; box-shadow: 0 2px 8px rgba(107,170,39,.3); }
.btn-primary-shell:hover { background: var(--brand-strong); color: #fff; }
.btn-ghost { background: var(--surface); border-color: var(--border); color: var(--ink); }
.btn-ghost:hover { background: var(--surface-2); border-color: var(--border-strong); color: var(--ink); }
.btn-danger-shell { background: var(--magenta); color: #fff; }
.btn-danger-shell:hover { background: color-mix(in srgb, var(--magenta) 85%, #000); color: #fff; }
.btn-block { width: 100%; }
.btn-lg-shell { height: 52px; padding: 0 24px; font-size: 16.5px; }
.btn-sm-shell { height: 38px; padding: 0 14px; font-size: 14px; }
.btn-icon-sm {
  width: 38px; height: 38px; padding: 0;
  border-radius: var(--r-sm);
  border: 1px solid var(--border); background: var(--surface);
  color: var(--ink-soft); cursor: pointer; display: grid; place-items: center;
  text-decoration: none;
  transition: background .12s, color .12s, border-color .12s;
}
.btn-icon-sm:hover { background: var(--surface-2); color: var(--ink); border-color: var(--border-strong); }
.btn-icon-sm.danger:hover { color: var(--magenta); border-color: var(--magenta); background: var(--magenta-soft); }
.btn-icon-sm.go:hover { color: var(--brand-strong); border-color: var(--brand); background: var(--brand-soft); }

/* back link */
.backlink {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 13.5px; font-weight: 600; color: var(--ink-soft);
  cursor: pointer; margin-bottom: 18px;
  background: none; border: none; font-family: inherit; padding: 0;
  text-decoration: none;
}
.backlink:hover { color: var(--brand-strong); }

/* ============================================================
   Data app — panel, toolbar, tabs, table
   ============================================================ */
.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.panel + .panel { margin-top: var(--gap); }

.tabs {
  display: flex;
  gap: 2px;
  padding: 6px 8px 0;
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
}
.tab {
  border: none; background: none; cursor: pointer;
  font-family: inherit; font-size: 14px; font-weight: 600;
  color: var(--muted);
  padding: 12px 16px 14px;
  border-bottom: 2.5px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
  display: flex; align-items: center; gap: 8px;
  transition: color .13s;
  text-decoration: none;
}
.tab:hover { color: var(--ink); }
.tab.active { color: var(--brand-strong); border-bottom-color: var(--brand); }
.tab .tab-count {
  font-size: 11px; font-weight: 700;
  background: var(--surface-2); color: var(--muted);
  padding: 1px 7px; border-radius: 20px;
}
.tab.active .tab-count { background: var(--brand-soft); color: var(--brand-strong); }

.toolbar {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 18px;
  flex-wrap: wrap;
}
.toolbar .grow { flex: 1; min-width: 180px; }
.field { position: relative; }
.field > label { font-size: 12.5px; font-weight: 600; color: var(--ink-soft); display: block; margin-bottom: 6px; }
.field > i { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--muted); font-size: 14px; pointer-events: none; }
.field input, .field select {
  width: 100%; height: 38px;
  border: 1px solid var(--border); background: var(--surface-2);
  border-radius: var(--r-sm); padding: 0 12px 0 34px;
  font-family: inherit; font-size: 13.5px; color: var(--ink); outline: none;
  transition: border-color .13s, box-shadow .13s;
}
.field.no-ico input, .field.no-ico select { padding-left: 12px; }
.field input:focus, .field select:focus { border-color: var(--brand); background: #fff; box-shadow: 0 0 0 3px rgba(107,170,39,.14); }
.field select { -webkit-appearance: none; appearance: none; cursor: pointer; min-width: 150px; padding-right: 30px; }

.table-wrap { overflow-x: auto; }
table.grid { width: 100%; border-collapse: collapse; font-size: 15.5px; }
table.grid thead th {
  text-align: left;
  font-size: 12.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--muted);
  padding: 13px 18px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
table.grid tbody td { padding: 15px 18px; border-bottom: 1px solid var(--border); vertical-align: middle; }
table.grid tbody tr { transition: background .1s; }
table.grid tbody tr:hover { background: var(--surface-2); }
table.grid tbody tr:last-child td { border-bottom: none; }
.cell-ref { font-weight: 600; }
.cell-strong { font-weight: 600; }
.cell-muted { color: var(--muted); font-size: 13px; }
.cell-amount { font-weight: 700; font-variant-numeric: tabular-nums; }
.row-actions { display: flex; gap: 6px; justify-content: flex-end; }

.table-foot {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 18px; border-top: 1px solid var(--border);
  font-size: 13px; color: var(--muted);
}
.pager { display: flex; gap: 4px; }
.pager button {
  min-width: 32px; height: 32px; border-radius: var(--r-sm);
  border: 1px solid var(--border); background: var(--surface);
  font-family: inherit; font-size: 13px; color: var(--ink-soft); cursor: pointer;
}
.pager button:hover { background: var(--surface-2); }
.pager button.active { background: var(--brand); border-color: var(--brand); color: #fff; font-weight: 600; }

/* stat tiles */
.stat-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--gap); margin-bottom: 24px; }
.stat {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: 18px 20px; box-shadow: var(--shadow-sm);
}
.stat-label { font-size: 12.5px; color: var(--muted); font-weight: 600; display: flex; align-items: center; gap: 7px; margin-bottom: 8px; }
.stat-val { font-size: 28px; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.stat-val .unit { font-size: 15px; color: var(--muted); font-weight: 600; }
.stat-ico { width: 16px; }
.stat.is-danger .stat-val { color: var(--magenta); }
.stat.is-warn .stat-val { color: #b5751a; }
.stat.is-ok .stat-val { color: var(--brand-strong); }

/* sub navigation (pills inside an app) */
.subnav { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 22px; }
.subnav button, .subnav a {
  border: 1px solid var(--border); background: var(--surface);
  border-radius: 20px; padding: 7px 15px; font-family: inherit; font-size: 13.5px; font-weight: 600;
  color: var(--ink-soft); cursor: pointer; display: flex; align-items: center; gap: 7px;
  text-decoration: none; transition: all .12s;
}
.subnav button:hover, .subnav a:hover { border-color: var(--border-strong); background: var(--surface-2); }
.subnav button.active, .subnav a.active { background: var(--brand); border-color: var(--brand); color: #fff; }
.subnav .pill-ct { font-size: 11px; font-weight: 700; background: rgba(0,0,0,.08); padding: 0 6px; border-radius: 10px; }
.subnav .active .pill-ct { background: rgba(255,255,255,.25); }

/* ============================================================
   Forms
   ============================================================ */
.form-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm); overflow: hidden; margin-bottom: var(--gap);
}
.form-card-head {
  padding: 16px 20px; border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 12px; background: var(--surface-2);
}
.form-card-head h3 { margin: 0; font-size: 15.5px; font-weight: 650; }
.form-card-head .fch-ico { color: var(--brand-strong); font-size: 18px; }
.form-card-body { padding: 20px; }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px 20px; }
.fld { display: flex; flex-direction: column; gap: 6px; }
.fld label { font-size: 13.5px; font-weight: 600; color: var(--ink-soft); }
.fld label .req { color: var(--magenta); }
.fld input, .fld select, .fld textarea {
  height: 46px; border: 1px solid var(--border); background: var(--surface-2);
  border-radius: var(--r-sm); padding: 0 14px; font-family: inherit; font-size: 15.5px;
  color: var(--ink); outline: none; transition: border-color .13s, box-shadow .13s, background .13s; width: 100%;
}
.fld textarea { height: auto; min-height: 80px; padding: 10px 13px; resize: vertical; }
.fld input:focus, .fld select:focus, .fld textarea:focus { border-color: var(--brand); background: #fff; box-shadow: 0 0 0 3px rgba(107,170,39,.14); }
.fld select { -webkit-appearance: none; appearance: none; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 16 16'%3E%3Cpath fill='%238b9281' d='M8 11L3 6h10z'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center; padding-right: 30px; }
.fld .hint { font-size: 11.5px; color: var(--muted); }

/* checksheet criterion rows */
.cs-rows { display: flex; flex-direction: column; }
.cs-row {
  display: grid; grid-template-columns: 1fr auto; gap: 14px 18px;
  align-items: center; padding: 15px 20px; border-bottom: 1px solid var(--border);
}
.cs-row:last-child { border-bottom: none; }
.cs-row.notok { background: color-mix(in srgb, var(--magenta) 5%, var(--surface)); }
.cs-crit { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cs-crit-num { font-size: 11px; font-weight: 700; color: var(--muted); }
.cs-crit-text { font-size: 14.5px; font-weight: 550; }
.cs-crit-spec { font-size: 12.5px; color: var(--muted); }
.cs-input-zone { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; justify-content: flex-end; }
.cs-measure { width: 110px; }
.cs-measure input { height: 40px; text-align: center; font-variant-numeric: tabular-nums; font-weight: 600; }
.cs-comment { width: 100%; margin-top: 10px; }
.cs-comment input {
  width: 100%; height: 38px; border: 1px dashed var(--border-strong); background: var(--surface-2);
  border-radius: var(--r-sm); padding: 0 12px; font-family: inherit; font-size: 13px; color: var(--ink); outline: none;
}
.cs-comment input:focus { border-style: solid; border-color: var(--magenta); background: #fff; }

/* segmented OK / Not OK / N/A toggle */
.seg { display: inline-flex; border: 1px solid var(--border); border-radius: var(--r-sm); overflow: hidden; background: var(--surface-2); }
.seg button {
  border: none; background: none; cursor: pointer; font-family: inherit;
  font-size: 13px; font-weight: 650; padding: 9px 15px; color: var(--ink-soft);
  display: flex; align-items: center; gap: 6px; transition: background .12s, color .12s;
  border-right: 1px solid var(--border); white-space: nowrap;
}
.seg button:last-child { border-right: none; }
.seg button:hover { background: var(--surface); }
.seg button.on-ok { background: var(--brand); color: #fff; }
.seg button.on-no { background: var(--magenta); color: #fff; }
.seg button.on-na { background: var(--ink-soft); color: #fff; }

/* sticky form action bar */
.form-actionbar {
  position: sticky; bottom: 0; margin: 0 -36px -56px;
  padding: 16px 36px; background: rgba(255,255,255,.92); backdrop-filter: blur(10px);
  border-top: 1px solid var(--border); display: flex; align-items: center; gap: 12px; z-index: 10;
}
.form-actionbar .spacer { flex: 1; }
.form-actionbar .progress-note { font-size: 13px; color: var(--muted); }

/* photo / fault image slot */
.photo-slot {
  width: 64px; height: 64px; border-radius: var(--r-sm); flex-shrink: 0;
  border: 1.5px dashed var(--border-strong); background: var(--surface-2);
  display: grid; place-items: center; color: var(--muted); font-size: 20px; cursor: pointer;
  transition: border-color .12s, color .12s;
}
.photo-slot:hover { border-color: var(--brand); color: var(--brand-strong); }
.photo-slot.filled { border-style: solid; border-color: var(--brand); background: repeating-linear-gradient(45deg, #eef5e2, #eef5e2 6px, #e3eed2 6px, #e3eed2 12px); color: var(--brand-strong); }

/* ============================================================
   Signature block
   ============================================================ */
.sig-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px; }
.sig-slot {
  border: 1.5px dashed var(--border-strong); border-radius: var(--r-md);
  padding: 16px; display: flex; flex-direction: column; gap: 10px; background: var(--surface-2);
}
.sig-slot.signed { border-style: solid; border-color: var(--brand); background: var(--brand-soft); }
.sig-role { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.sig-pad {
  height: 70px; border-radius: var(--r-sm); background: #fff; border: 1px solid var(--border);
  display: grid; place-items: center; color: var(--muted); font-size: 13px;
}
.sig-meta { font-size: 12px; color: var(--ink-soft); display: flex; align-items: center; gap: 6px; }
.sig-fingerprint { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; color: var(--brand-strong); font-weight: 600; }

/* ============================================================
   Timeline / KV / kanban / empty / chip / meter
   ============================================================ */
.timeline { display: flex; flex-direction: column; gap: 0; }
.tl-item { display: grid; grid-template-columns: 28px 1fr; gap: 12px; }
.tl-rail { display: flex; flex-direction: column; align-items: center; }
.tl-node { width: 14px; height: 14px; border-radius: 50%; border: 2.5px solid var(--brand); background: #fff; margin-top: 3px; flex-shrink: 0; }
.tl-node.done { background: var(--brand); }
.tl-node.pending { border-color: var(--border-strong); }
.tl-line { flex: 1; width: 2px; background: var(--border); margin: 2px 0; min-height: 22px; }
.tl-body { padding-bottom: 18px; }
.tl-title { font-size: 14px; font-weight: 600; margin: 0; }
.tl-meta { font-size: 12.5px; color: var(--muted); }

.kv-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px 28px; }
.kv { display: flex; flex-direction: column; gap: 3px; }
.kv-k { font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.kv-v { font-size: 14.5px; font-weight: 550; }

.kanban { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(260px, 1fr); gap: var(--gap); overflow-x: auto; padding-bottom: 8px; }
.kcol { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 12px; }
.kcol-head { display: flex; align-items: center; justify-content: space-between; padding: 4px 6px 12px; font-weight: 700; font-size: 13.5px; }
.kcol-head .kct { font-size: 11px; background: var(--surface); border: 1px solid var(--border); padding: 1px 8px; border-radius: 20px; color: var(--muted); }
.kcard { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md); padding: 13px; margin-bottom: 10px; box-shadow: var(--shadow-sm); cursor: pointer; }
.kcard:hover { box-shadow: var(--shadow-md); }
.kcard-title { font-size: 13.5px; font-weight: 600; margin: 0 0 6px; }
.kcard-meta { font-size: 12px; color: var(--muted); display: flex; align-items: center; gap: 8px; }
.kbar { height: 5px; border-radius: 5px; background: var(--border); overflow: hidden; margin-top: 8px; }
.kbar > span { display: block; height: 100%; background: var(--brand); }

.empty { text-align: center; padding: 56px 24px; color: var(--muted); }
.empty .em-ico { font-size: 40px; color: var(--border-strong); margin-bottom: 12px; }
.empty h3 { margin: 0 0 6px; font-size: 17px; color: var(--ink); }
.empty p { margin: 0 auto; max-width: 42ch; font-size: 14px; }

.chip { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; padding: 3px 10px; border-radius: 20px; background: var(--surface-2); border: 1px solid var(--border); color: var(--ink-soft); }
.chip.brand { background: var(--brand-soft); border-color: transparent; color: var(--brand-strong); }

.meter { height: 8px; border-radius: 8px; background: var(--border); overflow: hidden; }
.meter > span { display: block; height: 100%; border-radius: 8px; background: var(--brand); }

/* compliance heatmap */
.heatmap { display: flex; gap: 3px; flex-wrap: wrap; }
.heat-cell { width: 15px; height: 15px; border-radius: 3px; background: var(--border); }
.heat-cell.h1 { background: #cde7b8; }
.heat-cell.h2 { background: #93cf6b; }
.heat-cell.h3 { background: var(--brand-strong); }
.heat-cell.miss { background: var(--magenta-soft); }

/* due-date pill helpers */
.due { display: inline-flex; flex-direction: column; gap: 1px; }
.due .due-date { font-weight: 600; font-variant-numeric: tabular-nums; }
.due .due-sub { font-size: 11.5px; color: var(--muted); }

/* ============================================================
   Alerts (namespaced -shell variants; do NOT touch Bootstrap .alert)
   ============================================================ */
.alert-shell { display: flex; gap: 12px; padding: 14px 16px; border-radius: var(--r-md); font-size: 13.5px; margin-bottom: var(--gap); align-items: flex-start; }
.alert-shell i { font-size: 17px; margin-top: 1px; }
.alert-shell.success { background: var(--brand-soft); color: var(--brand-strong); }
.alert-shell.warn { background: #fef3e0; color: #99670f; }
.alert-shell.info { background: #e4eefb; color: #2660ad; }
.alert-shell.danger { background: var(--magenta-soft); color: var(--magenta); }

/* ============================================================
   Dropdown panel (notifications) — restyle the bell dropdown's
   inner items without breaking Bootstrap's dropdown mechanics
   ============================================================ */
.topbar .dropdown-panel,
.dropdown-panel {
  width: 360px; max-width: 90vw;
  border: 1px solid var(--border);
  border-radius: var(--r-md); box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.dd-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px; border-bottom: 1px solid var(--border); }
.dd-head strong { font-size: 14.5px; }
.dd-head a { font-size: 12.5px; color: var(--brand-strong); text-decoration: none; font-weight: 600; }
.dd-item { display: flex; gap: 12px; padding: 13px 16px; border-bottom: 1px solid var(--border); }
.dd-item:last-child { border-bottom: none; }
.dd-item.unread { background: var(--brand-soft); }
.dd-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--brand); margin-top: 5px; flex-shrink: 0; }
.dd-item.read .dd-dot { background: var(--border-strong); }
.dd-body { min-width: 0; }
.dd-title { font-size: 13.5px; font-weight: 600; margin: 0 0 2px; }
.dd-meta { font-size: 12px; color: var(--muted); }

/* ============================================================
   Footer — was absolute-positioned in the legacy shell; in the
   grid it flows at the bottom of the scrolling content's column.
   Keep the element (out-of-scope CSS hides it by element).
   ============================================================ */
.content > .footer,
.main > .footer,
body > .footer {
  position: static;
  border-top: 1px solid var(--border);
  background: var(--surface);
  color: var(--muted);
  font-size: 13px;
  padding: 14px 36px;
}

/* ============================================================
   Brand button recolor — the ONLY permitted global Bootstrap-class
   recolor. Both spellings exist in the codebase; recolor both so
   every existing usage (in-scope and out) shifts to the new green.
   ============================================================ */
.btn-groots-primary,
.btn-primary-groots {
  --bs-btn-bg: var(--brand);
  --bs-btn-border-color: var(--brand);
  --bs-btn-color: #fff;
  --bs-btn-hover-bg: var(--brand-strong);
  --bs-btn-hover-border-color: var(--brand-strong);
  --bs-btn-hover-color: #fff;
  --bs-btn-active-bg: var(--brand-strong);
  --bs-btn-active-border-color: var(--brand-strong);
}
.btn-groots-secondary,
.btn-secondary-groots {
  --bs-btn-bg: var(--magenta);
  --bs-btn-border-color: var(--magenta);
  --bs-btn-color: #fff;
  --bs-btn-hover-bg: color-mix(in srgb, var(--magenta) 85%, #000);
  --bs-btn-hover-border-color: color-mix(in srgb, var(--magenta) 85%, #000);
  --bs-btn-hover-color: #fff;
}

/* `grassroots-green` helper — historically only defined inline on the KPI /
   ProjectLab pages, but the shared BatchCodeInput + LabSampleRequest modals
   use `.modal-header grassroots-green`. Define it globally (on the new green)
   so those shared modals render correctly anywhere they appear. */
.modal-header.grassroots-green,
.card-header.grassroots-green { background-color: var(--brand); color: #fff; }
.modal-header.grassroots-green .btn-close { filter: brightness(0) invert(1); }
.badge.bg-grassroots-green { background-color: var(--brand) !important; color: #fff; }
.btn-grassroots-green {
  --bs-btn-bg: var(--brand);
  --bs-btn-border-color: var(--brand);
  --bs-btn-color: #fff;
  --bs-btn-hover-bg: var(--brand-strong);
  --bs-btn-hover-border-color: var(--brand-strong);
  --bs-btn-hover-color: #fff;
}

/* ============================================================
   Auth pages (Login / Register / ForgotPassword / ...) — minimal shell:
   logo + nav top bar, centered content, NO sidebar.
   ============================================================ */
.auth-body {
  background: var(--bg);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
.auth-topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  padding: 14px clamp(20px, 4vw, 48px);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.auth-brand { display: flex; align-items: center; text-decoration: none; }
.auth-brand img { height: 46px; width: auto; display: block; }
.auth-nav { display: flex; align-items: center; gap: 26px; }
.auth-nav a {
  font-size: 15px; font-weight: 600; color: var(--ink-soft);
  text-decoration: none; display: inline-flex; align-items: center; gap: 6px;
  transition: color .13s;
}
.auth-nav a:hover { color: var(--brand-strong); }
.auth-main {
  flex: 1;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 56px 20px;
}
.auth-footer {
  text-align: center; padding: 18px; font-size: 13px; color: var(--muted);
  border-top: 1px solid var(--border); background: var(--surface);
}
.auth-footer a { color: var(--brand-strong); }

/* ============================================================
   Out-of-scope mitigations — keep apps with bespoke shell needs
   working under the new grid frame.
   ============================================================ */

/* Mobile: sidebar collapses to an overlay below 900px */
@media (max-width: 900px) {
  .app { grid-template-columns: 1fr; }
  /* MUST target #appSidebar by id — NOT `.sidebar`. Per-app rails (Leave, RCA2)
     are also class="sidebar" and sit INSIDE the global #app, so a bare `.sidebar`
     selector turned them into off-canvas drawers too: dragged 240px off-screen
     with no trigger of their own to reopen them, and — because both landed on
     z-index 60 — the app rail painted over the global nav when the top hamburger
     was tapped. That hid the Leave "Awaiting my action" queue on phones entirely.
     Scoped to the id, per-app rails keep their own rca2.css behaviour (they stack
     above the content at this width) and stay visible. */
  #appSidebar {
    position: fixed; top: 0; bottom: 0; left: 0;
    width: var(--sidebar-w); z-index: 60;
    transform: translateX(-100%);
    transition: transform .22s ease;
  }
  .app.sb-open #appSidebar { transform: translateX(0); }
  .sb-scrim {
    position: fixed; inset: 0; background: rgba(20,28,18,.45);
    z-index: 55; opacity: 0; pointer-events: none; transition: opacity .2s ease;
  }
  .app.sb-open .sb-scrim { opacity: 1; pointer-events: auto; }

  /* Callouts shell only: the Projects rail is ALSO a left-edge slide-in drawer
     (callouts.css: .callouts-app .sidebar = z-index 100, its scrim = 90). The
     global sidebar sits at z-index 60 / scrim 55, so on a Callouts page the
     top (global) hamburger opened the global sidebar UNDER the Projects rail —
     the Projects drawer painted over it and it looked like the wrong menu
     opened. Lift the global drawer + scrim above the Projects layer so the top
     hamburger behaves exactly as it does on every other page.
     MUST target #appSidebar by id — NOT `.sidebar`: the Projects rail is also
     class="sidebar", so a `.sidebar` selector raises BOTH drawers equally and
     the fix cancels itself out. #appSidebar is unique to the global sidebar. */
  body.callouts-shell #appSidebar { z-index: 130; }
  body.callouts-shell #sbScrim { z-index: 125; }
  .tb-hamburger { display: grid; }
  /* Hide the breadcrumb on mobile — it crams/wraps awkwardly between the
     hamburger and search. The page header already shows the location, and the
     hamburger opens the sidebar for navigation. */
  .tb-crumbs { display: none; }
  /* Reclaim the space: search fills the row between hamburger and actions. */
  .tb-search { margin-left: 0; flex: 1; max-width: none; }
  .topbar { gap: 10px; padding: 0 14px; }
  .content { padding: 22px 18px 48px; }
  .stat-row { grid-template-columns: repeat(2, 1fr); }
  /* The card grids use minmax(340px/360px, 1fr) columns. On a phone the content
     column is only ~324px wide, but the 340px MINIMUM forces the grid track
     wider than its container, so each card overflows its cell to the right —
     the card looks shoved right (big gap left, almost none right) even though
     the page itself doesn't scroll. Force a single column that shrinks to fit. */
  .card-grid, .doc-grid { grid-template-columns: 1fr; }

  /* On mobile the sidebar is a hidden full-width overlay driven by the
     hamburger — the desktop "collapsed icon rail" must NOT apply, or the
     auto-collapse on /Apps/* pages leaves a 64px rail squeezing the content.
     Neutralise every sb-collapsed rule here: single-column grid, overlay
     keeps its full width, and the labelled (not icon-only) sidebar shows. */
  .app.sb-collapsed { grid-template-columns: 1fr; }
  .app.sb-collapsed .sidebar { width: var(--sidebar-w); overflow: hidden; }
  .app.sb-collapsed .sb-logo { display: block; }
  .app.sb-collapsed .sb-brand { justify-content: flex-start; padding: 20px 20px 16px; }
  .app.sb-collapsed .sb-brand::after { display: none; }
  .app.sb-collapsed .sb-item { justify-content: flex-start; padding: 9px 12px; gap: 12px; font-size: 14px; }
  .app.sb-collapsed .sb-item .sb-count,
  .app.sb-collapsed .sb-item .sb-chev { display: inline-flex; }
  .app.sb-collapsed .sb-item .sb-dot { display: block; margin: 0; width: 8px; height: 8px; }
  .app.sb-collapsed .sb-section-label { font-size: 10.5px; padding: 16px 12px 7px; }
  .app.sb-collapsed .sb-section-label::before { display: none; }
  .app.sb-collapsed .sb-user { justify-content: flex-start; padding: 8px 10px; }
  .app.sb-collapsed .sb-user-meta { display: block; }
}
@media (min-width: 901px) {
  .sb-scrim { display: none; }
}

/* Offline indicator (drivers-offline.js prepends a fixed 50px top bar
   and sets body.has-offline-indicator). Push the shell down so the bar
   doesn't overlap the topbar. */
body.has-offline-indicator { padding-top: 0; }
body.has-offline-indicator .app { height: calc(100vh - 50px); margin-top: 50px; }

/* Factory Floor Display kiosk mode — hide all chrome, go edge to edge.
   Replaces the old DOM-coupled kiosk CSS for the new shell.
   IMPORTANT: match the VALUE ("1"), not a bare [data-ffd-kiosk]. Razor emits
   the attribute even when empty on normal pages, so a bare attribute selector
   would (and did) collapse the shell on every page. */
body[data-ffd-kiosk="1"] .sidebar,
body[data-ffd-kiosk="1"] .topbar,
body[data-ffd-kiosk="1"] .main > .footer,
body[data-ffd-kiosk="1"] .footer { display: none; }
body[data-ffd-kiosk="1"] .app { grid-template-columns: 1fr; height: 100vh; }
body[data-ffd-kiosk="1"] .content { padding: 0; overflow: auto; }
body[data-ffd-kiosk="1"] .content-inner { max-width: none; margin: 0; }

/* Callouts full-bleed — its callouts.css full-bleed selector was coupled
   to the old body>.container-lg>main DOM. Own the full-bleed here instead. */
body.callouts-shell .content { padding: 0; }
body.callouts-shell .content-inner { max-width: none; margin: 0; }
body.callouts-shell .main > .footer,
body.callouts-shell .footer { display: none; }

/* Callouts scroll fix.
   callouts.css sizes its 3-pane shell to `calc(100vh - 70px)` (the OLD top
   navbar height) and lets the right/main column grow so the PAGE scrolls. In
   the new shell the scroll container is `.content` (height = 100vh - 66px
   topbar), and the callouts grid's stale 100vh math overflowed it so the
   opened-project (right) pane was cut off with no way to scroll.
   Fix: let `.content` be the scroller and pin the grid + its sticky rail/
   listpane to the content's real height (100vh - 66px) instead of 100vh-70px. */
body.callouts-shell .content { overflow: hidden; }     /* the panes scroll, not .content */
body.callouts-shell .content-inner { height: 100%; }
/* Pin the 3-pane grid to the visible content height (100vh - 66px topbar) and
   make each region its OWN scroll container — rail, listpane, and the main
   column (which holds the opened-project reading pane). This is what lets the
   opened project on the right scroll instead of being cut off. */
body.callouts-shell .callouts-app .app {
  /* dvh (currently-visible viewport, excluding mobile toolbars) — same fix the
     outer .app uses. Plain 100vh over-counts by the address-bar height, so the
     bottom slice (last list item / form submit / FAB clearance) renders behind
     the browser toolbar and is unreachable at max scroll. 100vh is the fallback. */
  height: calc(100vh - 66px);
  height: calc(100dvh - 66px);
  min-height: 0;
}
body.callouts-shell .callouts-app .sidebar,
body.callouts-shell .callouts-app .listpane {
  height: calc(100vh - 66px);
  height: calc(100dvh - 66px);
}
body.callouts-shell .callouts-app .main { height: 100%; min-height: 0; overflow-y: auto; }

/* MOBILE: let no-dashboard form pages scroll as ONE document.
   The rules above pin the 3-pane shell to the viewport height and make .main
   an internal scroll region — correct for the dashboard/reading three-pane, but
   on a phone the Create / CreateBreakdown / Edit / Survey pages (which have NO
   #dashboardPane — just a form in .main) get TRAPPED: .content clips, .app is
   height-capped, and .main scrolls internally, so a tall form's lower fields and
   the submit row can't be reached by the normal page swipe (document stays locked
   at one screen). On mobile, for those pages only, unclip the shell and let the
   whole page grow so the document scrolls naturally. Scoped by :not(:has(#dashboardPane))
   so the real three-pane dashboard keeps its internal scroll. */
@media (max-width: 768px) {
  /* body.callouts-formpage is added by the callouts/breakdowns layout scripts on
     pages that have NO #dashboardPane (Create / CreateBreakdown / Edit / Survey).
     A plain body class is used deliberately instead of nested :has() — WebKit/iOS
     Safari does not reliably match :has() that itself contains :has(), which was
     the actual reason an earlier :has()-scoped version of this fix silently failed
     the mobile test. Every layer from the outer shell grid down to .main is
     released so the whole page grows and the DOCUMENT scrolls; the fixed-height
     3-pane dashboard/reading layout (which keeps #dashboardPane) is untouched. */
  body.callouts-shell.callouts-formpage #app { height: auto; min-height: 100vh; }
  body.callouts-shell.callouts-formpage #app > .main { overflow: visible; }
  body.callouts-shell.callouts-formpage .content { overflow: visible; }
  body.callouts-shell.callouts-formpage .content-inner { height: auto; }
  body.callouts-shell.callouts-formpage .callouts-app .app { height: auto; min-height: 0; overflow: visible; }
  body.callouts-shell.callouts-formpage .callouts-app .main { height: auto; min-height: 0; overflow: visible; }
}
