/* Tata letak layar sempit.
 *
 * Ditulis sebagai CSS biasa, bukan kelas Tailwind, karena Tailwind di sini datang dari
 * CDN. Kalau CDN-nya lambat atau tidak terjangkau, aturan yang menahan tata letak agar
 * tidak jebol di HP harus tetap berlaku.
 *
 * Satu berkas untuk keempat dashboard. Menyalin aturan yang sama ke masing-masing
 * template hanya memindahkan masalahnya: yang satu diperbaiki, tiga sisanya tertinggal
 * dan tidak ada yang tahu sampai ada yang membukanya dari HP.
 */

/* ==========================================================================
   BILAH ATAS
   ==========================================================================
   Bilah berisi dua kelompok yang sama-sama menolak menyusut: tombol menu di kiri
   bertanda shrink-0, dan seluruh kelompok tombol kanan juga. Selama isinya hanya jam
   dan empat tombol ikon, itu masih muat. Yang membuatnya jebol adalah select navigasi
   layar sempit — sekitar 140 piksel — yang dulu diselipkan ke salah satu kelompok itu.
   Di layar 360 piksel kebutuhannya melewati 450 piksel: judul halaman terhimpit habis
   dan seluruh halaman bisa digeser ke samping.

   Sekarang bilahnya boleh membungkus, dan select-nya punya barisnya sendiri. */

[data-bilah-atas] { flex-wrap: wrap; }

[data-bilah-atas] [data-bilah-baris-bawah] { width: 100%; }
[data-bilah-atas] [data-bilah-baris-bawah].hidden { display: none; }
[data-bilah-atas] [data-bilah-baris-bawah] > select,
[data-bilah-atas] [data-bilah-baris-bawah] > input {
    width: 100%;
    max-width: none;
    border-radius: .75rem;
    border: 1px solid #e2e8f0;
    background: #fff;
    padding: .5rem .75rem;
    font-size: .8125rem;
    font-weight: 700;
}

/* Dua kontrol atau lebih di baris bawah (dashboard orang tua punya pemilih anak dan
   navigasi sekaligus) dibagi rata, bukan ditumpuk memanjang ke bawah. */
[data-bilah-atas] [data-bilah-baris-bawah] {
    display: flex;
    gap: .5rem;
}
[data-bilah-atas] [data-bilah-baris-bawah] > * { flex: 1 1 0; min-width: 0; }

/* Mulai lg sidebar kembali muncul dan navigasinya ada di sana. Baris ini harus ikut
   hilang — kelas lg:hidden milik Tailwind kalah spesifik melawan aturan di atas, jadi
   penyembunyiannya ditulis eksplisit di sini. */
@media (min-width: 1024px) {
    [data-bilah-atas] [data-bilah-baris-bawah] { display: none; }
}

@media (max-width: 640px) {
    [data-bilah-atas] {
        padding-left: .75rem;
        padding-right: .75rem;
        gap: .5rem;
    }

    /* 2,25rem, bukan 2,5rem. Empat tombol kali seperempat rem mengembalikan satu rem
       penuh ke judul halaman, dan targetnya masih 36 piksel — di atas batas nyaman
       untuk jempol. */
    [data-bilah-atas] .tombol-ikon {
        width: 2.25rem;
        height: 2.25rem;
    }

    [data-bilah-atas] h1 {
        font-size: 1.0625rem;
        line-height: 1.5rem;
    }

    /* Tooltip tombol ikon di HP muncul lewat :active. Di dekat tepi kanan layar ia
       terpotong, jadi jangkarnya digeser ke dalam. */
    [data-bilah-atas] .tombol-ikon:last-child::after {
        left: auto;
        right: 0;
        transform: translateX(0) translateY(3px);
    }
    [data-bilah-atas] .tombol-ikon:last-child:active::after {
        transform: translateX(0) translateY(0);
    }
}

