@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');

:root {
  --bg-primary: #F4F6F9;
  --bg-secondary: #ffffff;
  --bg-card: #ffffff;
  --bg-hover: #f0f4f8;
  --sidebar-w: 210px;
  --accent: #0B5FA5;
  --accent-dark: #17344A;
  --accent2: #F28C00;
  /* Navy shell. Same pair the sign-in button uses (views/login.ejs), so the
     sidebar and the login screen read as one product. */
  --navy: #16336b;
  --navy-dark: #0f2450;
  /* Sidebar-local tokens: the light-theme text/border tokens below are unusable
     on the navy ground, so everything inside .sidebar states its own. Each alpha
     is chosen for its contrast on navy (see the scale documented at .sidebar):
     .82 = 8.7:1 for menu items, .58 = 5.2:1 for secondary text, .55 = 4.8:1 for
     section labels — muted, but all still above the 4.5:1 AA floor. */
  --nav-text: rgba(255,255,255,0.82);
  --nav-text-dim: rgba(255,255,255,0.58);
  --nav-label: rgba(255,255,255,0.55);
  --nav-line: rgba(255,255,255,0.10);
  --nav-hover: rgba(255,255,255,0.055);
  --nav-active-bg: rgba(255,255,255,0.08);
  --nav-active-bar: #8ab4e8;
  --danger: #e74c3c;
  --warning: #f39c12;
  --success: #27ae60;
  --text-primary: #333333;
  --text-secondary: #777777;
  --border: #e2e8f0;
  --radius: 12px;
  --shadow: 0 8px 25px rgba(0,0,0,0.06);
  --transition: 0.25s ease;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: 'Inter', sans-serif;
  background: var(--bg-primary);
  color: var(--text-primary);
  font-size: 14px;
  min-height: 100vh;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ─── LAYOUT ─────────────────────────────────────────── */
.layout { display: flex; min-height: 100vh; }
.sidebar-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(23, 52, 74, 0.42);
  backdrop-filter: blur(2px);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--transition), visibility var(--transition);
  z-index: 90;
}
.sidebar-backdrop.open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}
body.sidebar-open {
  overflow: hidden;
}

/* ─── SIDEBAR ─────────────────────────────────────────── */
/*
 * Navy panel (--navy, the sign-in button's colour) against the light content
 * area. Everything here restates colour on a dark ground: the shared
 * --text-secondary / --bg-hover / --border tokens are tuned for white cards and
 * vanish on navy.
 *
 * The panel is one compact type scale, and each tier differs in size, weight AND
 * opacity so the hierarchy survives without any of the three doing heavy lifting:
 *
 *   section label   10px / 600 / .12em tracking / 55% white   (4.8:1)
 *   menu item       14.5px / 500 / 82% white                  (8.7:1)
 *   active item     14.5px / 500 / 100% white on a 8% pill    (9.7:1)
 *   secondary text  10.5px / 400 / 58% white                  (5.2:1)
 *
 * Every alpha is held at or above 4.5:1 on its own ground (the active pill
 * included), so "muted" stays legible rather than decorative.
 */
.sidebar {
  width: var(--sidebar-w);
  background: var(--navy);
  border-right: 1px solid rgba(0,0,0,0.18);
  display: flex;
  flex-direction: column;
  position: fixed;
  top: 0; left: 0;
  height: 100vh;
  z-index: 100;
  transition: transform var(--transition);
}

/* ── Brand ─────────────────────────────────────────────── */
.sidebar-logo {
  padding: 18px 16px 16px;
  border-bottom: 1px solid var(--nav-line);
}
/* The ILS wordmark is dark artwork on transparency, so it needs a light plate to
   sit on. Kept small and tight — it is a mark, not a banner. */
.sidebar-logo .logo-text {
  display: inline-flex;
  align-items: center;
  background: #fff;
  border-radius: 8px;
  padding: 6px 9px;
}
.sidebar-logo .logo-text img {
  height: 26px;
  width: auto;
  display: block;
}
.sidebar-logo .logo-sub {
  font-size: 10px;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0.01em;
  color: var(--nav-text-dim);
  margin-top: 9px;
}

/* ── Nav ───────────────────────────────────────────────── */
.sidebar-nav {
  flex: 1;
  overflow-y: auto;
  padding: 10px 0 14px;
  /* Scrollable, but the scrollbar itself is not part of the design. */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.sidebar-nav::-webkit-scrollbar { width: 0; height: 0; }

.nav-section-label {
  font-size: 10px;
  line-height: 1;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--nav-label);
  font-weight: 600;
  padding: 0 18px 6px;
  margin-top: 18px;
}
/* One rhythm for every group: 18px above a heading, 2px between its items. The
   first heading sits closer, since the brand rule already separates it. */
