/* ============================================================================
   AURORA.CSS — Lapisan Desain "SAHUR"
   Sistem Absensi & Pengasuhan Santri — Revisi Besar Tahap 3
   ----------------------------------------------------------------------------
   Dimuat PALING AKHIR di <head>, sesudah premium.css. Tidak menghapus satu pun
   kemampuan lama — hanya menaikkan kualitas permukaan, warna, corak, dan gerak.

   ARAH DESAIN
   Aplikasi ini dipakai pada jam-jam yang sangat khas: Tahajjud 03:30, Subuh
   04:45, Briefing Malam 21:00. Paletnya diambil dari jam-jam itu — biru nila
   pekat malam hari yang perlahan menghangat jadi kuningan tua saat cahaya
   pertama. Latar mode terang memakai putih kertas hangat, mengikuti kop surat
   yang memang dicetak oleh aplikasi ini.

   PRINSIP
   1. Kedalaman lewat lapisan, bukan bayangan tebal. Setiap permukaan punya
      rim gradien 1px + bayangan berwarna (bukan abu netral).
   2. Corak adalah tokoh utamanya. Dua belas motif tenun & geometri Islam,
      seluruhnya dari CSS gradient — tajam di layar apa pun, nol berkas gambar,
      dan otomatis ikut warna tema.
   3. Angka adalah isi utama aplikasi ini, jadi angka diperlakukan sebagai
      elemen desain: tabular, tracking rapat, tinta gradien.
   4. Gerak menjawab tindakan. Gerak ambient dibuat sangat lambat & tipis,
      dan benar-benar berhenti pada prefers-reduced-motion.
   5. Splash screen TIDAK disentuh sama sekali (permintaan pengguna).
   6. Saat dicetak, seluruh dekorasi mati.

   DAFTAR ISI
   01. Token & skala
   02. Kanvas, aurora ambient
   03. Sistem corak (12 motif)
   04. Permukaan: kartu, rim gradien, elevasi
   05. Tipografi & perlakuan angka
   06. Kontrol: tombol, field, select, chip, badge
   07. App shell: sidebar, topbar, nav bawah, FAB
   08. Dashboard: panel waktu, kartu statistik, grafik
   09. Tabel, daftar, kartu santri
   10. Modal, drawer, bottom sheet, toast
   11. Halaman login
   12. Pustaka gerak
   13. Kepadatan, radius, skala huruf
   14. Responsif
   15. Reduced motion, kontras tinggi, cetak
   ============================================================================ */

/* ==========================================================================
   01. TOKEN & SKALA
   ========================================================================== */
:root {
    /* --- Aksen kuningan tua ("cahaya pertama"). Dipakai HEMAT: rim, penanda,
           garis pemisah penting. Tidak pernah jadi warna dasar permukaan. --- */
    --brs-50:  250 247 238;
    --brs-200: 226 210 174;
    --brs-400: 200 164  92;
    --brs-600: 146 114  54;

    /* --- Semantik kehadiran. Tiap status = warna + ikon + teks. ----------- */
    --st-hadir:   14 138  95;
    --st-telat:  180 121  26;
    --st-izin:    29 127 184;
    --st-sakit:  109  74 168;
    --st-alpa:   192  43  63;

    /* --- Elevasi berwarna: bayangan mengambil rona primary, bukan abu mati.
           Inilah yang membuat kartu terasa "menyatu" dengan tema. ---------- */
    --sh-1: 0 1px 2px rgb(var(--c-primary-950) / .05),
            0 1px 3px rgb(var(--c-primary-950) / .04);
    --sh-2: 0 2px 4px rgb(var(--c-primary-950) / .05),
            0 8px 18px -10px rgb(var(--c-primary-950) / .14);
    --sh-3: 0 4px 10px rgb(var(--c-primary-950) / .06),
            0 18px 38px -18px rgb(var(--c-primary-950) / .22);
    --sh-4: 0 8px 20px rgb(var(--c-primary-950) / .08),
            0 34px 70px -30px rgb(var(--c-primary-950) / .30);
    --sh-glow: 0 0 0 1px rgb(var(--c-primary-500) / .18),
               0 10px 34px -14px rgb(var(--c-primary-500) / .42);

    /* --- Radius. Dikendalikan modal Tema (Tajam / Lembut / Bulat). -------- */
    --rad: 14px;
    --rad-sm: calc(var(--rad) * .64);
    --rad-lg: calc(var(--rad) * 1.4);
    --rad-pill: 999px;

    /* --- Kepadatan. Dikendalikan modal Tema (Rapat / Nyaman / Lega). ------ */
    --den: 1;

    /* --- Corak: intensitas & skala. Dikendalikan modal Tema. -------------- */
    --corak-alpha: .055;
    --corak-size: 44px;
    --corak-ink: var(--c-primary-600);

    /* --- Gerak ----------------------------------------------------------- */
    --ease-out: cubic-bezier(.22, 1, .36, 1);
    --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
    --mo: 1;            /* dikalikan durasi; jadi 0 saat "kurangi animasi" */
}

html.dark {
    --sh-1: 0 1px 2px rgb(0 0 0 / .40);
    --sh-2: 0 2px 6px rgb(0 0 0 / .42), 0 10px 22px -12px rgb(0 0 0 / .60);
    --sh-3: 0 6px 16px rgb(0 0 0 / .46), 0 22px 46px -20px rgb(0 0 0 / .70);
    --sh-4: 0 10px 26px rgb(0 0 0 / .50), 0 40px 80px -34px rgb(0 0 0 / .80);
    --sh-glow: 0 0 0 1px rgb(var(--c-primary-400) / .26),
               0 12px 40px -14px rgb(var(--c-primary-500) / .55);
    --corak-alpha: .075;
    --corak-ink: var(--c-primary-300);
    --st-hadir:   52 190 135;
    --st-telat:  232 168  62;
    --st-izin:    88 180 238;
    --st-sakit:  168 136 232;
    --st-alpa:   244 110 128;
}

/* ==========================================================================
   02. KANVAS & AURORA AMBIENT
   --------------------------------------------------------------------------
   Dua lapisan tetap (fixed) di belakang seluruh isi:
     .sky-aurora — tiga gumpalan cahaya yang hanyut sangat lambat (60 detik)
     .sky-corak  — motif tenun pilihan pengguna
   Keduanya pointer-events:none dan tidak pernah ikut tercetak.
   ========================================================================== */
html:not(.dark) body {
    background:
        radial-gradient(1100px 620px at 8% -8%,  rgb(var(--c-primary-200) / .34), transparent 62%),
        radial-gradient(900px 560px at 104% 4%,  rgb(var(--brs-200) / .30), transparent 58%),
        #F6F4EF;
}
html.dark body {
    background:
        radial-gradient(1100px 620px at 8% -8%,  rgb(var(--c-primary-800) / .50), transparent 62%),
        radial-gradient(900px 560px at 104% 4%,  rgb(var(--c-primary-900) / .60), transparent 58%),
        #070C18;
}

.sky-layer {
    position: fixed; inset: 0;
    pointer-events: none;
    z-index: 0;
}
#app-shell, #login-screen, #modal-container { position: relative; z-index: 1; }
/* #toast-container SENGAJA tidak lagi disertakan di sini: aturan ini dulu
   membalik posisinya jadi "relative", sehingga wadah toast ikut menempati
   ruang di alur dokumen dan mendorong header/konten utama ke bawah. Posisi
   & tampilan toast sekarang diatur penuh oleh toast.css. */

.sky-aurora::before,
.sky-aurora::after,
.sky-aurora > i {
    content: ''; position: absolute; display: block;
    border-radius: 50%;
    filter: blur(70px);
    opacity: .5;
    will-change: transform;
}
.sky-aurora::before {
    width: 46vw; height: 46vw; min-width: 320px; min-height: 320px;
    top: -14vw; left: -10vw;
    background: rgb(var(--c-primary-400) / .30);
    animation: auroraDriftA calc(64s / var(--mo, 1)) ease-in-out infinite;
}
.sky-aurora::after {
    width: 38vw; height: 38vw; min-width: 260px; min-height: 260px;
    bottom: -16vw; right: -8vw;
    background: rgb(var(--brs-400) / .20);
    animation: auroraDriftB calc(78s / var(--mo, 1)) ease-in-out infinite;
}
.sky-aurora > i {
    width: 26vw; height: 26vw; min-width: 200px; min-height: 200px;
    top: 38%; left: 46%;
    background: rgb(var(--c-primary-300) / .20);
    animation: auroraDriftC calc(92s / var(--mo, 1)) ease-in-out infinite;
}
html.dark .sky-aurora::before { background: rgb(var(--c-primary-500) / .34); opacity: .42; }
html.dark .sky-aurora::after  { background: rgb(var(--brs-600) / .26);       opacity: .36; }
html.dark .sky-aurora > i     { background: rgb(var(--c-primary-700) / .40); opacity: .40; }

