:root {
  --primary: #1f3864;
  --primary-dark: #16294a;
  --primary-soft: #eef2f8;
  --bg: #f3f5f8;
  --card-border: #e5e8ed;
  --text: #16181d;
  --muted: #667085;
  --shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.05);
  --shadow-md: 0 2px 8px rgba(16, 24, 40, 0.06), 0 1px 2px rgba(16, 24, 40, 0.04);
  --shadow-lg: 0 12px 32px rgba(16, 24, 40, 0.12), 0 2px 6px rgba(16, 24, 40, 0.06);
  --radius: 12px;
  --radius-sm: 8px;
  /* Admin-adjustable appearance (Settings -> Appearance). Defaults here so
     the app renders correctly before config loads and on the login screen. */
  --logo-size-sidebar: 48px;
  --logo-size-topbar: 30px;
  --present-bg: #0f9d6e;
  --present-fg: #ffffff;
  --absent-bg: #c0392b;
  --absent-fg: #ffffff;
}

* { box-sizing: border-box; }
html { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 14px;
  line-height: 1.45;
  /* Nothing in this app should ever scroll the whole page sideways. If a
     single wide element (a table, a long unbroken email address) escapes
     its container, this contains the damage to that element instead of
     letting it shift the entire layout and leave the user panning left
     and right to read anything. */
  overflow-x: hidden;
}

/* Long unbroken strings -- guardian emails, admission numbers, pasted
   URLs, message-template placeholders -- were the main source of text
   spilling out of cards on narrow screens. Break them rather than let
   them set a minimum width their container can't honour. */
p, span, div, td, th, li, strong, label, h1, h2, h3, h4 { overflow-wrap: break-word; word-break: break-word; }
/* Flex and grid children default to min-width:auto, which means they
   refuse to shrink below their content -- the single most common cause
   of "why is this pushing off screen". */
.row > *, .main-col > *, .side-col > * { min-width: 0; }
img { max-width: 100%; }

/* ---------- Shell / sidebar layout ---------- */
.shell { min-height: 100vh; display: flex; }
.sidebar {
  width: 264px; flex-shrink: 0; background: linear-gradient(180deg, var(--primary) 0%, var(--primary-dark) 100%); color: #fff;
  display: flex; flex-direction: column; position: sticky; top: 0; height: 100vh;
  box-shadow: var(--shadow-lg);
  z-index: 40;
  transition: transform 0.22s ease;
}
.brand-text { min-width: 0; }
/* The in-drawer close button and the topbar hamburger are both desktop
   no-ops -- the sidebar is permanent there, so offering to close it would
   strand the user with no navigation. Revealed at the drawer breakpoint. */