.nav-section-label:first-child { margin-top: 4px; }

.nav-item {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 1px 8px;
  padding: 8px 10px;
  color: var(--nav-text);
  font-size: 14.5px;
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: -0.005em;
  border-radius: 6px;
  cursor: pointer;
  transition: background var(--transition), color var(--transition);
}
.nav-item:hover {
  background: var(--nav-hover);
  color: #fff;
  text-decoration: none;
}
/*
 * Active: a slightly lighter navy and a 2px accent flush to the pill's left
 * edge. The accent is an inset shadow rather than a border so it follows the
 * radius and costs the row no width — a border would square the corner off and
 * shift the label.
 */
.nav-item.active {
  background: var(--nav-active-bg);
  color: #fff;
  box-shadow: inset 2px 0 0 var(--nav-active-bar);
}
.nav-item:focus-visible {
  outline: 1px solid var(--nav-active-bar);
  outline-offset: -1px;
}

/* ── Icons ─────────────────────────────────────────────── */
/*
 * One monochrome set drawn in currentColor at a single 16px optical size and
 * 1.6 stroke, so the column reads as one family and each glyph tracks the
 * colour of its own row (muted → white on hover and active).
 */
.nav-item .nav-icon,
.sidebar-action .nav-icon,
.sidebar-logout .nav-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  stroke: currentColor;
  opacity: 0.68;
  transition: opacity var(--transition);
}
.nav-item:hover .nav-icon,
.nav-item.active .nav-icon,
.sidebar-action:hover .nav-icon,
.sidebar-logout:hover .nav-icon { opacity: 1; }

/* ── Two-line item (Master Companies) ──────────────────── */
.nav-copy {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.3;
}
/* Inherits the row's weight: a submenu parent is not a heavier item than its
   single-line siblings, only a taller one. */
.nav-title {
  color: inherit;
  font-weight: inherit;
  word-break: break-word;
}
.nav-subtitle {
  font-size: 11px;
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: 0.01em;
  color: var(--nav-text-dim);
  margin-top: 2px;
  word-break: break-word;
}
.nav-item:hover .nav-subtitle,
.nav-item.active .nav-subtitle { color: rgba(255,255,255,0.72); }

/* The notification count rides in the nav; the light-theme purple wash it
   inherits from .badge-new is invisible on navy. */
.sidebar .badge-new {
  background: rgba(255,255,255,0.14);
  color: #fff;
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 1px 6px;
  border-radius: 999px;
}

/* ── Footer: identity + sign out ───────────────────────── */
/*
 * One block rather than two stacked controls: the user row and Log out share a
 * column, the same 8px gutter as the nav pills, and the same radius — so the
 * footer reads as the end of the panel instead of a separate widget.
 */
.sidebar-footer {
  padding: 10px 8px 12px;
  border-top: 1px solid var(--nav-line);
}
/* Identity only. The pointer cursor and hover tint went with the click handler:
   they were the row advertising itself as a control, which it no longer is —
   the action moved to .sidebar-action below. */