@keyframes auroraDriftA {
    0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
    33%      { transform: translate3d(6vw, 4vh, 0) scale(1.12); }
    66%      { transform: translate3d(-3vw, 8vh, 0) scale(.94); }
}
@keyframes auroraDriftB {
    0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
    40%      { transform: translate3d(-7vw, -5vh, 0) scale(1.16); }
    75%      { transform: translate3d(2vw, -9vh, 0) scale(.92); }
}
@keyframes auroraDriftC {
    0%, 100% { transform: translate3d(-50%, -50%, 0) scale(1); }
    50%      { transform: translate3d(-42%, -62%, 0) scale(1.2); }
}

/* ==========================================================================
   03. SISTEM CORAK — 12 MOTIF
   --------------------------------------------------------------------------
   Seluruhnya dibangun dari CSS gradient: tidak ada berkas gambar, tajam pada
   layar kepadatan berapa pun, dan warnanya otomatis mengikuti tema aktif
   lewat --corak-ink.

   Kendali dari modal "Tampilan":
     html[data-corak]        -> motif yang dipakai
     html[data-corak-kuat]   -> halus | sedang | tegas   (mengubah --corak-alpha)
     html[data-corak-area]   -> latar | panel | penuh    (menentukan cakupan)

   Cakupan "latar"  : hanya lapisan belakang aplikasi
           "panel"  : latar + sidebar, topbar, kepala modal, panel waktu
           "penuh"  : panel + seluruh permukaan kartu (paling tegas)
   ========================================================================== */
html[data-corak-kuat="halus"]  { --corak-alpha: .035; }
html[data-corak-kuat="sedang"] { --corak-alpha: .065; }
html[data-corak-kuat="tegas"]  { --corak-alpha: .115; }
html.dark[data-corak-kuat="halus"]  { --corak-alpha: .05; }
html.dark[data-corak-kuat="sedang"] { --corak-alpha: .09; }
html.dark[data-corak-kuat="tegas"]  { --corak-alpha: .155; }

/* Warna tinta motif, dipakai semua definisi di bawah */
.corak-fill { --ci: rgb(var(--corak-ink) / var(--corak-alpha)); }

/* Kotak pratinjau di modal Tampilan memakai [data-corak-lokal]. Selektor global
   [data-corak="x"] .corak-fill berlaku ke SELURUH keturunan <html> — termasuk kotak
   pratinjau — sehingga tanpa penetral ini semua contoh tampil dengan motif yang
   sedang aktif, bukan motifnya sendiri. Kekhususan penetral disamakan dengan
   aturan lokal di bawah (0,2,1) supaya urutan sumber yang menentukan.
   Definisinya sengaja ditaruh di stylesheet, bukan disalin lewat CSSOM saat jalan:
   document.styleSheets.cssRules melempar SecurityError untuk berkas lintas-asal
   (mis. dibuka lewat file:// atau dilayani dari CDN). */
html [data-corak-lokal].corak-fill { background-image: none; }

/* --- 1. Polos ------------------------------------------------------------ */
[data-corak="polos"] .corak-fill,
[data-corak="polos"][data-corak-area="penuh"] .corak-kartu::before,
html [data-corak-lokal="polos"].corak-fill { background-image: none; }

/* --- 2. Titik — kisi titik halus, motif paling tenang -------------------- */
[data-corak="titik"] .corak-fill,
[data-corak="titik"][data-corak-area="penuh"] .corak-kartu::before,
html [data-corak-lokal="titik"].corak-fill {
    background-image: radial-gradient(rgb(var(--corak-ink) / var(--corak-alpha)) 1.1px, transparent 1.2px);
    background-size: calc(var(--corak-size) * .5) calc(var(--corak-size) * .5);
}

/* --- 3. Garis — rambut diagonal ------------------------------------------ */
[data-corak="garis"] .corak-fill,
[data-corak="garis"][data-corak-area="penuh"] .corak-kartu::before,
html [data-corak-lokal="garis"].corak-fill {
    background-image: repeating-linear-gradient(48deg,
        rgb(var(--corak-ink) / var(--corak-alpha)) 0 1px,
        transparent 1px calc(var(--corak-size) * .28));
}

/* --- 4. Anyaman — jalinan bambu dua arah --------------------------------- */
[data-corak="anyaman"] .corak-fill,
[data-corak="anyaman"][data-corak-area="penuh"] .corak-kartu::before,
html [data-corak-lokal="anyaman"].corak-fill {
    background-image:
        repeating-linear-gradient(45deg,  rgb(var(--corak-ink) / var(--corak-alpha)) 0 1.5px, transparent 1.5px calc(var(--corak-size) * .3)),
        repeating-linear-gradient(-45deg, rgb(var(--corak-ink) / var(--corak-alpha)) 0 1.5px, transparent 1.5px calc(var(--corak-size) * .3));
}

/* --- 5. Tenun — silang benang rapat, terasa seperti kain ----------------- */
[data-corak="tenun"] .corak-fill,
[data-corak="tenun"][data-corak-area="penuh"] .corak-kartu::before,
html [data-corak-lokal="tenun"].corak-fill {
    background-image:
        repeating-linear-gradient(0deg,  rgb(var(--corak-ink) / var(--corak-alpha)) 0 1px, transparent 1px calc(var(--corak-size) * .14)),
        repeating-linear-gradient(90deg, rgb(var(--corak-ink) / calc(var(--corak-alpha) * .7)) 0 1px, transparent 1px calc(var(--corak-size) * .14));
}

/* --- 6. Kawung — empat lingkaran Jawa klasik ----------------------------- */
[data-corak="kawung"] .corak-fill,
[data-corak="kawung"][data-corak-area="penuh"] .corak-kartu::before,
html [data-corak-lokal="kawung"].corak-fill {
    background-image:
        radial-gradient(circle at 0 0,           transparent calc(var(--corak-size) * .3), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .3), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .32), transparent calc(var(--corak-size) * .32)),
        radial-gradient(circle at 100% 0,        transparent calc(var(--corak-size) * .3), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .3), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .32), transparent calc(var(--corak-size) * .32)),
        radial-gradient(circle at 0 100%,        transparent calc(var(--corak-size) * .3), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .3), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .32), transparent calc(var(--corak-size) * .32)),
        radial-gradient(circle at 100% 100%,     transparent calc(var(--corak-size) * .3), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .3), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .32), transparent calc(var(--corak-size) * .32)),
        radial-gradient(circle at 50% 50%,       transparent calc(var(--corak-size) * .3), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .3), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .32), transparent calc(var(--corak-size) * .32));
    background-size: var(--corak-size) var(--corak-size);
}

/* --- 7. Songket — tenun benang emas Sumatera, wajik bertingkat ----------- */
[data-corak="songket"] .corak-fill,
[data-corak="songket"][data-corak-area="penuh"] .corak-kartu::before,
html [data-corak-lokal="songket"].corak-fill {
    background-image:
        repeating-linear-gradient(60deg,  rgb(var(--corak-ink) / var(--corak-alpha)) 0 1px, transparent 1px calc(var(--corak-size) * .34)),
        repeating-linear-gradient(-60deg, rgb(var(--corak-ink) / var(--corak-alpha)) 0 1px, transparent 1px calc(var(--corak-size) * .34)),
        repeating-linear-gradient(0deg,   rgb(var(--corak-ink) / calc(var(--corak-alpha) * .55)) 0 1px, transparent 1px calc(var(--corak-size) * .58));
}

/* --- 8. Arabesque — jalinan lengkung tak berujung ------------------------ */
[data-corak="arabesque"] .corak-fill,
[data-corak="arabesque"][data-corak-area="penuh"] .corak-kartu::before,
html [data-corak-lokal="arabesque"].corak-fill {
    background-image:
        radial-gradient(circle at 50% 0,    transparent calc(var(--corak-size) * .24), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .24), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .262), transparent calc(var(--corak-size) * .262)),
        radial-gradient(circle at 0 50%,    transparent calc(var(--corak-size) * .24), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .24), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .262), transparent calc(var(--corak-size) * .262)),
        radial-gradient(circle at 100% 50%, transparent calc(var(--corak-size) * .24), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .24), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .262), transparent calc(var(--corak-size) * .262)),
        radial-gradient(circle at 50% 100%, transparent calc(var(--corak-size) * .24), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .24), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .262), transparent calc(var(--corak-size) * .262));
    background-size: var(--corak-size) var(--corak-size);
}

