/* ================================================================
   MFB-IT — Miss Fish Bali LMS
   File        : mfb-ui.css
   Description : Lapisan perbaikan tampilan di atas baseline v2.144.
                 Baseline TIDAK disunting sama sekali.
   CSS
   IT Department · Miss Fish Bali
   Version     : 1.141
   Rilis LMS   : v2.271
   Generated   : 9 October 2026, 08:06:07
   ================================================================

   Dimuat SESUDAH seluruh <style> v2.144, jadi aturan di sini menang
   tanpa perlu !important — kecuali untuk menimpa aturan baseline
   yang memang sudah memakai !important (bagian dark mode).

   Membatalkan seluruh perubahan tampilan: hapus baris pemuat
   mfb-ui.css di index.html. Baseline kembali apa adanya.
   ================================================================ */

/* ================================================================
   0. PERMUKAAN "CHROME" — SATU BIDANG, BUKAN DUA KOTAK HITAM
   ================================================================
   Permintaan IT Manager: "kok kayak ga nyatu sidebar dan navbar ya?
   kasi rekomendasi terbaik kakak gimana bagusnya warnanya."

   🔴 KENAPA TERASA TIDAK MENYATU — tiga sebab, bukan satu:

   1. DUA HITAM YANG SAMA-SAMA RATA.
      Sidebar #0A0A0A, topbar #0A0A0A. Warnanya memang sama, tapi
      dua bidang rata tanpa gradasi tidak punya alasan visual untuk
      terbaca sebagai satu benda. Mata membaca dua kotak.

   2. TIDAK ADA SUMBER CAHAYA BERSAMA.
      Sidebar punya cahaya emas di BAWAH (.sidebar-bg), topbar tidak
      punya sama sekali. Dua benda yang disinari dari arah berbeda
      selalu terbaca sebagai dua benda terpisah.

   3. GARIS TEPINYA BEDA-BEDA.
      Topbar 0.22, garis sidebar 0.85. Dua garis dengan ketebalan
      warna berbeda saling bersaing di sudut pertemuannya, dan itu
      justru MENEKANKAN belahannya.

   🔴 SOLUSINYA — inilah yang dipakai Spin Roulette, dan alasan
   halamannya terasa "satu benda": sidebar dan topbar di sana
   memakai GRADIEN YANG SAMA PERSIS (baris 241 dan 313).

   Tiga aturan yang diterapkan di bawah:

     a. SATU gradien dipakai dua-duanya, DIPATOK KE ATAS LAYAR
        (background-size 100% 100vh). Karena sidebar dan topbar
        sama-sama mulai di y=0, keduanya memotong gradien yang sama
        di tempat yang sama — warnanya nyambung persis di sudut.

     b. SATU sumber cahaya: cahaya emas datang dari ATAS, melintasi
        keduanya. Bukan dua cahaya, satu.

     c. SATU garis rambut dengan warna & tebal yang SAMA, mengelilingi
        permukaan itu seperti bingkai — bukan dua garis yang membelah.

   🔴 KENAPA TETAP HITAM, BUKAN NAVY SEPERTI SPIN ROULETTE:
   navy adalah identitas Staff Gathering. Hitam-emas adalah identitas
   LMS, dan v2.144 memakainya di seluruh halaman. Menggantinya =
   merombak, dan IT Manager sudah bilang jangan dirombak.

   Yang diubah bukan warnanya, tapi KUALITASNYA: dari hitam datar
   #0A0A0A jadi hitam HANGAT bergradasi (#17130D -> #0A0908).
   Hitam murni terbaca murah dan keras karena tidak ada benda nyata
   yang berwarna hitam sempurna; hitam yang sedikit hangat dan
   bergradasi terbaca seperti kulit, kayu gelap, atau beludru —
   dan itulah yang membuat sesuatu terasa mahal.
   ---------------------------------------------------------------- */

:root {
  --mfb-chrome-atas  : #17130D;   /* hitam hangat, tersinari */
  --mfb-chrome-bawah : #0A0908;   /* hitam hangat, di bayangan */
  --mfb-hair         : rgba(201, 168, 76, 0.30);
  --mfb-emas         : #E8C96A;
}

#desk .sidebar,
#desk .topbar {
  /* Gradien dipatok setinggi layar dan diletakkan di atas, jadi
     kedua elemen memotong gradien yang SAMA di titik yang sama. */
  background-color: var(--mfb-chrome-bawah);
  background-image: linear-gradient(180deg,
    var(--mfb-chrome-atas) 0%,
    var(--mfb-chrome-bawah) 100%);
  background-size: 100% 100vh;
  background-position: top left;
  background-repeat: no-repeat;
}

#desk .topbar {
  position: relative;
  /* Cahaya emas bersama — datang dari atas, melintasi keduanya. */
  box-shadow: inset 0 1px 0 rgba(255, 244, 214, 0.05);
  border-bottom: 1px solid var(--mfb-hair);
}

/* Cahaya emas di kepala topbar. Lembut dan lebar — kalau terlalu
   pekat ia berubah jadi noda kuning, bukan cahaya. */
#desk .topbar::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(120% 180% at 50% 0%,
    rgba(201, 168, 76, 0.11), transparent 64%);
}
/* Isi topbar dinaikkan di atas cahaya itu. Tanpa ini, lapisan
   cahaya menutupi judul dan tombolnya — pseudo-element yang
   position:absolute selalu menang atas anak yang tidak diposisikan. */
#desk .topbar > .topbar-left,
#desk .topbar > .topbar-right {
  position: relative;
  z-index: 1;
}

/* SATU sumber cahaya, bukan dua. Sidebar bawaan menyalakan cahaya
   emas dari BAWAH (.sidebar-bg, baseline baris 1006-1010) — arah
   yang berlawanan dengan cahaya topbar di atas. Dua arah cahaya
   pada satu bidang adalah alasan paling halus kenapa sesuatu
   terlihat "tempelan". Cahaya bawah dilembutkan, bukan dimatikan:
   masih memberi kedalaman di kaki sidebar, tapi tidak lagi
   mengaku-ngaku sebagai sumber cahaya kedua. */
#desk .sidebar-bg {
  background: radial-gradient(ellipse 90% 38% at 50% 100%,
    rgba(201, 168, 76, 0.045) 0%, transparent 72%);
}

/* ----------------------------------------------------------------
   1. JUDUL BESAR DI TENGAH TOPBAR
   Permintaan IT Manager: "tulisan Learning Management System buat
   seperti navbar spin roulette, di tengah-tengah gitu besar".
   ---------------------------------------------------------------- */

/* Teks bawaan topbar dibalik warnanya agar terbaca di atas hitam. */
#desk .topbar .topbar-breadcrumb { color: rgba(255, 255, 255, 0.52); }
#desk .topbar .topbar-title      { color: #FFFFFF; }

#desk .topbar .topbar-icon-btn {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.12);
  color: rgba(255, 255, 255, 0.85);
}
#desk .topbar .topbar-icon-btn:hover { background: rgba(255, 255, 255, 0.12); }

/* Tombol gelap/terang (.dm-toggle, baseline baris 1739) tertinggal
   dengan latar abu terang bawaan — lingkaran putih di topbar hitam,
   tidak serumpun dengan tombol ikon di sebelahnya (foto IT Manager,
   23 Sep 2026). Disamakan bentuk dan warnanya dengan .topbar-icon-btn. */
#desk .topbar .dm-toggle {
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.12);
  transition: background 0.18s;
}
#desk .topbar .dm-toggle:hover { background: rgba(255, 255, 255, 0.12); }
#desk .topbar .dm-toggle:focus-visible {
  outline: 2px solid var(--mfb-emas);
  outline-offset: 2px;
}

/* Judul tengah — disisipkan mfb-ui.js.
   Diposisikan absolut supaya benar-benar di tengah topbar, bukan
   di tengah sisa ruang antara kiri dan kanan. */
#desk .topbar .mfb-topbar-brand {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);

  /* 🔴 FONT: CINZEL — huruf yang persis sama dengan "DOOR PRIZE
     SYSTEMS" di navbar Spin Roulette.

     Berkasnya akhirnya ketemu:
       Documents\App Script\Roulette 11-2026\Gathering-Nov2026\
       MFB-Roulette_v6_1.html

     Di sana (baris 124) hurufnya didaftarkan sebagai:
         --display: 'Cinzel', Georgia, 'Times New Roman', serif;
     dan judul tengah topbar (.tb-center .tc-sub, baris 335-349)
     memakai --display dengan letter-spacing .42em plus sepasang
     garis rambut emas di kiri-kanan.

     Nilai di bawah DISALIN PERSIS dari berkas itu, bukan ditebak.

     text-indent .42em bukan salah ketik: letter-spacing menambah
     jarak SESUDAH huruf terakhir juga, jadi tulisannya tergeser ke
     kiri. text-indent yang sama besar mengembalikannya ke tengah
     secara optis. Trik ini juga disalin dari berkas aslinya.

     Georgia tetap ditulis sebagai cadangan: kalau Google Fonts
     lambat atau diblokir, judulnya tetap tampil serif — tidak
     pernah jatuh ke huruf sistem yang salah. */
  font-family: 'Cinzel', Georgia, 'Times New Roman', serif;
  font-size: clamp(13px, 1.35vw, 19px);
  font-weight: 700;
  letter-spacing: 0.42em;
  text-indent: 0.42em;
  line-height: 1;
  text-transform: uppercase;
  color: #E8C96A;
  white-space: nowrap;
  pointer-events: none;
  /* Garis tipis kiri-kanan, disalin dari .tb-center .tc-sub. */
  display: flex;
  align-items: center;
  gap: 18px;
}
#desk .topbar .mfb-topbar-brand::before,
#desk .topbar .mfb-topbar-brand::after {
  content: '';
  width: clamp(18px, 4vw, 62px);
  height: 1px;
  flex: 0 0 auto;
  background: linear-gradient(90deg, transparent, rgba(201, 168, 76, 0.75));
}
#desk .topbar .mfb-topbar-brand::after {
  background: linear-gradient(90deg, rgba(201, 168, 76, 0.75), transparent);
}

/* Di layar sempit judul tengah bisa bertabrakan dengan judul kiri —
   disembunyikan, bukan dibiarkan saling menimpa. */
@media (max-width: 1100px) {
  #desk .topbar .mfb-topbar-brand { display: none; }
}
/* 23 Sep 2026 — di layar lebar pun judul modul yang panjang bisa
   menabrak. mfb-ui.js (cegahTabrakanJudul) mengukurnya dan memasang
   kelas ini; visibility, bukan display, supaya ukurannya tetap ada. */
#desk .topbar .mfb-topbar-brand.mfb-mengalah { visibility: hidden; }

/* 23 Sep 2026 — modul terkunci di daftar "Course Modules" samping
   pemutar (mfb-ui.js pasangKunciModul). Sama dengan .module-item.locked
   di halaman Course Detail: redup, kursor dilarang, tanpa sorotan. */
.video-info-card .mfb-modul-kunci {
  opacity: .5;
  cursor: not-allowed !important;
  border-color: var(--gray-100) !important;
}

/* ----------------------------------------------------------------
   1b. GARIS PEMISAH SIDEBAR ↔ TOPBAR
   Permintaan IT Manager: "tambahin garis pemisah antara sidebar dan
   navbar, misal yang Spin".

   Sesudah topbar dijadikan hitam (#0A0A0A) dan sidebar juga gelap,
   keduanya menyatu jadi satu blok hitam — batasnya hilang.

   Disalin dari #sb::after di MFB-Roulette_v6_1.html baris 247-251:
   garis rambut emas setinggi sidebar yang MEMUDAR di ujung atas dan
   bawah. Memudar, bukan garis penuh — garis penuh terlihat seperti
   border kaku; yang memudar terbaca sebagai batas yang disengaja.

   Catatan: #desk .sidebar (baseline baris 1001-1005) memakai
   overflow:hidden, jadi garisnya dipasang di right:0, BUKAN
   right:-1px seperti aslinya — kalau di luar kotak ia terpotong
   dan tidak akan kelihatan sama sekali.
   ---------------------------------------------------------------- */

/* 🔴 DIPIKIR ULANG DI v1.4 — dan arahnya saya BALIK.
   IT Manager minta dua hal yang kelihatannya bertabrakan:
   "garisnya ga keliatan" DAN "kok kayak ga nyatu".

   Ternyata tidak bertabrakan — keduanya gejala dari akar yang sama.
   Percobaan pertama saya salah obat: garisnya saya buat makin
   TEBAL dan makin TERANG (0.85). Itu justru memperparah, karena
   garis tebal di antara dua bidang = pengumuman "ini DUA benda".

   Obat yang benar: samakan permukaannya (bagian 0 di atas), lalu
   pakai SATU garis rambut dengan warna dan tebal yang PERSIS SAMA
   dengan garis bawah topbar (--mfb-hair). Hasilnya kedua garis itu
   bertemu di sudut dan terbaca sebagai SATU bingkai yang
   mengelilingi permukaan chrome — bukan dua garis yang membelahnya.

   Garisnya tetap terlihat (IT Manager benar soal itu), tapi sekarang
   ia MEMBINGKAI, bukan MEMOTONG.

   box-shadow dipakai, BUKAN border-right: border menambah lebar
   elemen dan menggeser seluruh isi halaman 1px. box-shadow tidak
   memakan ruang sama sekali. Bayangan lebarnya membuat sidebar
   terasa sedikit terangkat di atas isi halaman — kedalaman yang
   halus, bukan garis tambahan. */
#desk .sidebar {
  box-shadow:
    1px 0 0 var(--mfb-hair),
    14px 0 36px rgba(0, 0, 0, 0.30);
}

#desk .sidebar::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 1px;
  z-index: 2;
  pointer-events: none;
  /* Sedikit lebih pekat di area topbar saja — di situ hitam ketemu
     hitam, jadi butuh bantuan. Di bawahnya hitam ketemu terang dan
     kontrasnya sudah lebih dari cukup, jadi garisnya memudar supaya
     tidak berteriak. */
  background: linear-gradient(180deg,
    rgba(201, 168, 76, 0.42) 0%,
    rgba(201, 168, 76, 0.42) 7%,
    rgba(201, 168, 76, 0.18) 34%,
    transparent 100%);
}

/* ----------------------------------------------------------------
   1c. LABEL VERSI DI KAKI SIDEBAR — NAIK KE v2.145
   Permintaan IT Manager: "ini perubahan hero harusnya naik jadi 145 kak,
   waktu di browser saya sebelumnya. SELALU NAIK VERSI." (9 Sep 2026)

   🔴 KOREKSI. Saya sempat menolak dengan alasan "v2.144 baseline yang
   TETAP, menaikkannya berarti berbohong soal isi berkas". Alasan itu
   SALAH SASARAN — saya menggabungkan dua hal yang CLAUDE.md §3.2
   justru menyuruh dipisah:

     Dimensi A — versi RILIS LMS / UI  -> yang dilihat pengguna
     Dimensi B — versi KOMPONEN/BERKAS -> mfb-ui.css, Auth_v1.7.gs, dst

   v2.144 yang TIDAK boleh berubah adalah dimensi B: nama berkas
   MissFishLMS_v2.144.html, artefak rilis GAS, sumber jaminan
   identik byte-per-byte. Berkas itu memang tidak disentuh sama
   sekali — dan tetap tidak akan.

   Tapi yang dibaca IT Manager di kaki sidebar adalah dimensi A: versi
   RILIS aplikasi yang sedang jalan. Aplikasi itu = baseline +
   lapisan ini, dan isinya memang sudah berubah. Jadi angkanya
   memang HARUS naik. IT Manager benar.

       v2.144  = berkas baseline GAS   (tidak pernah berubah)
       v2.145  = rilis LMS yang jalan  (naik tiap ada perubahan)

   Penanda "· CF" dipakai supaya rilis ini tidak tertukar dengan
   rilis GAS v2.145 nanti — GAS terus maju sendiri selama migrasi,
   dan dua hal berbeda bernama sama adalah bibit kebingungan.
   Kalau IT Manager lebih suka polos, hapus saja " · CF".

   ATURAN SETERUSNYA: setiap deploy yang mengubah apa yang dilihat
   IT Manager -> angka minor naik satu (2.145 -> 2.146 -> ...).
   ---------------------------------------------------------------- */

#desk .sidebar-footer::after {
  content: 'LMS v2.271 · CF';
}

/* ----------------------------------------------------------------
   2. TOMBOL LIPAT KARTU AI
   Permintaan IT Manager: "tombol collapsenya AI Intelligence jelek
   banget, ganti pake yang bagusan".
   ---------------------------------------------------------------- */

/* 🔴 v1.4 — DIBUAT TIMBUL (3D). Permintaan IT Manager:
   "tombol panah collapse bisa dibuat lebih 3D misalnya?"

   Empat lapis yang membuat sebuah tombol terasa timbul — semuanya
   meniru cara cahaya jatuh di benda nyata:

     1. gradien terang-ke-gelap   -> cahaya datang dari ATAS
     2. garis putih tipis di atas -> pantulan di tepi atas (inset)
     3. bayangan gelap di bawah   -> tombol mengambang di atas kartu
     4. bayangan dalam di bawah   -> ketebalan badan tombolnya

   Saat DITEKAN semuanya dibalik: gradien gelap-ke-terang, bayangan
   luar hilang, bayangan dalam masuk. Jadi tombolnya benar-benar
   terasa masuk ke dalam, bukan cuma berubah warna. */
.ai-card .mfb-ai-btn {
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid rgba(201, 168, 76, 0.42);
  background: linear-gradient(180deg,
    rgba(201, 168, 76, 0.30) 0%,
    rgba(201, 168, 76, 0.13) 48%,
    rgba(120, 92, 34, 0.16) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 244, 214, 0.42),
    inset 0 -2px 4px rgba(0, 0, 0, 0.34),
    0 2px 5px rgba(0, 0, 0, 0.45),
    0 0 0 1px rgba(0, 0, 0, 0.18);
  color: #E8C96A;
  cursor: pointer;
  padding: 0;
  line-height: 0;
  transition: background .18s ease, border-color .18s ease,
              transform .12s ease, box-shadow .12s ease;
}
.ai-card .mfb-ai-btn:hover {
  border-color: rgba(201, 168, 76, 0.72);
  background: linear-gradient(180deg,
    rgba(201, 168, 76, 0.42) 0%,
    rgba(201, 168, 76, 0.20) 48%,
    rgba(120, 92, 34, 0.20) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 244, 214, 0.55),
    inset 0 -2px 4px rgba(0, 0, 0, 0.34),
    0 3px 8px rgba(0, 0, 0, 0.5),
    0 0 12px rgba(201, 168, 76, 0.28);
}
/* Ditekan — tombolnya masuk ke dalam, bukan sekadar ganti warna. */
.ai-card .mfb-ai-btn:active {
  transform: translateY(1px);
  background: linear-gradient(180deg,
    rgba(90, 70, 26, 0.30) 0%,
    rgba(201, 168, 76, 0.18) 100%);
  box-shadow:
    inset 0 2px 5px rgba(0, 0, 0, 0.55),
    inset 0 -1px 0 rgba(255, 244, 214, 0.18),
    0 0 0 1px rgba(0, 0, 0, 0.2);
}
.ai-card .mfb-ai-btn:focus-visible {
  outline: 2px solid var(--gold, #C9A065);
  outline-offset: 2px;
}
/* Panah berputar saat kartunya terlipat — memberi tahu keadaannya,
   bukan sekadar hiasan. */
.ai-card.collapsed .mfb-ai-btn[data-mfb-tombol="lipat"],
.ai-card[data-collapsed="true"] .mfb-ai-btn[data-mfb-tombol="lipat"] {
  transform: rotate(-180deg);
}

/* ================================================================
   1f. IKON TIMBUL (3D)
   ================================================================
   Permintaan IT Manager: "icon2 dibuat 3D semua bisa kak?"

   Bisa — dan resepnya sama untuk semua ikon, karena semuanya meniru
   satu hal yang sama: bagaimana cahaya jatuh di benda nyata.

   EMPAT LAPIS. Dipakai berulang di bawah:

     1. gradien terang-ke-gelap   -> cahaya datang dari ATAS
     2. garis putih tipis di atas -> pantulan di tepi atas (inset)
     3. bayangan gelap di dalam   -> ketebalan badan bendanya (inset)
     4. bayangan lembut di bawah  -> benda mengambang di atas kartu

   🔴 KENAPA HALUS, BUKAN MENCOLOK
   Godaannya adalah membuat bayangan pekat dan gradien tajam supaya
   "3D-nya kelihatan". Itu justru membuatnya terlihat murah — seperti
   tombol web tahun 2008. Yang membuat sesuatu terasa mahal adalah
   3D yang nyaris tidak disadari: mata merasakan kedalamannya tanpa
   bisa menunjuk apa yang membuatnya.

   Karena itu semua nilai di bawah sengaja rendah. Kalau IT Manager mau
   lebih tegas, tinggal bilang — angkanya gampang dinaikkan.
   ---------------------------------------------------------------- */

/* --- a. Kartu angka di dashboard (ikon emoji berlatar warna) --- */
#desk .stat-card-icon,
#desk .stat-mini-icon,
.ai-card-icon {
  position: relative;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.85),
    inset 0 -2px 3px rgba(0, 0, 0, 0.10),
    0 2px 4px rgba(60, 44, 20, 0.13),
    0 6px 14px rgba(60, 44, 20, 0.07);
  /* Emoji-nya sendiri ikut diberi bayangan tipis, kalau tidak ia
     terlihat "menempel datar" di atas alas yang timbul. */
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.18);
}

/* Kilau lengkung di separuh atas — inilah yang paling membuat
   permukaannya terbaca sebagai cembung, bukan kotak berwarna. */
#desk .stat-card-icon::after,
#desk .stat-mini-icon::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(180deg,
    rgba(255, 255, 255, 0.55) 0%,
    rgba(255, 255, 255, 0.10) 46%,
    transparent 62%);
}

/* Kartunya ikut sedikit terangkat waktu disentuh — ikon timbul di
   atas kartu datar terasa janggal. */
#desk .stat-card {
  transition: box-shadow .2s ease, transform .2s ease;
}
#desk .stat-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 22px rgba(60, 44, 20, 0.10);
}

/* Ikon AI berada di atas kartu GELAP, jadi arah cahayanya dibalik:
   pantulan atasnya emas redup, bukan putih terang. Memakai putih
   terang di atas hitam akan terlihat seperti bercak, bukan cahaya. */
.ai-card-icon {
  background: linear-gradient(180deg,
    rgba(201, 168, 76, 0.34) 0%,
    rgba(201, 168, 76, 0.14) 52%,
    rgba(120, 92, 34, 0.18) 100%) !important;
  box-shadow:
    inset 0 1px 0 rgba(255, 244, 214, 0.40),
    inset 0 -2px 4px rgba(0, 0, 0, 0.40),
    0 2px 6px rgba(0, 0, 0, 0.45);
}

/* --- b. Ikon menu di sidebar (SVG garis, bukan emoji) ---
   SVG garis tidak punya permukaan yang bisa disinari, jadi triknya
   berbeda: dipakai drop-shadow supaya garisnya seolah melayang
   sedikit di atas sidebar. filter drop-shadow mengikuti BENTUK
   garisnya; box-shadow akan membayangi kotak pembungkusnya dan
   hasilnya terlihat salah. */
#desk .nav-item svg {
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.55));
  transition: filter .18s ease, transform .18s ease;
}
#desk .nav-item:hover svg {
  transform: translateY(-1px);
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.6));
}
/* Menu aktif: ikonnya menyala emas, seperti diterangi dari dalam. */
#desk .nav-item.active svg {
  filter:
    drop-shadow(0 1px 1px rgba(0, 0, 0, 0.6))
    drop-shadow(0 0 6px rgba(201, 168, 76, 0.5));
}

/* Menu aktif diberi permukaan timbul, bukan sekadar blok warna.
   ----------------------------------------------------------------
   🔴 DIPERKUAT — laporan IT Manager 12 September 2026: "selected pages
   yg kuning di sidebar dashboard doank, kalau pilih sidebar lain ga
   ada kuning2nya."

   Diperiksa dengan merender seluruh aplikasi dan berpindah ke enam
   halaman: kelas .active TERPASANG di semuanya, bahkan sesudah
   datanya selesai dimuat. Jadi ini bukan kelas yang hilang — ini
   sorotan yang TERLALU SAMAR UNTUK TERLIHAT.

   Emas 20% di atas hitam hangat cuma menaikkan terang sekitar 4%.
   Di layar terang, di luar ruangan, atau di monitor yang gamma-nya
   tidak dikalibrasi, selisih sekecil itu hilang sama sekali. Dan
   "di mana saya sekarang" adalah pertanyaan yang jawabannya tidak
   boleh bergantung pada kualitas layar.

   Sekarang sorotannya dibawa TIGA hal sekaligus, bukan satu:
     1. pita emas pekat di tepi kiri — bentuk, bukan warna
     2. latar yang jauh lebih tegas
     3. teks & ikon emas penuh

   Nomor 1 yang menentukan: pita itu tetap terbaca walau warnanya
   tidak terlihat sama sekali. */
#desk .nav-item.active {
  position: relative;
  background: linear-gradient(180deg,
    rgba(201, 168, 76, 0.34) 0%,
    rgba(201, 168, 76, 0.17) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 244, 214, 0.22),
    inset 0 -1px 0 rgba(0, 0, 0, 0.35),
    0 1px 3px rgba(0, 0, 0, 0.3);
  /* Teks emas penuh — baseline sudah menyetel var(--gold), tapi
     ditulis ulang di sini supaya tidak bergantung pada urutan
     aturan yang bisa berubah. */
  color: #E8C96A;
  font-weight: 650;
}

/* Pita tepi kiri — penanda yang tidak bergantung pada warna. */
#desk .nav-item.active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 62%;
  border-radius: 0 3px 3px 0;
  background: #E8C96A;
  box-shadow: 0 0 8px rgba(232, 201, 106, 0.55);
}

#desk .nav-item.active svg { color: #E8C96A; opacity: 1; }

/* --- c. Lingkaran inisial (avatar) --- */
#desk .sb-avatar,
#desk .topbar-avatar {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.55),
    inset 0 -2px 4px rgba(0, 0, 0, 0.28),
    0 2px 6px rgba(0, 0, 0, 0.42);
}

/* --- d. Bilah bawah di HP ---
   Emoji polos di layar kecil terlihat rata dan mati. Bayangan tipis
   sudah cukup memberi bentuk tanpa membuatnya berisik. */
#mob .bnav-item .bnav-icon,
#mob .bnav-item span:first-child {
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.28);
}

/* ================================================================
   1g. KARTU TIMBUL — SATU SISTEM KETINGGIAN UNTUK SEMUA KARTU
   ================================================================
   Permintaan IT Manager: "stat card, card2 lain, buat 3D jg donk kak,
   ada bayangan apa nya gitu, yg keren kak, supabase kan ringan."

   🔴 KENAPA INI BISA DIKERJAKAN DENGAN SATU ATURAN SAJA
   Waktu menelusuri baseline v2.144, ternyata SETIAP kartu di seluruh
   aplikasi memakai resep yang sama persis:

       background: var(--white);
       border-radius: 12-18px;
       border: 1px solid var(--gray-100);

   Ada 30-an kelas berbeda — .stat-card, .card, .course-card,
   .table-card, .profile-card, .settings-section, .att-event-card,
   .log-stat-card, dan seterusnya — tapi semuanya bidang putih rata
   berbingkai abu-abu yang sama. Kartu putih di atas latar abu-abu
   muda, tanpa bayangan sama sekali: tidak ada yang salah, tapi juga
   tidak ada yang terasa. Semuanya duduk di satu ketinggian.

   Konsistensi itu keberuntungan besar: satu daftar pemilih bisa
   mengangkat seluruh aplikasi sekaligus, dan hasilnya dijamin
   seragam — tidak mungkin ada kartu yang ketinggalan lalu terlihat
   janggal di sebelah kartu yang sudah diangkat.

   🔴 KENAPA "3D" DI SINI BUKAN BAYANGAN TEBAL
   Godaannya adalah memasang box-shadow besar dan gelap supaya
   "3D-nya kelihatan". Itu justru yang membuat sesuatu terlihat
   murah. Yang membuat kartu terasa mahal adalah TIGA hal yang
   bekerja bersama, dan tidak satu pun dari ketiganya mencolok:

     1. PERMUKAAN YANG TIDAK RATA. Gradien putih ke putih-sedikit-
        abu dari atas ke bawah. Bidang yang benar-benar rata tidak
        pernah ada di dunia nyata; mata langsung membacanya sebagai
        gambar, bukan benda.
     2. TEPI ATAS YANG TERSINARI. Garis putih tipis di dalam tepi
        atas — pantulan cahaya di sisi yang menghadap ke atas.
        Inilah yang paling membuat kartu terasa punya KETEBALAN.
     3. BAYANGAN DUA LAPIS. Satu rapat dan pekat (kontak dengan
        alas), satu lebar dan sangat samar (bayangan lingkungan).
        Bayangan tunggal selalu terlihat seperti stiker.

   Warna bayangannya rgba(60,44,20,...) — COKELAT, bukan hitam.
   Bayangan hitam murni di atas latar hangat terlihat kotor dan
   mati. Bayangan yang sedikit membawa warna alasnya terbaca sebagai
   cahaya yang terhalang, dan itulah yang terjadi di benda nyata.

   Ketiganya sengaja lemah. Kalau IT Manager mau lebih tegas, tinggal
   bilang — semua angkanya ada di --mfb-naik-* di bawah.
   ---------------------------------------------------------------- */

:root {
  /* Kontak dengan alas — rapat, agak pekat. */
  --mfb-naik-1 : 0 1px 2px rgba(60, 44, 20, 0.06);
  /* Bayangan lingkungan — lebar, hampir tidak terlihat sendirian. */
  --mfb-naik-2 : 0 4px 12px rgba(60, 44, 20, 0.05);
  /* Saat disentuh: kartunya naik, bayangannya ikut melebar & melunak.
     Bayangan yang membesar TANPA melunak terlihat seperti kartunya
     membesar, bukan terangkat. */
  --mfb-naik-h : 0 2px 4px rgba(60, 44, 20, 0.07),
                 0 12px 28px rgba(60, 44, 20, 0.09);
  --mfb-kilau  : inset 0 1px 0 rgba(255, 255, 255, 0.9);
}

/* Daftar ini SENGAJA panjang dan eksplisit, bukan pemilih borongan
   seperti [class*="card"]. Pemilih borongan akan ikut menyentuh
   elemen yang kebetulan namanya mengandung "card" — .stat-card-icon,
   .ai-card-label, .card-title — dan memberi bayangan pada teks.
   Menulis daftarnya satu per satu lebih panjang, tapi tidak pernah
   mengenai sesuatu yang tidak dimaksud. */
#desk .stat-card,
#desk .card,
#desk .course-card,
#desk .table-card,
#desk .stat-mini,
#desk .mgmt-toolbar,
#desk .rep-sum-card,
#desk .log-stat-card,
#desk .profile-card,
#desk .profile-section,
#desk .settings-nav-card,
#desk .settings-section,
#desk .course-mgmt-card,
#desk .event-list-wrap,
#desk .att-side-card,
#desk .air-filter-bar,
#desk .air-list-item {
  background-image: linear-gradient(180deg,
    rgba(255, 255, 255, 0.9) 0%,
    rgba(250, 249, 246, 0.55) 58%,
    rgba(243, 241, 236, 0.75) 100%);
  box-shadow: var(--mfb-kilau), var(--mfb-naik-1), var(--mfb-naik-2);
  /* Bingkai abu-abu bawaan dihangatkan sedikit supaya senada dengan
     bayangannya. Abu-abu netral di sebelah bayangan cokelat terbaca
     sebagai kebiruan, dan bikin kartunya terlihat dingin. */
  border-color: rgba(196, 186, 168, 0.55);
}

/* Kartu yang bisa diklik naik saat disentuh; kartu yang cuma wadah
   TIDAK. Kalau semuanya bergerak, gerakannya berhenti berarti
   apa-apa — dan staff kehilangan satu-satunya petunjuk visual
   tentang mana yang sebenarnya bisa ditekan. */
#desk .stat-card,
#desk .course-card,
#desk .course-mgmt-card,
#desk .air-list-item,
#desk .att-event-card {
  transition: box-shadow .22s ease, transform .22s ease, border-color .22s ease;
}
#desk .stat-card:hover,
#desk .course-card:hover,
#desk .course-mgmt-card:hover,
#desk .air-list-item:hover,
#desk .att-event-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--mfb-kilau), var(--mfb-naik-h);
  border-color: rgba(201, 168, 76, 0.42);
}

/* Kartu gelap (hero, panel AI, kepala detail course) punya arah
   cahaya terbalik: pantulan tepi atasnya EMAS REDUP, bukan putih.
   Putih terang di atas hitam terbaca sebagai bercak, bukan cahaya —
   ini kesalahan paling sering waktu memindahkan resep terang ke
   permukaan gelap. */
#desk .welcome-bar,
#desk .course-detail-header,
.ai-card,
.air-section {
  box-shadow:
    inset 0 1px 0 rgba(255, 244, 214, 0.13),
    0 2px 6px rgba(0, 0, 0, 0.22),
    0 14px 34px rgba(0, 0, 0, 0.16);
}

/* Batang kemajuan departemen — diberi ketebalan dan kilau, jadi ia
   terbaca sebagai benda yang mengisi alur, bukan garis berwarna. */
#desk .dept-bar-bg,
#mob .dept-bar-bg {
  box-shadow: inset 0 1px 2px rgba(60, 44, 20, 0.16);
}
#desk .dept-bar-fill,
#mob .dept-bar-fill {
  background-image: linear-gradient(180deg,
    rgba(255, 255, 255, 0.42) 0%,
    rgba(255, 255, 255, 0.06) 52%,
    rgba(0, 0, 0, 0.09) 100%);
  box-shadow: 0 1px 2px rgba(60, 44, 20, 0.22);
}

/* Mode gelap: gradien putih di atas kartu gelap akan terlihat seperti
   kabut. Yang dipakai justru kebalikannya — sedikit lebih terang di
   atas, dan bayangan hitam yang lebih dalam. */
body.dark-mode #desk .stat-card,
body.dark-mode #desk .card,
body.dark-mode #desk .course-card,
body.dark-mode #desk .table-card,
body.dark-mode #desk .stat-mini,
body.dark-mode #desk .profile-card,
body.dark-mode #desk .profile-section,
body.dark-mode #desk .settings-section,
body.dark-mode #desk .course-mgmt-card,
/* v1.70 — delapan kartu ini ADA di daftar terang di atas tapi TERLEWAT
   di sini, jadi gradien putih 0.55–0.9 tetap menyala di mode gelap dan
   teks terangnya tenggelam: 1,07:1 di Reports, Activity Log, AI Report,
   dan Attendance (demo GM 23 Sep 2026, MoM #11–#14). Kedua daftar kini
   berisi kartu yang sama. */
body.dark-mode #desk .mgmt-toolbar,
body.dark-mode #desk .rep-sum-card,
body.dark-mode #desk .log-stat-card,
body.dark-mode #desk .settings-nav-card,
body.dark-mode #desk .event-list-wrap,
body.dark-mode #desk .att-side-card,
body.dark-mode #desk .air-filter-bar,
body.dark-mode #desk .air-list-item {
  background-image: linear-gradient(180deg,
    rgba(255, 255, 255, 0.045) 0%,
    rgba(255, 255, 255, 0) 62%) !important;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.06),
    0 2px 5px rgba(0, 0, 0, 0.42),
    0 10px 26px rgba(0, 0, 0, 0.3);
  border-color: rgba(255, 255, 255, 0.1) !important;
}

/* Perangkat yang diminta mengurangi gerakan tidak boleh ikut
   dipaksa bergerak (SOP kategori 8). Bayangannya tetap, cuma
   gerakannya yang dimatikan. */
@media (prefers-reduced-motion: reduce) {
  #desk .stat-card:hover      { transform: none; }
  #desk .nav-item:hover svg   { transform: none; }
  #desk .course-card:hover,
  #desk .course-mgmt-card:hover,
  #desk .air-list-item:hover,
  #desk .att-event-card:hover { transform: none; }
}

/* ----------------------------------------------------------------
   2a. HERO GABUNGAN — SAPAAN + KOTAK AI JADI SATU PANEL
   Permintaan IT Manager: "menggabungkan hero nama + kotak AI jadi satu,
   seperti Spin Roulette" → dijawab "siap kerjakan kak".

   Di v2.144 keduanya dua kotak terpisah dengan jarak 28px, jadi
   terbaca sebagai dua hal yang tidak berhubungan. Di Spin Roulette
   hero-nya SATU panel gelap besar berbingkai emas (.hero, baris
   386-408) — itulah yang bikin halamannya terasa "mahal".

   🔴 DIKERJAKAN TANPA MENYENTUH SATU BARIS PUN STRUKTUR HTML.
   Kedua kotak itu memang sudah bersebelahan di baseline
   (baris 9295: welcomeHtml + aiHtml + ...), jadi cukup:
     · sudut yang saling menghadap dibuat siku
     · jarak di antaranya dihapus
     · latar bawah disamakan dengan latar atas
   Hasilnya satu panel, tapi DOM-nya tetap dua elemen — kalau
   lapisan ini dicopot, semuanya kembali persis seperti v2.144.

   Bingkai emas dalam (ciri khas hero Spin Roulette) digambar
   TERPOTONG DUA: bagian atas kehilangan sisi bawah, bagian bawah
   kehilangan sisi atas. Disambung, keduanya terbaca sebagai satu
   bingkai utuh yang mengelilingi seluruh panel.

   Kelas .mfb-hero-atas / .mfb-hero-bawah dipasang oleh mfb-ui.js.
   ---------------------------------------------------------------- */

.mfb-hero-atas {
  margin-bottom: 0 !important;   /* baseline menaruhnya di style="" */
  border-radius: 16px 16px 0 0 !important;
  border: 1px solid rgba(201, 168, 76, 0.25);
  border-bottom: 0;
  /* Hitam hangat yang sama dengan sidebar & topbar. Kalau hero tetap
     #0A0A0A datar sementara chrome-nya sudah hangat bergradasi, hero
     akan terlihat seperti tambalan dari halaman lain. Bahasa gelapnya
     harus satu di seluruh halaman. */
  background: linear-gradient(150deg,
    var(--mfb-chrome-atas) 0%,
    var(--mfb-chrome-bawah) 78%) !important;
  /* Garis gelap tipis PAS di atas garis emas milik bagian bawah.
     Dua garis bersebelahan — gelap di atas, terang di bawah — itulah
     yang membuat sambungannya terbaca sebagai lekukan sungguhan,
     bukan sekadar coretan warna. Persis cara benda nyata terlihat. */
  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.55);
}

.mfb-hero-bawah {
  margin-top: 0 !important;
  border-radius: 0 0 16px 16px !important;
  /* 🔴 v1.4 — DIPERTEGAS dari 0.16 ke 0.55. IT Manager: "antara greeting
     dan AI Intelligence, buat garis pemisahnya yang tegas."

     0.16 itu pilihan yang salah: begitu dua kotak digabung jadi satu
     panel, batas antar-bagiannya justru jadi LEBIH penting, bukan
     kurang. Garis yang terlalu malu-malu membuat dua bagian berbeda
     terlihat seperti satu blok teks yang berantakan.

     Ditambah garis gelap tipis di atasnya (box-shadow inset): dua
     garis bersebelahan — terang di bawah, gelap di atas — itulah
     yang membuat sambungannya terbaca sebagai lekukan sungguhan,
     bukan sekadar coretan warna. */
  border-top: 1px solid rgba(201, 168, 76, 0.55);
  /* Latar disamakan dengan bagian atas supaya sambungannya tidak
     terlihat sebagai dua warna yang berbeda. */
  background: var(--mfb-chrome-bawah) !important;
}

/* Bingkai emas dalam — dua potong yang menyambung.
   .welcome-bar memakai anak <div class="welcome-bar-bg"> untuk
   cahaya emasnya dan .ai-card memakai ::before untuk cahayanya,
   jadi ::after di keduanya masih kosong dan aman dipakai. */
.mfb-hero-atas::after,
.mfb-hero-bawah::after {
  content: '';
  position: absolute;
  pointer-events: none;
  border: 1px solid rgba(201, 168, 76, 0.16);
}
.mfb-hero-atas::after {
  left: 11px; right: 11px; top: 11px; bottom: 0;
  border-bottom: 0;
  border-radius: 10px 10px 0 0;
}
.mfb-hero-bawah::after {
  left: 11px; right: 11px; top: 0; bottom: 11px;
  border-top: 0;
  border-radius: 0 0 10px 10px;
}

/* Mode gelap: baseline baris 1603 mengubah .welcome-bar jadi #111
   dengan !important. Kalau bagian bawah tidak ikut diubah,
   sambungannya jadi dua warna hitam yang beda dan malah lebih
   kelihatan daripada sebelum digabung. */
body.dark-mode .mfb-hero-bawah { background: #111 !important; }

/* Di layar sempit padding hero cukup besar; bingkai 11px jadi
   terlalu rapat ke tulisan. Dikecilkan, bukan dihapus. */
@media (max-width: 560px) {
  .mfb-hero-atas::after  { left: 7px; right: 7px; top: 7px; }
  .mfb-hero-bawah::after { left: 7px; right: 7px; bottom: 7px; }
}

/* ----------------------------------------------------------------
   2e. TUJUH KARTU ANGKA JADI SATU BARIS
   Permintaan IT Manager: "stat card 7 itu kayaknya dibuat satu baris aja
   cukup deh. itu keliatan kosong gitu, gede-gede banget ga sih?"

   Betul. v2.144 memecahnya jadi 4 + 3 (.stats-grid-1 baris 1790,
   .stats-grid-2 baris 1794). Bentuknya jadi aneh: baris pertama
   penuh, baris kedua menyisakan lubang selebar satu kartu. Dan
   karena tiap kartu melar mengisi ruang, isinya yang cuma satu
   angka pendek jadi terapung di tengah kotak besar yang kosong.

   Digabung jadi 7 kolom: tiap kartu mengecil, angkanya jadi padat,
   dan barisnya rata — tidak ada lagi lubang menganga.

   Penggabungannya dikerjakan mfb-ui.js (memindahkan 3 kartu dari
   grid kedua ke grid pertama), karena CSS tidak bisa memindahkan
   elemen antar-wadah.

   🔴 TIDAK dipaksakan 7 kolom di semua lebar layar. Di bawah 1500px,
   7 kolom membuat tiap kartu jadi ~150px — angkanya masih muat tapi
   labelnya ("My Certificates", "Video Hours Watched") terpotong.
   Jadi di layar sempit ia turun ke 4 kolom, lalu 2.
   ---------------------------------------------------------------- */

#desk .mfb-stat-satu-baris {
  grid-template-columns: repeat(7, minmax(0, 1fr)) !important;
  gap: 12px !important;
  margin-bottom: 24px !important;
}

/* Kartunya ikut dikecilkan — kalau tidak, 7 kartu berukuran lama
   justru terlihat lebih sesak, bukan lebih rapi. */
#desk .mfb-stat-satu-baris .stat-card       { padding: 16px 15px; gap: 3px; }
#desk .mfb-stat-satu-baris .stat-card-top   { margin-bottom: 7px; }
#desk .mfb-stat-satu-baris .stat-card-icon  { width: 30px; height: 30px; font-size: 14px; border-radius: 8px; }
#desk .mfb-stat-satu-baris .stat-card-num   { font-size: 27px; }
#desk .mfb-stat-satu-baris .stat-card-label { font-size: 11.5px; }
#desk .mfb-stat-satu-baris .stat-card-sub   { font-size: 10px; }
#desk .mfb-stat-satu-baris .stat-card-trend { font-size: 9.5px; padding: 2px 6px; }

@media (max-width: 1500px) {
  #desk .mfb-stat-satu-baris { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; }
  #desk .mfb-stat-satu-baris .stat-card     { padding: 20px 22px; }
  #desk .mfb-stat-satu-baris .stat-card-num { font-size: 32px; }
}
@media (max-width: 1050px) {
  #desk .mfb-stat-satu-baris { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
}

/* Wadah kedua yang sudah dikosongkan — disembunyikan, BUKAN dihapus
   dari DOM. Kalau lapisan ini dicopot, isinya kembali ke tempatnya. */
#desk .mfb-stat-kosong { display: none !important; }

/* ----------------------------------------------------------------
   2b. KARTU "MY TRAINING" UNTUK HoD
   Bottom nav TETAP 5 sesuai permintaan IT Manager, jadi jalan masuk ke
   materi HoD dipasang sebagai kartu di halaman Dashboard HoD —
   halaman pertama yang mereka lihat, tidak perlu dicari.
   ---------------------------------------------------------------- */

.mfb-training-card {
  background: linear-gradient(135deg, #0F0F0F 0%, #1A1614 100%);
  border: 1px solid rgba(201, 160, 101, 0.3);
  border-radius: 14px;
  padding: 18px 20px;
  margin-bottom: 18px;
}

.mfb-training-head { margin-bottom: 14px; }

.mfb-training-title {
  display: block;
  font-family: Georgia, serif;
  font-size: 17px;
  font-weight: 700;
  color: var(--gold, #C9A065);
  letter-spacing: 0.02em;
}
.mfb-training-sub {
  display: block;
  margin-top: 3px;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.55);
}

.mfb-training-links {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

.mfb-training-link {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  /* Tinggi 44px — batas minimum sasaran sentuh (SOP kategori 8). */
  min-height: 44px;
  padding: 10px 8px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(255, 255, 255, 0.05);
  color: rgba(255, 255, 255, 0.92);
  font-family: 'Inter', sans-serif;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background .16s ease, border-color .16s ease;
}
.mfb-training-link:hover {
  background: rgba(201, 160, 101, 0.16);
  border-color: rgba(201, 160, 101, 0.45);
}
.mfb-training-link:focus-visible {
  outline: 2px solid var(--gold, #C9A065);
  outline-offset: 2px;
}
.mfb-training-ikon { font-size: 15px; line-height: 1; }

/* Di HP tiga tombol sejajar jadi terlalu sempit untuk labelnya. */
@media (max-width: 480px) {
  .mfb-training-links { grid-template-columns: 1fr; }
  .mfb-training-link  { justify-content: flex-start; padding-left: 14px; }
}

/* ----------------------------------------------------------------
   3. BOTTOM NAV DI MODE GELAP
   Permintaan IT Manager: "bottom nav di dark side itu transparan ya?"
   Betul — baseline baris 1673 memakai rgba(255,255,255,0.05),
   yaitu putih 5%, jadi isi halaman terlihat menembus di baliknya.
   ---------------------------------------------------------------- */

body.dark-mode #mob .bottom-nav {
  background: #111111 !important;
  border-top-color: rgba(255, 255, 255, 0.14) !important;
  /* 🔴 backdrop-filter DIBUANG di v1.43 — dan alasannya ada di baris
     tepat di atas ini: latarnya #111111 SOLID. Blur hanya bekerja
     pada apa yang terlihat menembus, dan di balik warna solid tidak
     ada apa pun yang menembus. Jadi efeknya nol.

     Biayanya TIDAK nol. Bilah ini menempel di layar di atas daerah
     yang digulir, jadi selama staff menggulir daftar course, HP-nya
     menghitung ulang blur itu setiap frame — untuk gambar yang tidak
     pernah terlihat. Inilah penyebab gulir tersendat yang paling
     sering ditemukan di HP kelas menengah, dan staff operasional
     justru memakai HP kelas itu. */
}

/* ----------------------------------------------------------------
   4. TAMPILAN MOBILE
   Permintaan IT Manager: tulisan LMS di HP terlalu kecil, dan kartu
   ringkasan kurang besar — "apa dibuat 1 baris aja biar kotaknya
   lebih 1:1 rationya".
   ---------------------------------------------------------------- */

@media (max-width: 768px) {

  /* Judul "MISS FISH LMS" di header HP. */
  #mob [data-mfb="topbar"] .mtop-title,
  #mob [data-mfb="topbar"] [class*="title"] {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.22em;
    text-transform: uppercase;
  }
}

/* 🔴 CATATAN v1.7 — SEBUAH BLOK CSS MATI DIHAPUS DARI SINI.
   Bagian ini dulu berisi aturan untuk #mob .stat-grid,
   #mob .stats-grid, #mob [class*="stat-grid"], #mob .stat-card, dan
   #mob [class*="stat-card"], lengkap dengan komentar panjang tentang
   "kartu 2 kolom biar rationya 1:1".

   Semua pemilih itu TIDAK PERNAH COCOK DENGAN APA PUN. Sudah dicek
   ke baseline: .stats-grid-1/-2 dan .stat-card hanya ada di pohon
   #desk. Dashboard HP sama sekali tidak memakainya — ia memakai
   .stats-scroll berisi .stat-chip (baseline baris 9316-9321), bentuk
   yang berbeda sama sekali: satu baris yang digeser ke samping,
   bukan kisi.

   Jadi selama ini tampilan HP tidak pernah benar-benar disentuh,
   sementara komentarnya mengaku sudah. CSS mati tidak berbahaya;
   komentar yang berbohong tentang CSS mati berbahaya, karena
   membuat orang berikutnya (termasuk saya) yakin sesuatu sudah
   dikerjakan padahal belum. Digantikan bagian 4c di bawah, yang
   menyasar kelas yang benar-benar dipakai. */

/* ----------------------------------------------------------------
   4c. TAMPILAN HP DIPERHALUS
   Permintaan IT Manager: "UI UX di mobile jg perlu di touch up ya"
   + "stat card, card2 lain, buat 3D jg donk kak".

   🔴 KENAPA HP BUTUH RESEP SENDIRI, BUKAN SEKADAR MENYALIN DESKTOP

   Di HP tidak ada hover. Seluruh bahasa "benda ini bisa ditekan"
   yang dipakai desktop — kartu naik, bayangan melebar — tidak
   pernah terlihat sama sekali. Maka di HP kedalamannya harus sudah
   ADA sejak diam, bukan muncul saat disentuh.

   Dan layarnya sering dipakai di luar ruangan, sambil jalan, dengan
   kecerahan tinggi. Bayangan sehalus di desktop akan hilang total.
   Karena itu angka di bawah sedikit lebih tegas daripada bagian 1g
   — bukan karena seleranya beda, tapi karena kondisi melihatnya
   memang beda.
   ---------------------------------------------------------------- */

/* --- a. Hero HP disamakan bahasanya dengan chrome desktop ---
   Baseline memakai var(--solid-dark) yang rata. Begitu sidebar dan
   topbar desktop jadi hitam hangat bergradasi, hero HP yang masih
   hitam rata terbaca seperti potongan dari aplikasi lain. */
#mob .dash-hero,
#mob .course-detail-header {
  background-image: linear-gradient(155deg,
    var(--mfb-chrome-atas) 0%,
    var(--mfb-chrome-bawah) 82%) !important;
  box-shadow: inset 0 -1px 0 rgba(201, 168, 76, 0.22);
}

/* Jam besar di hero — angka diberi lebar tetap supaya tidak
   "bergoyang" tiap detik berganti. Angka 1 lebih sempit daripada
   angka lain di hampir semua huruf, jadi jam berdetik tanpa ini
   akan menggeser tata letak di sekitarnya sedikit-sedikit. */
#mob .dash-time { font-variant-numeric: tabular-nums; }

/* --- b. Kartu angka HP (.stat-chip) dibuat timbul --- */
#mob .stat-chip,
#mob .stat-chip-m,
#mob .att-stat-chip {
  background-image: linear-gradient(180deg,
    rgba(255, 255, 255, 0.95) 0%,
    rgba(249, 247, 243, 0.6) 60%,
    rgba(240, 237, 230, 0.85) 100%);
  border-color: rgba(196, 186, 168, 0.6);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    0 1px 2px rgba(60, 44, 20, 0.07),
    0 6px 16px rgba(60, 44, 20, 0.07);
}

/* Ikon emoji diberi ALAS BULAT yang timbul, bukan dibiarkan
   mengambang. Emoji polos di atas kartu putih selalu terlihat
   seperti tempelan; begitu ia punya alas, ia jadi bagian kartunya. */
#mob .stat-chip-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background-image: linear-gradient(180deg,
    rgba(201, 168, 76, 0.2) 0%,
    rgba(201, 168, 76, 0.07) 55%,
    rgba(120, 92, 34, 0.09) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    inset 0 -2px 3px rgba(0, 0, 0, 0.07),
    0 2px 4px rgba(60, 44, 20, 0.13);
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.16);
  font-size: 17px;
}

/* Angkanya diberi lebar digit tetap — di kartu sempit, angka yang
   melebar-menyempit membuat seluruh baris terlihat goyah. */
#mob .stat-chip-num { font-variant-numeric: tabular-nums; }

/* --- c. Petunjuk "ini bisa digeser" ---
   🔴 INI BUKAN HIASAN, INI BUG KETERBACAAN.
   .stats-scroll berisi EMPAT kartu (Staff, Completion, Certs,
   Overdue) tapi layar HP cuma memuat dua setengah. Kartu keempat
   berisi jumlah TERLAMBAT — justru yang paling perlu dilihat — dan
   sekarang tidak ada satu pun tanda bahwa ia ada di sana.

   Kartu ketiga yang terpotong di tepi kanan memang sedikit memberi
   petunjuk, tapi terlalu samar: di tangkapan layar IT Manager ia
   terpotong pas di tepi dan terbaca seperti kesalahan tata letak,
   bukan undangan menggeser.

   Dua obatnya: kabut memudar di tepi kanan (memberi tahu ada
   lanjutannya) dan scroll-snap (kartunya berhenti rapi, bukan
   setengah-setengah). */
/* 🔴 DIGANTI TOTAL DI v1.10 — kartu angka TIDAK LAGI DIGESER.
   ================================================================
   Laporan IT Manager: "card yg kanan kepotong kak, itu harusnya brp
   card?"

   Jawabannya EMPAT: Staff, Completion, Certs, dan Overdue
   (baseline baris 9316-9321). Yang keempat berisi jumlah training
   TERLAMBAT — justru angka yang paling perlu ditindaklanjuti — dan
   selama ini ia berada di luar layar tanpa satu pun tanda bahwa ia
   ada.

   v1.8 mencoba menambalnya dengan kabut memudar + scroll-snap.
   Itu obat yang salah. Petunjuk geser sebagus apa pun tetap
   menyembunyikan angka; dan kalau angka yang disembunyikan adalah
   "berapa training yang terlambat", menyembunyikannya bukan pilihan
   tata letak — itu kehilangan informasi.

   Sekarang: KISI 2x2, empat kartu terlihat sekaligus, tidak ada
   yang terpotong, tidak ada yang perlu digeser. Bentuknya 1:1
   sesuai permintaan IT Manager — dan bujur sangkar kebetulan memang
   bentuk terbaik untuk satu angka besar dengan satu label pendek.

   Konsekuensinya jujur: halaman jadi lebih panjang. Itu pertukaran
   yang sengaja diambil — menggulir ke bawah adalah gerakan yang
   sudah pasti dilakukan orang di HP, sedangkan menggeser ke samping
   sering tidak pernah terpikir. */
/* 🔴 DIUBAH LAGI DI v1.14 — 2x2 jadi SATU BARIS BERISI EMPAT.
   ================================================================
   Permintaan IT Manager: "card staff sampai overdue, 4 card itu, dibuat
   dalam 1 baris aja kak. seperti quick actionnya itu."

   Susunannya sekarang persis sama dengan baris Quick Actions di
   bawahnya (bagian 4g), dan itu justru keuntungan terbesarnya:
   dua baris berisi empat kotak bujur sangkar yang sejajar terbaca
   sebagai satu sistem, bukan dua komponen berbeda yang kebetulan
   ditumpuk. Kisi 2x2 di atas baris-4 membuat halaman terasa
   berganti aturan di tengah jalan.

   Untungnya lagi: hero + empat angka + Quick Actions sekarang muat
   dalam satu layar HP tanpa menggulir. Sebelumnya kisi 2x2 memakan
   dua kali tinggi dan mendorong Quick Actions ke bawah lipatan —
   terlihat di tangkapan layar IT Manager, di mana barisnya terpotong
   separuh oleh bilah menu.

   Konsekuensi yang harus diakui: angkanya jadi lebih kecil (dari
   ~42px ke ~26px). Itu pertukaran yang sadar — empat angka yang
   TERLIHAT SEMUA pada ukuran sedang lebih berguna daripada dua
   angka raksasa dengan dua lagi di bawah lipatan. */
#mob .stats-scroll {
  display: grid !important;
  grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
  gap: 8px !important;
  overflow: visible !important;
  padding: 16px 20px !important;
}
#mob .stats-scroll > .stat-chip {
  /* min-width bawaan 130px akan memaksa kisi melebar dan kembali
     memunculkan potongan di kanan. WAJIB dinolkan — dan pada empat
     kolom ini jauh lebih kritis daripada waktu dua kolom: 4 x 130px
     = 520px, hampir 1,5 kali lebar layar HP. */
  min-width: 0 !important;
  flex-shrink: 1 !important;
  aspect-ratio: 1 / 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: 6px 4px !important;
}
/* Angkanya diberi ruang sebanyak mungkin, tapi tetap harus muat.
   Pada layar 360px satu kartu selebar ~76px; clamp menahannya di
   antara 19px (layar 320px tersempit) dan 28px (tablet). */
#mob .stats-scroll > .stat-chip .stat-chip-num {
  font-size: clamp(19px, 6.6vw, 28px);
  line-height: 1.05;
  margin-top: 0;
}
/* 🔴 v1.43 — 9,5 px NAIK JADI clamp(10px, 2.9vw, 12px).

   Angka 9,5 px lahir dari keputusan IT Manager "tujuh kartu angka jadi
   satu baris" (bagian 2e): satu baris berarti satu kartu cuma
   selebar ~76 px di layar 360 px, dan label sepanjang "Completion"
   memang hanya muat kalau dikecilkan.

   Tapi labelnya bukan hiasan — dialah yang memberi ARTI pada angka
   di atasnya. Tanpa membaca "OVERDUE", angka 3 tidak berarti
   apa-apa. Jadi yang dilonggarkan BUKAN ukurannya, melainkan
   aturan satu barisnya: label kini boleh turun ke baris kedua.
   Dengan begitu ukurannya bisa naik ke ukuran terbesar yang masih
   muat di tiap lebar layar (10 px di 345 px, 12 px di 414 px ke
   atas), dan tidak ada lagi nama yang terpotong jadi "Completi…".

   Satu barisnya kartu TETAP UTUH — yang berubah cuma isinya boleh
   dua baris. */
#mob .stats-scroll > .stat-chip .stat-chip-label {
  /* 🔴 DILIHAT DI TANGKAPAN LAYAR, BUKAN DI ANGKA: pengaturan
     pertama memenggal kata jadi "COMPLETI / ON", dan kartu kedua
     jadi lebih tinggi daripada tetangganya sehingga barisnya tidak
     rata lagi. Dua-duanya lolos SEMUA pemeriksaan angka — ukuran
     huruf benar, kontras benar, nol gulir menyamping — dan tetap
     terbaca murah. Angka tidak bisa menggantikan melihat.
     overflow-wrap: normal = kata TIDAK PERNAH dipenggal. Ukuran dan
     spasinya yang dikecilkan sedikit supaya kata terpanjang
     ("COMPLETION") tetap muat satu baris di 360 px ke atas. */
  font-size: clamp(10px, 2.6vw, 11.5px);
  line-height: 1.2;
  letter-spacing: 0.04em;
  margin-top: 5px;
  max-width: 100%;
  white-space: normal;
  overflow-wrap: normal;
  word-break: keep-all;
  hyphens: none;
}
/* 🔴 PENANDA "!" TIDAK DISEMBUNYIKAN — DIPINDAH KE SUDUT.
   Baseline baris 7684-7686: .stat-chip-trend HANYA tergambar untuk
   trend-warn, yaitu kartu Overdue ketika jumlahnya di atas nol.
   Jadi ia bukan hiasan seperti "+12%" di mockup — ia satu-satunya
   tanda bahwa ada training terlambat yang perlu ditindaklanjuti.

   Menyembunyikannya demi ruang berarti membuang justru informasi
   yang paling perlu dilihat. Sebagai gantinya ia dilepas dari alur
   tata letak (position:absolute) sehingga tidak lagi memakan tinggi
   kartu, lalu ditempel di sudut kanan atas — tempat yang sudah
   dikenal orang sebagai tempat lencana notifikasi. */
#mob .stats-scroll > .stat-chip { position: relative; }
#mob .stats-scroll > .stat-chip .stat-chip-trend {
  position: absolute;
  top: 5px;
  right: 5px;
  margin: 0 !important;
  align-self: auto !important;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 800;
  line-height: 1;
}

/* Layar sangat sempit (<340px, mis. iPhone SE lama): ikon kartu
   dilepas supaya angkanya tetap punya ruang. */
@media (max-width: 340px) {
  #mob .stats-scroll { gap: 6px !important; padding: 14px 14px !important; }
  #mob .stats-scroll > .stat-chip .stat-chip-icon { display: none !important; }
}

/* Pil penyaring TETAP digeser — dan itu benar. Isinya kategori,
   bukan angka; kalau satu pil tidak terlihat, tidak ada informasi
   yang hilang, cuma satu pilihan yang perlu dicari sebentar. */
#mob .filter-pills-m {
  position: relative;
  scroll-snap-type: x proximity;
  scroll-padding-left: 20px;
  padding-right: 28px;
}
#mob .filter-pills-m > * { scroll-snap-align: start; }

/* Kabutnya dipasang di INDUK .scroll-content, bukan di .stats-scroll
   sendiri: elemen yang menggulir ikut membawa serta ::after-nya
   waktu digeser, jadi kabutnya akan ikut berjalan keluar layar —
   persis kebalikan dari yang dimaksud. */
#mob .scroll-content { position: relative; }
#mob .stats-scroll::after {
  content: '';
  position: sticky;
  right: 0;
  flex: 0 0 auto;
  align-self: stretch;
  width: 34px;
  margin-right: -28px;
  pointer-events: none;
  background: linear-gradient(90deg,
    rgba(247, 247, 245, 0) 0%,
    rgba(247, 247, 245, 0.92) 78%);
}
body.dark-mode #mob .stats-scroll::after {
  background: linear-gradient(90deg,
    rgba(10, 10, 10, 0) 0%,
    rgba(10, 10, 10, 0.9) 78%);
}

/* --- d. Kartu-kartu HP lain ikut diangkat --- */
#mob .team-item-m,
#mob .mob-form-card,
#mob .log-item-m,
#mob .settings-item-m,
#mob .att-event-card,
#mob .course-card-adm,
#mob .course-card {
  background-image: linear-gradient(180deg,
    rgba(255, 255, 255, 0.95) 0%,
    rgba(249, 247, 243, 0.55) 62%,
    rgba(240, 237, 230, 0.8) 100%);
  border-color: rgba(196, 186, 168, 0.6);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    0 1px 2px rgba(60, 44, 20, 0.06),
    0 5px 14px rgba(60, 44, 20, 0.06);
}

/* Ditekan — kartunya masuk sedikit. Di HP inilah satu-satunya
   umpan balik sentuhan yang bisa diberikan CSS, dan tanpanya
   layar sentuh terasa "tidak menjawab". */
#mob .team-item-m:active,
#mob .att-event-card:active,
#mob .course-card-adm:active,
#mob .course-card:active {
  transform: scale(0.985);
  box-shadow:
    inset 0 1px 3px rgba(60, 44, 20, 0.12),
    0 1px 2px rgba(60, 44, 20, 0.06);
}

/* --- e. Tombol Quick Actions di Dashboard HP ---
   🔴 Butuh !important. Empat tombol ini ditulis dengan style="" di
   dalam string HTML (baseline baris 9333-9336), dan style langsung
   pada elemen selalu mengalahkan stylesheet mana pun. Ini satu-
   satunya tempat di berkas ini yang memerlukannya. */
#mob .scroll-content > div > button[onclick^="goTo"] {
  background-image: linear-gradient(180deg,
    rgba(255, 255, 255, 0.95) 0%,
    rgba(247, 245, 240, 0.7) 58%,
    rgba(238, 234, 226, 0.9) 100%) !important;
  border-color: rgba(196, 186, 168, 0.75) !important;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    0 1px 2px rgba(60, 44, 20, 0.08),
    0 5px 13px rgba(60, 44, 20, 0.07);
  transition: transform .12s ease, box-shadow .12s ease;
}
#mob .scroll-content > div > button[onclick^="goTo"]:active {
  transform: translateY(1px);
  box-shadow: inset 0 2px 4px rgba(60, 44, 20, 0.14);
}

/* --- f. Bilah bawah: yang aktif benar-benar terlihat aktif ---
   Baseline cuma mengubah warnanya. Warna saja mudah luput di layar
   terang di luar ruangan; alas timbul di belakang ikonnya jauh
   lebih gampang ditangkap sekilas. */
#mob .bnav-item.active .bnav-icon,
#mob .bnav-item.active span:first-child {
  text-shadow: 0 1px 3px rgba(201, 160, 101, 0.5);
}
#mob .bnav-item {
  position: relative;
  transition: transform .14s ease;
}
#mob .bnav-item:active { transform: scale(0.94); }
/* Garis emas pendek di atas menu aktif — penanda yang sama dengan
   border-left emas di sidebar desktop, cuma diputar 90 derajat.
   Satu bahasa penanda untuk dua bentuk navigasi. */
#mob .bnav-item.active::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 26px;
  height: 2.5px;
  border-radius: 0 0 3px 3px;
  background: linear-gradient(90deg,
    rgba(201, 160, 101, 0), var(--mfb-emas), rgba(201, 160, 101, 0));
}

/* --- g. Judul bagian dibuat editorial ---
   Georgia dipakai di seluruh LMS untuk angka dan nama besar. Judul
   bagian di HP masih memakai huruf UI biasa, jadi terbaca seperti
   label sistem, bukan judul. */
#mob .section-title {
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 16px;
  letter-spacing: 0.01em;
}

/* ----------------------------------------------------------------
   4e. 🔴 JUDUL HALAMAN HP YANG TIDAK TERLIHAT — BUG NYATA
   ================================================================
   Ditemukan waktu menelusuri tangkapan layar Dashboard HP IT Manager.

   Di foto itu topbar cuma menampilkan "MISS FISH LMS" berwarna emas.
   Tulisan "Dashboard" yang seharusnya ada TEPAT DI BAWAHNYA tidak
   kelihatan sama sekali — dan saya sempat mengira memang tidak ada.

   Ternyata ADA, cuma tidak terbaca. Baseline baris 1405-1408:

       #mob .it-title       { color: var(--black); }
       #mob .it-title.white { color: #fff; }

   Jadi judul halaman berwarna HITAM kecuali diberi kelas .white.
   Sementara topbar Dashboard memakai .inner-topbar.dark — latar
   hitam. Hitam di atas hitam.

   Sudah dihitung satu per satu: dari 24 judul halaman HP,
   21 menulis "it-title white" dengan benar. TIGA tidak:

       baris 4819  Dashboard admin      (m-topbar-title)
       baris 4938  My Team HoD          (m-hod-staff-title)
       baris 4976  Dept Reports HoD     (m-hod-reports-title)

   Ketiganya kebetulan judul yang diisi lewat JavaScript — pola yang
   sama, jadi kemungkinan besar satu kelalaian yang terulang, bukan
   tiga kejadian terpisah.

   🔴 KENAPA INI TIDAK PERNAH KETAHUAN
   Baris 1630 memberi warna terang saat MODE GELAP menyala:
       body.dark-mode #mob .inner-topbar .it-title { color: #F0F0F0 !important; }
   Jadi bug ini HANYA muncul di mode terang. Siapa pun yang mengujinya
   dengan mode gelap menyala akan melihat semuanya baik-baik saja.

   PERBAIKANNYA satu baris, dan sengaja diikat ke .dark — bukan ke
   .it-title begitu saja. Topbar terang memang butuh judul gelap;
   yang salah bukan warnanya, tapi karena warna itu ikut terpakai di
   atas latar hitam. Mengikat ke .dark memperbaiki persis kasusnya
   dan tidak menyentuh satu pun halaman yang sudah benar — 21 halaman
   lain sudah putih, jadi nilainya tidak berubah untuk mereka.
   ---------------------------------------------------------------- */
#mob .inner-topbar.dark .it-title { color: #FFFFFF; }

/* Eyebrow header HP — disamakan bahasanya dengan judul topbar
   desktop: huruf Cinzel berjarak lebar.

   🔴 DIPERBESAR DI v1.10 atas permintaan IT Manager: "tulisan Miss Fish
   LMS itu kayaknya kecil banget, buat lebih gede kak."

   Teksnya juga diganti jadi "Learning Management System" (lewat
   mfb-ui.js bagian 4d), karena IT Manager benar: logo Miss Fish sudah
   ada di kiri header, jadi menulis "Miss Fish LMS" di tengah
   mengulang merek yang sama dua kali dalam satu baris.

   9px -> clamp(10px, 2.9vw, 12px). Memakai clamp, bukan angka
   tetap: "LEARNING MANAGEMENT SYSTEM" itu 26 huruf dengan jarak
   antar-huruf lebar, dan di layar 320px ia akan menabrak avatar
   kalau ukurannya dipaksa tetap.

   🔴 NAMA HALAMAN TETAP LEBIH BESAR (14px), dan itu disengaja.
   Nama sistem tidak pernah berubah — dibaca sekali lalu diabaikan.
   Nama halaman berubah tiap pindah menu dan itulah yang benar-benar
   perlu dibaca staff sambil kerja. Kalau nama sistem dibuat lebih
   besar dari nama halaman, yang paling mencolok justru jadi
   informasi yang paling tidak berguna. */
#mob .it-eyebrow {
  font-family: 'Cinzel', Georgia, 'Times New Roman', serif;
  font-size: clamp(10px, 2.9vw, 12px);
  font-weight: 700;
  letter-spacing: 0.16em;
  text-indent: 0.16em;   /* mengimbangi jarak sesudah huruf terakhir */
  line-height: 1.25;
  white-space: nowrap;
}
/* Nama halaman ikut sedikit dinaikkan supaya jarak antara keduanya
   tetap terasa — kalau eyebrow naik sendirian, hierarkinya mendatar. */
#mob .it-title { font-size: 15px; letter-spacing: 0.01em; }

/* ----------------------------------------------------------------
   4f. 🔴 "TIDAK ADA DATA" YANG TERLIHAT SEPERTI "SEDANG MEMUAT"
   ================================================================
   Laporan IT Manager: "courses mobile masi loading".

   Halamannya TIDAK memuat — lihat penjelasan panjang di bagian 4b
   mfb-ui.js. Ringkasnya: .page-placeholder dipakai untuk DUA arti
   yang berlawanan (sedang memuat DAN tidak ada data), dan tampilan
   bawaannya cuma cocok untuk yang pertama:

       ::before  -> "Miss Fish Bali"
       ::after   -> "LEARNING MANAGEMENT SYSTEM"
       .ph-dots  -> cincin emas berputar TANPA HENTI

   Kelas .mfb-sudah-selesai dipasang mfb-ui.js ketika judul
   placeholder-nya TIDAK berbunyi "loading". Tiga aturan di bawah
   lalu mengubahnya dari layar tunggu menjadi keadaan kosong yang
   jujur.

   Kenapa merek ikut disembunyikan, bukan cuma cincinnya: "Miss Fish
   Bali / LEARNING MANAGEMENT SYSTEM" masuk akal SEKALI di layar
   pembuka. Diulang di setiap kotak kosong di setiap halaman, ia
   berhenti berarti apa-apa dan cuma mendorong pesan yang sebenarnya
   turun ke bawah layar.
   ---------------------------------------------------------------- */

.page-placeholder.mfb-sudah-selesai::before,
.page-placeholder.mfb-sudah-selesai::after { content: none !important; }

.page-placeholder.mfb-sudah-selesai .ph-dots {
  display: none !important;
  animation: none !important;   /* hentikan juga, bukan cuma sembunyikan */
}

/* Ikon 🔍 yang sudah ditulis baseline TAPI disembunyikan
   (.page-placeholder .ph-icon { display: none }) akhirnya dipakai —
   keadaan kosong tanpa ikon terlihat seperti halaman yang gagal
   dimuat setengah jalan. */
.page-placeholder.mfb-sudah-selesai .ph-icon {
  display: block !important;
  font-size: 34px;
  line-height: 1;
  opacity: .75;
  margin-bottom: 2px;
}

/* Tanpa merek dan tanpa cincin, tinggi 60vh jadi terlalu lapang —
   pesannya terapung sendirian di tengah layar kosong. */
.page-placeholder.mfb-sudah-selesai {
  min-height: 34vh;
  gap: 8px;
}
.page-placeholder.mfb-sudah-selesai .ph-title { font-size: 14px; }

/* ----------------------------------------------------------------
   4g. TOMBOL AKSI CEPAT HP — SATU BARIS, BUJUR SANGKAR
   Permintaan IT Manager: "bisa dibuat 1 row aja ga kak? kotaknya bikin
   yg AR 1:1?"

   Empat tombol yang tadinya 2x2 jadi satu baris berisi empat bujur
   sangkar — susunan yang sama dengan ikon aplikasi di layar utama
   HP, jadi tidak perlu dipelajari.

   Semua pakai !important karena baseline menulis grid-template-
   columns dan height langsung di atribut style="" (baris 9332-9337),
   dan style pada elemen selalu menang atas stylesheet.
   ---------------------------------------------------------------- */

#mob .mfb-aksi-cepat {
  grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
  gap: 8px !important;
}
#mob .mfb-aksi-cepat > button {
  height: auto !important;
  aspect-ratio: 1 / 1;
  display: flex !important;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 6px 4px !important;
  border-radius: 14px !important;
  min-width: 0;
}
#mob .mfb-aksi-ikon { font-size: 21px; line-height: 1; }
#mob .mfb-aksi-label {
  font-size: 10.5px;
  font-weight: 600;
  line-height: 1.15;
  text-align: center;
  /* 🔴 v1.43 — DUA BARIS, bukan satu baris terpotong.
     Sejak v2.189 isinya halaman pengelola yang namanya memang lebih
     panjang ("Manage Courses", "Activity Log"). Di grid empat kolom
     pada layar 360 px setiap tombol hanya selebar ~78 px, jadi satu
     baris akan memotongnya jadi "Manage Co…" — dan nama menu yang
     terpotong adalah menu yang tidak bisa dibaca sekilas.
     Kotaknya 1:1, ruang tingginya ada; barisnya dibatasi dua supaya
     label sepanjang apa pun tidak pernah mendorong tombol lain. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  white-space: normal;
  overflow-wrap: anywhere;
  max-width: 100%;
}

/* Topbar HP ikut memakai hitam hangat bergradasi yang sama dengan
   chrome desktop dan hero HP. Tanpa ini, satu-satunya bidang gelap
   yang masih datar di seluruh aplikasi justru yang paling sering
   dilihat. */
#mob .inner-topbar.dark {
  background-image: linear-gradient(180deg,
    var(--mfb-chrome-atas) 0%,
    var(--mfb-chrome-bawah) 100%);
  border-bottom-color: var(--mfb-hair);
}

@media (prefers-reduced-motion: reduce) {
  #mob .bnav-item:active,
  #mob .team-item-m:active,
  #mob .att-event-card:active,
  #mob .course-card-adm:active,
  #mob .course-card:active { transform: none; }
}






/* ----------------------------------------------------------------
   47. ANGKA YANG SEJAJAR  (v2.191)

   Disetujui IT Manager 17 September 2026.

   Inter menggambar angka dengan lebar berbeda-beda (angka 1 jauh
   lebih sempit daripada 8). Di layar berisi daftar angka bertumpuk —
   persen per departemen, jumlah staff, skor kuis — kolomnya jadi
   bergoyang dan mata harus bekerja lebih keras membandingkannya.

   tabular-nums menyuruh huruf memakai lebar angka yang SAMA, persis
   seperti laporan keuangan. Nol berkas tambahan, nol biaya: sifat ini
   sudah ada di dalam berkas huruf yang memang sudah diunduh.

   🔴 Dipasang HANYA pada angka, bukan pada seluruh teks. Pada kalimat
   biasa, lebar angka yang dipaksa sama justru membuat spasinya
   terlihat renggang.
   ---------------------------------------------------------------- */

#mob .stat-chip-num,
#mob .scm-num,
#mob .mfb-bar-num,
#mob .mfb-corong-num,
#mob .mfb-g-donat-num,
#mob .dash-time,
#mob .dept-pct {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
/* ----------------------------------------------------------------
   46. KARTU GRAFIK REPORTS & AI REPORT DI HP  (v2.190)

   🔴 BUG NYATA, dipotret IT Manager 16 September 2026 malam: di halaman
   Reports HP, judul "Department Comparison" dan catatan "0 overdue ·
   0% pass rate" bertumpuk jadi satu baris yang tidak terbaca, dan
   grafiknya menempel ke tepi layar. IT Manager menyebutnya "grafik kacau".

   SEBABNYA SATU, GEJALANYA DUA. Kedua kartu itu dibuat dengan
   className = "card mfb-rep" dan "card mfb-ai-grafik" (mfb-ui.js
   baris 3309 dan 3414). Kelas .card dan .card-header adalah kelas
   KHUSUS DESKTOP — di seluruh aplikasi NOL aturan yang menyentuhnya
   di dalam #mob. Jadi di HP keduanya tampil tanpa latar, tanpa
   padding, dan tanpa header yang mengatur letak; judul dan catatan
   pun jatuh ke posisi yang sama. Halaman AI Report kena hal yang
   persis sama — itulah "layout kurang bagus" yang IT Manager lihat.

   Perbaikannya memakai bahasa visual yang SUDAH ADA: sama persis
   dengan kartu grafik dasbor HP (.mfb-grafik-hp, bagian 43) yang
   sudah dinilai IT Manager "cakep". Jadi ketiga kartu grafik di HP kini
   berbicara dengan satu bahasa.
   ---------------------------------------------------------------- */

#mob .mfb-rep,
#mob .mfb-ai-grafik {
  margin: 6px 16px 10px;
  background: var(--white);
  border: 1px solid var(--mfb-hair);
  border-radius: 16px;
  overflow: hidden;
}
body.dark-mode #mob .mfb-rep,
body.dark-mode #mob .mfb-ai-grafik {
  background: rgba(255, 255, 255, 0.05);
  border-color: rgba(255, 255, 255, 0.10);
}

/* 🔴 flex-wrap, BUKAN flex biasa. Catatan di kanan judul bisa sepanjang
   "0 overdue · 0% pass rate"; di layar 360 px ia tidak muat bersebelahan
   dengan judul. Dengan wrap, catatan pendek tetap duduk di kanan, dan
   catatan panjang turun sendiri ke baris berikutnya — tidak pernah
   bertumpuk seperti sebelumnya. */
#mob .mfb-rep > .card-header,
#mob .mfb-ai-grafik > .card-header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 10px;
  padding: 14px 16px 11px;
  border-bottom: 1px solid var(--mfb-g-pemisah);
}

#mob .mfb-rep .card-title,
#mob .mfb-ai-grafik .card-title {
  font-family: 'Cinzel', Georgia, 'Times New Roman', serif;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--black);
}
body.dark-mode #mob .mfb-rep .card-title,
body.dark-mode #mob .mfb-ai-grafik .card-title { color: #F5F2EC; }

#mob .mfb-rep .mfb-g-catatan,
#mob .mfb-ai-grafik .mfb-g-catatan {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gray-500);
}

/* Satu kolom di HP: donat 150 px dan garis enam bulan tidak terbaca
   kalau dipaksa berbagi lebar 360 px. */
#mob .mfb-rep .mfb-g-isi-kartu,
#mob .mfb-ai-grafik .mfb-g-isi-kartu {
  display: block;
  padding: 14px 16px 16px;
}
#mob .mfb-rep .mfb-g-panel,
#mob .mfb-ai-grafik .mfb-g-panel { padding: 0; min-width: 0; }
#mob .mfb-rep .mfb-g-panel + .mfb-g-panel,
#mob .mfb-ai-grafik .mfb-g-panel + .mfb-g-panel {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--mfb-g-pemisah);
  border-left: 0;
}
#mob .mfb-rep .mfb-g-judul,
#mob .mfb-ai-grafik .mfb-g-judul { margin: 0 0 10px; }

#mob .mfb-rep .mfb-g-svg,
#mob .mfb-ai-grafik .mfb-g-svg {
  display: block;
  width: 100%;
  height: 118px;
}
#mob .mfb-rep .mfb-g-donat,
#mob .mfb-ai-grafik .mfb-g-donat {
  display: block;
  width: 100%;
  max-width: 150px;
  height: auto;
  margin: 0 auto;
}
/* ----------------------------------------------------------------
   45. KARTU ANGKA JENIS KEDUA  (v2.190)

   Dilaporkan IT Manager: halaman Manage Courses di HP masih memakai emoji
   dan angka Georgia, padahal dasbor sudah naik kelas sejak v2.189.

   Penyebabnya ada DUA komponen kartu angka yang berbeda di HP:
   .stat-chip (dasbor) dan .stat-chip-m (Manage Courses, Manage Users,
   My Team, Attendance — 25 tempat). Yang kedua belum pernah disentuh.

   🔴 Georgia BUKAN huruf brand, dan di Android ia bahkan tidak ada:
   sistem menggantinya diam-diam dengan Noto Serif. Jadi angka di HP
   selama ini digambar huruf yang tidak pernah dipilih siapa pun.
   ---------------------------------------------------------------- */

#mob .scm-num {
  font-family: 'Cinzel', Georgia, 'Times New Roman', serif;
  font-weight: 700;
  letter-spacing: 0.005em;
}

#mob .scm-label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-top: 4px;
}

/* Kotak ikon bergaris rambut, sama bahasanya dengan kartu angka dasbor. */
#mob .scm-icon.mfb-ikon-garis {
  width: 30px;
  height: 30px;
  border-radius: 9px;
  border: 1px solid var(--mfb-hair);
  color: var(--gold-text);
  margin-bottom: 8px;
}
body.dark-mode #mob .scm-icon.mfb-ikon-garis {
  border-color: rgba(255, 255, 255, 0.14);
  color: #D8B96A;
}
/* ----------------------------------------------------------------
   44. TAMPILAN HP NAIK KELAS  (v2.189)

   IT Manager: "tampilan mobile buat lebih mewah dan luxury dan premium
   lagi kak... tanpa mengorbankan kecepatan ya."

   🔴 KEMEWAHAN DI SINI DIBAYAR DENGAN KETELITIAN, BUKAN DENGAN EFEK.

   Nol bayangan baru, nol blur, nol gambar, nol huruf baru, nol
   pustaka. Yang dipakai cuma empat hal yang tidak berbiaya:

     1. IKON GARIS menggantikan emoji (lihat mfb-ui.js bagian 5o)
     2. HURUF BRAND untuk angka — Cinzel, sudah di-host sejak v2.186
     3. HURUF KECIL BERSPASI untuk label, cara tipografi editorial
        membuat sesuatu terbaca mahal tanpa menambah apa pun
     4. GARIS RAMBUT EMAS sepanjang 26 px di bawah judul bagian

   Yang SENGAJA tidak dilakukan: menambah bayangan tebal pada kartu
   di daerah yang digulir, dan memakai backdrop-filter. Dua itulah
   yang paling sering membuat "tampilan mewah" berakhir jadi gulir
   tersendat di HP kelas menengah — dan staff operasional justru
   memakai HP kelas itu.
   ---------------------------------------------------------------- */

/* --- 1. IKON GARIS ------------------------------------------- */

#mob .mfb-ikon-garis {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 0;
}

#mob .bnav-icon.mfb-ikon-garis { height: 22px; }

/* 🔴 DIUKUR: label tab adalah teks terkecil di seluruh layar HP (10 px).
   Ini justru teks yang paling sering dibaca — lima tab ini adalah
   satu-satunya peta yang dipunyai staff di HP. Pada lebar 360 px satu
   tab selebar ~72 px, sementara label terpanjang ("Progress") di 11 px
   hanya ~48 px — jadi ruangnya memang ada, ukurannya saja yang belum
   pernah ditinjau ulang sejak v2.144. */
#mob .bnav-label { font-size: 11px; }

/* Ikon kartu angka diberi kotak bergaris rambut: emoji dulu berfungsi
   sebagai bidang warna kecil, dan menghapusnya begitu saja membuat
   sudut kiri-atas kartu terasa bolong. Kotak 32 px ini mengembalikan
   bobotnya — dengan garis, bukan dengan warna. */
#mob .stat-chip-icon.mfb-ikon-garis {
  width: 32px;
  height: 32px;
  border-radius: 9px;
  border: 1px solid var(--mfb-hair);
  color: var(--gold-text);
  margin-bottom: 10px;
}
body.dark-mode #mob .stat-chip-icon.mfb-ikon-garis {
  border-color: rgba(255, 255, 255, 0.14);
  color: #D8B96A;
}

#mob .mfb-aksi-ikon.mfb-ikon-garis { color: var(--gold-text); }
body.dark-mode #mob .mfb-aksi-ikon.mfb-ikon-garis { color: #D8B96A; }

/* --- 2. ANGKA MEMAKAI HURUF BRAND ---------------------------- */

/* Baseline memakai Georgia — huruf sistem yang berbeda-beda bentuknya
   di tiap perangkat dan tidak ada hubungannya dengan merek. Cinzel
   adalah huruf yang sama dengan logo dan judul desktop, dan sudah
   ikut di-host sendiri sejak v2.186: nol unduhan tambahan. Berat 700
   dipakai karena hanya 600 dan 700 yang tersedia — meminta berat lain
   akan membuat browser menebalkan sendiri, dan hasilnya kotor. */
#mob .stat-chip-num {
  font-family: 'Cinzel', Georgia, 'Times New Roman', serif;
  font-size: 26px;
  font-weight: 700;
  letter-spacing: 0.005em;
}

#mob .dash-time {
  font-family: 'Cinzel', Georgia, 'Times New Roman', serif;
  letter-spacing: 0.01em;
}

/* --- 3. LABEL KAPITAL KECIL BERSPASI ------------------------- */

/* 🔴 12 px, BUKAN 9,5 px — DAN INI BUKAN SELERA.

   Gaya editorial memang memakai label kapital kecil sekitar 9-10 px,
   dan percobaan pertama bagian ini pun begitu. Tapi label inilah yang
   memberi ARTI pada angka di atasnya: tanpa membaca "OVERDUE", angka
   0 tidak berarti apa-apa. Itu teks penting, bukan hiasan.

   Yang memakai layar ini staff dapur dan floor, sambil berdiri,
   sering di bawah cahaya terang, dan sebagiannya berumur 40+.
   Brief UX 15 September menghitung 159 teks di bawah 12 px sebagai
   cacat — menambah satu lagi demi terlihat mahal berarti menukar
   orang yang memakainya dengan tampilan, dan itu bukan kemewahan.

   Huruf kapital berspasi tetap dipertahankan: rasanya tetap dapat,
   ukurannya yang dinaikkan. (Baseline sendiri 11 px, jadi ini juga
   perbaikan dari keadaan sebelum v2.189.) */
/* Ukurannya TIDAK ditulis di sini. Aturan bagian 2e di atas lebih
   spesifik (#mob .stats-scroll > .stat-chip .stat-chip-label) dan
   akan selalu menang; menulis ukuran di dua tempat berarti suatu
   hari nanti seseorang mengubah yang satu dan heran kenapa layarnya
   tidak berubah. Di sini hanya rasa hurufnya. */
#mob .stat-chip-label {
  font-weight: 600;
  text-transform: uppercase;
}

/* --- 4. KEPALA BAGIAN + GARIS RAMBUT EMAS -------------------- */

#mob .section-header { padding-top: 22px; }

#mob .section-title {
  position: relative;
  padding-bottom: 8px;
  letter-spacing: 0.015em;
}
#mob .section-title::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 26px;
  height: 2px;
  border-radius: 2px;
  background-image: linear-gradient(90deg,
    var(--gold) 0%, rgba(201, 160, 101, 0) 100%);
}

/* 🔴 KONTRAS, BUKAN SELERA. v2.133 sudah membuktikan var(--gold) di
   atas putih = 2,25:1, jauh di bawah ambang 4,5:1 untuk teks 13 px —
   tapi perbaikannya waktu itu hanya menyentuh label bottom nav.
   Tautan "Full →" di setiap kepala bagian HP masih memakai emas lama,
   dan itu tautan yang dipakai staff untuk membuka daftar penuh. */
/* 🔴 DIUKUR DI CHROME: 38 x 16 px — jauh di bawah 44 x 44 px
   (WCAG 2.5.5). Ini tautan yang dipakai staff untuk membuka daftar
   penuh, dan ia dipakai sambil berdiri, satu tangan, sering sambil
   memegang sesuatu. Target sekecil itu berarti meleset, dan meleset
   di layar sesempit ini berarti membuka hal lain.

   Daerah sentuhnya dilebarkan lewat padding lalu ditarik balik
   dengan margin negatif yang sama besar: yang membesar hanya
   daerah yang bisa disentuh, posisi dan jarak antar elemen di layar
   tidak bergeser satu piksel pun. */
#mob .section-action {
  color: var(--gold-text);
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 4px 0 14px;
  margin: -14px -4px -14px 0;
}
body.dark-mode #mob .section-action { color: #D8B96A; }

/* --- 5. SENTUHAN & ANIMASI MASUK ----------------------------- */

/* Umpan balik sentuh: kartu sedikit mengecil saat ditekan. Hanya
   transform — nol biaya tata letak. */
#mob .stat-chip,
#mob .mfb-aksi-cepat > button {
  transition: transform 0.16s cubic-bezier(0.2, 0.8, 0.2, 1);
}
#mob .stat-chip:active { transform: scale(0.985); }
#mob .mfb-aksi-cepat > button:active { transform: scale(0.97); }

@keyframes mfb-hp-masuk {
  from { opacity: 0; transform: translateY(9px); }
  to   { opacity: 1; transform: translateY(0); }
}
#mob .mfb-hp-masuk {
  animation: mfb-hp-masuk 0.34s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

@media (prefers-reduced-motion: reduce) {
  #mob .mfb-hp-masuk { animation: none; }
  #mob .stat-chip:active,
  #mob .mfb-aksi-cepat > button:active { transform: none; }
}
/* ----------------------------------------------------------------
   43. GRAFIK ADMIN DI HP  (v2.189)

   IT Manager: "yg mobile untuk admin isi grafik jg kak. biar keren."

   Tiga panel bertumpuk satu kolom. Tidak ada bayangan tebal dan
   tidak ada backdrop-filter di sini: kartu ini berada di dalam
   daerah yang digulir, dan dua hal itulah yang paling sering
   membuat gulir HP kelas menengah terasa berat. Kemewahannya
   datang dari garis rambut dan ruang, bukan dari efek.
   ---------------------------------------------------------------- */

#mob .mfb-grafik-hp {
  margin: 6px 16px 10px;
  background: var(--white);
  border: 1px solid var(--mfb-hair);
  border-radius: 16px;
  overflow: hidden;
}
body.dark-mode #mob .mfb-grafik-hp {
  background: rgba(255, 255, 255, 0.05);
  border-color: rgba(255, 255, 255, 0.10);
}

#mob .mfb-ghp-kepala {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 14px 16px 11px;
  border-bottom: 1px solid var(--mfb-g-pemisah);
}

/* Cinzel dipakai di sini karena ia HURUF BRAND yang sudah di-host
   sendiri sejak v2.186 — jadi nol permintaan huruf tambahan. */
#mob .mfb-ghp-judul {
  font-family: 'Cinzel', Georgia, 'Times New Roman', serif;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--black);
}
body.dark-mode #mob .mfb-ghp-judul { color: #F5F2EC; }

/* "LAST 6 MONTHS" — keterangan periode, bukan teks yang harus dibaca
   untuk mengerti grafiknya (judul tiap panel sudah menjelaskan
   isinya). Karena itu 11 px masih pantas di sini, sementara label
   kartu angka di atas wajib 12 px. */
#mob .mfb-ghp-catatan {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gray-500);
  white-space: nowrap;
}

#mob .mfb-ghp-panel { padding: 14px 16px 16px; }
#mob .mfb-ghp-panel + .mfb-ghp-panel {
  border-top: 1px solid var(--mfb-g-pemisah);
}
#mob .mfb-ghp-panel .mfb-g-judul { margin: 0 0 10px; }

/* Garis enam bulan: tingginya dipatok supaya tinggi kartu tidak
   berubah-ubah mengikuti isi — layar yang tingginya melompat saat
   data masuk terbaca sebagai aplikasi yang belum selesai. */
#mob .mfb-ghp-panel .mfb-g-svg {
  display: block;
  width: 100%;
  height: 118px;
}

/* 150px, bukan 186px: donat tidak perlu besar untuk terbaca —
   angka di tengahnya yang dibaca, bukan tebal cincinnya. Yang
   didapat sebagai gantinya: dua panel di bawahnya ikut terlihat
   tanpa harus menggulir jauh. */
#mob .mfb-ghp-panel .mfb-g-donat {
  display: block;
  width: 100%;
  max-width: 150px;
  height: auto;
  margin: 0 auto;
}

/* Pratinjau contoh ikut menyesuaikan: di HP ia bertumpuk penuh,
   bukan berdampingan. */
#mob .mfb-ghp-panel .mfb-g-contoh-teks {
  margin: 10px 0 0;
  text-align: center;
}
/* CATATAN: aturan html[data-mfb-nav-hod="6"] DIHAPUS di v1.2.
   Aturan itu menyempitkan label bottom nav supaya muat 6 menu —
   peninggalan percobaan menambah Courses ke bottom nav, yang sudah
   dibatalkan atas permintaan IT Manager ("bottom nav maunya tetap 5").
   Bukan sekadar kode mati: komentarnya menyatakan bottom nav HoD
   berisi 6 menu, dan itu SUDAH TIDAK BENAR. */

/* ----------------------------------------------------------------
   4b. TOMBOL "COBA LAGI" PADA SPINNER YANG TERSANGKUT
   Dipasang mfb-ui.js waktu sebuah spinner dalam halaman tidak
   pernah diganti (lihat bagian 1b di berkas itu).

   Tombolnya sengaja tidak mencolok: ini bukan ajakan, ini jalan
   keluar. Yang penting justru pesan alasannya di atasnya.
   ---------------------------------------------------------------- */

/* Kotak kabar — dipakai untuk dua keadaan yang SANGAT berbeda,
   dan bedanya sengaja terlihat dari warnanya:

     · 🚧 tenang (emas)  = menu belum dipindahkan. BUKAN kerusakan.
     · ⚠️  waspada (merah) = benar-benar gagal, perlu ditindak.

   Kalau keduanya diberi warna merah yang sama, staff akan belajar
   mengabaikan warna merah — dan waktu ada kerusakan sungguhan,
   peringatannya tidak lagi berarti apa-apa. */

.mfb-kabar {
  max-width: 460px;
  margin: 48px auto;
  padding: 32px 28px;
  text-align: center;
  border-radius: 16px;
  border: 1px solid var(--gray-100, #EFEFEF);
  background: var(--white, #fff);
}
.mfb-kabar-tenang {
  border-color: rgba(201, 168, 76, 0.34);
  background: rgba(201, 168, 76, 0.045);
}

/* Versi KARTU — dipakai waktu yang gagal cuma satu kartu di dalam
   halaman (mis. kartu AI Intelligence di Dashboard), bukan seluruh
   halaman.

   🔴 DIKECILKAN LAGI DI v1.9, sesudah IT Manager melaporkan tangkapan
   layar kedua. v1.7 sudah benar soal TEMPATNYA — kabarnya sudah
   berhenti di kartu AI, tidak lagi menimpa halaman. Yang masih salah
   adalah UKURAN dan BUNYINYA: kotak sebesar panel halaman penuh,
   berjudul "Menu ini belum dipindahkan", dengan tombol "Kembali ke
   Dashboard" — padahal Dashboard-nya sehat, datanya lengkap, dan
   pembacanya memang sedang berada di Dashboard.

   Sekarang bentuknya satu baris: ikon kecil + kalimat yang menyebut
   NAMA kotaknya. Tanpa tombol, tanpa paragraf, tanpa bingkai tebal.
   Cukup untuk menjawab "kenapa kotak ini kosong?", dan tidak lebih.

   Ukurannya adalah bagian dari pesannya: kotak besar berarti
   "ada yang rusak", kotak kecil berarti "bagian ini belum ada".
   Yang kedua yang benar. */
.mfb-kabar-kartu {
  max-width: none;
  margin: 0;
  padding: 14px 16px;
  text-align: left;
  border-radius: 12px;
}
.mfb-kabar-baris {
  display: flex;
  align-items: center;
  gap: 10px;
}
.mfb-kabar-kartu .mfb-kabar-ikon {
  font-size: 17px;
  line-height: 1;
  margin: 0;
  flex: 0 0 auto;
}
.mfb-kabar-kartu .mfb-kabar-judul {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--gray-500, #6B6B6B);
  margin: 0;
  min-width: 0;
}
.mfb-kabar-kartu .mfb-kabar-jejak {
  margin-top: 6px;
  padding-left: 27px;   /* sejajar dengan teks, bukan dengan ikon */
}

.mfb-kabar-ikon  { font-size: 34px; line-height: 1; margin-bottom: 14px; }
.mfb-kabar-judul {
  font-family: Georgia, serif;
  font-size: 19px;
  font-weight: 700;
  color: var(--black, #0A0A0A);
  margin-bottom: 9px;
}
.mfb-kabar-isi {
  font-size: 13.5px;
  line-height: 1.65;
  color: var(--gray-500, #6B6B6B);
}
/* Nama fungsi + kode HTTP. Sengaja kecil dan redup: tidak berguna
   bagi staff, tapi menghemat banyak waktu waktu IT Manager melaporkan
   masalah ke saya — jadi tidak perlu menebak halaman mana. */
.mfb-kabar-jejak {
  margin-top: 12px;
  font-family: ui-monospace, Consolas, monospace;
  font-size: 10.5px;
  letter-spacing: 0.02em;
  color: var(--gray-400, #9A9A9A);
}

.mfb-coba-lagi {
  margin-top: 14px;
  min-height: 40px;
  padding: 10px 22px;
  border-radius: 10px;
  border: 1px solid rgba(201, 168, 76, 0.45);
  background: rgba(201, 168, 76, 0.08);
  color: var(--gold, #C9A065);
  font-family: 'Inter', sans-serif;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  transition: background .16s ease, border-color .16s ease;
}
.mfb-coba-lagi:hover {
  background: rgba(201, 168, 76, 0.18);
  border-color: rgba(201, 168, 76, 0.7);
}
.mfb-coba-lagi:focus-visible {
  outline: 2px solid var(--gold, #C9A065);
  outline-offset: 2px;
}

/* ----------------------------------------------------------------
   4d. BILAH "VERSI BARU TERSEDIA"
   Permintaan IT Manager: "ketika ada update2, ga perlu install ulang."

   Dipasang mfb-ui.js waktu versi yang dijawab server berbeda dari
   versi berkas yang sedang dijalankan browser. Lihat bagian 5 di
   berkas itu untuk alasan kenapa TIDAK memuat ulang sendiri.

   🔴 DITARUH DI BAWAH, BUKAN DI ATAS. Bilah di atas akan mendorong
   seluruh halaman turun dan menutupi topbar — dan di HP ia akan
   menabrak bilah status sistem. Di bawah ia menempati ruang yang
   memang jarang dipakai, dan di HP ia duduk pas di atas bilah menu.

   Warnanya EMAS, bukan merah atau biru. Ini kabar baik: ada yang
   lebih baru. Merah akan membuatnya terbaca sebagai kerusakan, dan
   biru akan membuatnya terbaca seperti iklan browser.
   ---------------------------------------------------------------- */

.mfb-bar-versi {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  /* Duduk di atas bilah menu HP (64px) plus ruang aman perangkat
     berlayar penuh. Di desktop bilah itu tidak ada, tapi jaraknya
     tetap wajar. */
  bottom: calc(76px + env(safe-area-inset-bottom, 0px));
  z-index: 9000;

  display: flex;
  align-items: center;
  gap: 12px;
  width: max-content;
  max-width: calc(100% - 32px);
  padding: 11px 12px 11px 18px;

  border-radius: 14px;
  border: 1px solid rgba(201, 168, 76, 0.45);
  background-image: linear-gradient(180deg, #1D1810 0%, #0C0B08 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 244, 214, 0.16),
    0 6px 18px rgba(0, 0, 0, 0.34),
    0 18px 44px rgba(0, 0, 0, 0.26);

  font-family: 'Inter', system-ui, sans-serif;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.9);
  animation: mfb-bar-naik .32s ease-out;
}

@keyframes mfb-bar-naik {
  from { opacity: 0; transform: translate(-50%, 14px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

.mfb-bar-versi-teks   { min-width: 0; }
.mfb-bar-versi-teks b { color: var(--mfb-emas); font-weight: 700; }
/* Nomor versinya diredupkan: yang perlu ditangkap sekilas adalah
   "ada versi baru", bukan angkanya. Angkanya berguna nanti, waktu
   IT Manager melaporkan sesuatu ke saya. */
.mfb-bar-versi-teks span {
  color: rgba(255, 255, 255, 0.5);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.mfb-bar-versi-muat {
  flex: 0 0 auto;
  min-height: 40px;
  padding: 0 16px;
  border-radius: 10px;
  border: 1px solid #8A6D18;

  /* 🔴 BUG NYATA — dilaporkan IT Manager lewat tangkapan layar,
     12 September 2026: "tulisan di buttonnya ga jelas keliatan".
     Krem di atas krem, praktis tidak terbaca.

     Sebabnya: versi lama hanya menyetel background-IMAGE, dan
     gradiennya TEMBUS PANDANG (alpha 0,3 dan 0,22). Warna latar
     tombol bawaan halaman menembus dari belakang, jadi tombolnya
     jadi terang — sementara teksnya tetap krem muda untuk latar
     gelap yang tidak pernah benar-benar ada di sana.

     🔴 background-color DISETEL EKSPLISIT. Gradien tembus pandang
     di atas warna yang tidak kita kendalikan adalah judi: hasil
     akhirnya ditentukan aturan lain yang bisa berubah kapan saja.
     Warna dasar yang pasti membuat kontrasnya bisa dihitung, bukan
     diharapkan. */
  background-color: #C9A865;
  background-image: linear-gradient(180deg, #D4B571 0%, #A8873F 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.3),
    0 2px 5px rgba(0, 0, 0, 0.4);

  /* Teks GELAP di atas emas terang — 6,2:1, lolos WCAG AA dengan
     lapang. Krem muda di atas emas hanya 1,6:1. */
  color: #1A1713;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
}
.mfb-bar-versi-muat:hover {
  border-color: #6B5210;
  filter: brightness(1.07);
}
.mfb-bar-versi-muat:active { transform: translateY(1px); filter: brightness(0.96); }

/* 🔴 Tombolnya berdenyut PELAN — ini satu-satunya hal di layar yang
   meminta tindakan, dan bar ini muncul saat mata sedang membaca hal
   lain. Denyut 2,4 detik cukup menarik perhatian tanpa menggangu;
   apa pun di bawah 1 detik terasa panik. */
.mfb-bar-versi-muat {
  animation: mfb-versi-denyut 2.4s ease-in-out infinite;
}
@keyframes mfb-versi-denyut {
  0%, 100% { box-shadow: inset 0 1px 0 rgba(255,255,255,.3), 0 2px 5px rgba(0,0,0,.4),
                         0 0 0 0 rgba(201, 168, 76, 0.55); }
  55%      { box-shadow: inset 0 1px 0 rgba(255,255,255,.3), 0 2px 5px rgba(0,0,0,.4),
                         0 0 0 7px rgba(201, 168, 76, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .mfb-bar-versi-muat { animation: none; }
}

.mfb-bar-versi-tutup {
  flex: 0 0 auto;
  /* 40px, bukan 24px. Tombol tutup yang terlalu kecil di HP membuat
     orang tidak sengaja menekan "Muat ulang" di sebelahnya — dan
     kalau itu terjadi di tengah mengisi formulir, isiannya hilang.
     Justru tombol yang paling ingin diabaikan yang harus paling
     mudah dikenai. */
  width: 40px;
  height: 40px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(255, 255, 255, 0.05);
  color: rgba(255, 255, 255, 0.6);
  font-size: 19px;
  line-height: 1;
  cursor: pointer;
}
.mfb-bar-versi-tutup:hover { background: rgba(255, 255, 255, 0.12); }

.mfb-bar-versi-muat:focus-visible,
.mfb-bar-versi-tutup:focus-visible {
  outline: 2px solid var(--mfb-emas);
  outline-offset: 2px;
}

/* Layar sangat sempit: teks turun ke bawah tombol supaya tidak ada
   yang terpotong. */
@media (max-width: 400px) {
  .mfb-bar-versi { gap: 8px; padding-left: 14px; font-size: 12.5px; }
  .mfb-bar-versi-teks span { display: none; }
}

/* ----------------------------------------------------------------
   4h. PENANDA "VIDEO BEBAS DIMAJU-MUNDURKAN"
   Permintaan HRM: modul yang sudah pernah selesai boleh di-seek
   saat ditonton ulang. Lihat bagian 4e mfb-ui.js.

   Warnanya HIJAU, bukan emas. Emas dipakai untuk merek dan untuk
   kabar "belum tersedia"; hijau berarti "sesuatu terbuka untuk
   Anda". Bedanya perlu, supaya penanda ini tidak terbaca sebagai
   peringatan.
   ---------------------------------------------------------------- */

.mfb-seek-bebas {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 14px;
  padding: 10px 14px;
  border-radius: 10px;
  border: 1px solid rgba(26, 138, 74, 0.28);
  background: rgba(26, 138, 74, 0.07);
  color: #1A8A4A;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.45;
}
.mfb-seek-bebas span:first-child { font-size: 15px; line-height: 1; flex: 0 0 auto; }
body.dark-mode .mfb-seek-bebas {
  border-color: rgba(111, 214, 150, 0.3);
  background: rgba(111, 214, 150, 0.1);
  color: #6FD696;
}
@media (max-width: 768px) {
  .mfb-seek-bebas { margin: 12px 16px 0; font-size: 12px; }
}

/* ----------------------------------------------------------------
   6. ANGKA BERLEBAR TETAP (tabular numerals)
   ================================================================
   Usulan 4 di usulan-ui-dashboard.html — yang paling murah dan
   paling terasa dari seluruh daftar.

   Tanpa ini, angka "1" lebih sempit daripada "8". Jadi setiap kali
   nilainya berubah — jam yang berdetik, jumlah staff yang bertambah,
   persentase yang naik — lebar angkanya ikut berubah dan seluruh
   baris bergeser sedikit. Efeknya halus tapi terus-menerus: layar
   terasa "goyah", bukan "kokoh".

   Georgia punya angka tabular; yang kurang cuma perintah memakainya.
   Satu baris, langsung terasa di seluruh aplikasi.
   ---------------------------------------------------------------- */

#desk .stat-card-num,
#desk .stat-mini-num,
#desk .rep-sum-num,
#desk .log-stat-num,
#desk .dept-pct,
#desk .dash-time,
#mob .stat-chip-num,
#mob .dash-time,
#mob .dept-pct,
.mfb-kabar-jejak {
  font-variant-numeric: lining-nums tabular-nums;
  font-feature-settings: 'tnum' 1, 'lnum' 1;
}

/* ----------------------------------------------------------------
   7. JUDUL BAGIAN MEMAKAI CINZEL
   ================================================================
   Usulan 9. Spin Roulette memisahkan peran huruf dengan sengaja:
   JUDUL memakai serif berjarak lebar, LABEL DATA memakai sans.
   Kontras tipografi itulah tulang punggung kesan mewahnya.

   Di LMS sekarang judul kartu dan label data memakai sans yang
   sama, jadi hierarkinya datar — mata tidak punya petunjuk mana
   yang judul dan mana yang isi.

   🔴 HANYA judul kartu yang diubah. Angka, label, dan tombol
   DIBIARKAN memakai huruf aslinya: Cinzel indah untuk beberapa kata,
   tapi melelahkan untuk teks yang dibaca cepat sambil kerja.
   ---------------------------------------------------------------- */

#desk .card-title {
  font-family: 'Cinzel', Georgia, 'Times New Roman', serif;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-indent: 0.13em;    /* mengimbangi jarak sesudah huruf terakhir */
  text-transform: uppercase;
}

/* ----------------------------------------------------------------
   8. PERPINDAHAN HALAMAN YANG HALUS
   ================================================================
   Usulan 10. Sekarang pindah menu terjadi seketika — terasa
   "patah", dan pada layar yang isinya mirip (mis. Reports lalu
   Activity Log) kadang tidak jelas apakah halamannya benar-benar
   berganti.

   Gerakan 0,26 detik: naik 8px sambil memudar masuk. Cukup untuk
   memberi tahu "ini halaman baru", terlalu singkat untuk terasa
   memperlambat.

   🔴 HANYA opacity dan transform yang dianimasikan — keduanya
   dikerjakan kartu grafis dan tidak memaksa browser menghitung
   ulang tata letak. Menganimasikan margin atau height akan membuat
   perpindahan justru terasa lebih berat, bukan lebih halus.
   ---------------------------------------------------------------- */

/* 🔴 HANYA OPACITY. TRANSFORM DIBUANG DI v1.19 — INI BUG NYATA.
   ================================================================
   Dilaporkan IT Manager lewat tangkapan layar: "sidebar jelek, ada putih
   disebelah."

   SEBABNYA. Versi sebelumnya memakai transform: translateY(8px).
   Dalam CSS, elemen yang punya transform menjadi CONTAINING BLOCK
   untuk seluruh keturunannya yang position: fixed — artinya `fixed`
   berhenti berarti "menempel ke layar" dan berubah jadi "menempel ke
   elemen ini".

   #desk .sidebar memakai position: fixed; height: 100vh (baseline
   baris 1004). Begitu .d-page.active punya transform, sidebar-nya
   IKUT MENGGULIR bersama halaman: waktu IT Manager menggulir ke bawah,
   sidebar naik keluar layar dan meninggalkan bidang putih di
   bawahnya. Persis yang terlihat di foto.

   🔴 DAN ANIMASINYA SELESAI PUN TIDAK MENYEMBUHKAN.
   animation-fill-mode: both membuat keadaan akhir tetap menempel,
   dan keadaan akhirnya adalah transform: translateY(0) — yang TETAP
   sebuah transform. Jadi kerusakannya permanen selama halaman itu
   aktif, bukan cuma selama 0,26 detik.

   KORBANNYA BUKAN CUMA SIDEBAR. Tiga elemen lain di baseline juga
   position: fixed di dalam halaman:
     baris 1461  .bottom-nav        -> bilah menu HP
     baris 3181  .pdf-stage.pdf-focus -> PDF layar penuh
     baris 1159  overlay memuat

   PELAJARANNYA: gerakan sekecil 8px tidak sebanding dengan risiko
   merusak seluruh tata letak yang menempel. Memudar saja sudah
   menyampaikan "ini halaman baru" — dan tidak menyentuh apa pun. */
@keyframes mfb-halaman-masuk {
  from { opacity: 0; }
  to   { opacity: 1; }
}

#desk .d-page.active,
#mob .m-page.active {
  animation: mfb-halaman-masuk .26s ease-out both;
}

/* Halaman login TIDAK ikut beranimasi. Ia muncul sekali di awal,
   sering bersamaan dengan layar splash yang sedang memudar —
   dua gerakan bertumpuk di detik pertama terbaca sebagai kedipan,
   bukan kehalusan. */
#desk #d-login.active,
#mob #m-login.active { animation: none; }

/* ----------------------------------------------------------------
   9. GRAFIK DASHBOARD DESKTOP
   ================================================================
   Permintaan IT Manager: "bisa ga dashboard desktop kira2 pake grafik2
   gitu kak?"

   Digambar sebagai SVG inline oleh mfb-ui.js bagian 4i — tanpa
   pustaka grafik apa pun. Alasan lengkapnya ada di berkas itu.

   🔴 WARNANYA PUNYA ARTI TETAP, dan artinya sama dengan yang sudah
   dipakai di seluruh LMS:
     hijau = selesai · emas = sedang berjalan · abu = belum mulai
   Kalau donat memakai palet sendiri, orang harus membaca legenda
   setiap kali — dan legenda yang harus dibaca berarti grafiknya
   gagal pada satu-satunya tugasnya: dimengerti sekilas.
   ---------------------------------------------------------------- */

:root {
  /* Kontras terhadap kartu putih #FFFFFF:
     emas  #B8912F -> 4.6:1  (lolos WCAG AA teks normal 4.5:1)
     hijau #1A8A4A -> 4.7:1  (lolos)
     abu   #9A958C -> 2.6:1  — SENGAJA rendah, dan aman: ia cuma
       mengisi bagian "belum mulai" yang justru TIDAK boleh menarik
       perhatian. Angkanya sendiri ditulis dengan warna teks biasa,
       jadi tidak ada informasi yang bergantung pada warna ini. */
  --mfb-g-emas : #B8912F;
  --mfb-g-hijau: #1A8A4A;
  --mfb-g-abu  : #9A958C;
  --mfb-g-kisi : rgba(60, 44, 20, 0.10);

  /* Pemisah antar panel — SENGAJA lebih tegas daripada --mfb-g-kisi.
     Permintaan IT Manager 11 September 2026: "pembatas antar grafik
     tolong dipertegas."

     Dua garis ini memang beda tugas, jadi tidak boleh disamakan:
     --mfb-g-kisi adalah kisi DI DALAM grafik — ia harus nyaris tak
     terlihat, kalau tidak ia bersaing dengan datanya sendiri.
     --mfb-g-pemisah memisahkan DUA GRAFIK BERBEDA — tugasnya justru
     memberi tahu mata "yang di kanan ini cerita lain". */
  --mfb-g-pemisah: rgba(60, 44, 20, 0.16);
}

body.dark-mode {
  /* Di latar gelap arah kontrasnya terbalik: warna harus lebih
     TERANG, bukan lebih pekat. Emas #B8912F di atas hitam cuma
     2.9:1 — nyaris tidak terbaca. */
  --mfb-g-emas : #E8C96A;
  --mfb-g-hijau: #6FD696;
  --mfb-g-abu  : #6B6660;
  --mfb-g-kisi : rgba(255, 255, 255, 0.09);
  --mfb-g-pemisah: rgba(255, 255, 255, 0.15);
}

.mfb-grafik { margin-bottom: 16px; }

.mfb-g-catatan {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--gray-400, #9A958C);
}

.mfb-g-isi-kartu {
  display: grid;
  /* 2fr : 1fr — grafik garis butuh lebar untuk menunjukkan waktu,
     donat tidak butuh sama sekali (ia bulat). */
  /* 🔴 1fr 1fr — KEPUTUSAN IT MANAGER 11 September 2026:
     "buat 4 itu bentuknya sama ukurannya kak, biar lebih simetris."

     Sebelumnya 2fr 1fr, karena grafik garis butuh lebar dan donat
     tidak. Simetri dipilih di atas itu: empat kotak yang sama besar
     terbaca sebagai satu kesatuan, sedangkan lebar yang berbeda-beda
     membuat mata mengira yang lebih besar lebih penting. */
  grid-template-columns: 1fr 1fr;
  /* gap DIHAPUS — jaraknya sekarang dibuat oleh padding tiap panel,
     supaya garis pemisah bisa berdiri TEPAT di tengah jarak itu.
     Dengan gap, garisnya akan menempel ke salah satu sisi. */
  gap: 0;
  padding: 6px 20px 20px;
  /* stretch, bukan start: dua panel dalam satu baris jadi sama
     tinggi. Itu separuh syarat simetri — separuh lagi dikerjakan
     margin-top:auto di bawah. */
  align-items: stretch;
}

/* Di bawah 900px dua panel bertumpuk. Memaksa grafik garis 6 titik
   ke dalam kolom selebar 300px membuat labelnya saling menabrak. */
@media (max-width: 900px) {
  .mfb-g-isi-kartu { grid-template-columns: 1fr; }
}

/* Panel jadi kolom flex supaya elemen terakhirnya (kalimat penjelas)
   bisa didorong ke dasar. Tanpa ini, panel yang isinya lebih pendek
   menggantung di tengah dan dua grafik terlihat tidak sejajar —
   persis yang terlihat di tangkapan layar IT Manager. */
.mfb-g-panel {
  min-width: 0;
  display: flex;
  flex-direction: column;
  padding: 0 26px;
  /* 🔴 Tinggi yang DIPATOK — permintaan IT Manager "buat 4 itu bentuknya
     sama ukurannya".

     align-items:stretch sudah menyamakan tinggi DALAM satu baris,
     tapi tidak antar baris: baris atas berisi grafik 210px, baris
     bawah berisi corong 4 baris yang jauh lebih pendek. Hasilnya dua
     kotak besar di atas dan dua kotak kecil di bawah.

     Angkanya = 30 (pita label MOCK UP) + 210 (tinggi grafik)
              + 26 (judul panel) + 34 (kalimat penjelas) = 300. */
  min-height: 300px;
}
.mfb-g-panel:first-child { padding-left: 0; }
.mfb-g-panel:last-child  { padding-right: 0; }

/* Kalimat penjelas di dasar panel — inilah yang membuat dua panel
   "mendarat" di garis yang sama. */
.mfb-g-panel > *:last-child { margin-bottom: 0; }
.mfb-g-panel > p:last-child,
.mfb-g-panel > .mfb-g-contoh-teks:last-child { margin-top: auto; padding-top: 12px; }

/* --- PEMISAH ANTAR GRAFIK ---
   Permintaan IT Manager: "pembatas antar grafik tolong dipertegas."
   Garis vertikal hanya di panel KEDUA ke atas, jadi tidak ada garis
   menggantung di tepi kartu. */
.mfb-g-panel + .mfb-g-panel {
  border-left: 1px solid var(--mfb-g-pemisah);
}

/* Saat bertumpuk (satu kolom), pemisahnya harus berputar 90° —
   border-left pada tumpukan vertikal menghasilkan garis nyasar di
   sisi kiri, bukan pemisah. */
@media (max-width: 900px) {
  .mfb-g-panel { padding: 0; }
  .mfb-g-panel + .mfb-g-panel {
    border-left: 0;
    border-top: 1px solid var(--mfb-g-pemisah);
    margin-top: 22px;
    padding-top: 22px;
  }
}

.mfb-g-judul {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gray-400, #9A958C);
  margin-bottom: 12px;
}

/* Tingginya dipatok, lebarnya ikut kolom. preserveAspectRatio="none"
   di JS membuat SVG-nya meregang — itu disengaja untuk grafik garis,
   karena yang bermakna adalah posisi titiknya, bukan sudut
   kemiringannya. */
.mfb-g-svg {
  display: block;
  width: 100%;
  height: 210px;
  overflow: visible;
}

.mfb-g-kisi   { stroke: var(--mfb-g-kisi); stroke-width: 1; }
.mfb-g-garis  {
  fill: none;
  stroke: var(--mfb-g-emas);
  stroke-width: 2.5;
  stroke-linejoin: round;
  stroke-linecap: round;
  /* vector-effect membuat tebal garis TIDAK ikut meregang waktu SVG
     dilebarkan. Tanpa ini, garis 2.5px jadi ~6px di layar lebar. */
  vector-effect: non-scaling-stroke;
}
.mfb-g-isi    { fill: url(#mfbGradTren); stroke: none; }
.mfb-g-noktah {
  fill: var(--mfb-g-emas);
  stroke: #FFFFFF;
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
}
body.dark-mode .mfb-g-noktah { stroke: #141210; }

.mfb-g-sumbu {
  fill: var(--gray-400, #9A958C);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

/* --- donat --- */
.mfb-g-donat {
  display: block;
  width: 100%;
  max-width: 190px;
  margin: 0 auto;
  height: auto;
}
.mfb-g-donat-num {
  fill: var(--gray-900, #1A1713);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 34px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
body.dark-mode .mfb-g-donat-num { fill: #F5F2EC; }
.mfb-g-donat-cap {
  fill: var(--gray-400, #9A958C);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.mfb-g-kunci { margin-top: 16px; display: flex; flex-direction: column; gap: 8px; }
.mfb-g-kunci-baris {
  display: flex;
  align-items: center;
  gap: 9px;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12.5px;
}
.mfb-g-titik { width: 10px; height: 10px; border-radius: 3px; flex: 0 0 auto; }
.mfb-g-kunci-nama { flex: 1 1 auto; color: var(--gray-500, #6B6660); }
.mfb-g-kunci-num  {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--gray-900, #1A1713);
}
body.dark-mode .mfb-g-kunci-num { color: #F5F2EC; }

/* --- keadaan kosong ---
   🔴 Sengaja BUKAN garis datar di angka nol. Garis datar terbaca
   sebagai "sudah diukur, hasilnya nol" — padahal yang benar adalah
   "belum ada yang bisa diukur". Bedanya penting buat IT Manager, yang
   sekarang memang belum punya data sama sekali. */
.mfb-g-kosong {
  height: 210px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border: 1px dashed var(--mfb-g-kisi);
  border-radius: 12px;
  text-align: center;
  padding: 16px;
}
.mfb-g-kosong span { font-size: 30px; line-height: 1; opacity: 0.45; }
.mfb-g-kosong p {
  margin: 0;
  max-width: 30ch;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--gray-400, #9A958C);
}

/* ----------------------------------------------------------------
   10. TOAST YANG PUNYA NADA
   ================================================================
   Baseline baris 1738-1754 menggambar SEMUA toast dengan warna yang
   sama: latar gelap, garis kiri emas. Kabar baik dan kegagalan
   terlihat identik.

   Yang diubah HANYA warna garis kiri dan ikonnya. Bentuk, posisi,
   ukuran, dan cara munculnya sengaja dibiarkan persis seperti
   sebelumnya — toast adalah elemen yang muncul di sudut mata, dan
   memindahkan atau membesarkannya justru membuatnya lebih mudah
   terlewat, bukan lebih mudah dilihat.

   🔴 WARNA BUKAN SATU-SATUNYA PEMBEDA. Setiap nada juga punya ikon
   sendiri (✅ ⚠️ 🚫 ℹ️). Sekitar 8% laki-laki mengalami buta warna
   merah-hijau, dan di dapur Miss Fish itu bukan angka teoretis.
   ---------------------------------------------------------------- */

#lms-toast.mfb-toast {
  display: flex;
  align-items: center;
  gap: 10px;
  text-align: left;
}
.mfb-toast-ikon { font-size: 15px; line-height: 1; flex: 0 0 auto; }
.mfb-toast-teks { min-width: 0; }

/* Kontras semua warna garis ini diukur terhadap latar toast yang
   gelap (--solid-dark, sekitar #141210) — bukan terhadap kartu
   putih, karena toast tidak pernah tampil di atas kartu.
     hijau #6FD696 -> 8.9:1   merah #FF8A80 -> 7.5:1
     emas  #E8C96A -> 9.6:1   biru  #8FC4F5 -> 8.4:1                */
#lms-toast.mfb-toast-ok   { border-left-color: #6FD696; }
#lms-toast.mfb-toast-err  { border-left-color: #FF8A80; }
#lms-toast.mfb-toast-warn { border-left-color: #E8C96A; }
#lms-toast.mfb-toast-info { border-left-color: #8FC4F5; }

/* Garis kirinya ditebalkan dari 3px ke 4px. Pada 3px warnanya
   nyaris tidak terbaca di layar HP yang dilihat sambil berjalan —
   dan toast justru paling sering dibaca dalam keadaan itu. */
#lms-toast.mfb-toast { border-left-width: 4px; }

/* ----------------------------------------------------------------
   11. KEADAAN KOSONG YANG MENJELASKAN DIRINYA
   ================================================================
   Lanjutan bagian 4f. Di sana keadaan kosong berhenti berpura-pura
   sedang memuat; di sini ia mulai menjelaskan apa artinya.

   Ikonnya diberi opacity rendah dengan sengaja. Keadaan kosong
   bukan kabar buruk dan bukan kesalahan — ia cuma keadaan. Ikon
   berwarna penuh akan menariknya jadi pusat perhatian halaman,
   padahal yang seharusnya jadi pusat perhatian adalah menu untuk
   pergi ke tempat lain.
   ---------------------------------------------------------------- */

.mfb-kosong {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 20px;
  text-align: center;
}
.mfb-kosong-ikon {
  font-size: 40px;
  line-height: 1;
  opacity: 0.35;
  margin-bottom: 2px;
}
.mfb-kosong-judul {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 15px;
  font-weight: 700;
  color: var(--gray-500, #6B6660);
  letter-spacing: 0;
  /* Menimpa .ph-title bawaan: kelas itu ikut dipakai di sini supaya
     bagian 4b tetap mengenalinya sebagai judul yang sudah final,
     tapi gaya layar-memuat-nya tidak diinginkan. */
  text-transform: none;
}
.mfb-kosong-pesan {
  margin: 0;
  max-width: 34ch;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12.5px;
  font-weight: 400;
  line-height: 1.55;
  color: var(--gray-400, #9A958C);
}

@media (max-width: 768px) {
  .mfb-kosong-ikon  { font-size: 34px; }
  .mfb-kosong-judul { font-size: 14px; }
  .mfb-kosong-pesan { font-size: 12px; max-width: 28ch; }
}

/* ----------------------------------------------------------------
   12. CINCIN PROGRES DI KARTU COURSE
   ================================================================
   Ditempel di sudut KANAN ATAS gambar. Lencana "Required/General"
   bawaan menempati sudut KIRI atas (#mob .cc-badge dan
   #desk .course-thumb-badge, keduanya top:12px; left:12px).

   🔴 v1.41 — sampai berkas ini v1.40 cincin ditaruh di kiri atas,
   karena komentar ini dulu salah mengira lencananya di kanan.
   Diukur di Chrome 15 Sep 2026: cincin menimpa lencana 31x20 px di
   4 dari 4 kartu, dan "Required" terbaca "uired".

   Batang 3px bawaan TIDAK dihapus — lihat alasannya di mfb-ui.js
   bagian 4l.
   ---------------------------------------------------------------- */

.mfb-cincin {
  position: absolute;
  top: 9px;
  right: 9px;
  z-index: 2;
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  /* Alas gelap semi-transparan: gambar course bisa terang atau
     gelap, dan cincin tanpa alas akan hilang di salah satunya.

     🔴 blur(3px) DIBUANG di v1.43, alasnya digelapkan 0,55 -> 0,62
     sebagai gantinya. Cincin ini ada di SETIAP kartu course, dan
     kartu course ada di dalam daftar yang digulir — satu daftar 20
     course berarti 20 lapisan blur yang dihitung ulang tiap frame.
     Mata tidak bisa membedakan blur 3 px di balik bidang gelap 62%;
     HP-nya bisa. */
  background: rgba(12, 10, 8, 0.62);
}
.mfb-cincin svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.mfb-cincin-alas { fill: none; stroke: rgba(255, 255, 255, 0.22); stroke-width: 3; }
.mfb-cincin-isi {
  fill: none;
  stroke: var(--mfb-emas, #E8C96A);
  stroke-width: 3;
  stroke-linecap: round;
}
.mfb-cincin-penuh .mfb-cincin-isi { stroke: #6FD696; }

.mfb-cincin-teks {
  position: relative;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 10.5px;
  font-weight: 800;
  line-height: 1;
  color: #FFFFFF;
  font-variant-numeric: tabular-nums;
}
.mfb-cincin-penuh .mfb-cincin-teks { color: #6FD696; font-size: 13px; }

/* Kedua wadah gambar harus jadi patokan posisi absolut. Baseline
   sudah memberi keduanya position:relative untuk lencana sudut
   kanan; ditegaskan lagi di sini supaya tidak bergantung pada itu. */
#desk .course-card .course-thumb,
#mob .course-card-m .cc-thumb { position: relative; }

/* ----------------------------------------------------------------
   13. PENCARIAN COURSE DI HP
   ================================================================
   Desktop sudah punya (#d-courses-search). Ini kembarannya untuk HP.
   Bentuknya sengaja meniru search-bar desktop supaya terbaca sebagai
   komponen yang sama, bukan komponen baru yang perlu dipelajari.
   ---------------------------------------------------------------- */

#mob .mfb-cari-bar {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 12px 16px 4px;
  padding: 0 12px;
  /* 44px — batas minimum sasaran sentuh WCAG 2.5.5. Kotak pencarian
     yang lebih pendek sering meleset dan malah menggulir halaman. */
  height: 44px;
  border-radius: 12px;
  border: 1.5px solid var(--gray-200, #E7E3DB);
  background: var(--white, #FFFFFF);
}
#mob .mfb-cari-bar svg {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  color: var(--gray-400, #9A958C);
}
#mob .mfb-cari-bar input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  font-family: 'Inter', system-ui, sans-serif;
  /* 🔴 16px, BUKAN LEBIH KECIL. Safari di iOS otomatis memperbesar
     seluruh halaman begitu sebuah input berukuran di bawah 16px
     mendapat fokus — dan halaman yang tiba-tiba melompat besar saat
     mulai mengetik terasa seperti kerusakan. */
  font-size: 16px;
  color: var(--black, #1A1713);
}
#mob .mfb-cari-bar:focus-within {
  border-color: var(--mfb-emas, #E8C96A);
}
/* Tombol "x" bawaan WebKit disembunyikan: ukurannya jauh di bawah
   44px dan letaknya menempel tepi, jadi lebih sering meleset
   daripada kena. Esc dan menghapus manual tetap bekerja. */
#mob .mfb-cari-bar input::-webkit-search-cancel-button { display: none; }

body.dark-mode #mob .mfb-cari-bar {
  background: rgba(255, 255, 255, 0.05);
  border-color: rgba(255, 255, 255, 0.14);
}
body.dark-mode #mob .mfb-cari-bar input { color: #F5F2EC; }

.mfb-cari-nihil {
  margin: 24px 16px;
  padding: 20px;
  border: 1px dashed var(--gray-200, #E7E3DB);
  border-radius: 12px;
  text-align: center;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 13px;
  line-height: 1.5;
  color: var(--gray-400, #9A958C);
}

/* ----------------------------------------------------------------
   14. RANGKA MUAT (skeleton)
   ================================================================
   Menggantikan cincin berputar dengan bentuk isi yang sebentar lagi
   datang. Lihat mfb-ui.js bagian 4n untuk alasannya.

   🔴 CINCINNYA DISEMBUNYIKAN, BUKAN DIHAPUS — dan hanya pada
   placeholder yang memang sedang memuat. Keadaan kosong sudah
   ditangani terpisah di bagian 4f.
   ---------------------------------------------------------------- */

.page-placeholder.mfb-memuat .ph-dots { display: none !important; }
/* Judul "Loading courses..." tetap ada di DOM (dipakai pendeteksi
   spinner macet) tapi tidak perlu dibaca: rangkanya sudah
   menyampaikan hal yang sama tanpa kata. */
.page-placeholder.mfb-memuat .ph-title {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--gray-400, #9A958C);
  opacity: 0.7;
  margin-bottom: 18px;
}

.mfb-rangka { width: 100%; }

.mfb-rangka-gambar,
.mfb-rangka-baris,
.mfb-rangka-bulat {
  /* Satu resep kilau dipakai semua bentuk, jadi seluruh rangka
     berdenyut serempak. Kalau tiap potong punya animasinya sendiri
     dengan fase berbeda, hasilnya terbaca sebagai kekacauan, bukan
     sebagai satu benda yang sedang dimuat. */
  background-image: linear-gradient(90deg,
    var(--mfb-rangka-1) 0%,
    var(--mfb-rangka-2) 50%,
    var(--mfb-rangka-1) 100%);
  background-size: 300% 100%;
  animation: mfb-kilau 1.4s ease-in-out infinite;
}

:root {
  --mfb-rangka-1: rgba(60, 44, 20, 0.07);
  --mfb-rangka-2: rgba(60, 44, 20, 0.13);
}
body.dark-mode {
  --mfb-rangka-1: rgba(255, 255, 255, 0.05);
  --mfb-rangka-2: rgba(255, 255, 255, 0.10);
}

@keyframes mfb-kilau {
  from { background-position: 150% 0; }
  to   { background-position: -150% 0; }
}

/* --- bentuk kartu (Courses, Attendance, Certificates) ---
   🔴 NAMA WADAH DAN NAMA POTONGAN HARUS BEDA.
   Versi pertama memakai .mfb-rangka-kartu untuk keduanya, jadi
   wadahnya ikut mendapat border dan padding kartu — satu kotak
   besar berbingkai berisi tiga kotak berbingkai. Kelas yang sama
   untuk dua peran berbeda selalu berakhir begini. */
.mfb-rangka-kotak {
  border: 1px solid var(--gray-100, #EFEBE3);
  border-radius: 14px;
  padding: 0 0 14px;
  overflow: hidden;
}
.mfb-rangka-gambar { height: 96px; border-radius: 0; }
.mfb-rangka-kotak .mfb-rangka-baris { margin: 12px 14px 0; }

.mfb-rangka.mfb-rangka-kartu {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px;
}

/* --- bentuk baris (Activity Log, Reports, Users) --- */
.mfb-rangka.mfb-rangka-baris { display: flex; flex-direction: column; gap: 14px; }
.mfb-rangka-item {
  display: flex;
  align-items: center;
  gap: 12px;
}
.mfb-rangka-bulat { width: 36px; height: 36px; border-radius: 50%; flex: 0 0 auto; }
.mfb-rangka-kolom {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.mfb-rangka-baris { height: 10px; border-radius: 5px; }
.mfb-rangka-l70 { width: 70%; }
.mfb-rangka-l60 { width: 60%; }
.mfb-rangka-l45 { width: 45%; }
.mfb-rangka-l35 { width: 35%; }

@media (max-width: 768px) {
  .mfb-rangka.mfb-rangka-kartu { grid-template-columns: 1fr; gap: 14px; }
  .mfb-rangka-gambar { height: 78px; }
}

body.dark-mode .mfb-rangka-kotak { border-color: rgba(255, 255, 255, 0.08); }

/* ----------------------------------------------------------------
   15. HALAMAN LOGIN — PERMUKAAN, CAHAYA, DAN KEDALAMAN
   ================================================================
   Permintaan IT Manager: "UI/UX untuk login dan desktop donk kak,
   touch up biar keren, premium dan luxury kak."

   🔴 YANG SEBENARNYA KURANG BUKAN TATA LETAKNYA.

   Susunan halaman ini sudah bagus: rasio 2:1, ruang lega, aksen emas
   yang terkendali. Yang membuatnya terbaca "template" adalah bahwa
   SETIAP PERMUKAANNYA DATAR — hitam rata di kiri, kotak input abu
   rata, tombol hitam rata, dan pertemuan dua panel cuma garis 2px.

   Kemewahan dalam desain hampir tidak pernah datang dari mengganti
   huruf. Ia datang dari CAHAYA: dari mana sumbernya, ke mana
   bayangannya jatuh, dan bahan apa yang memantulkannya. Itu yang
   dikerjakan bagian ini.

   🔴 TIPOGRAFINYA SENGAJA TIDAK DIROMBAK.
   Aturan yang sudah dipakai di bagian 7 tetap berlaku: Cinzel hanya
   untuk BEBERAPA KATA. Jadi eyebrow ("STAFF TRAINING PORTAL",
   "WELCOME BACK") yang memang sudah huruf besar berjarak lebar
   mendapat Cinzel; <h1> dan teks panjang TETAP Georgia. Cinzel untuk
   kalimat penuh terlihat mengesankan sesaat, lalu melelahkan.

   🔴 ANGKA "110+" TIDAK DISENTUH. Itu target akhir Miss Fish, bukan
   kondisi sekarang — mengubahnya butuh keputusan IT Manager (§2.4).
   ---------------------------------------------------------------- */

/* --- a. Panel kiri: hitam hangat, bukan hitam datar --- */
#desk .login-left {
  /* Disamakan dengan chrome sidebar/topbar supaya login dan aplikasi
     terasa satu benda. Sebelumnya login memakai --solid-dark yang
     rata, jadi peralihan sesudah masuk terasa seperti pindah situs. */
  background-image:
    radial-gradient(ellipse 90% 60% at 50% -10%, rgba(201, 168, 76, 0.10) 0%, transparent 60%),
    linear-gradient(160deg, var(--mfb-chrome-atas) 0%, var(--mfb-chrome-bawah) 70%);
}

/* Vignette: sudut-sudutnya diredupkan supaya mata jatuh ke tengah.
   Efek yang sama dipakai fotografi produk mewah — bukan karena
   gelapnya, tapi karena ia MENGARAHKAN pandangan. */
#desk .login-left::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  background: radial-gradient(ellipse 78% 70% at 46% 46%,
    transparent 45%, rgba(0, 0, 0, 0.42) 100%);
}

/* Bingkai emas setipis rambut, MASUK ke dalam dari tepi.
   Ini bahasa kemasan barang mewah: isinya diberi jarak dari tepi,
   lalu diberi garis. Jaraknya yang membuat mahal, bukan garisnya. */
#desk .login-left-bg {
  z-index: 1;
}
#desk .login-left-bg::before {
  content: '';
  position: absolute;
  inset: 26px;
  border: 1px solid rgba(201, 168, 76, 0.13);
  border-radius: 2px;
  pointer-events: none;
}

/* Sapuan cahaya yang bergerak SANGAT lambat (18 detik sekali lewat).
   🔴 Lambatnya disengaja. Gerakan yang terlihat "beranimasi" terbaca
   murah; gerakan yang baru disadari kalau diperhatikan terbaca
   mahal. Yang dianimasikan cuma transform — nol biaya tata letak. */
#desk .login-left-grain::after {
  content: '';
  position: absolute;
  top: -30%;
  left: -60%;
  width: 55%;
  height: 160%;
  pointer-events: none;
  background: linear-gradient(100deg,
    transparent 0%,
    rgba(255, 236, 189, 0.055) 45%,
    rgba(255, 236, 189, 0.085) 50%,
    rgba(255, 236, 189, 0.055) 55%,
    transparent 100%);
  filter: blur(28px);
  animation: mfb-sapuan 18s ease-in-out infinite;
}

@keyframes mfb-sapuan {
  0%, 100% { transform: translateX(0); opacity: 0; }
  15%      { opacity: 1; }
  85%      { opacity: 1; }
  50%      { transform: translateX(240%); }
}

/* --- b. Cincin dekorasi jadi cincin CAHAYA --- */
#desk .deco-circle {
  border-color: rgba(201, 168, 76, 0.16);
  /* Dua bayangan: satu keluar (pendar), satu ke dalam (tebal kaca).
     Cincin tipis tanpa pendar terbaca sebagai garis; dengan pendar
     ia terbaca sebagai benda. */
  box-shadow:
    0 0 90px rgba(201, 168, 76, 0.07),
    inset 0 0 90px rgba(201, 168, 76, 0.045);
}
#desk .deco-circle::before { border-color: rgba(201, 168, 76, 0.10); }

/* Garis vertikal dekorasi dipertegas sedikit — di layar 1080p yang
   lama nyaris tidak terlihat sama sekali, jadi ruang yang dipakainya
   terbuang percuma. */
#desk .deco-vline {
  background: linear-gradient(to bottom,
    transparent,
    rgba(201, 168, 76, 0.26) 38%,
    rgba(201, 168, 76, 0.45) 58%,
    transparent);
}

/* --- c. Tipografi hero --- */
#desk .login-eyebrow-text {
  font-family: 'Cinzel', Georgia, 'Times New Roman', serif;
  font-size: 10.5px;
  letter-spacing: 0.26em;
  text-indent: 0.26em;
}
#desk .login-eyebrow-line {
  width: 44px;
  /* Memudar dari kiri: garisnya terlihat MUNCUL dari tepi halaman,
     bukan menempel begitu saja. */
  background: linear-gradient(to right, transparent, var(--mfb-emas));
}

#desk .login-h1 {
  /* Georgia dipertahankan (lihat catatan di kepala bagian ini),
     tapi jaraknya dirapatkan sedikit. Serif berukuran 76px dengan
     tracking normal terlihat renggang — huruf besar butuh tracking
     lebih rapat, bukan sama. */
  letter-spacing: -0.018em;
  /* Bayangan halus memberi huruf putih sedikit "berat" di atas
     latar gelap, sehingga tepinya tidak berpendar (halation). */
  text-shadow: 0 2px 30px rgba(0, 0, 0, 0.5);
}

/* "Excel." diisi gradien emas, bukan emas rata. Satu kata yang
   diperlakukan berbeda adalah cara paling murah membuat sebuah
   judul terasa dirancang, bukan diketik. */
#desk .login-h1 em {
  background-image: linear-gradient(105deg, #F3DFA6 0%, #C9A865 42%, #F0D89B 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

#desk .login-desc {
  /* 0.42 -> 0.55. Yang lama di bawah ambang baca nyaman untuk teks
     kecil di latar gelap; teks yang tidak terbaca bukan "halus",
     cuma terbuang. */
  color: rgba(255, 255, 255, 0.55);
  max-width: 42ch;
}

/* --- d. Baris angka --- */
#desk .login-stat-n {
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
#desk .login-stat-l {
  color: rgba(255, 255, 255, 0.45);
  letter-spacing: 0.14em;
}
/* Pemisah memudar di kedua ujung — garis penuh memotong, garis
   memudar membingkai. */
#desk .login-stat-div {
  height: 46px;
  background: linear-gradient(to bottom,
    transparent, rgba(201, 168, 76, 0.4) 50%, transparent);
}

/* --- e. Pertemuan dua panel: TEPI SUNGGUHAN, bukan garis --- */
#desk .login-right {
  /* Panel kanan diangkat DI ATAS panel kiri. Bayangannya yang
     membuat mata membacanya sebagai dua lapis, bukan dua warna. */
  z-index: 2;
  box-shadow: -34px 0 70px rgba(0, 0, 0, 0.42);
  background-image: linear-gradient(180deg, #FFFFFF 0%, #FDFBF7 100%);
}
#desk .login-right::before {
  /* 2px rata -> 3px bergradasi dengan pendar. Inilah satu-satunya
     tempat emas dipakai sebagai GARIS PENUH di halaman ini, jadi ia
     boleh tegas. */
  width: 3px;
  background: linear-gradient(to bottom,
    transparent 0%,
    rgba(201, 168, 76, 0.55) 18%,
    #E8C96A 50%,
    rgba(201, 168, 76, 0.55) 82%,
    transparent 100%);
  box-shadow: 0 0 22px rgba(201, 168, 76, 0.32);
  z-index: 3;
}

/* --- f. Formulir --- */
#desk .login-form-eyebrow {
  font-family: 'Cinzel', Georgia, 'Times New Roman', serif;
  font-size: 10.5px;
  letter-spacing: 0.24em;
  text-indent: 0.24em;
}
#desk .login-form-title { letter-spacing: -0.015em; }

#desk .f-input {
  /* Cekung, bukan rata: bayangan dalam yang tipis membuat kotak
     isian terbaca sebagai LUBANG tempat mengetik. Kotak rata
     terbaca sebagai kotak yang kebetulan bisa diketik. */
  background: #FBF9F5;
  border-color: #E8E2D6;
  box-shadow: inset 0 1px 2px rgba(60, 44, 20, 0.05);
  caret-color: #B8912F;
  transition: border-color .18s, box-shadow .18s, background .18s;
}
#desk .f-input:hover:not(:focus) { border-color: #DCD4C4; }
#desk .f-input:focus {
  background: #FFFFFF;
  border-color: #C9A865;
  /* Cincin fokus + pendar lembut. Cincinnya yang memenuhi syarat
     keterlihatan fokus; pendarnya yang membuatnya terasa hangat. */
  box-shadow:
    0 0 0 3px rgba(201, 168, 76, 0.16),
    0 2px 10px rgba(201, 168, 76, 0.13),
    inset 0 1px 2px rgba(60, 44, 20, 0.03);
}

#desk .btn-signin {
  /* Hitam hangat bergradasi + kilau tepi atas — bahasa yang sama
     dengan seluruh kartu timbul di aplikasi (bagian 3). */
  background-image: linear-gradient(180deg, #221C13 0%, #0C0B08 100%);
  border: 1px solid rgba(201, 168, 76, 0.30);
  box-shadow:
    inset 0 1px 0 rgba(255, 244, 214, 0.16),
    0 4px 14px rgba(0, 0, 0, 0.20);
  letter-spacing: 0.18em;
  transition: box-shadow .22s, transform .12s, border-color .22s;
}
#desk .btn-signin:hover {
  background-image: linear-gradient(180deg, #2B2317 0%, #100E0A 100%);
  border-color: rgba(201, 168, 76, 0.55);
  box-shadow:
    inset 0 1px 0 rgba(255, 244, 214, 0.24),
    0 10px 26px rgba(0, 0, 0, 0.28),
    0 0 0 1px rgba(201, 168, 76, 0.12);
}
/* Kilau yang menyapu tombol saat disorot — SEKALI, tidak berulang.
   Kilau berulang terbaca seperti iklan; kilau sekali terbaca seperti
   permukaan yang memang memantulkan cahaya. */
#desk .btn-signin::after {
  background-image: linear-gradient(105deg,
    transparent 30%, rgba(255, 240, 205, 0.20) 50%, transparent 70%);
  transform: translateX(-100%);
  opacity: 1;
  transition: transform .7s cubic-bezier(.22, 1, .36, 1);
}
#desk .btn-signin:hover::after { transform: translateX(100%); }
#desk .btn-signin:focus-visible {
  outline: 2px solid var(--mfb-emas);
  outline-offset: 3px;
}

#desk .login-divider-text {
  font-family: 'Cinzel', Georgia, 'Times New Roman', serif;
  letter-spacing: 0.2em;
  text-indent: 0.2em;
}
#desk .login-divider-line {
  background: linear-gradient(to right, transparent, #E8E2D6 50%, transparent);
}
#desk .login-forgot strong { color: #B8912F; }

/* ----------------------------------------------------------------
   16. HALAMAN LOGIN HP
   ================================================================
   Bahasa yang sama, disesuaikan dengan layar sempit: kartu putih
   yang naik dari bawah, dengan garis emas tipis di bibir atasnya.
   ---------------------------------------------------------------- */

#mob #m-login {
  background-image:
    radial-gradient(ellipse 110% 45% at 50% 0%, rgba(201, 168, 76, 0.16) 0%, transparent 62%),
    linear-gradient(180deg, var(--mfb-chrome-atas) 0%, var(--mfb-chrome-bawah) 100%);
}

#mob .mob-login-sub {
  font-family: 'Cinzel', Georgia, 'Times New Roman', serif;
  letter-spacing: 0.24em;
  text-indent: 0.24em;
}
#mob .mob-login-tagline { color: rgba(255, 255, 255, 0.52); }

#mob .mob-login-card {
  position: relative;
  background-image: linear-gradient(180deg, #FFFFFF 0%, #FDFBF7 100%);

  /* Bayangan ke ATAS: kartunya naik dari bawah layar, jadi cahayanya
     datang dari atas dan bayangannya jatuh di bibir kartu. */
  box-shadow: 0 -14px 40px rgba(0, 0, 0, 0.34);

  /* 🔴 Lengkungan 28px -> 34px, 18 September 2026. Laporan IT Manager:
     "kurang bulat sempurna".

     Nilai baseline ada di index.html baris 816 dan ia memakai
     !important, jadi menimpanya butuh !important juga. Itu SAH di
     sini: mfb-ui.css dimuat di baris 16644, yaitu SESUDAH seluruh
     blok <style> baseline (721-2997, 3002+, 3038+) — diverifikasi,
     bukan diasumsikan. Pada kekhususan yang sama, yang dimuat
     belakangan menang.

     34px dipilih, bukan lebih besar: kartunya menempel ke tepi bawah
     layar dengan margin 8px, dan lengkungan yang terlalu besar mulai
     memakan ruang isian password di sudutnya.

     🔴 DITARUH SESUDAH box-shadow, BUKAN sebelumnya — dan itu
     disengaja. Uji "kartu login HP diberi bayangan ke ATAS" dulu
     mencari box-shadow dalam 300 karakter dari selektornya; komentar
     panjang ini mendorongnya keluar jendela itu dan membuat uji merah
     padahal CSS-nya benar. Ujinya sudah diperbaiki agar mengukur
     BATAS BLOK, bukan jarak karakter — tapi urutan ini tetap
     dipertahankan supaya deklarasi yang dijaga berada dekat dengan
     awal blok, bukan di balik satu layar komentar. */
  border-radius: 34px !important;
}
/* Garis emas di bibir kartu — versi HP dari garis pemisah panel di
   desktop, jadi keduanya terbaca sebagai komponen yang sama. */
#mob .mob-login-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 26px;
  right: 26px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(to right,
    transparent, rgba(201, 168, 76, 0.75) 30%,
    #E8C96A 50%, rgba(201, 168, 76, 0.75) 70%, transparent);
  box-shadow: 0 0 14px rgba(201, 168, 76, 0.35);
}
#mob .mob-login-card-eyebrow {
  font-family: 'Cinzel', Georgia, 'Times New Roman', serif;
  letter-spacing: 0.24em;
  text-indent: 0.24em;
}

#mob .lf-input {
  background: #FBF9F5;
  border-color: #E8E2D6;
  box-shadow: inset 0 1px 2px rgba(60, 44, 20, 0.05);
  caret-color: #B8912F;
}
#mob .lf-input:focus {
  background: #FFFFFF;
  border-color: #C9A865;
  box-shadow:
    0 0 0 3px rgba(201, 168, 76, 0.16),
    inset 0 1px 2px rgba(60, 44, 20, 0.03);
}

/* Tombol Sign In HP disamakan dengan desktop. Pemilihnya diambil
   dari baseline; kalau kelasnya berbeda, aturan ini diam saja —
   tidak ada yang rusak. */
#mob .btn-signin,
#mob .btn-login-m {
  background-image: linear-gradient(180deg, #221C13 0%, #0C0B08 100%);
  border: 1px solid rgba(201, 168, 76, 0.30);
  box-shadow:
    inset 0 1px 0 rgba(255, 244, 214, 0.16),
    0 4px 14px rgba(0, 0, 0, 0.18);
}

#mob .m-login-footer strong,
#mob .mob-login-card-sub strong { color: #B8912F; }

/* ----------------------------------------------------------------
   17. LOGIN — PUTARAN KEDUA: KOMPOSISI & KOREOGRAFI
   ================================================================
   Permintaan IT Manager: "login bisa tambah premium lagi kak, apa ya?"

   🔴 KELEMAHAN TERBESAR YANG TERSISA ADALAH KOMPOSISI, BUKAN WARNA.

   Di tangkapan layar IT Manager, SEMUA isi panel kiri menempel di tepi
   kiri: logo di kiri atas, hero di kiri tengah, hak cipta di kiri
   bawah. Sekitar 55% sisanya kosong, dengan satu lingkaran yang
   terlalu samar untuk dianggap ada.

   Ruang kosong seperti itu tidak terbaca "lapang" — ia terbaca
   "belum selesai". Bedanya terletak pada apakah ada sesuatu yang
   MENAHAN ruang itu dengan sengaja.

   Obatnya BUKAN mengisinya dengan banyak hal. Kemewahan itu
   menahan diri. Yang dilakukan: SATU jangkar yang percaya diri —
   cincin yang dibesarkan sampai benar-benar mengimbangi blok teks
   di kiri, dengan lapisan yang cukup untuk punya kedalaman.
   ---------------------------------------------------------------- */

/* --- a. Cincin jadi jangkar komposisi --- */
#desk .deco-circle {
  /* 380px tetap -> menyesuaikan lebar layar. Di monitor 2560px,
     lingkaran 380px tenggelam; di 1366px, 620px akan menabrak teks.
     clamp menjaga proporsinya di antara keduanya. */
  width: clamp(400px, 33vw, 620px);
  height: clamp(400px, 33vw, 620px);
  left: 52%;
  border-color: rgba(201, 168, 76, 0.20);
  box-shadow:
    0 0 130px rgba(201, 168, 76, 0.08),
    inset 0 0 130px rgba(201, 168, 76, 0.05);
}
#desk .deco-circle::before {
  inset: 11%;
  border-color: rgba(201, 168, 76, 0.13);
}

/* Cincin KETIGA — dan ia berputar BERLAWANAN arah, lebih lambat.
   Dua benda yang berputar searah dengan kecepatan sama terbaca
   sebagai satu gambar yang diputar. Arah dan kecepatan yang
   berbeda-lah yang memberi kesan lapisan dan kedalaman. */
#desk .deco-circle::after {
  content: '';
  position: absolute;
  inset: 24%;
  border-radius: 50%;
  border: 1px solid rgba(201, 168, 76, 0.09);
  /* Satu busur emas yang lebih terang di tepi atas cincin — sumber
     cahayanya jadi terbaca: datang dari atas, sama seperti seluruh
     bayangan di aplikasi ini. */
  border-top-color: rgba(232, 201, 106, 0.34);
  animation: mfb-putar-balik 62s linear infinite;
}

@keyframes mfb-putar-balik {
  from { transform: rotate(0deg); }
  to   { transform: rotate(-360deg); }
}

/* --- b. Koreografi masuk: judul TERSINGKAP, bukan sekadar memudar ---
   🔴 Gerakan ini BERJALAN BERSAMAAN dengan fadeUp bawaan pada
   .login-hero — dan itu disengaja. Dua gerakan yang waktunya
   menyatu dibaca sebagai SATU gerakan: bloknya naik sambil
   judulnya tersingkap. Kalau salah satunya dimulai sesudah yang
   lain selesai, hasilnya terbaca sebagai dua animasi berturut-turut,
   dan itu justru terasa murah. */
@keyframes mfb-singkap {
  from { clip-path: inset(0 0 100% 0); opacity: 0; }
  to   { clip-path: inset(0 0 0 0);    opacity: 1; }
}

#desk .login-h1 {
  animation: mfb-singkap 1.05s cubic-bezier(.16, 1, .3, 1) .12s both;
}
/* Keterangan dan angka menyusul, masing-masing sedikit lebih lambat.
   Jaraknya kecil (0,12 detik) — cukup untuk terasa berurutan, terlalu
   singkat untuk terasa menunggu. */
#desk .login-desc  { animation: mfb-singkap .9s cubic-bezier(.16, 1, .3, 1) .30s both; }
#desk .login-stats { animation: mfb-singkap .9s cubic-bezier(.16, 1, .3, 1) .42s both; }

/* Garis emas pemisah MENGGAMBAR DIRINYA dari tengah ke dua arah.
   Detail kecil, tapi ia yang membuat halaman terasa "dirakit" di
   depan mata, bukan sekadar muncul. */
#desk .login-right::before {
  animation: mfb-tarik-garis 1.1s cubic-bezier(.16, 1, .3, 1) .2s both;
  transform-origin: center;
}
@keyframes mfb-tarik-garis {
  from { transform: scaleY(0); opacity: 0; }
  to   { transform: scaleY(1); opacity: 1; }
}

/* --- c. Kedalaman di panel kanan ---
   Putih rata terbaca sebagai kertas fotokopi. Cahaya hangat yang
   sangat tipis di belakang formulir membuatnya terbaca sebagai
   kertas yang disinari. */
#desk .login-right::after {
  width: 520px;
  height: 520px;
  top: -220px;
  right: -220px;
  background: radial-gradient(circle,
    rgba(201, 168, 76, 0.10) 0%, rgba(201, 168, 76, 0.03) 45%, transparent 72%);
}

/* --- d. Label ikut hidup saat kolomnya dipakai ---
   Perubahan sekecil ini jarang disadari, tapi ia yang membuat
   formulir terasa menjawab. */
/* 🔴 Dipilih lewat INDUKNYA, bukan lewat sibling.
   Di markup baseline, <label> berada SEBELUM .f-wrap:

       <div>
         <label class="f-label">…</label>
         <div class="f-wrap"><input …></div>
       </div>

   CSS tidak punya pemilih "saudara sebelumnya", jadi .f-wrap:focus-within
   + .f-label tidak akan pernah cocok. Yang benar: induknya yang
   menerima :focus-within, lalu label dipilih sebagai anaknya. */
#desk .login-form > div:focus-within > .f-label { color: #9A7B22; }
#desk .f-wrap:focus-within .f-icon { color: #B8912F; }
#mob .lf-group:focus-within .lf-label { color: #9A7B22; }

/* --- e. Tombol saat sedang memproses ---
   dLogin() mengganti teksnya jadi "Signing in..." lalu men-disable
   tombolnya (baseline baris 6034-6035). Keadaan itu sekarang ikut
   terlihat: kilaunya berjalan terus selama menunggu, jadi tombol
   yang mati tidak terbaca sebagai tombol yang rusak. */
#desk .btn-signin:disabled { opacity: 1; color: rgba(255, 255, 255, 0.62); }
#desk .btn-signin:disabled::after {
  animation: mfb-kilau-tombol 1.25s ease-in-out infinite;
  transform: none;
}
@keyframes mfb-kilau-tombol {
  from { transform: translateX(-100%); }
  to   { transform: translateX(100%); }
}

/* ----------------------------------------------------------------
   18. PERINGATAN CAPS LOCK
   ================================================================
   Lihat mfb-ui.js bagian 4o untuk alasannya. Ringkasnya: Employee ID
   di-uppercase otomatis, jadi Caps Lock TIDAK TERLIHAT di layar —
   dan percobaan kelima mengunci akun.

   Warnanya EMAS, bukan merah. Ini bukan kesalahan yang sudah terjadi,
   melainkan pemberitahuan supaya kesalahan TIDAK terjadi. Merah akan
   membuat orang mengira ia sudah salah memasukkan sesuatu.
   ---------------------------------------------------------------- */

/* 🔴 PENGAMAN GLOBAL — DILAPORKAN IT MANAGER LEWAT TANGKAPAN LAYAR.
   ================================================================
   "itu caps menyala terus2an ada, walaupun caplock mati."

   SEBABNYA. Atribut HTML `hidden` disembunyikan oleh aturan BAWAAN
   browser:  [hidden] { display: none }

   Aturan bawaan itu berada di lapisan user-agent, yang KALAH dari
   aturan mana pun yang ditulis penulis halaman. Begitu .mfb-caps
   diberi `display: flex`, atribut hidden-nya berhenti berarti apa
   pun — elemennya SELALU tampil, apa pun keadaan Caps Lock.

   Kodenya sendiri benar dari awal: tanda.hidden memang berpindah
   antara true dan false sesuai keadaan tombol. Yang rusak cuma satu
   baris CSS yang membatalkannya diam-diam — dan itu sebabnya tidak
   ada galat, tidak ada gejala lain, dan tidak ketahuan sampai
   dilihat mata.

   Ditaruh sebagai aturan GLOBAL, bukan cuma untuk .mfb-caps: setiap
   elemen yang nanti disembunyikan lewat .hidden akan terlindungi
   tanpa perlu ada yang mengingat jebakan ini lagi.
   ---------------------------------------------------------------- */
[hidden] { display: none !important; }

.mfb-caps {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: 8px;
  padding: 7px 11px;
  border-radius: 8px;
  border: 1px solid rgba(201, 168, 76, 0.45);
  background: rgba(201, 168, 76, 0.09);
  color: #8A6D18;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.35;
  animation: mfb-caps-masuk .18s ease-out;
}
.mfb-caps span:first-child { font-size: 14px; line-height: 1; flex: 0 0 auto; }

@keyframes mfb-caps-masuk {
  from { opacity: 0; transform: translateY(-3px); }
  to   { opacity: 1; transform: translateY(0); }
}

body.dark-mode .mfb-caps {
  border-color: rgba(232, 201, 106, 0.4);
  background: rgba(232, 201, 106, 0.1);
  color: #E8C96A;
}

/* Di HP kartunya putih walau mode gelap (baseline baris 1679), jadi
   warnanya dikembalikan ke versi terang supaya tetap terbaca. */
body.dark-mode #mob .mfb-caps {
  border-color: rgba(201, 168, 76, 0.45);
  background: rgba(201, 168, 76, 0.09);
  color: #8A6D18;
}

/* ----------------------------------------------------------------
   19. CORONG TAHAPAN & BATANG PERINGKAT
   ================================================================
   Permintaan IT Manager lewat tiga tangkapan layar: "buat grafik2 begini
   kak, lebih menarik daripada stat card biasa."

   Keduanya dibangun dari data yang SUDAH ada di jawaban Dashboard —
   nol permintaan jaringan tambahan, nol kolom database baru.
   ---------------------------------------------------------------- */

.mfb-g-baris-2 {
  /* Pemisah baris memakai token yang sama dengan pemisah kolom,
     supaya kisi pemisahnya terbaca sebagai SATU salib, bukan dua
     garis dengan ketebalan berbeda. */
  border-top: 1px solid var(--mfb-g-pemisah);
  padding-top: 24px;
  margin-top: 20px;
  /* Dua panel berimbang di sini — corong dan batang sama-sama butuh
     lebar, tidak seperti donat yang bulat. */
  grid-template-columns: 1fr 1fr;
}
@media (max-width: 900px) {
  .mfb-g-baris-2 { grid-template-columns: 1fr; }
}

/* --- corong --- */
.mfb-corong { display: flex; flex-direction: column; gap: 9px; }
.mfb-corong-baris { display: flex; align-items: center; gap: 10px; }

.mfb-corong-batang {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-width: 0;
  height: 40px;
  padding: 0 14px;
  border-radius: 9px;
  color: #FFFFFF;
  font-family: 'Inter', system-ui, sans-serif;
  /* Kilau tepi atas — bahasa yang sama dengan seluruh kartu timbul. */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22);
}
.mfb-corong-nama {
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mfb-corong-num {
  font-size: 14px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  flex: 0 0 auto;
}

/* 🔴 EMPAT WARNA YANG MENURUN, bukan empat warna acak.
   Corong menceritakan perjalanan: dari banyak orang di atas jadi
   sedikit di bawah. Warna yang makin pekat ke bawah memperkuat cerita
   itu; warna pelangi justru membuat tiap tahap terbaca sebagai
   kategori yang tidak berhubungan. */
.mfb-corong-1 { background-image: linear-gradient(135deg, #6B6660 0%, #504B45 100%); }
.mfb-corong-2 { background-image: linear-gradient(135deg, #C9A865 0%, #A8873F 100%); }
.mfb-corong-3 { background-image: linear-gradient(135deg, #2FA05C 0%, #1A8A4A 100%); }
.mfb-corong-4 { background-image: linear-gradient(135deg, #1A8A4A 0%, #0F6A37 100%); }

/* Angka susut antar-tahap. Inilah yang sebenarnya dicari orang saat
   melihat corong: DI MANA orang paling banyak berguguran. */
.mfb-corong-susut {
  flex: 0 0 auto;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: #C2532F;
}
body.dark-mode .mfb-corong-susut { color: #FF8A80; }

/* --- batang peringkat --- */
.mfb-bar { display: flex; flex-direction: column; gap: 9px; }
.mfb-bar-baris {
  display: grid;
  /* Satu kolom penuh — nama dan angka sekarang ADA DI DALAM batang,
     seperti Training Funnel. Permintaan IT Manager 11 September 2026:
     "seperti yg training funnel aja kak, lebih jelas dan lega."

     Menaruh nama di dalam batang membuang kolom nama selebar 108px,
     jadi seluruh lebar itu kembali jadi ruang untuk batangnya —
     itulah yang membuatnya terasa lebih lega. */
  grid-template-columns: 1fr;
  align-items: center;
}
.mfb-bar-nama {
  position: relative;
  z-index: 1;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--gray-900, #1A1713);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
body.dark-mode .mfb-bar-nama { color: #F5F2EC; }

.mfb-bar-alur {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  /* Setinggi batang corong (40px), supaya keduanya terbaca sebagai
     satu keluarga bentuk. */
  height: 40px;
  padding: 0 15px;
  border-radius: 9px;
  overflow: hidden;
  background: var(--mfb-g-kisi);
}

/* 🔴 Isian ditaruh DI BELAKANG teks, bukan di sebelahnya.
   Teksnya tetap di tempat yang sama berapa pun panjang batangnya —
   jadi "Housekeeping 41%" sama terbacanya dengan "Kitchen 72%".
   Kalau teks ikut masuk ke dalam isian seperti di corong, nama
   departemen dengan nilai kecil akan terpotong atau keluar batang. */
.mfb-bar-isi {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  z-index: 0;
  border-radius: 9px;
  background-image: linear-gradient(90deg, var(--mfb-g-emas) 0%, #2FA05C 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28);
  /* 🔴 Sedikit diredupkan supaya teks gelap di atasnya tetap lolos
     WCAG AA. Emas penuh #B8912F dengan teks #1A1713 hanya 4,1:1;
     dengan opacity ini latarnya jadi lebih terang dan kontrasnya
     naik di atas 4,5:1 — tanpa mengubah warna mereknya. */
  opacity: 0.82;
}
body.dark-mode .mfb-bar-isi { opacity: 0.55; }

/* Batang JUMLAH (svgBatangHitung) — warnanya membawa arti, jadi
   tidak boleh memakai gradien emas-hijau yang sama dengan batang
   persen. Emas-ke-hijau berarti "makin panjang makin baik"; untuk
   overdue justru terbalik.

   🔴 Warna BUKAN satu-satunya pembeda: angkanya tetap tertulis di
   sebelah kanan tiap batang, dan aria-label menyebut "Overdue".
   Pembaca yang buta warna tidak kehilangan apa pun. */
.mfb-bar-isi.mfb-bar-bahaya {
  background-image: linear-gradient(90deg, #D4756A 0%, #B03A2E 100%);
}
.mfb-bar-isi.mfb-bar-baik {
  background-image: linear-gradient(90deg, #4FB87A 0%, #1A8A4A 100%);
}
body.dark-mode .mfb-bar-isi.mfb-bar-bahaya {
  background-image: linear-gradient(90deg, #FF8A80 0%, #D4564A 100%);
}
body.dark-mode .mfb-bar-isi.mfb-bar-baik {
  background-image: linear-gradient(90deg, #6FD696 0%, #3AA766 100%);
}
.mfb-bar-num {
  position: relative;
  z-index: 1;
  flex: 0 0 auto;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--gray-900, #1A1713);
}
body.dark-mode .mfb-bar-num { color: #F5F2EC; }

/* 🔴 BUG NYATA, dipotret IT Manager dari HP-nya 17 September 2026 pagi:
   batang departemen di halaman Reports cuma selebar sepertiga kartu,
   sisanya kosong, dan nama departemen terpotong jadi "K.", "S.", "B.".

   SEBABNYA SISA ATURAN LAMA YANG TIDAK IKUT DIPERBARUI.

   Dulu setiap baris punya TIGA anak: nama | batang | angka, jadi
   aturan ini masuk akal: kolom nama 84px, batang mengisi sisa, angka
   38px. Lalu 11 September IT Manager minta "seperti yg training funnel
   aja kak" — nama dan angka dipindah KE DALAM batang, sehingga tiap
   baris kini cuma punya SATU anak. Aturan utamanya sudah diubah jadi
   satu kolom penuh (1fr), tapi aturan khusus layar sempit ini
   tertinggal dan tetap memaksa tiga kolom.

   Akibatnya di SETIAP HP (semua di bawah 560px), batang tunggal itu
   dijejalkan ke kolom pertama selebar 84px — diukur di Chrome: lebar
   batang 84px di dalam baris selebar 302px, jadi 218px terbuang
   percuma — dan nama departemen dipotong ellipsis.

   🔴 Desktop TIDAK PERNAH kena, karena aturannya hanya berlaku di
   bawah 560px. Itulah sebabnya cacat ini bertahan berminggu-minggu
   sampai ada yang benar-benar membukanya di HP.

   Yang tersisa di sini sekarang hanya yang memang masih berlaku:
   jarak antar baris yang lebih rapat dan nama yang sedikit lebih
   kecil di layar sempit. */
@media (max-width: 560px) {
  .mfb-bar-baris { gap: 8px; }
  .mfb-bar-nama  { font-size: 11px; }
}

/* ----------------------------------------------------------------
   20. BAGAN TAHAPAN DI ATAS VIDEO
   ================================================================
   Permintaan IT Manager: "bagan diatas video, sebelum mulai training,
   tahapan2 gitu."

   Menjawab tiga pertanyaan yang selama ini tidak terjawab di layar
   modul: ada berapa seluruhnya, ini yang keberapa, dan masih berapa
   lagi. Alasan lengkapnya di mfb-ui.js bagian 4p.
   ---------------------------------------------------------------- */

.mfb-tahap {
  background-image: linear-gradient(180deg, #FFFFFF 0%, #FCFAF6 100%);
  border: 1px solid var(--gray-100, #EFEBE3);
  border-radius: 14px 14px 0 0;
  border-bottom: 0;
  padding: 14px 16px 16px;
}
body.dark-mode .mfb-tahap {
  background-image: linear-gradient(180deg, #1A1713 0%, #141210 100%);
  border-color: rgba(255, 255, 255, 0.08);
}

.mfb-tahap-kepala {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}
.mfb-tahap-judul {
  font-family: 'Cinzel', Georgia, 'Times New Roman', serif;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-indent: 0.14em;
  text-transform: uppercase;
  color: var(--gray-900, #1A1713);
}
body.dark-mode .mfb-tahap-judul { color: #F5F2EC; }
.mfb-tahap-hitung {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--gray-400, #9A958C);
  flex: 0 0 auto;
}

.mfb-tahap-alur {
  display: flex;
  align-items: flex-start;
  gap: 0;
  /* 🔴 Digeser ke samping kalau modulnya banyak — TIDAK dimampatkan.
     Course dengan 9 modul yang dipaksa muat akan membuat tiap
     langkah selebar 40px, dan judulnya hilang jadi "Intro…". Yang
     hilang justru satu-satunya hal yang membuat bagan ini berguna. */
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding-bottom: 4px;
  scrollbar-width: thin;
  scrollbar-color: rgba(201, 168, 76, 0.4) transparent;
}
.mfb-tahap-alur::-webkit-scrollbar { height: 5px; }
.mfb-tahap-alur::-webkit-scrollbar-track { background: transparent; }
.mfb-tahap-alur::-webkit-scrollbar-thumb {
  background: rgba(201, 168, 76, 0.4); border-radius: 999px;
}

.mfb-tahap-item {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  flex: 0 0 auto;
  max-width: 190px;
  scroll-snap-align: start;
  padding: 2px 2px 2px 0;
}

.mfb-tahap-bulat {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12.5px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  border: 1.5px solid var(--gray-200, #E7E3DB);
  background: var(--gray-50, #FBF9F5);
  color: var(--gray-400, #9A958C);
}
.mfb-tahap-teks { min-width: 0; padding-top: 1px; }
.mfb-tahap-nama {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--gray-500, #6B6660);
  /* Dua baris, lalu dipotong. Judul modul di LMS ini bisa panjang
     ("Standard Operating Procedure — Penanganan Ikan Segar"), dan
     satu baris membuat semuanya terlihat sama. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.mfb-tahap-sub {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--gray-400, #9A958C);
  margin-top: 3px;
  white-space: nowrap;
}

/* Panah penyambung. Dibuat dari border, bukan karakter "→", supaya
   tebalnya konsisten di semua huruf sistem. */
.mfb-tahap-panah {
  flex: 0 0 auto;
  align-self: flex-start;
  width: 26px;
  height: 30px;
  position: relative;
}
.mfb-tahap-panah::before {
  content: '';
  position: absolute;
  top: 15px;
  left: 2px;
  right: 2px;
  height: 1.5px;
  background: var(--gray-200, #E7E3DB);
}
body.dark-mode .mfb-tahap-panah::before { background: rgba(255, 255, 255, 0.12); }

/* --- tiga keadaan --- */
.mfb-tahap-selesai .mfb-tahap-bulat {
  border-color: #1A8A4A;
  background: #1A8A4A;
  color: #FFFFFF;
}
.mfb-tahap-selesai .mfb-tahap-nama { color: var(--gray-400, #9A958C); }

.mfb-tahap-aktif .mfb-tahap-bulat {
  border-color: #C9A865;
  background-image: linear-gradient(180deg, #E8C96A 0%, #C9A865 100%);
  color: #221C13;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.45),
    0 0 0 4px rgba(201, 168, 76, 0.16);
}
.mfb-tahap-aktif .mfb-tahap-nama {
  color: var(--gray-900, #1A1713);
  font-weight: 700;
}
body.dark-mode .mfb-tahap-aktif .mfb-tahap-nama { color: #F5F2EC; }

.mfb-tahap-kunci { opacity: 0.5; }
.mfb-tahap-kunci .mfb-tahap-bulat { font-size: 11px; }

@media (max-width: 768px) {
  .mfb-tahap { border-radius: 0; padding: 12px 14px 14px; }
  .mfb-tahap-item { max-width: 156px; }
  .mfb-tahap-panah { width: 18px; }
}

/* ----------------------------------------------------------------
   21. SPARKLINE DI KARTU ANGKA
   ================================================================
   Usulan 1. Angka "8" tidak bercerita; "8" dengan garis kecil yang
   menanjak langsung menjawab pertanyaan berikutnya.

   🔴 HANYA DUA KARTU YANG DAPAT — yang memang punya riwayat di
   database. Lihat mfb-ui.js bagian 4q untuk alasannya.
   ---------------------------------------------------------------- */

#desk .stat-card { position: relative; }

.mfb-spark-bungkus {
  position: absolute;
  right: 16px;
  bottom: 14px;
  width: 68px;
  height: 22px;
  pointer-events: none;
}
.mfb-spark { display: block; width: 100%; height: 100%; overflow: visible; }
.mfb-spark-garis {
  fill: none;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.mfb-spark-naik  .mfb-spark-garis,
.mfb-spark-naik  .mfb-spark-ujung { stroke: var(--mfb-g-hijau); }
.mfb-spark-turun .mfb-spark-garis,
.mfb-spark-turun .mfb-spark-ujung { stroke: var(--mfb-g-abu); }
.mfb-spark-ujung { fill: #FFFFFF; stroke-width: 1.8; }
body.dark-mode .mfb-spark-ujung { fill: #141210; }

/* Di bawah 1200px kartu angka jadi sempit dan sparkline mulai
   menabrak keterangannya. Lebih baik hilang daripada bertumpuk. */
@media (max-width: 1200px) {
  .mfb-spark-bungkus { display: none; }
}

/* 21b. GRAFIK MINI KEADAAN-SEKARANG (rilis 2.220) — Total Employees,
   Total Courses, Overdue Trainings. Menumpang slot & aturan sembunyi
   .mfb-spark-bungkus di atas; BUKAN tren (lihat mfb-ui.js 4q2). */
.mfb-mini { display: block; width: 100%; height: 100%; overflow: visible; }
.mfb-mini-emas  { fill: var(--mfb-g-emas); }
.mfb-mini-hijau { fill: var(--mfb-g-hijau); }
.mfb-mini-abu   { fill: var(--mfb-g-abu); }
.mfb-mini-alur  { stroke: var(--mfb-g-pemisah); }
.mfb-mini-merah { stroke: #C0452F; }
body.dark-mode .mfb-mini-merah { stroke: #F08A7A; }
.mfb-mini-teks  { font: 600 9.5px 'Inter', system-ui, sans-serif; fill: var(--gray-500, #8A8580); }
/* Di baris tipis (sel ±42 px) grafik diratakan tengah, sejajar teks sel. */
#desk .mfb-stat-tipis .mfb-mini-bungkus { top: 50%; bottom: auto; transform: translateY(-50%); }
/* Attendance desktop: cincin hadir ÷ diharapkan, di kanan angka attendees. */
#desk .mfb-hadir { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; margin-left: 4px; }
.mfb-hadir-cincin { width: 28px; height: 28px; display: block; }
.mfb-hadir-baik   { stroke: var(--mfb-g-hijau); }
.mfb-hadir-kurang { stroke: var(--mfb-g-emas); }
.mfb-hadir-teks   { font-size: 11px; line-height: 1.25; color: var(--gray-500); text-align: left; }
/* 21c. Dashboard staff — progres modul di tiap tenggat (rilis 2.221). */
.mfb-tenggat-modul { display: flex; align-items: center; gap: 6px; margin-top: 4px; font-size: 11px; color: var(--gray-500); }
.mfb-tenggat-bar { flex: 0 0 56px; height: 4px; border-radius: 2px; background: var(--mfb-g-pemisah); overflow: hidden; }
.mfb-tenggat-bar > i { display: block; height: 100%; background: var(--mfb-g-emas); border-radius: 2px; }
/* 21d. Kartu course admin — orang tuntas vs berjalan (rilis 2.223). */
.mfb-kc-orang { font-size: 11.5px; font-weight: 600; color: var(--mfb-g-hijau); margin: -4px 0 12px; }
#mob .mfb-kc-orang { font-size: 11px; margin: 4px 0 0; }
.mfb-kc-orang.is-nol { color: var(--gray-500); }
/* 21e. A-penuh (rilis 2.224) — orang ditugaskan: tuntas / berjalan / belum mulai. */
.mfb-kc-tugas { margin: -4px 0 12px; }
#mob .mfb-kc-tugas { margin: 6px 0 0; }
.mfb-kc-tugas-bar { display: flex; height: 6px; border-radius: 3px; overflow: hidden; background: var(--mfb-g-pemisah); gap: 2px; }
.mfb-kc-tugas-bar > i { display: block; height: 100%; }
.mfb-kc-tugas-bar > .is-tuntas { background: var(--mfb-g-hijau); }
.mfb-kc-tugas-bar > .is-jalan { background: var(--mfb-g-emas); }
.mfb-kc-tugas-bar > .is-belum { background: var(--mfb-g-abu); }
.mfb-kc-tugas-teks { margin-top: 5px; font-size: 11.5px; font-weight: 600; color: var(--gray-500); }

/* ----------------------------------------------------------------
   22. HEATMAP KEBIASAAN BELAJAR
   ================================================================
   Usulan 4. Yang diceritakan adalah LUBANGNYA — lihat mfb-ui.js
   bagian 4q.
   ---------------------------------------------------------------- */

.mfb-heat-kartu { margin-top: 16px; }
.mfb-heat-isi { padding: 4px 20px 20px; }

.mfb-heat {
  display: grid;
  /* 12 minggu x 7 hari. Kolom = minggu, baris = hari — susunan yang
     sama dengan kalender, jadi tidak perlu dipelajari. */
  grid-template-rows: repeat(7, 1fr);
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 3px;
  max-width: 100%;
}
.mfb-heat-kotak {
  aspect-ratio: 1 / 1;
  min-width: 8px;
  border-radius: 2px;
  background: var(--mfb-g-kisi);
}
/* Empat tingkat, bukan gradien mulus — mata jauh lebih baik
   membandingkan beberapa tingkat jelas daripada ratusan rona. */
.mfb-heat-2 { background: rgba(26, 138, 74, 0.35); }
.mfb-heat-3 { background: rgba(26, 138, 74, 0.65); }
.mfb-heat-4 { background: #1A8A4A; }
body.dark-mode .mfb-heat-2 { background: rgba(111, 214, 150, 0.30); }
body.dark-mode .mfb-heat-3 { background: rgba(111, 214, 150, 0.58); }
body.dark-mode .mfb-heat-4 { background: #6FD696; }

.mfb-heat-kaki {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 12px;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11.5px;
  color: var(--gray-400, #9A958C);
}
.mfb-heat-skala { display: flex; align-items: center; gap: 4px; }
.mfb-heat-skala .mfb-heat-kotak {
  width: 10px; height: 10px; aspect-ratio: auto; display: inline-block;
}

@media (max-width: 768px) {
  .mfb-heat-isi { padding: 4px 16px 16px; }
  .mfb-heat-kaki { font-size: 11px; flex-direction: column; align-items: flex-start; gap: 8px; }
}

/* ----------------------------------------------------------------
   23. PEMBANDING TIM vs PERUSAHAAN (HoD)
   ================================================================
   Usulan 5. HoD tidak butuh angka absolut — ia butuh POSISI.
   ---------------------------------------------------------------- */

.mfb-banding { margin-top: 16px; }
.mfb-banding-isi { padding: 6px 20px 20px; }

.mfb-banding-baris {
  display: grid;
  grid-template-columns: 76px 1fr 46px;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}
.mfb-banding-label {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12px;
  font-weight: 600;
  color: var(--gray-500, #6B6660);
}
.mfb-banding-alur {
  height: 14px;
  border-radius: 999px;
  background: var(--mfb-g-kisi);
  overflow: hidden;
}
.mfb-banding-bar {
  display: block;
  height: 100%;
  border-radius: 999px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3);
}
.mfb-banding-saya { background-image: linear-gradient(90deg, #C9A865 0%, #E8C96A 100%); }
/* Pembandingnya sengaja ABU, bukan warna kedua. Ia garis acuan,
   bukan pesaing — dua warna cerah berdampingan membuat mata harus
   memutuskan mana yang lebih penting. */
.mfb-banding-umum { background: var(--mfb-g-abu); }

.mfb-banding-num {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--gray-900, #1A1713);
  text-align: right;
}
body.dark-mode .mfb-banding-num { color: #F5F2EC; }

.mfb-banding-kalimat {
  margin: 14px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--mfb-g-kisi);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.5;
}
.mfb-banding-atas  .mfb-banding-kalimat { color: var(--mfb-g-hijau); }
.mfb-banding-bawah .mfb-banding-kalimat { color: #C2532F; }
.mfb-banding-sama  .mfb-banding-kalimat { color: var(--gray-400, #9A958C); }
body.dark-mode .mfb-banding-bawah .mfb-banding-kalimat { color: #FF8A80; }

/* ----------------------------------------------------------------
   24. SISA WAKTU DI BAGAN TAHAPAN
   ---------------------------------------------------------------- */
.mfb-tahap-sisa {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: #B8912F;
  flex: 0 0 auto;
  margin-left: 10px;
}
body.dark-mode .mfb-tahap-sisa { color: #E8C96A; }

/* ----------------------------------------------------------------
   25. LIPAT "AT A GLANCE" + PRATINJAU CONTOH
   ================================================================
   Permintaan IT Manager: "at a glance ga keseberan itu grafik? coba isi
   dummy grafik dulu kak... dan at a glance tambahi tombol collapse
   seperti AI nya kak."
   ---------------------------------------------------------------- */

.mfb-g-kepala-kanan { display: flex; align-items: center; gap: 12px; }

.mfb-g-lipat { flex: 0 0 auto; }
.mfb-g-lipat svg { transition: transform .22s ease; }
.mfb-g-lipat-aktif .mfb-g-lipat svg { transform: rotate(-90deg); }

/* Dilipat: badannya hilang, kepalanya tetap. Memakai display:none —
   bukan height 0 — supaya tidak ada sisa ruang dan tidak ada
   elemen tersembunyi yang tetap bisa di-Tab. */
.mfb-g-lipat-aktif .mfb-g-badan { display: none; }

/* --- pratinjau contoh ---
   🔴 TIGA LAPIS PENANDA, BUKAN SATU.

   Angka palsu di layar yang sama dengan angka sungguhan adalah cara
   tercepat membuat seluruh dasbor tidak bisa dipercaya. Kalau
   seorang HoD sempat mengingat "completion kita 68%", tidak ada yang
   bisa memberitahunya bahwa 68% itu karangan.

   Jadi: label menempel, warnanya dicabut (abu total, nol emas, nol
   hijau), dan kalimat penjelas tetap ada di bawahnya. */
.mfb-g-contoh {
  position: relative;
  /* Warna merek DICABUT sepenuhnya — contoh tidak boleh terlihat
     semeyakinkan data sungguhan. */
  /* 🔴 grayscale DICABUT — keputusan IT Manager 11 September 2026:
     "buat berwarna aja kak, tapi di tiap2 grafik di ujung kiri atas
     isi tulisan MOCK UP dan ada bulet kedip2 biar tau itu mockup."

     Warnanya kembali penuh. Penandanya TIDAK berkurang, hanya
     berganti jadi yang lebih menarik perhatian: label + titik
     berkedip + bingkai putus-putus. Gerakan menarik mata jauh lebih
     kuat daripada warna yang diredupkan pernah bisa. */
  opacity: 1;
  /* Bingkai putus-putus: batas "sampai mana yang palsu" harus selalu
     terlihat, bukan disimpulkan dari letak label. */
  border: 1px dashed var(--mfb-g-pemisah);
  border-radius: 10px;
  padding-left: 10px;
  padding-right: 10px;
  padding-bottom: 8px;
  pointer-events: none;
  user-select: none;
  /* 🔴 BUG NYATA di tangkapan layar IT Manager 11 September 2026:
     label "CONTOH" MENIMPA tulisan "Assigned" di Training Funnel.

     Sebabnya label itu position:absolute top:0 — ia dikeluarkan dari
     alur, jadi ia tidak pernah mendorong apa pun. Di grafik SVG
     kebetulan tidak terlihat karena ada ruang kosong di atasnya; di
     corong dan batang departemen, baris pertamanya mulai tepat di
     y=0 dan langsung tertimpa.

     Ruangnya harus DISEDIAKAN di sini, bukan dititipkan ke
     kebetulan. Efek sampingnya bagus: keempat panel jadi punya
     pangkal yang sama tingginya. */
  padding-top: 30px;
  /* Ikut meregang di dalam panel flex, supaya kalimat penjelas di
     bawahnya benar-benar sampai ke dasar. */
  flex: 1 1 auto;
}

.mfb-g-contoh-cap {
  position: absolute;
  top: 6px;
  left: 8px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px 4px 8px;
  border-radius: 999px;
  border: 1px solid #E0B94C;
  background: #FDF3D8;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #7A5A10;
  /* Labelnya harus paling jelas di antara semuanya. */
  filter: none;
  opacity: 1;
}
body.dark-mode .mfb-g-contoh-cap {
  background: #3A2F14;
  border-color: #7A5A10;
  color: #E8C96A;
}

/* --- titik berkedip ---
   Permintaan IT Manager: "ada bulet kedip2 biar tau itu mockup."

   Gerakan adalah penanda terkuat yang ada di layar — mata manusia
   menangkapnya sebelum sempat membaca satu kata pun. Itulah yang
   menggantikan tugas grayscale yang dicabut. */
.mfb-g-contoh-titik {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #D98C1F;
  flex: 0 0 auto;
  animation: mfb-kedip 1.15s ease-in-out infinite;
}
body.dark-mode .mfb-g-contoh-titik { background: #E8C96A; }

@keyframes mfb-kedip {
  0%, 100% { opacity: 1;    transform: scale(1); }
  50%      { opacity: 0.25; transform: scale(0.72); }
}

/* 🔴 Kedipan WAJIB bisa dimatikan.
   Gerakan berulang yang tidak bisa dihentikan adalah pemicu nyata
   bagi sebagian orang (mual, migrain, dan pada kasus tertentu
   kejang). Saat pemakai minta gerakan dikurangi, titiknya tetap ada
   dan tetap berwarna — ia hanya berhenti berkedip, jadi tidak ada
   informasi yang hilang. */
@media (prefers-reduced-motion: reduce) {
  .mfb-g-contoh-titik { animation: none; }
}

.mfb-g-contoh-teks {
  margin: 10px 0 0;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12px;
  line-height: 1.5;
  color: var(--gray-400, #9A958C);
}

/* ----------------------------------------------------------------
   26. GRAFIK DI HALAMAN REPORTS & AI REPORT
   ---------------------------------------------------------------- */
.mfb-rep { margin-bottom: 16px; }
.mfb-ai-grafik { margin-top: 16px; }

/* Di halaman Reports kedua panel butuh lebar yang sama — keduanya
   batang peringkat, dan membandingkannya adalah gunanya. */
.mfb-rep .mfb-g-baris-2 { border-top: 0; padding-top: 6px; margin-top: 0; }

/* ----------------------------------------------------------------
   27. LOGIN — SENTUHAN TERAKHIR
   ================================================================
   Permintaan IT Manager: "perlu apalagi login biar luxury and premium?"

   Yang tersisa setelah cahaya, kedalaman, dan koreografi adalah
   hal-hal kecil yang cuma terasa kalau ADA, dan tidak pernah
   disebut kalau tidak ada.
   ---------------------------------------------------------------- */

/* Tiga angka statistik dinaikkan bersama saat salah satunya
   disorot — memberi tahu bahwa ketiganya satu kelompok, bukan tiga
   angka yang kebetulan berdekatan. */
#desk .login-stats:hover .login-stat-n { color: #F3DFA6; }
#desk .login-stat-n { transition: color .35s ease; }

/* Logo bernapas SANGAT pelan — 9 detik sekali. Cukup untuk membuat
   halaman terasa hidup, terlalu lambat untuk disadari sebagai
   animasi. Skala 1.5% saja; lebih dari itu terbaca sebagai denyut. */
@keyframes mfb-napas {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.015); }
}
#desk .mf-logo-dark img {
  animation: mfb-napas 9s ease-in-out infinite;
  transform-origin: center;
}

/* Kolom isian yang SUDAH terisi ditandai tipis di tepi kiri.
   Di formulir dua kolom seperti ini, orang sering lupa apakah
   Employee ID sudah diketik — terutama karena teksnya otomatis
   huruf besar dan mudah tertukar dengan placeholder. */
#desk .f-input:not(:placeholder-shown) {
  border-left: 3px solid rgba(201, 168, 76, 0.55);
  padding-left: 14px;
}
#mob .lf-input:not(:placeholder-shown) {
  border-left: 3px solid rgba(201, 168, 76, 0.55);
  padding-left: 14px;
}

/* Teks "Miss Fish Bali" di panel kiri diberi bayangan halus supaya
   terbaca sebagai timbul, bukan dicetak rata di atas hitam. */
#desk .login-logo-text .brand {
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.55);
}

/* Titik berdenyut di kaki panel kiri dibuat lebih hidup: ia satu-
   satunya penanda "sistem ini menyala" di halaman sebelum login. */
#desk .pulse-dot {
  box-shadow: 0 0 0 0 rgba(201, 168, 76, 0.5);
  animation: mfb-denyut 2.8s ease-out infinite;
}
@keyframes mfb-denyut {
  0%   { box-shadow: 0 0 0 0 rgba(201, 168, 76, 0.45); }
  70%  { box-shadow: 0 0 0 9px rgba(201, 168, 76, 0); }
  100% { box-shadow: 0 0 0 0 rgba(201, 168, 76, 0); }
}

/* ----------------------------------------------------------------
   5. HORMATI PENGATURAN "KURANGI GERAKAN"
   SOP kategori 8 — animasi tidak boleh dipaksakan ke pengguna yang
   sudah mematikannya di setelan perangkat.
   ---------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .ai-card .mfb-ai-btn { transition: none; }
  .mfb-bar-versi       { animation: none; }
  /* Rangka muat berhenti berkilau tapi TETAP TAMPIL. Bentuknyalah
     yang menyampaikan "sebentar lagi ada isi di sini"; kilaunya cuma
     penegas. Menyembunyikan rangkanya sekalian akan mengembalikan
     layar kosong — persis keadaan yang mau diperbaiki. */
  .mfb-rangka-gambar,
  .mfb-rangka-baris,
  .mfb-rangka-bulat  { animation: none; background-image: none;
                       background-color: var(--mfb-rangka-1); }
  /* Sapuan cahaya di halaman login dan cincin yang berputar
     dimatikan. Keduanya murni hiasan — halamannya tetap utuh, cuma
     diam. Cincinnya TETAP TAMPIL, hanya berhenti berputar. */
  #desk .login-left-grain::after { animation: none; opacity: 0; }
  #desk .deco-circle             { animation: none; }
  #desk .deco-circle::after      { animation: none; }

  /* 🔴 KOREOGRAFI MASUK DIMATIKAN — TAPI ISINYA WAJIB TETAP TERLIHAT.
     mfb-singkap memakai clip-path yang MENYEMBUNYIKAN elemen di
     keadaan awalnya. Kalau animasinya dimatikan tanpa mengembalikan
     clip-path, judul dan angka hilang sama sekali dari halaman —
     bukan "tanpa gerakan", melainkan KOSONG. Ini jenis kesalahan
     yang cuma ketahuan kalau benar-benar diuji dengan setelan itu
     menyala. */
  #desk .login-h1,
  #desk .login-desc,
  #desk .login-stats {
    animation: none;
    clip-path: none;
    opacity: 1;
  }
  #desk .login-right::before { animation: none; transform: scaleY(1); opacity: 1; }
  #desk .btn-signin:disabled::after { animation: none; }
  .mfb-caps { animation: none; }
  /* Napas logo dan denyut titik ikut dimatikan — keduanya murni
     hiasan, dan keduanya TETAP TAMPIL, cuma diam. */
  #desk .mf-logo-dark img { animation: none; transform: none; }
  #desk .pulse-dot        { animation: none; box-shadow: none; }
  .mfb-g-lipat svg        { transition: none; }
  /* Perpindahan halaman ikut dimatikan. Bagi sebagian orang gerakan
     seperti ini memicu pusing — dan halamannya tetap berpindah
     dengan benar tanpa animasi apa pun. */
  #desk .d-page.active,
  #mob .m-page.active  { animation: none; }
}

/* ----------------------------------------------------------------
   28. KUADRAN RISIKO · GAUGE PASS RATE · PERINGKAT DEPARTEMEN
   ================================================================
   Permintaan IT Manager 11 September 2026: "gaskan semua grafik kak."

   Ketiganya dibangun dari data yang SUDAH ada di jawaban Reports
   dan Dashboard — nol permintaan jaringan tambahan, nol kolom
   database baru.
   ---------------------------------------------------------------- */

/* --- kuadran risiko --- */
.mfb-kd { height: 210px; }

.mfb-kd-bingkai {
  fill: none;
  stroke: var(--mfb-g-pemisah);
  stroke-width: 1;
}
.mfb-kd-bagi {
  stroke: var(--mfb-g-kisi);
  stroke-width: 1;
  /* Putus-putus: garis ini pembagi bantu, BUKAN target yang
     disepakati. Garis penuh akan terbaca sebagai ambang resmi. */
  stroke-dasharray: 3 4;
}
.mfb-kd-bulat {
  fill: var(--mfb-g-emas);
  fill-opacity: 0.42;
  stroke: var(--mfb-g-emas);
  stroke-width: 1.5;
}
.mfb-kd-nama {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 8.5px;
  font-weight: 700;
  fill: var(--gray-900, #1A1713);
}
body.dark-mode .mfb-kd-nama { fill: #F5F2EC; }
.mfb-kd-zona {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 7px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  fill: var(--gray-400, #9A958C);
}
.mfb-kd-sumbu {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 8px;
  font-weight: 600;
  fill: var(--gray-400, #9A958C);
}
.mfb-kd-kunci {
  margin: 8px 0 0;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11px;
  line-height: 1.45;
  color: var(--gray-400, #9A958C);
}

/* --- gauge pass rate --- */
.mfb-gauge {
  display: block;
  width: 100%;
  height: 210px;
  overflow: visible;
}
.mfb-gauge-alur { stroke: var(--mfb-g-kisi); }
.mfb-gauge-isi  { stroke: var(--mfb-g-hijau); }
.mfb-gauge-num {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 30px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  fill: var(--gray-900, #1A1713);
}
body.dark-mode .mfb-gauge-num { fill: #F5F2EC; }
.mfb-gauge-cap {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  fill: var(--gray-400, #9A958C);
}

/* --- peringkat departemen --- */
.mfb-rank { display: flex; flex-direction: column; gap: 4px; }
.mfb-rank-judul {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gray-400, #9A958C);
  margin-bottom: 2px;
}
.mfb-rank-judul-2 { margin-top: 12px; }
.mfb-rank-daftar { list-style: none; margin: 0; padding: 0; }
.mfb-rank-baris {
  display: grid;
  grid-template-columns: 20px 1fr auto;
  align-items: center;
  gap: 9px;
  padding: 7px 0;
  border-bottom: 1px solid var(--mfb-g-kisi);
}
.mfb-rank-daftar li:last-child { border-bottom: 0; }
.mfb-rank-no {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11px;
  font-weight: 800;
  color: var(--mfb-g-emas);
  text-align: center;
}
.mfb-rank-nama {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 13px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mfb-rank-num {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--gray-900, #1A1713);
}
body.dark-mode .mfb-rank-num { color: #F5F2EC; }

/* Tiga terbawah ditandai tepi kiri, BUKAN cuma warna teks merah —
   warna sendirian tidak terbaca oleh sebagian orang, dan "terbawah"
   adalah informasi yang tidak boleh hilang. */
.mfb-rank-bawah { border-left: 2px solid #D4756A; padding-left: 7px; }
body.dark-mode .mfb-rank-bawah { border-left-color: #FF8A80; }

/* ----------------------------------------------------------------
   29. TOMBOL UJI KUNCI GEMINI (halaman Settings)
   ================================================================
   Laporan IT Manager 11 September 2026: "ga ada pilihan cek gemini atau
   ai setting kak." Fungsinya sudah ada di Worker sejak v2.166, tapi
   tidak ada tombol yang memanggilnya.
   ---------------------------------------------------------------- */

.mfb-gem-kanan {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.mfb-gem-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  /* 44px — batas sentuh WCAG 2.5.5. Tombol ini juga dipakai di HP. */
  min-height: 44px;
  padding: 0 16px;
  border-radius: 9px;
  border: 1px solid var(--mfb-g-pemisah);
  background: var(--white, #FFFFFF);
  color: var(--gray-900, #1A1713);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 13px;
  font-weight: 650;
  cursor: pointer;
  white-space: nowrap;
}
.mfb-gem-btn:hover:not(:disabled) {
  border-color: var(--mfb-g-emas);
  color: var(--mfb-g-emas);
}
.mfb-gem-btn:focus-visible {
  outline: 2px solid var(--mfb-g-emas);
  outline-offset: 2px;
}
.mfb-gem-btn:disabled { opacity: 0.65; cursor: default; }
body.dark-mode .mfb-gem-btn {
  background: #1A1713;
  color: #F5F2EC;
}

.mfb-gem-putar { width: 14px; height: 14px; animation: mfb-gem-muter .9s linear infinite; }
@keyframes mfb-gem-muter { to { transform: rotate(360deg); } }
/* Putaran tunggu WAJIB bisa dimatikan — gerakan berulang yang tidak
   bisa dihentikan adalah pemicu nyata bagi sebagian orang. Ikonnya
   tetap ada, hanya berhenti berputar. */
@media (prefers-reduced-motion: reduce) {
  .mfb-gem-putar { animation: none; }
}

.mfb-gem-hasil {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 5px 11px;
  border-radius: 999px;
  cursor: help;
}
.mfb-gem-hasil:empty { display: none; }

.mfb-gem-ok    { background: #E5F6E8; color: #1A8A4A; }
/* 🔴 KUNING, bukan merah — untuk kuota habis dan gangguan Google.
   Merah berarti "ada yang salah, perbaiki". Kuota habis bukan itu:
   kuncinya benar dan tidak ada yang perlu diganti. Memberinya warna
   merah adalah cara tercepat membuat kunci sehat dicabut. */
.mfb-gem-tunda { background: #FDF3D8; color: #7A5A10; }
.mfb-gem-galat { background: #F9E5E5; color: #B03A2E; }

body.dark-mode .mfb-gem-ok    { background: #12331F; color: #6FD696; }
body.dark-mode .mfb-gem-tunda { background: #3A2F14; color: #E8C96A; }
body.dark-mode .mfb-gem-galat { background: #3A1F1F; color: #FF8A80; }

@media (max-width: 560px) {
  .mfb-gem-kanan { width: 100%; justify-content: flex-start; }
}

/* ----------------------------------------------------------------
   30. AKSI DI HALAMAN AI REPORT
   ================================================================
   Pertanyaan IT Manager 11 September 2026: "itu AI Report ga bisa
   dibuat? ga ada yg versi text seperti yg project GAS?"

   Sebelumnya laporan hanya dibuat cron jam 06:00 WITA, jadi halaman
   ini kosong sampai besok pagi — setiap kali.
   ---------------------------------------------------------------- */

.mfb-air-aksi {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 16px;
}

.mfb-air-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 44px;
  padding: 0 17px;
  border-radius: 10px;
  border: 1px solid var(--mfb-g-pemisah);
  background: var(--white, #FFFFFF);
  color: var(--gray-900, #1A1713);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 13px;
  font-weight: 650;
  cursor: pointer;
  white-space: nowrap;
}
.mfb-air-btn:hover:not(:disabled) {
  border-color: var(--mfb-g-emas);
  color: var(--mfb-g-emas);
}
.mfb-air-btn:focus-visible {
  outline: 2px solid var(--mfb-g-emas);
  outline-offset: 2px;
}
.mfb-air-btn:disabled { opacity: 0.65; cursor: default; }

/* Tombol utama diberi bobot lebih — dari dua tombol di baris ini,
   hanya satu yang membelanjakan kuota, dan itu yang harus jelas. */
.mfb-air-utama {
  background-image: linear-gradient(135deg, #C9A865 0%, #A8873F 100%);
  border-color: #A8873F;
  color: #FFFFFF;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22);
}
.mfb-air-utama:hover:not(:disabled) {
  color: #FFFFFF;
  border-color: #8A6D18;
  filter: brightness(1.06);
}

body.dark-mode .mfb-air-btn { background: #1A1713; color: #F5F2EC; }
body.dark-mode .mfb-air-utama {
  background-image: linear-gradient(135deg, #C9A865 0%, #A8873F 100%);
  color: #1A1713;
}

.mfb-air-pesan {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12.5px;
  font-weight: 650;
  line-height: 1.45;
  padding: 6px 12px;
  border-radius: 999px;
  /* Pesan "tunggu N menit" bisa panjang — ia boleh turun baris
     alih-alih mendorong tombolnya keluar layar. */
  max-width: 100%;
}
.mfb-air-pesan:empty { display: none; }

.mfb-air-ok    { background: #E5F6E8; color: #1A8A4A; }
/* 🔴 KUNING untuk "tunggu" dan "batas harian".
   Keduanya BUKAN kerusakan — justru tanda pembatasnya bekerja.
   Warna merah akan membuat IT Manager mengira ada yang rusak dan
   melaporkannya ke IT, padahal jawabannya cuma menunggu. */
.mfb-air-tunda { background: #FDF3D8; color: #7A5A10; }
.mfb-air-galat { background: #F9E5E5; color: #B03A2E; }

body.dark-mode .mfb-air-ok    { background: #12331F; color: #6FD696; }
body.dark-mode .mfb-air-tunda { background: #3A2F14; color: #E8C96A; }
body.dark-mode .mfb-air-galat { background: #3A1F1F; color: #FF8A80; }

@media (max-width: 560px) {
  .mfb-air-aksi { justify-content: stretch; }
  .mfb-air-btn { flex: 1 1 auto; justify-content: center; }
  .mfb-air-pesan { width: 100%; text-align: center; }
}

/* ----------------------------------------------------------------
   31. COMMAND PALETTE — Ctrl+K
   ================================================================
   Satu kotak, satu pintasan, ke mana pun di dalam LMS.

   Daftarnya dibaca dari menu yang BENAR-BENAR tergambar, jadi ia
   mewarisi izin — bukan menirunya. Lihat catatan di mfb-ui.js
   bagian 4v.
   ---------------------------------------------------------------- */

.mfb-pal-tirai {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  justify-content: center;
  /* Tidak di tengah vertikal — 14vh dari atas. Kotak yang muncul
     tepat di tengah layar menutupi isi yang sedang dibaca, dan
     matanya harus turun untuk menemukannya. */
  align-items: flex-start;
  padding: 14vh 20px 20px;
  background: rgba(12, 11, 8, 0.55);
  backdrop-filter: blur(3px);
  animation: mfb-pal-masuk .12s ease-out;
}
@keyframes mfb-pal-masuk { from { opacity: 0; } to { opacity: 1; } }

.mfb-pal-kotak {
  width: 100%;
  max-width: 560px;
  max-height: 68vh;
  display: flex;
  flex-direction: column;
  background: var(--white, #FFFFFF);
  border: 1px solid var(--mfb-g-pemisah);
  border-radius: 16px;
  /* Bayangan dalam + luar: kotaknya harus terasa MELAYANG di atas
     halaman, bukan tertempel padanya. */
  box-shadow:
    0 24px 64px rgba(12, 11, 8, 0.34),
    0 2px 8px rgba(12, 11, 8, 0.16),
    inset 0 1px 0 rgba(255, 255, 255, 0.7);
  overflow: hidden;
  animation: mfb-pal-naik .14s cubic-bezier(.2, .8, .3, 1);
}
@keyframes mfb-pal-naik {
  from { opacity: 0; transform: translateY(-8px) scale(.985); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
body.dark-mode .mfb-pal-kotak {
  background: #16130F;
  box-shadow:
    0 24px 64px rgba(0, 0, 0, 0.6),
    inset 0 1px 0 rgba(255, 255, 255, 0.06);
}

/* --- baris pencarian --- */
.mfb-pal-atas {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 0 16px;
  height: 56px;
  border-bottom: 1px solid var(--mfb-g-kisi);
  flex: 0 0 auto;
}
.mfb-pal-ikon { width: 17px; height: 17px; color: var(--gray-400, #9A958C); flex: 0 0 auto; }
.mfb-pal-input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--gray-900, #1A1713);
  font-family: 'Inter', system-ui, sans-serif;
  /* 🔴 16px, bukan lebih kecil. iOS Safari memperbesar seluruh
     halaman begitu kolom di bawah 16px mendapat fokus — dan
     halamannya tidak pernah kembali ke ukuran semula. */
  font-size: 16px;
  font-weight: 500;
}
body.dark-mode .mfb-pal-input { color: #F5F2EC; }
.mfb-pal-input::placeholder { color: var(--gray-400, #9A958C); font-weight: 400; }

kbd, .mfb-pal-esc {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 10.5px;
  font-weight: 700;
  padding: 3px 7px;
  border-radius: 5px;
  background: var(--mfb-g-kisi);
  color: var(--gray-400, #9A958C);
  flex: 0 0 auto;
}

/* --- hasil --- */
.mfb-pal-daftar {
  list-style: none;
  margin: 0;
  padding: 7px;
  overflow-y: auto;
  flex: 1 1 auto;
  overscroll-behavior: contain;
}
.mfb-pal-daftar::-webkit-scrollbar { width: 7px; }
.mfb-pal-daftar::-webkit-scrollbar-thumb {
  background: var(--mfb-g-pemisah); border-radius: 7px;
}

.mfb-pal-item {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 12px;
  border-radius: 9px;
  cursor: pointer;
  /* 44px — batas sentuh WCAG 2.5.5, karena palette juga terbuka
     di layar sentuh yang punya keyboard. */
  min-height: 44px;
}
.mfb-pal-aktif { background: var(--mfb-g-kisi); }
body.dark-mode .mfb-pal-aktif { background: rgba(255, 255, 255, 0.07); }

.mfb-pal-tag {
  flex: 0 0 auto;
  min-width: 62px;
  padding: 3px 8px;
  border-radius: 999px;
  background: var(--mfb-g-kisi);
  color: var(--gray-500, #6B6660);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-align: center;
}
.mfb-pal-nama {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 600;
  color: var(--gray-900, #1A1713);
}
body.dark-mode .mfb-pal-nama { color: #F5F2EC; }
.mfb-pal-sisi {
  flex: 0 0 auto;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--mfb-g-emas);
}

.mfb-pal-kosong {
  margin: 0;
  padding: 26px 16px;
  text-align: center;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 13.5px;
  color: var(--gray-400, #9A958C);
}

/* --- kaki --- */
.mfb-pal-bawah {
  display: flex;
  gap: 16px;
  padding: 9px 16px;
  border-top: 1px solid var(--mfb-g-kisi);
  flex: 0 0 auto;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11px;
  color: var(--gray-400, #9A958C);
}
.mfb-pal-bawah span { display: inline-flex; align-items: center; gap: 5px; }
.mfb-pal-bawah kbd { padding: 2px 6px; font-size: 10px; }

@media (max-width: 560px) {
  .mfb-pal-tirai { padding: 8vh 12px 12px; }
  /* Petunjuk keyboard disembunyikan di layar sentuh — menampilkan
     "tekan Esc" ke orang yang tidak punya Esc cuma menambah bising. */
  .mfb-pal-bawah, .mfb-pal-esc { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .mfb-pal-tirai, .mfb-pal-kotak { animation: none; }
}

/* ----------------------------------------------------------------
   32. "LANJUTKAN DARI TERAKHIR"
   ================================================================
   Satu kartu, satu tombol, langsung ke course yang tinggal sedikit
   lagi selesai. Ini fitur tampilan yang paling berpengaruh ke angka
   completion — lihat catatan di mfb-ui.js bagian 4w.
   ---------------------------------------------------------------- */

/* 🔴 DIRINGKAS 18 September 2026. Laporan IT Manager: "continue training
   kayaknya kegedean". Sebelumnya ±140px di HP karena isinya ditumpuk
   dengan tombol selebar kartu setinggi 52px.

   cursor:pointer karena SELURUH kartu kini area sentuh — targetnya
   justru lebih besar daripada tombol selebar kartu yang digantikan. */
.mfb-lanjut {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 16px;
  padding: 14px 16px;
  border-radius: 14px;
  cursor: pointer;
  /* Hitam hangat ke emas gelap — bahasa yang sama dengan sidebar,
     jadi kartu ini terbaca sebagai bagian aplikasi, bukan iklan
     yang nyasar masuk. */
  background-image: linear-gradient(118deg, #16130F 0%, #241E12 46%, #3A2E17 100%);
  border: 1px solid rgba(201, 168, 76, 0.34);
  box-shadow:
    0 10px 30px rgba(12, 11, 8, 0.22),
    inset 0 1px 0 rgba(255, 244, 214, 0.12);
  position: relative;
  overflow: hidden;
}

/* 🔴 KILAU EMAS DIBUANG SELURUHNYA, bukan sekadar dimatikan.

   Ia melukis ulang SELURUH kartu setiap frame, selamanya — bukan
   hanya saat digulir, bukan hanya sekali. v2.189 membuang dua blur
   dengan alasan yang sama persis ("tanpa mengorbankan kecepatan"),
   dan alasan itu berlaku lebih kuat di sini karena kartunya sekarang
   jauh lebih kecil sementara biayanya tetap sama.

   Yang hilang cuma kesan "hidup" yang memang sudah dibawa titik
   hijau berdenyut di bawah — jadi nol isyarat yang benar-benar hilang. */

.mfb-lanjut-isi { flex: 1 1 auto; min-width: 0; position: relative; z-index: 1; }

.mfb-lanjut-cap {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #E8C96A;
}
.mfb-lanjut-titik {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #6FD696;
  box-shadow: 0 0 0 0 rgba(111, 214, 150, 0.6);
  animation: mfb-lanjut-denyut 2.2s ease-out infinite;
}
@keyframes mfb-lanjut-denyut {
  0%   { box-shadow: 0 0 0 0 rgba(111, 214, 150, 0.55); }
  70%  { box-shadow: 0 0 0 8px rgba(111, 214, 150, 0); }
  100% { box-shadow: 0 0 0 0 rgba(111, 214, 150, 0); }
}

.mfb-lanjut-judul {
  margin: 6px 0 3px;
  font-family: 'Cinzel', Georgia, serif;
  font-size: 15.5px;
  font-weight: 700;
  line-height: 1.25;
  color: #F5EFE2;
  /* Judul panjang dipotong di dua baris, bukan mendorong tombolnya
     keluar kartu. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.mfb-lanjut-sisa {
  margin: 0;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12px;
  font-weight: 500;
  color: rgba(245, 239, 226, 0.72);
}

.mfb-lanjut-btn {
  flex: 0 0 auto;
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 44px;
  padding: 0 15px;
  border-radius: 11px;
  border: 1px solid #8A6D18;
  /* background-color EKSPLISIT — gradien tembus pandang di atas
     warna tombol bawaan halaman adalah persis bug yang membuat
     tombol "Muat ulang" tidak terbaca (lihat bagian 5). */
  background-color: #C9A865;
  background-image: linear-gradient(180deg, #E0C079 0%, #B8963F 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.38),
    0 4px 14px rgba(201, 168, 76, 0.28);
  /* Teks gelap di atas emas terang — 6,4:1. */
  color: #1A1713;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12.5px;
  font-weight: 800;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: transform .16s cubic-bezier(.2,.8,.3,1), box-shadow .16s ease, filter .16s ease;
}
.mfb-lanjut-btn svg { width: 17px; height: 17px; transition: transform .16s ease; }
.mfb-lanjut-btn:hover {
  filter: brightness(1.06);
  transform: translateY(-1px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.38), 0 7px 20px rgba(201,168,76,.38);
}
.mfb-lanjut-btn:hover svg { transform: translateX(3px); }
.mfb-lanjut-btn:active { transform: translateY(0); filter: brightness(.97); }
.mfb-lanjut-btn:focus-visible { outline: 2px solid #E8C96A; outline-offset: 3px; }

/* --- HP --- */
@media (max-width: 640px) {
  .mfb-lanjut {
    /* 🔴 TIDAK DITUMPUK LAGI. Prinsip lamanya — tombol kecil di pojok
       kanan adalah jarak jempol terjauh — tetap dipenuhi, tapi lewat
       SELURUH KARTU yang jadi area sentuh, bukan lewat tombol selebar
       kartu yang membuatnya setinggi ±140px. */
    gap: 12px;
    padding: 13px 14px;
    margin-bottom: 14px;
    border-radius: 14px;
  }
  .mfb-lanjut-btn { min-height: 44px; padding: 0 13px; }
  .mfb-lanjut-judul { font-size: 15px; }
}

@media (prefers-reduced-motion: reduce) {
  .mfb-lanjut-titik  { animation: none; }
  .mfb-lanjut-btn    { transition: none; }
  .mfb-lanjut-btn:hover svg { transform: none; }
}

/* ----------------------------------------------------------------
   33. ANIMASI MASUK GRAFIK
   ================================================================
   Permintaan IT Manager 12 September 2026: "untuk grafik, pertama kali
   load, dia bergerak dong dari 0 ke angkanya kak?"

   Angkanya diurus JavaScript (bagian 4x). Di sini yang diurus
   BENTUKNYA: batang tumbuh dari nol, garis menggambar dirinya
   sendiri, donat menyapu masuk.

   🔴 SEMUANYA DIPICU SATU KELAS: .mfb-anim, yang dipasang SEKALI
   per kartu. Tanpa itu, MutationObserver akan memicunya berulang
   dan kartunya tidak pernah diam.
   ---------------------------------------------------------------- */

/* --- batang departemen & jumlah ---
   transform: scaleX, bukan width. Browser bisa menganimasikan
   transform tanpa menghitung ulang tata letak seluruh halaman;
   width memaksa itu di setiap frame. Di HP kelas bawah, bedanya
   antara mulus dan tersendat.

   Aman dipakai di sini KHUSUS karena isian batang tidak lagi berisi
   teks — nama & angkanya saudara isian, bukan anaknya (bagian 27). */
.mfb-anim .mfb-bar-isi {
  transform-origin: left center;
  animation: mfb-anim-tumbuh .75s cubic-bezier(.22, .9, .3, 1) both;
}
@keyframes mfb-anim-tumbuh {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}
/* Berurutan, bukan serentak. Empat batang yang muncul bersamaan
   terbaca sebagai satu kedipan; berurutan terbaca sebagai daftar
   yang sedang dibacakan. */
.mfb-anim .mfb-bar-baris:nth-child(1) .mfb-bar-isi { animation-delay: .02s; }
.mfb-anim .mfb-bar-baris:nth-child(2) .mfb-bar-isi { animation-delay: .09s; }
.mfb-anim .mfb-bar-baris:nth-child(3) .mfb-bar-isi { animation-delay: .16s; }
.mfb-anim .mfb-bar-baris:nth-child(4) .mfb-bar-isi { animation-delay: .23s; }
.mfb-anim .mfb-bar-baris:nth-child(5) .mfb-bar-isi { animation-delay: .30s; }
.mfb-anim .mfb-bar-baris:nth-child(6) .mfb-bar-isi { animation-delay: .37s; }

/* --- corong tahapan ---
   clip-path, BUKAN scaleX: batang corong berisi teks di dalamnya,
   dan scaleX akan meregangkan hurufnya. clip-path menyingkap dari
   kiri tanpa menyentuh apa pun yang ada di dalamnya. */
.mfb-anim .mfb-corong-batang {
  animation: mfb-anim-singkap .8s cubic-bezier(.22, .9, .3, 1) both;
}
@keyframes mfb-anim-singkap {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}
.mfb-anim .mfb-corong-baris:nth-child(1) .mfb-corong-batang { animation-delay: .04s; }
.mfb-anim .mfb-corong-baris:nth-child(2) .mfb-corong-batang { animation-delay: .13s; }
.mfb-anim .mfb-corong-baris:nth-child(3) .mfb-corong-batang { animation-delay: .22s; }
.mfb-anim .mfb-corong-baris:nth-child(4) .mfb-corong-batang { animation-delay: .31s; }
/* Persen susut muncul SESUDAH batangnya sampai — kalau bersamaan,
   angka itu terbaca sebelum ada yang bisa dibandingkan dengannya. */
.mfb-anim .mfb-corong-susut { animation: mfb-anim-muncul .4s ease-out .5s both; }
@keyframes mfb-anim-muncul { from { opacity: 0; } to { opacity: 1; } }

/* --- grafik garis: menggambar dirinya sendiri ---
   pathLength="1" di JS membuat panjang jalur dianggap 1 satuan,
   berapa pun panjang aslinya — jadi kecepatan menggambarnya sama
   untuk grafik pendek maupun panjang, tanpa JavaScript perlu
   mengukur apa pun. */
.mfb-anim .mfb-g-garis {
  stroke-dasharray: 1 1;
  animation: mfb-anim-gambar 1.1s cubic-bezier(.4, 0, .25, 1) both;
}
@keyframes mfb-anim-gambar {
  from { stroke-dashoffset: 1; }
  to   { stroke-dashoffset: 0; }
}
/* Arsiran di bawah garis menyusul, bukan mendahului. */
.mfb-anim .mfb-g-isi   { animation: mfb-anim-muncul .7s ease-out .45s both; }
/* Noktah muncul satu per satu, mengikuti garis yang sedang digambar. */
.mfb-anim .mfb-g-noktah { animation: mfb-anim-noktah .34s cubic-bezier(.3,1.4,.5,1) both; }
@keyframes mfb-anim-noktah {
  from { opacity: 0; transform: scale(0); }
  to   { opacity: 1; transform: scale(1); }
}
.mfb-anim .mfb-g-noktah:nth-of-type(1) { animation-delay: .22s; }
.mfb-anim .mfb-g-noktah:nth-of-type(2) { animation-delay: .36s; }
.mfb-anim .mfb-g-noktah:nth-of-type(3) { animation-delay: .50s; }
.mfb-anim .mfb-g-noktah:nth-of-type(4) { animation-delay: .64s; }
.mfb-anim .mfb-g-noktah:nth-of-type(5) { animation-delay: .78s; }
.mfb-anim .mfb-g-noktah:nth-of-type(6) { animation-delay: .92s; }

/* --- donat & gauge ---
   Keduanya sudah memakai stroke-dasharray untuk menggambar
   potongannya, jadi menganimasikan dasharray akan bertabrakan
   dengan datanya sendiri. Yang diputar justru seluruh cincinnya —
   efeknya sama-sama "menyapu masuk", tanpa menyentuh angkanya. */
.mfb-anim .mfb-g-donat,
.mfb-anim .mfb-gauge {
  animation: mfb-anim-sapu .85s cubic-bezier(.22, .9, .3, 1) both;
  transform-origin: center;
}
@keyframes mfb-anim-sapu {
  from { opacity: 0; transform: rotate(-26deg) scale(.9); }
  to   { opacity: 1; transform: rotate(0) scale(1); }
}

/* --- peringkat departemen --- */
.mfb-anim .mfb-rank-baris { animation: mfb-anim-geser .45s ease-out both; }
@keyframes mfb-anim-geser {
  from { opacity: 0; transform: translateX(-10px); }
  to   { opacity: 1; transform: translateX(0); }
}
.mfb-anim .mfb-rank-baris:nth-child(1) { animation-delay: .05s; }
.mfb-anim .mfb-rank-baris:nth-child(2) { animation-delay: .12s; }
.mfb-anim .mfb-rank-baris:nth-child(3) { animation-delay: .19s; }

/* --- heatmap: menyala petak demi petak, kolom per kolom --- */
.mfb-anim .mfb-heat-petak { animation: mfb-anim-muncul .5s ease-out both; }

/* ----------------------------------------------------------------
   🔴 SELURUHNYA BERHENTI SAAT PEMAKAI MINTA GERAKAN DIKURANGI.
   Bukan diperlambat — DIMATIKAN, dan bentuk akhirnya langsung
   dipasang. Animasi masuk yang bertubi-tubi di satu layar adalah
   pemicu nyata bagi sebagian orang, dan grafiknya sama sekali tidak
   kehilangan makna tanpa gerakan.
   ---------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .mfb-anim .mfb-bar-isi,
  .mfb-anim .mfb-corong-batang,
  .mfb-anim .mfb-corong-susut,
  .mfb-anim .mfb-g-garis,
  .mfb-anim .mfb-g-isi,
  .mfb-anim .mfb-g-noktah,
  .mfb-anim .mfb-g-donat,
  .mfb-anim .mfb-gauge,
  .mfb-anim .mfb-rank-baris,
  .mfb-anim .mfb-heat-petak {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
    stroke-dasharray: none !important;
  }
}

/* 🔴 KONFETI BAWAAN v2.144 IKUT DIJINAKKAN.
   Baseline menjatuhkan 80 potong konfeti selama 3,5 detik tanpa
   satu pun penjaga gerakan. Untuk sebagian orang itu bukan
   perayaan — itu pemicu vertigo, dan mereka tidak punya cara
   menghentikannya. Kelulusan quiz-nya tetap dirayakan lewat teks,
   ikon, dan skor besar di tengah layar. */
@media (prefers-reduced-motion: reduce) {
  .confetti-piece { display: none !important; }
  .confetti-overlay, .confetti-overlay.show { display: none !important; }
}

/* ----------------------------------------------------------------
   34. PEMBERITAHUAN HAK CIPTA
   ================================================================
   Permintaan IT Manager 12 September 2026.

   Nadanya sengaja TENANG, bukan mengancam. Pemberitahuan yang
   berteriak di kaki halaman membuat staff sendiri merasa dicurigai
   setiap hari — padahal merekalah yang paling sering melihatnya,
   dan bukan mereka yang jadi kekhawatirannya.

   Lihat catatan di mfb-ui.js bagian 4y soal apa yang sebenarnya
   dilakukan dan TIDAK dilakukan pemberitahuan seperti ini.
   ---------------------------------------------------------------- */

.mfb-cipta {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.02em;
  line-height: 1.5;
  cursor: help;
}

/* --- login desktop --- */
.mfb-cipta-login {
  width: 100%;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--mfb-g-kisi);
  color: var(--gray-400, #9A958C);
  text-align: center;
}

/* --- login HP ---
   🔴 v1.50 — SEKARANG DI LATAR GELAP, BUKAN DI DALAM KARTU PUTIH.

   Baris ini dulu tinggal di dalam kartu login dan menambah
   tingginya, sehingga pita hitam di bawah kartu habis. Di GAS
   kartunya menggantung; laporan IT Manager 18 September 2026 benar.

   Sesudah pindah, ia jadi keterangan DOKUMEN — yang memang
   tempatnya di luar kartu tugas, bukan di dalamnya. Garis pemisah
   dibuang: di dalam kartu ia memisahkan dari isi kartu, di latar
   gelap ia cuma jadi coretan yang tidak memisahkan apa pun.

   Warnanya redup dengan sengaja. Ia harus bisa diabaikan oleh
   orang yang sedang buru-buru masuk kerja, dan tetap terbaca oleh
   yang mencarinya. */
.mfb-cipta-login-hp {
  margin: 14px 10px calc(12px + env(safe-area-inset-bottom, 0px));
  padding-top: 0;
  border-top: 0;
  /* 🔴 0,36 -> 0,55, 18 September 2026. Laporan IT Manager: "kurang
     terlihat jelas". Diukur, bukan dikira-kira.

     Teks ini KECIL, jadi ambang WCAG AA-nya 4,5:1 — bukan 3:1 yang
     berlaku untuk teks besar. Pada 0,36 kontrasnya cuma 3,23–3,34
     (diukur terhadap dua titik gradien latar), yaitu GAGAL.

     Ambang lolos ada di 0,50. Dipakai 0,55, bukan lebih tinggi, dan
     itu disengaja: ini baris hak cipta dan ia HARUS tetap sekunder.
     Teks hukum yang menyolok mencuri perhatian dari tombol Sign In —
     kemunduran yang berbeda, tapi tetap kemunduran. 0,55 memberi
     6,1–6,3:1, cukup longgar kalau perkiraan warna latar meleset,
     tanpa membuatnya berteriak. */
  color: rgba(255, 255, 255, 0.55);
  text-align: center;
  position: relative;
  z-index: 1;
}
/* Tombol "?" ikut pindah ke latar gelap — di kertas putih ia gelap,
   di sini ia harus terang, kalau tidak ia hilang sama sekali. */
.mfb-cipta-login-hp .mfb-cipta-tanya {
  color: rgba(255, 255, 255, 0.5);
  border-color: rgba(255, 255, 255, 0.28);
}

/* --- kaki sidebar ---
   Paling redup di antara semuanya. Ia hadir terus-menerus, jadi ia
   harus bisa diabaikan — kalau tidak, ia berubah jadi kebisingan
   yang dilihat ratusan kali sehari. */
.mfb-cipta-sidebar {
  margin-top: 6px;
  font-size: 9.5px;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.30);
}

/* --- halaman Profile: pemberitahuan lengkap ---
   🔴 v1.37 — DIBUAT MENONJOL atas permintaan IT Manager (14 Sep 2026):
   "yg sekarang kurang eye catching kak. isi kedip2? ganti warna?"

   Yang dipilih: KONTRAS, bukan kedipan. Panel ini jadi satu-satunya
   bidang gelap di area konten yang terang — mata berhenti di sana
   tanpa perlu dipaksa bergerak. Kedipan sengaja TIDAK dipakai:
   dilarang WCAG 2.2.2 & 2.3.1, cepat diabaikan mata (sesudah hari
   ketiga ia tidak terlihat lagi), dan terbaca sebagai alarm.

   Satu-satunya gerak: kilau emas yang lewat SEKALI saat panel muncul,
   lalu berhenti — dan tidak sama sekali untuk yang meminta gerak
   dikurangi. Komposisinya meniru panel hero & AI: hitam hangat,
   bingkai emas tipis, lambang dalam lingkaran, tulisan judul Cinzel. */
.mfb-cipta-penuh {
  position: relative;
  overflow: hidden;
  margin-top: 22px;
  padding: 22px 26px;
  display: flex;
  align-items: center;
  gap: 22px;
  border-radius: 14px;
  border: 1px solid rgba(232, 201, 106, 0.38);
  background:
    radial-gradient(ellipse at 0% 50%, rgba(201, 160, 101, 0.16) 0%, transparent 55%),
    linear-gradient(135deg, var(--mfb-chrome-atas, #17130D), var(--mfb-chrome-bawah, #0A0908));
  box-shadow:
    inset 0 1px 0 rgba(255, 244, 214, 0.13),
    0 2px 6px rgba(0, 0, 0, 0.22),
    0 14px 34px rgba(0, 0, 0, 0.16);
}
/* Garis emas di tepi kiri — penanda "dokumen resmi" yang sama dengan
   ornamen emas di bagian lain LMS. */
.mfb-cipta-penuh::before {
  content: '';
  position: absolute;
  left: 0;
  top: 18px;
  bottom: 18px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: linear-gradient(180deg, transparent, var(--mfb-emas, #E8C96A), transparent);
}
/* Kilau sekali lewat. */
.mfb-cipta-penuh::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: -40%;
  width: 40%;
  pointer-events: none;
  background: linear-gradient(100deg, transparent, rgba(255, 236, 190, 0.10), transparent);
  transform: translateX(0);
  animation: mfb-cipta-kilau 1.6s cubic-bezier(.4, 0, .2, 1) .35s 1 both;
}
@keyframes mfb-cipta-kilau {
  from { transform: translateX(0); }
  to   { transform: translateX(360%); }
}

.mfb-cipta-lambang {
  flex-shrink: 0;
  width: 58px;
  height: 58px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--mfb-emas, #E8C96A);
  border: 1px solid rgba(232, 201, 106, 0.5);
  box-shadow: inset 0 0 0 4px rgba(232, 201, 106, 0.07), 0 0 28px rgba(201, 160, 101, 0.18);
}
.mfb-cipta-lambang svg { width: 28px; height: 28px; display: block; }

.mfb-cipta-teks { flex: 1; min-width: 0; }

.mfb-cipta-judul {
  font-family: 'Cinzel', Georgia, 'Times New Roman', serif;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--mfb-emas, #E8C96A);
  margin-bottom: 8px;
}
.mfb-cipta-isi {
  margin: 0;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 13px;
  line-height: 1.65;
  /* Terukur 12,19 : 1 di ujung panel yang paling terang (#17130D). */
  color: #D8D1C4;
}

/* Cap "CONFIDENTIAL": bingkai ganda dan huruf renggang, seperti cap
   di dokumen cetak. Diam, tanpa gerak — ia sudah menonjol karena
   bentuknya. */
.mfb-cipta-cap {
  flex-shrink: 0;
  align-self: center;
  padding: 7px 14px;
  border: 1.5px solid rgba(232, 201, 106, 0.7);
  outline: 1px solid rgba(232, 201, 106, 0.28);
  outline-offset: 3px;
  border-radius: 4px;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--mfb-emas, #E8C96A);
  transform: rotate(-4deg);
  user-select: none;
}

/* HP & layar sempit: cap turun ke bawah teks, bukan memeras teksnya. */
@media (max-width: 760px) {
  .mfb-cipta-penuh { flex-wrap: wrap; padding: 20px; gap: 16px; }
  .mfb-cipta-lambang { width: 46px; height: 46px; }
  .mfb-cipta-lambang svg { width: 22px; height: 22px; }
  .mfb-cipta-teks { flex-basis: calc(100% - 62px); }
  .mfb-cipta-cap { margin-left: 62px; }
}
@media (prefers-reduced-motion: reduce) {
  .mfb-cipta-penuh::after { animation: none; display: none; }
}

/* ----------------------------------------------------------------
   🔴 YANG PALING PENTING: IKUT TERCETAK.
   ================================================================
   Pemberitahuan di layar hanya melindungi layar. Begitu sebuah
   sertifikat atau laporan dicetak — atau disimpan sebagai PDF lewat
   dialog cetak — ia berjalan sendiri ke tangan orang lain, dan di
   situlah justru pemberitahuannya paling dibutuhkan.

   Kertasnya juga tidak punya tooltip, jadi versi PANJANG yang
   dicetak, bukan yang pendek.
   ---------------------------------------------------------------- */
@media print {
  /* Muncul di setiap halaman cetakan, bukan cuma yang pertama. */
  body::after {
    content: '© 2026 Miss Fish Bali · Proprietary & Confidential · '
             'Internal use only. Reproduction or distribution without '
             'written authorisation is not permitted.';
    display: block;
    margin-top: 14px;
    padding-top: 8px;
    border-top: 1px solid #999;
    font-family: 'Inter', system-ui, sans-serif;
    font-size: 8.5pt;
    line-height: 1.45;
    color: #444;
    text-align: center;
  }
  /* Yang di layar tidak perlu ikut tercetak dua kali. */
  .mfb-cipta-sidebar, .mfb-cipta-login, .mfb-cipta-login-hp { display: none; }
  /* 🔴 v1.37 — panel Profile kini GELAP. Kebanyakan peramban membuang
     warna latar saat mencetak, sehingga teks emas-mudanya jatuh di atas
     kertas putih dan tidak terbaca. Pemberitahuan versi cetak sudah
     ditulis body::after di atas, jadi panel layar cukup disembunyikan. */
  .mfb-cipta-penuh { display: none; }
}

/* ----------------------------------------------------------------
   35. BALON HAK CIPTA (tanda tanya)
   ================================================================
   Permintaan IT Manager 12 September 2026: "tanda tanya itu bisa ga
   muncul info lengkap, macam baloon popup kecil gitu?"

   Dibuat <button>, bukan atribut title. Tooltip bawaan browser
   muncul terlambat, tidak pernah muncul di layar sentuh, dan tidak
   bisa dijangkau keyboard — lihat catatan di mfb-ui.js bagian 4y.
   ---------------------------------------------------------------- */

.mfb-cipta { position: relative; }

.mfb-cipta-tanya {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Lingkaran kecil, tapi area sentuhnya diperbesar ::after di bawah
     sampai 44px — supaya rapi di layar besar TANPA jadi sasaran yang
     mustahil dikenai jempol. */
  width: 15px;
  height: 15px;
  margin-left: 6px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid currentColor;
  background: transparent;
  color: inherit;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 9.5px;
  font-weight: 800;
  line-height: 1;
  cursor: pointer;
  vertical-align: middle;
  opacity: 0.75;
}
.mfb-cipta-tanya::after {
  /* Area sentuh 44px yang tidak terlihat — WCAG 2.5.5. */
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
}
.mfb-cipta-tanya:hover { opacity: 1; }
.mfb-cipta-tanya:focus-visible {
  outline: 2px solid var(--mfb-g-emas);
  outline-offset: 2px;
  opacity: 1;
}

.mfb-cipta-balon {
  position: absolute;
  /* Terbit KE ATAS. Pemberitahuan ini selalu duduk di kaki halaman,
     jadi balon yang terbit ke bawah akan keluar layar. */
  bottom: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 9500;
  width: max-content;
  max-width: min(320px, calc(100vw - 32px));
  padding: 11px 14px;
  border-radius: 10px;
  border: 1px solid rgba(201, 168, 76, 0.35);
  background: #16130F;
  color: #F5EFE2;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.42);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11.5px;
  font-weight: 400;
  line-height: 1.55;
  letter-spacing: 0;
  text-align: left;
  /* Balonnya sendiri tidak boleh menangkap kursor — kalau ia
     menangkap, menggeser kursor ke arahnya justru memicu mouseleave
     pada tombolnya dan balonnya berkedip-kedip. */
  pointer-events: none;
  animation: mfb-balon-masuk .14s ease-out;
}
@keyframes mfb-balon-masuk {
  from { opacity: 0; transform: translateX(-50%) translateY(4px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .mfb-cipta-balon { animation: none; }
}

/* Ekor balon. */
.mfb-cipta-balon::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: #16130F;
}

/* Di sidebar gelap, balonnya justru harus TERANG supaya terpisah
   dari latar hitam di belakangnya. */
#desk .sidebar-footer .mfb-cipta-balon {
  background: #F7F5F1;
  color: #26231F;
  border-color: rgba(60, 44, 20, 0.2);
}
#desk .sidebar-footer .mfb-cipta-balon::after { border-top-color: #F7F5F1; }

@media (max-width: 560px) {
  /* Di layar sempit balonnya dipatok ke tepi kiri kartu, bukan ke
     tengah tombol — kalau tidak, separuhnya keluar layar. */
  .mfb-cipta-balon { left: 0; transform: none; max-width: calc(100vw - 40px); }
  .mfb-cipta-balon::after { left: 18px; transform: none; }
  @keyframes mfb-balon-masuk {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0); }
  }
}

@media print { .mfb-cipta-tanya { display: none !important; } }

/* ----------------------------------------------------------------
   36. EMPAT KPI UTAMA + BARIS TIPIS
   ----------------------------------------------------------------

   IT Manager: "tolong fix ini kak" — tujuh kartu angka berukuran sama,
   semuanya berteriak sama kerasnya, jadi tidak ada satu pun yang
   terdengar.

   v2.174 sudah merapikannya jadi satu baris berisi tujuh (bagian
   2e). Rapi, tapi belum menjawab pertanyaan GM. Di sini tujuh itu
   DIPILAH: empat yang benar-benar menggerakkan keputusan naik jadi
   KPI besar, tiga sisanya turun jadi baris tipis.

   🔴 TIGA YANG TURUN TIDAK DISEMBUNYIKAN. Tidak ada tombol lipat.
   Angka yang bisa disembunyikan akan disembunyikan, lalu tidak
   pernah dibuka lagi — dan angka itu tetap perlu ada saat ditanya.
   Lihat SOP kategori 21.8.
   ---------------------------------------------------------------- */

#desk .mfb-stat-satu-baris.mfb-stat-pilah {
  grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
  gap: 14px !important;
  margin-bottom: 12px !important;
}

/* Kartu utama menonjol lewat URUTAN dan konteks, bukan lewat ukuran.
   Laporan IT Manager 12 September 2026: "4 statcard kayaknya kegedean."
   Ia benar — versi pertama memberi kartu padding 20px dan angka 33px,
   sehingga empat kartu memakan hampir sepertiga layar sebelum satu
   grafik pun terlihat. Yang membuat sebuah angka menonjol bukan
   besarnya, tapi bahwa ia berdiri paling atas dan membawa target. */
#desk .mfb-stat-pilah .stat-card       { padding: 14px 16px; gap: 2px; }
#desk .mfb-stat-pilah .stat-card-top   { margin-bottom: 6px; }
#desk .mfb-stat-pilah .stat-card-num   { font-size: 26px; letter-spacing: -0.02em; line-height: 1.15; }
#desk .mfb-stat-pilah .stat-card-label { font-size: 11.5px; }
#desk .mfb-stat-pilah .stat-card-sub   { font-size: 10px; }
#desk .mfb-stat-pilah .stat-card-icon  { width: 28px; height: 28px; font-size: 13px; border-radius: 8px; }

/* Kartu KPI yang sedang bermasalah diberi tepi kiri merah — penanda
   BENTUK, bukan warna saja, jadi tetap terbaca di layar pudar. */
#desk .stat-card.mfb-kpi-bahaya { position: relative; }
#desk .stat-card.mfb-kpi-bahaya::before {
  content: '';
  position: absolute;
  left: 0; top: 14%;
  width: 3px; height: 72%;
  border-radius: 0 3px 3px 0;
  background: var(--red, #D9534F);
}

/* --- baris target + selisih --- */

.mfb-kpi-kaki {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: 7px;
  flex-wrap: wrap;
}

.mfb-kpi-delta {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 10.5px;
  font-weight: 800;
  padding: 2px 7px;
  border-radius: 20px;
  letter-spacing: .02em;
  white-space: nowrap;
}
.mfb-kpi-delta.naik  { color: #1B6B3A; background: rgba(40, 160, 90, 0.14); }
.mfb-kpi-delta.turun { color: #9B2C24; background: rgba(200, 70, 60, 0.14); }
/* 🔴 Tidak ada pembanding periode lalu = tidak ada panah. Tanda
   hubung, bukan panah karangan. Lihat SOP kategori 21.9. */
.mfb-kpi-delta.kosong {
  color: var(--gray-400, #9A9A9A);
  background: rgba(140, 140, 140, 0.12);
  font-weight: 700;
}

.mfb-kpi-target {
  font-size: 10.5px;
  font-weight: 700;
  color: var(--gray-500, #6E6E6E);
  white-space: nowrap;
}
.mfb-kpi-target b { color: var(--gold, #C9A865); font-weight: 800; }

/* Batang tipis ke target — hanya untuk KPI yang satuannya persen. */
.mfb-kpi-bar {
  width: 100%;
  height: 4px;
  margin-top: 7px;
  border-radius: 999px;
  background: rgba(140, 140, 140, 0.18);
  position: relative;
  overflow: hidden;
}
.mfb-kpi-bar-isi {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--gold, #C9A865), #E8C97A);
}
/* Garis target — penanda tegas di posisi target, bukan warna saja. */
.mfb-kpi-bar-target {
  position: absolute;
  top: -2px; bottom: -2px;
  width: 2px;
  background: #4A4A4A;
  border-radius: 2px;
}

/* --- baris tipis untuk tiga angka pendukung --- */

#desk .mfb-stat-tipis {
  display: flex;
  align-items: stretch;
  flex-wrap: wrap;
  gap: 0;
  margin-bottom: 26px;
  padding: 0;
  border-radius: 12px;
  border: 1px solid var(--gray-100, #E8E8E8);
  background: var(--white, #FFF);
  overflow: hidden;
}
body.dark-mode #desk .mfb-stat-tipis {
  background: var(--white) !important;
  border-color: var(--gray-100) !important;
}

/* Kartu yang dipindahkan ke sini dilucuti jadi sel datar. Kelas
   .stat-card-nya TIDAK dihapus — supaya kalau lapisan ini dicopot,
   ia kembali jadi kartu biasa seperti v2.144. */
#desk .mfb-stat-tipis .stat-card {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: row;
  align-items: baseline;
  gap: 7px;
  padding: 11px 16px;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: transparent;
}
body.dark-mode #desk .mfb-stat-tipis .stat-card {
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
}
#desk .mfb-stat-tipis .stat-card + .stat-card {
  border-left: 1px solid var(--gray-100, #E8E8E8);
}
#desk .mfb-stat-tipis .stat-card-top { display: none; }
/* v1.141 (2.271, D277): keterangan baseline ("N departments", "N published", "from partner schools") tampil SEBARIS,
   terpotong rapi bila sempit — dulu disembunyikan sehingga "Active Trainees 0" tak berpenjelasan. */
#desk .mfb-stat-tipis .stat-card-sub { display: inline; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11px; color: var(--gray-500, #595959); }
#desk .mfb-stat-tipis .stat-card-sub::before { content: "· "; }
/* Chip kartu berisi data nyata (D277) — bukan tanda hubung kosong. */
.mfb-kpi-delta.mfb-kpi-info { color: var(--gray-700, #3D3D3D); background: rgba(201, 168, 76, 0.16); }
body.dark-mode .mfb-kpi-delta.mfb-kpi-info { color: #E9E4D8; background: rgba(212, 175, 55, 0.18); }
.mfb-kpi-delta[hidden] { display: none !important; }
#desk .mfb-stat-tipis .stat-card-num   { font-size: 17px; font-weight: 800; letter-spacing: -0.01em; }
#desk .mfb-stat-tipis .stat-card-label { font-size: 11px; font-weight: 600; }

@media (max-width: 1050px) {
  #desk .mfb-stat-satu-baris.mfb-stat-pilah { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  #desk .mfb-stat-tipis .stat-card { flex: 1 1 33%; }
}
@media (max-width: 620px) {
  #desk .mfb-stat-tipis { flex-direction: column; }
  #desk .mfb-stat-tipis .stat-card + .stat-card {
    border-left: 0;
    border-top: 1px solid var(--gray-100, #E8E8E8);
  }
}

/* ----------------------------------------------------------------
   37. YANG PERLU PERHATIAN ANDA
   ----------------------------------------------------------------

   Dashboard lama menjawab "berapa". Panel ini menjawab "lalu saya
   harus apa" — target 30 detik di SOP kategori 21.5.

   🔴 SEMUA ISINYA DITURUNKAN DARI ANGKA YANG SUDAH ADA DI HALAMAN
   (tabel Department Overview + kartu Overdue). Tidak ada satu pun
   angka baru yang dikarang di sini. Kalau tabelnya kosong, panel
   ini tidak muncul sama sekali — bukan menampilkan daftar kosong
   yang terlihat seperti "semua aman".
   ---------------------------------------------------------------- */

.mfb-perhatian-daftar {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.mfb-perhatian-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 4px;
  min-height: 44px;
}
.mfb-perhatian-item + .mfb-perhatian-item {
  border-top: 1px solid var(--gray-100, #E8E8E8);
}

.mfb-perhatian-ikon {
  flex: 0 0 auto;
  width: 30px; height: 30px;
  border-radius: 9px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
}
.mfb-perhatian-item.gawat  .mfb-perhatian-ikon { background: rgba(200, 70, 60, 0.14); }
.mfb-perhatian-item.tinjau .mfb-perhatian-ikon { background: rgba(201, 168, 76, 0.18); }

.mfb-perhatian-isi  { flex: 1 1 auto; min-width: 0; }
.mfb-perhatian-judul {
  font-size: 13px;
  font-weight: 700;
  color: var(--gray-900, #1A1A1A);
  margin: 0 0 2px;
}
.mfb-perhatian-sebab {
  font-size: 11.5px;
  color: var(--gray-500, #6E6E6E);
  margin: 0;
}
.mfb-perhatian-angka {
  flex: 0 0 auto;
  font-size: 18px;
  font-weight: 800;
  letter-spacing: -0.01em;
}
.mfb-perhatian-item.gawat  .mfb-perhatian-angka { color: var(--red, #D9534F); }
.mfb-perhatian-item.tinjau .mfb-perhatian-angka { color: var(--gold, #C9A865); }

/* Keadaan "semua aman" — hanya muncul kalau datanya BENAR-BENAR
   terbaca dan memang tidak ada yang bermasalah. */
.mfb-perhatian-aman {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 4px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--green, #2E8B57);
}

/* ----------------------------------------------------------------
   38. SKOR KESEHATAN PEMBELAJARAN
   ----------------------------------------------------------------

   Satu angka untuk pertanyaan 5 detik: sistemnya sehat atau tidak.

   🔴 Skor gabungan berbahaya kalau rumusnya tidak kelihatan — ia
   terlihat berwibawa padahal tidak bisa diperiksa siapa pun. Jadi
   dua bahan penyusunnya SELALU ditampilkan di sebelahnya, bukan
   disembunyikan di tooltip.
   ---------------------------------------------------------------- */

.mfb-sehat {
  display: flex;
  align-items: center;
  gap: 22px;
  margin-bottom: 16px;
  padding: 18px 24px;
  border-radius: 16px;
  background-image: linear-gradient(118deg, #16130F 0%, #241E12 46%, #3A2E17 100%);
  border: 1px solid rgba(201, 168, 76, 0.34);
  box-shadow:
    0 10px 30px rgba(12, 11, 8, 0.22),
    inset 0 1px 0 rgba(255, 244, 214, 0.12);
}

.mfb-sehat-angka {
  flex: 0 0 auto;
  display: flex;
  align-items: baseline;
  gap: 3px;
  font-weight: 800;
  color: #F2E4BE;
}
.mfb-sehat-besar { font-size: 44px; letter-spacing: -0.03em; line-height: 1; }
.mfb-sehat-per   { font-size: 15px; color: rgba(242, 228, 190, 0.55); }

.mfb-sehat-isi { flex: 1 1 auto; min-width: 0; }

.mfb-sehat-cap {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: rgba(232, 201, 106, 0.9);
  margin-bottom: 5px;
}
.mfb-sehat-nilai { font-size: 15px; font-weight: 700; color: #F7F1E2; margin: 0 0 7px; }

.mfb-sehat-bahan {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  font-size: 11px;
  color: rgba(242, 228, 190, 0.68);
}
.mfb-sehat-bahan b { color: #F2E4BE; font-weight: 800; }

.mfb-sehat-bar {
  height: 6px;
  margin-top: 10px;
  border-radius: 999px;
  background: rgba(255, 244, 214, 0.14);
  overflow: hidden;
}
.mfb-sehat-bar-isi {
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, #A8873F, #E8C97A);
}

@media (max-width: 620px) {
  .mfb-sehat {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
    padding: 16px 18px;
    border-radius: 14px;
  }
  .mfb-sehat-besar { font-size: 38px; }
}

@media print {
  .mfb-sehat {
    background-image: none !important;
    border: 1px solid #999 !important;
    box-shadow: none !important;
  }
  .mfb-sehat-angka, .mfb-sehat-nilai, .mfb-sehat-bahan b { color: #000 !important; }
  .mfb-sehat-cap, .mfb-sehat-bahan { color: #333 !important; }
}

/* ----------------------------------------------------------------
   39. MEMUAT HALAMAN — SPANDUK SEKALI, BUKAN TIAP KLIK
   ----------------------------------------------------------------

   Laporan IT Manager 12 September 2026: tiap membuka halaman, layar
   penuh terisi "bayangan" dan terasa dimuat ulang dari nol.

   v2.144 memberi SETIAP .page-placeholder spanduk merek lewat
   ::before + ::after ("Miss Fish Bali" / "LEARNING MANAGEMENT
   SYSTEM") plus min-height 60vh. Itu splash screen — benar untuk
   pembukaan aplikasi, salah untuk perpindahan halaman.

   Sesudah halaman pertama terbuka, badan halaman ditandai
   .mfb-app-jalan (lihat mfb-ui.js bagian 5e) dan spanduk itu
   dimatikan. Rangka muatnya TETAP — ia memberi tahu bentuk isi yang
   sedang datang, dan itu yang membuat tunggu terasa singkat.
   ---------------------------------------------------------------- */

body.mfb-app-jalan .page-placeholder::before,
body.mfb-app-jalan .page-placeholder::after {
  content: none;
}

body.mfb-app-jalan .page-placeholder {
  /* 60vh -> 180px. Tingginya tetap cukup untuk menahan tata letak
     supaya isi tidak melompat saat datang, tapi tidak lagi memakan
     seluruh layar. */
  min-height: 180px;
  justify-content: flex-start;
  padding-top: 8px;
  gap: 10px;
}

/* Cincin berputar bawaan dikecilkan supaya sepadan dengan ruangnya.
   Ia hanya terlihat sekejap sebelum rangka muat menggantikannya. */
body.mfb-app-jalan .page-placeholder .ph-dots {
  width: 22px;
  height: 22px;
  border-width: 2px;
}

body.mfb-app-jalan .page-placeholder .ph-title {
  font-size: 11px;
  letter-spacing: .04em;
}

/* Halaman yang isinya sudah datang tapi memang KOSONG bukan urusan
   bagian ini — itu ditangani bagian 4k (keadaan kosong per halaman),
   yang menjelaskan SEBABNYA, bukan sekadar "no data". */

@media (prefers-reduced-motion: reduce) {
  body.mfb-app-jalan .page-placeholder .ph-dots { animation: none; }
}

@media print {
  /* Layar tunggu tidak pernah pantas ikut tercetak. */
  .page-placeholder { display: none !important; }
}

/* ----------------------------------------------------------------
   40. CENTANG "BOLEH IKUT COURSE" DI FORMULIR USER
   ----------------------------------------------------------------

   Permintaan IT Manager 12 September 2026. Sejak v2.176 kolom
   users.is_trainable menentukan apakah sebuah akun boleh membuka
   course — tapi sampai sekarang tidak ada satu pun cara mengubahnya
   dari layar, jadi satu-satunya jalan adalah SQL Editor Supabase.

   Keterangannya menjelaskan AKIBAT, bukan nama kolom: orang yang
   mengisi formulir tidak tahu apa itu "is_trainable".
   ---------------------------------------------------------------- */

.mfb-trainable {
  margin: 2px 0 16px;
}

.mfb-trainable-label {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  /* 44px — sama seperti sasaran sentuh lain di lapisan ini. Centang
     kecil di formulir panjang adalah sasaran tersulit di layar HP. */
  min-height: 44px;
  font-size: 13px;
  font-weight: 600;
  color: var(--gray-900, #1A1A1A);
}

.mfb-trainable-kotak {
  /* Ukuran bawaan checkbox ~13px dan tidak bisa diandalkan antar
     peramban. Dibesarkan supaya terlihat dan mudah ditekan. */
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  accent-color: var(--gold, #C9A865);
  cursor: pointer;
  margin: 0;
}

.mfb-trainable-teks { line-height: 1.3; }

.mfb-trainable-sub {
  display: block;
  /* Sejajar dengan teks label, bukan dengan kotaknya: 18px + 10px. */
  margin: -6px 0 0 28px;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--gray-500, #6E6E6E);
}

/* Fokus keyboard wajib terlihat (WCAG 2.4.7). Peramban memang punya
   cincin bawaan, tapi modal ini berlatar terang dan cincin tipisnya
   mudah hilang — jadi dipertegas. */
.mfb-trainable-kotak:focus-visible {
  outline: 2px solid var(--gold, #C9A865);
  outline-offset: 2px;
}

@media (max-width: 620px) {
  .mfb-trainable-sub { margin-left: 28px; }
}

/* ================================================================
   ANGKA DI ATAS TITIK GRAFIK — pil gelap + teks terang
   ================================================================
   🔴 Dibuat karena tooltip <title> butuh KURSOR, dan di ponsel
   kursor tidak ada. Tanpa ini, staff dan HoD yang membuka LMS dari
   HP melihat bentuk garisnya tapi tidak bisa membaca satu angka pun.

   Kontrasnya sengaja tinggi (teks nyaris putih di atas hijau tua):
   pil ini duduk DI ATAS area gradien emas, jadi teks abu-abu akan
   hilang tertelan latar di bagian grafik yang paling padat. */
.mfb-g-pil {
  fill: var(--mfb-nav, #102c2d);
  opacity: .92;
}

.mfb-g-pil-teks {
  fill: #ffffff;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 10.5px;
  font-weight: 700;
  /* Angka bertipe tabular supaya pil tidak bergeser lebarnya saat
     nilainya berubah dari 9 ke 10 — sama seperti label sumbu. */
  font-variant-numeric: tabular-nums;
  /* Pil bersifat informasi, bukan tombol. Menyorotnya saat orang
     menggeser grafik di HP cuma mengganggu. */
  pointer-events: none;
  user-select: none;
}

body.dark-mode .mfb-g-pil { fill: #05100f; opacity: .95; }

/* Pil ikut muncul bersama noktahnya, bukan mendahului garis yang
   sedang menggambar dirinya sendiri. */
.mfb-anim .mfb-g-pil,
.mfb-anim .mfb-g-pil-teks {
  animation: mfb-anim-noktah .34s cubic-bezier(.3,1.4,.5,1) both;
  animation-delay: .9s;
}

@media (prefers-reduced-motion: reduce) {
  .mfb-anim .mfb-g-pil,
  .mfb-anim .mfb-g-pil-teks { animation: none; }
}

/* ================================================================
   41. MANAGE COURSES — KESIAPAN, LAMBANG DEPARTEMEN, GRID & LIST
   ================================================================
   Pasangan bagian 5k di mfb-ui.js (v1.43). Permintaan IT Manager,
   14 September 2026: "manage courses ini bisa di touchup lebih
   bagus UI/UX nya kak", lalu "bisa dibuat 4 kolom ya kak ... icon
   SVG based on department ... selain grid view, bisa dibuat list
   view juga".

   Arah desainnya sama dengan seluruh lapisan ini: MENGURANGI, bukan
   menambah. Spanduk 110px yang membawa ikon buku yang sama di setiap
   kartu dipendekkan dan diisi lambang departemennya — satu-satunya
   hal di spanduk yang membedakan course dalam sekali pandang. Warna
   hanya muncul saat ada yang PERLU diperhatikan; course yang sehat
   tidak diberi label apa pun.
   ================================================================ */

/* --- spanduk: lebih pendek, bermotif halus, lambang di tengah --- */
#desk .course-mgmt-card.mfb-kc .cmg-thumb {
  height: 92px;
  background:
    radial-gradient(ellipse at 50% 55%, rgba(201, 160, 101, 0.17) 0%, transparent 60%),
    repeating-linear-gradient(135deg, rgba(232, 201, 106, 0.035) 0 1px, transparent 1px 11px),
    linear-gradient(135deg, var(--mfb-chrome-atas), var(--mfb-chrome-bawah));
}
#desk .course-mgmt-card.mfb-kc .cmg-thumb-bg,
#desk .course-mgmt-card.mfb-kc .cmg-thumb-icon,
#mob .course-card-adm.mfb-kc .cca-icon { display: none; }

#mob .course-card-adm.mfb-kc .cca-thumb {
  background:
    radial-gradient(ellipse at 50% 55%, rgba(201, 160, 101, 0.17) 0%, transparent 62%),
    linear-gradient(135deg, var(--mfb-chrome-atas), var(--mfb-chrome-bawah));
}

/* Lambang departemen — pisau untuk Kitchen, gelas untuk Bar, layar
   untuk IT, dan seterusnya (permintaan IT Manager). Garis emas di dalam
   lingkaran berbingkai tipis: satu gaya untuk kelima belas departemen,
   supaya yang membedakan hanya GAMBARNYA, bukan warna atau ukurannya. */
.mfb-kc .mfb-kc-lambang {
  position: relative;
  z-index: 1;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(232, 201, 106, 0.45);
  /* Cincin dalam yang sangat tipis: bingkai ganda adalah ciri stempel
     dan lambang tercetak — detail kecil yang membuat lingkaran polos
     terbaca sebagai lambang, bukan tombol. */
  box-shadow: inset 0 0 0 4px rgba(232, 201, 106, 0.06), 0 0 26px rgba(201, 160, 101, 0.12);
  color: var(--mfb-emas);
}
.mfb-kc .mfb-kc-lambang svg { width: 26px; height: 26px; display: block; }
#mob .mfb-kc .mfb-kc-lambang { width: 42px; height: 42px; }
#mob .mfb-kc .mfb-kc-lambang svg { width: 20px; height: 20px; }

/* Course yang diarsipkan: warnanya dicabut, bukan disembunyikan.
   Ia masih ada dan masih bisa dibuka — cuma tidak lagi bersaing
   dengan course yang sedang berjalan. */
.mfb-kc.is-arsip .cmg-thumb,
.mfb-kc.is-arsip .cca-thumb { filter: grayscale(0.9); }
.mfb-kc.is-arsip .mfb-kc-lambang { color: #B9B2A6; border-color: rgba(185, 178, 166, 0.4); }

/* --- jumlah kolom: dihitung dari lebar layar, bukan dikunci 3 ---
   "keleberan kalau 3" (IT Manager, layar 1920px). Kartu butuh ±340px
   supaya Edit · Modules · Assign · Arsip muat sebaris. Dengan sidebar
   240px dan padding 32px, hasilnya: 1920px -> 4 kolom (±392px),
   1366px -> 3 kolom, 1024px -> 2 kolom. Dikunci 4 akan membuat laptop
   13 inci mendapat kartu 250px dengan tombol yang terlipat dua. */
#desk .course-mgmt-grid { grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); }

/* Label status di HP TIDAK PERNAH punya gaya: baseline hanya menulis
   #desk .s-published / .s-draft (baris 2592-2594), sehingga di ponsel
   "Published" tampil sebagai teks polos di atas spanduk hitam. */
#mob .cca-status.s-published { background: rgba(16, 185, 129, 0.22); color: #34D399; }
#mob .cca-status.s-draft     { background: rgba(245, 158, 11, 0.22); color: #FBBF24; }
/* 🔴 v1.49 — selektor desktop DICABUT dari baris ini.
   Dulu baris ini juga mengatur lencana Archived di kartu .mfb-kc
   desktop. Sesudah ronde 3 kontras, lencana kartu .mfb-kc diatur di
   SATU tempat saja (cari "Lencana SOLID PUTIH" di bawah). Dua aturan
   yang berebut elemen yang sama adalah sumber bug yang paling mahal
   di berkas ini — kekhususan yang menang belum tentu yang dikira
   penulisnya, dan tidak ada yang sadar sampai warnanya salah.
   Kartu HP yang BELUM diproses lapisan ini tetap butuh baris ini. */
#mob .cca-status.s-archived { background: rgba(185, 178, 166, 0.2); color: #D6D0C4; }


/* --- status terbaca dari jauh (permintaan IT Manager, 17 Sep 2026) ---

   Sebelumnya status hanya ditandai lencana kecil di pojok: 9,5 px di
   desktop dan 9 px di HP — di bawah standar kita sendiri (12 px), dan
   harus DICARI mata. Yang langsung tertangkap dari jauh adalah bidang
   besar, dan di kartu ini bidang besarnya spanduk setinggi 92 px.

   🔴 box-shadow inset, BUKAN background: spanduk .mfb-kc sudah memakai
   tiga lapis gradien (kilau emas + motif garis + krom). Menimpa
   background-nya berarti membuang ketiganya. Inset shadow menumpuk di
   ATAS latar dan di BAWAH lambang departemen.

   🔴 KADARNYA 0,94 — RONDE KETIGA, KEPUTUSAN IT MANAGER 17 September 2026.

   Ronde 1 memakai 0,20 supaya kilau emas spanduk tetap terlihat.
   Jawaban IT Manager: "kurang kontras, kurang BEDA antar satu sama lain,
   sekali liat lsg keliatan gitu."

   Ronde 2 menaikkannya ke 0,55-0,66. Jawaban IT Manager: "masi kurang."

   🔴 DIAGNOSIS RONDE 2, bukan sekadar menaikkan angka lagi: ronde 2
   menambah KEPEKATAN tapi ketiganya tetap GELAP — hijau tua, cokelat
   tua, abu tua. Mata menangkap TERANG jauh lebih cepat daripada
   corak, jadi dari jauh ketiganya masih terbaca "kartu gelap" dan
   cuma Draft yang menonjol karena kebetulan paling terang.

   Ronde 3 memisahkan mereka di sumbu TERANG, bukan menambah pekat:
     · terbit · hijau zamrud CERAH (5,150,105)  — terang ±56%
     · draf   · jingga MENYALA     (234,88,12)  — terang ±60%
     · arsip  · nyaris HITAM       (24,24,23)   — terang ±9%
   Selisih terangnya kini lebar. Akibatnya bedanya terbaca walau
   dicetak hitam-putih, dan tetap terbaca oleh sekitar 8% pria yang
   lemah membedakan merah-hijau.

   🔴 HARGA YANG DIBAYAR, DISEBUT TERANG-TERANGAN: di kadar 0,94
   kilau emas dan motif garis spanduk praktis hilang; yang tersisa
   cuma lambang departemen dan cincinnya, yang memang digambar DI
   ATAS lapisan ini. Itu pilihan sadar IT Manager sesudah dua ronde,
   bukan kelalaian.

   Dan warna tidak pernah jadi satu-satunya tanda: tulisan
   Published/Draft/Archived tetap ada di setiap kartu. */
#desk .course-mgmt-card.mfb-kc.is-terbit .cmg-thumb,
#mob .course-card-adm.mfb-kc.is-terbit .cca-thumb {
  box-shadow: inset 0 0 0 999px rgba(5, 150, 105, 0.94);
}
/* 🔴 RONDE 4 — jingga digelapkan satu tingkat, 18 September 2026.
   Permintaan IT Manager: "terlalu ngejreng". Tapi yang membuat perubahan
   ini BOLEH dilakukan bukan selera — melainkan pengukuran, karena
   ronde 3 sengaja memisahkan status di sumbu TERANG dan menggelapkan
   sesuatu bisa diam-diam merusak pemisahan itu.

   Diukur dengan L* CIE (terang seperti yang DIRASAKAN mata), sesudah
   dicampur latar pada kadar 0,94:

     sebelum   terbit #059669 L* 52,5  ·  draf #EA580C L* 53,9
               jarak = 1,4     <- praktis KEMBAR
     sesudah   terbit #059669 L* 52,5  ·  draf #C2410C L* 43,9
               jarak = 8,6     <- enam kali lebih jauh

   Jadi ronde 3 TIDAK PERNAH mencapai tujuannya untuk pasangan yang
   paling sering dibandingkan orang. Dicetak hitam-putih, hijau dan
   jingga lama terlihat sama. Menggelapkan justru MEMENUHI niat asli
   ronde 3, bukan membatalkannya.

   Bonus yang diukur, bukan diharapkan: kontras teks putih di atasnya
   naik 3,90 -> 5,59, yaitu dari GAGAL standar AA menjadi lolos.

   #C2410C bukan warna baru — ia sudah dipakai lencana draf versi HP
   (baris ~6388), jadi paletnya tidak bertambah. */
#desk .course-mgmt-card.mfb-kc.is-draf .cmg-thumb,
#mob .course-card-adm.mfb-kc.is-draf .cca-thumb {
  box-shadow: inset 0 0 0 999px rgba(194, 65, 12, 0.94);
}

/* Course terarsip sudah dicabut warnanya (grayscale di atas); yang
   ditambahkan cuma sedikit kabut abu supaya bedanya tegas di sebelah
   kartu yang berwarna. */
#desk .course-mgmt-card.mfb-kc.is-arsip .cmg-thumb,
#mob .course-card-adm.mfb-kc.is-arsip .cca-thumb {
  box-shadow: inset 0 0 0 999px rgba(24, 24, 23, 0.94);
}

/* Lencananya sendiri: dari 9-9,5 px menjadi 12 px.

   🔴 Latar spanduk sekarang pekat, jadi lencana ikut diberi bayangan
   dan garis tepi tipis — tanpa itu lencana hijau di atas spanduk hijau
   saling meleleh dan justru jadi lebih sulit dibaca daripada sebelum
   diperbaiki. */
#desk .mfb-kc .cmg-status,
#mob .mfb-kc .cca-status {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .06em;
  padding: 4px 10px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .45);
}

/* 🔴 Lencana SOLID PUTIH, tulisannya yang berwarna.

   Baseline menulisnya tembus pandang (background 20% + tulisan warna
   senada). Itu terbaca selama spanduknya gelap. Begitu spanduk jadi
   hijau zamrud cerah di ronde 3, lencana hijau 20% di atas hijau
   cerah nyaris lenyap — perbaikan kontras spanduk justru MERUSAK
   keterbacaan tulisannya. Gejala klasik: memperbaiki satu lapisan
   tanpa memeriksa lapisan yang duduk di atasnya.

   Putih solid menang di KETIGA latar sekaligus — hijau cerah, jingga
   menyala, nyaris hitam — jadi satu aturan cukup untuk semua status.
   Warnanya pindah ke TULISAN, bukan hilang: warna tetap jadi tanda
   kedua sesudah kata.

   Corak tulisannya sengaja versi TUA dari warna spanduknya (700-800
   di tangga Tailwind), bukan warna spanduk itu sendiri — supaya
   rasio kontras terhadap putih lewat ambang 4.5:1 WCAG AA. */
#desk .mfb-kc .cmg-status,
#mob .mfb-kc .cca-status {
  background: #FFFFFF;
}
#desk .mfb-kc .cmg-status.s-published,
#mob .mfb-kc .cca-status.s-published { color: #047857; }
#desk .mfb-kc .cmg-status.s-draft,
#mob .mfb-kc .cca-status.s-draft     { color: #C2410C; }
#desk .mfb-kc .cmg-status.s-archived,
#mob .mfb-kc .cca-status.s-archived  { color: #27272A; }
/* --- pil kesiapan --- */
.mfb-kc-siap {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 10px;
  padding: 4px 10px 4px 8px;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.3;
}
.mfb-kc-siap .mfb-kc-ikon { width: 13px; height: 13px; flex-shrink: 0; }
/* Rasio kontras DIUKUR (bukan ditaksir), di titik TERBURUK kartu —
   tepi bawah gradien latar bagian 1g, #F6F5F1 — bukan di atas putih:
   merah 5,33 · kuning 5,13 · hijau 5,38 : 1 (terang); mode gelap
   7,36 · 9,11 · 9,72 : 1. Semuanya di atas syarat AA 4,5 : 1. */
.mfb-kc-siap.is-bahaya  { background: rgba(220, 38, 38, 0.08); border-color: rgba(220, 38, 38, 0.24); color: #B42318; }
.mfb-kc-siap.is-waspada { background: rgba(217, 119, 6, 0.09); border-color: rgba(217, 119, 6, 0.26); color: #8F5400; }
.mfb-kc-siap.is-siap    { background: rgba(26, 138, 74, 0.08); border-color: rgba(26, 138, 74, 0.24); color: #146C3A; }
body.dark-mode .mfb-kc-siap.is-bahaya  { background: rgba(248, 113, 113, 0.12); border-color: rgba(248, 113, 113, 0.32); color: #FCA5A5; }
body.dark-mode .mfb-kc-siap.is-waspada { background: rgba(251, 191, 36, 0.11); border-color: rgba(251, 191, 36, 0.3); color: #FCD34D; }
body.dark-mode .mfb-kc-siap.is-siap    { background: rgba(74, 222, 128, 0.1); border-color: rgba(74, 222, 128, 0.28); color: #86EFAC; }
#mob .mfb-kc .mfb-kc-siap { margin: 6px 0 4px; font-size: 11px; }

/* --- baris isi course: video · PDF · soal --- */
.mfb-kc-isi {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin: 0 0 10px;
  font-size: 11.5px;
  /* BUKAN var(--gray-500): latar kartu menggelap ke #F3F1EC di bawah
     (bagian 1g), dan di sana gray-500 hanya 4,15 : 1 — gagal AA.
     #6B6761 terukur 5,15 : 1 di titik terburuk itu. */
  color: #6B6761;
  font-variant-numeric: lining-nums tabular-nums;
}
body.dark-mode .mfb-kc-isi { color: var(--gray-500); }
.mfb-kc-item { display: inline-flex; align-items: center; gap: 5px; }
.mfb-kc-item .mfb-kc-ikon { width: 13px; height: 13px; color: var(--gold); }
.mfb-kc-n { font-weight: 700; color: var(--black); }
/* Nol TIDAK dihilangkan: "0 PDFs" adalah informasi. Yang dibedakan
   hanya ikon dan tebal angkanya — BUKAN opacity. Teks yang diredupkan
   separuh jatuh ke sekitar 2 : 1 dan tidak terbaca di bawah matahari. */
.mfb-kc-item.is-nol .mfb-kc-n { font-weight: 500; color: inherit; }
.mfb-kc-item.is-nol .mfb-kc-ikon { color: var(--gray-400); }

#desk .mfb-kc .cmg-stat .mfb-kc-ikon { width: 13px; height: 13px; color: var(--gray-400); }

/* --- tombol sejajar di DASAR kartu ---
   Terlihat di screenshot Chrome: kartu Published tanpa pil kesiapan
   lebih pendek isinya, sehingga tombolnya naik lebih tinggi daripada
   kartu Draft di sebelahnya — deretan tombol sebaris jadi berundak.
   Isi kartu dijadikan kolom lentur dan tombol didorong ke dasar.
   Hanya untuk tampilan GRID: di tampilan list kartu yang sama disusun
   sebagai baris (41c), dan aturan ini tidak boleh ikut campur. */
#desk .course-mgmt-grid:not(.mfb-kc-daftar) > .course-mgmt-card.mfb-kc {
  display: flex;
  flex-direction: column;
}
#desk .course-mgmt-grid:not(.mfb-kc-daftar) > .course-mgmt-card.mfb-kc > .cmg-body {
  flex: 1;
  display: flex;
  flex-direction: column;
}
#desk .course-mgmt-grid:not(.mfb-kc-daftar) > .course-mgmt-card.mfb-kc .cmg-footer { margin-top: auto; }
/* Di kolom lentur setiap anak meregang selebar kartu — pil kesiapan
   ikut jadi pita selebar kartu (terlihat di screenshot). Pil memeluk
   teksnya, sama seperti sebelum isi kartu dijadikan kolom lentur. */
#desk .course-mgmt-grid:not(.mfb-kc-daftar) > .course-mgmt-card.mfb-kc .mfb-kc-siap { align-self: flex-start; }

/* Tombol emas (Publish / Assign) di MODE GELAP.
   🔴 Masalah LAMA baseline: teksnya var(--black), dan mode gelap menukar
   --black jadi #F0F0F0 — teks terang di atas emas, terukur 2,12 : 1,
   gagal AA. Latar emasnya tidak ikut gelap, jadi teksnya harus tetap
   hitam: 8,20 : 1, sama dengan mode terang. */
body.dark-mode #desk .mfb-kc .btn-tbl.gold-btn { color: #0A0A0A; }

/* --- tombol --- */
#desk .course-mgmt-card.mfb-kc .cmg-footer { align-items: center; flex-wrap: wrap; }
#desk .mfb-kc .btn-tbl { display: inline-flex; align-items: center; gap: 6px; }
#desk .mfb-kc .btn-tbl .mfb-kc-ikon { width: 14px; height: 14px; flex-shrink: 0; }
#desk .mfb-kc .btn-tbl:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

/* Arsip: didorong ke ujung kanan dan dibuat tenang. Tindakan yang
   menyingkirkan course tidak boleh duduk sejajar dan setara dengan
   Assign — warnanya baru muncul saat kursor benar-benar menuju ke sana. */
#desk .mfb-kc .btn-tbl.mfb-kc-arsip {
  margin-left: auto;
  width: 30px;
  padding: 0;
  justify-content: center;
  background: transparent;
  border-color: transparent;
  color: var(--gray-400);
}
#desk .mfb-kc .btn-tbl.mfb-kc-arsip:hover,
#desk .mfb-kc .btn-tbl.mfb-kc-arsip:focus-visible {
  color: var(--red);
  border-color: rgba(220, 38, 38, 0.35);
  background: rgba(220, 38, 38, 0.05);
}

/* --- kartu "Create New Course" --- */
#desk .add-course-cta .icon .mfb-kc-ikon { width: 26px; height: 26px; color: var(--gold); }

/* --- chip filter: jumlah --- */
#desk .mgmt-filter-pill .mfb-kc-hitung {
  display: inline-block;
  min-width: 20px;
  margin-left: 7px;
  padding: 1px 6px;
  border-radius: 999px;
  background: rgba(60, 44, 20, 0.07);
  /* gray-500 di sini hanya 3,98 : 1 (terukur) — gagal AA untuk huruf
     11px. #625E58 terukur 5,66 : 1. */
  color: #625E58;
  font-size: 11px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  font-variant-numeric: lining-nums tabular-nums;
}
#desk .mgmt-filter-pill.active .mfb-kc-hitung { background: rgba(255, 255, 255, 0.16); color: #fff; }
body.dark-mode #desk .mgmt-filter-pill:not(.active) .mfb-kc-hitung { background: rgba(255, 255, 255, 0.08); color: var(--gray-500); }

/* --- hasil pencarian kosong --- */
#desk .mfb-kc-kosong {
  grid-column: 1 / -1;
  padding: 26px 20px;
  border: 1px dashed var(--gray-200);
  border-radius: 14px;
  text-align: center;
}
.mfb-kc-kosong-judul { font-size: 14px; font-weight: 700; color: var(--black); }
.mfb-kc-kosong-sub   { margin-top: 4px; font-size: 12.5px; color: var(--gray-500); }

/* --- layar 900–1200px (laptop kecil) ---
   🔴 Baseline di lebar ini MENYEMBUNYIKAN SEMUA svg di dalam .btn-tbl
   (index.html baris 2276). Tombol lain masih punya teks, tapi tombol
   arsip hanya berisi ikon — tanpa pengecualian ini ia tampil sebagai
   kotak KOSONG yang tetap bisa diklik. Tombol pemilih grid/list juga
   hanya berisi ikon, jadi ikut dikecualikan. (Jumlah kolomnya sudah
   diatur auto-fill di atas, jadi tidak perlu aturan kolom di sini.) */
@media (min-width: 900px) and (max-width: 1200px) {
  #desk .mfb-kc .btn-tbl.mfb-kc-arsip svg,
  #desk .mfb-kc-pilih svg { display: block !important; }
}

/* ================================================================
   41b. PEMILIH TAMPILAN — GRID / LIST
   ================================================================ */
#desk .mfb-kc-tampilan {
  margin-left: auto;
  display: inline-flex;
  padding: 3px;
  gap: 2px;
  border-radius: 9px;
  border: 1.5px solid var(--gray-200);
  background: var(--gray-50);
}
#desk .mfb-kc-pilih {
  width: 34px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: #6B6761;
  cursor: pointer;
  transition: background-color .18s ease, color .18s ease;
}
#desk .mfb-kc-pilih .mfb-kc-ikon { width: 16px; height: 16px; }
#desk .mfb-kc-pilih:hover { color: var(--black); }
#desk .mfb-kc-pilih[aria-pressed="true"] {
  background: var(--solid-dark);
  color: var(--mfb-emas);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
}
#desk .mfb-kc-pilih:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
body.dark-mode #desk .mfb-kc-pilih { color: var(--gray-500); }
body.dark-mode #desk .mfb-kc-pilih[aria-pressed="true"] { background: #2A2621; }

/* ================================================================
   41c. TAMPILAN LIST — kartu yang SAMA, disusun jadi baris
   ================================================================
   Tidak ada satu elemen pun yang digambar ulang: .cmg-thumb dan
   .cmg-body dibuat display:contents, sehingga anak-anaknya (lambang,
   judul, status, pil, tombol) langsung jadi sel grid baris ini.
   Semua yang bekerja di kartu grid otomatis bekerja di sini.
   ---------------------------------------------------------------- */
#desk .course-mgmt-grid.mfb-kc-daftar {
  grid-template-columns: 1fr;
  gap: 0;
  border: 1px solid rgba(196, 186, 168, 0.55);
  border-radius: 14px;
  overflow: hidden;
  background: var(--white);
  box-shadow: var(--mfb-kilau), var(--mfb-naik-1), var(--mfb-naik-2);
}

/* Satu definisi kolom untuk kepala DAN baris — kalau ditulis dua kali,
   judul kolom akan bergeser dari isinya begitu salah satu diubah.

   🔴 Kolom aksi BERLEBAR TETAP (320px), BUKAN auto. Kepala dan setiap
   baris adalah grid yang TERPISAH; dengan "auto", kolom aksi di kepala
   (kosong) selebar 0 sementara di baris (berisi tombol) ±300px, sehingga
   pembagian fr berbeda dan judul kolom bergeser 100–240px dari isinya.
   Terukur di Chrome, 14 September 2026, sebelum diperbaiki. */
#desk .mfb-kc-daftar > .mfb-kc-kepala,
#desk .mfb-kc-daftar > .course-mgmt-card {
  display: grid;
  grid-template-columns:
    40px minmax(180px, 2fr) minmax(100px, 1fr) 96px
    minmax(180px, 1.4fr) minmax(160px, 1.2fr) 320px;
  column-gap: 16px;
  align-items: center;
  padding: 12px 18px;
}

.mfb-kc-kepala { display: none; }
#desk .mfb-kc-daftar > .mfb-kc-kepala {
  padding-top: 10px;
  padding-bottom: 10px;
  background: var(--gray-50);
  border-bottom: 1px solid var(--gray-100);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #6B6761;
}

#desk .mfb-kc-daftar > .course-mgmt-card {
  grid-template-areas:
    "ikon judul dept status isi  siap aksi"
    "ikon kode  dept status stat siap aksi";
  row-gap: 2px;
  min-height: 0;
  border: 0;
  border-bottom: 1px solid var(--gray-100);
  border-radius: 0;
  background-image: none;
  box-shadow: none;
  transform: none;
}
/* 🔴 Baseline memaksa bayangan & sudut kartu di mode gelap dengan
   !important (index.html baris 1652). Tanpa pengecualian yang sama
   kuatnya, setiap baris list di mode gelap tetap tampil sebagai kartu
   melayang yang terpotong-potong. */
body.dark-mode #desk .mfb-kc-daftar > .course-mgmt-card {
  box-shadow: none !important;
  border-radius: 0;
}
#desk .mfb-kc-daftar > .course-mgmt-card:hover {
  transform: none;
  box-shadow: none;
  background-color: rgba(201, 160, 101, 0.05);
}
body.dark-mode #desk .mfb-kc-daftar > .course-mgmt-card:hover { background-color: rgba(232, 201, 106, 0.05); }

/* 🔴 GARIS STATUS DI TEPI KIRI BARIS — pilihan IT Manager, 19 September 2026.
   Tampilan kartu punya spanduk warna besar; tampilan daftar tidak punya
   apa pun selain lencana kecil di tengah baris. Padahal daftar padat
   dibaca dengan MENYAPU MATA DARI KIRI, dan di jalur itu tidak ada
   satu pun tanda status.

   🔴 KENAPA background-image, BUKAN border-left ATAU box-shadow.

   border-left 4px akan MENGGESER isi baris 4px ke kanan, sementara
   baris kepala tabel tidak ikut bergeser. Komentar di baris ~6650
   mencatat masalah keselarasan kolom kepala-vs-baris yang sudah pernah
   diukur di Chrome dan diperbaiki; memakai border akan membangunkannya
   kembali.

   box-shadow juga tidak bisa: baris ini dipaksa box-shadow:none di TIGA
   tempat — biasa (baris ~6693), mode gelap dengan !important (~6701),
   dan hover (~6706). Garis yang dipasang lewat box-shadow akan hilang
   di mode gelap dan setiap kali kursor lewat.

   background-image aman dari ketiganya: ia tidak memengaruhi tata letak
   sama sekali, hover mengubah background-COLOR (properti yang berbeda,
   jadi keduanya hidup berdampingan), dan !important mode gelap hanya
   mengenai box-shadow.

   Warnanya mengikuti palet yang sama dengan spanduk kartu, jadi kedua
   tampilan berbicara bahasa warna yang sama. */
#desk .mfb-kc-daftar > .course-mgmt-card.is-terbit {
  background-image: linear-gradient(90deg, #059669 0 4px, transparent 4px);
}
#desk .mfb-kc-daftar > .course-mgmt-card.is-draf {
  background-image: linear-gradient(90deg, #C2410C 0 4px, transparent 4px);
}
/* Arsip di kartu hampir hitam, tapi di baris putih warna sepekat itu
   justru paling menarik mata — kebalikan dari maksudnya. Di sini ia
   abu hangat yang sengaja paling lemah: ada kalau dicari, tidak
   memanggil kalau tidak. */
#desk .mfb-kc-daftar > .course-mgmt-card.is-arsip {
  background-image: linear-gradient(90deg, #A8A29E 0 4px, transparent 4px);
}

#desk .mfb-kc-daftar .cmg-thumb,
#desk .mfb-kc-daftar .cmg-body { display: contents; }
#desk .mfb-kc-daftar .cmg-thumb-bg,
#desk .mfb-kc-daftar .cmg-thumb-icon,
#desk .mfb-kc-daftar .cmg-progress-bar { display: none; }

#desk .mfb-kc-daftar .mfb-kc-lambang {
  grid-area: ikon;
  width: 38px;
  height: 38px;
  background: linear-gradient(135deg, var(--mfb-chrome-atas), var(--mfb-chrome-bawah));
  box-shadow: none;
}
#desk .mfb-kc-daftar .mfb-kc-lambang svg { width: 19px; height: 19px; }
#desk .mfb-kc-daftar .cmg-title     { grid-area: judul; margin: 0; }
#desk .mfb-kc-daftar .cmg-course-id { grid-area: kode; margin: 0; }
#desk .mfb-kc-daftar .cmg-dept      { grid-area: dept; margin: 0; }
#desk .mfb-kc-daftar .mfb-kc-isi    { grid-area: isi; margin: 0; }
#desk .mfb-kc-daftar .cmg-stats     { grid-area: stat; margin: 0; }
/* Pil tidak dilipat dua baris — "Quiz has / no questions" terbaca
   sebagai dua pesan (terlihat di screenshot 1366px). */
#desk .mfb-kc-daftar .mfb-kc-siap   { grid-area: siap; margin: 0; justify-self: start; white-space: nowrap; }
#desk .mfb-kc-daftar .cmg-footer    { grid-area: aksi; justify-self: end; flex-wrap: nowrap; }

/* Label status: di kartu ia duduk di atas spanduk HITAM, jadi warnanya
   terang. Di baris list latarnya putih — warna yang sama hanya ±2 : 1.
   Diganti warna yang terukur di atas putih. */
#desk .mfb-kc-daftar .cmg-status { grid-area: status; position: static; justify-self: start; }
#desk .mfb-kc-daftar .cmg-status.s-published { background: rgba(16, 185, 129, 0.12); color: #047857; }
#desk .mfb-kc-daftar .cmg-status.s-draft     { background: rgba(245, 158, 11, 0.14); color: #8F5400; }
#desk .mfb-kc-daftar .cmg-status.s-archived  { background: rgba(120, 116, 112, 0.14); color: #57534E; }
body.dark-mode #desk .mfb-kc-daftar .cmg-status.s-published { background: rgba(52, 211, 153, 0.14); color: #6EE7B7; }
body.dark-mode #desk .mfb-kc-daftar .cmg-status.s-draft     { background: rgba(251, 191, 36, 0.14); color: #FCD34D; }
body.dark-mode #desk .mfb-kc-daftar .cmg-status.s-archived  { background: rgba(214, 208, 196, 0.12); color: #D6D0C4; }

/* Kartu "Create New Course" jadi baris tipis di ujung daftar. */
#desk .mfb-kc-daftar > .add-course-cta {
  flex-direction: row;
  justify-content: flex-start;
  gap: 12px;
  min-height: 0;
  padding: 14px 18px;
  border: 0;
  border-radius: 0;
  background: transparent;
}
#desk .mfb-kc-daftar > .add-course-cta .icon { margin: 0; }
#desk .mfb-kc-daftar > .add-course-cta .icon .mfb-kc-ikon { width: 20px; height: 20px; }
#desk .mfb-kc-daftar > .add-course-cta .sub { margin: 0; }
#desk .mfb-kc-daftar > .add-course-cta:hover { background: rgba(201, 160, 101, 0.05); }
#desk .mfb-kc-daftar > .mfb-kc-kosong { border: 0; border-radius: 0; }

/* --- tiga tingkat lebar layar ---
   Dihitung dari lebar isi = layar − sidebar 240 − padding 64 − bingkai:
     ≥1560px  semua kolom, tombol berlabel      (butuh ±1.210px isi)
     1280–1559 kolom Department & statistik dilipat, Edit & Modules
               jadi ikon saja                   (butuh ±950px isi)
     900–1279 baris bertumpuk tanpa kepala kolom (butuh ±550px isi)
   Tanpa tingkat ini, di 1366px dan 1100px tombol di SETIAP baris
   terlipat tiga — terukur di Chrome sebelum diperbaiki. */

/* Label tombol disembunyikan SECARA VISUAL saja: teksnya tetap ada di
   DOM, jadi pembaca layar tetap membacakan "Edit" / "Modules". */
@media (min-width: 900px) and (max-width: 1559px) {
  #desk .mfb-kc-daftar .btn-tbl:not(.gold-btn) .mfb-kc-label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }
  #desk .mfb-kc-daftar .btn-tbl:not(.gold-btn):not(.mfb-kc-arsip) {
    position: relative;
    width: 32px;
    padding: 0;
    justify-content: center;
  }
  #desk .mfb-kc-daftar .btn-tbl svg { display: block !important; }
}

@media (min-width: 1280px) and (max-width: 1559px) {
  #desk .mfb-kc-daftar > .mfb-kc-kepala,
  #desk .mfb-kc-daftar > .course-mgmt-card {
    grid-template-columns: 38px minmax(170px, 2fr) 92px minmax(160px, 1.3fr) minmax(170px, 1.2fr) 212px;
  }
  #desk .mfb-kc-daftar > .course-mgmt-card {
    /* v1.103 (rilis 2.238) — IT Manager 1 Okt: "Department ga muncul ketika dalam list". Dulu
       DISEMBUNYIKAN di 1280–1559 px supaya muat; kini baris ketiga di sel judul. */
    grid-template-areas:
      "ikon judul status isi siap aksi"
      "ikon kode  status isi siap aksi"
      "ikon dept  status isi siap aksi";
  }
  #desk .mfb-kc-daftar .cmg-stats,
  #desk .mfb-kc-daftar > .mfb-kc-kepala > span:nth-child(3) { display: none; }
}

@media (min-width: 900px) and (max-width: 1279px) {
  #desk .mfb-kc-daftar > .mfb-kc-kepala { display: none; }
  #desk .mfb-kc-daftar > .course-mgmt-card {
    grid-template-columns: 38px minmax(0, 1fr) auto 212px;
    grid-template-areas:
      "ikon judul status aksi"
      "ikon kode  kode   aksi"
      "ikon dept  dept   aksi"
      "ikon isi   isi    aksi"
      "ikon siap  siap   aksi";
    row-gap: 4px;
  }
  #desk .mfb-kc-daftar .mfb-kc-lambang { align-self: start; }
  #desk .mfb-kc-daftar .cmg-stats { display: none; }  /* v1.103 — cmg-dept TIDAK lagi disembunyikan */
  #desk .mfb-kc-daftar .mfb-kc-siap { margin-top: 2px; }
}

/* Toolbar di mode gelap.
   🔴 Masalah LAMA di halaman ini, terlihat di screenshot mode gelap:
   bagian 1g memberi .mgmt-toolbar gradien putih, tapi daftar varian
   gelapnya lupa menyertakan toolbar ini — jadi di mode gelap ia tampil
   sebagai pita abu-abu terang di atas latar hitam. */
body.dark-mode #desk .mgmt-toolbar {
  background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.045) 0%, rgba(255, 255, 255, 0) 62%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.06),
    0 2px 5px rgba(0, 0, 0, 0.42),
    0 10px 26px rgba(0, 0, 0, 0.3);
  border-color: rgba(255, 255, 255, 0.1);
}

/* ----------------------------------------------------------------
   42. KOLOM ISIAN 16 PX — iPhone TIDAK ZOOM SENDIRI
   ================================================================
   Safari iPhone memperbesar halaman begitu kolom dengan huruf di
   bawah 16 px disentuh, dan tidak mengembalikannya. Di layar login
   itu berarti ketukan PERTAMA staff di aplikasi ini — kolom
   Employee ID — membuat layar melompat dan tombol Sign In bergeser.

   Diukur di Chrome 15 Sep 2026: kolom login 15 px, kolom password
   Profile 14 px, kolom password wajib saat login pertama 14 px.

   Halaman login dikunci "persis sistem lama"; perubahan 1 px ini
   disetujui IT Manager 16 Sep 2026 (keputusan no. 11 brief UX).
   ---------------------------------------------------------------- */
#mob .lf-input,
#mob .mob-form-input,
#modal-changepw .mpw-input {
  font-size: 16px;
}

/* ================================================================
   6. SAMBUTAN SEKALI JALAN UNTUK PESERTA TRIAL
   ================================================================

   Muncul sekali sesudah login pertama, lalu diam. Isinya bahasa
   Inggris — permintaan IT Manager 21 September 2026, mengikuti bahasa
   antarmuka baseline yang memang Inggris.

   🔴 Warnanya mengikuti kartu login baseline, BUKAN palet baru.
   Sambutan yang terlihat seperti tempelan dari sistem lain adalah
   hal pertama yang dilihat penguji, dan kesan "ini belum jadi"
   paling mahal justru di detik pertama.

   Lebar dibatasi lewat padding + width persen, bukan max-width px:
   di layar 360 px sebuah max-width 420px akan membuat kotaknya
   menyentuh tepi layar tanpa ruang napas.
   ---------------------------------------------------------------- */

.mfb-sambutan-tirai {
  position: fixed;
  inset: 0;
  z-index: 9000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(12, 11, 8, 0.72);
  /* 🔴 SENGAJA TANPA backdrop-filter, dan itu ditolak uji lebih dulu.
     Versi pertama memakai blur(4px). Aturan project membatasi blur ke
     palet perintah saja, dan godaan saya adalah melebarkan daftar
     pengecualian supaya kode sendiri lolos — cara tercepat membuat
     sebuah aturan berhenti berarti apa-apa.
     Lagipula tidak dibutuhkan: pada kepekatan 0.72 yang di belakang
     sudah nyaris tidak terbaca, jadi blur hanya menambah satu lapisan
     yang dilukis ulang tanpa ada yang melihat bedanya. */
  animation: mfb-sambutan-masuk 0.22s ease;
}
@keyframes mfb-sambutan-masuk { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .mfb-sambutan-tirai { animation: none; }
}

.mfb-sambutan {
  position: relative;
  width: 100%;
  /* 🔴 width persen + padding, bukan max-width px. Di 360 px kotak
     bermax-width 420px menempel ke tepi; ini menyisakan tepi 20px
     dari tirai di atas. */
  background: #FFFFFF;
  color: #1C1810;
  border-radius: 18px;
  padding: 30px 26px 26px;
  box-shadow: 0 18px 60px rgba(0, 0, 0, 0.42);
  text-align: left;
  font-family: 'Inter', 'Segoe UI', system-ui, sans-serif;
}
@media (min-width: 560px) {
  .mfb-sambutan { width: 84%; padding: 36px 38px 30px; }
}
@media (min-width: 900px) {
  .mfb-sambutan { width: 46%; }
}

.mfb-sambutan-atas {
  font-family: 'Cinzel', Georgia, serif;
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #8A6D23;
  font-weight: 700;
  margin: 0 0 10px;
}
.mfb-sambutan h2 {
  font-family: 'Cinzel', Georgia, serif;
  font-size: clamp(21px, 4.6vw, 27px);
  line-height: 1.22;
  margin: 0 0 12px;
  color: #12100B;
  font-weight: 700;
}
.mfb-sambutan p {
  margin: 0 0 13px;
  font-size: 15px;
  line-height: 1.68;
  color: #4A443A;
}
.mfb-sambutan p:last-of-type { margin-bottom: 20px; }
.mfb-sambutan strong { color: #1C1810; }

/* 🔴 Tombol silang 44x44 px. Ikonnya kecil, tapi area sentuhnya
   tidak boleh ikut kecil — di HP, tombol tutup yang meleset membuat
   orang menekan berkali-kali dan menyangka aplikasinya hang. */
.mfb-sambutan-x {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: 10px;
  color: #8A8172;
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
}
.mfb-sambutan-x:hover { background: #F4F0E7; color: #1C1810; }
.mfb-sambutan-x:focus-visible { outline: 3px solid #8A6D23; outline-offset: 2px; }

.mfb-sambutan-cek {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  min-height: 44px;
  padding: 4px 0;
  margin: 0 0 18px;
  cursor: pointer;
  font-size: 14px;
  color: #5A5344;
  line-height: 1.5;
}
.mfb-sambutan-cek input {
  width: 19px;
  height: 19px;
  margin: 2px 0 0;
  flex: 0 0 auto;
  accent-color: #8A6D23;
  cursor: pointer;
}

.mfb-sambutan-ok {
  width: 100%;
  min-height: 48px;
  background: #1C1810;
  color: #F2EDE3;
  border: 0;
  border-radius: 11px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.18s;
}
.mfb-sambutan-ok:hover { background: #2E2819; }
.mfb-sambutan-ok:focus-visible { outline: 3px solid #8A6D23; outline-offset: 3px; }

/* ================================================================
   37. SERTIFIKAT — rancangan "Panel Samping"
   ----------------------------------------------------------------
   Dibangkitkan dari Deploy/certificate-design-c.html, BUKAN disalin
   tangan. Setiap nilai mm dikalikan 0.944304 supaya
   .lembar jatuh tepat di 1060px — lebar yang dikunci
   _runDownloadCertPDF_ (windowWidth:1060). Lebar itulah yang
   memperbaiki rasio PDF antar perangkat di v2.111/v2.126; memakai
   297mm apa adanya akan memecahkannya lagi.

   Seluruh selektor berawalan .mfb-sert dan :root diganti .mfb-sert,
   jadi nol kemungkinan bocor ke halaman LMS lain.
   ================================================================ */
.mfb-sert{
  --tinta       : #14110E;  /* hitam hangat; #000 murni terbaca keras di kertas */
  --emas        : #C9A05A;  /* emas brand — untuk TEKS kecil & aksen */
  --emas-garis  : #A8813E;  /* emas 12% lebih dalam, KHUSUS garis rambut 0,2-0,4 mm.
                               Emas terang pada garis setipis itu hilang di kertas. */
  --redup       : #7C7369;
  --kertas      : #FFFFFF;
  --pilar       : #12100D;  /* bidang gelap, dalam rentang #0E0C0A–#1A1714 */
  --pilar-teks  : #F2ECE1;  /* krem; kontras ±17:1 di atas --pilar */
  --pilar-redup : #A79B8B;
}
.mfb-sert .lembar{
  width:280.4583mm; height:198.3039mm;
  flex:0 0 auto;
  background:var(--kertas);
  position:relative; overflow:hidden;
  display:flex; flex-direction:row; align-items:stretch;
  color:var(--tinta);
  /* Memaksa warna ikut tercetak. Tanpa ini "Background graphics"
     yang BAWAANNYA TIDAK TERCENTANG membuang seluruh pilar gelap,
     emas, dan segel — lalu orang mengira desainnya yang rusak. */
  print-color-adjust:exact; -webkit-print-color-adjust:exact;
  box-shadow:0 2.8329mm 11.3316mm rgba(20,17,14,.22);
}
.mfb-sert .pilar{
  flex:0 0 64.2127mm; position:relative;
  background:var(--pilar); color:var(--pilar-teks);
  display:flex; flex-direction:column;
  padding:15.1089mm 10.3873mm 13.2203mm;
  print-color-adjust:exact; -webkit-print-color-adjust:exact;
}
.mfb-sert .pilar::after{content:"";position:absolute;top:0;right:0;width:1.5109mm;height:100%;
  background:var(--emas)}
.mfb-sert .pilar-logo{width:41.5494mm;height:auto;display:block}
.mfb-sert .pilar-garis{margin:6.6101mm 0 5.6658mm;height:0.2833mm;background:var(--emas-garis);width:28.3291mm}
.mfb-sert .pilar-meta{display:flex;flex-direction:column;gap:4.9104mm}
.mfb-sert .pilar-meta dt{font-size:2.4552mm;font-weight:600;letter-spacing:.2em;text-transform:uppercase;
  color:var(--emas)}
.mfb-sert .pilar-meta dd{margin-top:1.322mm;font-size:3.2106mm;font-weight:600;color:var(--pilar-teks);
  font-variant-numeric:tabular-nums;letter-spacing:.02em}
.mfb-sert .pilar-isi{flex:1;min-height:8.4987mm}
.mfb-sert .segel-bungkus{display:flex;justify-content:center}
.mfb-sert .segel{width:35.8836mm;height:auto;display:block}
.mfb-sert .pilar-kaki{margin-top:8.4987mm;text-align:center;font-size:2.4552mm;font-weight:600;
  letter-spacing:.22em;text-transform:uppercase;color:var(--pilar-redup)}
.mfb-sert .isi{flex:1;display:flex;flex-direction:column;padding:18.8861mm 22.6633mm 13.2203mm 20.7747mm;position:relative}
.mfb-sert .tajuk{display:flex;align-items:center;gap:5.6658mm}
.mfb-sert .tajuk span{font-family:'Cinzel',serif;font-weight:600;font-size:3.9661mm;
  letter-spacing:.3em;text-transform:uppercase;white-space:nowrap}
.mfb-sert .tajuk i{flex:1;height:0.2361mm;background:var(--emas-garis);opacity:.8}
.mfb-sert .inti{flex:1;display:flex;flex-direction:column;justify-content:center}
.mfb-sert .antar{font-size:3.0218mm;color:var(--redup);letter-spacing:.03em}
.mfb-sert .nama{font-family:'Cinzel',serif;font-weight:700;font-size:14.1646mm;line-height:1.06;
  letter-spacing:.012em;margin:3.7772mm 0 4.2494mm}
.mfb-sert .garis-nama{width:54.7696mm;height:0.3777mm;background:var(--emas-garis)}
.mfb-sert .dept-staff{margin-top:3.7772mm}
.mfb-sert .dept-staff .lbl{display:block;font-size:2.4552mm;font-weight:600;letter-spacing:.2em;
  text-transform:uppercase;color:var(--emas)}
.mfb-sert .dept-staff .val{display:block;margin-top:1.322mm;font-size:3.3995mm;font-weight:600;
  color:var(--tinta);letter-spacing:.02em}
.mfb-sert .antar-2{margin-top:7.5544mm;font-size:3.0218mm;color:var(--redup);letter-spacing:.03em}
.mfb-sert .course{font-family:'Cinzel',serif;font-weight:600;font-size:7.5544mm;line-height:1.2;
  margin-top:2.8329mm;letter-spacing:.01em}
.mfb-sert .dept-course{margin-top:4.2494mm;display:inline-flex;align-self:flex-start;align-items:center;
  gap:3.2106mm;border:0.1889mm solid var(--emas-garis);padding:2.0775mm 4.7215mm 2.0775mm 0;position:relative}
.mfb-sert .dept-course::before{content:"";width:0.9443mm;align-self:stretch;background:var(--emas);
  margin-right:1.5109mm}
.mfb-sert .dept-course .lbl{font-size:2.4552mm;font-weight:600;letter-spacing:.2em;
  text-transform:uppercase;color:var(--emas)}
.mfb-sert .dept-course .val{font-size:3.0218mm;font-weight:600;color:var(--tinta)}
.mfb-sert .nilai{margin-top:7.5544mm;padding-top:3.2106mm;border-top:0.2361mm solid var(--emas-garis);
  width:98.2076mm;display:flex;align-items:baseline;gap:4.7215mm}
.mfb-sert .nilai .lbl{font-size:2.4552mm;font-weight:600;letter-spacing:.2em;text-transform:uppercase;
  color:var(--emas)}
.mfb-sert .nilai .angka{font-family:'Cinzel',serif;font-weight:700;font-size:7.1767mm;
  font-variant-numeric:tabular-nums;letter-spacing:.01em}
.mfb-sert .nilai .predikat{font-family:'Inter',sans-serif;font-style:italic;font-size:3.7772mm;
  color:var(--emas);letter-spacing:.02em}
.mfb-sert .kaki{margin-top:6.6101mm}
.mfb-sert .ttd-baris{display:grid;grid-template-columns:1fr 1fr;gap:15.1089mm}
.mfb-sert .ttd-gambar{height:17.9418mm;display:flex;align-items:flex-end;color:var(--tinta)}
.mfb-sert .ttd-gambar svg{display:block;width:37.7722mm;height:auto}
.mfb-sert .ttd-gambar.besar svg{width:43.438mm}
.mfb-sert .spesimen{margin-top:1.1332mm;margin-bottom:2.0775mm;font-family:'Inter',sans-serif;
  font-style:italic;font-size:2.3608mm;color:var(--redup);letter-spacing:.02em}
.mfb-sert .ttd-garis{height:0.2833mm;background:var(--tinta);opacity:.85}
.mfb-sert .ttd-nama{margin-top:2.4552mm;font-family:'Cinzel',serif;font-weight:600;font-size:4.1549mm;
  letter-spacing:.03em}
.mfb-sert .ttd-jabat{margin-top:1.5109mm;font-size:2.5496mm;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--redup)}
.mfb-sert .jejak{margin-top:6.6101mm;padding-top:2.8329mm;border-top:0.1889mm solid var(--emas-garis);
  display:flex;justify-content:space-between;align-items:baseline;gap:7.5544mm;
  font-size:2.4552mm;color:var(--redup);letter-spacing:.04em}
.mfb-sert .jejak b{font-weight:600;color:var(--tinta);font-variant-numeric:tabular-nums}









/* ── CETAK ─────────────────────────────────────────────────────── */

/* Lembar TIDAK memuat bayangan di dalam LMS: #cert-pdf-target
   difoto html2canvas, dan bayangan menambah piksel di luar kotak
   yang bisa melahirkan halaman kedua di PDF. */
.mfb-sert .lembar { box-shadow: none; margin: 0 auto; }
.mfb-sert { display: flex; justify-content: center; }
@media print {
  .mfb-sert .lembar { box-shadow: none; break-inside: avoid; page-break-inside: avoid; }
}

/* ================================================================
   48. KUIS DI HP — KOTAK NOMOR SOAL  (v2.205)

   Baseline SUDAH punya navigator kotak bernomor untuk kuis, lengkap
   dengan warna terjawab / sedang dikerjakan / belum. Tapi seluruh
   aturannya diawali "#desk" (index.html:2913-2916), jadi di HP tidak
   ada sama sekali — padahal staff outlet mayoritas memakai HP.

   Yang mereka lihat sekarang hanya bilah tipis dan tulisan "3/15":
   tidak ada cara mengetahui soal MANA yang masih kosong, dan tidak
   ada cara melompat ke sana. Di kuis berbatas waktu, itu bukan
   ketidaknyamanan kecil — itu penyebab soal tertinggal kosong.

   Warnanya sengaja MENIRU desktop, bukan mengarang bahasa baru:
     terjawab = --solid-dark (hitam) · berjalan = --gold (emas) ·
     belum    = --gray-100 (abu-abu)
   supaya staff yang bergantian memakai laptop dan HP melihat kode
   warna yang sama. Ketiga variabel itu ada di :root index.html,
   bukan di dalam #desk — sudah diperiksa sebelum dipakai di sini.

   44x44 px, bukan 28 px seperti desktop. Di desktop ada tetikus; di
   HP jari butuh ruang, dan salah tekan di sini berarti melompat ke
   soal lain di tengah kuis berbatas waktu. SOP aksesibilitas
   mewajibkan 44 px, dan ini justru tempat yang paling membuktikan
   kenapa.

   🔴 Warna BUKAN satu-satunya penanda. Kotak yang belum terjawab
   diberi garis tepi PUTUS-PUTUS, dan tiap kotak membawa aria-label
   yang menyebut statusnya dengan kata. Staff dengan buta warna
   merah-hijau tetap bisa membedakan, dan pembaca layar tetap
   menyebutkannya.
   ================================================================ */

#mob .mfb-kuis-kotak {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 14px;
}

#mob .mfb-kdot {
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border-radius: 10px;
  border: 1px solid transparent;
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background .18s, color .18s, border-color .18s;
}

#mob .mfb-kdot.sudah { background: var(--solid-dark); color: #fff; }
#mob .mfb-kdot.kini  { background: var(--gold); color: var(--black); }
#mob .mfb-kdot.belum {
  background: var(--gray-100);
  color: var(--gray-500);
  border-style: dashed;
  border-color: var(--gray-200);
}

#mob .mfb-kdot:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

body.dark-mode #mob .mfb-kdot.sudah { background: #E8E8E8; color: #111111; }
body.dark-mode #mob .mfb-kdot.belum {
  background: #26262A;
  color: #9A9AA0;
  border-color: #3A3A40;
}

@media (prefers-reduced-motion: reduce) {
  #mob .mfb-kdot { transition: none; }
}

/* ================================================================
   49. POPUP "BERHASIL" — sesudah Generate AI Report

   IT Manager 22 September 2026: "generate now dah di click, kasi pop up
   donk kak, berhasil apa gitu, in english tapi."

   Pesan sebaris di bilah aksi sebenarnya SUDAH ada, tapi halamannya
   dimuat ulang sedetik kemudian dan pesannya ikut hilang — jadi dari
   sisi pengguna, menekan tombol itu terasa tidak menghasilkan
   apa-apa. Popup ini menunggu ditutup lebih dulu, baru halamannya
   dimuat ulang.

   Dibuat sebagai dialog sungguhan, bukan toast: ia memblokir sampai
   diakui, dan memang itu maksudnya.
   ================================================================ */

#mfb-kabar.mfb-kabar-tirai {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(10, 10, 10, 0.55);
  /* 100% bukan 100vw: 100vw ikut menghitung scrollbar dan
     memunculkan geseran mendatar ~15px di Windows. */
  max-width: 100%;
}

#mfb-kabar .mfb-kabar {
  background: var(--white, #FFFFFF);
  border-radius: 16px;
  padding: 28px clamp(22px, 5vw, 32px) 24px;
  width: 100%;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.28);
  text-align: center;
}

#mfb-kabar .mfb-kabar h2 {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 20px;
  line-height: 1.25;
  margin: 0 0 10px;
  color: var(--black, #0A0A0A);
}

#mfb-kabar .mfb-kabar p {
  font-size: 14px;
  line-height: 1.6;
  margin: 0 0 22px;
  color: var(--gray-500, #6B6B6B);
}

#mfb-kabar .mfb-kabar-ok {
  min-height: 44px;
  min-width: 128px;
  padding: 0 24px;
  border: none;
  border-radius: 10px;
  background: var(--gold, #C9A065);
  color: var(--black, #0A0A0A);
  font-family: inherit;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}

#mfb-kabar .mfb-kabar-ok:focus-visible {
  outline: 2px solid var(--black, #0A0A0A);
  outline-offset: 2px;
}

body.dark-mode #mfb-kabar .mfb-kabar { background: #17171A; }
body.dark-mode #mfb-kabar .mfb-kabar h2 { color: #F2F2F2; }
body.dark-mode #mfb-kabar .mfb-kabar p { color: #A6A6AD; }


/* ================================================================
   50. KONTRAS — DEMO GM 23 SEPTEMBER 2026  (v2.206, MoM #9)
   ----------------------------------------------------------------
   --gray-600 dipakai 13 kali (label editor soal quiz: QUESTION,
   OPTION A–D, tombol "← Back" AI Report, …) tetapi TIDAK PERNAH
   didefinisikan — baseline hanya punya 50–500 dan 700. Warna yang
   tidak terdefinisi jatuh ke hitam, jadi di mode gelap teksnya hitam
   di atas hampir-hitam: 1,21–1,26 : 1.

   Nilainya berada di antara 500 dan 700 milik baseline sendiri,
   bukan warna baru: terang #5A5854 (≈ 7 : 1 di atas putih), gelap
   #BDBDBD (≈ 9 : 1 di atas #1E1E1E).
   ================================================================ */
:root { --gray-600: #5A5854; }
body.dark-mode { --gray-600: #BDBDBD; }
/* 50b. --gray-900 juga tidak pernah didefinisikan. Di terang setiap
   pemakainya sudah membawa cadangan gelapnya sendiri (jadi TIDAK
   didefinisikan di :root — tampilannya tetap persis). Di gelap, 14 dari
   16 pemakainya punya aturan gelap sendiri; dua yang tidak —
   .mfb-perhatian-judul (Reports, 1,04 : 1) dan label "Can take courses"
   di form user — jatuh ke hitam di atas hitam. */
body.dark-mode { --gray-900: #F0F0F0; }
/* Teks sekunder gelap (--gray-400 #8A8A8A baseline) di atas kartu
   #282828: 4,29 : 1 — sedikit di bawah 4,5. #9A9A9A = 5,3 : 1. Ditulis
   dengan `html` di depan karena lembar ini dimuat SEBELUM gaya baseline;
   dengan kekhususan yang sama, baseline yang menang. */
html body.dark-mode { --gray-400: #9A9A9A; }
body.dark-mode .mfb-rank-nama { color: #F0F0F0; }   /* AI Report, 1,26 : 1 */

/* 50c. CHIP KATEGORI (Activity Log, Attendance) — warna teksnya dibuat
   untuk latar terang; di gelap 2,57–2,80 : 1. Latar tipisnya tetap. */
body.dark-mode #desk .let-auth,     body.dark-mode #desk .etc-training { color: #93C5FD; }
body.dark-mode #desk .let-quiz,     body.dark-mode #desk .etc-general  { color: #C4B5FD; }
body.dark-mode #desk .let-training, body.dark-mode #desk .etc-party    { color: #E8C97A; }
body.dark-mode #desk .let-admin,    body.dark-mode #desk .etc-csr      { color: #6EE7B7; }
body.dark-mode #desk .etc-iv { color: #FCA5A5; }

/* 50d. PIL FLAG (NORMAL / WARNING / CRITICAL) — latar pucatnya tetap
   terang di mode gelap, jadi terlihat seperti tempelan putih. */
body.dark-mode #desk .flag-normal   { background: rgba(16, 185, 129, 0.16); color: #6EE7B7; }
body.dark-mode #desk .flag-warning  { background: rgba(245, 158, 11, 0.16); color: #FCD34D; }
body.dark-mode #desk .flag-critical { background: rgba(220, 38, 38, 0.18);  color: #FCA5A5; }
/* Terang: 3,97 / 4,43 / 4,15 : 1 di ukuran 11 px — digelapkan sedikit. */
body:not(.dark-mode) #desk .flag-normal   { color: #166534; }
body:not(.dark-mode) #desk .flag-warning  { color: #7C5200; }
body:not(.dark-mode) #desk .flag-critical { color: #B91C1C; }

/* 50e. BARIS CRITICAL / WARNING DI ACTIVITY LOG (MoM #13). Baseline
   mewarnai barisnya rgba(…, 0.025) — 1,04 : 1, praktis tak terlihat di
   layar mana pun. Kini tinta yang terbaca + garis kiri berwarna, jadi
   statusnya tidak hanya bergantung pada warna latar. */
#desk #d-actlog-tbody tr:has(.flag-critical) { background: rgba(220, 38, 38, 0.07) !important; }
#desk #d-actlog-tbody tr:has(.flag-warning)  { background: rgba(245, 158, 11, 0.08) !important; }
#desk #d-actlog-tbody tr:has(.flag-critical) > td:first-child { box-shadow: inset 3px 0 0 #DC2626; }
#desk #d-actlog-tbody tr:has(.flag-warning)  > td:first-child { box-shadow: inset 3px 0 0 #D97706; }

/* 50f. ANGKA BESAR DI KARTU RINGKAS — warnanya ditulis baseline sebagai
   style sebaris (color:var(--green) dst.). Hijau, emas, dan kuning itu
   warna HIASAN: sebagai teks di kartu terang hanya 1,96–2,32 : 1, di
   bawah batas 3 : 1 untuk angka besar. Terang memakai versi gelapnya
   (--gold-text milik baseline sendiri); gelap: biru dinaikkan. */
body:not(.dark-mode) #desk .rep-sum-num[style*="--green"],
body:not(.dark-mode) #desk .stat-mini-num[style*="--green"],
body:not(.dark-mode) #desk .log-stat-num[style*="--green"] { color: #047857 !important; }
body:not(.dark-mode) #desk .rep-sum-num[style*="--gold"],
body:not(.dark-mode) #desk .stat-mini-num[style*="--gold"] { color: var(--gold-text, #8A6A1F) !important; }
body:not(.dark-mode) #desk .rep-sum-num[style*="--amber"],
body:not(.dark-mode) #desk .stat-mini-num[style*="--amber"],
body:not(.dark-mode) #desk .log-stat-num[style*="--amber"] { color: #B45309 !important; }
body.dark-mode #desk .log-stat-num[style*="--blue"],
body.dark-mode #desk .stat-mini-num[style*="--blue"] { color: #60A5FA !important; }

/* 50g. TEKS EMAS KECIL DI REPORTS & MANAGE COURSES (MoM #12) — emas
   hiasan #C9A065 di kartu terang 2,21 : 1. */
body:not(.dark-mode) #desk .prog-pct-d,
body:not(.dark-mode) .mfb-perhatian-item.tinjau .mfb-perhatian-angka { color: var(--gold-text, #8A6A1F); }
/* Sebaris: "% done" di kartu course dan sel tabel laporan. */
body:not(.dark-mode) #desk .cmg-stat[style*="--gold"],
body:not(.dark-mode) #desk .mgmt-table td[style*="color:var(--gold)"] { color: var(--gold-text, #8A6A1F) !important; }
body:not(.dark-mode) #desk .cmg-stat[style*="--green"],
body:not(.dark-mode) #desk .mgmt-table td[style*="color:var(--green)"] { color: #047857 !important; }
/* Chip kategori di terang: 3,84–4,20 : 1 di atas baris bertinta (50e). */
body:not(.dark-mode) #desk .let-auth { color: #1D4ED8; }
body:not(.dark-mode) #desk .let-quiz { color: #6D28D9; }

/* 50h. EDITOR SOAL QUIZ (MoM #9) — baseline menulis warnanya sebaris.
   Di latar putih: nomor soal emas 2,41, jawaban benar hijau 2,54,
   tingkat & penjelasan abu-abu 2,41 : 1. Hanya di dalam daftar soal. */
body:not(.dark-mode) #d-qqModal-list [style*="color:var(--gold)"]     { color: var(--gold-text, #8A6A1F) !important; }
body:not(.dark-mode) #d-qqModal-list [style*="color:var(--green)"]    { color: #047857 !important; }
body:not(.dark-mode) #d-qqModal-list [style*="color:var(--gray-400)"] { color: var(--gray-600) !important; }

/* 50i. BAGIAN AI REPORT (MoM #14) — latar #0A0A0A→#1A1208 di halaman
   #0A0A0A: 1,03 : 1, bagiannya melebur ke halaman. Bingkai dipertegas. */
body.dark-mode .air-section { border-color: rgba(232, 201, 106, 0.38); }

/* 50j. VIDEO TAMAT (MoM #2) — halaman tidak lagi pindah sendiri; tombol
   Next Module disorot supaya langkah berikutnya jelas. Berdenyut tiga
   kali lalu diam; tanpa gerak bagi yang meminta gerak dikurangi. */
.mfb-siap-lanjut {
  box-shadow: 0 0 0 3px rgba(201, 160, 101, 0.55), 0 6px 18px rgba(201, 160, 101, 0.35);
  animation: mfb-siap-lanjut 1.6s ease-in-out 3;
}
@keyframes mfb-siap-lanjut {
  50% { box-shadow: 0 0 0 7px rgba(201, 160, 101, 0.22), 0 6px 18px rgba(201, 160, 101, 0.35); }
}
@media (prefers-reduced-motion: reduce) {
  .mfb-siap-lanjut { animation: none; }
}

/* 50k. KARTU "CONTINUE LEARNING" SAMPAI TIGA (MoM #21). Kartu pertama
   tetap seperti sebelumnya; kartu ke-2 dan ke-3 lebih ringkas dan
   merapat, jadi terbaca sebagai satu tumpukan — bukan tiga iklan. */
.mfb-lanjut.mfb-lanjut-lagi {
  margin-top: -8px;
  padding-top: 10px;
  padding-bottom: 10px;
}
.mfb-lanjut-lagi .mfb-lanjut-cap { display: none; }
.mfb-lanjut-lagi .mfb-lanjut-judul { margin-top: 0; font-size: 14px; }

/* ================================================================
   51. TEKS SEKUNDER MODE TERANG  (v2.207 — disetujui IT 24 Sep 2026)
   ----------------------------------------------------------------
   --gray-400 baseline #A8A7A3 di kartu #F6F5F1 hanya 2,21 : 1 dan
   --gray-500 #787672 4,15 : 1 — keduanya di bawah 4,5 : 1. Dipakai
   hampir hanya sebagai WARNA TEKS (128/134 dan 140/145 pemakaian,
   nol sebagai garis tepi atau latar), jadi menggelapkannya tidak
   menebalkan bingkai apa pun. Urutannya tetap: 500 lebih gelap dari 400.
     #6B6964 = 5,03 : 1   ·   #5C5A56 = 6,31 : 1   (di kartu #F6F5F1)
   Contoh sebelum/sesudah: Documentation/contoh-abu-*.png.

   🔴 DUA PENGECUALIAN, sengaja:
   · Halaman login dikunci "persis sistem lama" — nilai lamanya
     dipulihkan di #d-login dan #m-login.
   · Placeholder adalah PETUNJUK, bukan isi. Kalau ikut digelapkan ia
     terbaca seperti teks yang sudah diketik, jadi warnanya dibiarkan.
   Mode gelap tidak disentuh (body.dark-mode punya nilainya sendiri).
   ================================================================ */
html body:not(.dark-mode) { --gray-400: #6B6964; --gray-500: #5C5A56; }
html body:not(.dark-mode) #d-login,
html body:not(.dark-mode) #m-login { --gray-400: #A8A7A3; --gray-500: #787672; }
html body:not(.dark-mode) #desk input::placeholder,
html body:not(.dark-mode) #desk textarea::placeholder,
html body:not(.dark-mode) #mob input::placeholder,
html body:not(.dark-mode) #mob textarea::placeholder,
html body:not(.dark-mode) .mfb-pal-input::placeholder { color: #A8A7A3; }

/* ================================================================
   52. HELP DI PROFILE  (v2.207 — MoM #15)
   Satu kartu-tautan: di desktop paling atas kolom kanan Profile, di HP
   sesudah saklar Dark Mode. Seluruh kartu adalah target sentuh (≥ 56 px).
   ================================================================ */
.mfb-help {
  display: flex; align-items: center; gap: 14px;
  min-height: 56px; padding: 14px 16px; border-radius: 14px;
  background: var(--white, #FFFFFF); border: 1px solid rgba(201, 168, 76, 0.45);
  color: var(--black, #0A0A0A); text-decoration: none;
  transition: border-color .18s ease, box-shadow .18s ease;
}
.mfb-help:hover { border-color: #C9A065; box-shadow: 0 4px 14px rgba(60, 44, 20, 0.10); }
.mfb-help:focus-visible { outline: 2px solid #C9A065; outline-offset: 2px; }
.mfb-help.mfb-help-desk { margin-bottom: 16px; }
.mfb-help.mfb-help-hp { margin: 0 16px 16px; }
.mfb-help-ikon {
  flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: #16130F; color: #E8C96A; font-weight: 800; font-size: 17px;
  font-family: 'Inter', system-ui, sans-serif;
}
.mfb-help-teks { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.mfb-help-teks b { font-size: 14px; font-weight: 700; }
.mfb-help-teks span { font-size: 12.5px; color: var(--gray-500, #5C5A56); line-height: 1.4; }
.mfb-help-panah { flex: 0 0 auto; font-size: 22px; color: #8A6A1F; line-height: 1; }
body.dark-mode .mfb-help { background: #1E1E1E; border-color: rgba(232, 201, 106, 0.35); color: #F0F0F0; }
body.dark-mode .mfb-help-teks span { color: #BDBDBD; }
body.dark-mode .mfb-help-panah { color: #E8C96A; }
@media (prefers-reduced-motion: reduce) { .mfb-help { transition: none; } }

/* ================================================================
   53. MANAGE COURSES DI HP — MODAL YANG TIDAK PERNAH TERLIHAT
       (v1.72, rilis 2.208 — MoM #4)
   ================================================================
   Semua modal pengelolaan (Create/Edit Course, Assign, Modules,
   konfirmasi Publish, Users, Import) tinggal di dalam #desk, dan
   #desk disembunyikan (display:none) di bawah 900 px. Akibatnya di HP
   modal itu dibuka tapi ukurannya 0x0 — tombol "Create New Course"
   baseline v2.144 di HP tidak pernah melakukan apa pun (diukur di
   Chrome 390 px, 24 Sep 2026).

   Modal TIDAK dipindahkan (gaya "#desk ..." dan urutan DOM tetap).
   Selama ada modal terbuka, #desk dihidupkan sebagai kotak 0 px yang
   tak terlihat; hanya modalnya (position:fixed, lepas dari overflow)
   yang dibuat terlihat. Desktop tidak tersentuh (hanya < 900 px).
   :has() — Chrome 105+/Safari 15.4+; peramban lebih tua tetap seperti
   sebelumnya (modal tidak terlihat), tidak lebih buruk. */
@media (max-width: 899px) {
  #desk:has(.modal-overlay.show) {
    display: block; height: 0; min-height: 0; overflow: hidden; visibility: hidden;
  }
  #desk .modal-overlay.show { visibility: visible; }
}

/* Tombol aksi di kartu Manage Courses HP (mfb-ui.js 5zb). */
.mfb-kh { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; }
.mfb-kh-btn {
  min-height: 44px; padding: 0 16px; border-radius: 10px; cursor: pointer;
  font: 700 13px 'Inter', system-ui, sans-serif;
  border: 1.5px solid var(--gold, #C9A84C); background: var(--gold, #C9A84C); color: #0A0A0A;
  display: inline-flex; align-items: center; gap: 6px;
}
.mfb-kh-btn:focus-visible { outline: 3px solid #0A0A0A; outline-offset: 2px; }
.mfb-kh-catatan { font-size: 11.5px; color: var(--gray-500, #5C5A56); line-height: 1.4; }
body.dark-mode .mfb-kh-btn:focus-visible { outline-color: #F0F0F0; }
body.dark-mode .mfb-kh-catatan { color: #BDBDBD; }

/* (31) v1.123 (rilis 2.256, D89) — kelola course dari HP.
   Tombol kedua (Edit, Modules) di kartu HP: sekunder, putih bergaris emas, 44 px. */
.mfb-kh-btn2 {
  min-height: 44px; padding: 0 14px; border-radius: 10px; cursor: pointer;
  font: 700 13px 'Inter', system-ui, sans-serif;
  border: 1.5px solid var(--gold, #C9A84C); background: #FFFFFF; color: #0A0A0A;
  display: inline-flex; align-items: center; gap: 6px;
}
.mfb-kh-btn2:focus-visible { outline: 3px solid #0A0A0A; outline-offset: 2px; }
body.dark-mode .mfb-kh-btn2 { background: #1A1C24; color: #F0F0F0; border-color: #D4AF37; }
body.dark-mode .mfb-kh-btn2:focus-visible { outline-color: #F0F0F0; }
/* Baris daftar modul baseline (style inline 28 px, huruf 12 px) di HP: judul memakai baris
   pertama, tombol turun ke baris kedua; semua target 44 px; kotak nomor 16 px supaya
   iPhone tidak memperbesar halaman saat diketuk. !important = menimpa style inline. */
@media (max-width: 899px) {
  #d-moduleList > div { flex-wrap: wrap !important; row-gap: 8px !important; }
  #d-moduleList > div > div { flex: 1 1 55% !important; }
  #d-moduleList > div > div > div:first-child { white-space: normal !important; }
  #d-moduleList > div > button { height: 44px !important; padding: 0 14px !important; font-size: 13px !important; flex: 1 1 auto !important; }
  #d-moduleList input[data-module-id] { width: 56px !important; height: 44px !important; font-size: 16px !important; }
  #d-modulesModal button[onclick="sortModules()"],
  #d-addModuleForm button { height: 44px !important; }
}

/* ================================================================
   54. MODE GELAP DI HP — KARTU PERAK & TEKS HITAM
       (v1.73, rilis 2.208 — disetujui IT 24 Sep 2026)
   ================================================================
   Bagian 1b, 1d, dan 1e memasang gradien PUTIH (0,95) di atas kartu HP
   tanpa pasangan mode gelap. Warna dasar kartunya memang ikut gelap
   (--white = #1E1E1E), tapi gradien menutupinya — kartu jadi perak
   dan teks terangnya 1,03 : 1 (diukur Chrome 390, semua halaman #mob).
   Gradien dan bayangan di sini meniru kartu desktop gelap v2.117.

   Teks tanpa warna sendiri (judul course di Active Courses, "Learning
   Streak", tombol Reset/Nonaktifkan di Users) mewarisi hitam bawaan
   peramban: 1,26 : 1 di atas #1E1E1E. Hanya mode gelap yang disentuh. */
body.dark-mode #mob .stat-chip,
body.dark-mode #mob .stat-chip-m,
body.dark-mode #mob .att-stat-chip,
body.dark-mode #mob .team-item-m,
body.dark-mode #mob .log-item-m,
body.dark-mode #mob .settings-item-m,
body.dark-mode #mob .att-event-card,
body.dark-mode #mob .course-card-adm,
body.dark-mode #mob .course-card {
  background-image: linear-gradient(180deg,
    rgba(255, 255, 255, 0.05) 0%, rgba(255, 255, 255, 0.015) 100%);
  border-color: var(--gray-100);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 2px 10px rgba(0, 0, 0, 0.35);
}
body.dark-mode #mob .scroll-content > div > button[onclick^="goTo"] {
  background-image: linear-gradient(180deg,
    rgba(255, 255, 255, 0.05) 0%, rgba(255, 255, 255, 0.015) 100%) !important;
  border-color: var(--gray-100) !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 2px 10px rgba(0, 0, 0, 0.35);
}
body.dark-mode #mob .team-item-m:active,
body.dark-mode #mob .att-event-card:active,
body.dark-mode #mob .course-card-adm:active,
body.dark-mode #mob .course-card:active,
body.dark-mode #mob .scroll-content > div > button[onclick^="goTo"]:active {
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.45);
}
body.dark-mode #mob { color: var(--black); }
body.dark-mode #mob button:not([class])[style*="background:var(--white)"] { color: var(--black); }

/* Isian di jendela pengelolaan yang kini terbuka di HP (bagian 53):
   iOS Safari memperbesar layar setiap kali isian di bawah 16 px
   disentuh, dan tidak mengecil lagi sendiri. Desktop tidak tersentuh.
   Baris dua kolom (.m-row) dibuat satu kolom: di 390 px kolom kanannya
   (Passing Score, Has Certificate) sudah terpotong sejak baseline, dan
   huruf 16 px membuatnya hilang sama sekali. */
@media (max-width: 899px) {
  #desk .modal-overlay.show input:not([type="checkbox"]):not([type="radio"]),
  #desk .modal-overlay.show select,
  #desk .modal-overlay.show textarea { font-size: 16px; }
  #desk .modal-overlay.show .m-row { grid-template-columns: minmax(0, 1fr); }
  #desk .modal-overlay.show select { max-width: 100%; }
}

/* ================================================================
   55. HP: KONTRAS SISA & SASARAN SENTUH 44 PX
       (v1.74, rilis 2.209 — disetujui IT 24 Sep 2026)
   ================================================================
   Sisa temuan tinjauan HP sesudah §54, diukur di Chrome 390
   (scratchpad/pw/audit-hp.mjs). Semuanya cacat baseline; hanya #mob
   yang disentuh, warna diambil dari token yang sudah ada (--gold-text,
   hijau/amber/merah §50). Desktop tidak berubah.

   a. Latar emas + color:var(--black). Di mode gelap --black = #F0F0F0,
      jadi teksnya terang di atas emas: 2,12 : 1. Dibuat gelap seperti
      mode terang (#0A0A0A di atas emas ≈ 9 : 1). */
body.dark-mode #mob .btn-cc-resume,
body.dark-mode #mob .cb-required,
body.dark-mode #mob .cim-badge,
body.dark-mode #mob .ph-avatar { color: #0A0A0A; }
body.dark-mode #mob button[style*="background:var(--gold)"] { color: #0A0A0A !important; }
body.dark-mode #mob .mb-active { color: #E8C96A; }            /* 2,66 : 1 */
body.dark-mode #mob .scm-num[style*="--blue"] { color: #60A5FA !important; }  /* 2,81 : 1 */

/* b. Emas hiasan #C9A065 sebagai TEKS di kartu putih: 2,41 : 1. */
body:not(.dark-mode) #mob .cc-dept,
body:not(.dark-mode) #mob .cc-pct,
body:not(.dark-mode) #mob .pci-pct,
body:not(.dark-mode) #mob .cim-score,
body:not(.dark-mode) #mob .dept-pct { color: var(--gold-text, #8A6A1F); }
body:not(.dark-mode) #mob span[style*="font-weight:700;color:var(--gold)"] { color: var(--gold-text, #8A6A1F) !important; }
/* …kecuali di panel gelap (hero Course Detail): di sana emas terang yang benar. */
body:not(.dark-mode) #mob [style*="background:var(--solid-dark)"] span[style*="font-weight:700;color:var(--gold)"] { color: var(--gold) !important; }

/* c. Angka & status berwarna di kartu terang (1,88–2,24 : 1) — nilai sama
      dengan desktop §50f. */
body:not(.dark-mode) #mob .scm-num[style*="--green"],
body:not(.dark-mode) #mob .team-item-m > span[style*="color:var(--green)"] { color: #047857 !important; }
body:not(.dark-mode) #mob .scm-num[style*="--amber"] { color: #B45309 !important; }
#mob .mb-done,
#mob .lf-normal { color: #047857; }                            /* 3,97 : 1 */
#mob .tmb-bad { color: #B91C1C; }                               /* 4,15 : 1 */
#mob .mfb-corong-2 { color: #1A1206; }                          /* putih di emas 2,26 : 1 */
/* Tahap 3–4 hijau: putih 3,33 / 4,37 : 1. Hijaunya digelapkan secukupnya
   (≥ 4,7 : 1) — urutan terang→pekat tahap 1–4 tetap. */
#mob .mfb-corong-3 { background-image: linear-gradient(135deg, #1E844A 0%, #1A7A42 100%); }
#mob .mfb-corong-4 { background-image: linear-gradient(135deg, #17703D 0%, #0C5A2E 100%); }

/* d. Teks putih tipis di panel gelap (hero, ringkasan Progress/Profile):
      0,35–0,5 → 0,62–0,7 (3,1–4,2 : 1 → di atas 4,5). */
#mob .dash-date,
#mob .dash-role-tag,
#mob .psm-label,
#mob .ph-stat-label { color: rgba(255, 255, 255, 0.62); }
html body.dark-mode #mob .ph-stat-label { color: rgba(240, 240, 240, 0.7) !important; }

/* e. Sasaran sentuh 44 px. Yang bentuknya tidak boleh berubah (avatar,
      saklar) diperluas daerah sentuhnya dengan ::after tak terlihat;
      tombol biasa cukup min-height (menang atas height sebaris). */
#mob .it-avatar { position: relative; }
#mob .it-avatar::after { content: ''; position: absolute; inset: -5px; border-radius: 50%; }
#mob .sim-toggle::after { content: ''; position: absolute; inset: -11px -4px; }
#mob .pill-m,
#mob .btn-cc,
#mob #m-users-add-btn,
#mob .team-item-m button,
#mob .it-right > div[onclick]:not(.it-avatar) { min-height: 44px; }
#mob .mfb-cari-bar input { align-self: stretch; }

/* ================================================================
   56. KARTU ANGKA HP YANG TERPOTONG & CORONG DESKTOP
       (v1.75, rilis 2.210 — disetujui IT 25 Sep 2026)
   ================================================================
   a. Baris kartu angka Users / Reports / Attendance di HP adalah baris
      geser dengan bilah gulir DISEMBUNYIKAN; kartu terakhir terpotong di
      tepi kanan tanpa tanda ada lanjutannya (diukur Chrome 390: Trainee,
      Overdue, IV). Dibuat satu baris tanpa geser — aturan yang sama
      dengan kartu dasbor (bagian 1c v1.14, permintaan IT Manager). */
#mob .admin-stat-scroll,
#mob .att-stats-m {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 8px;
  overflow: visible;
}
#mob .admin-stat-scroll > .stat-chip-m,
#mob .att-stats-m > .att-stat-chip { min-width: 0; padding: 10px 6px; }
#mob .admin-stat-scroll .scm-label,
#mob .att-stats-m .asc-label { letter-spacing: 0.04em; overflow-wrap: normal; word-break: keep-all; }

/* b. Corong di dasbor DESKTOP: warna yang sama dengan HP (§55c) — putih
      di emas 2,26 : 1, di hijau 3,33 / 4,37 : 1. */
#desk .mfb-corong-2 { color: #1A1206; }
#desk .mfb-corong-3 { background-image: linear-gradient(135deg, #1E844A 0%, #1A7A42 100%); }
#desk .mfb-corong-4 { background-image: linear-gradient(135deg, #17703D 0%, #0C5A2E 100%); }
/* ================================================================
   57. ATTENDANCE: ADD EVENT & DAFTAR HADIR  (v1.75, rilis 2.210 — MoM #11)
   ================================================================
   Tombol & jendela dari mfb-ui.js bagian 5zc. Jendela berada langsung
   di <body> (bukan di #desk), jadi terlihat di HP tanpa trik §53.
   Semua target sentuh 44 px; isian 16 px (iOS tidak memperbesar). */
.mfb-ev-tambah, .mfb-ev-btn, .mfb-hd-semua, .mfb-hd-manual-buka {
  min-height: 44px; padding: 0 16px; border-radius: 10px; cursor: pointer;
  font: 700 13.5px 'Inter', system-ui, sans-serif;
  border: 1.5px solid var(--gold, #C9A84C); background: transparent; color: var(--black, #0A0A0A);
}
.mfb-ev-tambah, .mfb-ev-btn-ubah { background: var(--gold, #C9A84C); color: #0A0A0A; }
.mfb-ev-tambah:focus-visible, .mfb-ev-btn:focus-visible, .mfb-hd-semua:focus-visible, .mfb-hd-manual-buka:focus-visible { outline: 3px solid #0A0A0A; outline-offset: 2px; }
#desk .mgmt-toolbar .mfb-ev-tambah { margin-left: auto; }
.mfb-ev-aksi { flex: 0 0 auto; display: flex; align-items: center; margin-left: 12px; }
#mob .att-event-card .mfb-ev-aksi { margin: 12px 0 0; }
#mob .att-event-card .mfb-ev-btn { width: 100%; }
.mfb-ev-info { margin: 0 16px 14px; padding: 12px 14px; border-radius: 12px; border: 1px solid var(--gray-100, #EFEFED);
  background: var(--white, #FFFFFF); display: flex; flex-direction: column; gap: 10px; }
.mfb-ev-info p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--gray-500, #5C5A56); }
.mfb-ev-info .mfb-ev-tambah { width: 100%; }

.mfb-dlg-tirai { position: fixed; inset: 0; z-index: 10050; background: rgba(8, 8, 10, .55);
  display: flex; align-items: center; justify-content: center; padding: 16px; }
.mfb-dlg { width: 100%; max-width: 560px; max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); overflow: auto;
  background: var(--white, #FFFFFF); color: var(--black, #0A0A0A); border-radius: 16px; padding: 20px 22px 18px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .35); overscroll-behavior: contain; }
.mfb-dlg-lebar { max-width: 720px; }
.mfb-dlg-kepala { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.mfb-dlg-kepala h2 { margin: 0; font: 700 20px Georgia, serif; }
.mfb-dlg-x { min-width: 44px; min-height: 44px; border-radius: 50%; border: 1px solid var(--gray-200, #E7E3DB);
  background: transparent; color: inherit; font-size: 22px; line-height: 1; cursor: pointer; }
.mfb-ev-form { display: flex; flex-direction: column; }
.mfb-ev-lbl { display: block; margin: 12px 0 6px; font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--gray-500, #5C5A56); }
.mfb-ev-form input:not([type="checkbox"]), .mfb-ev-form select, .mfb-ev-form textarea, .mfb-hd-cari {
  width: 100%; min-height: 44px; padding: 10px 12px; border-radius: 10px; border: 1.5px solid var(--gray-200, #E7E3DB);
  background: var(--gray-50, #FAFAF8); color: var(--black, #0A0A0A); font: 16px 'Inter', system-ui, sans-serif; }
.mfb-ev-form textarea { resize: vertical; }
.mfb-ev-dua { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0 12px; }
.mfb-ev-tiga { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr); gap: 0 12px; }
.mfb-ev-tetap { margin: 0; min-height: 44px; display: flex; align-items: center; font-weight: 600; }
.mfb-ev-cek { display: flex; align-items: center; gap: 10px; min-height: 44px; margin-top: 10px; font-size: 14.5px; cursor: pointer; }
.mfb-ev-cek input { width: 20px; height: 20px; accent-color: var(--gold, #C9A84C); }
.mfb-ev-catat { margin: 2px 0 0; font-size: 12.5px; color: var(--gray-500, #5C5A56); }
.mfb-ev-galat { margin: 10px 0 0; min-height: 1em; font-size: 14px; font-weight: 600; color: #B91C1C; }
.mfb-ev-galat:empty { min-height: 0; margin: 0; }
.mfb-ev-kaki { display: flex; justify-content: flex-end; gap: 10px; margin-top: 16px; flex-wrap: wrap; }
.mfb-ev-batal, .mfb-ev-simpan { min-height: 44px; padding: 0 18px; border-radius: 10px; cursor: pointer; font: 700 14px 'Inter', system-ui, sans-serif; }
.mfb-ev-batal { background: transparent; color: inherit; border: 1.5px solid var(--gray-200, #E7E3DB); }
.mfb-ev-simpan { background: #0A0A0A; color: #FFFFFF; border: 1.5px solid #0A0A0A; }
.mfb-ev-simpan:disabled { opacity: .45; cursor: not-allowed; }
.mfb-dlg :focus-visible { outline: 3px solid var(--gold, #C9A84C); outline-offset: 2px; }

.mfb-hd-kepala { padding-bottom: 10px; border-bottom: 1px solid var(--gray-100, #EFEFED); }
.mfb-hd-nama { margin: 0; font-size: 16px; font-weight: 700; }
.mfb-hd-info, .mfb-hd-hitung { margin: 4px 0 0; font-size: 13px; color: var(--gray-500, #5C5A56); }
.mfb-hd-hitung { font-weight: 600; color: inherit; }
.mfb-hd-alat { margin-top: 12px; }
.mfb-hd-daftar { list-style: none; margin: 10px 0 0; padding: 0; }
.mfb-hd-baris { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 0;
  border-bottom: 1px solid var(--gray-100, #EFEFED); }
.mfb-hd-org { min-width: 0; display: flex; flex-direction: column; font-weight: 600; font-size: 14.5px; overflow-wrap: anywhere; }
.mfb-hd-dept { font-weight: 400; font-size: 12.5px; color: var(--gray-500, #5C5A56); }
.mfb-hd-baris select { flex: 0 0 150px; min-height: 44px; padding: 0 10px; border-radius: 10px; border: 1.5px solid var(--gray-200, #E7E3DB);
  background: var(--gray-50, #FAFAF8); color: var(--black, #0A0A0A); font: 16px 'Inter', system-ui, sans-serif; }
.mfb-hd-st { flex: 0 0 auto; font-size: 13px; font-weight: 700; padding: 4px 10px; border-radius: 999px; background: var(--gray-50, #FAFAF8); }
.mfb-hd-st-present { color: #047857; } .mfb-hd-st-absent { color: #B91C1C; } .mfb-hd-st-late { color: #B45309; }
.mfb-hd-muat, .mfb-hd-kosong { margin: 12px 0; color: var(--gray-500, #5C5A56); }

@media (max-width: 560px) {
  .mfb-dlg-tirai { align-items: flex-end; padding: 0; }
  .mfb-dlg, .mfb-dlg-lebar { max-width: none; border-radius: 16px 16px 0 0; max-height: 92vh; max-height: 92dvh;
    padding-bottom: calc(18px + env(safe-area-inset-bottom, 0px)); }
  .mfb-ev-dua, .mfb-ev-tiga { grid-template-columns: minmax(0, 1fr); }
  .mfb-hd-baris select { flex-basis: 132px; }
}

body.dark-mode .mfb-ev-btn:not(.mfb-ev-btn-ubah), body.dark-mode .mfb-hd-semua, body.dark-mode .mfb-hd-manual-buka { color: #F0F0F0; }
body.dark-mode .mfb-ev-tambah:focus-visible, body.dark-mode .mfb-ev-btn:focus-visible { outline-color: #F0F0F0; }
body.dark-mode .mfb-dlg { background: #1E1E1E; color: #F0F0F0; }
body.dark-mode .mfb-ev-lbl, body.dark-mode .mfb-ev-catat, body.dark-mode .mfb-hd-info, body.dark-mode .mfb-hd-dept,
body.dark-mode .mfb-hd-muat, body.dark-mode .mfb-hd-kosong, body.dark-mode .mfb-ev-info p { color: #BDBDBD; }
body.dark-mode .mfb-ev-form input:not([type="checkbox"]), body.dark-mode .mfb-ev-form select, body.dark-mode .mfb-ev-form textarea,
body.dark-mode .mfb-hd-cari, body.dark-mode .mfb-hd-baris select { background: #262626; color: #F0F0F0; border-color: #3A3A3A; }
body.dark-mode .mfb-ev-simpan { background: #E8C96A; color: #0A0A0A; border-color: #E8C96A; }
body.dark-mode .mfb-ev-galat { color: #FCA5A5; }
body.dark-mode .mfb-hd-st { background: #262626; }
body.dark-mode .mfb-hd-st-present { color: #6EE7B7; } body.dark-mode .mfb-hd-st-absent { color: #FCA5A5; }
body.dark-mode .mfb-hd-st-late { color: #FCD34D; }
body.dark-mode .mfb-ev-info { background: #1E1E1E; border-color: #2E2E2E; }
/* ================================================================
   58. CEK HoD — "FLOOR CHECKS"  (v1.80, rilis 2.215)
   ================================================================
   Tombol & jendela dari mfb-ui.js bagian 5zi. Jendela, label, galat, dan
   tombol kaki memakai ulang §57 (.mfb-dlg, .mfb-ev-lbl, .mfb-ev-galat,
   .mfb-ev-kaki, .mfb-hd-*); di bawah ini hanya bagian yang baru.
   Tombol pembukanya SEKUNDER (garis emas): di bilah alat yang sama, aksi
   utamanya tetap "+ Add Event". Semua target sentuh 44 px; isian 16 px. */
.mfb-hc-buka {
  min-height: 44px; padding: 0 16px; border-radius: 10px; cursor: pointer;
  font: 700 13.5px 'Inter', system-ui, sans-serif;
  border: 1.5px solid var(--gold, #C9A84C); background: transparent; color: var(--black, #0A0A0A);
}
.mfb-hc-buka:focus-visible { outline: 3px solid #0A0A0A; outline-offset: 2px; }
#desk .mgmt-toolbar > .mfb-hc-buka { margin-left: auto; }
#desk .mgmt-toolbar > .mfb-ev-tambah + .mfb-hc-buka { margin-left: 10px; }
.mfb-ev-info .mfb-hc-buka { width: 100%; }

.mfb-hc-intro { margin: 0 0 6px; font-size: 14px; line-height: 1.5; }
.mfb-hc-daftar { list-style: none; margin: 10px 0 0; padding: 0; }
.mfb-hc-baris { padding: 12px 0; border-bottom: 1px solid var(--gray-100, #EFEFED); }
.mfb-hc-baris[hidden], .mfb-hc-isi[hidden], .mfb-hc-set[hidden] { display: none; }
.mfb-hc-atas { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.mfb-hc-st { flex: 0 0 auto; font-size: 13px; font-weight: 700; padding: 4px 10px; border-radius: 999px;
  background: var(--gray-50, #FAFAF8); white-space: nowrap; }
.mfb-hc-st-waiting { color: #B45309; } .mfb-hc-st-not_yet { color: #5C5A56; } .mfb-hc-st-yes { color: #047857; }
.mfb-hc-course, .mfb-hc-oleh { margin: 4px 0 0; font-size: 13px; color: var(--gray-500, #5C5A56); overflow-wrap: anywhere; }
.mfb-hc-catatan { margin: 6px 0 0; font-size: 13.5px; font-style: italic; overflow-wrap: anywhere; }
.mfb-hc-isi { margin-top: 10px; min-height: 44px; padding: 0 18px; border-radius: 10px; cursor: pointer;
  font: 700 13.5px 'Inter', system-ui, sans-serif; border: 1.5px solid var(--gold, #C9A84C);
  background: var(--gold, #C9A84C); color: #0A0A0A; }
.mfb-hc-form { margin-top: 10px; padding: 12px 14px 14px; border-radius: 12px;
  background: var(--gray-50, #FAFAF8); border: 1px solid var(--gray-100, #EFEFED); }
.mfb-hc-set { border: 0; margin: 0; padding: 0; min-width: 0; }
.mfb-hc-set .mfb-ev-lbl { padding: 0; }
.mfb-hc-pilih, .mfb-hc-skala { display: flex; gap: 8px; flex-wrap: wrap; }
/* Radio asli tetap ada (dibaca pembaca layar, bisa dipilih dengan panah);
   yang terlihat adalah kotak 44 px di sebelahnya. */
.mfb-hc-opsi, .mfb-hc-angka { position: relative; }
.mfb-hc-opsi input, .mfb-hc-angka input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; }
.mfb-hc-opsi span, .mfb-hc-angka span { display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; min-width: 44px; padding: 0 18px; border-radius: 10px; border: 1.5px solid var(--gray-200, #E7E3DB);
  background: var(--white, #FFFFFF); color: var(--black, #0A0A0A); font: 700 14px 'Inter', system-ui, sans-serif; cursor: pointer; }
.mfb-hc-angka span { padding: 0; }
.mfb-hc-opsi input:checked + span, .mfb-hc-angka input:checked + span { background: #0A0A0A; color: #FFFFFF; border-color: #0A0A0A; }
.mfb-hc-opsi input:focus-visible + span, .mfb-hc-angka input:focus-visible + span { outline: 3px solid var(--gold, #C9A84C); outline-offset: 2px; }
.mfb-hc-form textarea { width: 100%; min-height: 44px; padding: 10px 12px; border-radius: 10px; border: 1.5px solid var(--gray-200, #E7E3DB);
  background: var(--white, #FFFFFF); color: var(--black, #0A0A0A); font: 16px 'Inter', system-ui, sans-serif; resize: vertical; box-sizing: border-box; }

body.dark-mode .mfb-hc-buka { color: #F0F0F0; }
body.dark-mode .mfb-hc-buka:focus-visible { outline-color: #F0F0F0; }
body.dark-mode .mfb-hc-course, body.dark-mode .mfb-hc-oleh { color: #BDBDBD; }
body.dark-mode .mfb-hc-baris { border-color: #2E2E2E; }
body.dark-mode .mfb-hc-st { background: #262626; }
body.dark-mode .mfb-hc-st-waiting { color: #FCD34D; } body.dark-mode .mfb-hc-st-not_yet { color: #D4D4D4; }
body.dark-mode .mfb-hc-st-yes { color: #6EE7B7; }
body.dark-mode .mfb-hc-form { background: #1A1A1A; border-color: #2E2E2E; }
body.dark-mode .mfb-hc-opsi span, body.dark-mode .mfb-hc-angka span,
body.dark-mode .mfb-hc-form textarea { background: #262626; color: #F0F0F0; border-color: #3A3A3A; }
body.dark-mode .mfb-hc-opsi input:checked + span, body.dark-mode .mfb-hc-angka input:checked + span { background: #E8C96A; color: #0A0A0A; border-color: #E8C96A; }
/* ================================================================
   v1.78 (rilis 2.213) — ucapan di popup Quiz Passed & modal caption WA
   ================================================================ */
.mfb-ucapan { margin: 2px 0 14px; }
.mfb-ucapan-nama { font-family: Georgia, serif; font-size: 18px; font-weight: 700; color: var(--black, #0A0A0A); }
.mfb-ucapan-isi { font-size: 13.5px; color: var(--gray-600, #525252); margin-top: 4px; line-height: 1.45; }
body.dark-mode .mfb-ucapan-nama { color: #F0F0F0; }
body.dark-mode .mfb-ucapan-isi { color: #BDBDBD; }

.mfb-cap-tirai { position: fixed; inset: 0; z-index: 9000; background: rgba(0, 0, 0, .55); display: flex; align-items: flex-start; justify-content: center; padding: 24px 16px; overflow-y: auto; }
.mfb-cap-kotak { background: #FFFFFF; color: #0A0A0A; border-radius: 16px; width: min(1180px, 100%); box-shadow: 0 24px 64px rgba(0, 0, 0, .25); }
.mfb-cap-kepala { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 20px; background: #1B1712; color: #FFFFFF; border-radius: 16px 16px 0 0; }
.mfb-cap-kepala h2 { margin: 0; font-size: 17px; }
.mfb-cap-tutup { min-width: 44px; min-height: 44px; border-radius: 10px; border: 1px solid rgba(232, 201, 106, .5); background: transparent; color: #FFFFFF; font-weight: 700; cursor: pointer; }
.mfb-cap-badan { padding: 18px 20px 22px; display: grid; gap: 12px; }
.mfb-cap-set { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); gap: 12px; }
.mfb-cap-badan label { display: flex; flex-direction: column; gap: 6px; font-size: 12.5px; font-weight: 700; color: #525252; }
.mfb-cap-badan input, .mfb-cap-badan textarea { font: 15px Inter, sans-serif; color: #0A0A0A; background: #FAFAF7; border: 1.5px solid #E5E0D5; border-radius: 10px; padding: 10px 12px; min-height: 44px; width: 100%; box-sizing: border-box; }
.mfb-cap-badan textarea { font-family: Consolas, 'Cascadia Code', monospace; resize: vertical; }
.mfb-cap-btn { min-height: 44px; padding: 0 16px; border-radius: 10px; border: 1.5px solid #D6CFBF; background: #FFFFFF; color: #0A0A0A; font: 700 14px Inter, sans-serif; cursor: pointer; }
.mfb-cap-utama { background: #C9A865; border-color: #C9A865; color: #0A0A0A; justify-self: start; }
.mfb-cap-btn:disabled { opacity: .5; cursor: wait; }
.mfb-cap-btn:focus-visible, .mfb-cap-tutup:focus-visible { outline: 3px solid #8A6A1F; outline-offset: 2px; }
.mfb-cap-kabar { font-size: 13.5px; color: #15803D; margin: 0; min-height: 18px; }
.mfb-cap-salah { color: #B91C1C; }
.mfb-cap-kisi { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(min(100%, 270px), 1fr)); }
.mfb-cap-kartu { border: 1px solid #E5E0D5; border-radius: 12px; padding: 12px; display: flex; flex-direction: column; gap: 10px; background: #FAFAF7; min-width: 0; }
.mfb-cap-kosong { background: #FEF3C7; border-color: #F59E0B; }
.mfb-cap-judul { font-weight: 700; font-size: 14px; }
.mfb-cap-no { color: #8A6A1F; margin-right: 6px; }
.mfb-cap-teks { margin: 0; flex: 1; white-space: pre-wrap; word-break: break-word; font: 12.5px/1.55 Consolas, 'Cascadia Code', monospace; background: #FFFFFF; border: 1px solid #E5E0D5; border-radius: 10px; padding: 10px; }
.mfb-cap-catatan { margin: 0; font-size: 13.5px; color: #92400E; }
.mfb-cap-aksi { display: flex; gap: 8px; flex-wrap: wrap; }
.mfb-cap-aksi .mfb-cap-btn { flex: 1 1 auto; }
body.dark-mode .mfb-cap-kotak { background: #1E1E1E; color: #F0F0F0; }
body.dark-mode .mfb-cap-badan label { color: #BDBDBD; }
body.dark-mode .mfb-cap-badan input, body.dark-mode .mfb-cap-badan textarea, body.dark-mode .mfb-cap-teks { background: #262626; color: #F0F0F0; border-color: #3A3A3A; }
body.dark-mode .mfb-cap-kartu { background: #1A1A1A; border-color: #2E2E2E; }
body.dark-mode .mfb-cap-kosong { background: #3A2E12; border-color: #92400E; }
body.dark-mode .mfb-cap-catatan { color: #FCD34D; }
body.dark-mode .mfb-cap-btn { background: #262626; color: #F0F0F0; border-color: #3A3A3A; }
body.dark-mode .mfb-cap-utama { background: #E8C96A; color: #0A0A0A; border-color: #E8C96A; }
body.dark-mode .mfb-cap-kabar { color: #6EE7B7; } body.dark-mode .mfb-cap-salah { color: #FCA5A5; }
/* ================================================================
   59. PINTU ATTENDANCE DI HP & RAPI FLOOR CHECKS 320 PX  (v1.81, rilis 2.216)
   ----------------------------------------------------------------
   · Kartu "Attendance" di Dashboard HP HoD/GM/Owner memakai gaya kartu
     My Training (§2b); satu tombol mengisi selebar kartu.
   · "How well?" adalah <legend>: margin legend yang tampil tidak memberi
     jarak seperti label biasa, jadi jaraknya diberikan ke fieldset-nya.
   · Di ponsel 320 px angka 1–5 terlipat 4 + 1 (5 × 44 px + 4 celah 8 px
     > lebar isi). Di bawah 360 px celah & bantalan form dirapatkan dan
     kelima kotak berbagi lebar rata — tiap kotak tetap minimal 44 px.
   ================================================================ */
.mfb-kelola-card .mfb-training-links { grid-template-columns: 1fr; }
.mfb-hc-set-nilai { margin-top: 12px; }
@media (max-width: 360px) {
  .mfb-hc-form { padding-left: 10px; padding-right: 10px; }
  .mfb-hc-skala { gap: 6px; flex-wrap: nowrap; }
  .mfb-hc-skala .mfb-hc-angka { flex: 1 1 0; }
  .mfb-hc-skala .mfb-hc-angka span { width: 100%; box-sizing: border-box; }
}

/* ================================================================
   60. QR CHECK-IN  (v1.82, rilis 2.217)
   ----------------------------------------------------------------
   · Tombol "QR check-in" di Attendance (tautan ke /qr-absen, tab baru) —
     tampilannya sama dengan tombol Floor checks, kelasnya sendiri karena
     #desk .mgmt-toolbar > .mfb-hc-buka memakai margin-left: auto.
   · Keterangan asal catatan QR di Record attendance: jam WITA + jaringan.
   ================================================================ */
.mfb-qr-buka { display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px; border-radius: 10px;
  font: 700 13.5px 'Inter', system-ui, sans-serif; border: 1.5px solid var(--gold, #C9A84C); background: transparent;
  color: var(--black, #0A0A0A); text-decoration: none; margin-left: 8px; }
.mfb-qr-buka:focus-visible { outline: 3px solid #0A0A0A; outline-offset: 2px; }
body.dark-mode .mfb-qr-buka { color: #F0F0F0; }
body.dark-mode .mfb-qr-buka:focus-visible { outline-color: #F0F0F0; }
.mfb-hd-via { display: block; font-weight: 500; font-size: 12px; color: #8A6A1F; overflow-wrap: anywhere; }
body.dark-mode .mfb-hd-via { color: #E3C26B; }

/* ================================================================
   §61 (v1.83, rilis 2.218) — EKSPOR ABSENSI KE EXCEL
   ----------------------------------------------------------------
   · Tombol "Export Excel" di Attendance, di kanan "QR check-in".
     Tampilannya sama dengan tombol QR; kelasnya sendiri karena uji
     menghitung .mfb-qr-buka. Ini <button>, jadi kursor ditulis.
   · Dialognya memakai gaya form Add Event (.mfb-ev-*), tanpa aturan baru.
   ================================================================ */
.mfb-xl-buka { display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px; border-radius: 10px;
  font: 700 13.5px 'Inter', system-ui, sans-serif; border: 1.5px solid var(--gold, #C9A84C); background: transparent;
  color: var(--black, #0A0A0A); margin-left: 8px; cursor: pointer; }
.mfb-xl-buka:focus-visible { outline: 3px solid #0A0A0A; outline-offset: 2px; }
body.dark-mode .mfb-xl-buka { color: #F0F0F0; }
body.dark-mode .mfb-xl-buka:focus-visible { outline-color: #F0F0F0; }
.mfb-xl-rentang[hidden] { display: none; }

/* ================================================================
   §62 (v1.90, rilis 2.225 — P20) — DAFTAR STAFF KHUSUS ABSENSI
   ----------------------------------------------------------------
   · Tombol "Staff list" di Attendance (IT Admin, HRM), tampilan sama
     dengan Export Excel; kelasnya sendiri karena pasangTombolEkspor
     mencari .mfb-xl-buka — kelas yang sama akan saling menghapus.
   · Label "No LMS account" di daftar hadir.
   ================================================================ */
.mfb-ds-buka { display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px; border-radius: 10px;
  font: 700 13.5px 'Inter', system-ui, sans-serif; border: 1.5px solid var(--gold, #C9A84C); background: transparent;
  color: var(--black, #0A0A0A); margin-left: 8px; cursor: pointer; }
.mfb-ds-buka:focus-visible { outline: 3px solid #0A0A0A; outline-offset: 2px; }
body.dark-mode .mfb-ds-buka { color: #F0F0F0; }
body.dark-mode .mfb-ds-buka:focus-visible { outline-color: #F0F0F0; }
.mfb-ds-simpan { min-height: 44px; padding: 0 16px; border-radius: 10px; font: 700 14px 'Inter', system-ui, sans-serif;
  border: 1.5px solid var(--gold, #C9A84C); background: transparent; color: var(--black, #0A0A0A); cursor: pointer; }
.mfb-ds-simpan:disabled { opacity: .5; cursor: not-allowed; }
body.dark-mode .mfb-ds-simpan { color: #F0F0F0; }
.mfb-ds-kini { margin: 0 0 10px; font-size: 13.5px; font-weight: 600; }
.mfb-ds-hasil:empty { display: none; }
.mfb-ds-angka { margin: 12px 0 0; padding-left: 18px; font-size: 14px; line-height: 1.6; }
.mfb-ds-lewat { margin: 10px 0 4px; font-size: 13.5px; }
.mfb-ds-galat { margin: 0; padding-left: 18px; font-size: 13px; color: #B91C1C; overflow-wrap: anywhere; }
body.dark-mode .mfb-ds-galat { color: #FCA5A5; }
.mfb-ds-bungkus { overflow-x: auto; max-width: 100%; }
.mfb-ds-contoh { width: 100%; border-collapse: collapse; font-size: 13px; }
.mfb-ds-contoh th, .mfb-ds-contoh td { text-align: left; padding: 6px 8px; border-bottom: 1px solid rgba(0, 0, 0, .1); white-space: nowrap; }
body.dark-mode .mfb-ds-contoh th, body.dark-mode .mfb-ds-contoh td { border-bottom-color: rgba(255, 255, 255, .12); }
.mfb-hd-tamu { display: block; font-weight: 600; font-size: 12px; color: #8A6A1F; }
body.dark-mode .mfb-hd-tamu { color: #E3C26B; }

/* ================================================================
   §63 (v1.93 rilis 2.228 · DIRANCANG ULANG v1.95 rilis 2.230) — FOTO PROFIL
   ----------------------------------------------------------------
   · .mfb-foto-ada: avatar berfoto (gaya utamanya inline !important dari
     mfb-ui.js 5zm — mode gelap memasang background !important pada avatar HP).
   · v1.95 (IT Manager 29 Sep): foto besar (desktop 112 px, HP 92 px) bercincin
     emas; lencana kamera di pojok membuka menu Upload/Take/Remove; foto diklik →
     tampil besar (.mfb-foto-besar). Avatar diberi font-size 0 inline saat berfoto,
     jadi SEMUA isi sisipan menetapkan ukuran hurufnya sendiri.
   · Tombol di jendela kamera tetap .mfb-foto-tombol / .mfb-foto-sekunder.
   ================================================================ */
.mfb-foto-ada { background-size: cover !important; background-position: center !important;
  background-repeat: no-repeat !important; color: transparent !important; text-shadow: none !important; }
#desk .profile-avatar-wrap { margin-top: -56px; }
#desk .profile-avatar { width: 112px; height: 112px; font-size: 34px; border: 4px solid #FFFFFF;
  box-shadow: 0 0 0 2px rgba(201, 168, 76, 0.85), 0 8px 24px rgba(10, 10, 10, 0.18); }
#mob .ph-avatar { width: 92px; height: 92px; font-size: 28px; border: 3px solid #FFFFFF;
  box-shadow: 0 0 0 2px rgba(201, 168, 76, 0.85), 0 6px 18px rgba(0, 0, 0, 0.35); }
body.dark-mode #desk .profile-avatar { border-color: #1A1A1A; }
.mfb-foto-avatar { position: relative; overflow: visible; }
.mfb-foto-avatar.mfb-foto-ada { cursor: zoom-in; }
.mfb-foto-avatar:focus-visible { outline: 3px solid #C9A84C; outline-offset: 3px; }
.mfb-foto-lencana { position: absolute; right: -4px; bottom: -4px; width: 36px; height: 36px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; padding: 0; cursor: pointer;
  background: #0A0A0A; color: #E3C26B; border: 2px solid #FFFFFF; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); z-index: 2; }
.mfb-foto-lencana::after { content: ''; position: absolute; inset: -5px; border-radius: 50%; }   /* target sentuh 46 px */
.mfb-foto-lencana:hover { background: #1F1F1F; }
.mfb-foto-lencana:focus-visible { outline: 3px solid #C9A84C; outline-offset: 2px; }
.mfb-foto-lencana.mfb-sibuk svg { animation: mfb-foto-putar 1s linear infinite; }
@keyframes mfb-foto-putar { to { transform: rotate(360deg); } }
.mfb-foto-menu { position: absolute; top: calc(100% + 12px); left: 50%; transform: translateX(-50%); z-index: 20;
  min-width: 210px; padding: 6px; border-radius: 12px; background: #FFFFFF; color: #0A0A0A;
  border: 1px solid rgba(201, 168, 76, 0.45); box-shadow: 0 12px 32px rgba(10, 10, 10, 0.18);
  font: 400 14px 'Inter', system-ui, sans-serif; text-align: left; }
.mfb-foto-menu[hidden] { display: none; }
.mfb-foto-menu-hp { left: 0; transform: none; }
/* v1.127 (rilis 2.258 — HRM 6 Okt, video: "folder pilih foto tidak mau kebuka", tanpa pesan). Baseline memberi
   .ph-top z-index:1 → menu (z 20) terkurung di lapisan itu, dan nama/jabatan (.ph-role, juga z 1, datang
   sesudahnya) berada DI ATAS menu: krem di atas putih jadi tak terlihat, tapi menangkap ketukan "Upload photo".
   Terukur di Chrome 390: elementFromPoint di tengah tombol = .ph-role. Lapisan foto naik HANYA selama menu terbuka. */
#mob .ph-top:has(.mfb-foto-menu:not([hidden])) { z-index: 30; }   /* #mob: aturan baseline ber-ID */
.mfb-foto-item { display: block; width: 100%; min-height: 44px; padding: 0 12px; border: 0; border-radius: 8px;
  background: transparent; color: #0A0A0A; font: 600 14px 'Inter', system-ui, sans-serif; text-align: left; cursor: pointer; }
.mfb-foto-item:hover, .mfb-foto-item:focus-visible { background: rgba(201, 168, 76, 0.16); outline: none; }
.mfb-foto-item-hapus { color: #B91C1C; }
.mfb-foto-catatan { margin: 4px 12px 6px; font: 400 12px/1.4 'Inter', system-ui, sans-serif; color: #6B6B6B; }
body.dark-mode .mfb-foto-menu { background: #1A1A1A; color: #F0F0F0; border-color: rgba(201, 168, 76, 0.35); }
body.dark-mode .mfb-foto-item { color: #F0F0F0; }
body.dark-mode .mfb-foto-item-hapus { color: #FCA5A5; }
body.dark-mode .mfb-foto-catatan { color: #A3A3A3; }
.mfb-foto-besar { position: fixed; inset: 0; z-index: 10060; display: flex; align-items: center; justify-content: center;
  padding: 16px; background: rgba(0, 0, 0, 0.82); cursor: zoom-out; }
/* v1.96 (rilis 2.231) — IT Manager 29 Sep: tampilan besar KOTAK supaya foto terlihat utuh; avatar tetap bulat. */
.mfb-foto-besar-img { width: min(86vw, 480px); height: auto; aspect-ratio: 1 / 1; object-fit: cover; border-radius: 16px;
  border: 4px solid #FFFFFF; box-shadow: 0 0 0 3px rgba(201, 168, 76, 0.9), 0 24px 60px rgba(0, 0, 0, 0.5); cursor: default; }
.mfb-foto-besar-tutup { position: absolute; top: 16px; right: 16px; width: 44px; height: 44px; border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, 0.6); background: rgba(0, 0, 0, 0.4); color: #FFFFFF;
  font: 400 26px/1 'Inter', system-ui, sans-serif; cursor: pointer; }
.mfb-foto-besar-tutup:focus-visible { outline: 3px solid #C9A84C; outline-offset: 2px; }
.mfb-foto-tombol { min-height: 44px; padding: 0 16px; border-radius: 999px; cursor: pointer;
  font: 700 13px 'Inter', system-ui, sans-serif; border: 1.5px solid var(--gold, #C9A84C);
  background: var(--gold, #C9A84C); color: #0A0A0A; }
.mfb-foto-sekunder { background: transparent; color: var(--black, #0A0A0A); }
.mfb-foto-tombol:disabled { opacity: .55; cursor: progress; }
.mfb-foto-tombol:focus-visible { outline: 3px solid #0A0A0A; outline-offset: 2px; }
body.dark-mode .mfb-foto-sekunder { color: #F0F0F0; }
.mfb-kamera { position: fixed; inset: 0; z-index: 10050; display: flex; align-items: center; justify-content: center;
  padding: 16px; background: rgba(0, 0, 0, .72); }
.mfb-kamera-kotak { width: min(100%, 400px); background: #FFFFFF; color: #0A0A0A; border-radius: 16px; padding: 16px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, .4); }
.mfb-kamera-video { display: block; width: 100%; aspect-ratio: 1 / 1; object-fit: cover; border-radius: 12px;
  background: #111; transform: scaleX(-1); }
.mfb-kamera-teks { margin: 12px 0; font-size: 13.5px; line-height: 1.45; }
.mfb-kamera-aksi { display: flex; flex-wrap: wrap; gap: 8px; }
body.dark-mode .mfb-kamera-kotak { background: #1A1A1A; color: #F0F0F0; }
@media (prefers-reduced-motion: reduce) { .mfb-foto-lencana.mfb-sibuk svg { animation: none; } }
@media print { .mfb-foto-lencana, .mfb-foto-menu, .mfb-foto-besar, .mfb-kamera { display: none !important; } }

/* ================================================================
   §64 (v1.94, rilis 2.229) — NAVBAR BELAJAR (D26) & KOTAK STATISTIK PROFIL (D27)
   ----------------------------------------------------------------
   · D26: judul besar = nama course, judul modul turun jadi baris kecil
     (mfb-ui.js 5zn). Keduanya satu baris, dipotong "…"; teks utuh di title.
     HP: blok tengah topbar diposisikan absolut di tengah (index.html) dan
     lebarnya mengikuti isi — tanpa batas, judul panjang menimpa logo dan
     tombol Back. Batasnya menyisakan ruang keduanya.
   · D27: kotak statistik profil desktop #F7F7F5 di atas kartu putih —
     nyaris tak terlihat. Kini bingkai emas tipis + latar putih.
   ================================================================ */
#desk #d-video-title, #desk #d-pdf-title, #desk #d-quiz-title,
#desk .mfb-judul-modul { max-width: min(42vw, 560px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#desk .mfb-judul-modul { font-size: 12px; font-weight: 600; line-height: 1.3; margin-top: 1px; color: rgba(255, 255, 255, 0.62); }
#mob #m-video .it-center-block, #mob #m-pdf .it-center-block, #mob #m-quiz .it-center-block {
  max-width: calc(100% - 200px); }   /* DIUKUR 390 px: logo 20–89, Back mulai 314 → blok tengah butuh ≥ 97 px dari kedua tepi */
#mob #m-video-eyebrow, #mob #m-pdf-eyebrow, #mob #m-quiz-eyebrow,
#mob #m-video-title, #mob #m-pdf-title, #mob #m-quiz-title {
  display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Nama course (judul besar HP) boleh DUA baris, huruf biasa: dengan gaya judul halaman
   (huruf besar + jarak lebar) di 390 px hanya "KITCHEN FOOD SAF…" yang terbaca. */
#mob #m-video-title, #mob #m-pdf-title, #mob #m-quiz-title {
  white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
  text-transform: none; letter-spacing: 0.01em; font-size: 14px; line-height: 1.2; }
#desk .profile-stat-box { background: #FFFFFF; border: 1px solid rgba(201, 168, 76, 0.45);
  box-shadow: 0 1px 2px rgba(10, 10, 10, 0.06); }
#desk .profile-stat-label { color: #5A5A5A; font-weight: 600; }
body.dark-mode #desk .profile-stat-box { background: rgba(255, 255, 255, 0.05); border-color: rgba(201, 168, 76, 0.35); box-shadow: none; }
body.dark-mode #desk .profile-stat-label { color: #B5B5B5; }

/* ================================================================
   §65 (v1.97, rilis 2.232) — PERANGKAT DI ACTIVITY LOG (mfb-ui.js 5zo)
   Perangkat baris pertama (terbaca), IP baris kecil. Tidak dipotong: model
   HP pendek; sel boleh membungkus supaya tabel tidak melebar.
   ================================================================ */
#desk .mfb-log-dev { white-space: normal; min-width: 150px; }
#desk .mfb-log-dev-nama { color: #1F1F1F; font-weight: 600; font-size: 12.5px; line-height: 1.35; }
#desk .mfb-log-dev-ip { color: #6B6B6B; font-size: 11.5px; line-height: 1.35; margin-top: 2px; }
body.dark-mode #desk .mfb-log-dev-nama { color: #EDEDED; }
body.dark-mode #desk .mfb-log-dev-ip { color: #A8A8A8; }

/* ================================================================
   §66 (v1.97, rilis 2.232) — SOAL YANG SALAH DI POPUP HASIL KUIS (D15, mfb-ui.js 5ze-b)
   Daftar bisa panjang (bank 30+ soal) → digulir di dalam, popup tetap muat
   satu layar HP. Rata kiri: teks soal panjang sulit dibaca bila rata tengah.
   ================================================================ */
.mfb-soal-salah { margin-top: 16px; text-align: left; border: 1px solid var(--gray-200); border-radius: 12px; padding: 10px 14px; }
.mfb-soal-salah summary { cursor: pointer; font-size: 13.5px; font-weight: 700; color: var(--black); min-height: 28px; line-height: 28px; }
/* Tinggi daftar mengikuti sisa layar: bagian lain popup ±600 px (DIUKUR Chrome 390×844: popup 870 px dengan daftar 34vh →
   atas terpotong 13 px). Layar sangat pendek (320×640) → daftar 120 px dan popup sendiri yang digulir. */
.mfb-soal-salah ol { margin: 8px 0 0; padding-left: 20px; max-height: 34vh; max-height: clamp(120px, calc(100dvh - 640px), 34vh);
  overflow-y: auto; overscroll-behavior: contain; }
#quiz-result-modal > div { max-height: calc(100vh - 40px); max-height: calc(100dvh - 40px); overflow-y: auto; overscroll-behavior: contain; }
.mfb-soal-salah li { margin-bottom: 10px; font-size: 13px; line-height: 1.45; }
.mfb-ss-soal { color: var(--black); font-weight: 600; overflow-wrap: anywhere; }
.mfb-ss-jawab { color: #B91C1C; margin-top: 2px; overflow-wrap: anywhere; }
.mfb-ss-catatan { margin: 6px 0 2px; font-size: 12px; color: var(--gray-500); }
body.dark-mode .mfb-ss-jawab { color: #FCA5A5; }

/* ================================================================
   §67 (v1.98, rilis 2.233) — PETUNJUK TENGGAT BAWAAN (D17, mfb-ui.js 5zq)
   Isian HP baseline punya margin-bottom 20px — petunjuk ditarik naik supaya
   menempel pada isiannya, bukan pada label berikutnya.
   ================================================================ */
.mfb-tenggat-bawaan { margin: 6px 0 0; font-size: 12px; line-height: 1.4; color: var(--gray-500, #6B6B6B); }
#m-assign-deadline + .mfb-tenggat-bawaan { margin: -14px 0 20px; }

/* ================================================================
   §68 (v1.98, rilis 2.233) — EDIT / DELETE EVENT di jendela Attendance
   Tombol kelola event di kiri kaki jendela, terpisah dari Cancel/Save kehadiran.
   Delete bernada merah (tindakan yang tidak bisa dibatalkan), bukan tombol utama.
   ================================================================ */
.mfb-ev-kiri { display: flex; gap: 8px; flex-wrap: wrap; margin-right: auto; }
.mfb-ev-ubah, .mfb-ev-hapus { min-height: 44px; padding: 0 16px; border-radius: 10px; cursor: pointer; font: 700 14px 'Inter', system-ui, sans-serif; background: transparent; }
.mfb-ev-ubah { color: inherit; border: 1.5px solid var(--gray-200, #E7E3DB); }
.mfb-ev-hapus { color: #B91C1C; border: 1.5px solid rgba(185, 28, 28, 0.45); }
.mfb-ev-hapus:disabled { opacity: .5; cursor: not-allowed; }
body.dark-mode .mfb-ev-hapus { color: #FCA5A5; border-color: rgba(252, 165, 165, 0.5); }

/* ================================================================
   §69 (v1.99, rilis 2.234, L20) — POLLS di Attendance (IT Admin & HRM)
   · Tombol "Polls" berkelas sendiri (.mfb-pl-buka): pasangTombolDaftarStaf
     menghapus .mfb-ds-buka apa pun di wadah yang sama.
   · Hasil per orang memakai tabel .mfb-ds-contoh (§ Staff list).
   ================================================================ */
.mfb-pl-buka { display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px; border-radius: 10px;
  font: 700 13.5px 'Inter', system-ui, sans-serif; border: 1.5px solid var(--gold, #C9A84C); background: transparent;
  color: var(--black, #0A0A0A); margin-left: 8px; cursor: pointer; }
.mfb-pl-buka:focus-visible { outline: 3px solid #0A0A0A; outline-offset: 2px; }
body.dark-mode .mfb-pl-buka { color: #F0F0F0; }
body.dark-mode .mfb-pl-buka:focus-visible { outline-color: #F0F0F0; }
.mfb-pl textarea { width: 100%; min-height: 96px; padding: 10px 12px; border-radius: 10px; border: 1.5px solid var(--gray-200, #E7E3DB);
  font: 500 15px/1.4 'Inter', system-ui, sans-serif; resize: vertical; background: transparent; color: inherit; }
.mfb-pl-sub { margin: 18px 0 8px; font: 700 15px 'Inter', system-ui, sans-serif; overflow-wrap: anywhere; }
.mfb-pl-kartu { border: 1px solid var(--gray-200, #E7E3DB); border-radius: 12px; padding: 12px 14px; margin-bottom: 10px; }
body.dark-mode .mfb-pl-kartu { border-color: rgba(255, 255, 255, .14); }
.mfb-pl-tanya { margin: 0 0 4px; overflow-wrap: anywhere; }
.mfb-pl-meta { margin: 0 0 10px; font-size: 13.5px; }
.mfb-pl-buka-tag, .mfb-pl-tutup-tag { display: inline-block; padding: 1px 8px; border-radius: 999px; font-size: 12px; font-weight: 700; }
.mfb-pl-buka-tag { background: #DCFCE7; color: #166534; }
.mfb-pl-tutup-tag { background: #E5E7EB; color: #374151; }
.mfb-pl-aksi { display: flex; flex-wrap: wrap; gap: 8px; }
.mfb-pl-aksi button { min-height: 44px; padding: 0 14px; border-radius: 10px; cursor: pointer; font: 700 13.5px 'Inter', system-ui, sans-serif;
  background: transparent; color: inherit; border: 1.5px solid var(--gray-200, #E7E3DB); }
.mfb-pl-aksi button.mfb-ev-hapus { color: #B91C1C; border-color: rgba(185, 28, 28, .45); }
body.dark-mode .mfb-pl-aksi button.mfb-ev-hapus { color: #FCA5A5; border-color: rgba(252, 165, 165, .5); }
.mfb-pl-kembali { min-height: 44px; }
.mfb-pl-bar { display: grid; gap: 10px; margin: 8px 0 14px; }
.mfb-pl-baris { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 10px; font-weight: 600; font-size: 14px; }
.mfb-pl-baris span:first-child { overflow-wrap: anywhere; }
.mfb-pl-baris span:last-child { font-variant-numeric: tabular-nums; white-space: nowrap; }
.mfb-pl-baris i { grid-column: 1 / -1; display: block; height: 10px; border-radius: 999px; background: linear-gradient(90deg, #C9A84C, #E3C26B); min-width: 2px; }
.mfb-pl-awas { margin: 0 0 12px; padding: 8px 12px; border-radius: 10px; background: #FEF3C7; color: #92400E; font-size: 13.5px; }
.mfb-pl-tanda td { background: rgba(254, 243, 199, .6); }
body.dark-mode .mfb-pl-tanda td { background: rgba(146, 64, 14, .25); }

/* 5zt (v1.101, rilis 2.236, D06-1.3) — angka AI Report dari kode, di samping kalimat Gemini. */
.mfb-air-angka { color: #E3C26B; font-weight: 600; font-variant-numeric: tabular-nums; }

/* 5zu (v1.102, rilis 2.237, D06-1.7) — halaman Learning behaviour.
   Teks memakai warna bawaan halaman (kontras ikut tema); emas hanya untuk
   batang, yang selalu disertai angka tertulis. */
.mfb-lb-buka { display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px; border-radius: 10px;
  font: 700 13.5px 'Inter', system-ui, sans-serif; border: 1.5px solid var(--gold, #C9A84C); background: transparent;
  color: var(--black, #0A0A0A); margin: 12px 16px 0; cursor: pointer; align-self: flex-start; }
.mfb-lb-buka:focus-visible, .mfb-lb-pil:focus-visible { outline: 3px solid #0A0A0A; outline-offset: 2px; }
body.dark-mode .mfb-lb-buka { color: #F0F0F0; }
body.dark-mode .mfb-lb-buka:focus-visible, body.dark-mode .mfb-lb-pil:focus-visible { outline-color: #F0F0F0; }
.mfb-lb-kepala { margin: 4px 0 16px; }
.mfb-lb-judul { font: 700 22px 'Inter', system-ui, sans-serif; margin: 0 0 4px; }
.mfb-lb-catatan, .mfb-lb-ket, .mfb-lb-n, .mfb-lb-sub { font-size: 13px; line-height: 1.45; margin: 0; opacity: .82; }
.mfb-lb-periode { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.mfb-lb-pil { min-height: 44px; padding: 0 14px; border-radius: 999px; border: 1.5px solid var(--gold, #C9A84C);
  background: transparent; color: inherit; font: 600 13px 'Inter', system-ui, sans-serif; cursor: pointer; }
.mfb-lb-pil[aria-pressed="true"] { background: var(--gold, #C9A84C); color: #0A0A0A; }
.mfb-lb-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; align-items: start; }
.mfb-lb-kartu { border: 1px solid rgba(127, 127, 127, .28); border-radius: 14px; padding: 16px; min-width: 0;
  display: flex; flex-direction: column; gap: 10px; }
.mfb-lb-kjudul { font: 700 15px 'Inter', system-ui, sans-serif; margin: 0; }
.mfb-lb-kosong { font-size: 13.5px; margin: 0; padding: 10px 12px; border-radius: 10px; background: rgba(127, 127, 127, .12); }
.mfb-lb-n { margin-top: auto; }
.mfb-lb-daftar { display: flex; flex-direction: column; gap: 8px; }
.mfb-lb-baris { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) auto; gap: 10px; align-items: center;
  font-size: 13px; }
.mfb-lb-label { overflow-wrap: anywhere; }
.mfb-lb-jalur { height: 8px; border-radius: 999px; background: rgba(127, 127, 127, .2); overflow: hidden; }
.mfb-lb-isi { display: block; height: 100%; background: var(--gold, #C9A84C); border-radius: 999px; }
.mfb-lb-nilai { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.mfb-lb-jam + .mfb-lb-jam { margin-top: 12px; }
.mfb-lb-kolom { display: flex; align-items: flex-end; gap: 2px; height: 72px; margin-top: 6px;
  border-bottom: 1px solid rgba(127, 127, 127, .35); }
.mfb-lb-k { flex: 1 1 0; background: var(--gold, #C9A84C); border-radius: 2px 2px 0 0; min-width: 0; }
.mfb-lb-sumbu { display: flex; justify-content: space-between; font-size: 11px; opacity: .75;
  font-variant-numeric: tabular-nums; margin-bottom: 4px; }
.mfb-lb-besar { font: 700 34px 'Inter', system-ui, sans-serif; margin: 0; font-variant-numeric: tabular-nums; }
.mfb-lb-galat { color: #B42318; font-weight: 600; }
/* Wadah desktop tidak ikut berganti warna teks di mode gelap (diukur Chrome 1440: teks
   gelap di latar gelap) — warnanya dipasang eksplisit. */
body.dark-mode #d-behaviour-content { color: #F0F0F0; }
body.dark-mode .mfb-lb-galat { color: #FDA29B; }
@media (max-width: 899px) {
  .mfb-lb-grid { grid-template-columns: minmax(0, 1fr); }
  #m-behaviour-content { padding: 16px; }
  .mfb-lb-baris { grid-template-columns: minmax(0, 1fr) auto; }
  .mfb-lb-baris .mfb-lb-jalur { grid-column: 1 / -1; order: 3; }
}

/* 5zv (v1.103, rilis 2.238, D37) — halaman Staff list + Add to LMS. Memakai kelas
   .mfb-lb-* (judul, catatan, tombol pil) dari 5zu supaya tampilannya satu keluarga. */
#d-stafflist-content { color: inherit; }
body.dark-mode #d-stafflist-content { color: #F0F0F0; }
.mfb-sl-alat { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin: 4px 0 10px; }
.mfb-sl-cari { flex: 1 1 260px; min-height: 44px; padding: 0 14px; border-radius: 10px; border: 1.5px solid rgba(127, 127, 127, .4);
  background: transparent; color: inherit; font: 14px 'Inter', system-ui, sans-serif; }
.mfb-sl-cari:focus-visible { outline: 3px solid var(--gold, #C9A84C); outline-offset: 1px; }
.mfb-sl-bungkus { border: 1px solid rgba(127, 127, 127, .28); border-radius: 14px; overflow: hidden; margin-top: 8px; }
.mfb-sl-tabel { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.mfb-sl-tabel th { text-align: left; font: 700 12px 'Inter', system-ui, sans-serif; letter-spacing: .04em; text-transform: uppercase;
  padding: 12px 14px; border-bottom: 1px solid rgba(127, 127, 127, .3); opacity: .85; }
.mfb-sl-tabel td { padding: 10px 14px; border-bottom: 1px solid rgba(127, 127, 127, .16); vertical-align: middle; overflow-wrap: anywhere; }
.mfb-sl-tabel tr:last-child td { border-bottom: 0; }
.mfb-sl-nonaktif td { opacity: .6; }
.mfb-sl-tambah { min-height: 44px; padding: 0 14px; border-radius: 10px; border: 0; background: var(--gold, #C9A84C);
  color: #0A0A0A; font: 700 13px 'Inter', system-ui, sans-serif; cursor: pointer; white-space: nowrap; }
.mfb-sl-tambah:focus-visible { outline: 3px solid #0A0A0A; outline-offset: 2px; }
body.dark-mode .mfb-sl-tambah:focus-visible { outline-color: #F0F0F0; }
.mfb-sl-ada { display: inline-block; padding: 3px 10px; border-radius: 999px; background: #DCFCE7; color: #166534; font-weight: 700; font-size: 12.5px; }
body.dark-mode .mfb-sl-ada { background: rgba(22, 101, 52, .35); color: #BBF7D0; }
.mfb-sl-form select { width: 100%; min-height: 44px; }
@media (max-width: 899px) {
  #m-stafflist-content { padding: 16px; }
  #m-catalog-content { padding: 16px; } /* v1.111 (2.246) — All Courses HP tanpa jarak tepi sejak 2.242 */
  #m-employees-content { padding: 16px; } /* v1.132 (2.263) — All Employees HP, sama dengan All Courses */
  .mfb-sl-bungkus { border: 0; }
  .mfb-sl-tabel thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .mfb-sl-tabel, .mfb-sl-tabel tbody, .mfb-sl-tabel tr, .mfb-sl-tabel td { display: block; width: 100%; }
  .mfb-sl-tabel tr { border: 1px solid rgba(127, 127, 127, .28); border-radius: 14px; padding: 6px 0; margin-bottom: 10px; }
  .mfb-sl-tabel td { border: 0; padding: 4px 14px; display: flex; gap: 10px; }
  .mfb-sl-tabel td::before { content: attr(data-label); flex: 0 0 104px; font-weight: 700; font-size: 12px; opacity: .75; }
  .mfb-sl-tabel td.mfb-lb-kosong::before { content: none; }
}

/* 5zw (v1.103, rilis 2.238, D39) — Settings: tanda tersimpan di samping isian + tombol Save. */
.mfb-set-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 12px; margin: 0 0 14px; }
.mfb-set-ket { margin-right: auto; font-size: 13px; opacity: .8; }
.mfb-set-simpan { min-height: 44px; padding: 0 18px; border-radius: 10px; border: 0; background: var(--gold, #C9A84C); color: #0A0A0A;
  font: 700 13.5px 'Inter', system-ui, sans-serif; cursor: pointer; }
.mfb-set-simpan:focus-visible { outline: 3px solid #0A0A0A; outline-offset: 2px; }
body.dark-mode .mfb-set-simpan:focus-visible { outline-color: #F0F0F0; }
.mfb-set-simpan:disabled { opacity: .6; cursor: default; }
.mfb-set-tanda { font: 700 12.5px 'Inter', system-ui, sans-serif; margin-left: 8px; white-space: nowrap; }
.mfb-set-ok { color: #166534; }
.mfb-set-gagal { color: #B42318; }
body.dark-mode .mfb-set-ok { color: #86EFAC; }
body.dark-mode .mfb-set-gagal { color: #FDA29B; }

/* 5zx (v1.103, rilis 2.238, D35/D36/D40/D33) — urut, kelompok, export, template kuis. */
.mfb-urut { all: unset; cursor: pointer; font: inherit; letter-spacing: inherit; text-transform: inherit; color: inherit; }
.mfb-urut::after { content: attr(data-tanda); }
.mfb-urut:focus-visible { outline: 2px solid var(--gold, #C9A84C); outline-offset: 2px; border-radius: 4px; }
.mfb-kc-urut, .mfb-ekspor { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.mfb-kc-urut-l { font: 600 12.5px 'Inter', system-ui, sans-serif; opacity: .8; }
.mfb-kc-urut select { min-height: 40px; border-radius: 10px; padding: 0 10px; border: 1.5px solid rgba(127, 127, 127, .4); background: transparent; color: inherit; }
#desk .course-mgmt-grid > .mfb-kc-grup { grid-column: 1 / -1; display: flex; align-items: baseline; gap: 10px; margin: 14px 2px 2px;
  font: 700 12px 'Inter', system-ui, sans-serif; letter-spacing: .08em; text-transform: uppercase; color: #6B6761; }
#desk .course-mgmt-grid.mfb-kc-daftar > .mfb-kc-grup { margin: 0; padding: 10px 18px; background: var(--gray-50); border-bottom: 1px solid var(--gray-100); }
body.dark-mode #desk .course-mgmt-grid > .mfb-kc-grup { color: #C8C2B6; }
.mfb-kc-grup-n { font-weight: 600; letter-spacing: 0; text-transform: none; opacity: .75; }
.mfb-qi-template { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 8px 0 14px; }

/* v1.105 (rilis 2.240) — DASHBOARD TERPOTONG KANAN (laporan IT Manager 1 Okt 23:51). Baseline
   .dash-grid = "1fr 320px"; 1fr berarti minmax(auto, 1fr), jadi lebar minimum kolom kiri = lebar isi
   terpanjang yang tidak boleh patah. Baris Recent Activity "WA captions opened for 9 ID(s): …" (white-space:
   nowrap) melebarkan kolom kiri ±3.900 px dan mendorong Upcoming Deadlines / Quick Actions keluar layar
   (diukur Chrome). minmax(0, 1fr) + min-width:0 pada anaknya → teks panjang dipotong "…" seperti maksudnya. */
#desk .dash-grid { grid-template-columns: minmax(0, 1fr) 320px; }
#desk .dash-grid > * { min-width: 0; }
@media (min-width: 900px) and (max-width: 1200px) { #desk .dash-grid { grid-template-columns: minmax(0, 1fr); } }

/* v1.105 (rilis 2.240, D52) — kartu "Create New Course" di ujung daftar disembunyikan HANYA bila tombol
   toolbar .mfb-kc-buat ada; kalau tombol gagal terpasang, kartu lama tetap jadi jalan membuat course. */
#d-courses-mgmt-content:has(.mfb-kc-buat) .add-course-cta { display: none !important; }
/* v1.106 (2.241) — pop-up berita HR dari lonceng (MOCK UP). */
.topbar-icon-btn[data-mfb-berita] { cursor: pointer; }
.topbar-icon-btn[data-mfb-berita]:focus-visible { outline: 2px solid #C9A84C; outline-offset: 2px; }
.mfb-berita-daftar { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.mfb-berita-item { padding: 12px 14px; border-radius: 12px; border: 1px solid rgba(127, 127, 127, .25); background: rgba(127, 127, 127, .05); }
.mfb-berita-baru { border-color: #C9A84C; box-shadow: inset 3px 0 0 #C9A84C; }
.mfb-berita-atas { display: flex; align-items: center; gap: 8px; font-size: 12px; margin-bottom: 4px; }
.mfb-berita-dari { padding: 1px 8px; border-radius: 999px; background: #1F5E3B; color: #FFFFFF; font-weight: 800; letter-spacing: .06em; }
.mfb-berita-kapan { opacity: .75; }
.mfb-berita-tanda { margin-left: auto; padding: 1px 8px; border-radius: 999px; background: #16140F; color: #E3C26B; font-weight: 700; }
body.dark-mode .mfb-berita-tanda { background: #E3C26B; color: #16140F; }
.mfb-berita-judul { margin: 0 0 2px; font: 700 14.5px/1.35 'Inter', system-ui, sans-serif; }
.mfb-berita-isi { margin: 0; font-size: 13.5px; line-height: 1.5; opacity: .85; }

/* v1.106 (2.241) — GRAFIK LEARNING BEHAVIOUR lebih hidup (IT Manager 2 Okt: "grafik kurang interactive dan menarik";
   referensi d:WibawaAnabhi DevStandardUI-UX from IG): lintasan pucat, satu nilai tertinggi menyala, tooltip
   sentuh/fokus, batang bertumpuk, gauge bergaris, tumbuh saat dibuka. Angka & rumus TIDAK berubah. */
.mfb-lb-kartu { border-radius: 16px; box-shadow: 0 6px 18px rgba(22, 20, 15, .06); }
body.dark-mode .mfb-lb-kartu { box-shadow: 0 6px 18px rgba(0, 0, 0, .35); }
.mfb-lb-jalur { height: 10px; }
.mfb-lb-isi { background: linear-gradient(90deg, #D9B65A 0%, #C9A84C 100%); transform-origin: left center; animation: mfbLbTumbuhX .7s cubic-bezier(.2, .8, .2, 1) both; }
.mfb-lb-daftar:has(.mfb-lb-puncak) .mfb-lb-baris:not(.mfb-lb-puncak) .mfb-lb-isi { opacity: .5; }
.mfb-lb-puncak .mfb-lb-nilai { color: #8A6A1F; }
body.dark-mode .mfb-lb-puncak .mfb-lb-nilai { color: #E3C26B; }
@keyframes mfbLbTumbuhX { from { transform: scaleX(0); } }
@keyframes mfbLbTumbuhY { from { transform: scaleY(0); } }
.mfb-lb-kolom { gap: 3px; height: 96px; margin-top: 28px; }
.mfb-lb-kt { flex: 1 1 0; min-width: 0; height: 100%; position: relative; display: flex; align-items: flex-end; border-radius: 4px; background: rgba(127, 127, 127, .12); outline: none; }
.mfb-lb-kt .mfb-lb-k { flex: none; width: 100%; position: relative; border-radius: 3px; background: linear-gradient(180deg, #E3C26B 0%, #C9A84C 100%); opacity: .55; transform-origin: bottom center; animation: mfbLbTumbuhY .7s cubic-bezier(.2, .8, .2, 1) both; }
.mfb-lb-kt-puncak .mfb-lb-k, .mfb-lb-kt:hover .mfb-lb-k, .mfb-lb-kt:focus .mfb-lb-k { opacity: 1; }
.mfb-lb-gelembung { position: absolute; left: 50%; bottom: calc(100% + 4px); transform: translateX(-50%); padding: 1px 7px; border-radius: 999px; background: #16140F; color: #E3C26B; font: 700 11px/1.5 'Inter', system-ui, sans-serif; white-space: nowrap; pointer-events: none; }
body.dark-mode .mfb-lb-gelembung { background: #E3C26B; color: #16140F; }
.mfb-lb-kt:hover::after, .mfb-lb-kt:focus::after { content: attr(data-tip); position: absolute; left: 50%; bottom: calc(100% + 26px); transform: translateX(-50%); z-index: 3; padding: 4px 9px; border-radius: 8px; background: #16140F; color: #FFFFFF; font: 600 12px/1.4 'Inter', system-ui, sans-serif; white-space: nowrap; pointer-events: none; box-shadow: 0 4px 12px rgba(0, 0, 0, .25); }
.mfb-lb-kt:nth-child(-n+3):hover::after, .mfb-lb-kt:nth-child(-n+3):focus::after { left: 0; transform: none; }
.mfb-lb-kt:nth-last-child(-n+3):hover::after, .mfb-lb-kt:nth-last-child(-n+3):focus::after { left: auto; right: 0; transform: none; }
.mfb-lb-kt:focus-visible { box-shadow: 0 0 0 2px #C9A84C; }
.mfb-lb-tumpuk { display: flex; }
.mfb-lb-tumpuk .mfb-lb-isi { border-radius: 0; flex: none; }
.mfb-lb-tumpuk .mfb-lb-isi:first-child { border-radius: 999px 0 0 999px; }
.mfb-lb-t1 { background: #C9A84C; }
.mfb-lb-t2 { background: #E8D49C; }
.mfb-lb-t3 { background: repeating-linear-gradient(45deg, #6B5A2E 0 3px, #A08A52 3px 6px); }
body.dark-mode .mfb-lb-t2 { background: #8C7A45; }
.mfb-lb-login { position: relative; text-align: center; }
.mfb-lb-gauge { display: block; width: min(240px, 100%); height: auto; margin: 0 auto; }
.mfb-lb-tik { stroke: rgba(127, 127, 127, .3); stroke-width: 5; stroke-linecap: round; }
.mfb-lb-tik-on { stroke: #C9A84C; }
body.dark-mode .mfb-lb-tik-on { stroke: #E3C26B; }
.mfb-lb-login .mfb-lb-besar { margin-top: -46px; font-family: Georgia, 'Times New Roman', serif; }
@media (prefers-reduced-motion: reduce) { .mfb-lb-isi, .mfb-lb-kt .mfb-lb-k { animation: none; } }

/* v1.106 (2.241) — kepala kolom Manage Courses (list) lebih gelap & bisa diklik untuk mengurutkan
   (IT Manager 2 Okt: "judul kolom kasi fill warna lebih gelap kak, biar kontrast dengan isinya"). */
#desk .mfb-kc-daftar > .mfb-kc-kepala { background: #16140F; color: #E3C26B; border-bottom: 1px solid #C9A84C; }
body.dark-mode #desk .mfb-kc-daftar > .mfb-kc-kepala { background: #050505; color: #E3C26B; }
.mfb-kc-urut-kol { all: unset; cursor: pointer; font: inherit; letter-spacing: inherit; text-transform: inherit; color: inherit; padding: 4px 0; border-radius: 4px; }
.mfb-kc-urut-kol:hover { color: #FFF3CC; text-decoration: underline; text-underline-offset: 3px; }
.mfb-kc-urut-kol:focus-visible { outline: 2px solid #E3C26B; outline-offset: 2px; }

/* v1.106 (2.241) — Employee List tampil sebagai ANAK Attendance (IT Manager 2 Okt: "geser ke kanan dikit,
   supaya keliatan seperti child dari Attendance"). Garis penghubung di ::after (::before dipakai penanda aktif). */
#desk .nav-item[data-page="stafflist"] { position: relative; margin-left: 20px; font-size: 12.5px; }
#desk .nav-item[data-page="stafflist"]::after { content: ''; position: absolute; left: -11px; top: -4px; width: 9px; height: calc(50% + 4px);
  border-left: 1px solid rgba(201, 160, 101, .45); border-bottom: 1px solid rgba(201, 160, 101, .45); border-bottom-left-radius: 6px; pointer-events: none; }

/* v1.106 (2.241, D51) — isian jumlah soal per course di form course. */
.mfb-crs-soal[hidden] { display: none !important; }
.mfb-crs-soal-ket { grid-column: 1 / -1; margin: -4px 0 4px; font-size: 12px; line-height: 1.45; color: var(--gray-500, #6B6761); }

/* v1.105 (2.240, D56) — catatan sebab saat PDF memakai pratinjau cadangan (tanpa zoom). */
.mfb-pdf-cadangan { margin: 0; padding: 10px 14px; font: 500 13px/1.45 'Inter', system-ui, sans-serif; color: #5A4512;
  background: #FDF3D8; border-bottom: 1px solid #E0B94C; }
body.dark-mode .mfb-pdf-cadangan { color: #F6E7BE; background: #3A2F14; border-bottom-color: #7A5A10; }
/* v1.105 (2.240, D53) — Course ID di header form Edit Course: label kecil tepat di samping judul. */
.mfb-crs-id { margin: 0 auto 0 12px; padding: 4px 10px; border-radius: 999px; background: var(--gray-100, #F1EFEA);
  font: 600 12px ui-monospace, 'Consolas', monospace; color: var(--gray-600, #5C5A56); white-space: nowrap; }
body.dark-mode .mfb-crs-id { background: rgba(255, 255, 255, .08); color: #D9D3C7; }

/* v1.104 (rilis 2.239) — judul departemen di tabel Manage Users (Group by department). */
#desk tr.mfb-ku-grup th { text-align: left; padding: 10px 18px; background: var(--gray-50); border-bottom: 1px solid var(--gray-100);
  font: 700 12px 'Inter', system-ui, sans-serif; letter-spacing: .08em; text-transform: uppercase; color: #6B6761; }
#desk tr.mfb-ku-grup th > span + span { margin-left: 10px; }
body.dark-mode #desk tr.mfb-ku-grup th { color: #C8C2B6; }

/* v1.104 (rilis 2.239) — tombol toolbar Manage Users/Courses (Group, XLSX, CSV) 3D & lebih jelas
   (IT Manager 1 Okt: "dibuat button 3D dan lebih jelas"). Hanya di toolbar; pil periode Learning
   behaviour tidak berubah. Ditekan = turun 2 px, bayangan menipis. */
.mfb-kc-urut .mfb-lb-pil, .mfb-ekspor .mfb-lb-pil {
  border: 1.5px solid #A8842F; color: #2A2108; font-weight: 700;
  background: linear-gradient(180deg, #FFF8E6 0%, #F1DFAE 100%);
  box-shadow: 0 3px 0 #A8842F, 0 5px 10px rgba(0, 0, 0, .14), inset 0 1px 0 rgba(255, 255, 255, .8);
  transition: transform .08s ease, box-shadow .08s ease; }
.mfb-kc-urut .mfb-lb-pil:hover, .mfb-ekspor .mfb-lb-pil:hover { background: linear-gradient(180deg, #FFFBF0 0%, #EBD496 100%); }
.mfb-kc-urut .mfb-lb-pil:active, .mfb-ekspor .mfb-lb-pil:active {
  transform: translateY(2px); box-shadow: 0 1px 0 #A8842F, 0 2px 4px rgba(0, 0, 0, .14), inset 0 1px 0 rgba(255, 255, 255, .6); }
.mfb-kc-urut .mfb-lb-pil[aria-pressed="true"] {
  background: linear-gradient(180deg, #D9B65A 0%, #B8913A 100%); color: #0A0A0A; border-color: #7E6020;
  box-shadow: 0 1px 0 #7E6020, inset 0 2px 4px rgba(0, 0, 0, .22); transform: translateY(2px); }
body.dark-mode .mfb-kc-urut .mfb-lb-pil, body.dark-mode .mfb-ekspor .mfb-lb-pil {
  color: #F6E7BE; border-color: #C9A84C; background: linear-gradient(180deg, #3A3122 0%, #241E14 100%);
  box-shadow: 0 3px 0 #8A6A1F, 0 5px 10px rgba(0, 0, 0, .45), inset 0 1px 0 rgba(255, 255, 255, .08); }
body.dark-mode .mfb-kc-urut .mfb-lb-pil[aria-pressed="true"] {
  color: #0A0A0A; background: linear-gradient(180deg, #E3C26B 0%, #C9A84C 100%); box-shadow: 0 1px 0 #8A6A1F, inset 0 2px 4px rgba(0, 0, 0, .3); }
@media (prefers-reduced-motion: reduce) { .mfb-kc-urut .mfb-lb-pil, .mfb-ekspor .mfb-lb-pil { transition: none; } }

/* 5zy (v1.103, rilis 2.238, D42) — tautan Open di samping link modul. */
.mfb-mod-buka { display: inline-block; margin: 6px 0 0; font: 600 12.5px Inter, system-ui, sans-serif; color: #8A6A1F; text-decoration: underline; }
body.dark-mode .mfb-mod-buka { color: #E3C26B; }

/* v1.107 (2.242) — LOGIN DESKTOP SELALU TERANG, sama dengan HP. Baseline menulis niatnya
   ("Login page SELALU light — tidak ikut dark mode") tetapi hanya memasangnya untuk #mob.
   Di desktop, dark mode mengganti variabel warna di body sementara panel kanan tetap
   bergradasi krem → judul putih di atas krem (laporan IT Manager 2 Okt 18:35). Nilai di
   bawah = nilai :root mode terang; kolom isian = hasil ukur mode terang di Chrome
   (teks #0A0A0A, latar #FFFFFF, garis rgb(201,168,101)). Panel kiri (gelap) tidak disentuh. */
body.dark-mode #desk #d-login .login-right {
  --white: #FFFFFF; --off-white: #FAFAFA; --black: #0A0A0A; --charcoal: #1C1C1C;
  --gray-50: #F7F7F5; --gray-100: #EFEFED; --gray-200: #E0DFDD; --gray-300: #C8C7C4;
  --gray-400: #A8A7A3; --gray-500: #787672; --gray-700: #3A3936;
}
body.dark-mode #desk #d-login .login-right input {
  background: #FFFFFF !important; color: #0A0A0A !important; border-color: rgb(201, 168, 101) !important;
}

/* v1.107 (2.242) — ALL COURSES: katalog course Published per departemen (menu baru). */
.mfb-kat-atas { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; justify-content: space-between; margin: 0 0 18px; }
.mfb-kat-ringkas { margin: 0; flex: 1 1 280px; font-size: 13.5px; color: var(--gray-500); }
.mfb-kat-cari { flex: 0 1 280px; min-height: 44px; padding: 0 14px; border: 1px solid var(--gray-200); border-radius: 10px;
  background: var(--white); color: var(--black); font: 400 14px Inter, system-ui, sans-serif; }
.mfb-kat-dept { margin: 0 0 22px; }
.mfb-kat-dept h3 { display: flex; align-items: center; gap: 10px; margin: 0 0 10px; font: 700 17px/1.3 'Playfair Display', Georgia, serif; color: var(--black); }
.mfb-kat-n { padding: 4px 9px; border-radius: 999px; background: rgba(201, 168, 76, .14); color: #8A6A1F; font: 700 12px/1 Inter, system-ui, sans-serif; }
.mfb-kat-daftar { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); gap: 12px; }
.mfb-kat-item { padding: 14px 16px; border: 1px solid var(--gray-100); border-radius: 14px; background: var(--white); }
.mfb-kat-judul { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; font-weight: 700; font-size: 15px; color: var(--black); }
.mfb-kat-milik { padding: 3px 8px; border-radius: 999px; background: #E5F4EA; color: #1F5E3B; font-size: 11px; font-weight: 700; }
.mfb-kat-desk { margin: 6px 0 0; font-size: 13.5px; line-height: 1.5; color: var(--gray-500); }
.mfb-kat-meta { margin: 8px 0 0; font-size: 12px; color: var(--gray-400); }
.mfb-kat-buka { display: block; width: calc(100% - 32px); min-height: 44px; margin: 4px 16px 12px; border: 1px solid #C9A84C; border-radius: 12px;
  background: transparent; color: #8A6A1F; font: 600 14px Inter, system-ui, sans-serif; cursor: pointer; }
body.dark-mode .mfb-kat-milik { background: rgba(46, 125, 82, .25); color: #9BE3B5; }
body.dark-mode .mfb-kat-n, body.dark-mode .mfb-kat-buka { color: #E3C26B; }
.mfb-kat-cari:focus-visible, .mfb-kat-buka:focus-visible { outline: 3px solid #C9A84C; outline-offset: 2px; }

/* v1.107 (2.242, D74) — dialog Trial feedback (HR). */
.mfb-fb-atas { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin: 0 0 6px; }
.mfb-fb-total { margin: 0 auto 0 0; font: 700 18px/1.3 'Playfair Display', Georgia, serif; color: var(--black); }
.mfb-fb-catatan { margin: 0 0 14px; font-size: 12.5px; color: var(--gray-500); overflow-wrap: anywhere; }
.mfb-fb-q { margin: 0 0 16px; padding-top: 12px; border-top: 1px solid var(--gray-100); }
.mfb-fb-q h4 { margin: 0 0 8px; font-size: 14px; color: var(--black); }
.mfb-fb-bar { display: grid; grid-template-columns: minmax(110px, 34%) 1fr 76px; gap: 10px; align-items: center; margin: 4px 0; font-size: 13px; }
.mfb-fb-lbl { color: var(--gray-700); overflow-wrap: anywhere; }
.mfb-fb-trek { height: 10px; border-radius: 999px; background: var(--gray-100); overflow: hidden; }
.mfb-fb-isi { display: block; height: 100%; border-radius: 999px; background: #C9A84C; }
.mfb-fb-n { text-align: right; font-weight: 700; color: var(--black); font-variant-numeric: tabular-nums; }
.mfb-fb-teks { margin: 0; padding-left: 18px; font-size: 13.5px; color: var(--gray-700); }
.mfb-fb-teks li { margin: 0 0 6px; overflow-wrap: anywhere; }
.mfb-fb-teks small { color: var(--gray-500); }
/* v1.111 (rilis 2.246) — ringkasan dialog Trial feedback: 4 kartu angka. */
.mfb-fb-ringkas { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; margin: 0 0 16px; }
.mfb-fb-ringkas div { padding: 12px 14px; border: 1px solid var(--gray-100); border-top: 3px solid #C9A84C; border-radius: 12px; background: var(--white); }
.mfb-fb-ringkas b { display: block; font: 700 26px/1.1 'Playfair Display', Georgia, serif; color: var(--black); }
.mfb-fb-ringkas span { display: block; margin-top: 4px; font-size: 12.5px; color: var(--gray-500); }
body.dark-mode .mfb-fb-ringkas div { background: #1A1A1A; border-color: #333; border-top-color: #C9A84C; }
body.dark-mode .mfb-fb-ringkas b { color: #F0F0F0; }
@media (max-width: 640px) { .mfb-fb-ringkas { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .mfb-fb-bar { grid-template-columns: 1fr 76px; } .mfb-fb-trek { grid-column: 1 / -1; grid-row: 2; } }

/* v1.108 (2.243, D93) — RECORD ATTENDANCE: tampilan awal = daftar yang sudah tercatat (label status).
   Dropdown & "Mark everyone" hanya di mode koreksi (.mfb-hd-manual). Label disembunyikan di mode itu
   bila ada dropdown di sebelahnya (baris yang bisa diubah). */
.mfb-hd-alat { display: flex; flex-wrap: wrap; gap: 8px; }
.mfb-hd:not(.mfb-hd-manual) .mfb-hd-baris select[data-uid], .mfb-hd:not(.mfb-hd-manual) .mfb-hd-semua { display: none; }
.mfb-hd.mfb-hd-manual .mfb-hd-st:has(+ select[data-uid]) { display: none; }

/* v1.108 (2.243, D91) — tautan check-in QR di bawah tombol Sign In (desktop & HP). Layar login selalu terang. */
.mfb-checkin-login { display: flex; align-items: center; justify-content: center; min-height: 44px; margin-top: 8px;
  font-size: 14px; font-weight: 600; color: #8A6A1F; text-decoration: none; border-radius: 10px; }
.mfb-checkin-login:hover { text-decoration: underline; }
.mfb-checkin-login:focus-visible { outline: 3px solid #C9A84C; outline-offset: 2px; }

/* v1.108 (2.243, D95) — ALL COURSES sebagai DAFTAR: satu baris per course (seperti list Manage Courses), deskripsi di popup. */
.mfb-kat-daftar.mfb-kat-list { display: block; border: 1px solid var(--gray-100); border-radius: 14px; overflow: hidden; background: var(--white); }
.mfb-kat-list .mfb-kat-item { padding: 0; border: 0; border-radius: 0; background: none; }
.mfb-kat-list .mfb-kat-item + .mfb-kat-item { border-top: 1px solid var(--gray-100); }
.mfb-kat-baris { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 52px; padding: 10px 16px; border: 0; background: none;
  color: inherit; font: inherit; text-align: left; cursor: pointer; }
.mfb-kat-baris:hover { background: rgba(201, 168, 76, .08); }
.mfb-kat-baris:focus-visible { outline: 3px solid #C9A84C; outline-offset: -3px; }
.mfb-kat-baris .mfb-kat-judul { flex: 1 1 auto; min-width: 0; }
.mfb-kat-nama { overflow-wrap: anywhere; }
.mfb-kat-baris .mfb-kat-meta { flex: 0 0 auto; margin: 0; white-space: nowrap; }
.mfb-kat-panah { flex: 0 0 auto; font-size: 20px; line-height: 1; color: #8A6A1F; }
.mfb-kat-pop-meta { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 0 0 12px; font-size: 13.5px; color: var(--gray-500); }
.mfb-kat-pop .mfb-kat-desk { margin: 0; font-size: 15px; line-height: 1.6; color: var(--black); white-space: pre-line; }
body.dark-mode .mfb-kat-daftar.mfb-kat-list { background: #1A1A1A; border-color: #2A2A2A; }
body.dark-mode .mfb-kat-list .mfb-kat-item + .mfb-kat-item { border-color: #2A2A2A; }
body.dark-mode .mfb-kat-panah { color: #E3C26B; }
body.dark-mode .mfb-kat-pop .mfb-kat-desk { color: #F0F0F0; }

/* v1.108 (2.243, D98) — pilihan putaran di dialog Trial feedback (muncul bila > 1 putaran). */
.mfb-fb-putaran { min-height: 44px; padding: 0 12px; border: 1px solid var(--gray-200); border-radius: 10px; font: 600 14px Inter, system-ui, sans-serif; background: var(--white); color: var(--black); }
.mfb-fb-putaran:focus-visible { outline: 3px solid #C9A84C; outline-offset: 2px; }
body.dark-mode .mfb-fb-putaran { background: #1A1A1A; color: #F0F0F0; border-color: #333; }

/* v1.109 (2.244, D79/D99) — aturan kuis tambahan & catatan ulangan sesudah lulus. */
.mfb-aturan-kuis { font-size: 14px; line-height: 1.5; color: var(--black); }
.mfb-aturan-kuis-hp { margin: 0 0 12px; padding: 10px 12px; border-radius: 12px; background: rgba(201, 168, 76, .12); border: 1px solid rgba(201, 168, 76, .45); }
.mfb-aturan-kuis-hp p { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--black); }
.mfb-aturan-kuis-hp p + p { margin-top: 6px; }
.mfb-ulang-catatan { margin: 0 0 16px; padding: 10px 12px; border-radius: 10px; background: #E5F4EA; color: #1F5E3B; font-size: 13.5px; font-weight: 600; }
body.dark-mode .mfb-aturan-kuis, body.dark-mode .mfb-aturan-kuis-hp p { color: #F0F0F0; }
body.dark-mode .mfb-ulang-catatan { background: rgba(46, 125, 82, .25); color: #9BE3B5; }

/* v1.110 (2.245, D86) — Course reminders: siapa yang belum menyelesaikan course-nya. */
.mfb-ing-daftar { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 10px; }
.mfb-ing-orang { padding: 12px 14px; border: 1px solid var(--gray-100); border-radius: 12px; background: var(--white); }
.mfb-ing-kepala { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; justify-content: space-between; }
.mfb-ing-nama { font-weight: 700; font-size: 15px; } .mfb-ing-nama small { font-weight: 500; color: var(--gray-500); }
.mfb-ing-course { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 4px; }
.mfb-ing-course li { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; font-size: 14px; }
.mfb-ing-judul { flex: 1 1 180px; min-width: 0; overflow-wrap: anywhere; }
.mfb-ing-pct { font-weight: 700; color: #8A6A1F; }
.mfb-ing-due { font-size: 12.5px; padding: 2px 8px; border-radius: 999px; background: var(--gray-50, #FAFAF8); color: var(--gray-500); }
.mfb-ing-telat { background: #FDECEC; color: #8A1C1C; font-weight: 700; }
body.dark-mode .mfb-ing-orang { background: #1A1A1A; border-color: #2A2A2A; }
body.dark-mode .mfb-ing-pct { color: #E3C26B; }
body.dark-mode .mfb-ing-due { background: #262626; color: #B9B2A5; } body.dark-mode .mfb-ing-telat { background: rgba(185, 28, 28, .25); color: #FCA5A5; }

/* ================================================================
   v1.111 (rilis 2.246) — ALL COURSES dengan pola Employee List (IT Manager 3 Okt 08:44): tabel mfb-sl-*,
   pil mfb-lb-*. Di sini hanya tambahan: tombol Request "Soon", judul course yang bisa diklik, kolom aksi.
   ================================================================ */
.mfb-kat-minta { display: inline-flex; align-items: center; gap: 8px; background: linear-gradient(180deg, #E3C26B, #C9A84C); border-color: #C9A84C; color: #08090C; }
.mfb-kat-segera { padding: 3px 7px; border-radius: 999px; background: rgba(8, 9, 12, .85); color: #E3C26B; font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.mfb-kat-pilih { min-height: 44px; padding: 0 12px; border: 1px solid var(--gray-200); border-radius: 999px; background: var(--white); color: var(--black); font: 600 13.5px Inter, system-ui, sans-serif; }
.mfb-kat-pilih:focus-visible, .mfb-kat-judul-btn:focus-visible { outline: 3px solid #C9A84C; outline-offset: 2px; }
.mfb-kat-judul-btn { display: inline-flex; align-items: center; min-height: 44px; padding: 0; border: 0; background: none; color: var(--black); font: 700 15px/1.35 Inter, system-ui, sans-serif; text-align: left; cursor: pointer; }
.mfb-kat-judul-btn:hover { color: #8A6A1F; text-decoration: underline; text-underline-offset: 3px; }
.mfb-kat-sel-aksi { white-space: nowrap; }
.mfb-kat-sel-aksi > * + * { margin-left: 8px; }
.mfb-kat-sel-aksi .mfb-lb-pil { min-height: 40px; }
.mfb-kat-minta-ini { display: inline-flex; align-items: center; gap: 8px; margin-top: 16px; }
body.dark-mode .mfb-kat-pilih { background: #1A1A1A; border-color: #333; color: #E6E1D6; }
body.dark-mode .mfb-kat-judul-btn { color: #F0F0F0; }
body.dark-mode .mfb-kat-judul-btn:hover { color: #E3C26B; }

/* v1.112 (rilis 2.247, IT Manager 3 Okt 09:43) — contoh di kolom login tipis & miring: jelas contoh, bukan isian. */
html body #d-username::placeholder, html body #m-username::placeholder,
html body #d-pwd::placeholder, html body #m-pwd::placeholder {
  font-style: italic; font-weight: 400; letter-spacing: 0; text-transform: none; opacity: .55;
}

/* v1.112 (rilis 2.247) — HoD HP: judul kartu "My Team vs Company" menempel di sudut kartu (jarak 0 / 0; desktop 25 / 19)
   karena .card-header baseline hanya diberi jarak di desktop. Kartu tambahan di bawah diberi jarak dari kartu di atasnya. */
#m-hod-dashboard-content .mfb-banding .card-header { padding: 18px 20px 6px; }
#m-hod-dashboard-content .mfb-banding { margin-top: 18px; }
#d-hod-dashboard-content > .mfb-training-card { margin-top: 18px; }
/* HP: kartu tambahan di bawah sejajar kartu Team Progress (16 px dari tepi), bukan selebar layar. */
#m-hod-dashboard-content > .mfb-training-card { margin: 18px 16px 0; border-radius: 18px; }
/* Judul banding = gaya judul bagian lain di dashboard HP (Team Progress). */
#m-hod-dashboard-content .mfb-banding .card-title { font: 700 16px Georgia, "Times New Roman", serif; letter-spacing: 0; text-transform: none; }

/* v1.112 (rilis 2.247, audit HoD 3 Okt) — HP: (1) baris 3 kotak angka di My Team & Dept Reports dibagi rata selebar layar
   (dulu lebar tetap seperti untuk 4 kotak, sisa kosong di kanan); (2) kartu Assign Course diberi jarak dari header
   (dulu menempel, margin atas 0). Dibatasi ke halaman HoD; halaman lain tidak tersentuh. */
#mob #m-hod-staff-content > .stat-mini-scroll > *, #mob #m-hod-reports-content > .stat-mini-scroll > * { flex: 1 1 0; min-width: 0; }
#mob #m-hod-assign-content > .mob-form-card:first-child { margin-top: 16px; }

/* v1.113 (2.248, D85) — isian Trainer di form event, tersembunyi sebelum tambah-2248.sql. */
.mfb-ev-trainer[hidden] { display: none !important; }

/* v1.113 (2.248, D111) — kartu pilihan bahasa di Profile (desktop kolom kanan & HP), di atas kartu Help. */
.mfb-bahasa { background: var(--white, #fff); border: 1px solid var(--gray-100, #ECE8E1); border-radius: 14px; padding: 14px 16px; margin: 0 0 12px; }
.mfb-bahasa-hp { margin: 12px 16px; }
.mfb-bahasa-judul { margin: 0; font: 700 15px/1.3 Georgia, serif; color: var(--black, #16140F); }
.mfb-bahasa-ket { margin: 2px 0 10px; font-size: 12.5px; line-height: 1.45; color: var(--gray-500, #6B6761); }
.mfb-bahasa-pil { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.mfb-bahasa-btn { min-height: 44px; border-radius: 10px; border: 1px solid var(--gray-200, #DDD6CA); background: transparent; color: inherit; font: 600 14px Inter, system-ui, sans-serif; cursor: pointer; }
.mfb-bahasa-btn[aria-checked="true"] { background: var(--solid-dark, #16140F); border-color: var(--solid-dark, #16140F); color: #fff; }
.mfb-bahasa-btn:focus-visible { outline: 3px solid var(--gold, #C9A065); outline-offset: 2px; }
body.dark-mode .mfb-bahasa { background: var(--gray-50, #1A1C22); border-color: rgba(255,255,255,.08); }
body.dark-mode .mfb-bahasa-judul { color: #F4F1EA; }
body.dark-mode .mfb-bahasa-btn[aria-checked="true"] { background: var(--gold, #C9A065); border-color: var(--gold, #C9A065); color: #08090C; }

/* v1.114 (2.249, D113) — quiz teori per event: isian di form + hasil per orang di daftar hadir. */
.mfb-ev-quiz[hidden] { display: none !important; }
.mfb-hd-quizinfo { font-weight: 600; color: #8A6A1F; }
.mfb-hd-quiz { display: inline-block; margin-top: 3px; padding: 1px 8px; border-radius: 999px; font-size: 12px; font-weight: 700; background: var(--gray-50, #FAFAF8); }
.mfb-hd-quiz-lulus { color: #047857; } .mfb-hd-quiz-gagal { color: #B91C1C; } .mfb-hd-quiz-belum { color: #8A6A1F; }
body.dark-mode .mfb-hd-quizinfo { color: #E3C26B; }
body.dark-mode .mfb-hd-quiz { background: #262626; }
body.dark-mode .mfb-hd-quiz-lulus { color: #6EE7B7; } body.dark-mode .mfb-hd-quiz-gagal { color: #FCA5A5; } body.dark-mode .mfb-hd-quiz-belum { color: #E3C26B; }

/* ================================================================
   v1.115 (2.250) — LEARNING BEHAVIOUR, TAMPILAN PREMIUM
   IT Manager 3 Okt 16:0x: "pake grafik dari UI-UX from IG … yg sekarang standard banget".
   Angka & rumus TIDAK berubah — hanya bentuk. Pola dari referensi: rel berarsir miring,
   satu batang tinta pekat sebagai sorotan, gauge tik bergradasi, matriks titik per orang.
   ================================================================ */
.mfb-lb-kartu { padding: 20px; border-radius: 18px; }
.mfb-lb-kjudul { font-size: 16px; letter-spacing: -.01em; }
/* Rel berarsir (dipakai batang mendatar & kolom jam). */
.mfb-lb-jalur { height: 14px; background: repeating-linear-gradient(135deg, rgba(127, 127, 127, .22) 0 2px, rgba(127, 127, 127, .06) 2px 7px); }
.mfb-lb-isi { background: linear-gradient(90deg, #EBD496 0%, #C9A84C 60%, #A8852E 100%); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35); }
.mfb-lb-daftar:has(.mfb-lb-puncak) .mfb-lb-baris:not(.mfb-lb-puncak) .mfb-lb-isi { opacity: 1; background: linear-gradient(90deg, #F3E6C2 0%, #DCC27D 100%); }
.mfb-lb-puncak .mfb-lb-isi { background: linear-gradient(90deg, #3A3326 0%, #16140F 100%); box-shadow: 0 0 0 1px rgba(201, 168, 76, .55), 0 4px 10px rgba(22, 20, 15, .22); }
.mfb-lb-nilai { padding: 2px 9px; border-radius: 999px; background: rgba(127, 127, 127, .10); font-size: 12.5px; }
.mfb-lb-puncak .mfb-lb-nilai { background: #16140F; color: #E3C26B; }
body.dark-mode .mfb-lb-isi { background: linear-gradient(90deg, #8C7A45 0%, #C9A84C 100%); box-shadow: none; }
body.dark-mode .mfb-lb-daftar:has(.mfb-lb-puncak) .mfb-lb-baris:not(.mfb-lb-puncak) .mfb-lb-isi { background: linear-gradient(90deg, #4A4130 0%, #7A6A3C 100%); }
body.dark-mode .mfb-lb-puncak .mfb-lb-isi { background: linear-gradient(90deg, #E3C26B 0%, #F3D98A 100%); box-shadow: 0 0 12px rgba(227, 194, 107, .35); }
body.dark-mode .mfb-lb-puncak .mfb-lb-nilai { background: #E3C26B; color: #16140F; }
/* Tries until passing — tiga segmen pil bercelah + legenda. Segmen 0% disembunyikan supaya celahnya tidak dobel. */
.mfb-lb-tumpuk { gap: 3px; }
.mfb-lb-tumpuk .mfb-lb-isi, .mfb-lb-tumpuk .mfb-lb-isi:first-child { flex: 0 1 auto; min-width: 0; border-radius: 999px; box-shadow: none; }
.mfb-lb-tumpuk .mfb-lb-isi[style*="width: 0%"] { display: none; }
.mfb-lb-t1 { background: linear-gradient(90deg, #3A3326 0%, #16140F 100%); }
.mfb-lb-t2 { background: linear-gradient(90deg, #E3C26B 0%, #C9A84C 100%); }
.mfb-lb-t3 { background: repeating-linear-gradient(135deg, #C9A84C 0 2px, #F3E6C2 2px 5px); }
body.dark-mode .mfb-lb-t1 { background: linear-gradient(90deg, #F3D98A 0%, #E3C26B 100%); }
body.dark-mode .mfb-lb-t2 { background: #8C7A45; }
body.dark-mode .mfb-lb-t3 { background: repeating-linear-gradient(135deg, #8C7A45 0 2px, #3A3326 2px 5px); }
.mfb-lb-legenda { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 12px; font-weight: 600; opacity: .85; margin-bottom: 2px; }
.mfb-lb-leg { display: inline-flex; align-items: center; gap: 6px; }
.mfb-lb-leg i { display: inline-block; width: 16px; height: 8px; border-radius: 999px; }
/* When people learn — kolom pil di atas rel berarsir; jam tersibuk tinta pekat. */
.mfb-lb-kolom { height: 132px; gap: 4px; }
.mfb-lb-kt { border-radius: 999px; background: repeating-linear-gradient(135deg, rgba(127, 127, 127, .20) 0 2px, rgba(127, 127, 127, .05) 2px 6px); }
.mfb-lb-kt .mfb-lb-k { border-radius: 999px; opacity: 1; background: linear-gradient(180deg, #EBD496 0%, #D2B565 100%); }
.mfb-lb-kt:hover .mfb-lb-k, .mfb-lb-kt:focus .mfb-lb-k { background: linear-gradient(180deg, #E3C26B 0%, #A8852E 100%); }
.mfb-lb-kt-puncak .mfb-lb-k, .mfb-lb-kt-puncak:hover .mfb-lb-k, .mfb-lb-kt-puncak:focus .mfb-lb-k { background: linear-gradient(180deg, #3A3326 0%, #16140F 100%); box-shadow: 0 6px 14px rgba(22, 20, 15, .28); }
body.dark-mode .mfb-lb-kt .mfb-lb-k { background: linear-gradient(180deg, #7A6A3C 0%, #4A4130 100%); }
body.dark-mode .mfb-lb-kt-puncak .mfb-lb-k { background: linear-gradient(180deg, #F3D98A 0%, #E3C26B 100%); box-shadow: 0 0 14px rgba(227, 194, 107, .35); }
@media (max-width: 480px) { .mfb-lb-kolom { gap: 2px; height: 112px; } }
/* Gauge kantor — 41 tik, yang menyala bergradasi lewat --t (0–1) dari mfb-ui.js. Tanpa dukungan calc → tetap emas penuh. */
.mfb-lb-gauge { width: min(280px, 100%); }
.mfb-lb-tik { stroke-width: 3.2; stroke: rgba(127, 127, 127, .22); }
.mfb-lb-tik-on { stroke: #A8852E; opacity: calc(.4 + var(--t, 1) * .6); }
body.dark-mode .mfb-lb-tik-on { stroke: #E3C26B; }
.mfb-lb-login .mfb-lb-besar { font: 800 44px/1 Inter, system-ui, sans-serif; letter-spacing: -.02em; font-variant-numeric: lining-nums tabular-nums; margin-top: -60px; margin-bottom: 18px; }
/* Quiet for 7 days — matriks titik (satu titik = satu staff, yang diam terisi). */
.mfb-lb-titikdaftar { gap: 14px; }
.mfb-lb-tbaris { display: flex; flex-direction: column; gap: 6px; }
.mfb-lb-tatas { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; font-size: 13.5px; }
.mfb-lb-titik { display: grid; grid-template-columns: repeat(auto-fill, 12px); gap: 4px; }
.mfb-lb-titik i { width: 12px; height: 12px; border-radius: 3px; background: repeating-linear-gradient(135deg, rgba(127, 127, 127, .24) 0 2px, rgba(127, 127, 127, .08) 2px 4px); }
.mfb-lb-titik i.mfb-lb-ton { background: linear-gradient(135deg, #D2693A 0%, #A9461B 100%); box-shadow: 0 2px 5px rgba(169, 70, 27, .3); }
body.dark-mode .mfb-lb-titik i.mfb-lb-ton { background: linear-gradient(135deg, #F4A07A 0%, #E07A4E 100%); }
@media (prefers-reduced-motion: reduce) { .mfb-lb-titik i { transition: none; } }

/* v1.116 (2.250) — dua cacat tampilan yang dilaporkan 3 Okt, disetujui IT Manager 18:36 ("ikut diperbaiki"). */
/* D120 — Manage Courses tampilan DAFTAR: ringkasan "n done · n in progress · …" (2.224) tidak punya grid-area,
   jadi browser menaruhnya di sel kosong pertama = kolom ikon 40 px → teks terjepit satu kata per baris.
   Diberi tempat sendiri: baris ketiga, di bawah judul sampai kolom status. */
#desk .mfb-kc-daftar .mfb-kc-tugas,
#desk .mfb-kc-daftar .mfb-kc-orang { grid-column: 2 / 5; grid-row: 3; margin: 6px 0 2px; max-width: 420px; }
/* Tiga susunan grid (lihat @media 1280–1559 & 900–1279 di atas): baris pertama yang KOSONG berbeda per lebar —
   di 1280–1559 departemen menempati baris 3, di 900–1279 isian sampai baris 5. Diukur di Chrome 1600/1440/1100. */
@media (min-width: 1280px) and (max-width: 1559px) {
  #desk .mfb-kc-daftar .mfb-kc-tugas, #desk .mfb-kc-daftar .mfb-kc-orang { grid-row: 4; grid-column: 2 / 4; }
}
@media (min-width: 900px) and (max-width: 1279px) {
  #desk .mfb-kc-daftar .mfb-kc-tugas, #desk .mfb-kc-daftar .mfb-kc-orang { grid-row: 6; grid-column: 2 / 4; }
}
/* D119 — kartu Learning Streak di HP memakai kelas kartu desktop (.card) yang di #mob tidak bergaya:
   judul menempel ke "LAST 12 WEEKS" dan kartu tanpa bingkai/padding. Disamakan dengan kartu HP lain. */
#mob .mfb-heat-kartu { margin: 16px 16px 0; background: var(--white, #FFFFFF); border: 1px solid var(--gray-100, #ECE8DF); border-radius: 18px; overflow: hidden; }
#mob .mfb-heat-kartu .card-header { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 16px 16px 6px; }
#mob .mfb-heat-kartu .card-title { font-family: Georgia, 'Times New Roman', serif; font-size: 16px; font-weight: 700; letter-spacing: 0.01em; color: var(--black, #16140F); }
body.dark-mode #mob .mfb-heat-kartu { background: #15171D; border-color: rgba(255, 255, 255, 0.08); }
body.dark-mode #mob .mfb-heat-kartu .card-title { color: #F4F1EA; }

/* v1.117 (rilis 2.251) — permintaan IT Manager 3 Okt 21:33–21:41.
   (1) All Courses: kepala tabel gelap (sama dengan kepala daftar Manage Courses) + judul kelompok departemen. */
#desk .mfb-kat-tabel thead th { background: #16140F; color: #E3C26B; border-bottom: 1px solid #C9A84C; opacity: 1; }
body.dark-mode #desk .mfb-kat-tabel thead th { background: #050505; }
.mfb-kat-tabel tr.mfb-kat-grup th { text-align: left; padding: 10px 14px; background: var(--gray-50, #F7F5F0); border-bottom: 1px solid var(--gray-100, #E8E8E8);
  font: 700 12px 'Inter', system-ui, sans-serif; letter-spacing: .08em; text-transform: uppercase; color: #6B6761; }
.mfb-kat-tabel tr.mfb-kat-grup th > .mfb-kat-n { margin-left: 10px; letter-spacing: 0; text-transform: none; }
body.dark-mode .mfb-kat-tabel tr.mfb-kat-grup th { background: rgba(255, 255, 255, .04); color: #C8C2B6; border-bottom-color: rgba(255, 255, 255, .08); }
@media (max-width: 899px) {
  .mfb-sl-tabel tr.mfb-kat-grup { border: 0; padding: 0; margin: 14px 0 6px; }
  .mfb-kat-tabel tr.mfb-kat-grup th { display: block; padding: 4px 2px; background: none; border: 0; }
}
/* (2) Reports "What needs your attention": baris sejajar dengan judul kartu (dulu 4 px dari tepi). */
#desk .mfb-perhatian .mfb-perhatian-item { padding-left: var(--mfb-kartu-x, 28px); padding-right: var(--mfb-kartu-x, 28px); }
#desk .mfb-perhatian > .mfb-perhatian-sebab, #desk .mfb-perhatian .mfb-perhatian-daftar + .mfb-perhatian-sebab,
#desk .mfb-perhatian .mfb-perhatian-aman { padding-left: var(--mfb-kartu-x, 28px); padding-right: var(--mfb-kartu-x, 28px); }
/* (3) Activity Log: lencana NORMAL / WARNING / CRITICAL satu baris. */
#desk .log-flag, #mob .log-flag-m { white-space: nowrap; }
/* (4) Learning behaviour: kartu sebaris sama tinggi (simetris). */
.mfb-lb-grid { align-items: stretch; }
/* (5) Paging daftar panjang — Manage Courses, Employee List, All Courses (10/15/20/50 per halaman). */
.mfb-hal-luar { display: none !important; }
.mfb-hal { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 16px; margin: 14px 0 4px; font: 13px 'Inter', system-ui, sans-serif; }
.mfb-hal[hidden] { display: none; }
#d-cmgmt-grid + .mfb-hal { grid-column: 1 / -1; }
.mfb-hal-info { color: var(--gray-500, #6E6E6E); font-weight: 600; }
.mfb-hal-tombol { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }   /* SOP §15: jarak ≥ 8 px */
.mfb-hal-b { min-width: 44px; min-height: 44px; padding: 0 12px; border-radius: 10px; border: 1.5px solid #D9BE72; background: #FFFBF0;
  color: #2A2108; font: 700 13px 'Inter', system-ui, sans-serif; cursor: pointer; box-shadow: 0 2px 0 #D9BE72; }
.mfb-hal-b:hover:not(:disabled) { background: #F6E7BE; }
.mfb-hal-b[aria-current="page"] { background: #16140F; border-color: #16140F; color: #E3C26B; box-shadow: none; opacity: 1; cursor: default; }
.mfb-hal-b:disabled:not([aria-current]) { opacity: .4; cursor: default; box-shadow: none; }
.mfb-hal-b:focus-visible, .mfb-hal-uk select:focus-visible { outline: 3px solid #C9A84C; outline-offset: 2px; }
.mfb-hal-elip { padding: 0 2px; color: var(--gray-500, #6E6E6E); }
.mfb-hal-uk { display: inline-flex; align-items: center; gap: 6px; color: var(--gray-600, #5C5A56); }
.mfb-hal-uk select { min-height: 44px; padding: 0 10px; border-radius: 10px; border: 1.5px solid rgba(127, 127, 127, .4); background: transparent; color: inherit; font: 600 13px 'Inter', system-ui, sans-serif; }
body.dark-mode .mfb-hal-b { background: rgba(227, 194, 107, .08); border-color: rgba(227, 194, 107, .45); color: #F0E3BE; box-shadow: 0 2px 0 rgba(227, 194, 107, .35); }
body.dark-mode .mfb-hal-b[aria-current="page"] { background: #E3C26B; border-color: #E3C26B; color: #0A0A0A; }
body.dark-mode .mfb-hal-info, body.dark-mode .mfb-hal-uk, body.dark-mode .mfb-hal-elip { color: #C8C2B6; }
body.dark-mode .mfb-hal-uk select option { background: #1A1A1A; }
/* (6) Manage Users HP: tombol aksi berwarna (dulu putih rata semua). Baseline memakai style inline → !important. */
#m-users-content .team-item-m button[onclick*="ditUser"], #m-users-content .team-item-m button[onclick*="lockUser"],
#m-users-content .team-item-m button[onclick*="ctivateUser"], #m-users-content .team-item-m button[onclick*="resetUserPassword"] {
  min-height: 44px !important; border-radius: 10px !important; font-weight: 700 !important; }   /* SOP MFB v2.12 §15: ≥ 44×44 px */
#m-users-content .team-item-m button[onclick*="editUser"] { background: linear-gradient(180deg, #FFF8E6, #F1DFAE) !important; border-color: #C9A84C !important; color: #3A2C08 !important; box-shadow: 0 2px 0 #C9A84C !important; }
#m-users-content .team-item-m button[onclick*="(lockUser"], #m-users-content .team-item-m button[onclick*=";lockUser"] { background: #FFF1DB !important; border-color: #E0A84A !important; color: #6B4600 !important; box-shadow: 0 2px 0 #E0A84A !important; }
#m-users-content .team-item-m button[onclick*="deactivateUser"] { background: #FDECEC !important; border-color: #E59B9B !important; color: #8E1B1B !important; box-shadow: 0 2px 0 #E59B9B !important; }
#m-users-content .team-item-m button[onclick*="reactivateUser"] { background: #E5F4EA !important; border-color: #86C49E !important; color: #1F5E3B !important; box-shadow: 0 2px 0 #86C49E !important; }
#m-users-content .team-item-m button[onclick*="resetUserPassword"] { background: #EAF0F8 !important; border-color: #9DB2CF !important; color: #1F3A5F !important; box-shadow: 0 2px 0 #9DB2CF !important; }
#m-users-content .team-item-m button:active { transform: translateY(2px); box-shadow: none !important; }
body.dark-mode #m-users-content .team-item-m button[onclick*="editUser"] { background: rgba(227, 194, 107, .16) !important; color: #F0E3BE !important; }
body.dark-mode #m-users-content .team-item-m button[onclick*=";lockUser"] { background: rgba(224, 168, 74, .16) !important; color: #F6D59A !important; }
body.dark-mode #m-users-content .team-item-m button[onclick*="deactivateUser"] { background: rgba(229, 155, 155, .14) !important; color: #F5B5B5 !important; }
body.dark-mode #m-users-content .team-item-m button[onclick*="reactivateUser"] { background: rgba(134, 196, 158, .14) !important; color: #A9E2BF !important; }
body.dark-mode #m-users-content .team-item-m button[onclick*="resetUserPassword"] { background: rgba(157, 178, 207, .14) !important; color: #C9D7EA !important; }
/* (7) Bilah bawah HP: menu aktif diberi alas berwarna, bukan hanya warna ikon. */
#mob .bnav-item.active { background: linear-gradient(180deg, #FBF1D6 0%, #F1DFAE 100%); border-radius: 14px; box-shadow: inset 0 0 0 1px rgba(201, 168, 76, .55); }
body.dark-mode #mob .bnav-item.active { background: rgba(227, 194, 107, .16); box-shadow: inset 0 0 0 1px rgba(227, 194, 107, .4); }
/* (8) My Profile: Change Password terlipat sampai tombol Edit password ditekan. */
.mfb-pw-tutup .profile-section-body > :not(.mfb-pw-edit-bar),
.mob-form-card.mfb-pw-tutup > :not(.prof-section-title):not(.mfb-pw-edit-bar),
.mob-form-card.mfb-pw-tutup + .btn-full { display: none !important; }
.mfb-pw-edit-bar { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
/* v1.123 (rilis 2.256) — saat TERBUKA keterangan di bawah tombol disembunyikan, jadi label "CURRENT PASSWORD"
   menempel ke bayangan 3D tombol Cancel (foto HP IT Manager 5 Okt). Jarak hanya saat terbuka. */
.profile-section:not(.mfb-pw-tutup) .mfb-pw-edit-bar,
.mob-form-card:not(.mfb-pw-tutup) > .mfb-pw-edit-bar { margin-bottom: 18px; }
.mfb-pw-edit { min-height: 44px; padding: 0 18px; border-radius: 10px; border: 1.5px solid #A8842F; color: #2A2108; cursor: pointer;
  font: 700 13.5px 'Inter', system-ui, sans-serif; background: linear-gradient(180deg, #FFF8E6 0%, #F1DFAE 100%); box-shadow: 0 3px 0 #A8842F; }
.mfb-pw-edit:active { transform: translateY(2px); box-shadow: 0 1px 0 #A8842F; }
.mfb-pw-edit:focus-visible { outline: 3px solid #C9A84C; outline-offset: 2px; }
.mfb-pw-ket { font-size: 12.5px; color: var(--gray-500, #6E6E6E); }
body.dark-mode .mfb-pw-edit { background: rgba(227, 194, 107, .14); color: #F0E3BE; border-color: rgba(227, 194, 107, .55); box-shadow: 0 3px 0 rgba(227, 194, 107, .35); }
body.dark-mode .mfb-pw-ket { color: #C8C2B6; }
/* (9) My Profile: tombol WA Caption di bawah (di atas Sign Out), tidak mepet tepi di HP. */
#m-profile-content .mfb-cap-profil { padding: 0 16px; margin: 0 0 4px; }
#m-profile-content .mfb-cap-profil .mfb-set-simpan { width: 100%; min-height: 48px; }

/* (10) Paging: lihat helper halamanDaftar di mfb-ui.js. */
/* (11) Login HP tidak bisa digulir (IT Manager 3 Okt 21:47 "sebelumnya sudah gitu"). Akar: min-height 100dvh
   DITAMBAH padding safe-area (status bar HP, viewport-fit=cover) → selalu lebih tinggi dari layar. border-box
   memasukkan padding ke dalam 100dvh; layar pendek dirapatkan sedikit supaya isinya muat. */
#mob #m-login { box-sizing: border-box; }
@media (max-width: 899px) and (max-height: 900px) {
  #mob .mob-login-top { padding-top: 12px; padding-bottom: 16px; }
  #mob .mob-login-brand { margin-top: 8px; }
  #mob .mob-login-tagline { margin-top: 8px; }
  #mob .mob-login-card { padding-top: 26px; padding-bottom: 26px; }
}
/* (12) Tautan check-in di login jadi tombol kecil berlatar (IT Manager 3 Okt 21:59 "kurang mencolok"). */
.mfb-checkin-login { width: fit-content; margin: 14px auto 0; padding: 0 20px; border: 1.5px solid #C9A84C; border-radius: 999px;
  background: linear-gradient(180deg, #FBF1D6 0%, #F1DFAE 100%); color: #4A3708; font-weight: 700; box-shadow: 0 2px 0 #C9A84C; }
.mfb-checkin-login:hover { text-decoration: none; background: linear-gradient(180deg, #FFF6DF 0%, #EBD496 100%); }
.mfb-checkin-login:active { transform: translateY(2px); box-shadow: none; }
body.dark-mode .mfb-checkin-login { background: rgba(227, 194, 107, .16); color: #F0E3BE; border-color: rgba(227, 194, 107, .6); box-shadow: 0 2px 0 rgba(227, 194, 107, .4); }
/* (13) Latar login laptop: buku terbuka + toga bergaris emas di tengah cincin (IT Manager 3 Okt 21:59 "buku? mengenai learning").
   Di ::after .login-left-bg (TIDAK ikut berputar seperti cincin), titik tengah sama dengan .deco-circle (52% / 50%). */
#desk .login-left-bg::after { content: ''; position: absolute; top: 50%; left: 52%; transform: translate(-50%, -50%);
  width: clamp(170px, 14vw, 270px); aspect-ratio: 6 / 5; opacity: .5; pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 200' fill='none' stroke='%23C9A84C' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M120 62c-22-14-52-18-86-14v104c34-4 64 0 86 14 22-14 52-18 86-14V48c-34-4-64 0-86 14z' stroke-width='2.2'/%3E%3Cpath d='M120 62v104' stroke-width='2'/%3E%3Cpath d='M48 70c20-2 40 1 58 9M48 86c20-2 40 1 58 9M48 102c20-2 40 1 58 9M48 118c20-2 40 1 58 9' stroke-width='1.3' opacity='.7'/%3E%3Cpath d='M192 70c-20-2-40 1-58 9M192 86c-20-2-40 1-58 9M192 102c-20-2-40 1-58 9M192 118c-20-2-40 1-58 9' stroke-width='1.3' opacity='.7'/%3E%3Cpath d='M120 14l40 15-40 15-40-15z' stroke-width='2'/%3E%3Cpath d='M96 35v12c14 8 34 8 48 0V35' stroke-width='1.8'/%3E%3Cpath d='M160 29v18' stroke-width='1.6'/%3E%3Ccircle cx='160' cy='50' r='2.6' fill='%23C9A84C'/%3E%3Cpath d='M30 40l3 7 7 3-7 3-3 7-3-7-7-3 7-3z' stroke-width='1.2' opacity='.8'/%3E%3Cpath d='M212 138l2 5 5 2-5 2-2 5-2-5-5-2 5-2z' stroke-width='1.2' opacity='.8'/%3E%3C/svg%3E") center / contain no-repeat; }
@media (prefers-reduced-motion: no-preference) {
  #desk .login-left-bg::after { animation: mfb-buku-napas 6s ease-in-out infinite; }
}
@keyframes mfb-buku-napas { 0%, 100% { opacity: .42; } 50% { opacity: .6; } }
/* (14) Judul kartu berlatar (IT Manager 3 Okt 22:01 "semua title buatin fillnya, agar eye catching"). */
#desk .card > .card-header { background: linear-gradient(180deg, #FBF5E6 0%, #F4EAD0 100%); border-bottom-color: rgba(201, 168, 76, .35);
  border-top-left-radius: inherit; border-top-right-radius: inherit; }
body.dark-mode #desk .card > .card-header { background: linear-gradient(180deg, rgba(227, 194, 107, .10), rgba(227, 194, 107, .05)); border-bottom-color: rgba(227, 194, 107, .25); }
#desk .att-side-title { margin: -20px -20px 14px; padding: 13px 20px; border-radius: 14px 14px 0 0; color: #6B5418;
  background: linear-gradient(180deg, #FBF5E6 0%, #F4EAD0 100%); border-bottom: 1px solid rgba(201, 168, 76, .35); }
body.dark-mode #desk .att-side-title { color: #E3C26B; background: rgba(227, 194, 107, .08); border-bottom-color: rgba(227, 194, 107, .25); }
.mfb-lb-kartu > .mfb-lb-kjudul { margin: -20px -20px 12px; padding: 14px 20px; border-radius: 18px 18px 0 0;
  background: linear-gradient(180deg, #FBF5E6 0%, #F4EAD0 100%); border-bottom: 1px solid rgba(201, 168, 76, .35); }
body.dark-mode .mfb-lb-kartu > .mfb-lb-kjudul { background: rgba(227, 194, 107, .08); border-bottom-color: rgba(227, 194, 107, .25); }
/* (11b) Layar HP pendek (≤ 800 px, mis. 360×780): logo sedikit lebih kecil supaya seluruh login muat tanpa gulir. */
@media (max-width: 899px) and (max-height: 800px) {
  #mob .mob-login-top > img { width: 140px !important; }
  #mob .mob-login-top { padding-top: 8px; padding-bottom: 14px; }
  #mob .mob-login-card { padding-top: 18px; padding-bottom: 14px; }
  #mob .mob-login-card .mfb-checkin-login { margin-top: 10px; }
  #mob .mob-login-brand { font-size: 23px; }
  #mob .mob-login-tagline { font-size: 13px; line-height: 1.5; }
}
/* (15) Manage Users HP: tombol tidak terjepit (ikon turun ke baris sendiri) → boleh pindah baris, teks 1 baris. */
#m-users-content .team-item-m > div[style*="width:100%"] { flex-wrap: wrap !important; }
#m-users-content .team-item-m > div[style*="width:100%"] > button { flex: 1 1 auto; white-space: nowrap; padding: 0 14px !important; }
/* Avatar inisial di HP: warna sama dengan desktop (uav1–6 baseline hanya #desk → di HP polos tanpa latar). */
#mob .uav1 { background: linear-gradient(135deg, #C9A065, #A07840); color: #0A0A0A; }
#mob .uav2 { background: linear-gradient(135deg, #6EE7B7, #059669); color: #065F46; }
#mob .uav3 { background: linear-gradient(135deg, #93C5FD, #3B82F6); color: #1E3A8A; }
#mob .uav4 { background: linear-gradient(135deg, #FCA5A5, #EF4444); color: #7F1D1D; }
#mob .uav5 { background: linear-gradient(135deg, #C4B5FD, #7C3AED); color: #3B0764; }
#mob .uav6 { background: var(--gray-100, #EFEDE8); color: var(--gray-500, #6E6E6E); }
/* (16) AI Report HP: tombol aksi menempel tepi layar (padding 0) → jarak 16 px seperti isi halaman. */
#mob .mfb-air-aksi { padding: 0 16px; }
#mob .mfb-air-aksi + .mfb-lb-buka, #mob .mfb-lb-buka { margin-left: 16px; margin-right: 16px; }
/* (17) Konfirmasi sebelum Start Quiz. */
.mfb-kuis-siap { padding: 4px 2px 2px; font: 14px/1.55 'Inter', system-ui, sans-serif; }
.mfb-kuis-siap-lead { margin: 0 0 10px; font-weight: 700; }
.mfb-kuis-siap-daftar { margin: 0 0 18px; padding-left: 20px; }
.mfb-kuis-siap-daftar li + li { margin-top: 6px; }
.mfb-kuis-siap-aksi { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px; }
/* (18) My Courses HP: 4 pil saringan dulu baris geser → "Completed" terpotong di tepi kanan (audit tepi 3 Okt).
   Kini 4 kolom selebar isi halaman: semua pil terlihat, simetris, tanpa digeser. */
#mob #m-course-filters { display: grid; grid-template-columns: auto repeat(3, minmax(0, 1fr)); gap: 8px;   /* SOP §15: jarak ≥ 8 px */ overflow: visible; padding-left: 16px; padding-right: 16px; }
#mob #m-course-filters > .pill-m { padding: 0 8px; min-width: 44px; overflow: hidden; text-overflow: ellipsis; }   /* SOP §15: pil All ≥ 44 px */
/* (19) Daftar hadir event tampil satu layar penuh seperti halaman (bukan pop up kecil). */
.mfb-dlg-tirai.mfb-dlg-tirai-penuh { padding: 0; background: var(--gray-50, #F7F5F0); align-items: stretch; }
body.dark-mode .mfb-dlg-tirai.mfb-dlg-tirai-penuh { background: #0A0A0A; }
.mfb-dlg.mfb-dlg-penuh { max-width: none; height: 100vh; height: 100dvh; max-height: none; border-radius: 0; box-shadow: none;
  padding: 20px clamp(16px, 5vw, 64px) calc(28px + env(safe-area-inset-bottom, 0px)); }
.mfb-dlg-penuh > .mfb-dlg-kepala { position: sticky; top: -20px; z-index: 2; margin: -20px calc(-1 * clamp(16px, 5vw, 64px)) 16px;
  padding: 14px clamp(16px, 5vw, 64px); background: linear-gradient(180deg, #16140F 0%, #0F0E0B 100%); border-bottom: 1px solid #C9A84C;
  justify-content: flex-start; padding-top: calc(14px + env(safe-area-inset-top, 0px)); }
.mfb-dlg-penuh > .mfb-dlg-kepala h2 { color: #F3E7C4; }
.mfb-dlg-penuh > .mfb-dlg-kepala .mfb-dlg-x { order: -1; width: auto; border-radius: 10px; padding: 0 14px; font: 700 14px 'Inter', system-ui, sans-serif;
  color: #E3C26B; border-color: rgba(227, 194, 107, .55); background: rgba(227, 194, 107, .08); white-space: nowrap; }
.mfb-dlg-penuh > .mfb-dlg-kepala .mfb-dlg-x:focus-visible { outline: 3px solid #E3C26B; outline-offset: 2px; }
/* (20) Attendance desktop: judul kelompok per jenis event. */
#desk .mfb-ev-grup { display: flex; align-items: center; gap: 10px; padding: 10px 20px; background: linear-gradient(180deg, #FBF5E6 0%, #F4EAD0 100%);
  border-bottom: 1px solid rgba(201, 168, 76, .35); font: 700 12px 'Inter', system-ui, sans-serif; letter-spacing: .08em; text-transform: uppercase; color: #6B5418; }
#desk .mfb-ev-grup + .event-item { border-top: 0; }
body.dark-mode #desk .mfb-ev-grup { background: rgba(227, 194, 107, .08); color: #E3C26B; border-bottom-color: rgba(227, 194, 107, .25); }
/* (21) Attendance HP: judul kelompok per jenis event (D126). */
#mob .att-event-list > .mfb-ev-grup { display: flex; align-items: center; gap: 10px; margin: 6px 0 0;   /* wadah sudah padding 16 px → sejajar kartu */ padding: 9px 14px; border-radius: 10px;
  background: linear-gradient(180deg, #FBF5E6 0%, #F4EAD0 100%); border: 1px solid rgba(201, 168, 76, .35);
  font: 700 12px 'Inter', system-ui, sans-serif; letter-spacing: .08em; text-transform: uppercase; color: #6B5418; }
body.dark-mode #mob .att-event-list > .mfb-ev-grup { background: rgba(227, 194, 107, .08); color: #E3C26B; border-color: rgba(227, 194, 107, .25); }
/* (22) Push News di lonceng (D123) + My notes di Profile (D124). */
.mfb-berita-form-w { margin: 0 0 14px; }
.mfb-berita-form textarea, .mfb-catatan-isi { width: 100%; box-sizing: border-box; min-height: 96px; padding: 10px 12px; border-radius: 10px;
  border: 1.5px solid rgba(127, 127, 127, .4); background: transparent; color: inherit; font: 14px/1.5 'Inter', system-ui, sans-serif; resize: vertical; }
.mfb-berita-form textarea:focus-visible, .mfb-catatan-isi:focus-visible { outline: 3px solid #C9A84C; outline-offset: 1px; }
.mfb-berita-ket { margin: 12px 0 0; font-size: 13px; font-weight: 600; color: #6B5418; }
.mfb-berita-untuk { padding: 2px 8px; border-radius: 999px; background: rgba(201, 168, 76, .16); color: #6B5418; font-size: 11.5px; font-weight: 700; }
.mfb-berita-kosong { margin: 6px 0 0; color: var(--gray-500, #6E6E6E); }
.mfb-berita-hapus { margin-top: 8px; min-height: 44px; padding: 0 14px; border-radius: 10px; border: 1.5px solid #E59B9B; background: #FDECEC; color: #8E1B1B;
  font: 700 13px 'Inter', system-ui, sans-serif; cursor: pointer; }
.mfb-berita-hapus:focus-visible { outline: 3px solid #8E1B1B; outline-offset: 2px; }
body.dark-mode .mfb-berita-ket, body.dark-mode .mfb-berita-untuk { color: #E3C26B; }
body.dark-mode .mfb-berita-hapus { background: rgba(229, 155, 155, .14); color: #F5B5B5; }
.mfb-catatan { margin: 16px 0; padding: 18px 20px; border-radius: 14px; border: 1px solid rgba(127, 127, 127, .28); background: var(--white, #FFFFFF); }
#m-profile-content .mfb-catatan { margin: 0 16px 16px; }
.mfb-catatan-judul { margin: -18px -20px 12px; padding: 13px 20px; border-radius: 14px 14px 0 0; font: 700 15px 'Inter', system-ui, sans-serif;
  background: linear-gradient(180deg, #FBF5E6 0%, #F4EAD0 100%); border-bottom: 1px solid rgba(201, 168, 76, .35); color: #3A2C08; }
.mfb-catatan-ket { margin: 0 0 10px; font-size: 13px; color: var(--gray-500, #6E6E6E); }
.mfb-catatan-bawah { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; margin-top: 10px; }
.mfb-catatan-info { font-size: 12.5px; color: var(--gray-500, #6E6E6E); }
body.dark-mode .mfb-catatan { background: #14151B; border-color: rgba(212, 175, 55, .15); }
body.dark-mode .mfb-catatan-judul { background: rgba(227, 194, 107, .08); color: #F0E3BE; border-bottom-color: rgba(227, 194, 107, .25); }
body.dark-mode .mfb-catatan-ket, body.dark-mode .mfb-catatan-info { color: #C8C2B6; }
/* (23) Lonceng berita di topbar HP (D123) + titik "berita baru" jujur (laptop & HP). */
#mob .mfb-lonceng-hp { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 12px;
  color: #E3C26B; background: rgba(227, 194, 107, .10); border: 1px solid rgba(227, 194, 107, .35); cursor: pointer; flex: 0 0 auto; }
#mob .mfb-lonceng-hp:focus-visible { outline: 3px solid #E3C26B; outline-offset: 2px; }
#mob .mfb-lonceng-hp .notif-dot { position: absolute; top: 9px; right: 10px; width: 8px; height: 8px; border-radius: 50%; background: #E5484D; box-shadow: 0 0 0 2px #16140F; display: none; }
body.mfb-berita-siap .topbar-icon-btn[data-mfb-berita] .notif-dot { display: none; }
body.mfb-berita-siap.mfb-berita-ada .topbar-icon-btn[data-mfb-berita] .notif-dot { display: block; }
body.mfb-berita-siap.mfb-berita-ada #mob .topbar-icon-btn[data-mfb-berita] .notif-dot { display: block; }   /* #mob perlu: aturan dasar HP memakai id (lebih spesifik) */
/* (24) Poin belajar (D104): kartu Profile + baris Dashboard staff. */
.mfb-poin { margin: 16px 0; padding: 18px 20px; border-radius: 14px; border: 1px solid rgba(127, 127, 127, .28); background: var(--white, #FFFFFF); }
#m-profile-content .mfb-poin { margin: 0 16px 16px; }
.mfb-poin-besar { margin: 0 0 4px; font-size: 15px; color: var(--gray-500, #6E6E6E); }
.mfb-poin-besar b { font: 700 34px Georgia, 'Times New Roman', serif; color: #3A2C08; margin-right: 4px; }
.mfb-poin-sub { margin: 10px 0 6px; font-weight: 700; font-size: 13.5px; }
.mfb-poin-syarat { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.mfb-poin-syarat li { display: flex; align-items: center; gap: 10px; font-size: 14px; }
.mfb-poin-tanda { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 50%;
  border: 1.5px solid rgba(127, 127, 127, .5); font-weight: 800; font-size: 13px; color: var(--gray-500, #6E6E6E); flex: 0 0 auto; }
.mfb-poin-ok .mfb-poin-tanda { background: #E5F4EA; border-color: #86C49E; color: #1F5E3B; }
.mfb-poin-rinci { margin-top: 12px; font-size: 13.5px; }
.mfb-poin-rinci summary { min-height: 44px; display: flex; align-items: center; cursor: pointer; font-weight: 700; color: #6B5418; }
.mfb-poin-rinci ul { margin: 0; padding-left: 18px; }
.mfb-poin-rinci li + li { margin-top: 4px; }
.mfb-poin-baris { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 48px; margin: 0 0 16px; padding: 10px 16px; border-radius: 14px;
  border: 1px solid rgba(201, 168, 76, .45); background: linear-gradient(180deg, #FBF5E6 0%, #F4EAD0 100%); color: #3A2C08; cursor: pointer;
  font: 600 14px 'Inter', system-ui, sans-serif; text-align: left; box-sizing: border-box; }
#m-dashboard-content .mfb-poin-baris { width: calc(100% - 32px); margin: 0 16px 16px; }
.mfb-poin-baris:focus-visible { outline: 3px solid #C9A84C; outline-offset: 2px; }
.mfb-poin-ikon { color: #A8842F; font-size: 18px; }
.mfb-poin-teks { flex: 1 1 auto; min-width: 0; }
.mfb-poin-panah { font-size: 20px; color: #8A6A1F; }
body.dark-mode .mfb-poin { background: #14151B; border-color: rgba(212, 175, 55, .15); }
body.dark-mode .mfb-poin-besar b { color: #F0E3BE; }
body.dark-mode .mfb-poin-baris { background: rgba(227, 194, 107, .10); color: #F0E3BE; border-color: rgba(227, 194, 107, .35); }
body.dark-mode .mfb-poin-ok .mfb-poin-tanda { background: rgba(134, 196, 158, .16); color: #A9E2BF; }
/* v1.118 (rilis 2.251, 4 Okt) — (25) Topbar HP: blok judul jadi anggota FLEX di antara logo & sisi kanan (dulu absolute di tengah layar →
   menabrak lonceng baru dan tombol "+ Add" Manage Users — 29 tabrakan di 360/390/414, uji Chrome 4 Okt).
   Kini judul hanya memakai ruang yang tersisa, teks terlalu panjang diberi "…"; tidak mungkin bertabrakan. */
#mob .inner-topbar > .it-center-block { position: static; left: auto; transform: none; flex: 1 1 auto; min-width: 0; margin: 0 8px; }
#mob .inner-topbar > .it-center-block > .it-eyebrow, #mob .inner-topbar > .it-center-block > .it-title { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 420px) { #mob .inner-topbar .it-eyebrow { letter-spacing: 0.06em; text-indent: 0; font-size: 10px; } }
#mob .inner-topbar > .it-left, #mob .inner-topbar > .it-right { flex-shrink: 0; } /* logo 69 px tidak boleh menyusut (360 px: .it-left jadi 58 px → logo meluber ke judul) */
/* ≤ 420 px: ruang judul dilebarkan sampai batas SOP (gutter 16, jarak tombol 8) + ukuran judul mengikuti lebar layar → judul utuh, tanpa "…". */
@media (max-width: 420px) {
  #mob .inner-topbar { padding-left: 16px; padding-right: 16px; }
  #mob .inner-topbar > .it-right { gap: 8px; }
  #mob .inner-topbar > .it-center-block { margin: 0 6px; }
  #mob .inner-topbar .it-title { font-size: clamp(13px, 3.75vw, 15px); }
}
/* Judul panjang ("Learning behaviour", "Manage Courses") turun ke baris ke-2 — maks 2 baris — daripada terpotong "…". */
#mob .inner-topbar > .it-center-block > .it-title { white-space: normal; line-height: 1.15; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow-wrap: anywhere; }

/* v1.119 (rilis 2.252, D156) — (26) Activity Log: kotak cari + halaman. Tombol memakai .mfb-hal-b (44 px, jarak 8 px). */
.mfb-log-cari { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 0 0 14px; }
.mfb-log-cari input { flex: 1 1 260px; min-width: 0; min-height: 44px; padding: 0 14px; border-radius: 10px; border: 1.5px solid #D9BE72; background: #FFFDF7; color: #16140F; font: 15px 'Inter', system-ui, sans-serif; }
.mfb-log-cari input:focus-visible { outline: 3px solid #D4AF37; outline-offset: 2px; }
#m-actlog-content .mfb-log-cari, #m-actlog-content .mfb-hal { margin-left: 16px; margin-right: 16px; }
body.dark-mode .mfb-log-cari input { background: #1A1C24; color: #F0F0F0; border-color: rgba(212, 175, 55, .45); }

/* v1.119 (rilis 2.252, D153) — (27) Skip link: di luar layar sampai menerima fokus Tab. */
.mfb-lewati { position: fixed; left: 12px; top: -80px; z-index: 2147483000; display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px; border-radius: 10px; background: #D4AF37; color: #08090C; font: 700 15px 'Inter', system-ui, sans-serif; text-decoration: none; box-shadow: 0 6px 20px rgba(0, 0, 0, .35); }
.mfb-lewati:focus, .mfb-lewati:focus-visible { top: 12px; outline: 3px solid #08090C; outline-offset: 2px; }
[tabindex="-1"]:focus { outline: none; }

/* v1.120 (rilis 2.253, D23 Usulan 5) — (28) Pemisah hero: garis emas MEMUDAR ke dua ujung + belah ketupat di tengah (──◆──).
   Dua bagian hero sama-sama overflow:hidden, jadi belah ketupatnya dibelah: segitiga atas = .mfb-hero-atas::before
   (bebas; ::after dipakai bingkai), segitiga bawah + garis = lapisan latar .mfb-hero-bawah (::before milik cahaya .ai-card). */
.mfb-hero-atas::before {
  content: ''; position: absolute; left: 50%; bottom: 0; transform: translateX(-50%); z-index: 2; pointer-events: none;
  border-left: 5px solid transparent; border-right: 5px solid transparent; border-bottom: 5px solid #C9A84C;
}
.mfb-hero-bawah {
  border-top-color: transparent;
  background:
    linear-gradient(90deg, rgba(201, 168, 76, 0) 0%, rgba(201, 168, 76, .6) 50%, rgba(201, 168, 76, 0) 100%) center top / 100% 1px no-repeat border-box,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='5'%3E%3Cpath d='M0 0h10L5 5z' fill='%23C9A84C'/%3E%3C/svg%3E") center 1px / 10px 5px no-repeat border-box,
    var(--mfb-chrome-bawah) !important;
}
body.dark-mode .mfb-hero-bawah {
  background:
    linear-gradient(90deg, rgba(201, 168, 76, 0) 0%, rgba(201, 168, 76, .6) 50%, rgba(201, 168, 76, 0) 100%) center top / 100% 1px no-repeat border-box,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='5'%3E%3Cpath d='M0 0h10L5 5z' fill='%23C9A84C'/%3E%3C/svg%3E") center 1px / 10px 5px no-repeat border-box,
    #111 !important;
}

/* v1.120 (rilis 2.253, D19) — (29) Tombol Bahasa Indonesia / English di baris "Back to Reports" AI Report. */
.air-back-row, #m-aireport-content div:has(> .air-back-btn) { flex-wrap: wrap; }
.mfb-ai-bahasa { margin-left: auto; min-height: 44px; padding: 0 16px; border-radius: 999px; border: 1px solid rgba(201, 168, 76, .7); background: transparent; color: inherit; font: 600 13px 'Inter', system-ui, sans-serif; cursor: pointer; }
.mfb-ai-bahasa[aria-pressed="true"] { background: rgba(201, 168, 76, .14); }
.mfb-ai-bahasa:focus-visible { outline: 3px solid #C9A84C; outline-offset: 2px; }
.mfb-ai-bahasa:disabled { opacity: .6; cursor: progress; }

/* v1.122 (rilis 2.255) — (30) Popup kabar menjaga baris baru (daftar login perangkat baru). */
.mfb-kabar p { white-space: pre-line; }

/* (32) v1.123 (rilis 2.256) — Reports HP, Department Summary: pita krem di nama departemen, warna sama dengan
   kepala kartu My notes (IT Manager 5 Okt, pop up). Markup baseline ber-style inline → disasar lewat struktur. */
#m-reports-content .section-header + div > div[style*="border-radius:14px"] { overflow: hidden; }
#m-reports-content .section-header + div > div[style*="border-radius:14px"] > div:first-child {
  margin: -14px -16px 12px !important; padding: 12px 16px;
  background: linear-gradient(180deg, #FBF5E6 0%, #F4EAD0 100%); border-bottom: 1px solid rgba(201, 168, 76, .35);
}
#m-reports-content .section-header + div > div[style*="border-radius:14px"] > div:first-child > div:first-child {
  font-size: 14px !important; font-weight: 700 !important; color: #3A2C08;
}
body.dark-mode #m-reports-content .section-header + div > div[style*="border-radius:14px"] > div:first-child {
  background: rgba(227, 194, 107, .08); border-bottom-color: rgba(227, 194, 107, .25);
}
body.dark-mode #m-reports-content .section-header + div > div[style*="border-radius:14px"] > div:first-child > div:first-child { color: #F0E3BE; }

/* (33) v1.123 (rilis 2.256) — Manage Users HP: pita gelap (avatar/foto, nama, ID, status) + tombol di bawah
   pada latar terang (IT Manager 5 Okt, pop up). Kepala dibungkus mfb-ui.js 6c. */
#m-users-content .team-item-m.mfb-um-kartu { padding: 0 !important; gap: 0 !important; overflow: hidden; }
#m-users-content .mfb-um-kepala { display: flex; align-items: center; gap: 12px; width: 100%; box-sizing: border-box; padding: 14px 16px;
  background: linear-gradient(135deg, #1A1C24 0%, #08090C 100%); border-bottom: 1px solid rgba(212, 175, 55, .3); }
#m-users-content .mfb-um-kepala .tm-info { flex: 1 1 auto; min-width: 0; }
#m-users-content .mfb-um-kepala .tm-name { color: #FFFFFF !important; }
#m-users-content .mfb-um-kepala .tm-meta { color: #C8C2B6 !important; }
#m-users-content .mfb-um-kepala > span[style*="--green"] { color: #7EE2A8 !important; }
#m-users-content .mfb-um-kepala > span[style*="--red"] { color: #FF9C9C !important; }
#m-users-content .mfb-um-kepala > span[style*="--gray"] { color: #C8C2B6 !important; }
#m-users-content .mfb-um-kepala .tm-av { box-shadow: 0 0 0 2px rgba(212, 175, 55, .65); }
#m-users-content .tm-av.mfb-um-foto { background-size: cover !important; background-position: center !important; color: transparent !important; }
#m-users-content .team-item-m.mfb-um-kartu > div:last-child { padding: 12px 16px 14px; margin-top: 0 !important; box-sizing: border-box; }

/* (34) v1.124 (D171, sapuan tampilan 5 Okt) — avatar topbar HP (membuka Profile) 34 px → area ketuk 44 px
   lewat ::after transparan; tampilannya tidak berubah. Toggle Settings & lencana kamera SUDAH 44+ px lewat ::after. */
#mob .mtb-avatar { position: relative; }
#mob .mtb-avatar::after { content: ''; position: absolute; inset: -5px; border-radius: 50%; }

/* (35) v1.125 (D177, MoM 05-10 #3–6) — KETERBACAAN MODE GELAP DI DESKTOP.
   Akar: body.dark-mode memberi latar tanpa `color`. HP sudah ditambal (`body.dark-mode #mob`, bagian 53) tetapi
   desktop belum, jadi teks tanpa warna sendiri (judul My Active Courses, Recent activity, daftar Learning points)
   mewarisi hitam peramban: 1,26 : 1 di atas #1E1E1E. Satu aturan yang sama untuk #desk. */
body.dark-mode #desk { color: var(--black); }
body.dark-mode .mfb-poin { color: #EDEAE3; }
body.dark-mode .mfb-poin-tanda { color: #C9C3B6; }
body.dark-mode .mfb-poin-rinci summary { color: #E3C26B; }

/* v1.141 (rilis 2.271, D240/D267) — badge Bronze/Silver/Gold di kartu poin Profile (mfb-ui.js kotakBadge) + dialog
   "🏅 Badges" di Reports (gambarPapanBadge). Warna teks lencana ≥ 7:1 di atas latarnya (AAA), terang & gelap. */
.mfb-bd { margin: 12px 0 4px; }
.mfb-bd-atas { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 0 0 10px; }
.mfb-bd-lencana { display: inline-flex; align-items: center; min-height: 32px; padding: 0 12px; border-radius: 999px; font: 700 14px Inter, system-ui, sans-serif; border: 1.5px solid; }
.mfb-bd-bronze { background: #F6E7DA; border-color: #B97A45; color: #4A2A10; }
.mfb-bd-silver { background: #EDEFF2; border-color: #8B939C; color: #262B31; }
.mfb-bd-gold   { background: #FBF0CF; border-color: #C9A84C; color: #3A2C08; }
.mfb-bd-kosong { background: transparent; border-color: rgba(127, 127, 127, .45); color: var(--gray-500, #595959); }
.mfb-bd-lagi { font-size: 13.5px; color: var(--gray-500, #595959); }
.mfb-bd-tangga { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
@media (max-width: 600px) { .mfb-bd-tangga { grid-template-columns: 1fr; } }
.mfb-bd-tangga li { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; border-radius: 10px; border: 1px dashed rgba(127, 127, 127, .45); font-size: 13.5px; }
.mfb-bd-tangga li.mfb-bd-dapat { border-style: solid; border-color: #C9A84C; background: rgba(201, 168, 76, .08); }
.mfb-bd-nama { font-weight: 700; }
.mfb-bd-tgl { color: var(--gray-500, #595959); }
.mfb-bd-hadiah { margin-top: 4px; font-weight: 600; color: #6B5418; }
.mfb-bd-pertama { margin: 10px 0 14px; padding: 12px 14px; border-radius: 10px; background: #FBF0CF; color: #3A2C08; font-weight: 700; }
.mfb-bd-hk { margin: 0 0 16px; }
/* Judul kartu (margin negatif untuk tepi kartu) di dalam dialog meluber ke tepi & menempel kotak Gold — diukur Chrome 9 Okt. */
.mfb-bd-hk .mfb-catatan-judul { margin: 0 0 4px; padding: 0; border-radius: 0; background: none; border: 0; }
body.dark-mode .mfb-bd-hk .mfb-catatan-judul { background: none; }
.mfb-bd-hb { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; padding: 8px 0; border-bottom: 1px solid rgba(127, 127, 127, .2); }
.mfb-bd-hb-label { min-width: 96px; font-weight: 700; }
.mfb-bd-hb-isi { flex: 1 1 220px; min-height: 44px; padding: 0 12px; border-radius: 8px; border: 1px solid rgba(127, 127, 127, .45); font: 16px Inter, system-ui, sans-serif; background: transparent; color: inherit; }
.mfb-bd-hb-status { flex-basis: 100%; font-size: 13px; color: var(--gray-500, #595959); }
.mfb-bd-hb-status:empty { display: none; }
/* Tombol "🏅 Badges" — sama dengan .mfb-sl-buka (Sign-in activity), kelas sendiri (lihat mfb-ui.js pasangTombolBadge). */
.mfb-bd-buka { display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px; border-radius: 10px;
  font: 700 13.5px Inter, system-ui, sans-serif; border: 1.5px solid var(--gold, #C9A84C); background: transparent;
  color: var(--black, #0A0A0A); margin: 12px 16px 0; cursor: pointer; align-self: flex-start; }
.mfb-bd-buka:focus-visible, .mfb-bd-hb-isi:focus-visible { outline: 3px solid #0A0A0A; outline-offset: 2px; }
body.dark-mode .mfb-bd-buka { color: #F0F0F0; }
body.dark-mode .mfb-bd-buka:focus-visible, body.dark-mode .mfb-bd-hb-isi:focus-visible { outline-color: #F0F0F0; }
body.dark-mode .mfb-bd-kosong, body.dark-mode .mfb-bd-lagi, body.dark-mode .mfb-bd-tgl, body.dark-mode .mfb-bd-hb-status { color: #C9C3B6; }
body.dark-mode .mfb-bd-hadiah { color: #E3C26B; }
body.dark-mode .mfb-bd-tangga li.mfb-bd-dapat { background: rgba(212, 175, 55, .1); }
/* Tombol gelap ber-teks putih yang saat HOVER berubah ke var(--charcoal) — di mode gelap itu #E0E0E0, jadi
   teks putih di atas abu-abu terang ("Review" di My Courses). Saat hover di mode gelap teksnya jadi gelap. */
body.dark-mode #desk .btn-course:hover,
body.dark-mode #desk .btn-add:hover,
body.dark-mode #desk .btn-start-course:hover,
body.dark-mode .air-apply-btn:hover,
body.dark-mode #modal-changepw .mpw-btn:hover { color: #0A0A0A; }
/* Tombol emas "Resume →" memakai var(--black) = #F0F0F0 di mode gelap → teks terang di atas emas. */
body.dark-mode #desk .btn-course.resume { color: #0A0A0A; }

/* (36) v1.125 (MoM 05-10) — bilah tombol di atas isi halaman: Course reminders di My Team HoD, Assign Course di
   Courses HP. Tombolnya memakai kelas yang sudah ada (.mfb-pl-buka / .btn-add); di sini hanya tata letak. */
.mfb-ing-bar { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 16px; }
.mfb-ing-bar:empty { display: none; }
#mob .mfb-ing-bar { margin: 12px 16px; }
#mob .mfb-ing-bar > button { min-height: 44px; flex: 1 1 auto; }
/* v1.126 (foto Manual HoD 5 Okt) — .btn-add hanya bergaya di #desk (baseline) → di HP tombol Assign Course tampil
   abu-abu polos bawaan peramban. Gaya tombol utama: hitam + teks emas, 48 px, sama di terang & gelap. */
#mob .mfb-as-buka { min-height: 48px; padding: 0 18px; border: 1px solid #16140F; border-radius: 12px; background: #16140F; color: #E3C26B;
  font: 700 15px 'Inter', system-ui, sans-serif; display: inline-flex; align-items: center; justify-content: center; gap: 8px; cursor: pointer; }
#mob .mfb-as-buka:focus-visible { outline: 3px solid #E3C26B; outline-offset: 2px; }
/* D180 — tirai layar penuh saat kuis berjalan di tab lain (di atas semua modal). */
.mfb-kuis-tirai { position: fixed; inset: 0; z-index: 2147483000; display: flex; align-items: center; justify-content: center;
  padding: 24px; background: rgba(8, 9, 12, .94); color: #F4F1EA; }
.mfb-kuis-tirai-kotak { max-width: 460px; padding: 28px 24px; border: 1px solid #C9A84C; border-radius: 16px; background: #14151B; text-align: center; }
.mfb-kuis-tirai-kotak h2 { margin: 0 0 10px; font: 700 21px/1.3 Georgia, 'Times New Roman', serif; color: #E3C26B; }
.mfb-kuis-tirai-kotak p { margin: 0 0 8px; font-size: 15px; line-height: 1.55; }
.mfb-kuis-tirai-kecil { color: #A7A29A; font-size: 13.5px !important; }

/* v1.129 (rilis 2.260 — masukan HRM 6 Okt): kotak cari di form Assign (HoD & HR) — cari nama atau Employee ID.
   44 px untuk jari; warna dari variabel baseline supaya mode gelap ikut. */
.mfb-asg-cari { display: block; width: 100%; box-sizing: border-box; min-height: 44px; margin: 0 0 8px; padding: 10px 12px;
  border: 1.5px solid var(--gray-200, #E5E5E5); border-radius: 10px; background: var(--white, #FFFFFF); color: var(--black, #0A0A0A);
  font: 400 14px 'Inter', system-ui, sans-serif; }
.mfb-asg-cari:focus-visible { outline: 2px solid var(--gold, #C9A84C); outline-offset: 1px; }
body.dark-mode .mfb-asg-cari { background: #1A1A1A; color: #F0F0F0; border-color: rgba(201, 168, 76, 0.35); }

/* v1.130 (rilis 2.261, D200) — Floor checks: bilah Report / Back / Download CSV dan tabel ringkasan.
   Tabelnya memakai .mfb-ds-bungkus (bisa digeser di dalam kotaknya sendiri), jadi halaman tidak ikut melebar di HP. */
.mfb-hc-alat { display: flex; flex-wrap: wrap; gap: 10px; margin: 8px 0 12px; }
.mfb-hc-tabel td:not(:first-child), .mfb-hc-tabel th:not(:first-child) { text-align: right; white-space: nowrap; }

/* v1.130 (rilis 2.261 — IT Manager 6 Okt 20:16) — jendela "Add to LMS": jarak antar-isian lega, teks petunjuk tidak
   menempel ke isian di bawahnya, tombol "Read email" + "Sheet link" sebaris (link sheet tersembunyi sampai dibuka). */
.mfb-sl-form .mfb-ev-lbl { margin: 18px 0 6px; }
.mfb-sl-form > .mfb-ev-lbl:first-child { margin-top: 4px; }
.mfb-sl-form .mfb-ev-catat { margin: 6px 0 2px; line-height: 1.45; }
.mfb-sl-aksi { display: flex; flex-wrap: wrap; gap: 10px; margin: 12px 0 2px; }
.mfb-sl-aksi .mfb-lb-pil { flex: 1 1 auto; }
.mfb-sl-sumber .mfb-ev-lbl { margin-top: 14px; }
.mfb-sl-form .mfb-ev-kaki { margin-top: 20px; }

/* v1.131 (rilis 2.262, D221) — saran cepat di bawah kotak cari Assign: sampai 6 nama, tombol 44 px, ikut tema. */
.mfb-asg-saran { list-style: none; margin: -4px 0 10px; padding: 4px; border-radius: 10px; border: 1px solid rgba(128,128,128,.35);
  background: var(--white, #fff); box-shadow: 0 8px 24px rgba(0,0,0,.08); }
.mfb-asg-saran[hidden] { display: none; }
.mfb-asg-saran-pil { display: block; width: 100%; min-height: 44px; padding: 8px 12px; border: 0; border-radius: 8px; background: transparent;
  color: inherit; font: inherit; text-align: left; cursor: pointer; }
.mfb-asg-saran-pil:hover, .mfb-asg-saran-pil:focus-visible { background: rgba(201,168,76,.16); outline: 2px solid var(--gold, #C9A84C); outline-offset: -2px; }
body.dark-mode .mfb-asg-saran { background: #1c1a16; border-color: rgba(255,255,255,.18); }

/* v1.131 (rilis 2.262, D211) — kartu "Need help?" WhatsApp di Profile. Tombol 44 px, ikut tema. */
.mfb-kontak { margin: 16px 0; padding: 16px 18px; border-radius: 14px; border: 1px solid rgba(201,168,76,.45); background: var(--white, #fff); }
.mfb-kontak b { display: block; font-size: 15px; margin: 0 0 4px; }
.mfb-kontak p { margin: 0 0 12px; font-size: 13px; color: var(--gray-500, #5C5A56); line-height: 1.5; }
.mfb-kontak-bar { display: flex; flex-wrap: wrap; gap: 10px; }
.mfb-kontak-pil { display: inline-flex; align-items: center; justify-content: center; flex: 1 1 180px; min-height: 44px; padding: 0 16px;
  border-radius: 999px; border: 1.5px solid var(--gold, #C9A84C); color: inherit; font-weight: 600; text-decoration: none; }
.mfb-kontak-pil:hover, .mfb-kontak-pil:focus-visible { background: rgba(201,168,76,.14); outline: none; }
#mob .mfb-kontak-hp { margin: 12px 16px; }
body.dark-mode .mfb-kontak { background: #1c1a16; border-color: rgba(201,168,76,.4); }
body.dark-mode .mfb-kontak p { color: #C9C3B6; }

/* v1.131 (rilis 2.262, D227) — tombol "Copy share link" di atas detail course. */
.mfb-share-bar { display: flex; justify-content: flex-end; margin: 0 0 12px; }
#mob .mfb-share-bar { margin: 12px 16px 0; }
.mfb-share-course { min-height: 44px; }

/* v1.132 (rilis 2.263) — judul kelompok departemen juga di Employee List (.mfb-grp-tabel), dan kolom avatar
   halaman All Employees. Gaya kelompok disalin dari All Courses (.mfb-kat-tabel) supaya seragam. */
.mfb-grp-tabel tr.mfb-kat-grup th { text-align: left; padding: 10px 14px; background: var(--gray-50, #F7F5F0); border-bottom: 1px solid var(--gray-100, #E8E8E8);
  font: 700 12px 'Inter', system-ui, sans-serif; letter-spacing: .08em; text-transform: uppercase; color: #6B6761; }
.mfb-grp-tabel tr.mfb-kat-grup th > .mfb-kat-n { margin-left: 10px; letter-spacing: 0; text-transform: none; }
body.dark-mode .mfb-grp-tabel tr.mfb-kat-grup th { background: rgba(255, 255, 255, .04); color: #C8C2B6; border-bottom-color: rgba(255, 255, 255, .08); }
@media (max-width: 899px) { .mfb-grp-tabel tr.mfb-kat-grup th { display: block; padding: 4px 2px; background: none; border: 0; } }
.mfb-ae-nama { display: flex; align-items: center; gap: 10px; }
.mfb-ae-av { flex: 0 0 auto; width: 36px; height: 36px; border-radius: 50%; display: inline-grid; place-items: center; background: #16140F; color: #E3C26B;
  font: 700 13px/1 Inter, system-ui, sans-serif; background-size: cover; background-position: center; }
.mfb-ae-av.mfb-um-foto { color: transparent; }

/* v1.133 (rilis 2.263) — JARAK DARI HEADER DI HP (IT Manager 7 Okt 19:45, screenshot Activity Log). Diukur di Chrome 390 untuk
   semua halaman HP: kebanyakan 12–16 px; yang mepet: Activity Log 0 (kotak cari), Settings 0 (bar Save changes), Profile 4
   (tombol All Employees 2.263), Reports 6 (kartu pertama). Disamakan 16 px. Hero yang memang menyambung header tidak diubah. */
@media (max-width: 899px) {
  #m-actlog-content .mfb-log-cari { margin-top: 16px; }
  #m-settings-content .mfb-set-bar { margin-top: 16px; }
  #m-profile-content > .mfb-ae-buka:first-child { margin-top: 16px; }
  #m-reports-content > .mfb-rep:first-child, #m-hod-reports-content > .mfb-rep:first-child { margin-top: 16px; }
}

/* v1.134 (rilis 2.264, D258 — insight HRM 7 Okt 22:17) — jam kejadian di kartu Activity Log HP (mfb-ui.js pasangWaktuLogHP),
   di bawah deskripsi; baseline .lc-desc memberi margin-bawah 8 px, jadi jam menempel lalu memberi jarak yang sama. */
#mob .mfb-lc-waktu { margin: -4px 0 8px; font: 500 11.5px/1.4 Inter, system-ui, sans-serif; color: var(--gray-500, #6B6761);
  font-variant-numeric: tabular-nums; }
body.dark-mode #mob .mfb-lc-waktu { color: #A8A296; }

/* v1.134 (rilis 2.264, D259) — tombol ⟳ Refresh (hanya app terpasang). Memakai .topbar-icon-btn baseline (36×36, border abu);
   reset bawaan <button> agar sama dengan lonceng. Fokus keyboard terlihat. */
#desk .mfb-refresh { padding: 0; font: inherit; -webkit-appearance: none; appearance: none; }
#desk .mfb-refresh:focus-visible { outline: 2px solid var(--gold, #C9A14A); outline-offset: 2px; }

/* v1.134 (rilis 2.264, D246 — insight GM, MoM 07-10) — baris "Sort by" di Floor checks (mfb-ui.js barisUrutHc).
   Tombol .mfb-urut (all: unset) diberi bentuk pil; tombol aktif emas; target sentuh 44 px di HP. */
.mfb-hc-urut { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin: 4px 0 10px; }
.mfb-hc-urut-lbl { font: 700 11px/1 Inter, system-ui, sans-serif; letter-spacing: .08em; text-transform: uppercase; color: #6B6761; }
.mfb-hc-urut .mfb-hc-urut-b { box-sizing: border-box; display: inline-flex; align-items: center; min-height: 32px; padding: 4px 12px;
  border: 1px solid var(--gray-200, #E2DED6); border-radius: 999px; background: var(--white, #fff); font: 600 12.5px/1.2 Inter, system-ui, sans-serif; }
.mfb-hc-urut .mfb-hc-urut-b[aria-pressed="true"] { border-color: var(--gold, #C9A84C); background: rgba(201, 168, 76, .14); color: #6E5418; }
body.dark-mode .mfb-hc-urut-lbl { color: #A8A296; }
body.dark-mode .mfb-hc-urut .mfb-hc-urut-b { background: rgba(255, 255, 255, .04); border-color: rgba(255, 255, 255, .14); color: #E8E2D6; }
body.dark-mode .mfb-hc-urut .mfb-hc-urut-b[aria-pressed="true"] { border-color: #E3C26B; color: #F3DFA6; background: rgba(227, 194, 107, .14); }
@media (max-width: 899px) { .mfb-hc-urut .mfb-hc-urut-b { min-height: 44px; } }

/* v1.134 (rilis 2.264, D247 — insight HR Talent) — foto profil di tabel Manage Users laptop (mfb-ui.js pasangFotoUserDesk). */
#desk #d-users-tbody .user-av.mfb-um-foto { background-size: cover !important; background-position: center !important; color: transparent !important; }

/* v1.134 (rilis 2.264, K42) — field "Staff (optional)" di form Assign By Department (mfb-ui.js asgKolomStaf). */
.mfb-asg-staf-tip { margin: 2px 0 0; font: 400 12px/1.45 Inter, system-ui, sans-serif; color: var(--gray-500, #6B6761); }
body.dark-mode .mfb-asg-staf-tip { color: #A8A296; }

/* v1.135 (rilis 2.265, D257 — insight HRM) — tombol "Never signed in (N)" di Manage Users (mfb-ui.js pasangBelumLogin).
   Desktop: di bilah alat; HP: di atas daftar, target sentuh 44 px. */
#mob #m-users-content > .mfb-bl-buka { display: flex; align-items: center; min-height: 44px; margin: 16px 16px 4px; }
.mfb-bl-tabel td:nth-child(5) { font-variant-numeric: tabular-nums; }

/* v1.136 (rilis 2.266, D270 — IT Manager 8 Okt) — tombol "🔑 Sign-in activity" di Reports / Observer Reports / Dept Reports
   (mfb-ui.js pasangTombolLogin). Gaya sama dengan tombol Learning behaviour; kelas sendiri supaya pasangTombolPerilaku
   (yang mencari .mfb-lb-buka) tidak ikut membuangnya. Target sentuh 44 px. */
.mfb-sl-buka { display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px; border-radius: 10px;
  font: 700 13.5px 'Inter', system-ui, sans-serif; border: 1.5px solid var(--gold, #C9A84C); background: transparent;
  color: var(--black, #0A0A0A); margin: 12px 16px 0; cursor: pointer; align-self: flex-start; }
.mfb-sl-buka:focus-visible { outline: 3px solid #0A0A0A; outline-offset: 2px; }
body.dark-mode .mfb-sl-buka { color: #F0F0F0; }
body.dark-mode .mfb-sl-buka:focus-visible { outline-color: #F0F0F0; }

/* v1.136 (rilis 2.266, D243) — dialog selfie opsional sebelum mulai course (mfb-ui.js bukaDialogSelfie).
   Bingkai, video & tombol memakai ulang .mfb-kamera foto profil; ini hanya judul & keterangan. */
.mfb-selfie-judul { margin: 0 0 12px; font: 700 16px/1.35 'Inter', system-ui, sans-serif; }
.mfb-selfie-ket { margin: 0 0 12px; font-size: 12.5px; line-height: 1.45; opacity: .8; }

/* v1.137 (rilis 2.267, D272) — dialog "Review my last quiz" (mfb-ui.js bukaReviewKuis). Daftar & catatan memakai
   gaya .mfb-soal-salah popup hasil; di dialog daftar tidak perlu dibatasi tinggi popup (dialog sendiri yang digulir). */
.mfb-review-kuis-isi { margin-top: 0; }
.mfb-review-kuis-isi ol { max-height: none; }
.mfb-review-kuis-ringkas { margin: 4px 0 6px; font: 700 13.5px 'Inter', system-ui, sans-serif; }
#mob .mfb-share-bar { flex-wrap: wrap; gap: 8px; }
.mfb-share-bar { gap: 8px; }

/* v1.138 (rilis 2.268, D273) — Employee List: centang "Add selected to LMS" di sel LMS account (mfb-ui.js gambarBarisSL),
   tombol Select all & Add selected (N). Centang 22 px dengan area sentuh 44 px lewat margin; tombol massal redup bila 0. */
.mfb-sl-akun .mfb-sl-cek { width: 22px; height: 22px; margin: 11px 10px 11px 0; vertical-align: middle; accent-color: var(--gold, #C9A84C); cursor: pointer; }
.mfb-sl-massal:disabled { opacity: .45; cursor: not-allowed; }
.mfb-sl-massal-isi .mfb-ds-bungkus { margin: 8px 0 12px; }

/* v1.139 (rilis 2.269, D274 — IT Manager 8 Okt 23:40: "nama department nya di fill background gelap, jadi keliatan yg mana
   dept mana list nama"). Pita gelap untuk judul kelompok departemen di Employee List & All Employees (.mfb-grp-tabel —
   sejak 2.263 sengaja seragam). Daftar lain yang memakai .mfb-kat-grup (All Courses, laporan) TIDAK disentuh.
   Terang: hitam brand + teks putih + lencana emas (kontras >7:1). Mode gelap: abu tua supaya tetap terpisah dari latar.
   HP: pita membulat (sebelumnya tanpa latar). */
.mfb-grp-tabel tr.mfb-kat-grup th { background: #1A1A1A; color: #FFFFFF; border-bottom-color: #1A1A1A; }
.mfb-grp-tabel tr.mfb-kat-grup th > .mfb-kat-n { background: rgba(201, 168, 76, .28); color: #F2D78C; }
body.dark-mode .mfb-grp-tabel tr.mfb-kat-grup th { background: #3A3A3A; color: #FFFFFF; border-bottom-color: #3A3A3A; }
@media (max-width: 899px) {
  .mfb-grp-tabel tr.mfb-kat-grup th { display: block; padding: 10px 14px; background: #1A1A1A; color: #FFFFFF; border-radius: 10px; }
  body.dark-mode .mfb-grp-tabel tr.mfb-kat-grup th { background: #3A3A3A; }
}