.sidebar-user {
  display: flex;
  align-items: center;
  gap: 9px;
  border-radius: 6px;
  padding: 7px 10px;
}
.user-avatar {
  width: 28px; height: 28px;
  border-radius: 50%;
  background: rgba(255,255,255,0.12);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.16);
  display: flex; align-items: center; justify-content: center;
  font-weight: 600; font-size: 12px; color: #fff; flex-shrink: 0;
}
.user-info { min-width: 0; }
.user-info .user-name {
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -0.005em;
  color: #fff;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.user-info .user-role {
  font-size: 10px;
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: 0.02em;
  color: var(--nav-text-dim);
  margin-top: 1px;
  text-transform: capitalize;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/*
 * The two account actions share one row shape, so the footer reads as a short
 * list rather than as two unrelated widgets. They part company only on hover:
 * this one warms to white like any nav row, Logout goes red because it ends the
 * session.
 *
 * A <button> carries browser defaults a nav row does not, so font and background
 * are restated rather than inherited — without that it renders as a grey chip in
 * the middle of the dark column.
 */
.sidebar-action {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  margin-top: 2px;
  padding: 6px 10px;
  background: none;
  border: 0;
  border-radius: 6px;
  color: var(--nav-text-dim);
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.005em;
  cursor: pointer;
  text-align: left;
  transition: background var(--transition), color var(--transition);
}
.sidebar-action:hover {
  background: var(--nav-hover);
  color: #fff;
}
/* Keyboard focus has to be visible on its own: this row has no underline and no
   border to fall back on, and the dark column swallows the browser default. */
.sidebar-action:focus-visible,
.sidebar-logout:focus-visible {
  outline: 2px solid rgba(255, 255, 255, 0.65);
  outline-offset: 1px;
}

/* Sign out is a quiet row in the same column, not a red panel: destructive
   colour is held back for the hover, where the intent is being confirmed. */
.sidebar-logout {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-top: 2px;
  padding: 6px 10px;
  background: none;
  border: 0;
  border-radius: 6px;
  color: var(--nav-text-dim);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.005em;
  cursor: pointer;
  text-align: left;
  transition: background var(--transition), color var(--transition);
}
.sidebar-logout:hover {
  background: rgba(255,120,120,0.12);
  color: #ffb4b4;
  text-decoration: none;
}

/* ─── CHANGE PASSWORD MODAL ───────────────────────────── */
.cp-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(23,52,74,0.5);
  backdrop-filter: blur(3px);
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--transition), visibility var(--transition);
}
.cp-modal-overlay.open {
  opacity: 1;
  visibility: visible;
}
.cp-modal {
  background: var(--bg-secondary);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  width: 100%;
  max-width: 420px;
  margin: 16px;
}
.cp-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--border);
}
.cp-modal-header h3 { font-size: 16px; font-weight: 600; }
.cp-modal-close {
  background: none;
  border: none;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  color: var(--text-secondary);
  padding: 0 4px;
}
.cp-modal-close:hover { color: var(--text-primary); }
.cp-modal-body { padding: 20px; }
.cp-modal-body .form-group { margin-bottom: 14px; }
.cp-modal-body .form-group label { display: block; font-size: 13px; font-weight: 500; margin-bottom: 5px; }
.cp-hint { font-weight: 400; color: var(--text-secondary); font-size: 12px; }
.cp-modal-alert {
  padding: 10px 14px;
  border-radius: 8px;
  font-size: 13px;
  margin-bottom: 10px;
}
.cp-modal-alert.is-error { background: rgba(231,76,60,0.1); color: var(--danger); border: 1px solid rgba(231,76,60,0.25); }
.cp-modal-alert.is-success { background: rgba(39,174,96,0.1); color: var(--success); border: 1px solid rgba(39,174,96,0.25); }
.cp-modal-footer {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  padding-top: 4px;
}

/* ─── MAIN CONTENT ────────────────────────────────────── */
.main-content {
  margin-left: var(--sidebar-w);
  flex: 1;
  /* Without this a flex child will not shrink below its content, so one wide
     table pushed the whole page sideways on a phone instead of scrolling
     inside its own .table-wrap. */
  min-width: 0;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

/* ─── TOP BAR ─────────────────────────────────────────── */
.topbar {
  height: 60px;
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 28px;
  position: sticky;
  top: 0;
  z-index: 50;
}
.topbar-left {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
.topbar-title { font-size: 17px; font-weight: 600; color: var(--text-primary); }
.topbar-actions { display: flex; align-items: center; gap: 14px; }
.mobile-menu-btn {
  display: none;
  width: 40px;
  height: 40px;
  border: 1px solid var(--border);
  background: var(--bg-card);
  border-radius: 10px;
  padding: 0;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 4px;
  cursor: pointer;
  flex-shrink: 0;
}
.mobile-menu-btn span {
  display: block;
  width: 16px;
  height: 2px;
  border-radius: 2px;
  background: var(--text-primary);
}
.notif-btn {
  position: relative;
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: var(--text-secondary);
  width: 38px; height: 38px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px;
  cursor: pointer;
  transition: background var(--transition);
  text-decoration: none;
}
.notif-btn:hover { background: var(--bg-hover); color: var(--text-primary); text-decoration: none; }
.notif-badge {
  position: absolute;
  top: -4px; right: -4px;
  background: var(--danger);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  min-width: 18px; height: 18px;
  border-radius: 9px;
  display: flex; align-items: center; justify-content: center;
  padding: 0 4px;
}

/* ─── PAGE BODY ───────────────────────────────────────── */
.page-body {
  padding: 28px;
  flex: 1;
}

/* ─── APP FOOTER ──────────────────────────────────────── */
.app-footer {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 16px 28px 22px;
  border-top: 1px solid var(--border);
}
.app-footer-label {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-secondary);
}
.app-footer-logo {
  height: 26px;
  width: auto;
  display: block;
}
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 24px;
  flex-wrap: wrap;
  gap: 12px;
}
.page-header h1 { font-size: 22px; font-weight: 700; }
.page-header .subtitle { font-size: 13px; color: var(--text-secondary); margin-top: 2px; }

