
  :root{
    --bg:#F0F8F8; --card:#ffffff; --border:#dbe8f0; --border-strong:#c3d8e6;
    --text:#002050; --text-sec:#607080; --text-muted:#93a0b0;
    --accent:#147DEB; --accent-bg:#E0F0F8; --accent-light:#a9d4f0;
    --success:#18A878; --success-bg:#e0f7ef;
    --danger:#F0444A; --danger-bg:#fde3e4;
    --warning:#F5A623; --warning-bg:#fef0da;
    --radius:10px;
    /* Per-section accents: deep, jewel-tone gradients rather than bright pastel ones, so each
       section keeps its own identity but reads as a considered corporate palette rather than a
       playful/candy one. */
    --c-dashboard:#0878E8; --c-dashboard-bg:linear-gradient(135deg,#147DEB,#002050);
    --c-students:#0b6b3a; --c-students-bg:linear-gradient(135deg,#1c8a52,#08512b);
    --c-teachers:#7040E8; --c-teachers-bg:linear-gradient(135deg,#8a5cf0,#4d22b0);
    --c-fees:#F0B020; --c-fees-bg:linear-gradient(135deg,#f5c04a,#c98c10);
    --c-receipts:#18A8C8; --c-receipts-bg:linear-gradient(135deg,#2fc4e2,#0f7a92);
    --c-attendance:#F5A623; --c-attendance-bg:linear-gradient(135deg,#f7b84d,#c9791a);
    --c-reports:#4340b0; --c-reports-bg:linear-gradient(135deg,#5551c9,#312e86);
    --c-settings:#3f4854; --c-settings-bg:linear-gradient(135deg,#57626f,#2c333c);
    --c-exams:#8f2a17; --c-exams-bg:linear-gradient(135deg,#a83f28,#6b1c0e);
    --c-examroutine:#8f5a17; --c-examroutine-bg:linear-gradient(135deg,#c67f1f,#7a4a0e);
    --c-quiz:#8a6d1e; --c-quiz-bg:linear-gradient(135deg,#a9871f,#6b5314);
    --c-routine:#146357; --c-routine-bg:linear-gradient(135deg,#1d7d6c,#0c4a40);
    --c-notices:#a8471f; --c-notices-bg:linear-gradient(135deg,#c25f31,#7a2f10);
    --c-bkash:#b30e58; --c-bkash-bg:linear-gradient(135deg,#cc1568,#850d42);
    --c-courses:#5638b0; --c-courses-bg:linear-gradient(135deg,#6f4fc9,#3e2789);
    --c-duelist:#a83a12; --c-duelist-bg:linear-gradient(135deg,#c24f22,#7a2a0d);
    --c-sms:#0e7490; --c-sms-bg:linear-gradient(135deg,#1592b3,#0a5166);
    /* type */
    --font-display:"Baloo Da 2","Segoe UI","Hind Siliguri",sans-serif;
    --font-body:"Hind Siliguri",-apple-system,"Segoe UI","Hind Siliguri",Roboto,sans-serif;
    /* elevation: soft, tinted shadows read as more premium than plain black shadows */
    --shadow-sm:0 1px 2px rgba(20,30,50,0.05), 0 1px 3px rgba(20,30,50,0.04);
    --shadow-md:0 4px 12px rgba(20,30,50,0.07), 0 2px 4px rgba(20,30,50,0.05);
    --shadow-lg:0 10px 28px rgba(20,30,50,0.12), 0 4px 10px rgba(20,30,50,0.06);
    --radius-sm:8px; --radius-lg:16px; --radius-xl:20px;
    --ease:cubic-bezier(.2,.8,.2,1);
  }
  /* Dark mode: overrides the same custom properties (attribute selector on <html> beats
     the plain :root rule above, so no other CSS needs to change - every existing var(--x)
     usage throughout the app just picks up the dark value automatically). Section accent
     gradients (--c-dashboard-bg etc.) are already deep jewel tones, so they're left as-is
     and read fine on a dark background too. */
  html[data-theme="dark"]{
    --bg:#12151c; --card:#1b1f28; --border:#2a2f3a; --border-strong:#3a4150;
    --text:#e8e9ec; --text-sec:#a3a8b4; --text-muted:#767c89;
    --accent:#6db2ea; --accent-bg:#1c3450; --accent-light:#2d5580;
    --success:#3fcf85; --success-bg:#123826;
    --danger:#f0697c; --danger-bg:#3d1b22;
    --warning:#e8ab55; --warning-bg:#3d2c10;
    --shadow-sm:0 1px 2px rgba(0,0,0,0.3), 0 1px 3px rgba(0,0,0,0.25);
    --shadow-md:0 4px 12px rgba(0,0,0,0.35), 0 2px 4px rgba(0,0,0,0.3);
    --shadow-lg:0 10px 28px rgba(0,0,0,0.45), 0 4px 10px rgba(0,0,0,0.35);
  }
  /* Dark-mode button inside the logged-in top bars + dark fixes for the shared portal shell
     (top bar / profile menu were hard-coded white, brand text hard-coded navy). */
  .sd-theme-btn{ background:var(--bg); border:1px solid var(--border); border-radius:50%; width:38px; height:38px; display:flex; align-items:center; justify-content:center; font-size:20.5px; color:var(--text); padding:0; cursor:pointer; flex:none; }
  .sd-theme-btn:hover{ border-color:var(--accent); color:var(--accent); transform:none; }
  html[data-theme="dark"] .sd-topbar, html[data-theme="dark"] .sd-profile-menu{ background:var(--card); }
  html[data-theme="dark"] .sd-topbar-brand-text b, html[data-theme="dark"] .sd-hamburger, html[data-theme="dark"] .sd-bell{ color:var(--text); }
  /* Bigger, thicker portal top bar + larger text (shared by admin/student/teacher/staff shells).
     Sidebar offset must match the top bar height (72px desktop / 64px mobile). */
  .sd-shell .sd-topbar{ min-height:72px; padding:12px 22px; gap:14px; }
  .sd-shell .sd-topbar-brand{ gap:11px; }
  .sd-shell .sd-topbar-brand img{ width:44px; height:44px; }
  .sd-shell .sd-topbar-brand-text b{ font-size:23px; }
  .sd-shell .sd-topbar-brand-text span{ font-size:15px; }
  .sd-shell .sd-topbar-actions{ gap:12px; }
  .sd-shell .sd-bell, .sd-shell .sd-theme-btn, .sd-shell .sd-topbar-actions button.small{ width:42px !important; height:42px !important; font-size:23px; }
  .sd-shell .sd-topbar-actions button.small .ti{ font-size:23px; }
  .sd-shell .sd-topbar-actions button.small#app-lang-toggle-btn{ font-size:15px !important; }
  .sd-shell .sd-profile-chip{ gap:10px; padding:4px 14px 4px 4px; }
  .sd-shell .sd-profile-chip img, .sd-shell .sd-profile-chip .avatar{ width:38px !important; height:38px !important; }
  .sd-shell .sd-profile-chip-text b{ font-size:17px; }
  .sd-shell .sd-profile-chip-text span{ font-size:14px; }
  .sd-shell .sd-profile-menu{ min-width:190px; }
  .sd-shell .sd-profile-menu button{ font-size:17px; padding:10px 12px; }
  .sd-shell .sd-topbar-search{ height:42px; }
  .sd-shell .sd-topbar-search input{ font-size:17px; }
  .sd-shell .sd-sidebar.tabs{ top:72px; height:calc(100vh - 72px); }
  .sd-shell .sd-sidebar.tabs .tab{ font-size:18px; }
  .sd-shell .sd-sidebar.tabs .tab i{ font-size:24px; width:24px; }
  @media (max-width:900px){
    .sd-shell .sd-topbar{ min-height:64px; padding:10px 14px; gap:10px; }
    .sd-shell .sd-topbar-brand img{ width:38px; height:38px; }
    .sd-shell .sd-topbar-brand-text b{ font-size:20.5px; }
    .sd-shell .sd-hamburger{ font-size:30px; }
    .sd-shell .sd-sidebar.tabs{ top:0; height:100vh; padding-top:80px; }
  }
  .pw-wrap{ position:relative; display:block; }
  .pw-wrap > input{ width:100%; }
  .pw-eye-btn{ all:unset; box-sizing:border-box; position:absolute; right:6px; top:50%; transform:translateY(-50%); width:36px; height:36px; display:grid; place-items:center; border-radius:8px; cursor:pointer; color:var(--text-sec); font-size:22px; }
  .pw-eye-btn:hover{ color:var(--accent); background:var(--bg); }
  .pw-eye-btn:focus-visible{ outline:2px solid var(--accent); outline-offset:1px; }
  * { box-sizing: border-box; }
  @media (prefers-reduced-motion: reduce){
    *{ animation-duration:0.001ms !important; animation-iteration-count:1 !important; transition-duration:0.001ms !important; }
  }
  ::selection{ background:var(--accent-light); color:var(--accent); }
  ::-webkit-scrollbar{ width:10px; height:10px; }
  ::-webkit-scrollbar-track{ background:transparent; }
  ::-webkit-scrollbar-thumb{ background:var(--border-strong); border-radius:20px; }
  ::-webkit-scrollbar-thumb:hover{ background:var(--text-muted); }
  :focus-visible{ outline:2px solid var(--accent); outline-offset:2px; border-radius:4px; }
  /* Icons: real Tabler Icons webfont (loaded via <link> in <head>) is the default -
     professional line-icons, not emoji. If that webfont fails to load (slow/blocked
     connection), the inline script in <head> adds .icons-fallback to <html> within 2s,
     which activates the emoji-content rules below as a resilient fallback so icons are
     never blank. The higher-specificity "html.icons-fallback ..." selector means these
     rules only apply once that class is present - by default the real webfont wins. */
  .ti{ display:inline-block; line-height:1; font-style:normal; }
  html.icons-fallback .ti::before{ font-family:"Segoe UI Emoji","Noto Color Emoji","Apple Color Emoji",sans-serif; }
  html.icons-fallback .ti-alert-circle::before{ content:"❗"; }
  html.icons-fallback .ti-alert-triangle::before{ content:"⚠️"; }
  html.icons-fallback .ti-arrow-right::before{ content:"➡️"; }
  html.icons-fallback .ti-atom::before{ content:"⚛️"; }
  html.icons-fallback .ti-award::before{ content:"🎖️"; }
  html.icons-fallback .ti-bell-ringing::before{ content:"🔔"; }
  html.icons-fallback .ti-book-2::before{ content:"📖"; }
  html.icons-fallback .ti-books::before{ content:"📚"; }
  html.icons-fallback .ti-bulb::before{ content:"💡"; }
  html.icons-fallback .ti-brand-google-drive::before{ content:"📁"; }
  html.icons-fallback .ti-brand-whatsapp::before{ content:"💬"; }
  html.icons-fallback .ti-cake::before{ content:"🎂"; }
  html.icons-fallback .ti-calendar-check::before{ content:"🗓️"; }
  html.icons-fallback .ti-calendar-off::before{ content:"📅"; }
  html.icons-fallback .ti-calendar-plus::before{ content:"📅"; }
  html.icons-fallback .ti-calendar-stats::before{ content:"🗓️"; }
  html.icons-fallback .ti-calendar-time::before{ content:"🗓️"; }
  html.icons-fallback .ti-camera::before{ content:"📷"; }
  html.icons-fallback .ti-cash::before{ content:"💰"; }
  html.icons-fallback .ti-cash-banknote::before{ content:"💵"; }
  html.icons-fallback .ti-certificate::before{ content:"📜"; }
  html.icons-fallback .ti-chalkboard::before{ content:"🎓"; }
  html.icons-fallback .ti-check::before{ content:"✔️"; }
  html.icons-fallback .ti-checks::before{ content:"✅"; }
  html.icons-fallback .ti-chevron-left::before{ content:"⬅️"; }
  html.icons-fallback .ti-chevron-right::before{ content:"➡️"; }
  html.icons-fallback .ti-circle-check::before{ content:"✅"; }
  html.icons-fallback .ti-circle-x::before{ content:"❌"; }
  html.icons-fallback .ti-cloud-check::before{ content:"☁️"; }
  html.icons-fallback .ti-cloud-upload::before{ content:"☁️"; }
  html.icons-fallback .ti-device-floppy::before{ content:"💾"; }
  html.icons-fallback .ti-device-laptop::before{ content:"💻"; }
  html.icons-fallback .ti-device-mobile::before{ content:"📱"; }
  html.icons-fallback .ti-download::before{ content:"⬇️"; }
  html.icons-fallback .ti-edit::before{ content:"✏️"; }
  html.icons-fallback .ti-eye::before{ content:"👁️"; }
  html.icons-fallback .ti-eye-off::before{ content:"🚫👁️"; }
  html.icons-fallback .ti-file-import::before{ content:"📥"; }
  html.icons-fallback .ti-file-spreadsheet::before{ content:"📊"; }
  html.icons-fallback .ti-file-type-pdf::before{ content:"📄"; }
  html.icons-fallback .ti-file-word::before{ content:"📘"; }
  html.icons-fallback .ti-file-zip::before{ content:"🗜️"; }
  html.icons-fallback .ti-flask::before{ content:"🧪"; }
  html.icons-fallback .ti-forms::before{ content:"📝"; }
  html.icons-fallback .ti-history::before{ content:"🕓"; }
  html.icons-fallback .ti-info-circle::before{ content:"ℹ️"; }
  html.icons-fallback .ti-language::before{ content:"🗣️"; }
  html.icons-fallback .ti-layout-dashboard::before{ content:"🗂️"; }
  html.icons-fallback .ti-link::before{ content:"🔗"; }
  html.icons-fallback .ti-list-check::before{ content:"☑️"; }
  html.icons-fallback .ti-list-details::before{ content:"📋"; }
  html.icons-fallback .ti-login::before{ content:"🔑"; }
  html.icons-fallback .ti-logout::before{ content:"🚪"; }
  html.icons-fallback .ti-mail::before{ content:"✉️"; }
  html.icons-fallback .ti-map-pin-filled::before{ content:"📍"; }
  html.icons-fallback .ti-math-function::before{ content:"🧮"; }
  html.icons-fallback .ti-medal::before{ content:"🏅"; }
  html.icons-fallback .ti-message::before{ content:"💬"; }
  html.icons-fallback .ti-message-2::before{ content:"🗨️"; }
  html.icons-fallback .ti-microscope::before{ content:"🔬"; }
  html.icons-fallback .ti-plug::before{ content:"🔌"; }
  html.icons-fallback .ti-plug-x::before{ content:"⚡"; }
  html.icons-fallback .ti-plus::before{ content:"➕"; }
  html.icons-fallback .ti-printer::before{ content:"🖨️"; }
  html.icons-fallback .ti-receipt::before{ content:"🧾"; }
  html.icons-fallback .ti-report::before{ content:"📈"; }
  html.icons-fallback .ti-report-analytics::before{ content:"📊"; }
  html.icons-fallback .ti-school::before{ content:"🏫"; }
  html.icons-fallback .ti-search::before{ content:"🔍"; }
  html.icons-fallback .ti-search-off::before{ content:"🔍"; }
  html.icons-fallback .ti-send::before{ content:"📤"; }
  html.icons-fallback .ti-settings::before{ content:"⚙️"; }
  html.icons-fallback .ti-shield-check::before{ content:"🛡️"; }
  html.icons-fallback .ti-shield-lock::before{ content:"🔒"; }
  html.icons-fallback .ti-speakerphone::before{ content:"📢"; }
  html.icons-fallback .ti-trash::before{ content:"🗑️"; }
  html.icons-fallback .ti-trash-x::before{ content:"🗑️"; }
  html.icons-fallback .ti-trophy::before{ content:"🏆"; }
  html.icons-fallback .ti-upload::before{ content:"⬆️"; }
  html.icons-fallback .ti-user-exclamation::before{ content:"❗"; }
  html.icons-fallback .ti-user-check::before{ content:"✅"; }
  html.icons-fallback .ti-user-off::before{ content:"🚫"; }
  html.icons-fallback .ti-user-plus::before{ content:"👤➕"; }
  html.icons-fallback .ti-user-shield::before{ content:"🧑‍💼"; }
  html.icons-fallback .ti-user-star::before{ content:"⭐"; }
  html.icons-fallback .ti-moon::before{ content:"🌙"; }
  html.icons-fallback .ti-sun::before{ content:"☀️"; }
  html.icons-fallback .ti-users::before{ content:"👥"; }
  html.icons-fallback .ti-users-group::before{ content:"👥"; }
  html.icons-fallback .ti-wand::before{ content:"✨"; }
  html.icons-fallback .ti-x::before{ content:"✖️"; }
  body{
    margin:0; font-family: var(--font-body);
    background: var(--bg); color: var(--text); font-size:17px; -webkit-font-smoothing:antialiased;
  }
  h1,h2,h3,h4{ font-family:var(--font-display); letter-spacing:.2px; }
  /* Continuous rainbow-gradient text for headings across every portal (admin dashboard,
     student portal, teacher portal). Excluded on purpose: the app/brand title
     ("প্রিজম একাডেমিক কেয়ার", always an <h1> or an element carrying .brand-title) and the
     "ড্যাশবোর্ড" section heading (.brand-title) - those get their own dedicated gradient
     below instead of this one, so the brand name reads as "the logo" rather than just
     another animated section heading. */
  h2:not(.brand-title):not(.sr-only), h3:not(.brand-title), h4:not(.brand-title){
    background:linear-gradient(90deg,#ff2d55,#ff9500,#ffcc00,#34c759,#00c7be,#0a84ff,#5e5ce6,#ff2d55);
    background-size:300% 100%;
    -webkit-background-clip:text; background-clip:text;
    color:transparent !important; -webkit-text-fill-color:transparent;
    animation:rainbow-text-shift 6s linear infinite;
  }
  /* The brand name/logo text itself now gets its own shimmering gradient too (separate
     from the rule above so it keeps reading as "the logo", not just another animated
     heading). Two variants: this base one is for every .brand-title on a plain white/card
     background (login screen, portal headers, PDF report header) - deep jewel tones like
     the rest of the app's section colors, saturated enough to stay legible as text fill. */
  .brand-title{
    background:linear-gradient(90deg,#0b6b3a,#F5A623,#0878E8,#7040E8,#18A8C8,#F0B020,#0b6b3a);
    background-size:300% 100%;
    -webkit-background-clip:text; background-clip:text;
    color:transparent !important; -webkit-text-fill-color:transparent;
    animation:rainbow-text-shift 8s linear infinite;
  }
  @keyframes rainbow-text-shift{ from{ background-position:0% 50%; } to{ background-position:300% 50%; } }
  .app{ max-width:1800px; margin:0 auto; padding:16px; }
  header{
    position:relative; overflow:hidden;
    display:flex; align-items:center; justify-content:space-between; margin-bottom:18px; flex-wrap:wrap; gap:10px;
    background: linear-gradient(120deg,#123f6b 0%, #1d6fa8 50%, #0a6b6b 100%);
    border-radius:var(--radius-lg); padding:16px 20px; color:#fff; box-shadow:var(--shadow-lg);
  }
  /* Signature "prism" motif: a thin spectrum strip along the header's top edge, echoing
     the app's own per-section color identity (dashboard/students/fees/... colors below). */
  header::before{
    content:""; position:absolute; inset:0 0 auto 0; height:4px;
    background:linear-gradient(90deg,var(--c-students),var(--c-attendance),var(--c-dashboard),var(--c-teachers),var(--c-receipts),var(--c-fees));
  }
  header::after{
    content:""; position:absolute; right:-40px; top:-40px; width:160px; height:160px; border-radius:50%;
    background:radial-gradient(circle,rgba(255,255,255,0.14),transparent 70%); pointer-events:none;
  }
  header h1{ font-family:var(--font-display); font-size:28.5px; font-weight:800; margin:0; display:flex; align-items:center; gap:8px; color:#fff; letter-spacing:.3px; text-shadow:0 1px 3px rgba(0,0,0,0.15); line-height:1.25; }
  /* On the header itself the background is already a dark blue/teal gradient, so the
     jewel-tone .brand-title gradient above wouldn't have enough contrast - use a bright
     gold/white/cyan shimmer instead, and drop the text-shadow (it muddies gradient-filled
     text). Higher specificity than "header h1" above wins this without needing !important
     on its own, but color/-webkit-text-fill-color still need it to beat the plain #fff. */
  header h1.brand-title{
    background:none;
    color:#ffffff !important; -webkit-text-fill-color:#ffffff;
    text-shadow:0 1px 3px rgba(0,0,0,0.15); animation:none;
  }
  header p{ color:rgba(255,255,255,0.9) !important; font-size:15.5px !important; font-weight:500; letter-spacing:.1px; }
  header .save-note{ background:rgba(255,255,255,0.18); color:#fff; border-radius:20px; padding:6px 12px; backdrop-filter:blur(6px); }
  .tabs{ display:flex; gap:7px; margin-bottom:18px; overflow-x:auto; padding-bottom:4px; scrollbar-width:thin; }
  .tab{
    padding:9px 15px; cursor:pointer; font-size:17.5px; color:var(--text-sec);
    white-space:nowrap; display:flex; gap:6px; align-items:center; border-radius:20px; border:1.5px solid var(--border);
    background:var(--card); font-weight:600; transition:transform .15s var(--ease), box-shadow .15s var(--ease), background .15s, color .15s, border-color .15s;
  }
  .tab:hover{ transform:translateY(-1px); border-color:var(--border-strong); }
  .tab.active{ color:#fff; border-color:transparent; box-shadow:var(--shadow-md); transform:translateY(-1px); }
  .tab[data-tab="dashboard"].active{ background:var(--c-dashboard-bg); }
  .tab[data-tab="students"].active{ background:var(--c-students-bg); }
  .tab[data-tab="teachers"].active{ background:var(--c-teachers-bg); }
  .tab[data-tab="staff"].active{ background:var(--c-teachers-bg); }
  .tab[data-tab="fees"].active{ background:var(--c-fees-bg); }
  .tab[data-tab="receipts"].active{ background:var(--c-receipts-bg); }
  .tab[data-tab="attendance"].active{ background:var(--c-attendance-bg); }
  .tab[data-tab="reports"].active{ background:var(--c-reports-bg); }
  .tab[data-tab="settings"].active{ background:var(--c-settings-bg); }
  .tab[data-tab="bkash"].active{ background:var(--c-bkash-bg); }
  .tab[data-tab="exams"].active{ background:var(--c-exams-bg); }
  .tab[data-tab="examRoutine"].active{ background:var(--c-examroutine-bg); }
  .tab[data-tab="quiz"].active{ background:var(--c-quiz-bg); }
  .tab[data-tab="routine"].active{ background:var(--c-routine-bg); }
  .tab[data-tab="notices"].active{ background:var(--c-notices-bg); }
  .tab[data-tab="duelist"].active{ background:var(--c-duelist-bg); }
  .tab[data-tab="sms"].active{ background:var(--c-sms-bg); }
  .tab[data-tab="courses"].active{ background:var(--c-courses-bg); }
  /* Idle (non-active) tabs: a soft tint of each tab's own color on the icon and border, so
     every tab reads as its own color at a glance instead of all of them looking the same
     plain white/gray until clicked - only the label text stays the neutral --text-sec. */
  .tab:not(.active) .ti{ opacity:.85; }
  .tab[data-tab="dashboard"]:not(.active){ color:var(--c-dashboard); border-color:color-mix(in srgb, var(--c-dashboard) 35%, var(--border)); }
  .tab[data-tab="students"]:not(.active){ color:var(--c-students); border-color:color-mix(in srgb, var(--c-students) 35%, var(--border)); }
  .tab[data-tab="teachers"]:not(.active){ color:var(--c-teachers); border-color:color-mix(in srgb, var(--c-teachers) 35%, var(--border)); }
  .tab[data-tab="staff"]:not(.active){ color:var(--c-teachers); border-color:color-mix(in srgb, var(--c-teachers) 35%, var(--border)); }
  .tab[data-tab="fees"]:not(.active){ color:var(--c-fees); border-color:color-mix(in srgb, var(--c-fees) 35%, var(--border)); }
  .tab[data-tab="receipts"]:not(.active){ color:var(--c-receipts); border-color:color-mix(in srgb, var(--c-receipts) 35%, var(--border)); }
  .tab[data-tab="attendance"]:not(.active){ color:var(--c-attendance); border-color:color-mix(in srgb, var(--c-attendance) 35%, var(--border)); }
  .tab[data-tab="reports"]:not(.active){ color:var(--c-reports); border-color:color-mix(in srgb, var(--c-reports) 35%, var(--border)); }
  .tab[data-tab="settings"]:not(.active){ color:var(--c-settings); border-color:color-mix(in srgb, var(--c-settings) 35%, var(--border)); }
  .tab[data-tab="bkash"]:not(.active){ color:var(--c-bkash); border-color:color-mix(in srgb, var(--c-bkash) 35%, var(--border)); }
  .tab[data-tab="exams"]:not(.active){ color:var(--c-exams); border-color:color-mix(in srgb, var(--c-exams) 35%, var(--border)); }
  .tab[data-tab="examRoutine"]:not(.active){ color:var(--c-examroutine); border-color:color-mix(in srgb, var(--c-examroutine) 35%, var(--border)); }
  .tab[data-tab="quiz"]:not(.active){ color:var(--c-quiz); border-color:color-mix(in srgb, var(--c-quiz) 35%, var(--border)); }
  .tab[data-tab="routine"]:not(.active){ color:var(--c-routine); border-color:color-mix(in srgb, var(--c-routine) 35%, var(--border)); }
  .tab[data-tab="notices"]:not(.active){ color:var(--c-notices); border-color:color-mix(in srgb, var(--c-notices) 35%, var(--border)); }
  .tab[data-tab="duelist"]:not(.active){ color:var(--c-duelist); border-color:color-mix(in srgb, var(--c-duelist) 35%, var(--border)); }
  .tab[data-tab="sms"]:not(.active){ color:var(--c-sms); border-color:color-mix(in srgb, var(--c-sms) 35%, var(--border)); }
  .tab[data-tab="courses"]:not(.active){ color:var(--c-courses); border-color:color-mix(in srgb, var(--c-courses) 35%, var(--border)); }
  /* Student/teacher/staff self-service portals: each portal's cards are grouped into
     step-tabs (see portalTabBtn/.portal-tab-panel) instead of one long scrolling page.
     These tabs use custom data-ptab ids (not the fixed dashboard/students/... set above),
     so they get one shared accent color instead of the per-section colors above. */
  .portal-tabs .tab.active{ background:linear-gradient(135deg,#1d6fa8,var(--accent)); color:#fff; }
  .portal-tabs .tab:not(.active){ color:var(--accent); border-color:var(--accent-light); }
  .card{
    background:var(--card); border:1px solid var(--border); border-radius:var(--radius-lg); padding:18px;
    margin-bottom:14px; box-shadow:var(--shadow-sm);
    transition:box-shadow .22s var(--ease), transform .22s var(--ease), border-color .22s var(--ease);
  }
  /* Entrance animation is gated by JS, not always-on: render() rebuilds the whole page's HTML
     on every data change (including background Firestore syncs), so an always-on entrance
     animation used to replay on every single re-render, many times a minute, showing up as
     constant on-screen "shaking". render() now only adds #tab-content's "tab-entering" class
     when the visible tab actually changed (a real navigation) - a same-tab background refresh
     gets no animation class, so its cards just appear instantly with no replay. Hover/press
     below is separately safe because it only ever fires on user interaction. */
  .card:hover{ transform:translateY(-3px); box-shadow:var(--shadow-lg); border-color:var(--border-strong); }
  .card:active{ transform:translateY(-1px); }
  @keyframes card-in{ from{ opacity:0; transform:translateY(10px); } to{ opacity:1; transform:translateY(0); } }
  #tab-content.tab-entering > .card{ animation:card-in .4s var(--ease) both; }
  #tab-content.tab-entering > .card:nth-child(1){ animation-delay:0ms; }
  #tab-content.tab-entering > .card:nth-child(2){ animation-delay:45ms; }
  #tab-content.tab-entering > .card:nth-child(3){ animation-delay:90ms; }
  #tab-content.tab-entering > .card:nth-child(4){ animation-delay:135ms; }
  #tab-content.tab-entering > .card:nth-child(5){ animation-delay:180ms; }
  #tab-content.tab-entering > .card:nth-child(n+6){ animation-delay:220ms; }
  /* Mobile swipe-between-tabs (see attachTabSwipeEvents in JS): when a tab switch was
     triggered by a swipe rather than a tap, the whole content block slides in from the
     direction the next tab "arrives" from, instead of the card-by-card fade-up above -
     this is what makes it read as flipping through slides one after another. */
  @keyframes tab-slide-from-right{ from{ opacity:0; transform:translateX(28px); } to{ opacity:1; transform:translateX(0); } }
  @keyframes tab-slide-from-left{ from{ opacity:0; transform:translateX(-28px); } to{ opacity:1; transform:translateX(0); } }
  #tab-content.tab-slide-next{ animation:tab-slide-from-right .28s var(--ease) both; }
  #tab-content.tab-slide-prev{ animation:tab-slide-from-left .28s var(--ease) both; }
  /* Notification bell: the 🔔 icon only ever renders when there's something to act on (e.g.
     the "বকেয়া রিমাইন্ডার পাঠান" button, which only appears while dueStudentCount>0), so a
     gentle continuous ring/wiggle is safe here - unlike .card above, this icon isn't rebuilt
     on every background sync, it simply isn't in the DOM at all when there's nothing to flag. */
  @keyframes bell-ring{
    0%,6%,100%{ transform:rotate(0deg); }
    1%{ transform:rotate(14deg); }
    2%{ transform:rotate(-12deg); }
    3%{ transform:rotate(9deg); }
    4%{ transform:rotate(-7deg); }
    5%{ transform:rotate(3deg); }
  }
  .ti-bell-ringing::before{ display:inline-block; transform-origin:50% 0%; animation:bell-ring 2.4s ease-in-out infinite; }
  .grid-stats{ display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:12px; margin-bottom:18px; }
  .stat{
    position:relative; overflow:hidden; border-radius:var(--radius-lg); padding:16px 18px; border:none; color:#fff;
    box-shadow:var(--shadow-md); transition:transform .18s var(--ease), box-shadow .18s var(--ease);
  }
  .stat:hover{ transform:translateY(-2px); box-shadow:var(--shadow-lg); }
  .stat::after{ content:""; position:absolute; right:-18px; bottom:-22px; width:80px; height:80px; border-radius:50%; background:rgba(255,255,255,0.12); }
  .stat .label{ font-size:16.5px; color:rgba(255,255,255,0.9); margin-bottom:6px; font-weight:600; }
  .stat .icon{
    font-size:24px; opacity:1; margin-bottom:10px;
    display:inline-flex; align-items:center; justify-content:center;
    width:40px; height:40px; border-radius:50%;
    background:rgba(255,255,255,0.22);
    box-shadow:inset 0 1px 1px rgba(255,255,255,0.35), 0 2px 6px rgba(0,0,0,0.1);
  }
  .stat .value{ font-family:var(--font-display); font-size:31px; font-weight:700; color:#fff; }
  .stat.c1{ background:linear-gradient(135deg,#2b7fd6,#185fa5); }
  .stat.c2{ background:linear-gradient(135deg,#22b06b,#0f8a4b); }
  .stat.c3{ background:linear-gradient(135deg,#f2a83e,#e08a1e); }
  .stat.c4{ background:linear-gradient(135deg,#f0568e,#d6336c); }
  /* Dedicated to any "বকেয়া" (outstanding/due) figure - kept visually separate from c1-c4
     so every due amount reads the same clear red wherever it's shown, instead of sharing
     a color with unrelated stats. */
  .stat.due{ background:linear-gradient(135deg,#e5484d,#c81e3a); }
  /* Softer amber tone for the "মোট বকেয়া" card on the STUDENT-facing portal only -
     keeps it noticeable without the alarming red used in the admin/teacher dashboards. */
  .stat.due-soft{ background:linear-gradient(135deg,#f2a83e,#d9821f); }
  /* Dashboard-tab stat cards get bigger, easier-to-scan text (plus an emoji in the label) */
  .grid-stats.dashboard-stats .label{ font-size:18px; font-weight:600; }
  .grid-stats.dashboard-stats .value{ font-size:33.5px; }
  .grid-stats.dashboard-stats .icon{ font-size:25.5px; width:44px; height:44px; }
  /* Neutral slate tone for stats that aren't about money owed and previously borrowed the
     yellow/orange c3 gradient (e.g. inactive-student count) - kept distinct from both the
     due-red above and the c1/c2/c4 meanings already in use. */
  .stat.c5{ background:linear-gradient(135deg,#7c6fd6,#5b4bb8); }
  .stat.c5{ background:linear-gradient(135deg,#7d7df2,#5c5ce0); }
  /* ---- KPI cards (Dashboard tab only): white cards with a circular colored icon badge
     and a small up/down trend chip, matching the reference admin-panel screenshot -
     visually distinct from the solid-gradient .stat cards used on every other tab. */
  .kpi-grid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(190px,1fr)); gap:14px; margin-bottom:18px; }
  .kpi-card{
    background:var(--card); border:1px solid var(--border); border-radius:var(--radius-lg);
    padding:16px 18px; box-shadow:var(--shadow-sm); transition:transform .18s var(--ease), box-shadow .18s var(--ease);
  }
  .kpi-card:hover{ transform:translateY(-2px); box-shadow:var(--shadow-md); }
  .kpi-top{ margin-bottom:10px; }
  .kpi-icon{
    width:46px; height:46px; border-radius:50%; display:inline-flex; align-items:center; justify-content:center;
    font-size:26px; flex:none;
  }
  .kpi-value{ font-family:var(--font-display); font-size:30px; font-weight:800; color:var(--text); line-height:1.2; }
  .kpi-bottom{ display:flex; align-items:center; justify-content:space-between; gap:8px; margin-top:4px; flex-wrap:wrap; }
  .kpi-caption{ font-size:16.5px; color:var(--text-sec); font-weight:600; }
  .kpi-trend{ display:inline-flex; align-items:center; gap:3px; font-size:14.5px; font-weight:700; white-space:nowrap; }
  .kpi-trend i{ font-size:16.5px; }
  .kpi-trend.up{ color:#16a34a; }
  .kpi-trend.down{ color:#dc2626; }
  .kpi-trend.flat{ color:var(--text-muted); }
  input, select, textarea{
    width:100%; padding:10px 12px; border-radius:var(--radius); border:1.5px solid var(--border-strong);
    /* 16px, not 14px: iOS Safari auto-zooms the whole page on focus for any input under
       16px, then zooms back out on blur - with inputs on nearly every screen, that zoom
       jump on every tap is what shows up as the app "shaking". 16px stops the auto-zoom. */
    font-size:18.5px; background:var(--card); color:var(--text); font-family:inherit; transition:border-color .15s, box-shadow .15s;
  }
  input:focus, select:focus, textarea:focus{ outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-bg); }
  label{ font-size:14px; color:var(--text-sec); display:block; margin-bottom:5px; font-weight:600; }
  .field{ margin-bottom:12px; }
  .row{ display:grid; grid-template-columns:1fr 1fr; gap:10px; }
  button{
    padding:9px 15px; border-radius:var(--radius); border:1.5px solid var(--border-strong);
    background:var(--card); cursor:pointer; font-size:16px; color:var(--text); font-family:inherit; font-weight:600;
    display:inline-flex; align-items:center; gap:6px; transition:transform .12s var(--ease), box-shadow .12s var(--ease), background .12s, opacity .12s;
  }
  button:hover:not(.ps-portal-card){ background:var(--bg); transform:translateY(-1px); }
  button:active{ transform:translateY(0); }
  button.primary{ background:linear-gradient(135deg,#1d6fa8,var(--accent)); color:#fff; border-color:var(--accent); box-shadow:var(--shadow-sm); }
  button.primary:hover{ opacity:0.94; box-shadow:var(--shadow-md); }
  button.danger-btn{ color:var(--danger); border-color:var(--danger-bg); }
  button.small{ padding:5px 9px; font-size:14px; background:var(--accent-bg); color:var(--accent); border-color:var(--accent-light); }
  /* select doesn't pick up button.small (different tag) - without this it falls back to
     the full-size input/select/textarea rule above (100% width, 16px text), which made
     the student status dropdown balloon far wider/taller than the icon buttons beside it
     and crowd the actions cell on mobile. Sized down to match, with room kept for its
     longest option text ("প্রাক্তন ছাত্র (Alumni)"). */
  select.small{
    width:auto; min-width:0; max-width:112px; flex-shrink:0;
    padding:4px 20px 4px 7px; font-size:13px; background:var(--accent-bg); color:var(--accent); border-color:var(--accent-light);
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  }
  @media (max-width:480px){
    select.small{ max-width:64px; font-size:12px; padding:2px 14px 2px 5px; }
  }
  button.small.primary{ background:linear-gradient(135deg,#1d6fa8,var(--accent)); color:#fff; border-color:var(--accent); }
  button.small.danger-btn{ background:var(--danger-bg); color:var(--danger); border-color:var(--danger); }
  /* Small icon-only buttons default to a soft accent tint above (instead of plain white)
     so they're never invisible against a white card. On top of that, color each one by
     what its icon means, so different actions are visually distinct at a glance. */
  button.small:has(.ti-trash), button.small:has(.ti-trash-x), button.small:has(.ti-plug-x), button.small:has(.ti-circle-x){ background:var(--danger-bg); color:var(--danger); border-color:var(--danger); }
  button.small:has(.ti-edit){ background:var(--accent-bg); color:var(--accent); border-color:var(--accent); }
  button.small:has(.ti-download), button.small:has(.ti-circle-check), button.small:has(.ti-plug), button.small:has(.ti-check){ background:var(--success-bg); color:var(--success); border-color:var(--success); }
  button.small:has(.ti-eye), button.small:has(.ti-eye-off){ background:var(--warning-bg); color:var(--warning); border-color:var(--warning); }
  button.small:has(.ti-medal), button.small:has(.ti-printer){ background:#fbf3da; color:#96650e; border-color:#c9860f; }
  button.small:has(.ti-link), button.small:has(.ti-brand-whatsapp){ background:#e0efe9; color:#146357; border-color:#146357; }
  button.small:has(.ti-list-details), button.small:has(.ti-report-analytics){ background:#e6e5f5; color:#4340b0; border-color:#4340b0; }
  button.small:has(.ti-file-type-pdf){ background:var(--danger-bg); color:var(--danger); border-color:var(--danger); }
  button.small:has(.ti-file-word){ background:#e5edfb; color:#2554a5; border-color:#2554a5; }
  table{ width:100%; border-collapse:collapse; font-size:15px; }
  table tbody tr{ transition:background .12s; }
  table tbody tr:hover{ background:var(--bg); }
  table thead th:first-child{ border-top-left-radius:8px; }
  table thead th:last-child{ border-top-right-radius:8px; }
  #tab-content[data-tab="students"] .card{ border-left:4px solid var(--c-students); }
  #tab-content[data-tab="teachers"] .card{ border-left:4px solid var(--c-teachers); }
  #tab-content[data-tab="staff"] .card{ border-left:4px solid var(--c-teachers); }
  #tab-content[data-tab="fees"] .card{ border-left:4px solid var(--c-fees); }
  #tab-content[data-tab="receipts"] .card{ border-left:4px solid var(--c-receipts); }
  #tab-content[data-tab="attendance"] .card{ border-left:4px solid var(--c-attendance); }
  #tab-content[data-tab="reports"] .card{ border-left:4px solid var(--c-reports); }
  #tab-content[data-tab="settings"] .card{ border-left:4px solid var(--c-settings); }
  #tab-content[data-tab="exams"] .card{ border-left:4px solid var(--c-exams); }
  #tab-content[data-tab="examRoutine"] .card{ border-left:4px solid var(--c-examroutine); }
  #tab-content[data-tab="quiz"] .card{ border-left:4px solid var(--c-quiz); }
  #tab-content[data-tab="routine"] .card{ border-left:4px solid var(--c-routine); }
  #tab-content[data-tab="notices"] .card{ border-left:4px solid var(--c-notices); }
  #tab-content[data-tab="bkash"] .card{ border-left:4px solid var(--c-bkash); }
  #tab-content[data-tab="courses"] .card{ border-left:4px solid var(--c-courses); }
  #tab-content[data-tab="students"] h3{ color:var(--c-students); }
  #tab-content[data-tab="teachers"] h3{ color:var(--c-teachers); }
  #tab-content[data-tab="staff"] h3{ color:var(--c-teachers); }
  #tab-content[data-tab="fees"] h3{ color:var(--c-fees); }
  #tab-content[data-tab="receipts"] h3{ color:var(--c-receipts); }
  #tab-content[data-tab="attendance"] h3{ color:var(--c-attendance); }
  #tab-content[data-tab="reports"] h3{ color:var(--c-reports); }
  #tab-content[data-tab="settings"] h3{ color:var(--c-settings); }
  #tab-content[data-tab="exams"] h3{ color:var(--c-exams); }
  #tab-content[data-tab="examRoutine"] h3{ color:var(--c-examroutine); }
  #tab-content[data-tab="quiz"] h3{ color:var(--c-quiz); }
  #tab-content[data-tab="routine"] h3{ color:var(--c-routine); }
  #tab-content[data-tab="notices"] h3{ color:var(--c-notices); }
  #tab-content[data-tab="bkash"] h3{ color:var(--c-bkash); }
  #tab-content[data-tab="students"] table thead{ background:var(--success-bg); }
  #tab-content[data-tab="teachers"] table thead{ background:#f1eafd; }
  #tab-content[data-tab="fees"] table thead{ background:var(--warning-bg); }
  #tab-content[data-tab="receipts"] table thead{ background:#fde8f1; }
  #tab-content[data-tab="attendance"] table thead{ background:#e2f8f8; }
  #tab-content[data-tab="reports"] table thead{ background:#eceafd; }
  #tab-content[data-tab="exams"] table thead{ background:#fbe4de; }
  #tab-content[data-tab="routine"] table thead{ background:#e0f5ef; }
  tr.fee-batch-heading td{ background:var(--warning-bg); color:var(--c-fees); font-weight:600; font-size:14.5px; border-bottom:1px solid var(--border); }
  table thead{ text-align:left; }
  table th{ padding:8px 10px; font-weight:600; font-size:14px; color:var(--text-sec); }
  th{ text-align:left; padding:8px; color:var(--text-sec); font-weight:500; border-bottom:1px solid var(--border); white-space:nowrap;}
  td{ padding:8px; border-bottom:1px solid var(--border); vertical-align:middle; }
  tr:last-child td{ border-bottom:none; }
  .badge{ padding:4px 10px 4px 8px; border-radius:20px; font-size:12.5px; font-weight:600; white-space:nowrap; display:inline-flex; align-items:center; gap:5px; }
  .badge::before{ content:""; width:6px; height:6px; border-radius:50%; background:currentColor; flex-shrink:0; }
  .badge.paid{ background:var(--success-bg); color:var(--success); }
  .badge.due{ background:var(--danger-bg); color:var(--danger); }
  .badge.partial{ background:var(--warning-bg); color:var(--warning); }
  .badge.present{ background:var(--success-bg); color:var(--success); }
  .badge.absent{ background:var(--danger-bg); color:var(--danger); }
  .badge.leave{ background:var(--warning-bg); color:var(--warning); }
  .modal-overlay{
    position:fixed; inset:0; background:rgba(15,20,30,0.5); backdrop-filter:blur(2px);
    display:flex; align-items:center; justify-content:center; z-index:50; padding:16px;
    animation:overlay-in .18s var(--ease);
  }
  @keyframes quiz-timer-pulse{ 0%,100%{ transform:scale(1); } 50%{ transform:scale(1.08); } }
  @keyframes overlay-in{ from{ opacity:0; } to{ opacity:1; } }
  .modal{
    background:var(--card); border-radius:var(--radius-lg); padding:22px; width:100%; max-width:440px;
    max-height:85vh; overflow-y:auto; box-shadow:var(--shadow-lg); animation:modal-in .2s var(--ease);
  }
  @keyframes modal-in{ from{ opacity:0; transform:translateY(10px) scale(.98); } to{ opacity:1; transform:translateY(0) scale(1); } }
  .modal h3{ font-family:var(--font-display); font-size:19.5px; font-weight:700; margin:0 0 14px; }
  .modal-actions{ display:flex; justify-content:flex-end; gap:8px; margin-top:16px; }
  .course-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(240px,1fr)); gap:16px; margin-top:8px; }
  /* Each card carries its own --course-accent / --course-accent-bg custom properties (set
     inline per-course by coursesCardHtml()/openCourseDetailModal() from COURSE_PALETTE), so
     courses are visually distinct from one another at a glance instead of all sharing one
     flat violet - falls back to the app's generic --c-courses colors if unset. */
  .course-card{
    position:relative; border-radius:var(--radius-lg); padding:20px; padding-top:18px; overflow:hidden;
    background:linear-gradient(165deg,var(--card) 0%,color-mix(in srgb, var(--course-accent, var(--c-courses)) 6%, var(--card)) 130%);
    border:1px solid color-mix(in srgb, var(--course-accent, var(--c-courses)) 22%, var(--border));
    box-shadow:0 3px 12px color-mix(in srgb, var(--course-accent, var(--c-courses)) 10%, transparent);
    transition:transform .22s var(--ease), box-shadow .22s var(--ease), border-color .22s var(--ease);
  }
  /* Accent bar along the top edge, in the card's own color. */
  .course-card::before{
    content:''; position:absolute; top:0; left:0; right:0; height:5px;
    background:var(--course-accent-bg, var(--c-courses-bg));
  }
  /* Faint oversized subject icon in the corner, purely decorative - gives each card some
     visual texture/depth beyond flat color without needing any extra course data. */
  .course-watermark{ position:absolute; right:-12px; bottom:-16px; font-size:87.5px; opacity:.06; color:var(--course-accent, var(--c-courses)); pointer-events:none; line-height:1; }
  .course-card:hover{
    transform:translateY(-5px);
    box-shadow:0 16px 32px color-mix(in srgb, var(--course-accent, var(--c-courses)) 22%, transparent);
    border-color:color-mix(in srgb, var(--course-accent, var(--c-courses)) 45%, var(--border));
  }
  .course-icon{
    width:44px; height:44px; border-radius:13px; background:var(--course-accent-bg, var(--c-courses-bg)); color:#fff;
    display:flex; align-items:center; justify-content:center; font-size:23px; margin-bottom:12px;
    box-shadow:0 5px 12px color-mix(in srgb, var(--course-accent, var(--c-courses)) 45%, transparent);
  }
  .course-card .course-title{ font-family:var(--font-display); font-weight:700; font-size:18.5px; line-height:1.35; margin-bottom:6px; padding-right:56px; }
  /* Small pill shown right after the course title, holding the grade/class the course is
     for (e.g. "HSC") - set via the "শ্রেণী" field in the course form, so admins can tell
     similarly-named courses for different classes apart at a glance. */
  .course-card .course-grade-chip{ display:inline-block; background:color-mix(in srgb, var(--course-accent, var(--c-courses)) 12%, transparent); color:var(--course-accent, var(--c-courses)); border-radius:20px; padding:2px 9px; font-size:12.5px; font-weight:700; vertical-align:middle; }
  .course-card .course-meta{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; font-size:13px; color:var(--text-sec); margin-bottom:8px; }
  .course-card .course-meta .badge{ background:var(--course-accent-bg, var(--c-courses-bg)); color:#fff; padding:4px 10px; border-radius:20px; font-weight:700; font-size:14.5px; box-shadow:0 3px 8px color-mix(in srgb, var(--course-accent, var(--c-courses)) 35%, transparent); }
  .course-card .course-meta .badge small{ font-weight:500; opacity:.85; margin-left:1px; }
  .course-card .course-desc{ font-size:14.5px; color:var(--text-sec); line-height:1.5; padding-top:8px; border-top:1px dashed var(--border); }
  /* Feature list: each course "বৈশিষ্ট্য" line rendered as its own row with a check icon,
     instead of one plain paragraph - keeps a pasted multi-line feature list readable and
     visually separated from the free-text description above it. */
  .course-card .course-features{ list-style:none; margin:8px 0 0; padding:8px 0 0; border-top:1px dashed var(--border); display:flex; flex-direction:column; gap:5px; }
  .course-card .course-features li{ display:flex; align-items:flex-start; gap:6px; font-size:14.5px; color:var(--text); line-height:1.4; }
  .course-card .course-features li i{ color:var(--course-accent, var(--c-courses)); font-size:16px; margin-top:2px; flex-shrink:0; }
  /* Teachers, grouped by subject and presented respectfully as a small profile row (avatar +
     full name on its own line) rather than a cramped pill/tag - a proper "শিক্ষক" label sits
     above each subject's group instead of being squeezed inline with the names. */
  .course-card .course-teachers{ display:flex; flex-direction:column; gap:10px; margin-top:8px; padding-top:8px; border-top:1px dashed var(--border); }
  .course-card .course-teacher-subject{ font-size:12px; font-weight:700; letter-spacing:.2px; color:var(--course-accent, var(--c-courses)); background:color-mix(in srgb, var(--course-accent, var(--c-courses)) 14%, transparent); border-radius:6px; padding:3px 7px; display:inline-block; margin-bottom:6px; }
  .course-card .course-teacher-chips{ display:flex; flex-direction:column; gap:6px; }
  .course-card .course-teacher-chip{ display:flex; align-items:center; gap:8px; font-size:15px; font-weight:600; color:var(--text); }
  .course-card .course-teacher-chip .course-teacher-name{ line-height:1.3; }
  .course-card .course-actions{ position:absolute; top:14px; right:12px; display:flex; gap:4px; }
  /* "বিস্তারিত দেখুন" footer link - makes it visually obvious the whole card is clickable
     (previously nothing hinted at that), and the arrow nudges right on hover as a small
     invitation to tap in, matching the card lift. */
  .course-card .course-cta{ display:flex; align-items:center; gap:5px; margin-top:12px; padding-top:10px; border-top:1px dashed var(--border); font-size:14.5px; font-weight:700; color:var(--course-accent, var(--c-courses)); }
  .course-card .course-cta i{ font-size:15px; transition:transform .2s var(--ease); }
  .course-card:hover .course-cta i{ transform:translateX(4px); }
  /* Class routine shown inside a course's detail modal (courseRoutineHtml()) - plain
     top-level rules (not nested under .course-card) since the detail modal's wrapper is
     .modal, not .course-card. */
  .course-routine{ margin-top:10px; padding-top:10px; border-top:1px dashed var(--border); }
  .course-routine-title{ display:flex; align-items:center; gap:6px; font-size:14.5px; font-weight:700; color:var(--text); margin-bottom:8px; }
  .course-routine-table{ width:100%; border-collapse:collapse; font-size:14.5px; }
  .course-routine-table th{ text-align:left; font-weight:600; color:var(--text-sec); padding:5px 6px; border-bottom:1px solid var(--border); }
  .course-routine-table td{ padding:6px 6px; border-bottom:1px solid var(--border); color:var(--text); }
  .empty{ text-align:center; padding:44px 16px; color:var(--text-muted); }
  .empty i{ font-size:39px; margin-bottom:10px; display:block; opacity:.7; }
  .gal-admin-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(120px,1fr)); gap:10px; }
  .gal-admin-item{ display:flex; flex-direction:column; gap:6px; }
  .gal-admin-thumb{ position:relative; aspect-ratio:4/3; border-radius:10px; overflow:hidden; background:var(--accent-bg); }
  .gal-admin-thumb img{ width:100%; height:100%; object-fit:cover; display:block; }
  .gal-admin-del{ position:absolute; top:5px; right:5px; width:26px; height:26px; border:none; border-radius:50%; background:rgba(220,38,38,.92); color:#fff; display:flex; align-items:center; justify-content:center; cursor:pointer; font-size:15px; box-shadow:0 1px 4px rgba(0,0,0,.25); }
  .gal-admin-caption{ width:100%; font-size:14px; padding:5px 7px; }
  .icon-badge{ width:38px; height:38px; border-radius:11px; display:inline-flex; align-items:center; justify-content:center; font-size:20.5px; flex-shrink:0; box-shadow:0 1px 3px rgba(0,0,0,0.08); }
  .toolbar{ display:flex; gap:8px; margin-bottom:14px; flex-wrap:wrap; align-items:center; }
  .toolbar input, .toolbar select{ width:auto; min-width:140px; flex:1; }
  .actions-cell{ display:flex; gap:6px; }
  .sr-only{ position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); border:0; }
  .avatar{ width:32px; height:32px; border-radius:50%; background:var(--accent-bg); color:var(--accent); display:flex; align-items:center; justify-content:center; font-size:14px; font-weight:700; flex-shrink:0; box-shadow:inset 0 0 0 2px rgba(255,255,255,0.6); }
  .name-cell{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
  /* ---- Student list row: bigger colored-ring avatar + stacked name/roll-class subtitle ----
     Gives each row visual weight and lets an admin recognize a student (and which class
     they're in, via the ring color) without having to scan sideways into the other columns -
     especially useful on the horizontally-scrolling table on narrow/mobile screens. */
  .student-name-cell{ align-items:center; flex-wrap:nowrap; }
  .student-avatar-ring{ padding:2px; border-radius:50%; flex-shrink:0; display:flex;
    background:linear-gradient(135deg, var(--ring-color,var(--c-students)), color-mix(in srgb, var(--ring-color,var(--c-students)) 45%, white));
    box-shadow:0 2px 6px rgba(0,0,0,.14); }
  .student-avatar-ring .avatar, .student-avatar-ring img{ box-shadow:0 0 0 2px var(--card); }
  .student-name-info{ min-width:0; }
  .student-name-main{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; font-size:15.5px; font-weight:600; }
  .student-name-sub{ font-size:12.5px; color:var(--text-sec); margin-top:2px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  /* ---- Student list: card-grid layout (replaces the old cramped single-row table) ----
     One card per student instead of one narrow horizontally-scrolling table row. Each
     card keeps the same data-id/class hooks the row used to (bulk-row, edit-student,
     invite-student, etc.) so the existing click-wiring in wireStudentRowButtons() below
     needs no changes - only the markup shape changed. Mobile gets a single stacked
     column (no horizontal scrolling); wider screens get 2-3 columns. */
  .student-cards-grid{ display:grid; grid-template-columns:1fr; gap:12px; padding:14px; }
  @media (min-width:640px){ .student-cards-grid{ grid-template-columns:repeat(2,1fr); } }
  @media (min-width:1000px){ .student-cards-grid{ grid-template-columns:repeat(3,1fr); } }
  .student-card{
    position:relative; display:flex; flex-direction:column; gap:10px;
    border:1px solid var(--border); border-radius:var(--radius-lg); padding:12px;
    background:var(--card); box-shadow:var(--shadow-sm);
    transition:box-shadow .18s var(--ease), border-color .18s var(--ease);
  }
  .student-card:hover{ box-shadow:var(--shadow-md); border-color:var(--border-strong); }
  .student-card-top{ display:flex; align-items:flex-start; gap:9px; }
  .student-card-select{ flex-shrink:0; padding-top:6px; cursor:pointer; }
  .student-card-headline{ flex:1; min-width:0; }
  .student-card-name{ font-size:16.5px; font-weight:700; line-height:1.3; word-break:break-word; }
  .student-card-badges{ display:flex; flex-wrap:wrap; gap:4px; margin-top:4px; }
  .student-card-badges:empty{ display:none; margin:0; }
  .student-card-actions{ display:flex; align-items:flex-start; gap:5px; flex-shrink:0; }
  .student-card-menu-wrap{ position:relative; }
  .student-card-menu{
    position:absolute; right:0; top:calc(100% + 6px); z-index:30; min-width:210px;
    background:var(--card); border:1px solid var(--border); border-radius:var(--radius);
    box-shadow:var(--shadow-lg); padding:6px; display:flex; flex-direction:column; gap:2px;
  }
  .student-card-menu[hidden]{ display:none; }
  .student-card-menu .menu-item{
    display:flex; align-items:center; gap:8px; width:100%; text-align:right;
    padding:8px 9px; border:none; background:none; box-shadow:none;
    font-size:14.5px; font-weight:500; color:var(--text); border-radius:7px; justify-content:flex-start;
  }
  .student-card-menu .menu-item:hover{ background:var(--bg); transform:none; }
  .student-card-menu .menu-item.danger{ color:var(--danger); }
  .student-card-menu .menu-item-label{ font-size:12px; color:var(--text-muted); font-weight:600; margin:2px 9px 0; text-transform:uppercase; letter-spacing:.02em; }
  .student-card-menu select.student-status-select{ width:calc(100% - 4px); max-width:none; margin:2px; }
  .student-card-menu .menu-divider{ height:1px; background:var(--border); margin:4px 2px; }
  .student-card-info{ display:grid; grid-template-columns:1fr 1fr; gap:7px 12px; padding-top:2px; border-top:1px dashed var(--border); }
  .student-card-info .info-pair{ min-width:0; display:flex; flex-direction:column; gap:1px; }
  .student-card-info .info-label{ font-size:12px; color:var(--text-muted); font-weight:600; text-transform:uppercase; letter-spacing:.03em; }
  .student-card-info .info-value{ font-size:14.5px; font-weight:600; color:var(--text); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .save-note{ font-size:14px; color:var(--text-muted); display:flex; align-items:center; gap:4px; }
  .loading{ text-align:center; padding:60px; color:var(--text-muted); }
  .report-header{ display:none; }
  .report-section{ margin-bottom:20px; }
  .report-section h3{ font-size:17px; font-weight:500; margin:0 0 10px; }
  @media print{
    /* Margin must be 0 on the @page box itself - this is what stops the browser
       drawing its own header/footer strip (which contains this page's URL/title).
       Size is fixed to A4 so the printed layout is consistent regardless of the
       printer/browser's default paper size. */
    @page{ size:A4 portrait; margin:0; }
    .tabs, .toolbar, .actions-cell, header, button{ display:none !important; }
    .student-card-menu-wrap, .student-card-select{ display:none !important; }
    .student-cards-grid{ grid-template-columns:1fr !important; gap:6px !important; padding:0 !important; }
    .student-card{ break-inside:avoid; box-shadow:none !important; }
    /* Screen view stays fully colorful; only the printed output is forced to
       black & white (grayscale) - saves color ink and keeps printed reports
       looking like a plain document regardless of on-screen theming. */
    html{ -webkit-filter:grayscale(1); filter:grayscale(1); background:#fff; }
    /* Printing already forces grayscale + white body background above (comment right
       above this rule) - if the person is using dark mode on-screen though, the --card/
       --text/--border custom properties are still the dark-mode values at print time
       unless reset here, which would print dark card backgrounds through the grayscale
       filter (dark gray boxes) instead of the plain white page this section intends. */
    html[data-theme="dark"]{
      --bg:#ffffff; --card:#ffffff; --border:#e5e5e0; --border-strong:#d4d4cc;
      --text:#002050; --text-sec:#607080; --text-muted:#93a0b0;
      --accent:#147DEB; --accent-bg:#E0F0F8; --accent-light:#a9d4f0;
      --success:#18A878; --success-bg:#e0f7ef;
      --danger:#F0444A; --danger-bg:#fde3e4;
      --warning:#F5A623; --warning-bg:#fef0da;
    }
    body{ background:#fff; }
    .app{ padding:12.7mm; max-width:none; }
    .card{ border:none; padding:0; box-shadow:none !important; }
    .report-header{ display:block !important; text-align:center; margin-bottom:16px; }
    .report-header h2{ font-size:18px; margin:0 0 4px; }
    .report-header p{ font-size:12px; color:#555; margin:0; }
    /* Avoid awkward page breaks through a card, table row, or chart. */
    .report-section, .card, table tr, canvas{ page-break-inside:avoid; break-inside:avoid; }
  }
  @media (max-width:600px){
    .row{ grid-template-columns:1fr; }
    th:nth-child(n+4), td:nth-child(n+4){ display:none; }
    th:nth-child(1), td:nth-child(1), th:last-child, td:last-child{ display:table-cell; }
    /* Result tables must always show every column (incl. প্রাপ্ত) - never hide marks on phones. */
    .exam-result-table th, .exam-result-table td, .ms-wrap table th, .ms-wrap table td{ display:table-cell !important; }
  }
  /* ---------- ID CARD PREVIEW/PRINT OVERLAY ----------
     Student & staff ID card view/print used to open a brand-new window (window.open +
     document.write) and print from there. That's a normal pattern on desktop browsers,
     but this app is also shipped as an Android TWA (see manifest.json's
     related_applications -> play -> ...twa, and Prism-care.apk) - a TWA runs as a single
     Chrome-backed Activity with no multi-window/tab UI, so window.open('', '_blank', ...)
     silently fails to produce anything usable there (and is flaky even in plain mobile
     browser tabs). Rendering the card directly into an overlay on THIS page and calling
     window.print() on THIS window - exactly like printCurrentView() already does for the
     student list - works everywhere: desktop, mobile browser, and the TWA app alike. */
  .idcard-overlay-screen{ position:fixed; inset:0; z-index:9999; background:#eef3f7; overflow:auto; }
  .idcard-overlay-toolbar{ position:sticky; top:0; z-index:2; background:#fff; border-bottom:1px solid var(--border,#d8e2ec); padding:10px 14px; display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; }
  .idcard-overlay-title{ font-family:'Baloo Da 2',sans-serif; font-weight:700; color:var(--text,#0c3a5c); font-size:17px; display:flex; align-items:center; gap:6px; }
  .idcard-overlay-actions{ display:flex; gap:8px; }
  .idcard-print-area{ padding:18px; }
  .idcard-print-page{ max-width:210mm; margin:0 auto 20px; background:#fff; padding:12mm; box-shadow:0 2px 15px rgba(0,0,0,.12); border-radius:4px; }
  .idcard-print-grid{ display:grid; grid-template-columns:repeat(2,85.6mm); gap:5mm; justify-content:center; }
  .idcard-print-wrap{ width:85.6mm; height:54mm; break-inside:avoid; page-break-inside:avoid; }
  @media print{
    /* Only active while body has this class (set right before window.print(), removed on
       'afterprint' - see openIdCardOverlay()), so it never affects any other print flow
       (e.g. printCurrentView()'s existing student-list print) sharing this same page. */
    body.printing-idcard-overlay > *:not(#idcard-overlay){ display:none !important; }
    body.printing-idcard-overlay .idcard-overlay-toolbar{ display:none !important; }
    body.printing-idcard-overlay #idcard-overlay{ position:static !important; inset:auto !important; background:#fff !important; overflow:visible !important; }
    body.printing-idcard-overlay .idcard-print-area{ padding:0 !important; }
    body.printing-idcard-overlay .idcard-print-page{ box-shadow:none !important; max-width:none !important; margin:0 !important; padding-top:0 !important; page-break-after:always; }
    body.printing-idcard-overlay .idcard-print-page:last-child{ page-break-after:auto; }
    body.printing-idcard-overlay .idcard{ box-shadow:none !important; }
    /* Everything printed from this app is forced to grayscale by default (see the
       html{filter:grayscale(1)} rule above) to save ink. ID cards look better in color
       though, so an optional "রঙিন প্রিন্ট" checkbox in the overlay toolbar lets the
       office opt into color for just this print job by adding this class to <html>
       (see openIdCardOverlay's doPrint). Higher specificity than the plain html{} rule
       above means this wins regardless of source order. */
    html.printing-idcard-color{ -webkit-filter:none !important; filter:none !important; }
  }
  .idcard-color-print-toggle{ display:flex; align-items:center; gap:6px; font-size:15px; color:var(--text-sec,#5a6b7a); cursor:pointer; user-select:none; }
  /* ---------- ADMISSION FORM PRINT OVERLAY ----------
     printAdmissionFormNative() used to call printPagedWindow(), which does window.open('','_blank',...)
     + document.write() (see the long comment on printPagedWindow itself). That's exactly the pattern
     the ID CARD PREVIEW/PRINT OVERLAY comment above warns about: inside the Android TWA wrapper,
     window.open('', '_blank', ...) silently fails to produce anything usable, so a student submitting
     the public admission form from the app got a successful submission but the "পূরণকৃত ফর্ম প্রিন্ট করুন"
     button did nothing - no error, just nothing to download/print. Switched to the same in-page overlay
     + window.print() pattern already proven for ID cards (openIdCardOverlay), which works on desktop,
     mobile browser tabs, and the TWA alike. */
  .af-print-overlay-screen{ position:fixed; inset:0; z-index:9999; background:#eef3f7; overflow:auto; }
  .af-print-overlay-toolbar{ position:sticky; top:0; z-index:2; background:#fff; border-bottom:1px solid var(--border,#d8e2ec); padding:10px 14px; display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; }
  .af-print-overlay-title{ font-family:'Baloo Da 2',sans-serif; font-weight:700; color:var(--text,#0c3a5c); font-size:17px; display:flex; align-items:center; gap:6px; }
  .af-print-overlay-actions{ display:flex; gap:8px; }
  .af-print-overlay-area{ padding:18px; }
  .af-print-overlay-page{ max-width:190mm; margin:0 auto; background:#fff; padding:12mm; box-shadow:0 2px 15px rgba(0,0,0,.12); border-radius:4px; position:relative; }
  @media print{
    /* Only active while body has this class (set right before window.print(), removed on
       'afterprint' - see printAdmissionFormNative()), mirroring how the ID card overlay's
       printing-idcard-overlay class scopes itself so the two print flows never collide. */
    body.printing-af-overlay > *:not(#af-print-overlay){ display:none !important; }
    body.printing-af-overlay .af-print-overlay-toolbar{ display:none !important; }
    body.printing-af-overlay #af-print-overlay{ position:static !important; inset:auto !important; background:#fff !important; overflow:visible !important; }
    body.printing-af-overlay .af-print-overlay-area{ padding:0 !important; }
    body.printing-af-overlay .af-print-overlay-page{ box-shadow:none !important; max-width:none !important; margin:0 !important; padding:10mm !important; }
    /* Keeps each info block (and the signature row) intact on one page instead of
       letting the browser split a section awkwardly across a page boundary - the whole
       filled form is compact enough to fit a single A4 page, this just guards against
       an unlucky break if a guardian's optional message is a bit long. */
    body.printing-af-overlay .af-print-section,
    body.printing-af-overlay .af-print-signatures{ break-inside:avoid; page-break-inside:avoid; }
  }
  /* ---------- GENERIC PAGINATED PRINT OVERLAY (printPagedWindow) ----------
     printPagedWindow() used to be window.open('','_blank',...)+document.write() - the same
     TWA-breaking pattern documented above on .af-print-overlay-screen and the ID card overlay
     comment. Its only two callers (progress report, batch result sheet) had the identical bug:
     the print/download button silently did nothing inside the Android TWA. Converted to the
     same in-page overlay + window.print() approach, generalized (unlike .af-print-overlay-*)
     since printPagedWindow's callers vary in title/content rather than being one fixed form. */
  .gpw-overlay-screen{ position:fixed; inset:0; z-index:9999; background:#eef3f7; overflow:auto; }
  .gpw-overlay-toolbar{ position:sticky; top:0; z-index:2; background:#fff; border-bottom:1px solid var(--border,#d8e2ec); padding:10px 14px; display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; }
  .gpw-overlay-title{ font-family:'Baloo Da 2',sans-serif; font-weight:700; color:var(--text,#0c3a5c); font-size:17px; display:flex; align-items:center; gap:6px; }
  .gpw-overlay-actions{ display:flex; gap:8px; }
  .gpw-overlay-area{ padding:18px; }
  .gpw-overlay-page{ margin:0 auto; background:#fff; padding:12mm; box-shadow:0 2px 15px rgba(0,0,0,.12); border-radius:4px; position:relative; font-family:Arial,'Hind Siliguri',sans-serif; color:#000; }
  @media print{
    body.printing-gpw-overlay > *:not(#gpw-overlay){ display:none !important; }
    body.printing-gpw-overlay .gpw-overlay-toolbar{ display:none !important; }
    body.printing-gpw-overlay #gpw-overlay{ position:static !important; inset:auto !important; background:#fff !important; overflow:visible !important; }
    body.printing-gpw-overlay .gpw-overlay-area{ padding:0 !important; }
    /* Printed sheets get a real 12.7mm (0.5in) margin on every side. The @page margin stays 0 (that is
       what suppresses the browser's own URL/date header+footer), so the margin is drawn here as padding;
       box-decoration-break:clone repeats it at the top/bottom of every page, not just the first/last. */
    body.printing-gpw-overlay .gpw-overlay-page{ box-shadow:none !important; margin:0 !important; padding:12.7mm !important; box-sizing:border-box; -webkit-box-decoration-break:clone; box-decoration-break:clone; }
  }
  /* ---------- PUBLIC ADMISSION FORM: MULTI-STEP WIZARD ----------
     Turns the single long form into 4 steps (student -> academic -> guardian -> review).
     All fields keep their original ids and validation; only visibility/navigation changes,
     via attachAdmissionFormEvents() in the script below. */
  .af-wizard-grid{ max-width:480px; width:100%; margin:0 auto; }
  @media (min-width:860px){
    .af-wizard-grid{ max-width:1400px; width:96%; display:grid; grid-template-columns:minmax(0,1fr) 340px; gap:28px; align-items:start; }
    .af-preview-col{ display:block !important; }
  }
  .af-preview-col{ display:none; }
  .af-preview-card{ position:sticky; top:20px; border-radius:var(--radius-lg); background:var(--card); border:1px solid var(--border); padding:20px 16px; text-align:center; box-shadow:var(--shadow-md); }
  .af-progress{ display:flex; align-items:center; padding:16px 20px 2px; }
  .af-dot{ width:28px; height:28px; border-radius:50%; background:var(--accent-bg); color:var(--text-sec); display:flex; align-items:center; justify-content:center; font-size:14.5px; font-weight:700; flex-shrink:0; border:2px solid var(--border-strong); transition:all .25s var(--ease); position:relative; }
  .af-dot .af-dot-check{ display:none; font-size:15px; }
  .af-dot.active{ background:var(--accent); color:#fff; border-color:var(--accent); box-shadow:0 0 0 4px var(--accent-bg); }
  .af-dot.done{ background:var(--success); color:#fff; border-color:var(--success); }
  .af-dot.done .af-dot-num{ display:none; }
  .af-dot.done .af-dot-check{ display:inline-block; }
  .af-dot-line{ flex:1; height:2px; background:var(--border-strong); margin:0 4px; min-width:10px; transition:background .25s var(--ease); }
  .af-dot-line.done{ background:var(--success); }
  .af-progress-labels{ display:flex; padding:5px 14px 12px; font-size:12px; color:var(--text-sec); }
  .af-progress-labels span{ flex:1; text-align:center; }
  .af-step{ display:none; }
  .af-step.active{ display:block; animation:afStepIn .22s var(--ease); }
  @keyframes afStepIn{ from{ opacity:0; transform:translateY(6px); } to{ opacity:1; transform:translateY(0); } }
  .af-nav{ display:flex; gap:10px; margin-top:2px; }
  .af-nav button{ flex:1; justify-content:center; }
  .af-draft-banner{ background:var(--accent-bg); border:1px solid var(--accent-light); border-radius:var(--radius); padding:10px 12px; margin-bottom:14px; font-size:14px; color:var(--accent); display:flex; align-items:center; justify-content:space-between; gap:8px; flex-wrap:wrap; }
  .af-draft-banner .af-draft-actions{ display:flex; gap:6px; flex-shrink:0; }
  .af-review-row{ display:flex; justify-content:space-between; gap:10px; font-size:14.5px; padding:4px 0; border-bottom:1px dashed var(--border); }
  .af-review-row span:first-child{ color:var(--text-sec); flex-shrink:0; }
  .af-review-row span:last-child{ font-weight:600; text-align:right; min-width:0; overflow-wrap:break-word; word-break:break-word; }

  /* ═════ স্টুডেন্ট পোর্টাল লগইন — আপনার দেওয়া কোড, হুবহু (spl-page = wrapper, যাতে :root/body/*
     এর গ্লোবাল রুলগুলো বাকি অ্যাপের ওপর প্রভাব না ফেলে - প্রতিটা সিলেক্টরের আগে শুধু .spl-page
     বসানো হয়েছে, ভ্যালু/ডিজাইন কিছুই বদলানো হয়নি) ═════ */
  .spl-page{
    --primary: #0879e8; --primary-dark: #0756b5; --purple: #7046e8; --navy: #0d2c52;
    --text: #123a63; --muted: #6b8bab; --border: #c3ddf2;
    --background: #dcefff; --surface: #f0f8ff; --surface-2: #e1f0fc;
    --success: #0e9f6e; --success-soft: #e0f7ee; --danger: #e34d65; --danger-soft: #fdeef1; --info-soft: #e6f2ff;
    --shadow-lg: 0 25px 70px rgba(30, 100, 180, .18), 0 5px 18px rgba(30, 100, 180, .08);
    --shadow-btn: 0 8px 18px rgba(8, 121, 232, .22);
    --shadow-btn-hover: 0 12px 24px rgba(8, 121, 232, .30);
    --ring: rgba(22, 131, 237, .14); --focus: #1683ed;
    --logo-dark: #0f2234; --logo-mid: #1e3b57; --logo-light: #2a4d6e;
  }
  html[data-theme="dark"] .spl-page{
    --primary: #3b9bff; --primary-dark: #1f6fd8; --purple: #9a7bff; --navy: #cfe1f6;
    --text: #d3e2f2; --muted: #8298b0; --border: #22374f;
    --background: #0a141f; --surface: #101f31; --surface-2: #16273b;
    --success: #35c98a; --success-soft: #102b23; --danger: #ff8090; --danger-soft: #2c1620; --info-soft: #12263c;
    --shadow-lg: 0 25px 70px rgba(0, 0, 0, .55), 0 5px 18px rgba(0, 0, 0, .3);
    --shadow-btn: 0 8px 18px rgba(0, 0, 0, .35);
    --shadow-btn-hover: 0 12px 24px rgba(0, 0, 0, .45);
    --ring: rgba(59, 155, 255, .16); --focus: #3b9bff;
    --logo-dark: #24445f; --logo-mid: #365a7b; --logo-light: #4a7aa3;
  }
  .spl-page, .spl-page *{ margin: 0; padding: 0; box-sizing: border-box; }
  .spl-page{
    min-height: 100vh; min-height: 100dvh;
    display: flex; justify-content: center; align-items: center; padding: 35px 18px;
    font-family: "Hind Siliguri", sans-serif; color: var(--text);
    background:
        radial-gradient(circle at 10% 10%, rgba(71, 164, 255, .20), transparent 38%),
        radial-gradient(circle at 90% 90%, rgba(112, 70, 232, .12), transparent 38%),
        var(--background);
    transition: background-color .4s ease, color .4s ease;
  }
  .spl-page .background-shape{ position: fixed; z-index: 0; pointer-events: none; }
  .spl-page .shape-top{ width: 310px; height: 220px; top: -115px; left: -110px; background: linear-gradient(135deg, #0879e8, #64b5ff); border-radius: 35px; transform: rotate(-12deg); opacity: .9; }
  .spl-page .shape-bottom{ width: 260px; height: 180px; right: -100px; bottom: -100px; background: linear-gradient(135deg, #a8dfff, #0879e8); border-radius: 45px; transform: rotate(-20deg); opacity: .55; }
  html[data-theme="dark"] .spl-page .shape-top{ opacity: .35; }
  html[data-theme="dark"] .spl-page .shape-bottom{ opacity: .22; }
  .spl-page .login-container{
    width: 100%; max-width: 760px; position: relative; z-index: 1; overflow: hidden;
    background: var(--surface); border: 1px solid var(--border); border-radius: 27px;
    box-shadow: var(--shadow-lg);
    animation: splCardAppear .7s ease both;
    transition: background-color .4s ease, border-color .4s ease;
  }
  @keyframes splCardAppear{ from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: translateY(0); } }
  .spl-page .login-container::before{
    content: ""; position: absolute; top: 0; left: 0; width: 260px; height: 150px;
    background: linear-gradient(135deg, #075be0, #0879e8 55%, #7647e8);
    clip-path: polygon(0 0, 100% 0, 0 100%); opacity: .96; pointer-events: none;
  }
  .spl-page .login-container::after{
    content: ""; position: absolute; bottom: 0; right: 0; width: 240px; height: 110px;
    background: linear-gradient(135deg, rgba(143, 222, 255, .35), rgba(25, 142, 255, .30));
    clip-path: polygon(100% 0, 100% 100%, 0 100%); pointer-events: none;
  }
  .spl-page .portal-header{ position: relative; z-index: 3; display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; padding: 22px 35px 18px; background: var(--surface); border-radius: 0 0 22px 22px; box-shadow: 0 2px 10px rgba(13, 44, 82, .06); }
  .spl-page .portal-label{ display: flex; align-items: center; gap: 12px; color: var(--navy); font-size: 19.5px; font-weight: 600; }
  .spl-page .portal-label i{ font-size: 40px; color: var(--navy); }
  .spl-page .portal-label span{ padding-left: 12px; border-left: 3px solid var(--primary); line-height: 1.45; }
  .spl-page .portal-label small{ color: var(--muted); font-size: .78em; font-weight: 500; }
  .spl-page .login-content{ width: 100%; max-width: 570px; margin: 0 auto; padding: 35px 28px 32px; position: relative; z-index: 2; }
  .spl-page .stagger > *{ animation: splRiseIn .55s cubic-bezier(.22, .8, .3, 1) both; }
  .spl-page .stagger > *:nth-child(1){ animation-delay: .05s; }
  .spl-page .stagger > *:nth-child(2){ animation-delay: .12s; }
  .spl-page .stagger > *:nth-child(3){ animation-delay: .19s; }
  .spl-page .stagger > *:nth-child(4){ animation-delay: .26s; }
  .spl-page .stagger > *:nth-child(5){ animation-delay: .33s; }
  .spl-page .stagger > *:nth-child(6){ animation-delay: .40s; }
  @keyframes splRiseIn{ from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
  .spl-page .brand{ text-align: center; margin-bottom: 26px; }
  .spl-page .logo{ width: 150px; height: 150px; margin: 0 auto 8px; display: flex; align-items: center; justify-content: center; position: relative; }
  .spl-page .logo img{ width: 100%; height: 100%; object-fit: contain; display: block; filter: drop-shadow(0 6px 16px rgba(14, 36, 55, .18)); transition: filter .4s ease, transform .4s ease; }
  .spl-page .brand:hover .logo img{ transform: translateY(-2px) scale(1.02); filter: drop-shadow(0 10px 22px rgba(14, 36, 55, .26)); }
  html[data-theme="dark"] .spl-page .logo img{ filter: drop-shadow(0 6px 16px rgba(0, 0, 0, .5)) brightness(1.35) contrast(1.05); }
  html[data-theme="dark"] .spl-page .brand:hover .logo img{ filter: drop-shadow(0 10px 22px rgba(0, 0, 0, .6)) brightness(1.45) contrast(1.05); }
  .spl-page .logo .logo-fallback{ display: none; width: 100%; height: 100%; }
  .spl-page .logo .logo-fallback svg{ width: 100%; height: 100%; display: block; filter: drop-shadow(0 6px 16px rgba(14, 36, 55, .22)); transition: filter .4s ease, transform .4s ease; }
  .spl-page .brand:hover .logo-fallback svg{ transform: translateY(-2px) scale(1.02); filter: drop-shadow(0 10px 22px rgba(14, 36, 55, .30)); }
  .spl-page .logo .logo-fallback svg .facet{ transition: fill .4s ease; }
  .spl-page .welcome{ text-align: center; margin-bottom: 26px; }
  .spl-page .welcome h1{ color: var(--navy); font-size: 39px; font-weight: 700; line-height: 1.4; }
  .spl-page .welcome p{ margin-top: 8px; color: var(--muted); font-size: 18.5px; line-height: 1.8; }
  .spl-page .login-form{ width: 100%; }
  .spl-page .form-group{ margin-bottom: 20px; }
  .spl-page .form-group label{ display: block; margin-bottom: 9px; color: var(--navy); font-size: 18.5px; font-weight: 600; }
  .spl-page .required{ color: var(--danger); }
  .spl-page .input-box{ width: 100%; position: relative; }
  .spl-page .input-box > i{ position: absolute; left: 19px; top: 50%; transform: translateY(-50%); color: var(--muted); font-size: 22px; pointer-events: none; transition: color .2s ease; }
  .spl-page .input-box input{
    width: 100%; height: 64px; padding: 15px 52px 15px 58px;
    background: var(--surface-2); border: 2px solid var(--border); border-radius: 15px;
    color: var(--text); font-family: "Poppins", "Hind Siliguri", sans-serif; font-size: 19.5px;
    outline: none; transition: border-color .22s ease, box-shadow .22s ease, background-color .4s ease;
  }
  .spl-page .input-box input::placeholder{ color: var(--muted); opacity: .85; }
  .spl-page .input-box input:hover{ border-color: var(--primary); }
  .spl-page .input-box input:focus{ border-color: var(--focus); background: #ffffff; box-shadow: 0 0 0 4px var(--ring); }
  html[data-theme="dark"] .spl-page .input-box input:focus{ background: var(--surface); }
  .spl-page .input-box:focus-within > i{ color: var(--primary); }
  .spl-page .field-status{ position: absolute; right: 18px; top: 50%; transform: translateY(-50%) scale(.6); font-size: 22px; opacity: 0; pointer-events: none; transition: opacity .22s ease, transform .22s ease; }
  .spl-page .input-box.is-valid .field-status{ opacity: 1; transform: translateY(-50%) scale(1); color: var(--success); }
  .spl-page .input-box.is-valid input{ border-color: var(--success); }
  .spl-page .input-box.is-invalid input{ border-color: var(--danger); background: var(--danger-soft); }
  .spl-page .input-box.is-invalid input:focus{ box-shadow: 0 0 0 4px rgba(227, 77, 101, .12); }
  .spl-page .field-hint{ min-height: 18px; margin-top: 6px; padding-left: 4px; color: var(--muted); font-size: 14.5px; line-height: 1.5; transition: color .2s ease; }
  .spl-page .form-group.has-error .field-hint{ color: var(--danger); }
  .spl-page .form-extras{ display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; margin: -4px 0 4px; }
  .spl-page .checkbox{ display: inline-flex; align-items: center; gap: 9px; cursor: pointer; user-select: none; color: var(--muted); font-size: 16px; font-weight: 500; }
  .spl-page .checkbox input{ position: absolute; opacity: 0; width: 0; height: 0; }
  .spl-page .checkbox .box{ width: 20px; height: 20px; flex-shrink: 0; display: grid; place-items: center; border: 2px solid var(--border); border-radius: 6px; background: var(--surface-2); color: #fff; font-size: 12.5px; transition: .2s ease; }
  .spl-page .checkbox .box i{ opacity: 0; transition: opacity .15s ease; }
  .spl-page .checkbox input:checked + .box{ background: var(--primary); border-color: var(--primary); }
  .spl-page .checkbox input:checked + .box i{ opacity: 1; }
  .spl-page .checkbox input:focus-visible + .box{ outline: 3px solid var(--ring); outline-offset: 2px; }
  .spl-page .demo-badge{ display: inline-flex; align-items: center; gap: 7px; padding: 5px 11px; border-radius: 999px; border: 1px dashed var(--border); background: var(--surface-2); color: var(--muted); font-size: 14px; font-weight: 500; }
  .spl-page .demo-badge code{ font-family: "Poppins", monospace; font-size: 13px; color: var(--primary); letter-spacing: .3px; }
  .spl-page .login-button{
    width: 100%; height: 64px; margin-top: 20px; position: relative; overflow: hidden;
    display: grid; place-items: center; border: 1px solid rgba(255, 255, 255, .35); border-radius: 15px;
    background: linear-gradient(105deg, #0879e8, #126fe0 55%, #0879e8); background-size: 200% 100%;
    color: #fff; font-family: "Hind Siliguri", sans-serif; font-size: 24px; font-weight: 700; cursor: pointer;
    box-shadow: var(--shadow-btn);
    transition: transform .25s ease, box-shadow .25s ease, background-position .5s ease, opacity .2s ease;
  }
  .spl-page .login-button:hover:not(:disabled){ background-position: 100% 0; transform: translateY(-2px); box-shadow: var(--shadow-btn-hover); }
  .spl-page .login-button:active:not(:disabled){ transform: translateY(0); }
  .spl-page .login-button:focus-visible{ outline: 3px solid var(--ring); outline-offset: 3px; }
  .spl-page .login-button:disabled{ cursor: not-allowed; opacity: .85; }
  .spl-page .btn-content{ display: flex; align-items: center; gap: 15px; transition: opacity .2s ease, transform .2s ease; }
  .spl-page .btn-content i{ font-size: 24px; }
  .spl-page .btn-spinner{ position: absolute; width: 26px; height: 26px; border: 3px solid rgba(255, 255, 255, .35); border-top-color: #fff; border-radius: 50%; opacity: 0; animation: splSpin .7s linear infinite; }
  @keyframes splSpin{ to { transform: rotate(360deg); } }
  .spl-page .login-button.is-loading .btn-content{ opacity: 0; transform: scale(.9); }
  .spl-page .login-button.is-loading .btn-spinner{ opacity: 1; }
  .spl-page .message{ display: none; align-items: flex-start; gap: 11px; margin-top: 18px; padding: 13px 15px; border-radius: 12px; border: 1px solid #bfdbfe; background: var(--info-soft); color: #1d4ed8; font-size: 16px; line-height: 1.7; }
  .spl-page .message.show{ display: flex; animation: splRiseIn .35s ease both; }
  .spl-page .message i{ margin-top: 4px; font-size: 18.5px; flex-shrink: 0; }
  .spl-page .message.is-error{ background: var(--danger-soft); border-color: rgba(227, 77, 101, .35); color: var(--danger); }
  .spl-page .message.is-success{ background: var(--success-soft); border-color: rgba(14, 159, 110, .35); color: var(--success); }
  .spl-page .security-note{ margin-top: 22px; display: flex; justify-content: center; align-items: flex-start; gap: 12px; color: var(--muted); font-size: 16px; line-height: 1.8; text-align: center; }
  .spl-page .security-note i{ margin-top: 4px; color: var(--primary); font-size: 23px; flex-shrink: 0; }
  .spl-page .return-area{ margin-top: 26px; display: flex; justify-content: center; align-items: center; gap: 13px; }
  .spl-page .return-area::before, .spl-page .return-area::after{ content: ""; height: 1px; flex: 1; background: var(--border); }
  .spl-page .return-link{ display: inline-flex; align-items: center; gap: 9px; color: var(--primary); font-size: 18.5px; font-weight: 600; text-decoration: underline; text-underline-offset: 4px; transition: .2s ease; }
  .spl-page .return-link:hover{ color: var(--purple); }
  .spl-page .return-link:focus-visible{ outline: 3px solid var(--ring); outline-offset: 3px; border-radius: 4px; }
  .spl-page .success-panel{ display: none; text-align: center; padding: 8px 0 4px; }
  .spl-page .success-panel.show{ display: block; animation: splRiseIn .45s ease both; }
  .spl-page .success-icon{ width: 74px; height: 74px; margin: 0 auto 18px; display: grid; place-items: center; border-radius: 50%; background: var(--success-soft); color: var(--success); font-size: 37px; animation: splPopIn .5s cubic-bezier(.34, 1.56, .64, 1) both; }
  @keyframes splPopIn{ from { transform: scale(.5); opacity: 0; } to { transform: scale(1); opacity: 1; } }
  .spl-page .success-panel h2{ color: var(--navy); font-size: 27.5px; font-weight: 700; }
  .spl-page .success-panel p{ margin-top: 8px; color: var(--muted); font-size: 17px; line-height: 1.8; }
  .spl-page .success-panel strong{ color: var(--primary); font-family: "Poppins", sans-serif; letter-spacing: .5px; }
  .spl-page .reset-link{ display: inline-flex; align-items: center; gap: 8px; margin-top: 20px; padding: 11px 22px; border: 2px solid var(--border); border-radius: 12px; background: var(--surface-2); color: var(--navy); font-family: "Hind Siliguri", sans-serif; font-size: 17px; font-weight: 600; cursor: pointer; transition: .22s ease; }
  .spl-page .reset-link:hover{ border-color: var(--primary); color: var(--primary); }
  .spl-page .reset-link:focus-visible{ outline: 3px solid var(--ring); outline-offset: 2px; }
  .spl-page .input-box.has-toggle input{ padding-right: 60px; }
  .spl-page .toggle-password{ position: absolute; right: 10px; top: 50%; transform: translateY(-50%); width: 40px; height: 40px; display: grid; place-items: center; border: none; border-radius: 10px; background: transparent; color: var(--muted); font-size: 19.5px; cursor: pointer; transition: color .2s ease, background-color .2s ease; }
  .spl-page .toggle-password:hover{ color: var(--primary); background: rgba(8, 121, 232, .08); }
  .spl-page .toggle-password{ padding: 0; z-index: 2; }
  .spl-page .toggle-password:hover{ transform: translateY(-50%); }
  .spl-page .toggle-password svg{ width: 22px; height: 22px; display: block; }
  .spl-page .input-box.has-toggle .field-status{ right: 58px; }
  .spl-page .toggle-password:focus-visible{ outline: 3px solid var(--ring); outline-offset: 2px; }
  .spl-page .footer{ position: relative; z-index: 2; padding: 20px 15px 24px; color: var(--muted); font-family: "Poppins", sans-serif; font-size: 12.5px; text-align: center; letter-spacing: .4px; }
  @media (max-width: 700px){
    .spl-page{ padding: 25px 15px; }
    .spl-page .login-container{ max-width: 540px; border-radius: 23px; }
    .spl-page .login-container::before{ width: 180px; height: 110px; }
    .spl-page .portal-header{ padding: 22px 20px 0; }
    .spl-page .portal-label{ font-size: 16px; gap: 9px; }
    .spl-page .portal-label i{ font-size: 32px; }
    .spl-page .login-content{ padding: 35px 25px 25px; }
    .spl-page .logo{ width: 130px; height: 130px; }
    .spl-page .welcome h1{ font-size: 34.5px; }
    .spl-page .welcome p{ font-size: 17px; }
    .spl-page .input-box input{ height: 60px; font-size: 18.5px; }
    .spl-page .login-button{ height: 59px; font-size: 22px; }
  }
  @media (max-width: 420px){
    .spl-page{ padding: 15px 10px; }
    .spl-page .login-container{ border-radius: 19px; }
    .spl-page .login-container::before{ width: 125px; height: 85px; }
    .spl-page .portal-header{ padding: 17px 14px 0; }
    .spl-page .portal-label{ font-size: 14px; gap: 8px; }
    .spl-page .portal-label i{ font-size: 27.5px; }
    .spl-page .portal-label span{ padding-left: 8px; }
        .spl-page .login-content{ padding: 27px 17px 23px; }
    .spl-page .brand{ margin-bottom: 22px; }
    .spl-page .logo{ width: 110px; height: 110px; margin-bottom: 6px; }
    .spl-page .welcome{ margin-bottom: 22px; }
    .spl-page .welcome h1{ font-size: 31px; }
    .spl-page .welcome p{ font-size: 16px; line-height: 1.8; }
    .spl-page .form-group{ margin-bottom: 17px; }
    .spl-page .form-group label{ font-size: 16px; margin-bottom: 8px; }
    .spl-page .input-box input{
        height: 57px; padding-left: 48px; padding-right: 46px; border-radius: 12px; font-size: 17px;
    }
    .spl-page .input-box > i{ left: 15px; font-size: 18.5px; }
    .spl-page .field-status{ right: 14px; font-size: 19.5px; }
    .spl-page .form-extras{ font-size: 15px; }
    .spl-page .demo-badge{ font-size: 12.5px; padding: 4px 9px; }
    .spl-page .login-button{
        height: 56px; margin-top: 14px; border-radius: 12px; font-size: 20.5px;
    }
    .spl-page .security-note{ margin-top: 18px; gap: 9px; font-size: 14px; }
    .spl-page .security-note i{ font-size: 19.5px; }
    .spl-page .return-area{ margin-top: 23px; gap: 9px; }
    .spl-page .return-link{ font-size: 16px; gap: 7px; }
    .spl-page .success-icon{ width: 62px; height: 62px; font-size: 30px; }
    .spl-page .success-panel h2{ font-size: 23px; }
    .spl-page .success-panel p{ font-size: 16px; }
    .spl-page .footer{ padding: 17px 10px 20px; font-size: 12px; }
  }
  @media (prefers-reduced-motion: reduce){
    .spl-page *, .spl-page *::before, .spl-page *::after{
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
  }

/* ============ DASHBOARD CARD TINTS (admin + student/teacher/staff portals) ============
 Each dashboard card gets its own soft, professional tint via --tb/--tl/--ti variables.
 Specificity is deliberately higher than the portal CSS injected from JS, so no !important fights.
============================================================ */
.kpi-grid > .kpi-card:nth-child(1){ --tb:#ecf8f1; --tl:#c8ebd7; --ti:#157a48; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.kpi-grid > .kpi-card:nth-child(2){ --tb:#fff0f1; --tl:#f6ccd0; --ti:#b4233a; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.kpi-grid > .kpi-card:nth-child(3){ --tb:#eef5ff; --tl:#cde0fa; --ti:#1d4ed8; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.kpi-grid > .kpi-card:nth-child(4){ --tb:#eff0ff; --tl:#d2d6fa; --ti:#4338ca; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.kpi-grid > .kpi-card:nth-child(5){ --tb:#f5efff; --tl:#dfd0f9; --ti:#6d28d9; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.kpi-grid > .kpi-card:nth-child(6){ --tb:#ebf8fb; --tl:#c4e6ee; --ti:#0e7490; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.kpi-grid > .kpi-card:nth-child(7){ --tb:#e8f8f4; --tl:#c0e7de; --ti:#0f766e; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.kpi-grid > .kpi-card:nth-child(8){ --tb:#fff8e6; --tl:#f5e3b2; --ti:#a16207; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.kpi-grid > .kpi-card:nth-child(9){ --tb:#fff2e8; --tl:#f7d8bd; --ti:#c2410c; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.kpi-grid + .dash-2col > .card:nth-child(1){ --tb:#eaf6ff; --tl:#c5e2f7; --ti:#0369a1; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.kpi-grid + .dash-2col > .card:nth-child(2){ --tb:#f4f9e6; --tl:#dcebb8; --ti:#4d7c0f; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.kpi-grid + .dash-2col + .dash-2col > .card:nth-child(1){ --tb:#fffbe6; --tl:#f1e8b0; --ti:#8a6d0a; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.kpi-grid + .dash-2col + .dash-2col > .card:nth-child(2){ --tb:#fff0f7; --tl:#f6cfe2; --ti:#be185d; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.dash-2col + .dash-2col + .card{ --tb:#fff0f1; --tl:#f6ccd0; --ti:#b4233a; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.dash-2col + .dash-2col + .card + .card{ --tb:#fff3ec; --tl:#f6d9c8; --ti:#b45309; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.dash-2col + .dash-2col + .card + .card + .card{ --tb:#f4f1ff; --tl:#dcd5f7; --ti:#5b45c9; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.sd-main .sd-quick-grid > .sd-quick-tile:nth-child(1){ --tb:#eef5ff; --tl:#cde0fa; --ti:#1d4ed8; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.sd-main .sd-quick-grid > .sd-quick-tile:nth-child(2){ --tb:#f5efff; --tl:#dfd0f9; --ti:#6d28d9; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.sd-main .sd-quick-grid > .sd-quick-tile:nth-child(3){ --tb:#ecf8f1; --tl:#c8ebd7; --ti:#157a48; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.sd-main .sd-quick-grid > .sd-quick-tile:nth-child(4){ --tb:#fff2e8; --tl:#f7d8bd; --ti:#c2410c; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.sd-main .sd-quick-grid > .sd-quick-tile:nth-child(5){ --tb:#fff0f1; --tl:#f6ccd0; --ti:#b4233a; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.sd-main .sd-quick-grid > .sd-quick-tile:nth-child(6){ --tb:#e8f8f4; --tl:#c0e7de; --ti:#0f766e; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.sd-main .sd-notice-card{ --tb:#fff8e6; --tl:#f5e3b2; --ti:#a16207; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.sd-main .sd-welcome + .card:not(.sd-notice-card){ --tb:#ebf8fb; --tl:#c4e6ee; --ti:#0e7490; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.sd-main .sd-mini-card{ --tb:#e8f8f4; --tl:#c0e7de; --ti:#0f766e; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.sd-main .sd-mini-grid > .sd-mini-card:nth-child(2){ --tb:#f5efff; --tl:#dfd0f9; --ti:#6d28d9; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.sd-main .sd-mini-grid ~ .card:not(.sd-mini-card){ --tb:#eff0ff; --tl:#d2d6fa; --ti:#4338ca; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.sd-main .sd-due-card{ --tb:#eaf6ff; --tl:#c5e2f7; --ti:#0369a1; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
.sd-main .sd-due-card.sd-due-clear{ --tb:#ecf8f1; --tl:#c8ebd7; --ti:#157a48; --tchip:rgba(255,255,255,.78); --tink:#12305c; }
/* dark theme: translucent tint over the dark card colour */
html[data-theme="dark"] .kpi-grid > .kpi-card:nth-child(1){ --tb:rgba(59,185,120,.14); --tl:rgba(59,185,120,.38); --ti:rgba(59,185,120,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .kpi-grid > .kpi-card:nth-child(2){ --tb:rgba(240,90,110,.14); --tl:rgba(240,90,110,.38); --ti:rgba(240,90,110,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .kpi-grid > .kpi-card:nth-child(3){ --tb:rgba(59,130,246,.14); --tl:rgba(59,130,246,.38); --ti:rgba(59,130,246,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .kpi-grid > .kpi-card:nth-child(4){ --tb:rgba(99,102,241,.14); --tl:rgba(99,102,241,.38); --ti:rgba(99,102,241,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .kpi-grid > .kpi-card:nth-child(5){ --tb:rgba(139,92,246,.14); --tl:rgba(139,92,246,.38); --ti:rgba(139,92,246,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .kpi-grid > .kpi-card:nth-child(6){ --tb:rgba(34,175,205,.14); --tl:rgba(34,175,205,.38); --ti:rgba(34,175,205,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .kpi-grid > .kpi-card:nth-child(7){ --tb:rgba(20,184,166,.14); --tl:rgba(20,184,166,.38); --ti:rgba(20,184,166,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .kpi-grid > .kpi-card:nth-child(8){ --tb:rgba(245,170,30,.14); --tl:rgba(245,170,30,.38); --ti:rgba(245,170,30,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .kpi-grid > .kpi-card:nth-child(9){ --tb:rgba(249,115,22,.14); --tl:rgba(249,115,22,.38); --ti:rgba(249,115,22,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .kpi-grid + .dash-2col > .card:nth-child(1){ --tb:rgba(14,165,233,.14); --tl:rgba(14,165,233,.38); --ti:rgba(14,165,233,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .kpi-grid + .dash-2col > .card:nth-child(2){ --tb:rgba(132,204,22,.14); --tl:rgba(132,204,22,.38); --ti:rgba(132,204,22,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .kpi-grid + .dash-2col + .dash-2col > .card:nth-child(1){ --tb:rgba(234,200,40,.14); --tl:rgba(234,200,40,.38); --ti:rgba(234,200,40,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .kpi-grid + .dash-2col + .dash-2col > .card:nth-child(2){ --tb:rgba(236,72,153,.14); --tl:rgba(236,72,153,.38); --ti:rgba(236,72,153,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .dash-2col + .dash-2col + .card{ --tb:rgba(240,90,110,.14); --tl:rgba(240,90,110,.38); --ti:rgba(240,90,110,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .dash-2col + .dash-2col + .card + .card{ --tb:rgba(251,146,60,.14); --tl:rgba(251,146,60,.38); --ti:rgba(251,146,60,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .dash-2col + .dash-2col + .card + .card + .card{ --tb:rgba(129,110,240,.14); --tl:rgba(129,110,240,.38); --ti:rgba(129,110,240,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .sd-main .sd-quick-grid > .sd-quick-tile:nth-child(1){ --tb:rgba(59,130,246,.14); --tl:rgba(59,130,246,.38); --ti:rgba(59,130,246,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .sd-main .sd-quick-grid > .sd-quick-tile:nth-child(2){ --tb:rgba(139,92,246,.14); --tl:rgba(139,92,246,.38); --ti:rgba(139,92,246,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .sd-main .sd-quick-grid > .sd-quick-tile:nth-child(3){ --tb:rgba(59,185,120,.14); --tl:rgba(59,185,120,.38); --ti:rgba(59,185,120,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .sd-main .sd-quick-grid > .sd-quick-tile:nth-child(4){ --tb:rgba(249,115,22,.14); --tl:rgba(249,115,22,.38); --ti:rgba(249,115,22,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .sd-main .sd-quick-grid > .sd-quick-tile:nth-child(5){ --tb:rgba(240,90,110,.14); --tl:rgba(240,90,110,.38); --ti:rgba(240,90,110,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .sd-main .sd-quick-grid > .sd-quick-tile:nth-child(6){ --tb:rgba(20,184,166,.14); --tl:rgba(20,184,166,.38); --ti:rgba(20,184,166,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .sd-main .sd-notice-card{ --tb:rgba(245,170,30,.14); --tl:rgba(245,170,30,.38); --ti:rgba(245,170,30,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .sd-main .sd-welcome + .card:not(.sd-notice-card){ --tb:rgba(34,175,205,.14); --tl:rgba(34,175,205,.38); --ti:rgba(34,175,205,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .sd-main .sd-mini-card{ --tb:rgba(20,184,166,.14); --tl:rgba(20,184,166,.38); --ti:rgba(20,184,166,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .sd-main .sd-mini-grid > .sd-mini-card:nth-child(2){ --tb:rgba(139,92,246,.14); --tl:rgba(139,92,246,.38); --ti:rgba(139,92,246,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .sd-main .sd-mini-grid ~ .card:not(.sd-mini-card){ --tb:rgba(99,102,241,.14); --tl:rgba(99,102,241,.38); --ti:rgba(99,102,241,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .sd-main .sd-due-card{ --tb:rgba(14,165,233,.14); --tl:rgba(14,165,233,.38); --ti:rgba(14,165,233,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
html[data-theme="dark"] .sd-main .sd-due-card.sd-due-clear{ --tb:rgba(59,185,120,.14); --tl:rgba(59,185,120,.38); --ti:rgba(59,185,120,1); --tchip:rgba(255,255,255,.10); --tink:var(--text); }
.kpi-grid > .kpi-card:nth-child(1),
.kpi-grid > .kpi-card:nth-child(2),
.kpi-grid > .kpi-card:nth-child(3),
.kpi-grid > .kpi-card:nth-child(4),
.kpi-grid > .kpi-card:nth-child(5),
.kpi-grid > .kpi-card:nth-child(6),
.kpi-grid > .kpi-card:nth-child(7),
.kpi-grid > .kpi-card:nth-child(8),
.kpi-grid > .kpi-card:nth-child(9),
.kpi-grid + .dash-2col > .card:nth-child(1),
.kpi-grid + .dash-2col > .card:nth-child(2),
.kpi-grid + .dash-2col + .dash-2col > .card:nth-child(1),
.kpi-grid + .dash-2col + .dash-2col > .card:nth-child(2),
.dash-2col + .dash-2col + .card,
.dash-2col + .dash-2col + .card + .card,
.dash-2col + .dash-2col + .card + .card + .card,
.sd-main .sd-quick-grid > .sd-quick-tile:nth-child(1),
.sd-main .sd-quick-grid > .sd-quick-tile:nth-child(2),
.sd-main .sd-quick-grid > .sd-quick-tile:nth-child(3),
.sd-main .sd-quick-grid > .sd-quick-tile:nth-child(4),
.sd-main .sd-quick-grid > .sd-quick-tile:nth-child(5),
.sd-main .sd-quick-grid > .sd-quick-tile:nth-child(6),
.sd-main .sd-notice-card,
.sd-main .sd-welcome + .card:not(.sd-notice-card),
.sd-main .sd-mini-card,
.sd-main .sd-mini-grid > .sd-mini-card:nth-child(2),
.sd-main .sd-mini-grid ~ .card:not(.sd-mini-card),
.sd-main .sd-due-card,
.sd-main .sd-due-card.sd-due-clear{ background:var(--tb) !important; border:1px solid var(--tl) !important; box-shadow:0 1px 2px rgba(20,30,50,.04); }
.kpi-grid > .kpi-card .kpi-icon{ background:var(--tchip) !important; color:var(--ti) !important; }
.kpi-grid > .kpi-card .kpi-caption{ color:var(--tink); opacity:.78; }
.dash-2col > .card h3, .dash-2col + .dash-2col + .card h3{ color:inherit; }
.sd-main .sd-quick-grid > .sd-quick-tile i{ background:var(--tchip) !important; color:var(--ti) !important; }
.sd-main .sd-quick-grid > .sd-quick-tile{ color:var(--tink); }
.sd-main .sd-mini-card h3, .sd-main .sd-notice-card .sd-card-head h3{ color:var(--ti); }
.sd-main .sd-mini-card h3 i{ color:var(--ti); }
.sd-main .sd-due-card{ color:var(--tink); }
.sd-main .sd-due-card .sd-due-label{ color:var(--ti); opacity:.85; }
.sd-main .sd-due-card .sd-due-amount{ color:var(--tink); }
.sd-main .sd-due-card .sd-due-status{ background:var(--tchip); color:var(--ti); }
.sd-main .sd-due-card .sd-due-btn{ border:1px solid var(--tl) !important; }
html[data-theme="dark"] .sd-main .sd-due-card .sd-due-btn{ background:rgba(255,255,255,.12) !important; color:var(--text) !important; }
html[data-theme="dark"] .sd-main .sd-due-card .sd-due-btn i{ color:var(--text) !important; }
.sd-main .sd-progress{ background:rgba(255,255,255,.7); }
html[data-theme="dark"] .sd-main .sd-progress{ background:rgba(255,255,255,.12); }
.sd-main .sd-contact-line a{ color:var(--ti); text-decoration:none; font-weight:600; }
html[data-theme="dark"] .sd-main .sd-contact-line a{ color:#c4b5fd; }
html[data-theme="dark"] .sd-main .sd-mini-card .sd-due-btn{ background:rgba(255,255,255,.12) !important; color:var(--text) !important; }
html[data-theme="dark"] .sd-main .sd-mini-card .sd-due-btn i{ color:var(--text) !important; }