.sidebar-close { display: none; margin-left: auto; flex-shrink: 0; }
.nav-toggle { display: none; color: var(--text); flex-shrink: 0; }
.nav-backdrop {
  position: fixed; inset: 0; background: rgba(16, 24, 40, 0.45);
  z-index: 35; border: none; padding: 0;
  animation: nav-fade 0.18s ease;
}
@keyframes nav-fade { from { opacity: 0; } to { opacity: 1; } }
.sidebar-brand { display: flex; align-items: center; gap: 12px; padding: 22px 20px; border-bottom: 1px solid rgba(255,255,255,0.12); }
.brand-logo {
  width: var(--logo-size-sidebar); height: var(--logo-size-sidebar); border-radius: 12px; object-fit: contain; background: #ffffff; padding: 6px;
  flex-shrink: 0; border: 1px solid rgba(255,255,255,.35); box-shadow: 0 1px 4px rgba(0,0,0,.18);
  box-shadow: 0 2px 6px rgba(0,0,0,0.18), 0 0 0 1px rgba(0,0,0,0.04);
  flex-shrink: 0;
}
.brand-logo-fallback {
  display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 20px;
  background: #ffffff; color: var(--primary);
}
.brand-name { font-size: 15.5px; font-weight: 700; line-height: 1.25; letter-spacing: -0.01em; }
.brand-sub { font-size: 11.5px; opacity: 0.72; margin-top: 1px; letter-spacing: 0.01em; }
.sidebar-nav { flex: 1; padding: 14px 12px; display: flex; flex-direction: column; gap: 3px; overflow-y: auto; }
.nav-item {
  display: flex; align-items: center; gap: 11px; background: transparent; border: none; color: rgba(255,255,255,0.78);
  padding: 10px 13px; border-radius: var(--radius-sm); cursor: pointer; font-size: 13.5px; text-align: left;
  transition: background 0.12s ease, color 0.12s ease; font-weight: 500;
}
.nav-item:hover { background: rgba(255,255,255,0.1); color: #fff; }
.nav-item.active { background: #fff; color: var(--primary); font-weight: 700; box-shadow: var(--shadow-sm); }
.nav-subitems { display: flex; flex-direction: column; gap: 1px; margin: 2px 0 6px 0; }
.nav-subitem {
  background: transparent; border: none; color: rgba(255,255,255,0.62); cursor: pointer;
  text-align: left; padding: 7px 13px 7px 42px; font-size: 12.5px; border-radius: var(--radius-sm);
  transition: background .12s ease, color .12s ease;
}
.nav-subitem:hover { background: rgba(255,255,255,0.08); color: #fff; }
.nav-subitem.active { background: rgba(255,255,255,0.16); color: #fff; font-weight: 700; }

.sidebar-user { display: flex; align-items: center; gap: 10px; padding: 16px 18px; border-top: 1px solid rgba(255,255,255,0.12); }
.user-avatar {
  width: 34px; height: 34px; border-radius: 999px; background: rgba(255,255,255,0.18); display: flex; align-items: center;
  justify-content: center; font-weight: 700; font-size: 13.5px; flex-shrink: 0; box-shadow: 0 0 0 1px rgba(255,255,255,0.15) inset;
}
.user-meta { flex: 1; min-width: 0; }
.user-name { font-size: 12.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.user-role { font-size: 11px; opacity: 0.68; text-transform: capitalize; }
.icon-btn { background: transparent; border: none; color: rgba(255,255,255,0.75); cursor: pointer; padding: 7px; border-radius: 7px; display: flex; transition: background 0.12s ease; }
.icon-btn:hover { background: rgba(255,255,255,0.14); color: #fff; }

.main-area {
  flex: 1; min-width: 0; max-width: 1480px;
  /* Padding is a variable so the sticky topbar can cancel it out with
     matching negative margins at every breakpoint. Previously both were
     hardcoded to 28/32px, so any responsive padding change silently broke
     the topbar's full-bleed alignment. */
  --pad-x: 32px;
  --pad-y: 28px;
  padding: var(--pad-y) var(--pad-x);
}
.topbar {
  display: flex; justify-content: flex-end; align-items: center; gap: 12px;
  margin: calc(var(--pad-y) * -1) calc(var(--pad-x) * -1) 20px;
  padding: 10px var(--pad-x);
  background: #fff; border-bottom: 1px solid var(--card-border);
  position: sticky; top: 0; z-index: 30;
  min-height: 52px;
}
/* Shows the current section on small screens, where the sidebar (and so
   the highlighted nav item) is hidden behind the drawer. */
.topbar-left { display: flex; align-items: center; gap: 10px; margin-right: auto; min-width: 0; }
.topbar-logo {
  width: var(--logo-size-topbar); height: var(--logo-size-topbar); border-radius: 7px; object-fit: contain; background: #fff; padding: 3px;
  flex-shrink: 0; border: 1px solid #e4e7ec;
  box-shadow: 0 0 0 1px var(--card-border); flex-shrink: 0;
}
.topbar-logo-fallback { display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 15px; background: var(--primary-soft); color: var(--primary); }
.topbar-title { font-weight: 700; font-size: 14px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.live-clock { display: flex; align-items: baseline; gap: 10px; font-variant-numeric: tabular-nums; }
.live-clock-date { font-size: 12.5px; color: var(--muted); }
.live-clock-time { font-size: 15px; font-weight: 700; color: var(--primary); letter-spacing: 0.3px; }
@media print { .topbar { display: none; } }

.content { display: grid; grid-template-columns: 1fr 340px; gap: 22px; align-items: start; }
.content-full { display: block; }
.main-col { min-width: 0; }
.side-col { min-width: 0; }

/* ---------- Cards / forms / buttons ---------- */
.card {
  background: #fff; border: 1px solid var(--card-border); border-radius: var(--radius); padding: 20px 22px; margin-bottom: 16px;
  box-shadow: var(--shadow-sm); transition: box-shadow 0.15s ease;
}
.card h3 { margin: 0 0 12px; font-size: 15px; font-weight: 700; color: var(--text); letter-spacing: -0.01em; }
.row { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
.muted { color: var(--muted); font-size: 12.5px; }
.badge {
  display: inline-flex; align-items: center; font-size: 11px; padding: 4px 10px; border-radius: 999px; font-weight: 700;
  letter-spacing: 0.01em; text-transform: uppercase; white-space: nowrap;
}
.badge.present { background: #dcf5ea; color: #067a4e; }
.badge.absent { background: #fce4e4; color: #b3261e; }
.badge.pending { background: #fbedd4; color: #8a5a05; }
.badge.leave { background: #e8e5fd; color: #4c3fc7; }
.badge.unmarked { background: #eeeef0; color: #51525c; }
button.btn {
  background: var(--primary); color: #fff; border: none; padding: 8.5px 16px; border-radius: var(--radius-sm); cursor: pointer;
  font-size: 12.5px; font-weight: 600; display: inline-flex; align-items: center; gap: 6px;
  box-shadow: 0 1px 2px rgba(16,24,40,0.08); transition: background 0.12s ease, box-shadow 0.12s ease, transform 0.05s ease;
}
button.btn:hover:not(:disabled) { background: var(--primary-dark); box-shadow: var(--shadow-md); }
button.btn:active:not(:disabled) { transform: translateY(1px); }
button.btn.secondary { background: #fff; color: var(--primary); border: 1px solid #d5dbe4; box-shadow: none; }
button.btn.secondary:hover:not(:disabled) { background: var(--primary-soft); border-color: var(--primary); }
button.btn:disabled { opacity: 0.5; cursor: not-allowed; }
button.btn.ghost { background: transparent; color: var(--muted); border: 1px solid #dfe2e8; box-shadow: none; }
input, select, textarea {
  border: 1px solid #d5dbe4; border-radius: var(--radius-sm); padding: 8.5px 11px; font-size: 13px; width: 100%;
  font-family: inherit; transition: border-color 0.12s ease, box-shadow 0.12s ease; background: #fff;
}
input[type="checkbox"], input[type="radio"] {
  width: 16px; height: 16px; padding: 0; flex-shrink: 0; accent-color: var(--primary); cursor: pointer;
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-soft);
}
label.field-label { font-size: 12px; font-weight: 600; color: #444a58; display: block; margin: 10px 0 5px; letter-spacing: 0.01em; }

.login-wrap {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  background: radial-gradient(circle at 20% 20%, rgba(255,255,255,0.08), transparent 45%),
              linear-gradient(160deg, var(--primary) 0%, var(--primary-dark) 100%);
  padding: 24px;
}
.login-card {
  background: #fff; padding: 36px 34px; border-radius: 18px; width: 360px; max-width: 100%; box-shadow: var(--shadow-lg);
}
.login-brand { display: flex; flex-direction: column; align-items: center; text-align: center; margin-bottom: 22px; }
.login-logo {
  width: 76px; height: 76px; border-radius: 18px; object-fit: contain; background: #fff; padding: 8px;
  box-shadow: var(--shadow-md), 0 0 0 1px var(--card-border); margin-bottom: 14px;
}
.login-logo-fallback {
  width: 76px; height: 76px; border-radius: 18px; display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 30px; background: var(--primary-soft); color: var(--primary); margin-bottom: 14px;
}
.login-card h2 { margin: 0; color: var(--text); font-size: 19px; font-weight: 700; letter-spacing: -0.01em; }
.login-card .muted { margin-top: 4px; }
.error-text { color: #b3261e; font-size: 12.5px; margin-top: 6px; font-weight: 500; }
.notif-feed { max-height: 70vh; overflow-y: auto; }
.notif-item { border-bottom: 1px solid #f1f2f4; padding: 10px 0; font-size: 12.5px; }
.notif-item:last-child { border-bottom: none; }
.notif-item .time { color: #98a1b1; font-size: 11px; }
.notif-item .chan { font-weight: 700; margin-right: 6px; color: var(--primary); }
.demo-list { list-style: none; padding: 0; margin: 0; font-size: 12px; color: #555; display: flex; flex-direction: column; gap: 6px; }
.demo-list li { padding: 0; }

/* ---------- Dashboard ---------- */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 14px; margin-bottom: 18px; }
.kpi {
  background: #fff; border: 1px solid var(--card-border); border-radius: var(--radius); padding: 16px 18px;
  border-left: 4px solid var(--primary); box-shadow: var(--shadow-sm); transition: box-shadow 0.15s ease, transform 0.1s ease;
}
.kpi:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
.kpi-value { font-size: 26px; font-weight: 800; color: var(--text); line-height: 1.1; letter-spacing: -0.02em; }
.kpi-label { font-size: 12px; color: var(--muted); margin-top: 5px; font-weight: 500; }
.kpi-present { border-left-color: #0f9d6e; }
.kpi-absent { border-left-color: #c0392b; }
.kpi-leave { border-left-color: #6c5ce7; }
.kpi-pending { border-left-color: #d68910; }
.dash-grid { display: grid; grid-template-columns: 1.3fr 1fr; gap: 18px; }
@media (max-width: 900px) { .dash-grid { grid-template-columns: 1fr; } }
.activity-feed { max-height: 320px; overflow-y: auto; }
.activity-item { font-size: 12.5px; padding: 8px 0; border-bottom: 1px solid #f1f2f4; }
.activity-item:last-child { border-bottom: none; }
.activity-item .time { color: #98a1b1; }

/* ---------- Tables ---------- */
/* Wraps every table. A report with 7 columns cannot shrink to 375px, so
   the table scrolls sideways inside its own card rather than widening the
   page. -webkit-overflow-scrolling gives iOS momentum scrolling. */
.table-wrap {
  width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch;
  /* Hint that there is more content to the right on touch devices. */
  scrollbar-width: thin;
}
.data-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.table-wrap .data-table { min-width: 520px; }
.data-table th, .data-table td { text-align: left; padding: 10px 10px; border-bottom: 1px solid #f1f2f4; }
.data-table th {
  color: var(--muted); font-weight: 700; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em;
  background: #fafbfc; position: sticky; top: 0;
}
.data-table tbody tr { transition: background 0.1s ease; }
.data-table tbody tr:hover { background: #fafbfc; }

/* ---------- Pagination ---------- */
.pagination {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap; justify-content: center;
  padding: 14px 0 4px; margin-top: 4px;
}
.pagination-info { font-size: 12.5px; color: var(--muted); font-weight: 600; min-width: 100px; text-align: center; }
.pagination-goto { display: flex; align-items: center; gap: 6px; margin-left: 8px; }
.pagination-goto input { width: 74px; padding: 7px 9px; }
/* Attendance Present/Absent actions -- colours are admin-configurable so
   staff can match whatever convention the institute already uses. */
/* Attendance actions are the highest-frequency tap targets in the app --
   a teacher hits them dozens of times per class -- so they get a larger
   footprint and a deliberate gap so present/absent can't be mis-tapped. */
.attend-actions { margin-top: 14px; display: flex; gap: 22px; flex-wrap: wrap; align-items: center; }
button.btn.attend-btn { padding: 13px 26px; font-size: 14.5px; font-weight: 700; min-height: 48px; min-width: 150px; justify-content: center; border-radius: 10px; }
@media (max-width: 640px) { .attend-actions { gap: 14px; } button.btn.attend-btn { flex: 1 1 44%; min-width: 0; padding: 13px 12px; } }
button.btn.attend-present { background: var(--present-bg); color: var(--present-fg); border-color: var(--present-bg); }
button.btn.attend-absent { background: var(--absent-bg); color: var(--absent-fg); border-color: var(--absent-bg); }
button.btn.attend-present:hover:not(:disabled), button.btn.attend-absent:hover:not(:disabled) { filter: brightness(0.92); }

/* ---------- Searchable dropdown ---------- */
.ss-root { position: relative; width: 100%; }
.ss-trigger {
  width: 100%; display: flex; align-items: center; gap: 8px; justify-content: space-between;
  border: 1px solid #d5dbe4; border-radius: var(--radius-sm); padding: 8.5px 11px;
  background: #fff; font-size: 13px; font-family: inherit; cursor: pointer; text-align: left;
  min-height: 38px; color: var(--text);
}
.ss-trigger:hover:not(:disabled) { border-color: #b9c2ce; }
.ss-trigger:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-soft); }
.ss-disabled .ss-trigger { opacity: .55; cursor: not-allowed; }
.ss-value { display: flex; align-items: center; gap: 8px; min-width: 0; overflow: hidden; }
.ss-label-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ss-placeholder { color: #98a1b1; }
.ss-sub { color: var(--muted); font-weight: 400; }
.ss-caret { color: var(--muted); flex-shrink: 0; font-size: 11px; }
.ss-thumb { width: 22px; height: 22px; border-radius: 5px; object-fit: cover; flex-shrink: 0; }

.ss-menu {
  position: absolute; z-index: 50; top: calc(100% + 4px); left: 0; right: 0;
  background: #fff; border: 1px solid var(--card-border); border-radius: 10px;
  box-shadow: var(--shadow-lg); overflow: hidden;
}
.ss-search { padding: 8px; border-bottom: 1px solid #f1f2f4; }
.ss-search input { font-size: 13px; padding: 8px 10px; }
.ss-count {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 5px 10px; font-size: 11px; color: var(--muted); background: #fafbfc;
  border-bottom: 1px solid #f1f2f4; font-weight: 600;
}
.ss-clear { background: none; border: none; color: var(--primary); font-size: 11px; font-weight: 700; cursor: pointer; padding: 0; }
.ss-list { max-height: 260px; overflow-y: auto; }
.ss-empty { padding: 14px 12px; font-size: 12.5px; color: var(--muted); text-align: center; }
.ss-option {
  width: 100%; display: flex; align-items: center; gap: 9px; text-align: left;
  background: none; border: none; cursor: pointer; padding: 8px 11px; font-family: inherit;
  border-bottom: 1px solid #f6f7f9;
}
.ss-option:last-child { border-bottom: none; }
.ss-option.hl { background: var(--primary-soft); }
.ss-option.sel { font-weight: 700; }
.ss-opt-text { display: flex; flex-direction: column; min-width: 0; }
.ss-opt-label { font-size: 13px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ss-opt-sub { font-size: 11.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Full-height list is unusable on a phone keyboard; cap it tighter. */
@media (max-width: 640px) { .ss-list { max-height: 210px; } }

/* ---------- Modal confirm + toasts ---------- */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(16,24,40,.5); z-index: 60;
  display: flex; align-items: center; justify-content: center; padding: 20px;
  animation: nav-fade .15s ease;
}
.modal-card {
  background: #fff; border-radius: 14px; box-shadow: var(--shadow-lg);
  width: 460px; max-width: 100%; padding: 22px 24px;
}
.modal-title { margin: 0 0 8px; font-size: 16.5px; font-weight: 700; }
.modal-body { font-size: 13.5px; color: #3a3f4b; line-height: 1.55; white-space: pre-line; }
.modal-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; flex-wrap: wrap; }
button.btn.danger { background: #b3261e; border-color: #b3261e; }
button.btn.danger:hover:not(:disabled) { background: #8f1e18; }

.toast-stack {
  position: fixed; right: 18px; bottom: 18px; z-index: 70;
  display: flex; flex-direction: column; gap: 8px; align-items: flex-end;
  pointer-events: none;
}
.toast {
  padding: 11px 16px; border-radius: 10px; font-size: 13px; font-weight: 600;
  box-shadow: var(--shadow-lg); max-width: 380px;
  animation: toast-in .18s ease;
}
.toast-success { background: #0f6e56; color: #fff; }
.toast-error { background: #b3261e; color: #fff; }
@keyframes toast-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@media (max-width: 640px) {
  .toast-stack { right: 10px; left: 10px; bottom: 10px; align-items: stretch; }
  .toast { max-width: 100%; }
}

.save-bar { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; position: sticky; bottom: 10px; }
.save-bar .btn { margin-left: auto; }
@media (max-width: 640px) { .save-bar .btn { margin-left: 0; width: 100%; } }

/* Settings sub-tabs */
.settings-tabs { display: flex; gap: 6px; flex-wrap: wrap; }
.settings-tab {
  background: #fff; border: 1px solid #d5dbe4; color: var(--muted); cursor: pointer;
  padding: 8px 14px; border-radius: 999px; font-size: 12.5px; font-weight: 600;
  white-space: nowrap; transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.settings-tab:hover { background: var(--primary-soft); color: var(--primary); }
.settings-tab.active { background: var(--primary); border-color: var(--primary); color: #fff; }

.pagination-size { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--muted); font-weight: 600; white-space: nowrap; }
.pagination-size select { width: auto; padding: 7px 9px; }

/* ---------- Report sheet ---------- */
.report-header { display: flex; gap: 18px; align-items: flex-start; flex-wrap: wrap; }
.report-photo { width: 88px; height: 88px; border-radius: var(--radius-sm); object-fit: cover; box-shadow: var(--shadow-sm); }

@media print {
  .sidebar, .no-print, .nav-backdrop, .topbar { display: none !important; }
  .table-wrap { overflow: visible; }
  .table-wrap .data-table { min-width: 0; }
  .main-area { padding: 0; max-width: 100%; }
  .content, .content-full { display: block; }
  .card { border: none; box-shadow: none; padding: 8px 0; margin-bottom: 10px; page-break-inside: avoid; }
  body { background: #fff; }
}

/* ---------- Signature capture (gate passes) ---------- */
.sig-panel { border-top: 1px solid var(--border, #eceff3); margin-top: 12px; padding-top: 10px; }
.sig-panel-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.sig-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 10px; }
.sig-slot {
  border: 1px solid #e4e7ec; border-radius: 10px; padding: 10px;
  display: flex; flex-direction: column; gap: 6px; background: #fcfcfd; min-width: 0;
}
.sig-slot.signed { background: #f4fbf8; border-color: #cfe9df; }
.sig-slot-label { font-size: 12px; font-weight: 700; overflow-wrap: anywhere; }
.sig-slot-empty { font-size: 12px; color: var(--muted, #98a1b1); font-style: italic; }
/* The stored PNG is wider than it is tall; contain keeps the whole signature
   visible in the tile instead of cropping the end of someone's name. */
.sig-slot-image {
  width: 100%; height: 54px; object-fit: contain; background: #fff;
  border: 1px solid #e4e7ec; border-radius: 6px;
}
.sig-slot-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.sig-slot-actions .btn, .sig-slot .btn { padding: 5px 10px; font-size: 12px; }
/* The pad breaks out of its grid cell: a signature box constrained to a
   210px tile is too small to sign in on a phone. */
.sig-slot-pad {
  grid-column: 1 / -1; margin-top: 8px; padding-top: 10px;
  border-top: 1px dashed #d0d5dd;
}
.danger-text { color: #b42318; }

.sigpad-canvas {
  display: block; width: 100%; height: 150px; background: #fff;
  border: 1px solid #c8cdd6; border-radius: 8px; cursor: crosshair;
  /* Without this a finger stroke scrolls the page instead of drawing. */
  touch-action: none;
}
.sigpad-actions { display: flex; align-items: center; gap: 10px; margin: 6px 0 4px; }
.sigpad-footer { display: flex; gap: 8px; margin-top: 10px; }
.sigpad-footer .btn { flex: 0 0 auto; }

/* ---------- Leave desk: pass + cancel bars ---------- */
.leave-passbar {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex-wrap: wrap; margin-top: 10px; padding: 10px 12px;
  background: #f6f8fb; border: 1px solid #e7ebf1; border-radius: 10px;
}
.leave-cancelbar { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 8px; }
.leave-cancelrow { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.leave-cancelrow input { flex: 1 1 240px; min-width: 0; }

/* ---------- Sidebar collapse (desktop) ----------
   On a desktop the hamburger now genuinely hides the sidebar instead of
   doing nothing. width:0 + overflow rather than display:none so the CSS
   transition gives a slide, not a jump. */
@media (min-width: 1025px) {
  .sidebar { transition: margin-left .18s ease; }
  .sidebar.collapsed { margin-left: -264px; }
  .sidebar-close { display: inline-flex; }
}

/* ---------- Bulk list management (Academic setup) ---------- */
.bulk-bar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  background: #f2f6fc; border: 1px solid #d7e3f4; border-radius: 10px;
  padding: 8px 12px; margin: 10px 0;
}
.bulk-bar select { height: 34px; }
.bulk-add {
  background: #f8f9fb; border: 1px solid #eceff3; border-radius: 10px;
  padding: 12px 14px; margin-top: 10px;
}
.bulk-add textarea { width: 100%; font-family: inherit; font-size: 14px; padding: 8px; border-radius: 8px; border: 1px solid #d0d5dd; resize: vertical; }
.data-table tr.row-selected td { background: #eef4fd; }

.linklike {
  background: none; border: none; padding: 0; font: inherit; cursor: pointer;
  color: var(--primary); font-weight: 700; text-align: left;
}
.linklike:hover { text-decoration: underline; }

.feed-pager { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 8px; }
.feed-pager .btn { padding: 4px 12px; font-size: 12px; }

/* ---------- Notification feed delivery status ---------- */
.notif-item.notif-failed { border-left: 3px solid #b42318; padding-left: 8px; border-radius: 0; }
.notif-status {
  display: inline-block; font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; padding: 1px 6px; border-radius: 4px; margin-left: 4px; vertical-align: 1px;
}
.notif-status-failed { background: #fceaea; color: #b42318; }
.notif-status-simulated { background: #eef1f6; color: #475467; }
.notif-error { font-size: 11.5px; color: #b42318; margin-top: 3px; overflow-wrap: anywhere; }

/* ---------- Printed gate pass ----------
   Sized for a single A4 page: the header, details table, six signature
   boxes and the re-entry section all have to fit without a page break
   splitting a signature away from its label. */
.gp-sheet { color: #16181d; font-size: 12.5px; }

.gp-header { display: flex; align-items: center; gap: 14px; padding-bottom: 10px; border-bottom: 2px solid #16181d; }
.gp-logo { width: 62px; height: 62px; object-fit: contain; flex-shrink: 0; }
.gp-header-text { flex: 1; min-width: 0; }
.gp-school { margin: 0; font-size: 19px; line-height: 1.2; }
.gp-address { font-size: 11px; color: #475467; line-height: 1.45; white-space: pre-line; }
.gp-photo { width: 68px; height: 68px; object-fit: cover; border: 1px solid #98a1b1; flex-shrink: 0; }

.gp-title {
  display: flex; align-items: center; justify-content: space-between;
  margin: 10px 0; font-size: 15px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
}
.gp-code { font-size: 15px; font-weight: 800; border: 1.5px solid #16181d; padding: 2px 10px; letter-spacing: .06em; }
.gp-void { border: 2px solid #b42318; color: #b42318; font-weight: 700; text-align: center; padding: 6px 10px; margin: 0 0 10px; }

.gp-details { width: 100%; border-collapse: collapse; margin-bottom: 14px; }
.gp-details th, .gp-details td { border: 1px solid #c8cdd6; padding: 5px 8px; text-align: left; vertical-align: top; }
.gp-details th { background: #f2f4f7; font-size: 10.5px; text-transform: uppercase; letter-spacing: .03em; color: #475467; width: 92px; font-weight: 700; }
.gp-details td { font-weight: 600; overflow-wrap: anywhere; }

.gp-section-title {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  color: #475467; margin-bottom: 8px;
}
.gp-section-note { text-transform: none; letter-spacing: 0; font-weight: 400; }

.gp-sig-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px 16px; margin-bottom: 12px; }
.gp-sig { page-break-inside: avoid; break-inside: avoid; }
/* Fixed height whether signed or not, so signed and unsigned boxes line up
   in the grid instead of the row jumping around. */
.gp-sig-box { height: 44px; display: flex; align-items: flex-end; }
.gp-sig-img { max-height: 44px; max-width: 100%; object-fit: contain; }
.gp-sig-placeholder { display: block; height: 44px; }
.gp-sig-rule { border-bottom: 1px solid #16181d; }
.gp-sig-role { font-size: 11px; font-weight: 700; margin-top: 3px; }
.gp-sig-meta { font-size: 9.5px; color: #667085; line-height: 1.4; }

.gp-exit-line { border: 1px solid #c8cdd6; padding: 7px 10px; font-size: 11.5px; margin-bottom: 12px; }

.gp-reentry { border: 1.5px solid #16181d; padding: 10px 12px; page-break-inside: avoid; break-inside: avoid; }
.gp-reentry-body { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: end; }
.gp-reentry-time { padding-top: 44px; }

.gp-footer { font-size: 10px; color: #667085; margin-top: 12px; line-height: 1.5; }

@media print {
  .gp-sheet { font-size: 11.5px; }
  /* The pass is one page by definition -- it is handed over as a single
     sheet, and a signature orphaned onto page two is worthless. */
  .gp-sheet, .gp-header, .gp-details { page-break-inside: avoid; }
}

/* =======================================================================
   RESPONSIVE
   Two breakpoints:
     <= 1024px  tablets and small laptops -- the 340px notification rail
                stops fitting beside content, and the sidebar becomes an
                overlay drawer opened from the topbar hamburger.
     <=  640px  phones -- tighter padding, stacked controls, and form rows
                that were side-by-side become full width.
   ======================================================================= */

@media (max-width: 1024px) {
  /* Sidebar leaves the document flow and becomes an off-canvas drawer.
     Without position:fixed it would still reserve its 264px column and
     squeeze the content it is supposed to be revealing. */
  .sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; height: 100dvh;
    transform: translateX(-100%);
  }
  .sidebar.open { transform: translateX(0); }
  .sidebar-close { display: flex; }
  .nav-toggle { display: flex; }
  .topbar { justify-content: flex-start; }

  .main-area { --pad-x: 20px; --pad-y: 20px; max-width: 100%; }

  /* The notification feed drops below the main column instead of fighting
     it for width. */
  .content { grid-template-columns: 1fr; }
  .notif-feed { max-height: 340px; }

  .dash-grid { grid-template-columns: 1fr; }
}

@media (max-width: 640px) {
  /* Bulk action bars: fixed-width selects overflow a phone; full width
     stacks them instead. */
  .bulk-bar { flex-direction: column; align-items: stretch; }
  .bulk-bar select, .bulk-bar .btn { width: 100%; }
  .bulk-bar .btn.ghost { margin-left: 0; }
  .feed-pager .btn { flex: 1; }
  /* The printed pass is also viewable on screen before printing; three
     signature columns are unreadable on a phone. */
  .gp-sig-grid { grid-template-columns: 1fr 1fr; }
  .gp-reentry-body { grid-template-columns: 1fr; }
  .gp-reentry-time { padding-top: 12px; }
  .gp-header { flex-wrap: wrap; }
  /* One signature tile per row on a phone -- two columns squeezes the role
     label into three lines and makes the Sign button hard to hit. */
  .sig-grid { grid-template-columns: 1fr; }
  .sigpad-canvas { height: 170px; }
  .sigpad-footer .btn, .leave-cancelrow .btn { flex: 1 1 auto; }
  .leave-passbar { flex-direction: column; align-items: stretch; }
  .leave-passbar .btn { width: 100%; }

  .main-area { --pad-x: 12px; --pad-y: 14px; }
  .card { padding: 14px 14px; border-radius: 10px; margin-bottom: 12px; }
  .card h3 { font-size: 14px; }

  /* .row is used everywhere as a "title on the left, actions on the right"
     bar. At phone width that produces cramped, awkwardly-split lines, so
     it becomes a normal vertical stack. */
  .row { flex-direction: column; align-items: stretch; gap: 10px; }
  /* Once .row is a column, any inline `flex: 1 1 200px` on a child (used
     throughout the forms to size fields side by side) applies that 200px
     to HEIGHT instead of width -- which rendered the student search box
     as a ~200px-tall empty rectangle. Those inline styles can only be
     overridden with !important, and only inside this breakpoint. */
  .row > * { flex-basis: auto !important; }
  /* Keep genuinely inline groups (button clusters, checkbox + label) from
     being stretched into full-width columns by the rule above. */
  .row > div[style*="display: flex"], .row > div[style*="display:flex"] { flex-wrap: wrap; }

  .kpi-grid { grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); gap: 10px; }
  .kpi { padding: 12px 13px; }
  .kpi-value { font-size: 21px; }
  .kpi-label { font-size: 11.5px; }

  /* Full-width tap targets read better than a row of tiny buttons, and
     44px is the accepted minimum comfortable touch size. */
  button.btn { padding: 10px 14px; font-size: 13px; min-height: 40px; }

  /* 16px prevents iOS Safari from zooming the viewport on focus -- the
     usual cause of "the page jumps when I tap a field on iPhone". */
  input, select, textarea { font-size: 16px; padding: 10px 12px; }

  .topbar { gap: 8px; padding: 8px var(--pad-x); }
  .topbar-title { font-size: 13px; }
  .live-clock { flex-direction: column; align-items: flex-end; gap: 0; line-height: 1.25; }
  .live-clock-date { font-size: 10.5px; }
  .live-clock-time { font-size: 13px; }

  .login-card { padding: 26px 20px; border-radius: 14px; }
  .login-logo, .login-logo-fallback { width: 62px; height: 62px; }

  .pagination { gap: 8px; }
  .pagination-goto { margin-left: 0; }

  .report-header { gap: 12px; }
  .report-photo { width: 64px; height: 64px; }

  .data-table th, .data-table td { padding: 8px 8px; }
  .table-wrap .data-table { min-width: 460px; }

  /* Form field pairs laid out with inline flex:1 styles stack instead of
     splitting a 320px screen into unusable half-columns. */
  .field-pair { flex-direction: column; gap: 0; }
}

/* Very small phones (iPhone SE and similar). */
@media (max-width: 380px) {
  .main-area { --pad-x: 10px; }
  .kpi-grid { grid-template-columns: 1fr 1fr; }
  .brand-name { font-size: 14px; }
}

/* ---------- Topbar icon buttons (hamburger) ----------
   .icon-btn's white colouring is for the dark sidebar; on the white topbar
   it made the menu button invisible. Scoped override wins on specificity. */
.topbar .icon-btn { color: var(--text); }
.topbar .icon-btn:hover { background: var(--primary-soft); color: var(--primary); }
