/* ============================================================
   shared/styles.css
   DESIGN TOKENS
   Carried forward from the existing Viva Smart Classes brand:
   indigo primary (#4f46e5), amber accent (#f59e0b), Poppins for
   display type, Inter for body — centralised here instead of being
   redeclared (and drifting) on every page. Every portal loads this
   file first, then its own <role>.css for page-specific styling.
   ============================================================ */
:root{
  --font-display:'Poppins',sans-serif;
  --font-body:'Inter',sans-serif;

  --bg:#f4f6fb;
  --surface:#ffffff;
  --surface-2:#f8fafc;
  --glass:rgba(255,255,255,.78);
  --border:#e2e8f0;
  --text:#0f172a;
  --text-dark:#1e293b;
  --text-muted:#64748b;


  --primary:#0b5ed7;
  --primary-hover:#0b4aa8;
  --primary-tint:#eef0fd;
  --accent:#f59e0b;
  --accent-tint:#fef3e0;
  --success:#16a34a;
  --danger:#dc2626;
  --warning:#d97706;
  --info:#0891b2;

  --footer-bg:#0b1120;
  --footer-text:#e2e8f0;
  --footer-muted:#94a3b8;

  --radius-sm:10px;
  --radius-md:16px;
  --radius-lg:22px;
  --shadow-sm:0 1px 2px rgba(15,23,42,.06);
  --shadow-md:0 10px 15px -3px rgba(15,23,42,.07),0 4px 6px -4px rgba(15,23,42,.05);
  --shadow-lg:0 20px 25px -5px rgba(15,23,42,.10),0 8px 10px -6px rgba(15,23,42,.05);
  --ease:cubic-bezier(.4,0,.2,1);

  /* Role accent — portals override this one variable to tint their
     sidebar/header without duplicating a whole theme (see each
     <role>.css). Defaults to the brand primary. */
  --role-accent: var(--primary);
  --role-accent-tint: var(--primary-tint);
}

[data-theme="dark"]{
  --bg:#0a0e1a;
  --surface:#121a2e;
  --surface-2:#161d33;
  --glass:rgba(18,26,46,.78);
  --border:#232c48;
  --text:#eef1fa;
  --text-dark:#e5e9f5;
  --text-muted:#8994b3;
  --primary-tint:#1c1f3d;
  --accent-tint:#2a2210;
}

*{box-sizing:border-box;}
html{scroll-behavior:smooth;}
body{
  margin:0;background:var(--bg);color:var(--text);font-family:var(--font-body);
  -webkit-font-smoothing:antialiased;transition:background .25s var(--ease),color .25s var(--ease);
}
h1,h2,h3,h4,h5,h6{font-family:var(--font-display);color:var(--text-dark);margin:0;}
p{margin:0;}
a{color:inherit;text-decoration:none;}
button{font-family:inherit;}
::selection{background:var(--primary);color:#fff;}

::-webkit-scrollbar{width:10px;height:10px;}
::-webkit-scrollbar-track{background:transparent;}
::-webkit-scrollbar-thumb{background:var(--border);border-radius:8px;}
::-webkit-scrollbar-thumb:hover{background:var(--text-muted);}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important;scroll-behavior:auto !important;}
}

:focus-visible{outline:2px solid var(--primary);outline-offset:2px;border-radius:4px;}

/* ---------- Utility classes ----------
   Every portal's JS relies on these Bootstrap-style names (most
   importantly d-none, which showView()-style functions use to hide
   inactive sections) but only Bootstrap ICONS is loaded, never
   Bootstrap's CSS — defined here, matching Bootstrap's own spacing
   scale so existing gap-2/mb-3/etc values look as designed. */