/* --- 9. Bintang — bintang delapan gaya kufi ------------------------------ */
[data-corak="bintang"] .corak-fill,
[data-corak="bintang"][data-corak-area="penuh"] .corak-kartu::before,
html [data-corak-lokal="bintang"].corak-fill {
    background-image:
        repeating-linear-gradient(45deg,  rgb(var(--corak-ink) / var(--corak-alpha)) 0 1.2px, transparent 1.2px calc(var(--corak-size) * .5)),
        repeating-linear-gradient(-45deg, rgb(var(--corak-ink) / var(--corak-alpha)) 0 1.2px, transparent 1.2px calc(var(--corak-size) * .5)),
        repeating-linear-gradient(0deg,   rgb(var(--corak-ink) / var(--corak-alpha)) 0 1.2px, transparent 1.2px calc(var(--corak-size) * .5)),
        repeating-linear-gradient(90deg,  rgb(var(--corak-ink) / var(--corak-alpha)) 0 1.2px, transparent 1.2px calc(var(--corak-size) * .5));
}

/* --- 10. Mozaik — ubin segitiga masjid ----------------------------------- */
[data-corak="mozaik"] .corak-fill,
[data-corak="mozaik"][data-corak-area="penuh"] .corak-kartu::before,
html [data-corak-lokal="mozaik"].corak-fill {
    background-image:
        linear-gradient(45deg,  rgb(var(--corak-ink) / var(--corak-alpha)) 25%, transparent 25%),
        linear-gradient(-45deg, rgb(var(--corak-ink) / var(--corak-alpha)) 25%, transparent 25%),
        linear-gradient(45deg,  transparent 75%, rgb(var(--corak-ink) / var(--corak-alpha)) 75%),
        linear-gradient(-45deg, transparent 75%, rgb(var(--corak-ink) / var(--corak-alpha)) 75%);
    background-size: var(--corak-size) var(--corak-size);
    background-position: 0 0, 0 calc(var(--corak-size) * .5), calc(var(--corak-size) * .5) calc(var(--corak-size) * -.5), calc(var(--corak-size) * -.5) 0;
}

/* --- 11. Ombak — riak air, garis lengkung bertumpuk ---------------------- */
[data-corak="ombak"] .corak-fill,
[data-corak="ombak"][data-corak-area="penuh"] .corak-kartu::before,
html [data-corak-lokal="ombak"].corak-fill {
    background-image:
        radial-gradient(ellipse calc(var(--corak-size) * .62) calc(var(--corak-size) * .24) at 50% 100%,
            transparent calc(var(--corak-size) * .2), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .21), transparent calc(var(--corak-size) * .24));
    background-size: calc(var(--corak-size) * .9) calc(var(--corak-size) * .45);
}

/* --- 12. Sisik — sisik ikan bertumpuk ------------------------------------ */
[data-corak="sisik"] .corak-fill,
[data-corak="sisik"][data-corak-area="penuh"] .corak-kartu::before,
html [data-corak-lokal="sisik"].corak-fill {
    background-image:
        radial-gradient(circle at 50% 100%, transparent calc(var(--corak-size) * .34), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .34), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .36), transparent calc(var(--corak-size) * .36)),
        radial-gradient(circle at 0 100%,   transparent calc(var(--corak-size) * .34), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .34), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .36), transparent calc(var(--corak-size) * .36)),
        radial-gradient(circle at 100% 100%,transparent calc(var(--corak-size) * .34), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .34), rgb(var(--corak-ink) / var(--corak-alpha)) calc(var(--corak-size) * .36), transparent calc(var(--corak-size) * .36));
    background-size: var(--corak-size) calc(var(--corak-size) * .56);
}

/* --- Lapisan corak latar: hanyut sangat pelan supaya terasa "hidup" ------ */
/* PERFORMA: dulu yang dianimasikan background-position — itu memaksa SELURUH layar
   digambar ulang setiap frame tanpa henti (boros baterai & membuat gulir patah-patah
   di HP). Kini lapisannya dilebarkan 240px ke kiri-atas lalu digeser dengan
   transform: gerak & tampilannya sama persis, tetapi dikerjakan GPU tanpa
   menggambar ulang. */
.sky-corak {
    opacity: 1;
    top: -240px; left: -240px;
    animation: corakHanyut calc(140s / var(--mo, 1)) linear infinite;
    will-change: transform;
}
@keyframes corakHanyut {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(240px, 240px, 0); }
}
/* Mozaik punya background-position bermakna — jangan dihanyutkan. */
[data-corak="mozaik"] .sky-corak { animation: none; }

/* --- Cakupan corak ------------------------------------------------------- */
/* latar (bawaan): hanya .sky-corak yang aktif — sudah otomatis.             */
/* panel: sidebar, topbar, kepala modal, panel waktu ikut bercorak.          */
html[data-corak-area="latar"] .corak-panel::before,
html[data-corak-area="latar"] .corak-kartu::before { display: none; }

.corak-panel { position: relative; isolation: isolate; }
.corak-panel > * { position: relative; z-index: 1; }
.corak-panel::before {
    content: ''; position: absolute; inset: 0; z-index: 0;
    pointer-events: none;
    opacity: .9;
}
html[data-corak-area="panel"] .corak-kartu::before,
html[data-corak-area="latar"] .corak-kartu::before { display: none; }

.corak-kartu { position: relative; isolation: isolate; }
.corak-kartu > * { position: relative; z-index: 1; }
.corak-kartu::before {
    content: ''; position: absolute; inset: 0; z-index: 0;
    pointer-events: none;
    border-radius: inherit;
    opacity: .75;
    background-size: inherit;
}
/* Cakupan "penuh" saja — pada cakupan lain lapisan ini disembunyikan di atas. */
html[data-corak-area="penuh"] .corak-kartu::before { display: block; }

/* ==========================================================================
   04. PERMUKAAN — KARTU, RIM GRADIEN, ELEVASI
   --------------------------------------------------------------------------
   Tiga tingkat permukaan yang sengaja dibedakan, supaya hirarki terbaca tanpa
   harus menumpuk bayangan:
     .surf-hero  — panel utama (panel waktu, hero)
     .surf-card  — kartu data biasa
     .surf-strip — baris/strip tipis di dalam kartu
   ========================================================================== */
html:not(.dark) .surf-card,
html:not(.dark) .surf-hero {
    background:
        linear-gradient(180deg, rgb(255 255 255 / .96), rgb(253 252 250 / .92));
    border: 1px solid rgb(var(--c-primary-900) / .09);
    box-shadow: var(--sh-2);
}
html.dark .surf-card,
html.dark .surf-hero {
    background:
        linear-gradient(180deg, rgb(var(--c-primary-950) / .62), rgb(6 10 22 / .74));
    border: 1px solid rgb(255 255 255 / .08);
    box-shadow: var(--sh-2);
}
.surf-card, .surf-hero {
    border-radius: var(--rad);
    position: relative;
    isolation: isolate;
}

/* Rim gradien 1px — sisi atas kartu menangkap "cahaya", sisi bawah meredup.
   Inilah yang memberi kesan material, bukan kotak datar. */