/* ─── CARDS ───────────────────────────────────────────── */
.card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px;
  box-shadow: var(--shadow);
}
.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  gap: 18px;
  margin-bottom: 28px;
}
.stat-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-left: 3px solid var(--border);
  border-radius: var(--radius);
  padding: 18px 20px;
  display: flex;
  align-items: center;
  gap: 14px;
  box-shadow: 0 1px 2px rgba(15,36,80,0.04);
  transition: transform var(--transition), box-shadow var(--transition);
}
/* Was rgba(0,0,0,0.4) — a near-black drop on a light page. */
.stat-card:hover { transform: translateY(-2px); box-shadow: 0 10px 24px rgba(15,36,80,0.10); }
.stat-card-btn { cursor: pointer; }
.stat-card-btn.stat-card-active {
  outline: 2px solid var(--navy);
  outline-offset: 1px;
  box-shadow: 0 8px 20px rgba(22,51,107,0.14);
}

/*
 * Tinted stat cards. Each tone is that hue washed to ~5% on white, with the
 * border, the 3px rail and the figure carrying it at full strength — enough to
 * tell the four apart at a glance without competing with the navy sidebar or
 * the status badges in the table below. Set per card in views/dashboard.ejs;
 * an untoned .stat-card still renders as the plain white card.
 */