.d-none{display:none !important;}
.d-block{display:block !important;}
.d-flex{display:flex !important;}
.d-inline{display:inline !important;}
.d-inline-flex{display:inline-flex !important;}
.flex-wrap{flex-wrap:wrap !important;}
.flex-column{flex-direction:column !important;}
.flex-fill{flex:1 1 auto !important;}
.justify-content-start{justify-content:flex-start !important;}
.justify-content-center{justify-content:center !important;}
.justify-content-between{justify-content:space-between !important;}
.justify-content-end{justify-content:flex-end !important;}
.align-items-start{align-items:flex-start !important;}
.align-items-center{align-items:center !important;}
.align-items-end{align-items:flex-end !important;}
.w-100{width:100% !important;}
.h-100{height:100% !important;}
.text-muted{color:var(--text-muted) !important;}
.text-center{text-align:center !important;}
.container{width:100%;max-width:1200px;margin:0 auto;padding:0 1.25rem;}
.gap-1{gap:.25rem !important;} .gap-2{gap:.5rem !important;} .gap-3{gap:1rem !important;} .gap-4{gap:1.5rem !important;}
.mt-0{margin-top:0 !important;} .mt-1{margin-top:.25rem !important;} .mt-2{margin-top:.5rem !important;} .mt-3{margin-top:1rem !important;} .mt-4{margin-top:1.5rem !important;}
.mb-0{margin-bottom:0 !important;} .mb-1{margin-bottom:.25rem !important;} .mb-2{margin-bottom:.5rem !important;} .mb-3{margin-bottom:1rem !important;} .mb-4{margin-bottom:1.5rem !important;}
.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important;} .py-2{padding-top:.5rem !important;padding-bottom:.5rem !important;} .py-3{padding-top:1rem !important;padding-bottom:1rem !important;}
.px-1{padding-left:.25rem !important;padding-right:.25rem !important;} .px-2{padding-left:.5rem !important;padding-right:.5rem !important;} .px-3{padding-left:1rem !important;padding-right:1rem !important;}
@media (min-width:576px){
  .d-sm-none{display:none !important;}
  .d-sm-inline-flex{display:inline-flex !important;}
  .d-sm-flex{display:flex !important;}
  .d-sm-inline{display:inline !important;}
}
@media (min-width:768px){
  .d-md-none{display:none !important;}
  .d-md-inline-flex{display:inline-flex !important;}
  .d-md-flex{display:flex !important;}
  .d-md-inline{display:inline !important;}
}