/* ==========================================================================
   ISI DASHBOARD SISWA
   ==========================================================================
   Di bawah lg sidebar disembunyikan dan isinya memakai lebar penuh layar. Kartu
   ber-padding 24 piksel di kiri dan kanan, di dalam main yang juga 16 piksel, menyisakan
   288 piksel untuk isi pada layar 360 — dan di dalamnya masih ada kartu statistik,
   tombol, serta judul setebal font-black ukuran 24 piksel yang tidak muat sebaris. */

@media (max-width: 640px) {
    #dashboard main { padding: .75rem; }
    #dashboard main > * + * { margin-top: 1rem; }

    #dashboard .kartu-siswa {
        padding: 1rem;
        border-radius: 1.25rem;
    }

    #dashboard .kartu-siswa h2,
    #dashboard .student-section > div > h2 {
        font-size: 1.25rem;
        line-height: 1.75rem;
    }
    #dashboard .kartu-siswa h3 { font-size: 1.0625rem; line-height: 1.5rem; }

    /* Kolom pencarian kelas memakai satu baris penuh; saringan dan tombol tampilan
       turun ke bawahnya. */
    #dashboard .bilah-cari-siswa { row-gap: .5rem; }

    /* Empat kotak statistik nilai berdampingan menyisakan sekitar 60 piksel per kotak.
       Dua per baris membuat angkanya terbaca. */
    #student-analytics { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    /* Tabel benar-salah dan rekap iuran lebih lebar daripada layarnya. Keduanya sudah
       berada dalam pembungkus overflow-x-auto; yang kurang hanya isyarat bahwa ia bisa
       digeser, dan jaminan tabelnya tidak menyusut sampai tidak terbaca. */
    #dashboard .overflow-x-auto > table { min-width: 32rem; }
    #dashboard .overflow-x-auto { -webkit-overflow-scrolling: touch; }
}

/* Daftar kelas siswa harus tetap terbaca ketika runtime Tailwind CDN tidak termuat.
   Batasi ikon dan ukuran kolom dengan CSS lokal, termasuk kartu yang dirender JS. */
