/* =====================================================================
   SISTEM GERAK — motion.css
   Dipakai bersama oleh web publik, dashboard admin, dan portal guru/murid.
   Hanya MENAMBAH gerak di atas desain yang ada (tidak mengganti warna, tata letak, logo, hero, atau efek lama).

   Aturan pakai:
   - Hanya transform/opacity (properti terpisah: translate, scale, rotate) supaya ringan di HP dan tidak
     bertabrakan dengan `transform` milik efek lama.
   - Gerak pegas memakai kurva linear() (cadangan: cubic-bezier overshoot untuk browser lama).
   - Perangkat yang meminta gerak dikurangi (prefers-reduced-motion) mendapat versi tanpa gerak. Untuk memaksa
     gerak tetap tampil di semua perangkat, beri <html data-motion="penuh">.
   - Logika JavaScript-nya ada di /assets/js/motion.js.
   ===================================================================== */

:root {
  --m-pegas: cubic-bezier(.34, 1.56, .64, 1);
  --m-pegas-lembut: cubic-bezier(.22, 1.25, .36, 1);
  --m-pegas-lentur: cubic-bezier(.3, 1.8, .5, 1);
  --m-keluar: cubic-bezier(.22, 1, .36, 1);
  --m-masuk: cubic-bezier(.4, 0, .2, 1);
  --m-ok: #1f6b4a;
  --m-galat: #a63232;
  --m-ico-ok: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E");
  --m-ico-galat: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 6v7M12 18v.01'/%3E%3C/svg%3E");
  --m-ico-kosong: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 28l6-16h24l6 16'/%3E%3Cpath d='M6 28v8a2 2 0 0 0 2 2h32a2 2 0 0 0 2-2v-8H30a6 6 0 0 1-12 0z'/%3E%3C/svg%3E");
}
@supports (animation-timing-function: linear(0, 1)) {
  :root {
    --m-pegas: linear(0, 0.0332, 0.1175, 0.2331, 0.3636, 0.4966, 0.6231, 0.7369, 0.8345, 0.9145, 0.9769, 1.0229, 1.0542, 1.0731, 1.082, 1.0832, 1.0788, 1.0708, 1.0606, 1.0495, 1.0385, 1.0282, 1.0192, 1.0115, 1.0053, 1.0005, 0.9971, 0.9949, 0.9936, 0.9931, 0.9931, 0.9936, 0.9944, 0.9952, 0.9962, 0.9971, 0.9979, 0.9986, 1);
    --m-pegas-lembut: linear(0, 0.0265, 0.093, 0.1836, 0.286, 0.3914, 0.4936, 0.5885, 0.6737, 0.748, 0.8113, 0.8638, 0.9064, 0.9401, 0.9661, 0.9855, 0.9994, 1.009, 1.015, 1.0184, 1.0198, 1.0198, 1.0187, 1.0171, 1.0152, 1.0131, 1.011, 1.009, 1.0072, 1.0057, 1.0043, 1.0032, 1.0022, 1.0015, 1);
    --m-pegas-lentur: linear(0, 0.0387, 0.1387, 0.2769, 0.4334, 0.592, 0.7405, 0.8705, 0.977, 1.0581, 1.1144, 1.1479, 1.162, 1.1605, 1.1476, 1.127, 1.1023, 1.0763, 1.0512, 1.0288, 1.0099, 0.9951, 0.9844, 0.9776, 0.9741, 0.9735, 0.975, 0.9779, 0.9817, 0.986, 0.9901, 0.994, 0.9973, 1, 1.002, 1.0033, 1.0041, 1.0043, 1.0042, 1.0038, 1.0032, 1.0026, 1.0019, 1.0012, 1);
  }
}

/* ---------- Keyframes dasar (dipakai berulang) ---------- */
@keyframes m-naik { from { opacity: 0; translate: 0 14px; scale: .985; } to { opacity: 1; translate: none; scale: none; } }
@keyframes m-turun { from { opacity: 0; translate: 0 -8px; } to { opacity: 1; translate: none; } }
@keyframes m-geser-masuk { from { opacity: 0; translate: -8px 0; } to { opacity: 1; translate: none; } }
@keyframes m-muncul { from { opacity: 0; } to { opacity: 1; } }
@keyframes m-pop { 0% { opacity: 0; scale: .3; } 100% { opacity: 1; scale: none; } }
@keyframes m-pop-2 { 0% { opacity: 0; scale: .3; } 100% { opacity: 1; scale: none; } }
@keyframes m-pop-s { 0% { scale: .78; } 100% { scale: none; } }
@keyframes m-pop-m { 0% { scale: .9; } 100% { scale: none; } }
@keyframes m-putar { to { rotate: 360deg; } }
@keyframes m-gambar { to { stroke-dashoffset: 0; } }
@keyframes m-getar {
  0%, 100% { translate: 0 0; }
  18% { translate: -7px 0; }
  36% { translate: 6px 0; }
  54% { translate: -4px 0; }
  72% { translate: 3px 0; }
  88% { translate: -1px 0; }
}
@keyframes m-melayang { 0%, 100% { translate: 0 0; } 50% { translate: 0 -4px; } }
@keyframes m-item-masuk { from { opacity: 0; translate: 0 10px; scale: .97; } to { opacity: 1; translate: none; scale: none; } }

