/* ============================================================
   FRANEJ MONTESSORI ACADEMY — Portal Stylesheet v2
   Role-Based Access | Fully Mobile Responsive
   ============================================================ */
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;800;900&family=DM+Sans:opsz,wght@9..40,300;9..40,400;9..40,500;9..40,600&display=swap');
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
html{-webkit-tap-highlight-color:transparent}

/* ── Design Tokens ───────────────────────────────────────── */
:root{
  --emerald:#059669;--emerald-d:#047857;--emerald-l:#d1fae5;
  --sky:#0284c7;--sky-d:#0369a1;--sky-l:#e0f2fe;
  --amber:#d97706;--amber-l:#fef3c7;
  --violet:#7c3aed;--violet-l:#ede9fe;
  --rose:#e11d48;--rose-l:#ffe4e6;
  --teal:#0d9488;--teal-l:#ccfbf1;
  --orange:#ea580c;--orange-l:#ffedd5;
  --primary:var(--emerald);--primary-d:var(--emerald-d);--primary-l:var(--emerald-l);
  --primary-glow:rgba(5,150,105,.10);
  --bg:#f1f5f4;--surface:#fff;--surface-2:#f7f9f8;--surface-3:#eef2f0;
  --border:#d4ddd9;--text:#172b22;--text-muted:#5e7a6e;
  --sidebar-bg:#0f2d1e;--sidebar-text:#c8dcd3;--sidebar-muted:#7aab94;
  --sidebar-active-bg:rgba(5,150,105,.25);--sidebar-active:#6ee7b7;
  --sidebar-hover:rgba(255,255,255,.06);
  --sidebar-w:272px;--header-h:60px;
  --radius:12px;--radius-lg:18px;--radius-xl:24px;
  --shadow:0 4px 16px rgba(0,0,0,.06);--shadow-md:0 8px 28px rgba(0,0,0,.10);
  --transition:.18s ease;
}
body.dark{
  --bg:#0b1a12;--surface:#12211a;--surface-2:#182c22;--surface-3:#1f3a2c;
  --border:#2e4a3a;--text:#e8f7ef;--text-muted:#a8ccba;
  --primary-glow:rgba(52,211,153,.12);
}

/* ── Base ── */
body{font-family:'DM Sans',sans-serif;background:var(--bg);color:var(--text);font-size:15px;transition:background var(--transition),color var(--transition);overflow-x:hidden}
a{color:inherit;text-decoration:none}
button{font-family:inherit;cursor:pointer}
img{display:block;max-width:100%}

/* ── App Loader ── */
#app-loader{position:fixed;inset:0;background:var(--sidebar-bg);display:flex;align-items:center;justify-content:center;flex-direction:column;gap:20px;z-index:9999;transition:opacity .4s}
#app-loader.hide{opacity:0;pointer-events:none}
.loader-spinner{width:48px;height:48px;border:3px solid rgba(255,255,255,.12);border-top-color:var(--emerald);border-radius:50%;animation:spin .9s linear infinite}
#app-loader p{color:rgba(255,255,255,.45);font-size:13px}
@keyframes spin{to{transform:rotate(360deg)}}

/* ── Mobile overlay backdrop ── */
#sidebar-backdrop{display:none;position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:110;backdrop-filter:blur(2px)}
#sidebar-backdrop.active{display:block}

/* ── Layout Grid ── */
#main-layout{display:grid;grid-template-columns:var(--sidebar-w) 1fr;grid-template-rows:var(--header-h) 1fr;min-height:100vh;opacity:0;transition:opacity .3s}
#main-layout.ready{opacity:1}
#main-layout.sidebar-collapsed{grid-template-columns:68px 1fr}