#student-section-classes,
#student-section-classes * { box-sizing: border-box; }
#student-section-classes { min-width: 0; color: #0f172a; }
#student-section-classes .kartu-siswa {
    min-width: 0;
    padding: 1.5rem;
    border: 1px solid #e2e8f0;
    border-radius: 1rem;
    background: #fff;
}
#student-section-classes h2 { margin: 0; font-size: 1.5rem; font-weight: 900; }
#student-section-classes h2 + p { margin: .25rem 0 0; font-size: .875rem; color: #64748b; }
#student-section-classes .bilah-cari-siswa {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    margin: 1rem 0 1.25rem;
    padding: .5rem .75rem;
    border: 1px solid #e2e8f0;
    border-radius: 1rem;
    background: #f8fafc;
}
#student-section-classes .bilah-cari-siswa > div {
    display: flex; align-items: center; gap: .5rem; min-width: 0;
}
#student-section-classes .bilah-cari-siswa > div:first-child { flex: 1 1 12rem; }
#student-section-classes .bilah-cari-siswa > div:last-child { flex: 0 1 auto; margin-left: auto; }
#student-section-classes .bilah-cari-siswa svg { width: 1rem; height: 1rem; flex-shrink: 0; }
#student-section-classes .bilah-cari-siswa > div:first-child svg { width: 1.25rem; height: 1.25rem; }
#student-class-search {
    width: 100%; min-width: 0; flex: 1; padding: .25rem 0;
    border: 0; background: transparent; font: inherit; font-size: .875rem;
}
#student-class-filter { min-width: 0; max-width: 7rem; border: 0; background: transparent; font-size: .75rem; }
#student-section-classes [data-student-class-view] {
    display: flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 2.5rem; height: 2.5rem; padding: 0; border: 0; border-radius: .5rem;
    background: #e2e8f0; color: #475569; cursor: pointer;
}
#student-section-classes [data-student-class-view][aria-pressed="true"] {
    background: #4f46e5; color: #fff;
}
#student-class-list {
    display: grid; grid-template-columns: minmax(0, 1fr); gap: 1rem;
    width: 100%; min-width: 0; font-size: .875rem;
}
#student-class-list > p { grid-column: 1 / -1; overflow-wrap: anywhere; }
#student-class-list .class-card {
    min-width: 0; overflow: hidden; border: 1px solid #e2e8f0;
    border-radius: 1rem; background: #fff; box-shadow: 0 1px 2px #0f172a0d;
}
#student-class-list .class-card-header {
    display: flex; align-items: center; gap: .75rem; padding: 1rem;
    background: linear-gradient(135deg, #6366f1, #6d28d9); color: #fff;
}
#student-class-list .class-card-header > div:first-child {
    display: flex; align-items: center; justify-content: center; flex: 0 0 3rem;
    width: 3rem; height: 3rem; border-radius: .75rem; background: #ffffff33;
}
#student-class-list .class-card-header svg { width: 1.75rem; height: 1.75rem; }
#student-class-list .class-card-header > div:last-child { flex: 1; min-width: 0; }
#student-class-list .class-card-header > div:last-child > div { display: block; min-width: 0; }
#student-class-list .class-card-header h4,
#student-class-list .class-card-header p {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin: 0;
}
#student-class-list .class-card-header h4 { font-size: 1rem; font-weight: 900; }
#student-class-list .class-card-header p { margin-top: .25rem; font-size: .75rem; }
#student-class-list .class-card-body { padding: 1rem; }
#student-class-list .class-card-stats {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .75rem;
}
#student-class-list .class-card-stat {
    display: flex; align-items: center; gap: .5rem; min-width: 0;
    padding: .75rem; border-radius: .5rem; background: #f8fafc;
}
#student-class-list .class-card-stat > div:first-child {
    display: flex; align-items: center; justify-content: center; flex: 0 0 2rem;
    width: 2rem; height: 2rem; border-radius: .5rem; background: #eef2ff; color: #4f46e5;
}
#student-class-list .class-card-stat svg { width: 1.25rem; height: 1.25rem; }
#student-class-list .class-card-stat > div:last-child { min-width: 0; }
#student-class-list .class-card-stat p { margin: 0; }
#student-class-list .class-card-stat p:first-child {
    font-size: .625rem; line-height: .875rem; font-weight: 800; color: #64748b;
    text-transform: uppercase; overflow-wrap: anywhere;
}
#student-class-list .class-card-stat p:last-child {
    font-size: .875rem; font-weight: 800; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#student-class-list .class-card-footer { padding: 1rem; border-top: 1px solid #f1f5f9; background: #f8fafc; }
#student-class-list .class-card-footer > button {
    display: block; width: 100%; min-height: 2.75rem; padding: .625rem .75rem;
    border: 0; border-radius: .75rem; font: inherit; font-weight: 800; cursor: pointer;
    color: #fff; background: linear-gradient(135deg, #6366f1, #6d28d9); overflow-wrap: anywhere;
}
#student-class-list .class-card-footer > button[onclick="showStudentSection('iuran')"] {
    background: #fef2f2; color: #b91c1c; border: 1px solid #fecaca;
}
@media (min-width: 1024px) {
    #student-class-list[data-class-view="grid"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    #student-class-list[data-class-view="list"] .class-card-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (min-width: 1536px) {
    #student-class-list[data-class-view="grid"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
    #student-section-classes .kartu-siswa { padding: .875rem; }
    #student-section-classes h2 { font-size: 1.25rem; }
    #student-section-classes .bilah-cari-siswa > div:first-child { flex-basis: 100%; }
    #student-class-list .class-card-header,
    #student-class-list .class-card-body,
    #student-class-list .class-card-footer { padding: .75rem; }
    #student-class-list .class-card-stats { gap: .5rem; }
    #student-class-list .class-card-stat { padding: .5rem; }
}

/* Layar sangat sempit (360 piksel ke bawah). */
@media (max-width: 380px) {
    [data-bilah-atas] .tombol-ikon { width: 2.125rem; height: 2.125rem; }
    [data-bilah-atas] h1 { font-size: 1rem; }
    #dashboard .kartu-siswa { padding: .875rem; }
}