.surf-card::after, .surf-hero::after {
    content: ''; position: absolute; inset: 0;
    border-radius: inherit; pointer-events: none;
    padding: 1px;
    background: linear-gradient(160deg,
        rgb(255 255 255 / .85) 0%,
        rgb(255 255 255 / 0) 34%,
        rgb(var(--c-primary-500) / 0) 66%,
        rgb(var(--c-primary-500) / .18) 100%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask-composite: exclude;
    z-index: 2;
}
html.dark .surf-card::after, html.dark .surf-hero::after {
    background: linear-gradient(160deg,
        rgb(255 255 255 / .16) 0%,
        rgb(255 255 255 / 0) 34%,
        rgb(var(--c-primary-400) / 0) 66%,
        rgb(var(--c-primary-400) / .22) 100%);
}

.surf-strip {
    border-radius: var(--rad-sm);
    background: rgb(var(--c-primary-500) / .05);
    border: 1px solid rgb(var(--c-primary-500) / .08);
}
html.dark .surf-strip {
    background: rgb(255 255 255 / .035);
    border-color: rgb(255 255 255 / .06);
}

/* Angkat saat disentuh — halus, tidak melompat */
.lift {
    transition: transform calc(.26s * var(--mo)) var(--ease-out),
                box-shadow calc(.26s * var(--mo)) var(--ease-out),
                border-color calc(.26s * var(--mo)) var(--ease-out);
}
@media (hover: hover) {
    .lift:hover {
        transform: translateY(calc(-3px * var(--mo)));
        box-shadow: var(--sh-3);
        border-color: rgb(var(--c-primary-400) / .42);
    }
}

/* Sorotan mengikuti kursor. Dua variabel --mx/--my diisi aurora-motion.js. */
.spot { position: relative; }
.spot::before {
    content: ''; position: absolute; inset: 0;
    border-radius: inherit; pointer-events: none; z-index: 1;
    opacity: 0;
    background: radial-gradient(420px circle at var(--mx, 50%) var(--my, 50%),
        rgb(var(--c-primary-400) / .13), transparent 62%);
    transition: opacity calc(.3s * var(--mo)) var(--ease-out);
}
@media (hover: hover) { .spot:hover::before { opacity: 1; } }

/* Kilau menyapu — dipakai sekali saja pada elemen paling penting */
.sheen { position: relative; overflow: hidden; }
.sheen::after {
    content: ''; position: absolute; top: 0; bottom: 0; width: 46%;
    left: -60%; pointer-events: none; z-index: 3;
    background: linear-gradient(100deg, transparent, rgb(255 255 255 / .34), transparent);
    transform: skewX(-16deg);
    transition: left calc(.85s * var(--mo)) var(--ease-out);
}
@media (hover: hover) { .sheen:hover::after { left: 116%; } }
html.dark .sheen::after { background: linear-gradient(100deg, transparent, rgb(255 255 255 / .12), transparent); }

/* ==========================================================================
   05. TIPOGRAFI & PERLAKUAN ANGKA
   --------------------------------------------------------------------------
   Aplikasi ini isinya hitungan. Jadi angka tidak diperlakukan sebagai teks
   biasa: tabular supaya kolom tidak bergoyang, tracking dirapatkan, dan pada
   angka besar diberi tinta gradien.
   ========================================================================== */
body { font-feature-settings: 'cv02','cv03','cv04','ss01'; }

h1, h2, h3, .font-display {
    font-family: 'Plus Jakarta Sans', 'Inter', system-ui, sans-serif;
    letter-spacing: -.022em;
    font-weight: 700;
}

.num, .tnum, table td, table th {
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum' 1, 'cv02' 1;
}

/* Angka besar: tinta gradien nila -> kuningan. Dipakai hanya pada statistik
   utama, tidak pada angka di dalam tabel. */
.num-hero {
    font-family: 'Plus Jakarta Sans', 'Inter', sans-serif;
    font-weight: 800;
    letter-spacing: -.045em;
    font-variant-numeric: tabular-nums;
    line-height: .92;
    background: linear-gradient(152deg,
        rgb(var(--c-primary-700)) 0%,
        rgb(var(--c-primary-500)) 52%,
        rgb(var(--brs-600)) 124%);
    -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent;
}
html.dark .num-hero {
    background: linear-gradient(152deg,
        rgb(255 255 255) 0%,
        rgb(var(--c-primary-200)) 54%,
        rgb(var(--brs-400)) 126%);
    -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent;
}

/* Gulungan odometer saat angka berubah (dipicu aurora-motion.js) */
.num-roll { display: inline-block; }
.num-roll.is-rolling { animation: numRoll calc(.44s * var(--mo)) var(--ease-out); }
@keyframes numRoll {
    0%   { transform: translateY(.34em); opacity: 0; filter: blur(3px); }
    100% { transform: translateY(0);     opacity: 1; filter: blur(0); }
}

/* Label bagian: garis kuningan pendek, bukan eyebrow huruf besar */
.sec-label {
    display: flex; align-items: center; gap: 10px;
    font-weight: 700; font-size: .9375rem;
    color: rgb(var(--c-primary-900));
    letter-spacing: -.015em;
}
html.dark .sec-label { color: rgb(var(--c-primary-50)); }
.sec-label::before {
    content: ''; width: 3px; height: 1.05em; flex: none;
    border-radius: 2px;
    background: linear-gradient(180deg, rgb(var(--brs-400)), rgb(var(--c-primary-500)));
}

/* ==========================================================================
   06. KONTROL — TOMBOL, FIELD, CHIP, BADGE
   ========================================================================== */
.a-btn {
    position: relative; overflow: hidden;
    display: inline-flex; align-items: center; justify-content: center; gap: 9px;
    min-height: calc(44px * var(--den));
    padding: 0 calc(18px * var(--den));
    border-radius: var(--rad-sm);
    font-weight: 650; font-size: .875rem;
    border: 1px solid transparent;
    cursor: pointer;
    transition: transform calc(.18s * var(--mo)) var(--ease-out),
                box-shadow calc(.22s * var(--mo)) var(--ease-out),
                filter calc(.22s * var(--mo)) var(--ease-out);
}
.a-btn--utama {
    color: #fff;
    background: linear-gradient(140deg,
        rgb(var(--c-primary-500)) 0%,
        rgb(var(--c-primary-600)) 48%,
        rgb(var(--c-primary-700)) 100%);
    box-shadow: 0 1px 0 rgb(255 255 255 / .18) inset,
                0 10px 22px -12px rgb(var(--c-primary-600) / .9);
}
.a-btn--utama:hover { filter: saturate(1.1) brightness(1.05); box-shadow: 0 1px 0 rgb(255 255 255 / .22) inset, 0 16px 30px -12px rgb(var(--c-primary-600) / .95); }
.a-btn--halus {
    background: rgb(var(--c-primary-500) / .1);
    color: rgb(var(--c-primary-700));
    border-color: rgb(var(--c-primary-500) / .2);
}
html.dark .a-btn--halus { color: rgb(var(--c-primary-200)); background: rgb(var(--c-primary-400) / .14); border-color: rgb(var(--c-primary-400) / .24); }
.a-btn--garis {
    background: transparent;
    border-color: rgb(var(--c-primary-500) / .3);
    color: rgb(var(--c-primary-700));
}
html.dark .a-btn--garis { color: rgb(var(--c-primary-200)); }
.a-btn:active { transform: scale(.975); }
.a-btn:focus-visible { outline: 2px solid rgb(var(--c-primary-500)); outline-offset: 2px; }

/* Riak sentuh — elemen dibuat oleh aurora-motion.js */
.a-ripple {
    position: absolute; border-radius: 50%;
    transform: translate(-50%, -50%) scale(0);
    background: rgb(255 255 255 / .42);
    pointer-events: none;
    animation: ripple calc(.62s * var(--mo)) var(--ease-out) forwards;
}
@keyframes ripple { to { transform: translate(-50%, -50%) scale(2.6); opacity: 0; } }

/* Field */
.a-field {
    width: 100%;
    min-height: calc(46px * var(--den));
    padding: 0 14px;
    border-radius: var(--rad-sm);
    border: 1px solid rgb(var(--c-primary-900) / .14);
    background: rgb(255 255 255 / .8);
    font-size: .9375rem;
    transition: border-color calc(.2s * var(--mo)) var(--ease-out),
                box-shadow calc(.2s * var(--mo)) var(--ease-out),
                background calc(.2s * var(--mo)) var(--ease-out);
}
html.dark .a-field { background: rgb(255 255 255 / .05); border-color: rgb(255 255 255 / .1); color: #fff; }
.a-field:focus {
    outline: none;
    border-color: rgb(var(--c-primary-500));
    background: #fff;
    box-shadow: 0 0 0 4px rgb(var(--c-primary-500) / .13);
}
html.dark .a-field:focus { background: rgb(255 255 255 / .08); box-shadow: 0 0 0 4px rgb(var(--c-primary-400) / .16); }

/* Chip / pil penyaring */
.a-chip {
    display: inline-flex; align-items: center; gap: 7px;
    height: calc(34px * var(--den)); padding: 0 14px;
    border-radius: var(--rad-pill);
    font-size: .8125rem; font-weight: 600;
    border: 1px solid rgb(var(--c-primary-900) / .12);
    background: rgb(255 255 255 / .74);
    color: rgb(var(--c-primary-800));
    cursor: pointer;
    transition: all calc(.2s * var(--mo)) var(--ease-out);
}
html.dark .a-chip { background: rgb(255 255 255 / .05); border-color: rgb(255 255 255 / .1); color: rgb(var(--c-primary-100)); }
.a-chip:hover { border-color: rgb(var(--c-primary-400) / .5); transform: translateY(calc(-1px * var(--mo))); }
.a-chip[aria-pressed="true"], .a-chip.is-on {
    background: linear-gradient(140deg, rgb(var(--c-primary-500)), rgb(var(--c-primary-700)));
    border-color: transparent; color: #fff;
    box-shadow: 0 6px 16px -8px rgb(var(--c-primary-600) / .9);
}

/* Badge status — warna + ikon + teks, tidak pernah warna sendirian */
.a-badge {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 3px 10px 3px 8px;
    border-radius: var(--rad-pill);
    font-size: .75rem; font-weight: 650;
    border: 1px solid currentColor;
    background: color-mix(in srgb, currentColor 11%, transparent);
}
.a-badge--hadir { color: rgb(var(--st-hadir)); }
.a-badge--telat { color: rgb(var(--st-telat)); }
.a-badge--izin  { color: rgb(var(--st-izin)); }
.a-badge--sakit { color: rgb(var(--st-sakit)); }
.a-badge--alpa  { color: rgb(var(--st-alpa)); }

/* ==========================================================================
   07. APP SHELL — SIDEBAR, TOPBAR, NAV BAWAH, FAB
   ========================================================================== */

/* --- Sidebar: gradien nila dalam, rim kuningan tipis di tepi kanan ------- */
#app-shell > aside {
    background:
        linear-gradient(176deg,
            rgb(var(--c-primary-900) / .97) 0%,
            rgb(var(--c-primary-950) / .99) 58%,
            #060A14 100%) !important;
    border-right: 1px solid rgb(var(--brs-400) / .16) !important;
    position: relative;
}
#app-shell > aside::after {
    content: ''; position: absolute; top: 0; bottom: 0; right: 0; width: 1px;
    background: linear-gradient(180deg, transparent, rgb(var(--brs-400) / .42) 22%, rgb(var(--brs-400) / .42) 74%, transparent);
    pointer-events: none;
}

/* Butir navigasi: indikator aktif berupa batang kuningan + latar bercahaya */
#desktop-nav a, #desktop-nav button {
    position: relative;
    border-radius: var(--rad-sm);
    transition: background calc(.2s * var(--mo)) var(--ease-out),
                color calc(.2s * var(--mo)) var(--ease-out),
                transform calc(.2s * var(--mo)) var(--ease-out);
}
#desktop-nav a:hover, #desktop-nav button:hover { transform: translateX(calc(2px * var(--mo))); }
#desktop-nav .is-active,
#desktop-nav [aria-current="page"] {
    background: linear-gradient(96deg,
        rgb(var(--c-primary-400) / .24),
        rgb(var(--c-primary-400) / .06)) !important;
    box-shadow: inset 0 0 0 1px rgb(var(--c-primary-300) / .2);
}
#desktop-nav .is-active::before,
#desktop-nav [aria-current="page"]::before {
    content: ''; position: absolute; left: -3px; top: 50%;
    transform: translateY(-50%);
    width: 3px; height: 58%;
    border-radius: 0 3px 3px 0;
    background: linear-gradient(180deg, rgb(var(--brs-200)), rgb(var(--brs-400)));
    box-shadow: 0 0 12px rgb(var(--brs-400) / .8);
}