/* =====================================================================
   1. TOMBOL — status kirim: pesawat kertas → memuat → centang / silang
   Elemen .m-fx dipasang oleh motion.js hanya saat sebuah permintaan ke server benar-benar berjalan.
   ===================================================================== */
.m-st { pointer-events: none !important; color: transparent !important; text-shadow: none !important; }
.m-st:disabled { opacity: 1 !important; cursor: progress; }
.m-st > :not(.m-fx) { visibility: hidden; }
.m-fx {
  position: absolute; inset: 0; display: grid; place-items: center; visibility: visible;
  color: var(--m-fg, currentColor); pointer-events: none; overflow: visible; line-height: 1;
}
.m-fx > svg {
  grid-area: 1 / 1; width: 1.4em; height: 1.4em; overflow: visible; fill: none; stroke: currentColor;
  stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round;
}
.m-fx .m-lacak { opacity: .22; }
.m-fx .m-garis { stroke-dasharray: 1; stroke-dashoffset: 1; animation: m-gambar .42s var(--m-keluar) .08s forwards; }

/* pesawat kertas: ditarik sedikit ke belakang, lalu melesat ke kanan atas */
.m-fx[data-k="pesawat"] > svg { animation: m-terbang .7s var(--m-keluar) forwards; }
@keyframes m-terbang {
  0% { translate: 0 0; rotate: 0deg; scale: 1; opacity: 1; }
  24% { translate: -3px 3px; rotate: -12deg; scale: .88; opacity: 1; }
  100% { translate: 2.5em -2em; rotate: 18deg; scale: .45; opacity: 0; }
}
.m-fx[data-k="pesawat"]::before {
  content: ""; grid-area: 1 / 1; width: 1.6em; height: 2px; border-radius: 2px; background: currentColor;
  opacity: 0; transform-origin: 100% 50%; rotate: -16deg; animation: m-jejak .62s var(--m-keluar) .1s backwards;
}
@keyframes m-jejak {
  0% { opacity: 0; scale: 0 1; translate: 0 0; }
  32% { opacity: .5; scale: 1 1; translate: -.15em .1em; }
  100% { opacity: 0; scale: .2 1; translate: 1.4em -1.1em; }
}

/* memuat */
.m-fx[data-k="muat"] > svg { animation: m-pop .28s var(--m-pegas) backwards, m-putar .8s linear infinite; }

/* berhasil */
.m-fx[data-k="ok"] > svg { animation: m-pop .55s var(--m-pegas-lentur) backwards; }
.m-fx[data-k="ok"] .m-garis { animation-duration: .4s; animation-delay: .12s; }
.m-fx[data-k="galat"] > svg { animation: m-pop .4s var(--m-pegas-lentur) backwards; }
.m-cincin {
  position: absolute; left: 50%; top: 50%; width: 2.3em; height: 2.3em; margin: -1.15em 0 0 -1.15em;
  border-radius: 50%; border: 2px solid var(--m-cincin, currentColor); opacity: 0; pointer-events: none;
  animation: m-cincin .75s var(--m-keluar) forwards;
}
@keyframes m-cincin { 0% { opacity: .75; scale: .35; } 100% { opacity: 0; scale: 1.9; } }

/* riak sentuhan (dibuat motion.js di atas tombol, tanpa menyentuh isi tombol) */
.m-riak { position: fixed; z-index: 2147483000; pointer-events: none; overflow: hidden; contain: strict; }
.m-riak > i { position: absolute; border-radius: 50%; background: currentColor; opacity: .2; will-change: transform, opacity; }