/* ==========================================================================
   LACI SIDEBAR
   ==========================================================================
   Di bawah titik hentinya, sidebar keempat dashboard ditandai `hidden` dan tidak punya
   cara untuk dibuka. Tombol menu di bilah atas hanya mengganti mode kuncup, dan mode
   kuncup tidak berarti apa-apa pada sidebar yang display-nya none — jadi pengguna HP
   tidak pernah melihat menunya sama sekali.

   Titik hentinya TIDAK ditulis di sini sebagai @media. Ia dihitung sidebar_kuncup.js
   dan saat ini seragam pada 1024 px untuk semua dashboard. Jendela desktop yang
   dipersempit / split-screen karena itu memakai laci, bukan memaksa sidebar tetap
   permanen sampai konten utama terjepit. Menulis angkanya di dua tempat berarti suatu
   hari keduanya berselisih, dan gejalanya adalah laci yang terbuka tetapi tidak
   terlihat. */

/* --------------------------------------------------------------------------
   SIDEBAR DESKTOP + FALLBACK TANPA TAILWIND
   --------------------------------------------------------------------------
   Template lama memakai "hidden lg:flex" / "hidden md:flex". Kalau Tailwind CDN
   terlambat atau gagal, kelas hidden dari CSS dasar tetap menang dan sidebar desktop
   tidak pernah muncul. Keadaan desktop/laci sebenarnya sudah diketahui JavaScript
   lewat .sp-laci-mode, jadi display dan offset layout ditentukan lagi di sini tanpa
   bergantung pada Tailwind. */

html:not(.sp-laci-mode) #dashboard:not(.hidden) > aside,
html:not(.sp-laci-mode) #teacher-dashboard:not(.hidden) > aside,
html:not(.sp-laci-mode) #admin-dashboard:not(.hidden) > aside,
html:not(.sp-laci-mode) #parent-dashboard:not(.hidden) > aside,
html:not(.sp-laci-mode) #penerbit-dashboard:not(.hidden) > aside {
    display: flex !important;
}

/* Sidebar fixed milik siswa/admin/orang-tua butuh ruang nyata pada konten. Kelas
   lg:pl-72/lg:ml-72 tetap dipertahankan sebagai fallback Tailwind, tetapi aturan ini
   membuat layout tetap benar saat Tailwind belum siap dan ikut menyesuaikan icon rail. */
#student-dashboard-shell,
#admin-dashboard > main,
#parent-dashboard > aside + div,
#penerbit-dashboard > aside + div {
    min-width: 0;
    transition: padding-left .18s ease, margin-left .18s ease;
}

html:not(.sp-laci-mode):not(.sp-kuncup) #dashboard:not(.hidden) > aside,
html:not(.sp-laci-mode):not(.sp-kuncup) #admin-dashboard:not(.hidden) > aside,
html:not(.sp-laci-mode):not(.sp-kuncup) #parent-dashboard:not(.hidden) > aside,
html:not(.sp-laci-mode):not(.sp-kuncup) #penerbit-dashboard:not(.hidden) > aside {
    width: 18rem !important;
    min-width: 18rem !important;
    max-width: 18rem !important;
    flex-basis: 18rem !important;
}

html:not(.sp-laci-mode):not(.sp-kuncup) #student-dashboard-shell {
    padding-left: 18rem !important;
}
html:not(.sp-laci-mode):not(.sp-kuncup) #admin-dashboard > main {
    margin-left: 18rem !important;
}
html:not(.sp-laci-mode):not(.sp-kuncup) #parent-dashboard > aside + div,
html:not(.sp-laci-mode):not(.sp-kuncup) #penerbit-dashboard > aside + div {
    padding-left: 18rem !important;
}

html:not(.sp-laci-mode).sp-kuncup #student-dashboard-shell {
    padding-left: 4.5rem !important;
}
html:not(.sp-laci-mode).sp-kuncup #admin-dashboard > main {
    margin-left: 4.5rem !important;
}
html:not(.sp-laci-mode).sp-kuncup #parent-dashboard > aside + div,
html:not(.sp-laci-mode).sp-kuncup #penerbit-dashboard > aside + div {
    padding-left: 4.5rem !important;
}

