/* ============================================================================
   AQOON shell stylesheet
   ----------------------------------------------------------------------------
   Extracted from templates/base.html so the ~18 KB of shell CSS is downloaded
   ONCE and cached (versioned via ?v=APP_VERSION) instead of re-sent on every
   page. Load order: bootstrap.min.css -> this file -> the tiny dynamic
   <style> block in base.html (school theme colours from Settings).

   COLOR SYSTEM
   ------------
   All colours flow through semantic role tokens, defined for BOTH light and
   dark mode. Never hard-code a hex in templates — use the tokens:

     --app-bg     page background            --ink       primary text
     --surface    cards / sidebar / topbar   --muted     secondary text
     --surface-2  inset panels, table heads  --line      borders / dividers
     --primary    school brand colour (== --kaah, from Settings)
     --accent     school secondary  (== --kia-green, from Settings)
     --ok / --warn / --danger / --info   status roles (calm, desaturated)

   The palette is intentionally CALM: desaturated slate neutrals and muted
   status hues for long working sessions; the school brand colour is reserved
   for primary actions and active navigation so attention lands where it should.
   ========================================================================== */

:root{
  /* neutral roles — light */
  --app-bg:#f3f5f8;
  --surface:#ffffff;
  --surface-2:#f7f9fb;
  --line:#e3e9ef;
  --ink:#22304a;
  --muted:#64748b;
  /* sidebar (slightly tinted so the shell reads as one calm unit) */
  --sb-bg:#eceff3;
  --sb-line:#dde4ea;
  --sb-hover:#e0e7ed;
  --sb-sub-bg:#f3f6f8;
  /* status roles — desaturated for comfort; Bootstrap contextual classes are
     re-tuned to these below so Success/Warning/Danger/Info are consistent. */
  --ok:#2e8b57;
  --ok-soft:#e4f3ea;
  --warn:#c07f10;
  --warn-soft:#fdf3dd;
  --danger:#c0392b;
  --danger-soft:#fbe9e7;
  --info:#2471a3;
  --info-soft:#e7f1f8;
  /* focus ring follows the brand colour at low alpha (fallback first for
     older browsers without color-mix) */
  --focus-ring:rgba(244,123,32,.25);
  --focus-ring:color-mix(in srgb, var(--kaah, #1A2B6D) 30%, transparent);
}
[data-bs-theme="dark"]{
  --app-bg:#0f141b;
  --surface:#1a212b;
  --surface-2:#141a22;
  --line:#2b3542;
  --ink:#e6edf3;
  --muted:#93a1b0;
  --sb-bg:#1a212b;
  --sb-line:#2b3542;
  --sb-hover:#222c38;
  --sb-sub-bg:#141a22;
  --ok:#5cb884;
  --ok-soft:rgba(46,139,87,.18);
  --warn:#e0a63f;
  --warn-soft:rgba(224,166,63,.16);
  --danger:#e07b6d;
  --danger-soft:rgba(192,57,43,.20);
  --info:#6aa5cc;
  --info-soft:rgba(36,113,163,.18);
  /* Align Bootstrap's dark surfaces with ours so cards/menus/tables match the
     custom shell instead of Bootstrap's default near-black. */
  --bs-body-bg:var(--app-bg);
  --bs-body-color:var(--ink);
  --bs-border-color:var(--line);
  --bs-secondary-color:var(--muted);
  --bs-secondary-bg:var(--surface-2);
  --bs-tertiary-bg:var(--surface-2);
}

/* ---------------------------------------------------------------- shell -- */
body{ background:var(--app-bg); color:var(--ink); }
/* 100dvh (not vh): on mobile browsers 100vh is TALLER than the visible area
   (URL bar), which pushed the last menu items out of reach. overscroll-behavior
   stops a finished sidebar scroll from "chaining" into the page behind it. */
.sidebar{ width:248px; height:100vh; height:100dvh; background:var(--sb-bg); position:fixed; top:0; left:0; overflow-y:auto; overscroll-behavior:contain; border-right:1px solid var(--sb-line); transition:transform .2s ease; z-index:1030; padding-bottom:calc(16px + env(safe-area-inset-bottom, 0px)); }
body.sidebar-hidden .sidebar{ transform:translateX(-100%); }
body.sidebar-hidden .content{ margin-left:0; }
.sidebar-toggle{ border:none; background:var(--app-bg); color:var(--ink); font-size:1.3rem; line-height:1; padding:6px 10px; border-radius:8px; cursor:pointer; }
.sidebar-toggle:hover{ background:var(--sb-hover); }
.sidebar::-webkit-scrollbar{ width:8px; }
.sidebar::-webkit-scrollbar-thumb{ background:#c2ccd4; border-radius:4px; }
[data-bs-theme="dark"] .sidebar::-webkit-scrollbar-thumb{ background:#3a4553; }
.sidebar .brand{ padding:14px 16px; font-weight:700; color:var(--ink); background:var(--surface); border-bottom:1px solid var(--sb-line); display:flex; align-items:center; gap:10px; position:sticky; top:0; z-index:2; }
.sidebar .brand img{ width:38px; height:38px; }
.sidebar .brand span{ font-size:.92rem; line-height:1.1; }
.sidebar a.nav-link{ color:var(--ink); padding:11px 18px; font-weight:600; font-size:.93rem; border-bottom:1px solid var(--sb-line); display:flex; align-items:center; gap:12px; }
.sidebar a.nav-link:hover{ background:var(--sb-hover); }
.sidebar a.nav-link.active{ background:#E8EBF7; background:color-mix(in srgb, var(--kaah,#1A2B6D) 14%, var(--surface)); color:var(--kaah-dark,#111F52); }
[data-bs-theme="dark"] .sidebar a.nav-link{ color:#c4cfda; }
[data-bs-theme="dark"] .sidebar a.nav-link.active{ background:rgba(244,123,32,.18); color:#fbbf77; }
.sidebar a.nav-link i{ font-size:1.05rem; width:20px; }
.sidebar a.nav-link.sub{ padding-left:42px; font-size:.86rem; font-weight:500; background:var(--sb-sub-bg); color:var(--muted); }
.sidebar a.nav-link.sub:hover{ background:var(--sb-hover); }
.sidebar a.nav-link.sub.active{ background:var(--ok-soft); color:var(--kia-green-dark,#B8860B); border-left:3px solid var(--kia-green,#F2C230); }
[data-bs-theme="dark"] .sidebar a.nav-link.sub{ color:#a9b6c3; }
[data-bs-theme="dark"] .sidebar a.nav-link.sub.active{ background:rgba(109,190,69,.16); color:#a7e08a; }
.sidebar a.nav-link.sub i{ font-size:.7rem; }
.sidebar a.nav-link.grp[aria-expanded="true"] .bi-chevron-down{ transform:rotate(180deg); }

/* Sidebar type-to-filter (input in base.html, logic in app.js). Sticky just
   below the brand block (67px tall) so it stays put while the menu scrolls.
   16px font prevents iOS from zooming the page when the field gets focus. */
/* Collapsed by default (0 height, no border). It slides in when the sidebar is
   scrolled — see initSidebarFilter() — or when it has focus/typed text. */
.sb-filter{ position:sticky; top:67px; z-index:2; background:var(--sb-bg);
            max-height:0; padding:0 12px; opacity:0; overflow:hidden; border-bottom:0 solid var(--sb-line);
            transition:max-height .2s ease, opacity .2s ease, padding .2s ease; }
.sb-filter.revealed{ max-height:60px; padding:8px 12px; opacity:1; border-bottom-width:1px; }
.sb-filter input{ font-size:16px; }
/* While filtering, every group is forced open so matches inside collapsed
   groups are visible; the chevrons are meaningless in that state. */
.sidebar.filtering .collapse{ display:block !important; }
.sidebar.filtering a.grp .bi-chevron-down{ visibility:hidden; }

/* Pinned pages (app.js): user-starred quick links rendered above the groups. */
#sbPinned .sb-pin-head{ padding:8px 18px 2px; font-size:.68rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--muted); }
#sbPinned a.nav-link.sub{ padding-left:18px; background:transparent; }
#sbPinned a.nav-link.sub i{ color:var(--kia-green-dark,#B8860B); font-size:.85rem; }
[data-bs-theme="dark"] #sbPinned a.nav-link.sub i{ color:#fbbf77; }
.sidebar .sb-pin{ margin-left:auto; opacity:0; padding:2px 6px; cursor:pointer; transition:opacity .12s ease; }
.sidebar a.nav-link.sub:hover .sb-pin{ opacity:.65; }
.sidebar .sb-pin:hover{ opacity:1 !important; }
/* Touch screens have no hover — keep the pin faintly visible so it exists. */
@media (hover:none){ .sidebar .sb-pin{ opacity:.3; } }

/* App-shell: the topbar is PINNED and only .page scrolls, so the header stays
   put and the screen always fits the viewport (100dvh handles mobile browser
   chrome). overflow-x:hidden on .page prevents horizontal page scrolling. */
.content{ margin-left:248px; padding:0; transition:margin-left .2s ease; height:100vh; height:100dvh; display:flex; flex-direction:column; }
.topbar{ background:var(--surface); border-bottom:1px solid var(--line); padding:12px 24px; display:flex; justify-content:space-between; align-items:center; flex:0 0 auto; z-index:1020; }
.page{ padding:24px; flex:1 1 auto; overflow-y:auto; overflow-x:hidden; }
.page-title{ font-weight:700; color:var(--ink); }

/* ------------------------------------------------------------- surfaces -- */
.card{ border:none; box-shadow:0 1px 3px rgba(15,23,42,.06); border-radius:12px; }
[data-bs-theme="dark"] .card{ background-color:var(--surface); box-shadow:0 1px 3px rgba(0,0,0,.35); }
[data-bs-theme="dark"] .dropdown-menu{ background-color:var(--surface); border-color:var(--line); }
[data-bs-theme="dark"] .modal-content{ background-color:var(--surface); }
.stat-card{ border:none; border-radius:12px; color:#fff; }
[data-bs-theme="dark"] .stat-card{ filter:saturate(.85) brightness(.9); }
.table thead th{ background:var(--surface-2); font-size:.82rem; text-transform:uppercase; letter-spacing:.03em; color:var(--muted); }
[data-bs-theme="dark"] .table thead th{ background:#212a35; }
[data-bs-theme="dark"] .list-group-item{ background-color:transparent; color:var(--ink); }

/* ----------------------------------------------------- brand components -- */
.btn-brand{ background:var(--kaah,#1A2B6D); color:#fff; }
.btn-brand:hover, .btn-brand:focus{ background:var(--kaah-dark,#111F52); color:#fff; }
.nav-pills .nav-link.active{ background:var(--kaah,#1A2B6D); }
.nav-pills .nav-link{ color:var(--kaah-dark,#111F52); }
[data-bs-theme="dark"] .nav-pills .nav-link{ color:#fbbf77; }
.session-badge{ background:var(--ok-soft); color:var(--kia-green-dark,#B8860B); border:1px solid #F2E4B4; border-color:color-mix(in srgb, var(--kia-green,#F2C230) 40%, transparent); padding:3px 10px; border-radius:20px; font-size:.8rem; font-weight:600; }
[data-bs-theme="dark"] .session-badge{ color:#a7e08a; }
.btn:focus-visible, .form-control:focus, .form-select:focus{ box-shadow:0 0 0 .25rem var(--focus-ring); }

/* ----------------------------------------------------------- dark: fixes -- */
/* Action icon buttons (Edit / Delete / View use .btn-light) — Bootstrap keeps
   .btn-light light in dark mode, which glares. Re-tone to the surface scale. */
[data-bs-theme="dark"] .btn-light{
  --bs-btn-bg:var(--surface-2);
  --bs-btn-color:var(--ink);
  --bs-btn-border-color:var(--line);
  --bs-btn-hover-bg:#232e3a;
  --bs-btn-hover-color:var(--ink);
  --bs-btn-hover-border-color:var(--line);
  --bs-btn-active-bg:#26303d;
  --bs-btn-active-color:var(--ink);
  --bs-btn-active-border-color:var(--line);
  --bs-btn-disabled-bg:var(--surface-2);
  --bs-btn-disabled-color:var(--muted);
  --bs-btn-disabled-border-color:var(--line);
}
[data-bs-theme="dark"] .btn-light.text-danger{ color:var(--danger)!important; }
[data-bs-theme="dark"] .btn-light.text-success{ color:var(--ok)!important; }
[data-bs-theme="dark"] .btn-outline-secondary{ --bs-btn-color:var(--muted); --bs-btn-border-color:var(--line); --bs-btn-hover-bg:var(--surface-2); --bs-btn-hover-color:var(--ink); --bs-btn-hover-border-color:var(--line); }
/* Hard-coded light utility surfaces used across pages. */
[data-bs-theme="dark"] .bg-white{ background-color:var(--surface)!important; color:var(--ink); }
[data-bs-theme="dark"] .bg-light{ background-color:var(--surface-2)!important; color:var(--ink); }
[data-bs-theme="dark"] .border{ border-color:var(--line)!important; }
[data-bs-theme="dark"] .text-dark{ color:var(--ink)!important; }
[data-bs-theme="dark"] .text-secondary{ color:var(--muted)!important; }
[data-bs-theme="dark"] .input-group-text.bg-white{ background-color:var(--surface-2)!important; color:var(--muted); border-color:var(--line); }
[data-bs-theme="dark"] .topbar .bg-white{ background:var(--surface-2)!important; color:var(--ink); }
[data-bs-theme="dark"] .topbar .bi-bell{ color:#c4cfda!important; }
/* "-subtle" chips/badges — force readable text on the darkened backgrounds. */
[data-bs-theme="dark"] .bg-warning-subtle{ background-color:var(--warn-soft)!important; border-color:rgba(224,166,63,.4)!important; }
[data-bs-theme="dark"] .bg-warning-subtle.text-dark, [data-bs-theme="dark"] .bg-warning-subtle .text-dark{ color:#fcd980!important; }
[data-bs-theme="dark"] .bg-info-subtle.text-dark, [data-bs-theme="dark"] .bg-success-subtle.text-dark,
[data-bs-theme="dark"] .bg-secondary-subtle.text-dark, [data-bs-theme="dark"] .bg-primary-subtle.text-dark,
[data-bs-theme="dark"] .bg-danger-subtle.text-dark{ color:var(--ink)!important; }
[data-bs-theme="dark"] .badge.bg-light.text-dark{ color:#cbd5e1!important; }
[data-bs-theme="dark"] .badge.bg-info.text-dark, [data-bs-theme="dark"] .badge.bg-warning.text-dark{ color:#10151c!important; }
[data-bs-theme="dark"] .fw-bold.text-secondary{ color:var(--ink)!important; }
[data-bs-theme="dark"] .alert-info{ background:var(--info-soft); color:#bcd9ee; border-color:rgba(106,165,204,.35); }
[data-bs-theme="dark"] .alert-success{ background:var(--ok-soft); color:#bfe6cf; border-color:rgba(92,184,132,.35); }
[data-bs-theme="dark"] .alert-warning{ background:var(--warn-soft); color:#f2d9a4; border-color:rgba(224,166,63,.35); }
[data-bs-theme="dark"] .alert-danger{ background:var(--danger-soft); color:#f0b9b1; border-color:rgba(224,123,109,.35); }
/* QR / photos keep a white matte so scanners and print stay reliable. */
[data-bs-theme="dark"] img.qr-matte, [data-bs-theme="dark"] .keep-white{ background:#fff!important; }
/* Dashboard "needs attention" hover + ws-card active tint. */
[data-bs-theme="dark"] .action-item:hover{ background:#222c38!important; }
[data-bs-theme="dark"] .ws-card.active{ background:rgba(244,123,32,.12)!important; }
/* Quill editor: the page around it darkens, the "paper" stays white on purpose
   (letters are printed documents); the toolbar joins the dark surface. */
[data-bs-theme="dark"] .ql-toolbar.ql-snow{ background:var(--surface-2)!important; border-color:var(--line)!important; }
[data-bs-theme="dark"] .ql-toolbar.ql-snow .ql-stroke{ stroke:var(--muted); }
[data-bs-theme="dark"] .ql-toolbar.ql-snow .ql-fill{ fill:var(--muted); }
[data-bs-theme="dark"] .ql-toolbar.ql-snow .ql-picker-label{ color:var(--muted); }
[data-bs-theme="dark"] .ql-container.ql-snow{ border-color:var(--line)!important; }
/* Theme toggle icon swap (topbar button AND the mobile profile-menu item) */
[data-bs-theme="dark"] .theme-toggle .bi-sun-fill{ display:inline; }
[data-bs-theme="dark"] .theme-toggle .bi-moon-stars-fill{ display:none; }
.theme-toggle .bi-sun-fill{ display:none; }
.theme-toggle .bi-moon-stars-fill{ display:inline; }
/* Menu-item label follows the same swap: light mode offers "Dark mode", etc. */
.theme-toggle .tt-to-light{ display:none; }
[data-bs-theme="dark"] .theme-toggle .tt-to-light{ display:inline; }
[data-bs-theme="dark"] .theme-toggle .tt-to-dark{ display:none; }

/* ------------------------------------------------------- table utilities -- */
/* Sticky header: add .table-sticky to a table inside a scroll container. */
.table-sticky thead th{ position:sticky; top:0; z-index:5; }
/* Sticky first column for wide matrices (result grid / fee status / timetable):
   add .table-sticky-col to the table; first cell of each row pins left. */
.table-sticky-col th:first-child, .table-sticky-col td:first-child{
  position:sticky; left:0; z-index:4; background:var(--surface);
  box-shadow:2px 0 4px rgba(15,23,42,.06);
}
.table-sticky-col thead th:first-child{ z-index:6; background:var(--surface-2); }
/* Long-text columns that should wrap even under the mobile nowrap default. */
.table td.cell-wrap, .table th.cell-wrap{ white-space:normal!important; min-width:220px; }

/* --------------------------------------------------------------- toasts -- */
#appToasts{ position:fixed; right:16px; bottom:16px; z-index:2000; display:flex; flex-direction:column; gap:8px; }
#appToasts .app-toast{ background:var(--surface); color:var(--ink); border:1px solid var(--line); border-left:4px solid var(--ok); border-radius:10px; box-shadow:0 6px 24px rgba(15,23,42,.18); padding:10px 14px; min-width:240px; max-width:360px; font-size:.9rem; opacity:0; transform:translateY(6px); transition:opacity .18s ease, transform .18s ease; }
#appToasts .app-toast.show{ opacity:1; transform:none; }
#appToasts .app-toast.t-danger{ border-left-color:var(--danger); }
#appToasts .app-toast.t-warning{ border-left-color:var(--warn); }
#appToasts .app-toast.t-info{ border-left-color:var(--info); }

/* ------------------------------------------------------ htmx navigation -- */
/* Thin brand-coloured progress bar while a partial navigation is in flight. */
#navProgress{ position:fixed; top:0; left:0; height:3px; width:0; background:var(--kaah,#1A2B6D); z-index:3000; opacity:0; transition:width .25s ease, opacity .3s ease; }
html.htmx-nav-active #navProgress{ opacity:1; width:70%; }

/* ------------------------------------------------- mobile responsiveness -- */
.sidebar-backdrop{ display:none; position:fixed; inset:0; background:rgba(0,0,0,.45); z-index:1040; }
@media (max-width: 991.98px){
  .content{ margin-left:0 !important; }
  .sidebar{ z-index:1045; box-shadow:12px 0 40px rgba(0,0,0,.35); }
  body:not(.sidebar-hidden) .sidebar-backdrop{ display:block; overscroll-behavior:contain; touch-action:none; }
  /* While the drawer is open, the page behind it must not scroll — otherwise a
     finger that drifts off the sidebar scrolls the page and the menu "sticks". */
  body:not(.sidebar-hidden) .page{ overflow-y:hidden; }
  .topbar{ padding:10px 12px; gap:6px; }
  .page{ padding:14px; }
  .tbl-scroll{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
  .nav-pills{ flex-wrap:wrap; gap:.25rem; }
  .nav-pills .nav-link{ padding:.4rem .7rem; }
  .btn{ min-height:44px; }
  .btn-sm, .btn-group-sm > .btn{ min-height:38px; }
  .table td, .table th{ white-space:nowrap; }
  /* Mobile search: the expanding topbar search (see base.html + app.js). */
  .mobile-search-btn{ display:inline-block; }
  /* Bottom tab bar: one-thumb access to the daily pages. The page and the
     toasts get extra bottom clearance so nothing hides behind it. */
  .bottomnav{ position:fixed; left:0; right:0; bottom:0; z-index:1035; display:flex; background:var(--surface); border-top:1px solid var(--line); padding-bottom:env(safe-area-inset-bottom, 0px); box-shadow:0 -2px 12px rgba(15,23,42,.08); }
  .bottomnav .bn-item{ flex:1 1 0; display:flex; flex-direction:column; align-items:center; gap:2px; padding:8px 4px 6px; font-size:.62rem; font-weight:600; color:var(--muted); text-decoration:none; border:none; background:none; }
  .bottomnav .bn-item i{ font-size:1.25rem; line-height:1; }
  .bottomnav .bn-item.active{ color:var(--kaah,#1A2B6D); }
  [data-bs-theme="dark"] .bottomnav .bn-item.active{ color:#fbbf77; }
  .page{ padding-bottom:calc(76px + env(safe-area-inset-bottom, 0px)); }
  #appToasts{ bottom:calc(72px + env(safe-area-inset-bottom, 0px)); }
}
@media (min-width: 992px){ .bottomnav{ display:none; } }
@media (min-width: 992px){ .mobile-search-btn{ display:none; } }
@media (max-width: 575.98px){
  .page{ padding:10px; }
  .page-title{ font-size:1.05rem; }
  .topbar{ padding:8px 10px; }
  .stat-card h3, .stat-card .display-6{ font-size:1.4rem; }
}

/* ----------------------------------- universal small-screen hardening ---- */
/* Works down to the narrowest phones (~320px) and up. The rules keep content
   inside the viewport on ANY pixel width instead of relying on fixed sizes. */
@media (max-width: 991.98px){
  /* Never let the page scroll sideways, whatever a child tries to do. */
  html, body{ max-width:100%; overflow-x:hidden; }
  /* Flex/grid children shrink instead of forcing horizontal overflow. */
  .content, .topbar, .page, .card, .card-body, .row, .d-flex{ min-width:0; }
  #pageHeading{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  /* Media and code blocks stay inside their container. */
  img, svg, video, canvas{ max-width:100%; height:auto; }
  pre, code{ white-space:pre-wrap; word-break:break-word; }
  /* Toasts must fit a 320px screen. */
  #appToasts{ left:12px; right:12px; }
  #appToasts .app-toast{ min-width:0; max-width:100%; }
  /* Long words/emails/urls wrap rather than push the layout wide. */
  td, th, .card-body{ overflow-wrap:anywhere; }
}
@media (max-width: 360px){
  .btn{ padding-left:.5rem; padding-right:.5rem; }
  .page-title{ font-size:1rem; }
  .topbar{ gap:4px; }
}

/* ------------------------------------------------- attendance fast path -- */
/* Row tint follows the selected status; tap/click a row to cycle. */
#attTable tr.att-row{ cursor:pointer; }
#attTable tr.att-present td{ background:var(--ok-soft); }
#attTable tr.att-absent td{ background:var(--danger-soft); }
#attTable tr.att-late td{ background:var(--warn-soft); }
#attTable tr.att-holiday td{ background:var(--info-soft); }
#attTable tr.att-flash td{ transition:none; filter:brightness(.92); }
#attTable tr.att-focus td{ outline:2px solid var(--kaah,#1A2B6D); outline-offset:-2px; }
#attTable .att-chip{ text-transform:capitalize; color:var(--muted); }
#attTable input[type=radio]{ width:1.15em; height:1.15em; }
@media (max-width: 991.98px){
  /* Bigger touch targets & a save bar that stays reachable while scrolling. */
  #attTable input[type=radio]{ width:1.6em; height:1.6em; }
  #attTable td.att-cell{ padding-top:.8rem; padding-bottom:.8rem; }
  .att-savebar{ position:sticky; bottom:8px; z-index:10; }
  .att-savebar .btn{ box-shadow:0 6px 18px rgba(15,23,42,.25); }
}

/* --------------------------------------------------------------- print -- */
@media print{
  .content{ height:auto !important; display:block !important; margin-left:0 !important; }
  .page{ overflow:visible !important; height:auto !important; padding:0 !important; }
  .sidebar, .sidebar-backdrop, .topbar, #appToasts, #navProgress, .bottomnav{ display:none !important; }
}