/* ── Sidebar ── */
#sidebar{
  grid-row:1/-1;background:var(--sidebar-bg);
  display:flex;flex-direction:column;width:var(--sidebar-w);
  position:sticky;top:0;height:100vh;
  transition:width .3s cubic-bezier(.4,0,.2,1),transform .3s cubic-bezier(.4,0,.2,1);
  overflow:hidden;box-shadow:4px 0 20px rgba(0,0,0,.18);z-index:120;
}
#sidebar.collapsed{width:68px}
.sidebar-brand{display:flex;align-items:center;gap:12px;padding:0 16px;height:var(--header-h);border-bottom:1px solid rgba(255,255,255,.07);flex-shrink:0;text-decoration:none}
.brand-logo{width:42px;height:42px;border-radius:10px;background:linear-gradient(135deg,var(--emerald),var(--teal));display:flex;align-items:center;justify-content:center;font-size:18px;color:#fff;flex-shrink:0;box-shadow:0 4px 12px rgba(5,150,105,.4);overflow:hidden}
.brand-logo img{width:100%;height:100%;object-fit:contain;object-position:center;display:block}
.brand-logo.has-logo{background:none;box-shadow:none;border-radius:0}
#sidebar-logo-text strong{font-family:'Nunito',sans-serif;font-size:13px;font-weight:800;color:#fff;display:block;line-height:1.2;white-space:nowrap}
#sidebar-logo-text span{font-size:10px;color:var(--sidebar-muted);white-space:nowrap}
#sidebar.collapsed #sidebar-logo-text{display:none}
.sidebar-scroll{flex:1;overflow-y:auto;padding:12px 8px 8px;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.08) transparent}
.sidebar-scroll::-webkit-scrollbar{width:4px}
.sidebar-scroll::-webkit-scrollbar-thumb{background:rgba(255,255,255,.1);border-radius:2px}
/* Nav group accordion */
.nav-group{list-style:none}
.nav-group-header{
  width:100%;display:flex;align-items:center;justify-content:space-between;
  padding:7px 10px;border-radius:8px;background:none;border:none;
  color:var(--sidebar-muted);cursor:pointer;font-family:'DM Sans',sans-serif;
  font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:1.3px;
  transition:background var(--transition),color var(--transition);margin-top:10px;
  white-space:nowrap;
}
.nav-group-header:hover{background:rgba(255,255,255,.04);color:var(--sidebar-text)}
.nav-group-chevron{font-size:9px;transition:transform .22s;flex-shrink:0}
.nav-group-chevron.closed{transform:rotate(-90deg)}
.nav-group-items{list-style:none;padding:0;overflow:hidden;max-height:0;transition:max-height .28s ease}
.nav-group-items.open{max-height:2000px}
/* Collapsed sidebar — hide group headers, show all items flat */
#sidebar.collapsed .nav-group-header{display:none}
#sidebar.collapsed .nav-group-items{max-height:2000px}
.nav-item{width:100%;display:flex;align-items:center;gap:12px;padding:9px 10px;border-radius:10px;background:none;border:none;color:var(--sidebar-text);cursor:pointer;font-family:'DM Sans',sans-serif;font-weight:500;font-size:14px;transition:background var(--transition),color var(--transition);text-align:left;white-space:nowrap;margin-bottom:1px;position:relative}
.nav-item:hover{background:var(--sidebar-hover);color:#fff}
.nav-item.active{background:var(--sidebar-active-bg);color:var(--sidebar-active)}
.nav-item.active .nav-icon,.nav-item:hover .nav-icon{color:inherit}
.nav-icon{width:20px;font-size:15px;text-align:center;flex-shrink:0;color:var(--sidebar-muted);transition:color var(--transition)}
.nav-item.active .nav-icon{color:var(--sidebar-active)}
#sidebar.collapsed .nav-label{display:none}
#sidebar.collapsed .nav-item{justify-content:center;padding:10px}
/* Collapsed tooltip */
#sidebar.collapsed .nav-item::after{content:attr(data-label);position:absolute;left:calc(100% + 10px);top:50%;transform:translateY(-50%);background:rgba(0,0,0,.8);color:#fff;font-size:12px;padding:4px 10px;border-radius:6px;white-space:nowrap;pointer-events:none;opacity:0;transition:opacity .15s}
#sidebar.collapsed .nav-item:hover::after{opacity:1}
/* Role accent colours */
#sidebar.role-admin{--sidebar-active:#fbbf24;--sidebar-active-bg:rgba(251,191,36,.2)}
#sidebar.role-teacher{--sidebar-active:#60a5fa;--sidebar-active-bg:rgba(96,165,250,.2)}
#sidebar.role-parent{--sidebar-active:#a78bfa;--sidebar-active-bg:rgba(167,139,250,.2)}
#sidebar.role-student{--sidebar-active:#34d399;--sidebar-active-bg:rgba(52,211,153,.2)}
/* Sidebar footer */
.sidebar-footer{padding:10px 8px;border-top:1px solid rgba(255,255,255,.07);flex-shrink:0}
.sidebar-user{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:10px;cursor:pointer;transition:background var(--transition)}
.sidebar-user:hover{background:var(--sidebar-hover)}
.sidebar-avatar{width:32px;height:32px;border-radius:50%;background:linear-gradient(135deg,var(--amber),var(--orange));display:flex;align-items:center;justify-content:center;font-size:13px;color:#fff;font-weight:700;font-family:'Nunito',sans-serif;flex-shrink:0}
.sidebar-user-info strong{display:block;font-size:12px;color:#fff;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:160px}
.sidebar-user-info span{font-size:10px;color:var(--sidebar-muted)}
#sidebar.collapsed .sidebar-user-info{display:none}
#sidebar.collapsed .sidebar-user{justify-content:center}

/* ── Header ── */
#header{background:var(--surface);border-bottom:1px solid var(--border);display:flex;align-items:center;gap:10px;padding:0 20px;position:sticky;top:0;z-index:100;box-shadow:0 2px 8px rgba(0,0,0,.04);height:var(--header-h)}
#sidebar-toggle{width:36px;height:36px;background:var(--surface-2);border:1px solid var(--border);border-radius:10px;cursor:pointer;color:var(--text-muted);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:background var(--transition)}
#sidebar-toggle:hover{background:var(--surface-3)}
.breadcrumb{display:flex;align-items:center;gap:8px;flex:1;min-width:0}
.breadcrumb-icon{font-size:16px;color:var(--primary);flex-shrink:0}
.breadcrumb-sep{color:var(--border);font-size:13px}
#page-title{font-family:'Nunito',sans-serif;font-size:17px;font-weight:800;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.header-right{display:flex;align-items:center;gap:8px;margin-left:auto;flex-shrink:0}
.school-badge{display:flex;align-items:center;gap:5px;padding:3px 10px;border-radius:20px;font-size:11px;font-weight:700;letter-spacing:.3px;border:1.5px solid;cursor:default;flex-shrink:0}
.school-badge.nursery{background:var(--violet-l);color:var(--violet);border-color:var(--violet)}
.school-badge.basic{background:var(--sky-l);color:var(--sky);border-color:var(--sky)}
.hdr-btn{width:36px;height:36px;border-radius:10px;background:var(--surface-2);border:1px solid var(--border);cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--text-muted);transition:background var(--transition);position:relative;flex-shrink:0}
.hdr-btn:hover{background:var(--surface-3)}
/* The bell's unread indicator. The dot itself carries no animation — the
   bright-red glow is gated entirely on .is-unread, which app.js's
   initNotifBell() adds only while the unread count is above zero and
   removes the moment it reaches zero. So the bell never pulses at an
   empty inbox; a glowing bell always means something is actually unread. */
.notif-dot{position:absolute;top:7px;right:7px;width:8px;height:8px;background:var(--rose);border-radius:50%;border:2px solid var(--surface);box-shadow:0 0 0 0 rgba(244,63,94,.65)}
.notif-dot.is-unread{animation:notifDotGlow 1.8s ease-in-out infinite}
@keyframes notifDotGlow{
  0%   { box-shadow:0 0 0 0 rgba(244,63,94,.55); }
  70%  { box-shadow:0 0 0 6px rgba(244,63,94,0); }
  100% { box-shadow:0 0 0 0 rgba(244,63,94,0); }
}
/* Reduced-motion users still get the dot, just without the pulse. */
@media (prefers-reduced-motion: reduce){ .notif-dot.is-unread{animation:none} }
/* Profile */
.profile-area{position:relative;flex-shrink:0}
#profile-btn{display:flex;align-items:center;gap:7px;padding:4px 10px 4px 5px;border-radius:30px;background:var(--surface-2);border:1px solid var(--border);cursor:pointer;color:var(--text);font-family:inherit;transition:background var(--transition)}
#profile-btn:hover{background:var(--surface-3)}
.header-avatar{width:28px;height:28px;border-radius:50%;background:linear-gradient(135deg,var(--emerald),var(--teal));display:flex;align-items:center;justify-content:center;font-size:12px;color:#fff;font-weight:700;font-family:'Nunito',sans-serif;flex-shrink:0}
#user-name{font-size:13px;font-weight:600;max-width:100px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#role-tag{font-size:10px;font-weight:700;padding:2px 7px;border-radius:20px;background:var(--primary-glow);color:var(--primary);white-space:nowrap}
#profile-dropdown{position:absolute;top:calc(100% + 8px);right:0;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);min-width:200px;opacity:0;pointer-events:none;transition:opacity .15s,transform .15s;transform:translateY(-4px);z-index:200;box-shadow:var(--shadow-md);overflow:hidden}
#profile-dropdown.open{opacity:1;pointer-events:all;transform:none}
.profile-info{padding:12px 16px;border-bottom:1px solid var(--border);background:var(--surface-2)}
.profile-info strong{display:block;font-size:13px;font-weight:700;margin-bottom:2px}
.profile-info span{font-size:11px;color:var(--text-muted)}
.dropdown-item{padding:10px 16px;width:100%;background:none;border:none;text-align:left;cursor:pointer;color:var(--text-muted);font-family:inherit;font-size:13px;display:flex;align-items:center;gap:10px;transition:background .12s,color .12s}
.dropdown-item:hover{background:var(--surface-2);color:var(--text)}
.dropdown-item.danger{color:var(--rose)}
.dropdown-item.danger:hover{background:var(--rose-l)}
.dropdown-item i{width:16px;text-align:center}

/* ── Content Area ── */
#content-area{overflow-y:auto;min-height:0}
#page-content{padding:20px 14px}
.page-exit{opacity:0;transform:translateY(-4px);transition:.15s}
.page-enter{animation:pageFade .25s ease}
@keyframes pageFade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

/* ── Page Header ── */
.page-header{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:24px;gap:14px;flex-wrap:wrap}
.page-header-left h1{font-family:'Nunito',sans-serif;font-size:24px;font-weight:900;margin-bottom:3px}
.page-header-left p{color:var(--text-muted);font-size:14px}
.page-header-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center}

/* ── RBAC Access Denied ── */
.access-denied{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 24px;text-align:center;min-height:300px}
.access-denied .lock-icon{font-size:48px;margin-bottom:16px;color:var(--text-muted);opacity:.4}
.access-denied h2{font-family:'Nunito',sans-serif;font-size:20px;font-weight:800;margin-bottom:8px}
.access-denied p{color:var(--text-muted);font-size:13px;max-width:360px}
.role-required-chips{display:flex;gap:6px;flex-wrap:wrap;justify-content:center;margin-top:12px}

/* ── Stat Cards ── */
.stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:16px;margin-bottom:24px}
.stat-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);padding:20px;transition:transform .2s,box-shadow .2s;position:relative;overflow:hidden}
.stat-card::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;background:var(--card-accent,var(--primary))}
.stat-card:hover{transform:translateY(-2px);box-shadow:var(--shadow-md)}
.stat-icon{width:40px;height:40px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:17px;margin-bottom:12px;background:var(--card-accent-l,var(--primary-l));color:var(--card-accent,var(--primary))}
.stat-value{font-family:'Nunito',sans-serif;font-size:clamp(18px,2.4vw,28px);font-weight:900;line-height:1.15;margin-bottom:3px;word-break:break-word;overflow-wrap:anywhere}
.fi-headline-stats .stat-value{font-size:20px;word-break:break-word;line-height:1.15}
.stat-title{font-size:12px;font-weight:700;color:var(--text-muted);text-transform:uppercase;letter-spacing:.6px}
.stat-sub{font-size:12px;color:var(--text-muted);margin-top:6px}
.stat-change{margin-top:8px;font-size:11px;display:flex;align-items:center;gap:4px}
.stat-change.up{color:var(--emerald)}.stat-change.down{color:var(--rose)}
.stat-card.green{--card-accent:var(--emerald);--card-accent-l:var(--emerald-l)}
.stat-card.sky{--card-accent:var(--sky);--card-accent-l:var(--sky-l)}
.stat-card.amber{--card-accent:var(--amber);--card-accent-l:var(--amber-l)}
.stat-card.violet{--card-accent:var(--violet);--card-accent-l:var(--violet-l)}
.stat-card.rose{--card-accent:var(--rose);--card-accent-l:var(--rose-l)}
.stat-card.teal{--card-accent:var(--teal);--card-accent-l:var(--teal-l)}
.stat-card.orange{--card-accent:var(--orange);--card-accent-l:var(--orange-l)}