/* Pada mode laci seluruh lebar viewport adalah milik konten; sidebar melayang di atas.
   Guru memakai flex-layout sehingga tidak perlu offset khusus. */
.sp-laci-mode #teacher-dashboard > main {
    min-width: 0;
    width: 100%;
}
.sp-laci-mode #teacher-dashboard main > div.flex-1 {
    padding: 18px !important;
}

.sp-laci-mode #dashboard > aside,
.sp-laci-mode #teacher-dashboard > aside,
.sp-laci-mode #admin-dashboard > aside,
.sp-laci-mode #parent-dashboard > aside,
.sp-laci-mode #penerbit-dashboard > aside {
    display: flex;
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: auto;
    z-index: 70;

    /* 84vw, bukan lebar tetap: pada layar 320 piksel laci selebar 18rem menyisakan 32
       piksel saja, terlalu sempit untuk disadari sebagai "di luar laci" dan ditekan. */
    width: min(18rem, 84vw) !important;
    min-width: 0 !important;
    max-width: none !important;
    flex-basis: auto !important;

    transform: translateX(-100%);
    visibility: hidden;
    transition: transform .22s ease, visibility .22s ease;
}

.sp-laci-mode.sp-laci #dashboard > aside,
.sp-laci-mode.sp-laci #teacher-dashboard > aside,
.sp-laci-mode.sp-laci #admin-dashboard > aside,
.sp-laci-mode.sp-laci #parent-dashboard > aside,
.sp-laci-mode.sp-laci #penerbit-dashboard > aside {
    transform: translateX(0);
    visibility: visible;
}

/* Isi halaman tidak boleh menyisakan ruang untuk sidebar yang sedang melayang. */
.sp-laci-mode #student-dashboard-shell,
.sp-laci-mode #admin-dashboard > main,
.sp-laci-mode #parent-dashboard > div,
.sp-laci-mode #penerbit-dashboard > div {
    padding-left: 0 !important;
    margin-left: 0 !important;
}

#sp-laci-tirai {
    position: fixed;
    inset: 0;
    z-index: 65;
    background: rgba(15, 23, 42, .55);
    /* Tanpa backdrop-filter.
       Blur di belakang lapisan penuh layar adalah salah satu efek termahal bagi GPU
       ponsel — dan pada laci yang dibuka-tutup puluhan kali sehari, harganya dibayar
       terus-menerus untuk hiasan yang tidak menambah kejelasan apa pun. Warna gelap
       sudah cukup memisahkan laci dari isi di belakangnya. */
}
#sp-laci-tirai.hidden { display: none; }

@media (prefers-reduced-motion: reduce) {
    .sp-laci-mode #dashboard > aside,
    .sp-laci-mode #teacher-dashboard > aside,
    .sp-laci-mode #admin-dashboard > aside,
    .sp-laci-mode #parent-dashboard > aside,
    .sp-laci-mode #penerbit-dashboard > aside { transition: none; }
}

/* ==========================================================================
   RUANG UJIAN SISWA
   ========================================================================== */

/* 100dvh mengikuti tinggi viewport nyata ketika bilah alamat browser ponsel naik/
   turun. Fallback 100vh tetap disediakan untuk WebView lama. */
#student-exam-room {
    height: 100vh;
    height: 100dvh;
}

#student-exam-room > main,
#exam-nav-drawer-body {
    min-height: 0;
}

#mobile-nav-drawer {
    transition: height .22s ease, box-shadow .22s ease;
}