/* bilah progres tipis di atas layar saat permintaan ke server agak lama */
.m-bar {
  position: fixed; left: 0; top: 0; right: 0; height: 3px; z-index: 2147483000; pointer-events: none;
  transform-origin: 0 50%; opacity: 0; background: var(--emas, #8cc4ec);
  box-shadow: 0 0 10px color-mix(in srgb, var(--emas, #8cc4ec) 70%, transparent);
}

/* =====================================================================
   2. ISIAN FORM — fokus, salah, pesan galat, centang, sakelar
   ===================================================================== */
:is(.input, .select, .textarea, .field input, .field select, .field textarea, .fl input, .fl select, .fl textarea, .df-form input, .df-form select, .df-form textarea):not([type="checkbox"]):not([type="radio"]):focus {
  animation: m-fokus .42s var(--m-keluar);
}
@keyframes m-fokus { 0% { scale: .99; } 55% { scale: 1.006; } 100% { scale: none; } }
:is(input, select, textarea, .fl, .field):is(.is-invalid, [aria-invalid="true"]) { animation: m-getar .44s var(--m-keluar); }
:is(.df-error, .fl-err, .sheet-pesan, .login-dlg-err, .profil-pesan, .field-galat, .df-help-top):not([hidden]):not(:empty) {
  animation: m-turun .4s var(--m-pegas-lembut) backwards;
}
input[type="checkbox"]:checked, input[type="radio"]:checked { animation: m-pop-s .42s var(--m-pegas-lentur); }
.df-check input:checked + .df-box { animation: m-pop-s .45s var(--m-pegas-lentur); }
.df-check input:checked + .df-box::after, .df-opt input:checked + .df-card .df-radio::after { transition-timing-function: var(--m-pegas-lentur); }
.df-opt input:checked + .df-card { animation: m-pop-m .45s var(--m-pegas-lembut); }
.switch .slider::after { transition: transform .4s var(--m-pegas), scale .26s var(--m-pegas), background-color .2s; }
.switch:active .slider::after { scale: 1.22 1; }
.switch input:checked + .slider { animation: m-pop-m .4s var(--m-pegas-lembut); }

/* =====================================================================
   3. TAB, MENU, LENCANA
   ===================================================================== */
.tab[aria-current="page"] :is(svg, .tab-ikon) { animation: m-tab .6s var(--m-pegas-lentur); }
@keyframes m-tab { 0% { scale: .7; } 100% { scale: none; } }
:is(.seg, .chip)[aria-selected="true"], .seg[aria-checked="true"], .chip[aria-pressed="true"] { animation: m-pop-m .45s var(--m-pegas-lentur); }
.side nav a[aria-current="page"], .nav-pc .nav-btn[aria-current="page"] { animation: m-geser-masuk .45s var(--m-pegas-lembut); }
:is(.lencana, .lencana-info, [data-badge]):not([hidden]) { animation: m-pop .5s var(--m-pegas-lentur) backwards; }
.nav-caret { transition-timing-function: var(--m-pegas); }
.menu-toggle span { transition-timing-function: var(--m-pegas-lembut); }

/* menu dropdown PC: item masuk berurutan; menu HP: tautan masuk berurutan */
.nav-grup:hover .nav-sub a, .nav-grup:focus-within .nav-sub a { animation: m-item-masuk .42s var(--m-pegas-lembut) backwards; animation-delay: calc(var(--m-n, 0) * 32ms + 40ms); }
.nav-sheet.open .link, .nav-sheet.open .nav-sheet-foot { animation: m-item-masuk .5s var(--m-pegas-lembut) backwards; animation-delay: calc(var(--m-n, 0) * 26ms + 90ms); }

/* akordeon */
details[open] > :not(summary) { animation: m-turun .45s var(--m-keluar) backwards; }
details > summary { transition: opacity .2s; }

/* =====================================================================
   4. DIALOG / LEMBAR — masuk dan KELUAR dengan pegas (dialog bawaan browser)
   ===================================================================== */
@supports (transition-behavior: allow-discrete) {
  dialog.sheet, dialog.artikel, dialog.lightbox, .login-dlg {
    opacity: 0; translate: 0 26px; scale: .965;
    transition: opacity .22s var(--m-masuk), translate .45s var(--m-pegas-lembut), scale .45s var(--m-pegas-lembut), display .45s allow-discrete, overlay .45s allow-discrete;
  }
  dialog.sheet[open], dialog.artikel[open], dialog.lightbox[open], .login-dlg[open] { opacity: 1; translate: none; scale: none; animation: none; }
  @starting-style {
    dialog.sheet[open], dialog.artikel[open], dialog.lightbox[open], .login-dlg[open] { opacity: 0; translate: 0 26px; scale: .965; }
  }
  dialog.sheet::backdrop, dialog.artikel::backdrop, dialog.lightbox::backdrop, .login-dlg::backdrop {
    opacity: 0; transition: opacity .3s var(--m-masuk), display .3s allow-discrete, overlay .3s allow-discrete;
  }
  dialog.sheet[open]::backdrop, dialog.artikel[open]::backdrop, dialog.lightbox[open]::backdrop, .login-dlg[open]::backdrop { opacity: 1; animation: none; }
  @starting-style {
    dialog.sheet[open]::backdrop, dialog.artikel[open]::backdrop, dialog.lightbox[open]::backdrop, .login-dlg[open]::backdrop { opacity: 0; }
  }
}

/* =====================================================================
   5. TOAST — ikon berhasil / gagal ikut muncul dengan pegas
   ===================================================================== */
.toast { transition: opacity .25s var(--m-masuk), transform .55s var(--m-pegas); }
.toast::before {
  content: ""; display: inline-block; width: 1.15em; height: 1.15em; margin-right: .55em; vertical-align: -.2em;
  background: currentColor; -webkit-mask: var(--m-ico-ok) center / contain no-repeat; mask: var(--m-ico-ok) center / contain no-repeat;
  animation: m-pop .55s var(--m-pegas-lentur) .12s backwards;
}
.toast.show::before { animation-name: m-pop-2; }
.toast:is(.error, .err, .m-galat)::before { -webkit-mask-image: var(--m-ico-galat); mask-image: var(--m-ico-galat); }

/* =====================================================================
   6. KEADAAN KOSONG, MEMUAT, BERHASIL
   ===================================================================== */
.kosong { animation: m-naik .55s var(--m-keluar) backwards; }
.kosong:not(:has(.lencana, .centang))::before {
  content: ""; display: block; width: 40px; height: 40px; margin: 0 auto 12px; opacity: .38; background: currentColor;
  -webkit-mask: var(--m-ico-kosong) center / contain no-repeat; mask: var(--m-ico-kosong) center / contain no-repeat;
  animation: m-pop .6s var(--m-pegas-lentur) .1s backwards, m-melayang 3.6s ease-in-out .8s infinite;
}
.kosong > :is(strong, h3) { animation: m-turun .5s var(--m-keluar) .12s backwards; }
.kosong-info, .loading-box { animation: m-naik .5s var(--m-keluar) backwards; }
.m-memuat::before {
  content: ""; display: inline-block; width: .95em; height: .95em; margin-right: .55em; vertical-align: -.12em; border-radius: 50%;
  border: 2px solid currentColor; border-right-color: transparent; opacity: .7; animation: m-putar .8s linear infinite;
}

/* tampilan baru (halaman SPA admin/portal, kartu, baris): masuk berurutan — kelas dipasang motion.js */
.m-masuk { animation: m-naik .55s var(--m-keluar) backwards; animation-delay: calc(var(--m-i, 0) * 38ms); }
.m-masuk-halus { animation: m-muncul .3s var(--m-masuk) backwards; }

/* =====================================================================
   7. TRANSISI HALAMAN (web publik, banyak halaman)
   - Browser yang mendukung View Transitions lintas dokumen: elemen kartu yang diketuk membesar menjadi
     bagian atas halaman berikutnya (shared element), sisanya memudar halus.
   - Browser lain: tirai yang tumbuh dari elemen yang diketuk (lihat .m-tirai), lalu halaman baru muncul.
   ===================================================================== */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: m-vt-keluar .26s var(--m-masuk) both; }
::view-transition-new(root) { animation: m-vt-masuk .46s var(--m-keluar) both; }
@keyframes m-vt-keluar { to { opacity: 0; } }
@keyframes m-vt-masuk { from { opacity: 0; } }
.page-hero { view-transition-name: m-hero; }
::view-transition-group(m-hero) { animation-duration: .6s; animation-timing-function: var(--m-pegas-lembut); }
::view-transition-old(m-hero), ::view-transition-new(m-hero) { animation-duration: .45s; animation-timing-function: var(--m-keluar); height: 100%; object-fit: cover; }
html:not(.m-lewat-vt) body { animation: m-muncul .32s var(--m-masuk) backwards; }
.m-tirai { position: fixed; inset: 0; z-index: 2147483000; pointer-events: none; background: var(--m-tirai, #fff); will-change: clip-path, opacity; }

/* =====================================================================
   8. KURANGI GERAK — hormati prefers-reduced-motion
   Sakelar: <html data-motion="penuh"> memaksa gerak tetap tampil.
   ===================================================================== */
@media (prefers-reduced-motion: reduce) {
  :root:not([data-motion="penuh"]) { --m-pegas: linear; --m-pegas-lembut: linear; --m-pegas-lentur: linear; }
  :root:not([data-motion="penuh"]) :is(.m-masuk, .m-masuk-halus, .kosong, .kosong > *, .kosong::before, .toast::before, .m-fx, .m-fx > svg, .m-fx::before, .m-cincin, .m-riak, .m-bar, .m-tirai, details > *, .nav-sub a, .nav-sheet .link) {
    animation: none !important; transition: none !important;
  }
  :root:not([data-motion="penuh"]) :is(input, select, textarea, .seg, .chip, .tab svg, .tab-ikon, .switch, .lencana, .df-box, .df-card) { animation: none !important; }
  :root:not([data-motion="penuh"]) .m-fx .m-garis { stroke-dashoffset: 0; }
  :root:not([data-motion="penuh"]) dialog, :root:not([data-motion="penuh"]) dialog::backdrop { transition: none !important; }
  @view-transition { navigation: none; }
  :root:not([data-motion="penuh"]) body { animation: none !important; }
}