/* ── Section Card ── */
.page-section{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);margin-bottom:20px;overflow:hidden}
.section-header{padding:14px 20px;border-bottom:1px solid var(--border);font-family:'Nunito',sans-serif;font-weight:800;font-size:14px;display:flex;align-items:center;justify-content:space-between;gap:10px;background:var(--surface-2)}
.section-header-left{display:flex;align-items:center;gap:10px}
.section-icon{width:30px;height:30px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:13px;background:var(--primary-l);color:var(--primary);flex-shrink:0}
.section-body{padding:18px 20px}

/* ── Tables ── */
.table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
.data-table{width:100%;border-collapse:collapse;font-size:13px;min-width:520px}
.data-table th{padding:10px 14px;text-align:left;font-weight:700;font-size:11px;text-transform:uppercase;letter-spacing:.6px;background:var(--surface-2);border-bottom:2px solid var(--border);color:var(--text-muted);white-space:nowrap}
.data-table td{padding:11px 14px;border-bottom:1px solid var(--border);color:var(--text-muted);font-size:14px;transition:background .1s}
.data-table tr:last-child td{border-bottom:none}
.data-table tbody tr:hover td{background:var(--surface-2);color:var(--text)}
/* Mobile card rows */
@media(max-width:600px){
  .data-table{min-width:unset}
  .data-table,.data-table thead,.data-table tbody,.data-table th,.data-table td,.data-table tr{display:block}
  .data-table thead tr{display:none}
  .data-table tbody tr{border:1px solid var(--border);border-radius:var(--radius);margin-bottom:10px;padding:12px;background:var(--surface)}
  .data-table td{border:none;padding:4px 0;display:flex;align-items:flex-start;gap:8px;font-size:13px}
  .data-table td::before{content:attr(data-label);font-weight:700;font-size:10px;text-transform:uppercase;letter-spacing:.5px;color:var(--text-muted);min-width:90px;flex-shrink:0;padding-top:2px}
}