@media (max-width: 767px) {
    #mobile-nav-drawer {
        box-sizing: border-box;
        height: calc(3.5rem + env(safe-area-inset-bottom, 0px));
        max-height: calc(100dvh - 4rem - env(safe-area-inset-top, 0px));
        padding-bottom: env(safe-area-inset-bottom, 0px);
        border-radius: 1rem 1rem 0 0;
        contain: layout paint;
    }

    #mobile-nav-drawer[data-open="1"] {
        height: min(72dvh, 42rem);
        box-shadow: 0 -16px 36px -18px rgba(15, 23, 42, .45);
    }

    /* Saat laci tertutup, hanya tombol pembukanya yang interaktif. Tanpa aturan ini,
       tombol Submit yang terpotong overflow masih dapat menerima fokus/ketukan. */
    #mobile-nav-drawer[data-open="0"] #exam-nav-drawer-body,
    #mobile-nav-drawer[data-open="0"] #exam-nav-drawer-submit {
        visibility: hidden;
        pointer-events: none;
    }

    #exam-nav-drawer-body {
        overflow-y: auto;
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
    }

    #exam-monitor-panel,
    #exam-nav-grid {
        position: relative;
        z-index: 0;
    }

    /* A354: saat rincian status perangkat dibuka, dialah yang mengisi laci -- grid nomor
       soal sudah disembunyikan, jadi panel ini boleh memakai sisa ruang dan menggulir
       sendiri. Tanpa min-height:0 flex item tidak pernah mau lebih pendek dari isinya
       dan tombol Kumpulkan Ujian akan terdorong keluar laci. */
    #student-exam-monitor-panel[data-terbuka="1"] {
        flex: 1 1 auto;
        min-height: 0;
        overflow-y: auto;
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
    }

    /* Ruang ini memastikan pilihan terakhir tidak berada di bawah handle laci. */
    #student-exam-room > main > .flex-1 {
        padding-bottom: calc(5rem + env(safe-area-inset-bottom, 0px)) !important;
    }
}

@media (min-width: 768px) {
    #mobile-nav-drawer {
        height: auto !important;
        max-height: none;
        transition: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    #mobile-nav-drawer { transition: none; }
}

/* ==========================================================================
   PANEL JADWAL SHOLAT
   ==========================================================================
   Panel dipusatkan tanpa batas tinggi dan tanpa gulir. Pada layar pendek, delapan baris
   jadwal beserta paragraf catatannya meluap ke atas dan ke bawah: kepala kartunya —
   berikut satu-satunya tombol tutup — berada di luar layar. Yang terlihat hanya lapisan
   gelap menutupi segalanya tanpa jalan keluar selain memuat ulang halaman.

   Tingginya dibatasi di sini, bukan lewat kelas Tailwind, karena inilah aturan yang
   paling tidak boleh hilang saat CDN-nya tidak terjangkau: tanpa gulir, panel ini
   mengunci seluruh aplikasi. */

.panel-sholat-kartu {
    max-height: 88vh;
    max-height: 88dvh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
}


/* ==========================================================================
   TABEL YANG MENUMPUK DI LAYAR SEMPIT
   ==========================================================================
   Tabel tujuh kolom tidak muat pada layar 360 piksel. Membungkusnya dengan
   overflow-x-auto memang mencegah halamannya melebar, tetapi memindahkan bebannya ke
   pengguna: ia harus menggeser ke samping untuk tiap baris, dan kolom pertama —
   satu-satunya yang memberi tahu baris siapa yang sedang dibaca — hilang begitu ia
   menggeser.

   Di bawah 640 piksel tiap baris menjadi kartu, dan tiap sel membawa nama kolomnya
   sendiri lewat data-kolom. Nama itu ditulis di HTML, bukan di CSS, supaya menambah
   kolom baru tidak menuntut siapa pun ingat memperbarui berkas ini juga. */