.stat-card.tone-navy  { background: #eef2fa; border-color: #d8e1f1; border-left-color: #2d5fa8; }
.stat-card.tone-amber { background: #fdf5ea; border-color: #f1e3ca; border-left-color: #d18b1f; }
.stat-card.tone-green { background: #ecf6f0; border-color: #d2e7db; border-left-color: #2f8f62; }
.stat-card.tone-violet { background: #f2eff8; border-color: #e1d9ef; border-left-color: #6a55a5; }

.stat-card.tone-navy  .stat-value { color: #1b3f76; }
.stat-card.tone-amber .stat-value { color: #8a5714; }
.stat-card.tone-green .stat-value { color: #1e6b47; }
.stat-card.tone-violet .stat-value { color: #4a3a7a; }

/* On a tinted card the 15%-alpha icon chip muddies into the ground; a white
   chip keeps the glyph crisp and the card's own hue on the rail and figure. */
.stat-card.tone-navy  .stat-icon,
.stat-card.tone-amber .stat-icon,
.stat-card.tone-green .stat-icon,
.stat-card.tone-violet .stat-icon {
  background: #fff;
  box-shadow: inset 0 0 0 1px rgba(15,36,80,0.07);
}
.stat-icon {
  width: 48px; height: 48px;
  border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px;
  flex-shrink: 0;
}
.stat-icon.blue   { background: rgba(79,142,247,0.15); }
.stat-icon.green  { background: rgba(0,200,150,0.15); }
.stat-icon.orange { background: rgba(245,166,35,0.15); }
.stat-icon.red    { background: rgba(240,95,95,0.15); }
.stat-icon.purple { background: rgba(160,100,240,0.15); }
.stat-value { font-size: 27px; font-weight: 700; line-height: 1.15; letter-spacing: -0.02em; }
.stat-label {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: #5c6b7d;
  margin-top: 4px;
}

/* ─── TABLE ───────────────────────────────────────────── */
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; }
.table-wrap table { min-width: 720px; }
thead th {
  text-align: left;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.7px;
  color: var(--text-secondary);
  font-weight: 600;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
tbody td {
  padding: 13px 16px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  font-size: 13.5px;
}
tbody tr:hover { background: var(--bg-hover); }
tbody tr:last-child td { border-bottom: none; }

/* ─── BADGES ──────────────────────────────────────────── */
.badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 20px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.3px;
  text-transform: uppercase;
  white-space: nowrap;
}
.badge-new       { background: rgba(142,68,173,0.15); color: #8e44ad; }
.badge-assigned  { background: rgba(11,95,165,0.15);  color: var(--accent); }
.badge-wo_created { background: rgba(242,140,0,0.15); color: var(--accent2); }
.badge-surveyor_appointed { background: rgba(9,132,227,0.15); color: #0984e3; }
.badge-vcvr_drafted { background: rgba(225,112,85,0.15); color: #e17055; }
.badge-vcvr_review { background: rgba(253,203,110,0.2); color: #e67e22; }
.badge-vcvr_final { background: rgba(39,174,96,0.15); color: var(--success); }
.badge-wo_closed { background: rgba(39,174,96,0.15); color: var(--success); }
.badge-draft     { background: rgba(119,119,119,0.15); color: var(--text-secondary); }
.badge-under_review { background: rgba(242,140,0,0.15); color: var(--accent2); }
/* QC signed off, waiting for the laboratory manager to finalize. */
.badge-qc_approved { background: rgba(9,132,227,0.15); color: #0984e3; }
.badge-revision  { background: rgba(231,76,60,0.15); color: var(--danger); }
.badge-final     { background: rgba(39,174,96,0.15); color: var(--success); }
.badge-open      { background: rgba(11,95,165,0.15); color: var(--accent); }
.badge-sent      { background: rgba(242,140,0,0.15); color: var(--accent2); }
.badge-paid      { background: rgba(39,174,96,0.15); color: var(--success); }
.badge-outstanding { background: rgba(214,158,46,0.18); color: #b7791f; }
.badge-cancelled { background: rgba(231,76,60,0.15); color: var(--danger); }
.badge-success   { background: rgba(39,174,96,0.15); color: var(--success); }
.badge-inactive  { background: rgba(119,119,119,0.15); color: var(--text-secondary); }

/* ─── BUTTONS ─────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 9px 18px;
  border-radius: 8px;
  font-size: 13.5px;
  font-weight: 500;
  border: none;
  cursor: pointer;
  transition: all var(--transition);
  white-space: nowrap;
  text-decoration: none;
}
.btn-primary {
  background: var(--accent);
  color: #fff;
}
.btn-primary:hover { background: var(--accent-dark); text-decoration: none; color: #fff; }
.btn-success {
  background: var(--success);
  color: #fff;
}
.btn-success:hover { filter: brightness(0.9); text-decoration: none; color: #fff; }
.btn-danger {
  background: var(--danger);
  color: #fff;
}
.btn-danger:hover { filter: brightness(0.9); text-decoration: none; color: #fff; }
.btn-warning {
  background: var(--warning);
  color: #fff;
}
.btn-warning:hover { filter: brightness(0.9); text-decoration: none; color: #fff; }
.btn-outline {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-secondary);
}
.btn-outline:hover { background: var(--bg-hover); color: var(--text-primary); text-decoration: none; }
.btn-sm { padding: 6px 12px; font-size: 12px; border-radius: 6px; }

/* Icon inside a .btn — sized so the label, not the glyph, sets the
   button height. Always the first child, never after the label. */
.btn-icon { width: 16px; height: 16px; flex: none; }
/* Excel green on the glyph only: the button itself stays a secondary
   outline so a utility never outweighs the page's primary action. */
.btn-icon-excel { color: #217346; }
/* The quietest button in the system, for entries that lead somewhere
   destructive. It carries no danger colour at rest — that would shout —
   and only turns red on hover/focus, once the pointer is committed. */
.btn-quiet-danger {
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-secondary);
}
.btn-quiet-danger:hover,
.btn-quiet-danger:focus-visible {
  background: rgba(231, 76, 60, 0.08);
  border-color: rgba(231, 76, 60, 0.28);
  color: var(--danger);
  text-decoration: none;
}

/* ─── PAGE ACTION BAR ─────────────────────────────────────
   One left-aligned toolbar under the page title holding every page-level
   action, ordered by weight: primary → utilities → trash/archive. Page
   actions live here and nowhere else, so there is a single place to scan.

   Grouping is done with space, not rules. Primary and secondary read as one
   cluster; only the destructive group gets a divider, because one line in a
   toolbar carries meaning while a line between every group is just noise. */
.page-actionbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 20px;
}
/* The heading gives up part of its own bottom margin rather than the toolbar
   pulling itself up with a negative one. Without :has() the heading keeps its
   24px — a touch looser, never broken. */
.page-header:has(+ .page-actionbar) { margin-bottom: 16px; }

.page-actionbar .action-group {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* Separation for the trash entry: a divider plus a wide gutter, so it is not
   hit by reflex on the way to a neighbouring button. Scoped to a group that
   actually follows another one — a role that saw only this group would
   otherwise get a rule with nothing to its left. */
.page-actionbar .action-group + .action-group-danger {
  margin-left: 8px;
  padding-left: 20px;
  border-left: 1px solid var(--border);
}

/* One optical box for every button in the bar, whatever its variant: height
   set outright rather than accumulated from padding, and a 1px border on all
   of them (transparent where the variant has none) so a filled button and an
   outlined one do not sit a pixel off each other. 36x14 is the toolbar size —
   the base .btn 9px/18px is tuned for standalone buttons and reads oversized
   in a row of three. */
.page-actionbar .btn {
  height: 36px;
  padding: 0 14px;
  gap: 8px;
  border: 1px solid transparent;
  border-radius: 8px;
  font-size: 13.5px;
  line-height: 1;
}
/* The SVGs carry stroke-width="2"; CSS outranks a presentation attribute, and
   2 is heavy beside 13.5px text at a 16px glyph. */
.page-actionbar .btn-icon { stroke-width: 1.75; }

/* Primary — the only filled button on the page. A 1px lift, not a glow. */
.page-actionbar .btn-primary { box-shadow: 0 1px 2px rgba(16, 24, 40, 0.10); }
.page-actionbar .btn-primary:hover { box-shadow: 0 2px 6px rgba(16, 24, 40, 0.14); }

/* Secondary — readable, not decorative. The shared .btn-outline is tuned for
   small in-table buttons: --text-secondary on a --border edge is too faint for
   a page-level action at this size. */
.page-actionbar .btn-outline {
  background: var(--bg-secondary);
  border-color: #d5dde7;
  color: var(--text-primary);
}
.page-actionbar .btn-outline:hover {
  background: var(--bg-hover);
  border-color: #c3cedb;
}

.page-actionbar .btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ─── INPUT UNIT SUFFIX ───────────────────────────────────
   A unit sitting at the right edge of a field ("KG" on the weight inputs).

   Drawn as a positioned sibling rather than appended to the value: the field
   still submits the bare number, and the numeric input filter that strips
   everything but digits never has to know the unit exists.

   The input keeps its full width and gains right padding, so a long figure
   scrolls under the unit instead of colliding with it. */
.input-suffix {
  position: relative;
  display: block;
}
.input-suffix > input {
  width: 100%;
  padding-right: 44px;
}
.input-suffix-text {
  position: absolute;
  top: 50%;
  right: 12px;
  transform: translateY(-50%);
  color: var(--text-secondary);
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1;
  /* Clicks fall through to the input underneath, so tapping the unit focuses
     the field rather than doing nothing. */
  pointer-events: none;
}

/* ─── FORMS ───────────────────────────────────────────── */
.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px 24px;
}
.form-grid.cols-1 { grid-template-columns: 1fr; }
.form-grid.cols-3 { grid-template-columns: 1fr 1fr 1fr; }
.form-group { display: flex; flex-direction: column; gap: 6px; }
.form-group.full { grid-column: 1 / -1; }
label {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
input[type=text], input[type=email], input[type=password],
input[type=date], input[type=time], input[type=number],
input[type=tel], select, textarea {
  background: var(--bg-primary);
  border: 1px solid var(--border);
  color: var(--text-primary);
  border-radius: 8px;
  padding: 9px 13px;
  font-size: 13.5px;
  font-family: inherit;
  outline: none;
  transition: border-color var(--transition);
  width: 100%;
}
/*
 * Edge — and Chrome on Windows — draws its own reveal eye inside a password field.
 * Every password input here already sits next to a #togglePassword button (see
 * views/login.ejs and views/users/form.ejs), so the native control shows up as a
 * second eye beside ours. Hidden, leaving one: ours, which is the one that also
 * swaps the open/struck-through icon and keeps aria-label in step.
 */
input[type=password]::-ms-reveal,
input[type=password]::-ms-clear {
  display: none;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(79,142,247,0.1);
}
select option { background: var(--bg-card); }
textarea { resize: vertical; min-height: 80px; }
.form-check { display: flex; align-items: center; gap: 8px; cursor: pointer; }
.form-check input[type=checkbox] {
  width: 16px; height: 16px;
  accent-color: var(--accent);
  cursor: pointer;
}
.section-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.8px;
  margin: 28px 0 16px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
  grid-column: 1 / -1;
}

/* ─── ALERTS ──────────────────────────────────────────── */
.alert {
  padding: 12px 16px;
  border-radius: 8px;
  font-size: 13.5px;
  margin-bottom: 16px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.alert-error   { background: rgba(240,95,95,0.1);   border: 1px solid rgba(240,95,95,0.25);   color: #f8a0a0; }
.alert-success { background: rgba(46,199,107,0.1);  border: 1px solid rgba(46,199,107,0.25);  color: #7ee5a2; }
.alert-info    { background: rgba(79,142,247,0.1);  border: 1px solid rgba(79,142,247,0.25);  color: #9cc4f9; }
.alert-warning { background: rgba(245,166,35,0.1);  border: 1px solid rgba(245,166,35,0.25);  color: #f9ce7a; }

/* ─── EMPTY STATE ─────────────────────────────────────── */
.empty-state {
  text-align: center;
  padding: 60px 20px;
  color: var(--text-secondary);
}
.empty-state .empty-icon { font-size: 48px; margin-bottom: 12px; opacity: 0.4; }
.empty-state h3 { font-size: 16px; color: var(--text-primary); margin-bottom: 6px; }
.empty-state p { font-size: 13px; }

/* ─── TIMELINE ────────────────────────────────────────── */
.timeline { list-style: none; position: relative; padding-left: 24px; }
.timeline::before {
  content: '';
  position: absolute;
  left: 8px; top: 0; bottom: 0;
  width: 2px;
  background: var(--border);
}
.timeline-item { position: relative; margin-bottom: 20px; }
.timeline-dot {
  position: absolute;
  left: -20px; top: 4px;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--bg-primary);
}
.timeline-content { font-size: 13px; }
.timeline-time { font-size: 11px; color: var(--text-secondary); margin-top: 2px; }

/* ─── PHOTO GRID ──────────────────────────────────────── */
.photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 12px;
  margin-top: 16px;
}
.photo-item {
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg-primary);
}
.photo-item img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
}
.photo-label {
  padding: 6px 8px;
  font-size: 11px;
  color: var(--text-secondary);
  text-align: center;
}

/* ─── LOGIN PAGE ──────────────────────────────────────── */
.login-layout {
  display: flex;
  min-height: 100vh;
}
.login-hero {
  flex: 1;
  background:
    linear-gradient(120deg, rgba(23,52,74,.92), rgba(11,95,165,.88)),
    url("../images/hero.jpg") center/cover;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
  color: white;
  padding: 60px;
}
/* .login-hero::after {
  content: "";
  position: absolute;
  top: 50%;
  right: -100px;
  transform: translateY(-50%);
  width: 300px;
  height: 300px;
  background: url("../images/logo-ils.png") no-repeat center;
  background-size: contain;
  opacity: 0.06;
  pointer-events: none;
} */
.login-hero .hero-content {
  max-width: 600px;
  z-index: 1;
}
.login-hero h1 {
  font-size: 3.2rem;
  font-weight: 800;
  margin-bottom: 16px;
  line-height: 1.2;
}
.login-hero p {
  font-size: 1.2rem;
  opacity: 0.9;
}
.btn-warning-hero {
  background: var(--accent2);
  color: white;
  border: none;
  font-weight: 600;
  padding: 14px 35px;
  border-radius: 50px;
  display: inline-block;
  margin-top: 30px;
  text-decoration: none;
  transition: opacity var(--transition);
}
.btn-warning-hero:hover {
  opacity: 0.9;
  color: white;
  text-decoration: none;
}
.login-form-container {
  width: 500px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-primary);
  padding: 20px;
}
@media(max-width: 900px){
  .login-hero { display: none; }
  .login-form-container { width: 100%; }
}
.login-box {
  width: 100%;
  max-width: 400px;
  padding: 48px 40px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow: var(--shadow);
}
.login-logo {
  text-align: center;
  margin-bottom: 32px;
}
.login-logo .brand {
  font-size: 26px;
  font-weight: 800;
  background: linear-gradient(90deg, var(--accent), var(--accent2));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}
.login-logo .tagline { font-size: 12px; color: var(--text-secondary); margin-top: 4px; }
.login-box h2 { font-size: 18px; font-weight: 700; margin-bottom: 4px; }
.login-box .sub { font-size: 13px; color: var(--text-secondary); margin-bottom: 24px; }
.btn-login {
  width: 100%;
  padding: 11px;
  background: linear-gradient(90deg, var(--accent), var(--accent-dark));
  color: #fff;
  border: none;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  transition: opacity var(--transition);
  margin-top: 4px;
}
.btn-login:hover { opacity: 0.9; }

/* ─── PAGINATION ──────────────────────────────────────── */
.pagination { display: flex; gap: 6px; margin-top: 20px; align-items: center; }
.pagination a, .pagination span {
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 13px;
  border: 1px solid var(--border);
  color: var(--text-secondary);
  transition: background var(--transition);
}
.pagination a:hover { background: var(--bg-hover); text-decoration: none; color: var(--text-primary); }
.pagination .active { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ─── PUBLIC VCVR PAGE ────────────────────────────────── */
.public-page {
  min-height: 100vh;
  background: var(--bg-primary);
  padding: 40px 20px;
}
.public-card {
  max-width: 800px;
  margin: 0 auto;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 16px;
  overflow: hidden;
}
.public-header {
  background: linear-gradient(135deg, var(--accent-dark), var(--accent));
  padding: 28px 32px;
  border-bottom: 1px solid var(--border);
}

@media (max-width: 1024px) {
  :root {
    --sidebar-w: 195px;
  }
  .page-body {
    padding: 20px;
  }
  .card {
    padding: 20px;
  }
  .form-grid,
  .form-grid.cols-3 {
    grid-template-columns: 1fr;
  }
}

/* ─── RESPONSIVE ──────────────────────────────────────── */
@media (max-width: 768px) {
  .sidebar {
    width: min(86vw, 320px);
    max-width: 320px;
    transform: translateX(-100%);
    box-shadow: 0 12px 36px rgba(0,0,0,0.18);
  }
  .sidebar.open { transform: translateX(0); }
  .main-content { margin-left: 0; }
  .mobile-menu-btn {
    display: inline-flex;
  }
  .topbar {
    height: auto;
    min-height: 60px;
    padding: 10px 16px;
  }
  .topbar-title {
    font-size: 16px;
    line-height: 1.3;
    word-break: break-word;
  }
  .page-body {
    padding: 16px;
  }
  .page-header {
    align-items: flex-start;
  }
  .page-header h1 {
    font-size: 20px;
  }
  .page-header .flex,
  .page-header > div:last-child {
    width: 100%;
    flex-wrap: wrap;
  }
  /* Primary claims its own full-width row — the one action worth a whole row
     on a phone; the utilities and the trash entry share the row under it,
     still left-aligned and still divided from each other. */
  .page-actionbar { margin: 0 0 16px; }
  .page-header:has(+ .page-actionbar) { margin-bottom: 12px; }
  /* 36px is a comfortable pointer target but a tight thumb one. */
  .page-actionbar .btn { height: 40px; }
  .page-actionbar .action-group-primary { flex: 1 1 100%; }
  .page-actionbar .action-group-primary .btn { flex: 1 1 auto; justify-content: center; }
  .page-actionbar .action-group + .action-group-danger {
    margin-left: 4px;
    padding-left: 12px;
  }
  .card {
    padding: 16px;
    border-radius: 10px;
  }
  .stat-grid { grid-template-columns: 1fr; }
  .stat-card { padding: 16px; }
  .btn {
    white-space: normal;
    justify-content: center;
    text-align: center;
  }
  .btn-sm {
    width: 100%;
  }
  .action-btns {
    width: 100%;
  }
  .action-btns .btn {
    width: 100%;
  }
  .pagination {
    flex-wrap: wrap;
  }
  .timeline {
    padding-left: 20px;
  }
  .photo-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  [style*="grid-template-columns:2fr 1fr"],
  [style*="grid-template-columns:1fr 1fr"],
  [style*="grid-template-columns:2fr 1fr 1fr 1fr 0.5fr 1fr"] {
    grid-template-columns: 1fr !important;
  }
  [style*="width:100%; max-width:500px;"] {
    max-width: 100% !important;
  }
  [style*="margin-left:8px"],
  [style*="margin-left:6px"] {
    margin-left: 0 !important;
  }
  .nav-item {
    padding: 10px 10px;
    gap: 11px;
    font-size: 14.5px;
  }
  .nav-title {
    font-size: 14.5px;
  }
  .nav-subtitle {
    font-size: 11.5px;
  }
  /* Both account rows grow to the same touch target — a 6px-tall row is not one. */
  .sidebar-action,
  .sidebar-logout { padding: 10px; font-size: 14px; }
  .sidebar-user { padding: 9px 10px; }
  .table-wrap {
    margin-inline: -16px;
    padding-inline: 16px;
  }
}

@media (max-width: 480px) {
  .page-body {
    padding: 12px;
  }
  .topbar {
    padding: 10px 12px;
  }
  .card {
    padding: 14px;
  }
  .photo-grid {
    grid-template-columns: 1fr;
  }
  .notif-btn,
  .mobile-menu-btn {
    width: 36px;
    height: 36px;
  }
  .table-wrap {
    margin-inline: -12px;
    padding-inline: 12px;
  }
}

/* ─── UTILITIES ───────────────────────────────────────── */
.mt-4  { margin-top: 16px; }
.mt-6  { margin-top: 24px; }
.mb-4  { margin-bottom: 16px; }
.mb-6  { margin-bottom: 24px; }
.gap-2 { gap: 8px; }
.flex  { display: flex; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.flex-wrap { flex-wrap: wrap; }
.text-sm { font-size: 12px; }
.text-muted { color: var(--text-secondary); }
.font-bold { font-weight: 700; }
.action-btns { display: flex; gap: 6px; flex-wrap: wrap; }