/* --- Topbar mobile: kaca gelap + corak ---------------------------------- */
/* PERFORMA (topbar & nav bawah): latarnya sudah 93–98% pekat, sehingga blur kaca di
   belakangnya praktis tak terlihat — tetapi tetap dihitung ulang GPU setiap kali
   isi di belakangnya bergulir. Blur dimatikan, latar dipekatkan sedikit. */
.app-topbar {
    background: linear-gradient(180deg,
        rgb(var(--c-primary-900) / .97), rgb(var(--c-primary-950) / .99)) !important;
    -webkit-backdrop-filter: none;
            backdrop-filter: none;
    border-bottom: 1px solid rgb(var(--brs-400) / .2) !important;
}

/* --- Nav bawah: pil kaca melayang, indikator bercahaya ------------------ */
.nav-shell {
    border-radius: var(--rad-lg) !important;
    background: linear-gradient(180deg,
        rgb(var(--c-primary-900) / .97), rgb(6 10 22 / .98)) !important;
    -webkit-backdrop-filter: none;
            backdrop-filter: none;
    border: 1px solid rgb(255 255 255 / .1) !important;
    box-shadow: 0 -2px 0 rgb(var(--brs-400) / .18) inset, var(--sh-4) !important;
}
.nav-indicator {
    background: linear-gradient(140deg, rgb(var(--c-primary-400) / .42), rgb(var(--c-primary-600) / .3)) !important;
    border: 1px solid rgb(var(--c-primary-300) / .42) !important;
    box-shadow: 0 0 18px rgb(var(--c-primary-400) / .5), inset 0 1px 0 rgb(255 255 255 / .22);
    transition: left calc(.38s * var(--mo)) var(--ease-spring),
                transform calc(.24s * var(--mo)) var(--ease-out),
                opacity calc(.2s * var(--mo)) ease !important;
}
.nav-btn.is-active .nav-label { color: #fff !important; font-weight: 700; }

/* --- FAB: denyut sangat pelan supaya terlihat "hidup" ------------------- */
#fab-absen {
    background: linear-gradient(140deg, rgb(var(--c-primary-400)), rgb(var(--c-primary-600))) !important;
    box-shadow: 0 10px 28px -10px rgb(var(--c-primary-500) / .9),
                inset 0 1px 0 rgb(255 255 255 / .26) !important;
    transition: transform calc(.24s * var(--mo)) var(--ease-spring), box-shadow calc(.24s * var(--mo)) var(--ease-out);
}
#fab-absen::before {
    content: ''; position: absolute; inset: -4px;
    border-radius: inherit; z-index: -1;
    background: rgb(var(--c-primary-400) / .34);
    animation: fabDenyut calc(3.4s / var(--mo, 1)) ease-in-out infinite;
}
@keyframes fabDenyut {
    0%, 100% { transform: scale(.94); opacity: .5; }
    50%      { transform: scale(1.06); opacity: 0; }
}
#fab-absen:active { transform: scale(.94); }

/* ==========================================================================
   08. DASHBOARD — PANEL WAKTU, KARTU STATISTIK, GRAFIK
   ========================================================================== */

/* --- Panel Waktu: hero dashboard. Menampilkan sesi yang sedang/akan
       berjalan — hal paling khas dari dunia aplikasi ini. ----------------- */