@media (max-width: 640px) {
    .tabel-menumpuk thead { display: none; }

    .tabel-menumpuk,
    .tabel-menumpuk tbody,
    .tabel-menumpuk tr,
    .tabel-menumpuk td {
        display: block;
        width: 100%;
    }

    .tabel-menumpuk tr {
        border: 1px solid #e2e8f0;
        border-radius: 1rem;
        padding: .25rem 0;
        margin-bottom: .75rem;
        background: #fff;
    }
    .tabel-menumpuk tr:last-child { margin-bottom: 0; }

    .tabel-menumpuk td {
        display: flex;
        gap: .75rem;
        align-items: baseline;
        justify-content: space-between;
        padding: .5rem .875rem;
        border: 0;
    }

    .tabel-menumpuk td[data-kolom]::before {
        content: attr(data-kolom);
        flex: 0 0 7.5rem;
        font-size: .6875rem;
        font-weight: 900;
        text-transform: uppercase;
        letter-spacing: .04em;
        color: #94a3b8;
        /* Label selalu rata kiri walau selnya text-center/text-right di desktop. */
        text-align: left;
    }

    /* Isi yang panjang — catatan orang tua — lebih baik memakai lebar penuh daripada
       diperas menjadi kolom sempit di sebelah namanya. */
    .tabel-menumpuk td[data-kolom="Catatan"],
    .tabel-menumpuk td[data-kolom="Tindakan"],
    .tabel-menumpuk td[data-kolom="Soal"],
    .tabel-menumpuk td[data-kolom="Aktivitas"] {
        flex-direction: column;
        align-items: stretch;
    }
    /* Pada sel bersusun, flex-basis 7.5rem menjadi TINGGI label dan menyisakan celah
       kosong besar di bawahnya. Labelnya cukup setinggi isinya. */
    .tabel-menumpuk td[data-kolom="Catatan"]::before,
    .tabel-menumpuk td[data-kolom="Tindakan"]::before,
    .tabel-menumpuk td[data-kolom="Soal"]::before,
    .tabel-menumpuk td[data-kolom="Aktivitas"]::before { flex: 0 0 auto; }
    .tabel-menumpuk td[data-kolom="Catatan"] p { max-width: none; }
    .tabel-menumpuk td[data-kolom="Tindakan"] button { flex: 1 1 0; min-height: 2.75rem; }

    /* whitespace-nowrap berguna di dalam sel tabel yang sempit; setelah menumpuk ia
       hanya memaksa baris melebar tanpa alasan. */
    .tabel-menumpuk td.whitespace-nowrap { white-space: normal; }
}

/* ==========================================================================
   KARTU DI DALAM LAPISAN PENUTUP LAYAR
   ==========================================================================
   Sembilan belas lapisan `fixed inset-0` di aplikasi ini memusatkan kartunya dengan
   flex, dan hampir semuanya tanpa batas tinggi. Selama isinya pendek itu tidak
   kelihatan. Begitu isinya lebih tinggi daripada layar — ponsel dalam posisi mendatar,
   laptop 768 piksel, atau modal yang isinya bertambah — kartunya meluap ke ATAS dan ke
   BAWAH sekaligus, karena itulah yang dilakukan pemusatan. Kepala kartunya, berikut
   tombol tutupnya, berada di luar layar.

   Yang tersisa bagi pengguna hanyalah lapisan gelap menutupi segalanya tanpa jalan
   keluar selain memuat ulang halaman. Persis yang pernah terjadi pada panel jadwal
   sholat, dan pola yang sama masih tersebar di banyak modal lain.

   Diperbaiki di satu tempat, bukan di sembilan belas berkas. Menambal satu per satu
   berarti modal berikutnya yang ditulis siapa pun akan mengulangi cacat yang sama.

   Hanya lapisan yang memusatkan isinya (.flex) yang disasar; yang memakai seluruh layar
   sebagai halaman penuh (mis. review soal) mengurus gulirnya sendiri. */