/* ---------- Buttons & icon buttons ---------- */
.btn-brand{
  background:var(--primary);color:#fff;border:none;border-radius:var(--radius-sm);
  padding:.65rem 1.4rem;font-weight:600;font-size:.95rem;display:inline-flex;align-items:center;gap:.5rem;
  cursor:pointer;transition:transform .18s var(--ease),background .18s var(--ease),box-shadow .18s var(--ease);
  box-shadow:0 4px 14px rgba(70, 86, 229, 0.25);
}
.btn-brand:hover{background:var(--primary-hover);transform:translateY(-1px);box-shadow:0 8px 20px rgba(70, 112, 229, 0.35);}
.btn-brand:active{transform:translateY(0);}
.btn-brand:disabled{opacity:.55;cursor:not-allowed;transform:none;box-shadow:none;}
.btn-ghost{
  background:transparent;border:1.5px solid var(--border);color:var(--text-dark);border-radius:var(--radius-sm);
  padding:.6rem 1.3rem;font-weight:600;font-size:.95rem;cursor:pointer;transition:all .18s var(--ease);
}
.btn-ghost:hover{border-color:var(--primary);color:var(--primary);}
.btn-danger-outline{
  background:transparent;border:1.5px solid #fecaca;color:var(--danger);border-radius:var(--radius-sm);
  padding:.5rem 1rem;font-weight:600;font-size:.88rem;cursor:pointer;transition:all .18s var(--ease);
}
.btn-danger-outline:hover{background:#fef2f2;border-color:var(--danger);}
.btn-sm{padding:.4rem .85rem;font-size:.84rem;}
.icon-btn{
  width:40px;height:40px;border-radius:50%;border:1px solid var(--border);background:var(--surface);
  color:var(--text-dark);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;
  font-size:1.05rem;transition:all .18s var(--ease);flex-shrink:0;
}
.icon-btn:hover{background:var(--primary-tint);color:var(--primary);border-color:var(--primary);}

/* ---------- Badges ---------- */
.badge-pill{
  display:inline-flex;align-items:center;gap:.35rem;padding:.28rem .7rem;border-radius:99px;
  font-size:.74rem;font-weight:700;letter-spacing:.02em;text-transform:uppercase;
}
.badge-primary{background:var(--primary-tint);color:var(--primary);}
.badge-accent{background:var(--accent-tint);color:#92400e;}
[data-theme="dark"] .badge-accent{color:var(--accent);}
.badge-success{background:#dcfce7;color:#166534;}
[data-theme="dark"] .badge-success{background:#0f2a1c;color:#4ade80;}
.badge-danger{background:#fee2e2;color:#991b1b;}
[data-theme="dark"] .badge-danger{background:#2a1414;color:#f87171;}
.badge-muted{background:var(--surface-2);color:var(--text-muted);border:1px solid var(--border);}

/* ---------- Skeleton loaders ---------- */
.skel{
  background:linear-gradient(100deg,var(--surface-2) 30%,var(--border) 45%,var(--surface-2) 60%);
  background-size:200% 100%;animation:shimmer 1.4s infinite;border-radius:var(--radius-md);
}
@keyframes shimmer{0%{background-position:180% 0;}100%{background-position:-20% 0;}}

/* ---------- Spinner ---------- */
.spinner{
  width:20px;height:20px;border:2.5px solid rgba(255,255,255,.4);border-top-color:#fff;
  border-radius:50%;animation:spin .7s linear infinite;display:inline-block;
}
.spinner-dark{border:2.5px solid var(--border);border-top-color:var(--primary);}
@keyframes spin{to{transform:rotate(360deg);}}

/* ---------- Empty states ---------- */
.empty-state{
  text-align:center;padding:3.5rem 1.5rem;color:var(--text-muted);
}
.empty-state i{font-size:2.4rem;color:var(--border);display:block;margin-bottom:1rem;}
.empty-state h4{color:var(--text-dark);margin-bottom:.4rem;font-size:1.15rem;}
.empty-state p{max-width:360px;margin:0 auto;font-size:.92rem;}

/* ---------- Toasts ---------- */
.toast-stack{
  position:fixed;top:1.1rem;right:1.1rem;z-index:9999;display:flex;flex-direction:column;gap:.6rem;
  max-width:min(360px,90vw);
}
.toast-item{
  background:var(--surface);color:var(--text-dark);border:1px solid var(--border);border-left:4px solid var(--primary);
  border-radius:var(--radius-sm);padding:.85rem 1rem;box-shadow:var(--shadow-lg);font-size:.88rem;font-weight:500;
  display:flex;align-items:flex-start;gap:.6rem;animation:toastIn .25s var(--ease);
}
.toast-item.success{border-left-color:var(--success);}
.toast-item.error{border-left-color:var(--danger);}
.toast-item.warning{border-left-color:var(--warning);}
.toast-item i{margin-top:.1rem;}
.toast-item.success i{color:var(--success);}
.toast-item.error i{color:var(--danger);}
.toast-item.warning i{color:var(--warning);}
.toast-item.info i{color:var(--info);}
@keyframes toastIn{from{opacity:0;transform:translateX(24px);}to{opacity:1;transform:translateX(0);}}
@keyframes toastOut{to{opacity:0;transform:translateX(24px);}}

/* ---------- Generic overlay modal (confirm dialog + all forms use this) ---------- */
.ov-overlay{
  position:fixed;inset:0;background:rgba(10,14,26,.55);backdrop-filter:blur(3px);
  display:flex;align-items:center;justify-content:center;z-index:9000;padding:1rem;
  opacity:0;pointer-events:none;transition:opacity .2s var(--ease);
}
.ov-overlay.open{opacity:1;pointer-events:auto;}
.ov-box{
  background:var(--surface);border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);
  width:100%;max-width:460px;padding:1.6rem;transform:translateY(14px) scale(.98);
  transition:transform .22s var(--ease);max-height:88vh;overflow-y:auto;
}
.ov-overlay.open .ov-box{transform:translateY(0) scale(1);}
.ov-box.wide{max-width:680px;}
.ov-box h4{font-size:1.15rem;margin-bottom:.5rem;}
.ov-box p{color:var(--text-muted);font-size:.92rem;line-height:1.55;}
.ov-actions{display:flex;justify-content:flex-end;gap:.6rem;margin-top:1.4rem;}

/* ---------- Form controls (shared by every search box + every form in every portal) ---------- */
.field-group{margin-bottom:1.1rem;}
.field-label{display:block;font-size:.82rem;font-weight:700;color:var(--text-dark);margin-bottom:.4rem;}
.field-label .req{color:var(--danger);}
.field-hint{font-size:.76rem;color:var(--text-muted);margin-top:.3rem;}
.field-input,.field-select,.field-textarea{
  width:100%;padding:.65rem .85rem;border:1.5px solid var(--border);border-radius:var(--radius-sm);
  background:var(--surface);color:var(--text);font-size:.92rem;font-family:inherit;
  transition:border-color .18s var(--ease),box-shadow .18s var(--ease);
}
.field-input:focus,.field-select:focus,.field-textarea:focus{
  outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint);
}
.field-textarea{resize:vertical;min-height:80px;}
.field-row{display:grid;grid-template-columns:1fr 1fr;gap:.9rem;}
.field-check{display:flex;align-items:center;gap:.55rem;font-size:.88rem;font-weight:600;color:var(--text-dark);cursor:pointer;}
.field-check input{width:17px;height:17px;accent-color:var(--primary);cursor:pointer;}
.field-color{width:44px;height:38px;padding:2px;border:1.5px solid var(--border);border-radius:var(--radius-sm);cursor:pointer;background:var(--surface);}

/* A scrollable 2-column checkbox grid — used for "which classes/subjects
   is this student enrolled in" pickers. Shared because both the
   admin/principal Add Student form and the teacher Add Student form need
   the exact same control. */
.subject-check-grid{display:grid;grid-template-columns:1fr 1fr;gap:.4rem .8rem;max-height:160px;overflow-y:auto;border:1px solid var(--border);border-radius:var(--radius-sm);padding:.7rem .8rem;}
.subject-check-grid label{display:flex;align-items:center;gap:.45rem;font-size:.83rem;cursor:pointer;}
.subject-check-grid input{width:auto;}

/* ---------- Avatars (photo, or a colored initial when there's none) ----------
   Replaces every previous use of the now-defunct via.placeholder.com —
   nothing in this app depends on an external image service to show a
   profile picture. Used by avatarHtml() in shared/utils.js. */
.avatar-img{border-radius:50%;object-fit:cover;border:2px solid var(--surface);box-shadow:0 0 0 1px var(--border);flex-shrink:0;}
.avatar-fallback{
  border-radius:50%;display:inline-flex;align-items:center;justify-content:center;color:#fff;font-weight:700;
  font-family:var(--font-display);flex-shrink:0;border:2px solid var(--surface);box-shadow:0 0 0 1px var(--border);
}

/* ---------- Photo picker (profile edit modals, every role) ---------- */
.photo-picker{display:flex;align-items:center;gap:1rem;margin-bottom:1.1rem;}
.photo-picker input[type="file"]{display:none;}
.photo-picker .photo-picker-actions{display:flex;flex-direction:column;gap:.4rem;}
.photo-picker .photo-picker-hint{font-size:.76rem;color:var(--text-muted);}

@media (max-width:576px){
  .field-row{grid-template-columns:1fr;}
  .toast-stack{left:1rem;right:1rem;max-width:none;}
}