.panel-waktu {
    position: relative; overflow: hidden;
    border-radius: var(--rad-lg);
    padding: calc(22px * var(--den)) calc(24px * var(--den));
    color: #fff;
    background:
        radial-gradient(760px 340px at 88% -30%, rgb(var(--brs-400) / .30), transparent 60%),
        radial-gradient(620px 320px at 4% 120%,  rgb(var(--c-primary-400) / .34), transparent 62%),
        linear-gradient(142deg, rgb(var(--c-primary-800)) 0%, rgb(var(--c-primary-950)) 62%, #060A14 100%);
    box-shadow: var(--sh-4);
    border: 1px solid rgb(var(--brs-400) / .22);
    isolation: isolate;
}
.panel-waktu > * { position: relative; z-index: 2; }
/* Cahaya fajar yang menyapu dari kiri bawah — 1 gerakan ambient, sangat pelan */
.panel-waktu::after {
    content: ''; position: absolute; z-index: 1;
    width: 150%; height: 150%; left: -25%; bottom: -70%;
    background: radial-gradient(ellipse at center, rgb(var(--brs-400) / .16), transparent 58%);
    animation: fajar calc(22s / var(--mo, 1)) ease-in-out infinite;
    pointer-events: none;
}
@keyframes fajar {
    0%, 100% { transform: translate3d(0, 0, 0) scale(1);   opacity: .55; }
    50%      { transform: translate3d(8%, -6%, 0) scale(1.14); opacity: .95; }
}
.panel-waktu-jam {
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-weight: 800; letter-spacing: -.05em;
    font-variant-numeric: tabular-nums;
    line-height: .9;
    background: linear-gradient(140deg, #fff 0%, rgb(var(--brs-200)) 100%);
    -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent;
}

/* --- Kartu statistik ---------------------------------------------------- */
.stat-kartu {
    position: relative; overflow: hidden;
    border-radius: var(--rad);
    padding: calc(16px * var(--den));
    background: linear-gradient(170deg, rgb(255 255 255 / .96), rgb(252 251 248 / .9));
    border: 1px solid rgb(var(--c-primary-900) / .09);
    box-shadow: var(--sh-1);
    transition: transform calc(.28s * var(--mo)) var(--ease-out),
                box-shadow calc(.28s * var(--mo)) var(--ease-out);
}
html.dark .stat-kartu {
    background: linear-gradient(170deg, rgb(var(--c-primary-950) / .7), rgb(6 10 22 / .82));
    border-color: rgb(255 255 255 / .08);
}
/* Batang warna semantik di tepi kiri — menggantikan kotak ikon berwarna */
.stat-kartu::before {
    content: ''; position: absolute; left: 0; top: 14%; bottom: 14%; width: 3px;
    border-radius: 0 3px 3px 0;
    background: var(--stat-warna, rgb(var(--c-primary-500)));
    box-shadow: 0 0 14px var(--stat-warna, rgb(var(--c-primary-500)));
    opacity: .9;
}
@media (hover: hover) {
    .stat-kartu:hover { transform: translateY(calc(-4px * var(--mo))); box-shadow: var(--sh-3); }
}

/* Cincin kemajuan (persentase kehadiran) */
.ring-track { stroke: rgb(var(--c-primary-500) / .12); }
.ring-value {
    stroke: url(#ringGrad);
    stroke-linecap: round;
    transition: stroke-dashoffset calc(1.1s * var(--mo)) var(--ease-out);
    filter: drop-shadow(0 0 5px rgb(var(--c-primary-400) / .55));
}

/* Batang bar sederhana yang tumbuh dari nol */
.bar-tumbuh { transform-origin: bottom; transition: transform calc(.8s * var(--mo)) var(--ease-out); }

/* ==========================================================================
   09. TABEL, DAFTAR, KARTU SANTRI
   ========================================================================== */
.a-tabel { width: 100%; border-collapse: separate; border-spacing: 0; }
.a-tabel thead th {
    position: sticky; top: 0; z-index: 2;
    /* PERFORMA: latar pekat (warna aksen tipis di atas putih) menggantikan blur kaca —
       baris yang tergulir di bawah kepala tabel tetap tertutup rapi. */
    background: linear-gradient(rgb(var(--c-primary-500) / .07), rgb(var(--c-primary-500) / .07)), #FFFFFF;
    font-size: .75rem; font-weight: 700;
    color: rgb(var(--c-primary-800));
    padding: 11px 12px; text-align: left;
    border-bottom: 1px solid rgb(var(--c-primary-500) / .16);
}
html.dark .a-tabel thead th { background: linear-gradient(rgb(255 255 255 / .05), rgb(255 255 255 / .05)), rgb(var(--c-primary-950)); color: rgb(var(--c-primary-100)); }
.a-tabel tbody td { padding: 11px 12px; border-bottom: 1px solid rgb(var(--c-primary-900) / .06); font-size: .875rem; }
html.dark .a-tabel tbody td { border-bottom-color: rgb(255 255 255 / .05); }
.a-tabel tbody tr { transition: background calc(.16s * var(--mo)) ease; }
.a-tabel tbody tr:hover { background: rgb(var(--c-primary-500) / .05); }

/* Pembungkus gulir mendatar supaya halaman tidak ikut bergeser */
.a-scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: var(--rad-sm); }
.a-scroll-x::-webkit-scrollbar { height: 7px; }
.a-scroll-x::-webkit-scrollbar-thumb { background: rgb(var(--c-primary-500) / .3); border-radius: 9px; }

/* Kartu santri */
.kartu-santri {
    transition: transform calc(.24s * var(--mo)) var(--ease-out),
                box-shadow calc(.24s * var(--mo)) var(--ease-out),
                border-color calc(.24s * var(--mo)) var(--ease-out);
}
@media (hover: hover) {
    .kartu-santri:hover { transform: translateY(calc(-3px * var(--mo))); box-shadow: var(--sh-3); }
}

/* Avatar dengan cincin gradien */
.avatar-cincin { position: relative; }
.avatar-cincin::before {
    content: ''; position: absolute; inset: -2.5px;
    border-radius: 50%; z-index: -1;
    background: conic-gradient(from 210deg,
        rgb(var(--c-primary-400)), rgb(var(--brs-400)), rgb(var(--c-primary-600)), rgb(var(--c-primary-400)));
}

/* ==========================================================================
   10. MODAL, DRAWER, BOTTOM SHEET, TOAST
   ========================================================================== */
#modal-container > div,
.modal-backdrop {
    -webkit-backdrop-filter: blur(10px) saturate(1.2);
            backdrop-filter: blur(10px) saturate(1.2);
}
.a-modal-masuk { animation: modalMasuk calc(.36s * var(--mo)) var(--ease-spring) both; }
@keyframes modalMasuk {
    from { opacity: 0; transform: translateY(14px) scale(.965); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}
.a-sheet-masuk { animation: sheetMasuk calc(.34s * var(--mo)) var(--ease-out) both; }
@keyframes sheetMasuk {
    from { transform: translateY(100%); }
    to   { transform: translateY(0); }
}

/* Kepala modal bercorak (cakupan "panel" ke atas) */
.modal-kepala {
    background: linear-gradient(140deg,
        rgb(var(--c-primary-500) / .1), rgb(var(--brs-400) / .07));
    border-bottom: 1px solid rgb(var(--c-primary-500) / .14);
}
html.dark .modal-kepala { background: linear-gradient(140deg, rgb(var(--c-primary-400) / .13), rgb(var(--brs-600) / .1)); }

/* Toast */
#toast-container > div {
    border-radius: var(--rad-sm) !important;
    box-shadow: var(--sh-4) !important;
    border: 1px solid rgb(255 255 255 / .14);
    animation: toastMasuk calc(.4s * var(--mo)) var(--ease-spring) both;
}
@keyframes toastMasuk {
    from { opacity: 0; transform: translateY(-14px) scale(.94); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* Centang tergambar — dipakai setelah simpan berhasil */
.centang-gambar { stroke-dasharray: 48; stroke-dashoffset: 48; animation: centang calc(.5s * var(--mo)) var(--ease-out) forwards; }
@keyframes centang { to { stroke-dashoffset: 0; } }

/* ==========================================================================
   11. HALAMAN LOGIN
   --------------------------------------------------------------------------
   Panel kiri memakai palet & corak yang sama dengan aplikasi, sehingga login
   terasa satu kesatuan dengan isi — bukan halaman terpisah.
   ========================================================================== */
html:not(.dark) #login-screen {
    background:
        radial-gradient(1000px 560px at 12% 6%,  rgb(var(--c-primary-200) / .5), transparent 62%),
        radial-gradient(760px 520px at 96% 94%,  rgb(var(--brs-200) / .42), transparent 60%),
        #F6F4EF;
}
html.dark #login-screen {
    background:
        radial-gradient(1000px 560px at 12% 6%,  rgb(var(--c-primary-800) / .6), transparent 62%),
        radial-gradient(760px 520px at 96% 94%,  rgb(var(--c-primary-900) / .7), transparent 60%),
        #070C18;
}
.login-brand-panel {
    background:
        radial-gradient(680px 460px at 12% 14%, rgb(var(--c-primary-500) / .42), transparent 62%),
        radial-gradient(560px 440px at 92% 90%, rgb(var(--brs-600) / .34), transparent 60%),
        linear-gradient(148deg, rgb(var(--c-primary-800)) 0%, rgb(var(--c-primary-950)) 54%, #060A14 100%) !important;
}
.login-form-shell {
    border-radius: var(--rad-lg) !important;
    border-color: rgb(var(--c-primary-900) / .1) !important;
}
html.dark .login-form-shell { border-color: rgb(255 255 255 / .09) !important; }
.login-submit {
    border-radius: var(--rad-sm) !important;
    background: linear-gradient(140deg,
        rgb(var(--c-primary-500)) 0%, rgb(var(--c-primary-600)) 50%, rgb(var(--c-primary-800)) 100%) !important;
    box-shadow: 0 14px 30px -14px rgb(var(--c-primary-600) / .95),
                inset 0 1px 0 rgb(255 255 255 / .2) !important;
}
.login-pill-input { border-radius: var(--rad-sm) !important; }
.login-kicker { color: rgb(var(--c-primary-600)) !important; }
html.dark .login-kicker { color: rgb(var(--brs-400)) !important; }

/* ==========================================================================
   12. PUSTAKA GERAK
   --------------------------------------------------------------------------
   Satu rangkaian masuk yang terorkestrasi saat halaman berpindah, bukan efek
   yang berserakan. Diatur aurora-motion.js lewat kelas .reveal.
   ========================================================================== */
.reveal { opacity: 0; transform: translateY(12px); animation: revealAman 1ms linear 2.5s forwards; }
@keyframes revealAman { to { opacity: 1; transform: none; } }
.reveal.is-in {
    opacity: 1; transform: none;   /* keadaan akhir sebagai gaya dasar, animasi hanya "backwards" */
    animation: revealIn calc(.52s * var(--mo)) var(--ease-out) backwards;
    animation-delay: var(--d, 0ms);
}
@keyframes revealIn {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: none; }   /* v1.6: bukan translateY(0) — lihat halamanMasuk */
}

/* Transisi ganti halaman */
/* fill-mode "backwards" (bukan "both"): setelah animasi selesai TIDAK ada transform tersisa.
   Peramban mengubah "transform: none" di akhir animasi ber-fill menjadi matriks identitas, yang
   tetap menjadikan #content-area acuan elemen position:fixed (penyebab bilah "melayang"). */
.halaman-masuk { animation: halamanMasuk calc(.34s * var(--mo)) var(--ease-out) backwards; }
/* v1.6 PERBAIKAN: dulu berakhir di translateY(0) dengan fill-mode "both", sehingga #content-area
   SELAMANYA ber-transform. Elemen position:fixed di dalam halaman (bilah "Simpan Data Absensi",
   lembar profil game, dll.) lalu menempel ke #content-area, ikut tergulir, dan tampak melayang
   di tengah layar — hanya di perangkat yang animasinya aktif. transform: none tidak membuat
   blok acuan baru. */
@keyframes halamanMasuk {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
}

/* Kerangka muat (skeleton) */
.a-skel {
    position: relative; overflow: hidden;
    background: rgb(var(--c-primary-500) / .08);
    border-radius: var(--rad-sm);
}
.a-skel::after {
    content: ''; position: absolute; inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(90deg, transparent, rgb(var(--c-primary-400) / .16), transparent);
    animation: skel calc(1.5s / var(--mo, 1)) ease-in-out infinite;
}
@keyframes skel { to { transform: translateX(100%); } }

/* Titik "langsung" pada indikator sinkron */
.titik-hidup { position: relative; }
.titik-hidup::before {
    content: ''; position: absolute; inset: -4px;
    border-radius: 50%; background: currentColor; opacity: .34;
    animation: titikDenyut calc(2.2s / var(--mo, 1)) ease-out infinite;
}
@keyframes titikDenyut {
    0%   { transform: scale(.7); opacity: .4; }
    70%, 100% { transform: scale(2); opacity: 0; }
}

/* ==========================================================================
   13. KEPADATAN, RADIUS, SKALA HURUF  (dikendalikan modal Tampilan)
   ========================================================================== */
html[data-padat="rapat"]  { --den: .86; }
html[data-padat="nyaman"] { --den: 1; }
html[data-padat="lega"]   { --den: 1.18; }

html[data-sudut="tajam"]  { --rad: 5px; }
html[data-sudut="lembut"] { --rad: 14px; }
html[data-sudut="bulat"]  { --rad: 22px; }

html[data-huruf="kecil"]  { font-size: 15px; }
html[data-huruf="normal"] { font-size: 16px; }
html[data-huruf="besar"]  { font-size: 17.5px; }
html[data-huruf="sangat-besar"] { font-size: 19px; }

/* Kurangi animasi (pilihan pengguna) — semua durasi jadi nol */
html[data-gerak="minim"] { --mo: .001; }
html[data-gerak="minim"] .sky-aurora::before,
html[data-gerak="minim"] .sky-aurora::after,
html[data-gerak="minim"] .sky-aurora > i,
html[data-gerak="minim"] .sky-corak,
html[data-gerak="minim"] .panel-waktu::after,
html[data-gerak="minim"] #fab-absen::before,
html[data-gerak="minim"] .titik-hidup::before,
html[data-gerak="minim"] .a-skel::after { animation: none !important; }

/* ==========================================================================
   14. RESPONSIF
   ========================================================================== */
@media (max-width: 1024px) {
    :root { --corak-size: 38px; }
    .panel-waktu { padding: 18px; border-radius: var(--rad); }
}
@media (max-width: 640px) {
    :root { --corak-size: 32px; }
    /* Aurora dimatikan di layar kecil: hemat baterai & GPU pada HP kelas bawah */
    .sky-aurora { display: none; }
    .panel-waktu { padding: 16px; }
    .surf-card, .surf-hero { border-radius: var(--rad); }
    .a-tabel thead th, .a-tabel tbody td { padding: 9px 10px; font-size: .8125rem; }
}
/* Target sentuh minimum 44px pada perangkat sentuh */
@media (pointer: coarse) {
    .a-btn, .a-chip, button, [role="button"] { min-height: 44px; }
    .a-chip { height: 40px; }
}

/* ==========================================================================
   15. REDUCED MOTION, KONTRAS TINGGI, CETAK
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
    :root { --mo: .001; }
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
    .sky-aurora, .sky-corak { animation: none !important; }
    .reveal { opacity: 1; transform: none; }
}

@media (prefers-contrast: more) {
    :root { --corak-alpha: .02; }
    .surf-card, .surf-hero { border-width: 2px; border-color: rgb(var(--c-primary-700)); }
    .a-tabel tbody td { border-bottom-color: rgb(var(--c-primary-800) / .3); }
}

@media print {
    /* Cetak = dokumen resmi. Seluruh dekorasi dimatikan. */
    .sky-layer, .sky-aurora, .sky-corak { display: none !important; }
    .corak-panel::before, .corak-kartu::before { display: none !important; }
    .panel-waktu::after, .sheen::after, .spot::before { display: none !important; }
    .surf-card, .surf-hero, .stat-kartu {
        box-shadow: none !important;
        border: 1px solid #999 !important;
        background: #fff !important;
    }
    .surf-card::after, .surf-hero::after { display: none !important; }
    .num-hero, .panel-waktu-jam {
        -webkit-text-fill-color: #000 !important;
        background: none !important;
        color: #000 !important;
    }
    .panel-waktu { background: #fff !important; color: #000 !important; border: 1px solid #999 !important; }
    * { animation: none !important; transition: none !important; }
}

/* ==========================================================================
   16. PEMETAAN KE MARKUP LAMA
   --------------------------------------------------------------------------
   Aplikasi lama sudah memakai kelas penanda yang konsisten: .shadow-elegant
   untuk setiap kartu, .stat-tile untuk kartu statistik, .chart-card untuk
   panel grafik, dan seterusnya. Dengan menargetkan penanda itu, seluruh
   9.000 baris markup ikut naik kelas tanpa satu pun template ditulis ulang —
   sekaligus menjamin tidak ada fitur yang rusak karena markup-nya diubah.
   ========================================================================== */

/* --- Kartu umum ---------------------------------------------------------- */
html:not(.dark) .shadow-elegant {
    background: linear-gradient(180deg, rgb(255 255 255 / .97), rgb(253 252 249 / .93)) !important;
    border-color: rgb(var(--c-primary-900) / .1) !important;
    box-shadow: var(--sh-2) !important;
}
/* PERFORMA: kelas ini dipakai puluhan kartu sekaligus. Blur kaca (backdrop-filter)
   di setiap kartu harus dihitung ulang GPU tiap kali latar bergerak/bergulir — inilah
   sumber utama rasa "berat" di HP & tablet. Di mode terang latarnya 93–97% pekat
   (blur tak terlihat); di mode gelap latar dipekatkan sedikit sebagai gantinya. */
html.dark .shadow-elegant {
    background: linear-gradient(180deg, rgb(var(--c-primary-950) / .74), rgb(6 10 22 / .86)) !important;
    border-color: rgb(255 255 255 / .08) !important;
    box-shadow: var(--sh-2) !important;
}
.shadow-elegant {
    position: relative;
    transition: box-shadow calc(.28s * var(--mo)) var(--ease-out),
                border-color calc(.28s * var(--mo)) var(--ease-out),
                transform calc(.28s * var(--mo)) var(--ease-out);
}
/* Rim gradien 1px — sisi atas menangkap cahaya, sisi bawah meredup */
.shadow-elegant::before {
    content: ''; position: absolute; inset: 0; z-index: 0;
    border-radius: inherit; pointer-events: none;
    padding: 1px;
    background: linear-gradient(158deg,
        rgb(255 255 255 / .9) 0%, rgb(255 255 255 / 0) 36%,
        rgb(var(--c-primary-500) / 0) 64%, rgb(var(--c-primary-500) / .2) 100%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask-composite: exclude;
}
html.dark .shadow-elegant::before {
    background: linear-gradient(158deg,
        rgb(255 255 255 / .17) 0%, rgb(255 255 255 / 0) 36%,
        rgb(var(--c-primary-400) / 0) 64%, rgb(var(--c-primary-400) / .24) 100%);
}
@media (hover: hover) {
    .shadow-elegant:hover { box-shadow: var(--sh-3) !important; border-color: rgb(var(--c-primary-400) / .36) !important; }
}

/* --- Kartu statistik: batang warna semantik + angka gradien -------------- */
.stat-tile { overflow: hidden; }
.stat-tile::after {
    content: ''; position: absolute; left: 0; top: 16%; bottom: 16%; width: 3px;
    border-radius: 0 3px 3px 0; z-index: 1;
    background: rgb(var(--c-primary-500));
    box-shadow: 0 0 14px rgb(var(--c-primary-500) / .7);
    opacity: .85;
}
.stat-tile:nth-child(1)::after { background: rgb(var(--st-hadir)); box-shadow: 0 0 14px rgb(var(--st-hadir) / .7); }
.stat-tile:nth-child(2)::after { background: rgb(var(--st-telat)); box-shadow: 0 0 14px rgb(var(--st-telat) / .7); }
.stat-tile:nth-child(3)::after { background: rgb(var(--st-sakit)); box-shadow: 0 0 14px rgb(var(--st-sakit) / .7); }
.stat-tile:nth-child(4)::after { background: rgb(var(--st-izin));  box-shadow: 0 0 14px rgb(var(--st-izin) / .7); }
.stat-tile:nth-child(5)::after { background: rgb(var(--st-alpa));  box-shadow: 0 0 14px rgb(var(--st-alpa) / .7); }
@media (hover: hover) {
    .stat-tile:hover { transform: translateY(calc(-4px * var(--mo))); }
}
/* Angka besar di dalam kartu statistik diberi tinta gradien */
.stat-tile [data-count], .stat-tile .text-3xl, .stat-tile .text-2xl {
    font-variant-numeric: tabular-nums;
    letter-spacing: -.04em;
}

/* --- Panel grafik -------------------------------------------------------- */
.chart-card { overflow: hidden; }
.chart-card canvas { position: relative; z-index: 1; }

/* --- Rel rekap ----------------------------------------------------------- */
/* PERBAIKAN: dulu `overflow: hidden` — chip rekap di luar lebar layar HP
   ("Terlambat", "Alpa", …) tersembunyi dan tidak bisa digeser. */
.recap-rail { overflow-x: auto; overflow-y: hidden; }

/* --- Tombol ikon --------------------------------------------------------- */
.icon-btn {
    position: relative;
    border-radius: var(--rad-sm) !important;
    transition: background calc(.2s * var(--mo)) var(--ease-out),
                transform calc(.2s * var(--mo)) var(--ease-spring),
                color calc(.2s * var(--mo)) ease;
}
.icon-btn:hover { background: rgb(255 255 255 / .12); transform: translateY(calc(-1px * var(--mo))); }
.icon-btn:active { transform: scale(.92); }
.badge-count {
    box-shadow: 0 0 0 2px rgb(var(--c-primary-900)), 0 0 12px rgb(var(--st-alpa) / .8);
    animation: badgeDenyut calc(2.6s / var(--mo, 1)) ease-in-out infinite;
}
@keyframes badgeDenyut {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.12); }
}

/* --- Chip sinkron: titik berdenyut saat daring -------------------------- */
.sync-chip {
    border-radius: var(--rad-pill) !important;
    transition: all calc(.24s * var(--mo)) var(--ease-out);
}
.sync-chip.is-online { color: rgb(var(--st-hadir)); }

/* --- Tombol utama lama (bg-primary-600) dinaikkan jadi gradien ---------- */
button.bg-primary-600, a.bg-primary-600,
button.bg-primary-700, .btn-ripple.bg-primary-600 {
    background-image: linear-gradient(140deg,
        rgb(var(--c-primary-500)), rgb(var(--c-primary-700))) !important;
    box-shadow: inset 0 1px 0 rgb(255 255 255 / .18),
                0 8px 20px -10px rgb(var(--c-primary-600) / .85);
    transition: filter calc(.2s * var(--mo)) ease,
                box-shadow calc(.22s * var(--mo)) var(--ease-out),
                transform calc(.16s * var(--mo)) var(--ease-out);
}
button.bg-primary-600:hover, a.bg-primary-600:hover, button.bg-primary-700:hover {
    filter: saturate(1.1) brightness(1.06);
    box-shadow: inset 0 1px 0 rgb(255 255 255 / .22),
                0 14px 28px -10px rgb(var(--c-primary-600) / .95);
}
button.bg-primary-600:active, a.bg-primary-600:active { transform: scale(.98); }

/* --- Panel kaca ---------------------------------------------------------- */
html:not(.dark) .glass-panel {
    background: rgb(255 255 255 / .82) !important;
    -webkit-backdrop-filter: blur(18px) saturate(1.5); backdrop-filter: blur(18px) saturate(1.5);
    border-color: rgb(var(--c-primary-900) / .1) !important;
}
html.dark .glass-panel {
    background: rgb(10 16 30 / .82) !important;
    -webkit-backdrop-filter: blur(18px) saturate(1.5); backdrop-filter: blur(18px) saturate(1.5);
    border-color: rgb(255 255 255 / .09) !important;
}

/* --- Garis aksen atas jadi gradien nila -> kuningan --------------------- */
.accent-top::before {
    background: linear-gradient(90deg,
        rgb(var(--c-primary-500)), rgb(var(--brs-400)) 62%, transparent) !important;
    height: 2px !important;
}

/* --- Reveal bawaan lama dipakai ulang oleh mesin gerak baru ------------- */
.reveal-up { will-change: transform, opacity; }

/* --- Field lama ---------------------------------------------------------- */
input:not([type="checkbox"]):not([type="radio"]):not([type="color"]):not([type="file"]),
select, textarea {
    border-radius: var(--rad-sm) !important;
    transition: border-color calc(.2s * var(--mo)) var(--ease-out),
                box-shadow calc(.2s * var(--mo)) var(--ease-out);
}
input:focus, select:focus, textarea:focus {
    box-shadow: 0 0 0 4px rgb(var(--c-primary-500) / .13);
}

/* --- Modal & drawer lama ------------------------------------------------- */
#modal-container > div > div,
#drawer-panel {
    border-radius: var(--rad-lg) !important;
    box-shadow: var(--sh-4) !important;
}
html.dark #modal-container > div > div { border: 1px solid rgb(255 255 255 / .09); }

/* --- Chip profil sidebar ------------------------------------------------- */
.profile-chip {
    border-radius: var(--rad-sm) !important;
    transition: background calc(.22s * var(--mo)) var(--ease-out),
                border-color calc(.22s * var(--mo)) var(--ease-out),
                transform calc(.22s * var(--mo)) var(--ease-out);
}
.profile-chip:hover { transform: translateY(calc(-1px * var(--mo))); border-color: rgb(var(--brs-400) / .4) !important; }

/* --- Scrollbar mengikuti tema ------------------------------------------- */
::-webkit-scrollbar-thumb { background: rgb(var(--c-primary-500) / .32) !important; }
::-webkit-scrollbar-thumb:hover { background: rgb(var(--c-primary-500) / .5) !important; }

/* --- Pilihan teks -------------------------------------------------------- */
::selection { background: rgb(var(--c-primary-400) / .3); }

/* --- Fokus papan tik yang selalu terlihat ------------------------------- */
:focus-visible {
    outline: 2px solid rgb(var(--c-primary-500)) !important;
    outline-offset: 2px !important;
    border-radius: 4px;
}