.fixed.inset-0.flex > :not(script):not(style) {
    max-height: 90vh;
    max-height: 90dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* ==========================================================================
   TARGET SENTUH
   ==========================================================================
   Sebagian tombol memakai py-1 (tinggi ±24 piksel). Dengan tetikus itu cukup; dengan
   jempol tidak. Batas yang lazim dipakai adalah 44 piksel, dan yang paling sering
   meleset justru tombol kecil bertuliskan "Edit" atau "Hapus" — yang akibat salah
   tekannya paling mahal.

   pointer: coarse, bukan sekadar lebar layar: laptop layar sentuh membutuhkan hal yang
   sama, sedangkan jendela peramban yang disempitkan di desktop tidak. */

@media (max-width: 640px), (pointer: coarse) {
    button:not(.tombol-ikon):not([data-lonceng-tombol]):not([class*="w-8"]):not([class*="w-9"]):not([class*="w-10"]) {
        min-height: 2.5rem;
    }
    /* Tombol ikon punya ukurannya sendiri dan sudah dijaga di bagian bilah atas. */
    .tombol-ikon { min-height: 0; }
}

/* ==========================================================================
   BILAH ATAS DIRINGKAS DI LAYAR SEMPIT
   ==========================================================================
   Lima tombol berdampingan — sholat, muat ulang, notifikasi, profil, keluar — memakan
   sekitar 190 piksel, dan itu pun setelah teks waktu sholat disembunyikan. Pada layar
   360 piksel judul halaman tinggal sekitar 60 piksel: cukup untuk empat huruf dan titik
   tiga.

   Di bawah 640 piksel kelimanya dilipat ke dalam satu tombol menu. Isinya bukan daftar
   yang ditulis ulang: tombol aslinya dipindahkan ke dalam lembar lalu dikembalikan.
   Daftar yang ditulis dua kali selalu berselisih suatu hari, dan yang tertinggal di
   salah satunya adalah tombol yang hilang tanpa ada yang tahu. */

[data-bilah-ringkas] { display: none; }

@media (max-width: 640px) {
    [data-bilah-atas] [data-bilah-ringkas] { display: inline-flex; }

    /* Semua tombol kelompok kanan disembunyikan KECUALI tombol menunya sendiri.
       Aturan ini tidak menyebut satu pun nama tombol, jadi tombol yang ditambahkan
       kelak — seperti lonceng yang dipasang berkas lain — ikut terlipat dengan
       sendirinya. */
    [data-bilah-atas] [data-bilah-kanan] > button:not([data-bilah-ringkas]) {
        display: none;
    }

    /* Di dalam lembar, tombolnya tampil kembali beserta namanya. */
    #lembar-bilah button.tombol-ikon { display: inline-flex !important; }
}

.lembar-bilah-kartu {
    max-height: 80vh;
    max-height: 80dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-bottom: env(safe-area-inset-bottom, 0px);
}

/* Baris di dalam lembar cukup tinggi untuk jempol, dan seluruh barisnya dapat ditekan. */
#lembar-bilah [data-lembar-isi] > div {
    min-height: 3rem;
    cursor: pointer;
}

/* ==========================================================================
   PANEL NOTIFIKASI
   ==========================================================================
   Di HP ia naik dari bawah seperti panel jadwal sholat — dekat jempol, dan tidak
   menggantung dari tombol yang sudah terlipat ke dalam menu. */

.panel-notifikasi-isi {
    max-height: 70vh;
    max-height: 70dvh;
}

@media (min-width: 640px) {
    .panel-notifikasi-isi {
        max-height: 60vh;
        max-height: 60dvh;
    }
}

@media (max-width: 640px) {
    #panel-notifikasi {
        padding-bottom: env(safe-area-inset-bottom, 0px);
        max-height: 85dvh;
    }
}

/* ==========================================================================
   KARTU KELAS DI DASHBOARD GURU
   ==========================================================================
   Kolom Siswa/Kuis/Materi disejajarkan lewat grid berkolom tetap. Aturan di bawah hanya
   mengurus layar sempit, tempat ketiganya menumpuk di bawah nama kelas. */

@media (max-width: 1023px) {
    .kartu-kelas-guru { gap: .75rem; }
    /* Tombol Buka melebar penuh saat menumpuk: pada baris tersendiri, tombol selebar
       80 piksel di tengah lebih sulit dikenali sebagai tindakan utama kartunya. */
    .kartu-kelas-guru > button { width: 100%; min-height: 2.75rem; }
}

/* Isi dashboard tidak boleh tersembunyi di balik bilah atas yang sticky saat halaman
   digulir ke sebuah bagian. */
#teacher-dashboard section,
#teacher-dashboard [id^="section-"] { scroll-margin-top: 5.5rem; }