/* ── Chips ── */
.chip{display:inline-flex;align-items:center;gap:4px;padding:3px 9px;border-radius:20px;font-size:11px;font-weight:700;white-space:nowrap}
.chip-green{background:var(--emerald-l);color:var(--emerald-d)}
.chip-sky{background:var(--sky-l);color:var(--sky-d)}
.chip-amber{background:var(--amber-l);color:#92400e}
.chip-rose{background:var(--rose-l);color:#9f1239}
.chip-violet{background:var(--violet-l);color:var(--violet)}
.chip-teal{background:var(--teal-l);color:var(--teal)}
.chip-orange{background:var(--orange-l);color:var(--orange)}
.chip-gray{background:var(--surface-3);color:var(--text-muted)}
/* Legacy aliases */
.status-chip{display:inline-block;padding:3px 9px;border-radius:20px;font-size:11px;font-weight:600}
.status-approved{background:var(--emerald-l);color:var(--emerald-d)}
.status-pending{background:var(--amber-l);color:#92400e}
.status-danger{background:var(--rose-l);color:#9f1239}

/* ── Buttons ── */
.btn{display:inline-flex;align-items:center;gap:6px;padding:7px 16px;border-radius:10px;font-family:'DM Sans',sans-serif;font-weight:600;font-size:13px;cursor:pointer;border:none;transition:transform .15s,box-shadow .15s,background .15s;line-height:1;text-decoration:none;white-space:nowrap;flex-shrink:0}
.btn:hover{transform:translateY(-1px)}
.btn:active{transform:none}
.btn-primary{background:var(--primary);color:#fff;box-shadow:0 4px 12px rgba(5,150,105,.3)}
.btn-primary:hover{background:var(--primary-d)}
.btn-sky{background:var(--sky);color:#fff;box-shadow:0 4px 10px rgba(2,132,199,.3)}
.btn-sky:hover{background:var(--sky-d)}
.btn-amber{background:var(--amber);color:#fff}
.btn-violet{background:var(--violet);color:#fff}
.btn-rose{background:var(--rose);color:#fff}
.btn-success{background:var(--emerald);color:#fff}
.btn-danger{background:var(--rose);color:#fff}
.btn-outline{background:transparent;border:1.5px solid var(--border);color:var(--text-muted)}
.btn-outline:hover{border-color:var(--primary);color:var(--primary);background:var(--primary-glow)}
.btn-ghost{background:var(--surface-2);color:var(--text-muted);border:1px solid var(--border)}
.btn-ghost:hover{background:var(--surface-3);color:var(--text)}
.btn-sm{padding:5px 11px;font-size:11px;border-radius:8px}
.btn-lg{padding:11px 22px;font-size:15px}

/* ── Forms ── */
.filter-bar{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:18px;align-items:center}
.form-input,.form-select,.form-textarea{background:var(--surface);border:1.5px solid var(--border);padding:8px 13px;border-radius:10px;color:var(--text);font-family:inherit;font-size:14px;transition:border-color .15s,box-shadow .15s;outline:none;width:100%}
.form-input:focus,.form-select:focus,.form-textarea:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-glow)}
.form-label{display:block;font-size:11px;font-weight:700;color:var(--text-muted);margin-bottom:5px;text-transform:uppercase;letter-spacing:.5px}
.form-group{margin-bottom:16px}
.form-group small{display:block;font-size:11px;color:var(--text-muted);margin-top:4px}
.filter-bar .form-input,.filter-bar .form-select{width:auto;min-width:140px}
.filter-bar .form-input.search-input{min-width:200px}

/* ── Searchable dropdown (combobox) — see searchDropdown() in page.js ── */
.search-dd{position:relative;min-width:240px}
.search-dd .search-dd-input{width:100%;padding-right:30px}
.search-dd-caret{position:absolute;right:11px;top:50%;transform:translateY(-50%);font-size:11px;color:var(--text-muted);pointer-events:none;transition:transform .15s ease}
.search-dd.open .search-dd-caret{transform:translateY(-50%) rotate(180deg)}
.search-dd-list{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:120;background:var(--surface);border:1.5px solid var(--border);border-radius:10px;box-shadow:0 10px 28px rgba(0,0,0,.14);max-height:280px;overflow-y:auto}
.search-dd-item{display:flex;flex-direction:column;gap:1px;padding:8px 13px;cursor:pointer;font-size:13px;color:var(--text)}
.search-dd-item:hover{background:var(--primary-glow)}
.search-dd-item small{color:var(--text-muted);font-size:11px}
.search-dd-empty{padding:10px 13px;color:var(--text-muted);font-size:12px}

/* ── Info banner (inline notices; also used on entrance-result page) ── */
.info-banner{display:flex;align-items:center;gap:10px;padding:11px 14px;border-radius:10px;font-size:13px;line-height:1.5;border:1.5px solid var(--border);background:var(--surface-2);color:var(--text-muted)}
.info-banner.info{background:var(--primary-glow);border-color:var(--primary);color:var(--primary-d)}
.info-banner.warning{background:var(--amber-l);border-color:var(--amber);color:var(--amber)}
.info-banner.success{background:var(--emerald-l);border-color:var(--emerald);color:var(--emerald-d)}

/* .form-control — alias used by the admission form inputs */
.form-control{background:var(--surface);border:1.5px solid var(--border);padding:8px 13px;border-radius:10px;color:var(--text);font-family:inherit;font-size:14px;transition:border-color .15s,box-shadow .15s;outline:none;width:100%}
.form-control:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-glow)}

/* Two-column form layout used inside large modals (admission form etc.) */
.form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:22px}
.form-grid .form-group{margin-bottom:16px}
@media (max-width:640px){.form-grid{grid-template-columns:1fr}}

/* Larger, roomier inputs inside the admission & admit modals */
#admission-modal .form-control,
#admission-modal .form-select,
#admission-modal .form-input,
#admit-modal .form-control,
#admit-modal .form-select{
  padding:14px 16px;
  font-size:15px;
  min-height:52px;
  width:100%;
  border-radius:10px;
}
#admission-modal .form-label{font-size:12px}
#admission-modal .form-group{margin-bottom:20px}

/* Admission fee / bank details banner on the admission form */
.fee-banner{border:1.5px solid var(--border);border-radius:10px;padding:14px 16px;margin-bottom:6px;background:var(--surface);font-size:13px;line-height:1.55}
.fee-banner .fee-amount{font-size:20px;font-weight:800;color:var(--primary)}

/* Consent declaration box on the admission form */
.consent-box{max-height:180px;overflow-y:auto;padding:14px 16px;border-radius:10px;background:var(--surface);border:1.5px solid var(--border);font-size:13px;line-height:1.6;color:var(--text-muted);white-space:pre-wrap}

/* ── Toast ── */
/* Toasts must sit ABOVE every overlay, because the moment you most need to
   read one is right after saving a form — and a form lives in a modal.
   The container was z-index:9999 against a modal at 10000, so every
   "Saved", every "That name is already taken", every failure reason was
   rendered one layer behind the dialog that produced it. 10100 clears the
   modal (10000) and the highest floating panel (10050). */
.toast-container{position:fixed;bottom:20px;right:20px;z-index:10100;display:flex;flex-direction:column;gap:8px;pointer-events:none;max-width:calc(100vw - 40px)}
.toast{background:var(--surface);border-radius:14px;padding:12px 16px;box-shadow:0 8px 28px rgba(0,0,0,.15);display:flex;align-items:center;gap:10px;animation:toastIn .3s cubic-bezier(.4,0,.2,1);pointer-events:all;border:1px solid var(--border);max-width:360px}
.toast-icon{width:30px;height:30px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:13px;flex-shrink:0}
.toast.success .toast-icon{background:var(--emerald-l);color:var(--emerald)}
.toast.error .toast-icon{background:var(--rose-l);color:var(--rose)}
.toast.info .toast-icon{background:var(--sky-l);color:var(--sky)}
.toast.warning .toast-icon{background:var(--amber-l);color:var(--amber)}
.toast-msg{font-size:13px;font-weight:500;flex:1;line-height:1.4}
@keyframes toastIn{from{transform:translateX(110%);opacity:0}to{transform:none;opacity:1}}
@media(max-width:640px){
  /* A modal fills a phone screen and its footer buttons sit at the bottom,
     which is exactly where the toast would appear. Move them to the top. */
  .toast-container{bottom:auto;top:14px;left:12px;right:12px;align-items:stretch;max-width:none}
  .toast{max-width:none}
}

/* ── Modal ── */
.modal{position:fixed;inset:0;z-index:10000;display:flex;align-items:center;justify-content:center;padding:16px}
.modal-overlay{position:absolute;inset:0;background:rgba(0,0,0,.5);backdrop-filter:blur(4px)}
.modal-container{position:relative;background:var(--surface);border-radius:var(--radius-xl);width:100%;max-width:460px;box-shadow:0 24px 60px rgba(0,0,0,.25);border:1px solid var(--border);animation:modalPop .2s cubic-bezier(.4,0,.2,1);overflow:hidden}
@keyframes modalPop{from{opacity:0;transform:scale(.94) translateY(10px)}to{opacity:1;transform:none}}
.modal-header{display:flex;justify-content:space-between;align-items:center;padding:16px 20px;border-bottom:1px solid var(--border);background:var(--surface-2)}
.modal-header h3{margin:0;font-size:16px;font-weight:700;font-family:'Nunito',sans-serif}
.modal-close{background:var(--surface-3);border:none;width:28px;height:28px;border-radius:50%;font-size:16px;cursor:pointer;color:var(--text-muted);display:flex;align-items:center;justify-content:center;transition:background .15s}
.modal-close:hover{background:var(--rose-l);color:var(--rose)}
.modal-body{padding:20px;max-height:70vh;overflow-y:auto}
.modal-buttons{display:flex;justify-content:flex-end;gap:10px;margin-top:20px}

/* ── Progress Bar ── */
.progress-bar{height:7px;border-radius:4px;background:var(--surface-3);overflow:hidden}
.progress-fill{height:100%;border-radius:4px;background:linear-gradient(90deg,var(--primary),var(--teal));transition:width .6s cubic-bezier(.4,0,.2,1)}

/* ── Grade Badges ── */
.grade-badge{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:7px;font-weight:900;font-size:13px;font-family:'Nunito',sans-serif}
.grade-A{background:var(--emerald-l);color:var(--emerald-d)}
.grade-B{background:var(--sky-l);color:var(--sky-d)}
.grade-C{background:var(--amber-l);color:#92400e}
.grade-P{background:var(--orange-l);color:var(--orange)}
.grade-F{background:var(--rose-l);color:#9f1239}

/* ── Timetable ── */
.timetable-grid{display:grid;grid-template-columns:84px repeat(5,1fr);gap:3px;font-size:12px}
.t-header{background:var(--sidebar-bg);color:#fff;padding:7px;border-radius:7px;text-align:center;font-weight:700;font-size:10px;letter-spacing:.5px}
.t-time{background:var(--surface-2);padding:7px;border-radius:7px;text-align:center;color:var(--text-muted);font-weight:600;display:flex;align-items:center;justify-content:center;font-size:10px}
.timetable-slot{padding:8px 6px;border-radius:7px;border:1.5px solid transparent;text-align:center;min-height:54px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;transition:transform .15s}
.timetable-slot:hover{transform:scale(1.02)}
.timetable-slot.empty{background:var(--surface-2);border-color:var(--border)}
.timetable-slot.break{background:var(--amber-l);border-color:var(--amber);color:#92400e;font-weight:700}
.timetable-slot .subject-name{font-weight:700;font-size:10px;line-height:1.2}
.timetable-slot .teacher-name{font-size:9px;opacity:.75}

/* ── Announcement cards ── */
.ann-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);padding:18px;margin-bottom:12px;border-left:4px solid var(--primary);transition:box-shadow .2s}
.ann-card:hover{box-shadow:var(--shadow)}
.ann-header{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;margin-bottom:8px;flex-wrap:wrap}
.ann-title{font-family:'Nunito',sans-serif;font-size:15px;font-weight:800;margin-top:6px}
.ann-body{font-size:13px;color:var(--text-muted);line-height:1.6}
.ann-date{font-size:11px;color:var(--text-muted);white-space:nowrap}

/* ── Two column grid ── */
.two-col{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-bottom:20px}

/* ── Quick action tiles ── */
.quick-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.quick-tile{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:14px;text-align:center;cursor:pointer;transition:transform .15s,box-shadow .15s,background .15s;border:none;font-family:inherit}
.quick-tile:hover{transform:translateY(-2px);box-shadow:var(--shadow-md);background:var(--surface-2)}
.quick-tile-icon{width:36px;height:36px;border-radius:9px;display:flex;align-items:center;justify-content:center;font-size:16px;margin:0 auto 8px}
.quick-tile-label{font-size:11px;font-weight:700;color:var(--text);line-height:1.3}
.quick-tile.green .quick-tile-icon{background:var(--emerald-l);color:var(--emerald)}
.quick-tile.sky .quick-tile-icon{background:var(--sky-l);color:var(--sky)}
.quick-tile.amber .quick-tile-icon{background:var(--amber-l);color:var(--amber)}
.quick-tile.violet .quick-tile-icon{background:var(--violet-l);color:var(--violet)}
.quick-tile.teal .quick-tile-icon{background:var(--teal-l);color:var(--teal)}
.quick-tile.orange .quick-tile-icon{background:var(--orange-l);color:var(--orange)}

/* ── Event list ── */
.event-item{display:flex;align-items:center;gap:14px;padding:12px;background:var(--surface-2);border-radius:var(--radius);border:1px solid var(--border);margin-bottom:8px}
.event-icon{width:42px;height:42px;border-radius:9px;display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0}
.event-title{font-weight:700;font-size:13px}
.event-date{font-size:11px;color:var(--text-muted);margin-top:2px}

/* ── Utility ── */
.mt-1{margin-top:6px}.mt-2{margin-top:12px}.mt-3{margin-top:20px}
.mb-1{margin-bottom:6px}.mb-2{margin-bottom:12px}
.text-muted{color:var(--text-muted)}.text-sm{font-size:12px}
.font-bold{font-weight:700}.flex{display:flex}.items-center{align-items:center}
.gap-2{gap:8px}.gap-3{gap:12px}.w-full{width:100%}
.avatar-green{background:linear-gradient(135deg,var(--emerald),var(--teal));color:#fff}
.avatar-sky{background:linear-gradient(135deg,var(--sky),#38bdf8);color:#fff}
.avatar-amber{background:linear-gradient(135deg,var(--amber),var(--orange));color:#fff}
.avatar-violet{background:linear-gradient(135deg,var(--violet),#a78bfa);color:#fff}

/* ── MOBILE RESPONSIVE ──────────────────────────────── */
@media(max-width:900px){
  :root{--sidebar-w:272px}
  /* Grid collapses to full-width content only */
  #main-layout{grid-template-columns:1fr;grid-template-rows:var(--header-h) 1fr}
  /* Sidebar off-canvas */
  #sidebar{position:fixed;left:0;top:0;height:100%;z-index:130;transform:translateX(-100%);width:var(--sidebar-w)!important;transition:transform .3s cubic-bezier(.4,0,.2,1)}
  #sidebar.mobile-open{transform:translateX(0)}
  #main-layout.sidebar-collapsed{grid-template-columns:1fr}
  /* Page content padding */
  #page-content{padding:14px 10px}
  /* Hide username in header to save space */
  #user-name{display:none}
  /* Two col stack */
  .two-col{grid-template-columns:1fr}
  /* Quick grid 2 cols */
  .quick-grid{grid-template-columns:repeat(2,1fr)}
  /* Stat grid 2 cols */
  .stat-grid{grid-template-columns:repeat(2,1fr)}
  /* Page header stack */
  .page-header{flex-direction:column;align-items:stretch}
  .page-header-actions{justify-content:flex-start}
  /* Filter bar column */
  .filter-bar{flex-direction:column}
  .filter-bar .form-input,.filter-bar .form-select{width:100%;min-width:unset}
  /* School badge hide text */
  #school-badge-text{display:none}
  /* Breadcrumb shorter */
  #page-title{font-size:15px}
  /* ── Touch targets — PWA/mobile pass (2026-08-19) ──
     Buttons, nav items and inputs sized for a mouse pointer are too small
     to tap reliably; bump them toward the ~44px recommended minimum
     touch target wherever it doesn't blow out dense table rows. */
  .btn{min-height:44px;padding:9px 16px}
  .btn-sm{min-height:36px;padding:8px 13px}
  .nav-item{min-height:46px}
  .hdr-btn{width:42px;height:42px}
  #sidebar-toggle{width:42px;height:42px}
  .modal-close{width:34px;height:34px;font-size:18px}
  .form-input,.form-select,.form-textarea{padding:11px 13px}
  .data-table td .btn,.data-table td .btn-sm{margin:2px 3px 2px 0}
}
@media(max-width:480px){
  .stat-grid{grid-template-columns:1fr 1fr}
  .quick-grid{grid-template-columns:repeat(2,1fr)}
  .header-right .hdr-btn:not(#themeToggle){display:none}
  #role-tag{display:none}
  .section-body{padding:14px}
  .section-header{padding:12px 14px}
}
@media(max-width:360px){
  #page-content{padding:12px}
  .stat-grid{grid-template-columns:1fr}
}


/* ── Heading visibility (2026-08-12) ── */
/* Table headers were 11px muted uppercase — they read as a caption rather than
   a heading. Darker, larger and heavier, on a tinted band with a solid rule. */
.data-table th{
  font-size:12.5px;
  letter-spacing:.4px;
  color:var(--text);
  font-weight:800;
  background:var(--surface-3,var(--surface-2));
  border-bottom:2px solid var(--primary);
  padding:12px 14px;
}

/* Modal titles: bigger, heavier, with a tinted bar so the dialog announces
   what it is at a glance. */
.modal-header{padding:18px 22px;background:var(--surface-2);border-bottom:2px solid var(--primary)}
.modal-header h3{font-size:19px;font-weight:800;letter-spacing:-.2px;color:var(--text)}

/* Section headings inside modals and cards. */
.rpt-heading{
  margin:0 0 10px;
  font-size:15px;
  font-weight:800;
  color:var(--text);
  letter-spacing:-.1px;
  display:flex;align-items:center;gap:8px;
}
.rpt-heading .rpt-note{font-weight:600;font-size:12px;color:var(--text-muted);letter-spacing:0}

/* Tables built inline inside modals (result preview, student result) — same
   heading treatment as .data-table without inheriting its cell padding. */
.rpt-table{width:100%;border-collapse:collapse;font-size:13.5px}
.rpt-table thead th{
  position:sticky;top:0;z-index:1;
  background:var(--surface-3,var(--surface-2));
  color:var(--text);
  font-size:12.5px;font-weight:800;letter-spacing:.4px;text-transform:uppercase;
  text-align:left;padding:11px 9px;
  border-bottom:2px solid var(--primary);
  white-space:nowrap;
}
.rpt-table tbody td{padding:8px 9px;border-bottom:1px solid var(--border)}
.rpt-table tbody tr:hover td{background:var(--surface-2)}


/* ── Hero modal header (2026-08-12) ── */
/* Opt-in via .modal-hero on .modal-container. Used by the result screens, where
   the dialog title carries the student's or class's name and needs to be the
   first thing the eye lands on. */
.modal-hero .modal-header{
  background:linear-gradient(135deg,var(--primary),var(--primary-d));
  border-bottom:none;
  padding:20px 24px;
}
.modal-hero .modal-header h3{
  color:#fff;
  font-size:23px;
  font-weight:900;
  letter-spacing:-.4px;
  line-height:1.15;
  text-shadow:0 1px 2px rgba(0,0,0,.18);
}
.modal-hero .modal-header h3 .modal-hero-sub{
  display:block;
  font-size:12.5px;
  font-weight:600;
  letter-spacing:.3px;
  text-transform:uppercase;
  opacity:.85;
  margin-top:3px;
  text-shadow:none;
}
.modal-hero .modal-close{background:rgba(255,255,255,.2);color:#fff}
.modal-hero .modal-close:hover{background:rgba(255,255,255,.34);color:#fff}


/* ── Attendance tiles (2026-08-12) ── */
.att-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(96px,1fr));gap:10px}
.att-tile{
  border:1px solid var(--border);
  border-left:4px solid var(--text-muted);
  border-radius:10px;
  padding:11px 13px;
  background:var(--surface);
}
.att-tile .att-value{font-size:1.6rem;font-weight:900;line-height:1;color:var(--text)}
.att-tile .att-label{
  font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.05em;
  color:var(--text-muted);margin-top:4px;
}
/* Each tile's label uses that tile's own accent colour instead of the base
   var(--text-muted) — the tinted background (var(--emerald-l) etc.) doesn't
   change in dark mode, but var(--text-muted) turns pale there, so "Present",
   "Absent", "Late", "Half day" read as very faint against their tile's
   colour. The accent colours below are fixed hex/non-theme values, so the
   label stays legible in both light and dark mode. */
.att-present{border-left-color:var(--emerald);background:var(--emerald-l)}
.att-present .att-value{color:var(--emerald-d)}
.att-present .att-label{color:var(--emerald-d)}
.att-absent{border-left-color:var(--rose);background:var(--rose-l)}
.att-absent .att-value{color:var(--rose)}
.att-absent .att-label{color:var(--rose)}
.att-late{border-left-color:var(--amber);background:var(--amber-l)}
.att-late .att-value{color:#92400e}
.att-late .att-label{color:#92400e}
.att-half{border-left-color:var(--sky);background:var(--sky-l)}
.att-half .att-value{color:var(--sky-d)}
.att-half .att-label{color:var(--sky-d)}
.att-rate{border-left-color:var(--primary)}

.att-bar{height:9px;border-radius:5px;background:var(--surface-3);overflow:hidden;margin-top:10px}
.att-bar span{display:block;height:100%;border-radius:5px;background:linear-gradient(90deg,var(--emerald),var(--teal))}


/* ── Result subject matrix (2026-08-12) ── */
.subj-table td.subj-name{font-weight:700;color:var(--text);white-space:nowrap}
.subj-table td.subj-mark{text-align:center;padding:5px 6px}
.subj-table th.subj-mark{text-align:center}
.subj-table th.subj-mark small{display:block;font-weight:600;font-size:10px;opacity:.7;letter-spacing:0}
.subj-mark input{
  width:52px;padding:3px 4px;text-align:center;font-size:12.5px;
  border:1px solid var(--border);border-radius:6px;background:var(--surface);color:var(--text);
}
.subj-mark input:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 2px var(--primary-glow)}
.subj-mark input.over-max{border-color:var(--rose);background:var(--rose-l);color:var(--rose);font-weight:700}
.subj-table td.subj-total{text-align:right;font-weight:700;white-space:nowrap}
.subj-table tfoot td{
  border-top:2px solid var(--border);font-weight:800;background:var(--surface-2);
  padding:9px;color:var(--text);
}


/* ── Broadsheet (2026-08-12) ── */
.bs-wrap{border:1px solid var(--border);border-radius:8px;overflow:auto;max-height:62vh}
.bs-table{width:100%;border-collapse:separate;border-spacing:0;font-size:12.5px}
.bs-table th,.bs-table td{padding:7px 8px;border-bottom:1px solid var(--border);white-space:nowrap}
.bs-table thead th{
  position:sticky;top:0;z-index:3;
  background:var(--surface-3,var(--surface-2));color:var(--text);
  font-size:11.5px;font-weight:800;letter-spacing:.4px;text-transform:uppercase;
  border-bottom:2px solid var(--primary);text-align:center;
}
.bs-table thead th.bs-subject{writing-mode:vertical-rl;transform:rotate(180deg);height:118px;padding:8px 4px;letter-spacing:.2px}
/* Student column stays put while the subjects scroll sideways. */
.bs-table .bs-sticky{position:sticky;left:0;z-index:2;background:var(--surface);text-align:left}
.bs-table thead .bs-sticky{z-index:4;background:var(--surface-3,var(--surface-2))}
.bs-table tbody tr:hover td{background:var(--surface-2)}
.bs-table tbody tr:hover .bs-sticky{background:var(--surface-2)}
.bs-mark{text-align:center;font-variant-numeric:tabular-nums}
.bs-mark .bs-grade{display:block;font-size:10px;font-weight:800;color:var(--text-muted);letter-spacing:.3px}
.bs-empty{color:var(--text-muted)}
.bs-total{text-align:right;font-weight:800;font-variant-numeric:tabular-nums}
.bs-table tfoot td{
  position:sticky;bottom:0;background:var(--surface-2);
  border-top:2px solid var(--border);font-weight:800;color:var(--text);
}
.bs-remark{min-width:210px;white-space:normal}
.bs-remark input{
  width:100%;padding:4px 6px;font-size:12px;border:1px solid var(--border);
  border-radius:6px;background:var(--surface);color:var(--text);
}
.bs-remark input:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 2px var(--primary-glow)}
.bs-remark input.dirty{border-color:var(--amber);background:var(--amber-l);color:#78350f}
.bs-viewtabs{display:inline-flex;border:1px solid var(--border);border-radius:8px;overflow:hidden}
.bs-viewtabs button{
  background:var(--surface);border:none;padding:7px 14px;cursor:pointer;
  font-weight:700;font-size:12.5px;color:var(--text-muted);
}
.bs-viewtabs button.active{background:var(--primary);color:#fff}


/* ── Broadsheet assessment columns (2026-08-12) ── */
/* Second header row: assessment abbreviations under each subject. */
.bs-table thead tr.bs-sub th{
  top:34px;                     /* sits directly under the subject row */
  font-size:10.5px;letter-spacing:.2px;text-transform:none;font-weight:700;
  border-bottom:2px solid var(--primary);
  padding:5px 4px;
}
.bs-table thead th.bs-group{
  border-left:2px solid var(--border);
  writing-mode:horizontal-tb;transform:none;height:auto;
  font-size:11px;padding:7px 6px;
}
.bs-table td.bs-group-start{border-left:2px solid var(--border)}
.bs-table td.bs-assess{text-align:center;padding:4px 5px}
.bs-assess input{
  width:60px;padding:5px 4px;text-align:center;font-size:13.5px;
  border:1px solid var(--border);border-radius:6px;background:var(--surface);color:var(--text);
  font-variant-numeric:tabular-nums;
}
.bs-assess input:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 2px var(--primary-glow)}
/* Explicit dark text here (not var(--text)) — var(--amber-l) stays a pale
   cream in both light and dark mode, but var(--text) turns near-white in
   dark mode, which made a just-typed figure invisible against it. */
.bs-assess input.dirty{border-color:var(--amber);background:var(--amber-l);color:#78350f;font-weight:700}
.bs-assess input:disabled{background:var(--surface-2);color:var(--text-muted)}
.bs-subtotal{text-align:center;font-weight:800;background:var(--surface-2);font-variant-numeric:tabular-nums}
/* Third-term carried-over columns (1T/2T totals) — read-only here, tinted to
   mark them as coming from an earlier term rather than this one. */
.bs-carried{background:var(--sky-l);color:var(--sky-d);font-variant-numeric:tabular-nums}


/* ── Class progress sheet (2026-08-12) ── */
.ps-attend{white-space:nowrap;font-size:12px}
.ps-attend .ps-bad{color:var(--rose);font-weight:700}
.ps-rate{text-align:center;padding:4px 5px}
.ps-rate input{
  width:48px;padding:3px 4px;text-align:center;font-size:12.5px;
  border:1px solid var(--border);border-radius:6px;background:var(--surface);color:var(--text);
  font-variant-numeric:tabular-nums;
}
.ps-rate input:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 2px var(--primary-glow)}
.ps-rate input.dirty{border-color:var(--amber);background:var(--amber-l);color:#78350f;font-weight:700}
.ps-rate input:disabled{background:var(--surface-2);color:var(--text-muted)}
.bs-table thead th.ps-cat-psychomotor{border-left:2px solid var(--border)}
.bs-table td.ps-cat-psychomotor{border-left:2px solid var(--border)}


/* ── Progress sheet dropdowns (2026-08-13) ── */
.ps-rate select{
  width:60px;padding:3px 4px;text-align:center;font-size:12.5px;
  border:1px solid var(--border);border-radius:6px;background:var(--surface);color:var(--text);
  font-variant-numeric:tabular-nums;cursor:pointer;
}
.ps-rate select:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 2px var(--primary-glow)}
.ps-rate select.dirty{border-color:var(--amber);background:var(--amber-l);color:#78350f;font-weight:700}
.ps-rate select:disabled{background:var(--surface-2);color:var(--text-muted);cursor:default}


/* ── Progress sheet attribute headers (2026-08-13) ── */
/* .bs-table sets white-space:nowrap globally, so "Sense of responsibility"
   would hold a column ~180px wide. These wrap inside a fixed narrow column
   instead, which fits roughly two lines and keeps 17 attributes on screen. */
.bs-table thead th.ps-attr{
  white-space:normal;
  width:78px;min-width:78px;max-width:78px;
  line-height:1.2;
  vertical-align:bottom;
  font-size:10.5px;
  letter-spacing:.1px;
  text-transform:none;
  padding:8px 5px;
  word-break:break-word;
}
.bs-table td.ps-rate{width:78px;min-width:78px}


/* ── Score entry: Moodle picker (2026-08-13) ── */
.es-lms{margin-top:5px;font-weight:400}
.es-lms-btn{
  background:var(--sky-l);color:var(--sky-d);border:1px solid transparent;
  border-radius:6px;padding:2px 7px;font-size:10.5px;font-weight:700;cursor:pointer;
  display:inline-flex;align-items:center;gap:4px;text-transform:none;letter-spacing:0;
}
.es-lms-btn:hover{border-color:var(--sky)}
.es-lms-btn.on{background:var(--sky);color:#fff}
.es-lms-panel{
  position:absolute;z-index:40;margin-top:4px;min-width:290px;max-width:360px;
  background:var(--surface);border:1px solid var(--border);border-radius:10px;
  box-shadow:var(--shadow-md);padding:12px;text-align:left;font-weight:400;
  text-transform:none;letter-spacing:0;color:var(--text);
}
.es-lms-panel h5{margin:0 0 4px;font-size:12.5px;font-weight:800}
.es-lms-panel .es-lms-note{font-size:11px;color:var(--text-muted);margin:0 0 8px;line-height:1.35}
.es-lms-list{max-height:220px;overflow:auto;border:1px solid var(--border);border-radius:7px;padding:6px;margin-bottom:9px}
.es-lms-item{display:flex;align-items:center;gap:7px;padding:3px 2px;font-size:12px}
.es-lms-item span.es-lms-max{margin-left:auto;color:var(--text-muted);font-size:11px}
.es-lms-total{font-size:11.5px;margin-bottom:9px}
.es-saved{animation:esFlash 1.6s ease}
@keyframes esFlash{0%{background:var(--emerald-l)}100%{background:transparent}}


/* ── Report card (2026-08-13) ── */
.rc-sheet{background:#fff;color:#111;padding:26px 30px;border-radius:10px;position:relative;overflow:hidden}
.rc-sheet *{color:inherit}
.rc-watermark{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  opacity:.05;pointer-events:none;
}
.rc-watermark img{width:52%}
.rc-head{display:flex;align-items:flex-start;gap:16px;position:relative}
.rc-head img.rc-logo{width:62px}
.rc-head .rc-titles{flex:1;text-align:center}
.rc-school{font-size:22px;font-weight:800;color:#1a3fd0;letter-spacing:.4px;line-height:1.1}
.rc-addr{font-size:9.5px;color:#555;margin-top:4px}
.rc-term{font-size:10px;font-weight:800;color:#c00;margin-top:5px;letter-spacing:.2px}
.rc-sec{font-size:9.5px;font-weight:800;margin:16px 0 7px;letter-spacing:.4px}
.rc-info{display:grid;grid-template-columns:1fr 1fr;gap:2px 26px;font-size:10px;position:relative}
.rc-info div{display:flex;gap:8px}
.rc-info .rc-k{width:104px;color:#444;flex-shrink:0}
.rc-info .rc-v{font-weight:600}
.rc-tables{display:flex;gap:6px;align-items:flex-start;position:relative}
.rc-table{border-collapse:collapse;font-size:9.5px}
.rc-table th,.rc-table td{border:1px solid #b9c0c7;padding:5px 6px}
.rc-table thead th{background:#fafbfc;font-weight:800;font-size:8px;vertical-align:bottom}
.rc-table th.rc-vert{
  writing-mode:vertical-rl;transform:rotate(180deg);
  height:104px;padding:6px 3px;white-space:nowrap;text-align:left;
}
.rc-table td.rc-subject{white-space:nowrap}
.rc-table td.rc-num,.rc-table th.rc-num{text-align:center}
.rc-table td.rc-grade{text-align:center;font-weight:800}
.rc-rate-head{width:78px}
.rc-rate-scale{display:flex;gap:5px;font-size:8px;color:#555;margin-top:22px}
.rc-rate-scale span{width:13px;text-align:center}
.rc-stars{display:inline-flex;gap:1px}
.rc-legend{margin-top:12px;font-size:8.5px}
.rc-legend b{display:block;font-size:9px;margin-bottom:3px;letter-spacing:.3px}
.rc-legend span{margin-right:14px;font-weight:700}
.rc-foot{display:flex;justify-content:space-between;align-items:flex-start;margin-top:18px;gap:20px;position:relative}
.rc-qr{width:64px;height:58px;background:#111;color:#fff;font-size:6.5px;font-weight:800;
  display:flex;align-items:center;justify-content:center;text-align:center;line-height:1.3}
.rc-totals{text-align:right;font-size:11px;font-weight:800;line-height:1.7}
.rc-remarks{margin-top:14px;font-size:10px;position:relative}
.rc-remarks .rc-rk{color:#1a3fd0;font-weight:800;font-size:9px;letter-spacing:.3px}
.rc-remarks .rc-rv{font-style:italic;font-size:11px;margin-left:10px}
.rc-rule{height:3px;background:#1a3fd0;margin-top:16px;border-radius:2px}
@media print{
  body *{visibility:hidden}
  .rc-sheet,.rc-sheet *{visibility:visible}
  .rc-sheet{position:absolute;inset:0;margin:0;border-radius:0}
}


/* ── Report card QR (2026-08-13) ── */
.rc-qrwrap{text-align:center}
.rc-qrwrap svg{border:1px solid #e2e6ea;border-radius:4px;background:#fff}
.rc-qrcode{font-size:7px;letter-spacing:.8px;color:#666;margin-top:2px;font-weight:700}


/* ── Report card seal (2026-08-13) ── */
.rc-seal{display:flex;justify-content:flex-end;margin-top:-6px}
.rc-seal img{width:82px;opacity:.95}


/* ── Library: circulation-desk search dropdowns (2026-08-15) ──
   Fixed-positioned (JS sets left/top/width to track the input) so they
   escape .page-section's overflow:hidden instead of being clipped. */
.lib-search-results{
  position:fixed;z-index:10050;background:var(--surface);color:var(--text);
  border:1px solid var(--border);border-radius:10px;max-height:260px;overflow-y:auto;
  display:none;box-shadow:var(--shadow-md,0 8px 28px rgba(0,0,0,.18));
}
.lib-result-row,.lib-book-row{
  padding:9px 12px;cursor:pointer;border-bottom:1px solid var(--border);
}
.lib-result-row:last-child,.lib-book-row:last-child{border-bottom:none}
.lib-result-row:hover,.lib-book-row:hover{background:var(--surface-2)}

/* Announcements: Quill rich-text editor + trusted-HTML notice rendering */
/* The editor is a deliberately theme-independent light surface (like a
   physical sheet of paper) so typed text stays legible in both light and
   dark app themes -- without this, dark mode's near-white --text colour was
   rendering on our white editor background, making typed text invisible. */
.ql-toolbar.ql-snow{border-radius:8px 8px 0 0;background:#f8faf9;border-color:#d4ddd9}
.ql-container.ql-snow{border-radius:0 0 8px 8px;border-color:#d4ddd9}
.ql-editor{min-height:160px;font-family:inherit;font-size:.92rem;background:#fff;color:#172b22}
.ql-editor.ql-blank::before{color:#5e7a6e;font-style:normal}
.ql-editor table{border-collapse:collapse;width:100%;margin:6px 0}
.ql-editor table td,.ql-editor table th{border:1px solid #d4ddd9;padding:6px 8px}
.ann-rich-content{font-size:.92rem}
.ann-rich-content p{margin:0 0 8px}
.ann-rich-content p:last-child{margin-bottom:0}
.ann-rich-content ul,.ann-rich-content ol{margin:0 0 8px 22px;padding:0}
.ann-rich-content img{max-width:100%;border-radius:6px}
.ann-rich-content a{color:var(--primary,#4f46e5)}
.ann-rich-content table{border-collapse:collapse;width:100%;margin:8px 0}
.ann-rich-content td,.ann-rich-content th{border:1px solid var(--border);padding:6px 8px}
.ql-toolbar .ql-ann-table-btn{width:28px;height:24px;padding:0;background:transparent;border:none;cursor:pointer;color:#444;vertical-align:middle}
.ql-toolbar .ql-ann-table-btn:hover{color:#06c}

/* Unread-announcement bubbles, bottom-left of the dashboard */
@keyframes annBubbleIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}
.ann-bubble:hover{box-shadow:0 10px 26px rgba(0,0,0,.2)}
.ann-list-row{transition:box-shadow .12s,background .12s}
.ann-list-row:hover{background:var(--surface-2);box-shadow:0 3px 10px rgba(0,0,0,.08)}

/* Announcements: school -> class -> classroom targeting tree */
.ann-target-tree{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:18px 22px;max-height:340px;overflow-y:auto;border:1px solid var(--border);border-radius:10px;padding:14px;background:var(--surface)}
.ann-target-col-title{font-weight:800;font-size:.78rem;text-transform:uppercase;letter-spacing:.5px;margin-bottom:6px;color:var(--text)}
.ann-target-row{display:flex;align-items:center;gap:8px;padding:3px 0;font-size:.85rem;cursor:pointer;color:var(--text)}
.ann-target-row-strong{font-weight:700}
.ann-target-rooms{margin:0 0 4px 22px;padding-left:10px;border-left:2px solid var(--border)}
.ann-target-row-sub{font-size:.8rem;color:var(--text-muted);padding:2px 0}
.ann-target-row input[type=checkbox]{flex-shrink:0;width:15px;height:15px}

/* Custom Quill table embed (see AnnTableBlot in page.js) */
.ann-table-embed{margin:8px 0}
.ann-table-embed table{cursor:text}

/* ============================================================
   USER MANUAL page
   ============================================================ */
.man-role-banner{display:flex;gap:18px;align-items:flex-start;background:linear-gradient(135deg,var(--primary-l,#d1fae5),var(--surface));border:1px solid var(--border);border-radius:var(--radius-lg,14px);padding:22px 24px;margin-bottom:22px}
.man-role-banner-icon{flex-shrink:0;width:56px;height:56px;border-radius:50%;background:var(--primary);color:#fff;display:flex;align-items:center;justify-content:center;font-size:24px;box-shadow:0 4px 10px rgba(0,0,0,.12)}
.man-role-banner-text h2{font-family:Nunito,sans-serif;font-weight:800;font-size:19px;margin-bottom:4px}
.man-role-banner-text p{color:var(--text-muted);font-size:.88rem;max-width:760px}
.man-role-banner-tips{margin-top:10px;padding-left:18px;font-size:.82rem;color:var(--text-muted)}
.man-role-banner-tips li{margin-bottom:3px}

.man-group{margin-bottom:26px}
.man-group-title{font-family:Nunito,sans-serif;font-weight:800;font-size:14px;letter-spacing:.02em;text-transform:uppercase;color:var(--text-muted);margin-bottom:12px;padding-bottom:6px;border-bottom:1px solid var(--border)}
.man-card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px}

.man-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg,14px);padding:18px;display:flex;flex-direction:column;gap:10px;transition:box-shadow .2s,transform .2s}
.man-card:hover{box-shadow:var(--shadow-md,0 4px 14px rgba(0,0,0,.08));transform:translateY(-1px)}
.man-card-head{display:flex;align-items:center;gap:12px}
.man-card-icon{flex-shrink:0;width:40px;height:40px;border-radius:12px;background:var(--primary-l,#d1fae5);color:var(--primary-d,var(--primary));display:flex;align-items:center;justify-content:center;font-size:17px}
.man-card-head h4{font-family:Nunito,sans-serif;font-weight:800;font-size:15px}
.man-card-what{font-size:.84rem;color:var(--text-muted);line-height:1.5}
.man-card-block h5{font-size:.74rem;font-weight:800;text-transform:uppercase;letter-spacing:.03em;color:var(--text-muted);display:flex;align-items:center;gap:6px;margin-bottom:6px}
.man-card-block ol,.man-card-block ul{padding-left:20px;font-size:.82rem;line-height:1.55}
.man-card-block li{margin-bottom:4px}
.man-tips{background:var(--surface-2,#f7f9f8);border-radius:10px;padding:10px 12px 10px 26px;margin-left:-6px}
.man-tips h5{margin-left:-8px}

@media (max-width:640px){
  .man-role-banner{flex-direction:column;align-items:flex-start}
  .man-card-grid{grid-template-columns:1fr}
}

/* ── Consent Management ─────────────────────────────────────────────
   A Consent Forms row stacks three things in its first cell: the title,
   a summary line and the status badges. At .data-table's default 11px
   cell padding those run into the row above and below, so the list reads
   as one block of text rather than a set of separate forms. Extra
   vertical room and top alignment give each form its own space.

   Only the Consent Forms list gets this; the Responses table underneath
   is single-line per row and reads fine at the default. */
.con-forms-table td { padding-top: 18px; padding-bottom: 18px; vertical-align: top; }
.con-forms-table tbody tr + tr td { border-top: 1px solid var(--border); }

@media (max-width: 768px) {
  /* .data-table's mobile layout already turns each row into its own card
     with its own margin, so the desktop padding would only make the cards
     tall and airy. */
  .con-forms-table td { padding-top: 4px; padding-bottom: 4px; }
}


/* ============================================================
   Mobile fixes + layouts for page-modules.js  (2026-09-01)
   ============================================================ */

/* A long page title ("Performance Reviews", "Leave Management") could not
   shrink. #page-title is a flex item, and a flex item's default
   min-width:auto makes its nowrap text the minimum width of everything
   above it — so the whole header, and with it the app, grew wider than a
   phone screen and picked up a horizontal scroll. These two let the title
   actually ellipsise instead. Nothing changes on a wide screen, where
   there is room and the ellipsis never triggers. */
#main-layout > #header { min-width: 0; }
#page-title { min-width: 0; }

/* Messages: message list beside the conversation on a wide screen,
   stacked on a phone. Without the media query the conversation pane is
   squeezed to a ~50px sliver in the installed app. */
.pm-split {
  display: grid;
  grid-template-columns: minmax(300px, 1fr) minmax(0, 1.4fr);
  gap: 18px;
  align-items: start;
}
@media (max-width: 980px) { .pm-split { grid-template-columns: 1fr; } }

/* "Who is away" calendar: the person beside their bar on a wide screen,
   above it on a phone, where 200px of the width is most of the screen. */
.pm-cal-row {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 12px;
  align-items: center;
  margin-bottom: 8px;
}
@media (max-width: 640px) {
  .pm-cal-row { grid-template-columns: 1fr; gap: 5px; margin-bottom: 14px; }
}

/* Appraisal scoring: the 0..n buttons wrap under the criterion name on a
   narrow screen, and stay a comfortable tap target on a touch device. */
.pm-scale-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border); flex-wrap: wrap;
}
.pm-scale {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 32px; border: 1px solid var(--border); border-radius: 7px;
  font-weight: 700; font-size: .84rem; user-select: none;
}
@media (max-width: 900px) { .pm-scale { width: 40px; height: 40px; } }

/* Two-pane thread view: cap the scroll height on a phone so the reply box
   is always reachable without scrolling the whole page first. */
@media (max-width: 980px) { .pm-thread-scroll { max-height: 60vh; } }
