html, body { max-width: 100%; overflow-x: hidden; }
body { font-family: 'Plus Jakarta Sans', sans-serif; }
.font-display { font-family: 'Fraunces', serif; font-optical-sizing: auto; }
.border-line { border-color: #DCE6E1; }
.blob { border-radius: 63% 37% 54% 46% / 43% 37% 63% 57%; }
.blob-2 { border-radius: 41% 59% 63% 37% / 47% 45% 55% 53%; }

/* ===================== Cards (seragam dengan admin) =====================
   Kartu di halaman publik memakai class yang sama persis dengan dashboard
   admin (.card-modern) supaya seluruh sistem - publik maupun admin -
   punya bahasa visual yang konsisten: border lebih terlihat, shadow
   berlapis, dan aksen garis gradien hijau-emas tipis di tepi atas. */
.card-modern {
  position: relative;
  background: #fff; border: 1px solid #DCE6E1; border-radius: 18px;
  box-shadow: 0 1px 3px rgba(16,40,32,.06), 0 14px 30px -16px rgba(16,40,32,.18);
  transition: box-shadow .2s ease, transform .2s ease;
}
.card-modern::before {
  content: ''; position: absolute; left: 18px; right: 18px; top: 0; height: 3px; border-radius: 0 0 3px 3px;
  background: linear-gradient(90deg, #3FA97B, #C9973F); opacity: .55;
}
.card-modern:hover { box-shadow: 0 6px 14px -4px rgba(16,40,32,.1), 0 22px 38px -16px rgba(16,40,32,.24); }

.animate-rise { animation: riseIn .4s ease both; }
@keyframes riseIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
.page-transition { animation: pageIn .28s ease; }
@keyframes pageIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }

.card-hover { transition: transform .2s ease, box-shadow .2s ease; }
.card-hover:hover { transform: translateY(-3px); box-shadow: 0 12px 24px -8px rgba(11,61,46,0.15); }

.chart-card { display: flex; align-items: flex-end; gap: 6px; }
/* PENTING: JANGAN pakai "flex: 1" di sini. Elemen ini berada di dalam
   wrapper kolom (flex-direction:column) yang sudah "flex:1" sendiri
   untuk lebar kolom. Kalau .chart-bar ikut diberi flex:1, flex-basis-nya
   jadi 0 dan batang akan selalu MEMBESAR mengisi sisa ruang vertikal
   kolom - meng-override height:% yang di-set lewat JS, sehingga semua
   batang tampil sama tinggi walau nilainya beda jauh (mis. 20 vs 81). */
.chart-bar { background: #0F7A5C; border-radius: 6px 6px 0 0; flex: 0 0 auto; min-width: 8px; transition: height .5s ease; }
.chart-bar-label { font-size: 10px; color: #6b7280; text-align: center; margin-top: 4px; }
.chart-bar-value { font-size: 11px; font-weight: 700; color: #1f2937; text-align: center; margin-bottom: 4px; white-space: nowrap; }

/* ---- Animasi "menggambar" untuk semua grafik SVG/HTML di Beranda &
   Detail Madrasah (donut, bar, bar-multi, radar, garis/tren). Dipicu
   sekali saat kartu grafik masuk ke area layar - class "in-view"
   ditambahkan oleh observeChartInView() di public-app.js. Sebelumnya
   class-class ini (donut-seg, bar-grow, line-draw, dst) sudah dipakai
   di markup JS tapi belum punya definisi animasi di sini, jadi diam
   saja / tidak semua grafik terlihat beranimasi. ---- */
.chart-pop { opacity: 0; transform: scale(.9); transform-origin: center; }
.in-view .chart-pop { animation: chartPop .5s cubic-bezier(.22,1,.36,1) forwards; }
@keyframes chartPop { to { opacity: 1; transform: scale(1); } }

.donut-seg { stroke-dasharray: 0 var(--seg-total, 1000); }
.in-view .donut-seg { animation: donutDraw .8s ease forwards; }
@keyframes donutDraw { to { stroke-dasharray: var(--seg-len, 0) var(--seg-gap, 0); } }

.bar-grow, .chart-bar.chart-bar-animated {
  opacity: 0; transform: scaleY(0); transform-origin: bottom;
}
.in-view .bar-grow, .in-view .chart-bar.chart-bar-animated {
  animation: barGrow .55s cubic-bezier(.22,1,.36,1) forwards;
}
@keyframes barGrow { to { opacity: 1; transform: scaleY(1); } }

.line-area { opacity: 0; }
.in-view .line-area { animation: fadeIn .7s ease forwards; animation-delay: .25s; }
@keyframes fadeIn { to { opacity: 1; } }

.line-draw { transition: none; }
.in-view .line-draw { animation: lineDraw 1.3s ease forwards; }
@keyframes lineDraw { to { stroke-dashoffset: 0; } }

.line-dot { opacity: 0; transform: scale(0); transform-box: fill-box; transform-origin: center; }
.in-view .line-dot { animation: dotPop .35s ease forwards; }
@keyframes dotPop { to { opacity: 1; transform: scale(1); } }

/* ---- Kalimat berjalan (marquee) di atas Beranda: konten digandakan
   di HTML (dua .marquee-item identik) lalu digeser -50% supaya loop-nya
   mulus tanpa "lompat". Kecepatan menyesuaikan panjang teks. ---- */
.marquee-wrap { width: 100%; }
.marquee-track {
  display: inline-flex;
  width: max-content;
  animation: marqueeScroll linear infinite;
  animation-duration: max(12s, calc(1s * var(--marquee-len, 40) * 0.16));
}
.marquee-wrap:hover .marquee-track { animation-play-state: paused; }
.marquee-item { display: inline-block; padding-right: 0; }
.marquee-entry { display: inline-flex; align-items: center; gap: 0.5em; margin-right: 2.5em; }
.marquee-flag { height: 1em; width: 1.5em; flex-shrink: 0; border-radius: 2px; box-shadow: 0 0 0 1px rgba(255,255,255,0.35); }
.marquee-logo { height: 1.35em; width: 1.35em; object-fit: contain; border-radius: 3px; background: #fff; padding: 1px; flex-shrink: 0; }
@keyframes marqueeScroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .marquee-track { animation: none; }
  .marquee-wrap { overflow-x: auto; }
}

#splashScreen { transition: opacity .35s ease; }
#splashScreen.fade-out { opacity: 0; pointer-events: none; }

#footerMapCard { perspective: 800px; }
#footerMapCardInner { will-change: transform; }
#footerMapCard.is-expanded #footerMapCardInner { transform: none !important; }

/* ---- "Sorotan Terbaru" (halaman Berita): strip kartu berita terbaru
   yang bisa digeser ke samping, sengaja dibuat dengan gaya kartu yang
   sama persis dengan grid berita di bawahnya (.card-modern) supaya
   konsisten dan tidak ada lagi masalah tampilan seperti versi galeri
   melebar sebelumnya. ---- */
.sorotan-scroll { scrollbar-width: thin; scrollbar-color: rgba(11,61,46,.25) transparent; }
.sorotan-scroll::-webkit-scrollbar { height: 7px; }
.sorotan-scroll::-webkit-scrollbar-thumb { background: rgba(11,61,46,.22); border-radius: 99px; }
.sorotan-card { scroll-snap-align: start; }

/* ---- Berita berjalan (halaman Beranda): strip kartu berita terbaru yang
   bergerak otomatis ke kiri secara berkelanjutan, dengan teknik yang sama
   dengan kalimat marquee di atas (daftar digandakan lalu digeser -50%
   supaya loop-nya mulus). Berhenti sejenak saat disorot mouse (hover)
   supaya berita masih bisa dibaca/diklik. ---- */
.berita-marquee-wrap { overflow: hidden; -webkit-mask-image: linear-gradient(90deg, transparent, #000 3%, #000 97%, transparent); mask-image: linear-gradient(90deg, transparent, #000 3%, #000 97%, transparent); }
.berita-marquee-track {
  display: flex; gap: 1.25rem; width: max-content;
  animation: beritaMarquee linear infinite;
  animation-duration: var(--berita-marquee-duration, 32s);
}
.berita-marquee-wrap:hover .berita-marquee-track { animation-play-state: paused; }
.berita-marquee-card { width: 19rem; flex-shrink: 0; }
@keyframes beritaMarquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .berita-marquee-track { animation: none; }
  .berita-marquee-wrap { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }
}

/* ---- Tombol mengambang "Pengaduan" (pojok kanan-bawah semua halaman
   publik, di atas tombol aksesibilitas) - gaya widget live-chat, biar

   selalu terlihat tapi tidak menyaingi menu navigasi utama. Dipindahkan
   dari index.html (SPA lama). ---- */
.pengaduan-fab { position: fixed; right: 18px; bottom: 84px; z-index: 45; }
.pengaduan-fab-btn {
  display: flex; align-items: center; height: 3.25rem; border-radius: 9999px;
  background: linear-gradient(135deg, #0F7A5C, #0A4A38); color: #fff;
  box-shadow: 0 10px 28px -8px rgba(11,61,46,0.55);
  padding: 0 0.85rem; gap: 0; overflow: hidden;
  transition: box-shadow .2s ease, transform .2s ease, padding .25s ease;
}
.pengaduan-fab-btn:hover, .pengaduan-fab-btn:focus-visible { transform: translateY(-2px); box-shadow: 0 14px 32px -8px rgba(11,61,46,0.6); }
.pengaduan-fab-icon { width: 1.55rem; height: 1.55rem; flex-shrink: 0; }
.pengaduan-fab-label {
  max-width: 0; opacity: 0; white-space: nowrap; overflow: hidden;
  font-size: .8rem; font-weight: 700; transition: max-width .25s ease, opacity .2s ease, margin .25s ease;
}
.pengaduan-fab-btn:hover .pengaduan-fab-label,
.pengaduan-fab-btn:focus-visible .pengaduan-fab-label { max-width: 11rem; opacity: 1; margin-left: .55rem; }
.pengaduan-fab-ping {
  position: absolute; inset: 0; border-radius: 9999px; background: #3FA97B;
  opacity: .55; animation: pengaduanFabPing 2.4s cubic-bezier(0,0,.2,1) infinite;
}
@keyframes pengaduanFabPing { 75%, 100% { transform: scale(1.35); opacity: 0; } }

/* Google Translate (auto-translate konten dinamis: berita, agenda, visi-misi,
   dsb yang tidak punya kunci data-i18n). Widget bawaan Google disembunyikan
   total; bahasa dipilih lewat tombol #currentLangLabel yang sudah ada, lihat
   webroot/js/i18n.js -> applyGoogleTranslate(). */
#google_translate_element { display: none !important; }
.goog-te-banner-frame.skiptranslate { display: none !important; visibility: hidden !important; }
.goog-te-gadget-icon { display: none !important; }
body { top: 0 !important; position: static !important; }
.goog-tooltip, .goog-tooltip:hover { display: none !important; }
.goog-text-highlight { background: none !important; box-shadow: none !important; }

/* ===================== Kontak Dock (keycap flip) =====================
   Dock kontak ala tuts keyboard: tiap "tuts" menampilkan huruf di sisi
   depan, lalu terangkat + membalik 180° menampilkan ikon platform saat
   dihover/disentuh - terinspirasi referensi animasi "Contact Dock".
   Dibangun murni CSS (3D transform + perspective), JS hanya dipakai
   untuk dukungan sentuh (tap-to-flip) di layar mobile - lihat
   initKontakDock() di public-app.js. */
/* Kontak Kami: ikon resmi tiap platform + label, langsung terlihat
   dan langsung bisa diklik/tap sekali (tidak ada lagi flip huruf ->
   ikon yang butuh sentuhan dua kali). */
.kdock { display: flex; flex-wrap: wrap; justify-content: center; gap: 1.1rem 1.4rem; }
.kdock-key { list-style: none; }
.kdock-hit {
  display: flex; flex-direction: column; align-items: center; gap: .4rem;
  text-decoration: none; -webkit-tap-highlight-color: transparent;
}
.kdock-icon {
  width: 2.75rem; height: 2.75rem; border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 6px 16px -6px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.15);
  transition: transform .2s ease, box-shadow .2s ease;
}
.kdock-icon svg { width: 52%; height: 52%; }
.kdock-hit:hover .kdock-icon, .kdock-hit:focus-visible .kdock-icon {
  transform: translateY(-3px) scale(1.06);
  box-shadow: 0 10px 20px -8px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.2);
}
.kdock-label { font-size: .68rem; font-weight: 600; color: rgba(255,255,255,.75); }
.kdock-hit:hover .kdock-label, .kdock-hit:focus-visible .kdock-label { color: #fff; }

/* Toast kecil untuk fallback klik ikon Email di footer (lihat
   bindEmailFallback() di public-app.js). Dipakai saat komputer/desktop
   pengguna tidak punya aplikasi email default terpasang, sehingga
   mailto: tidak membuka apa-apa - alamat emailnya tetap disalin ke
   clipboard dan ditampilkan lewat toast ini sebagai cadangan. */
.simpenmad-toast {
  position: fixed; left: 50%; bottom: 1.5rem; transform: translate(-50%, .5rem);
  background: #1a2e22; color: #fff; padding: .65rem 1.1rem; border-radius: .6rem;
  font-size: .8rem; font-weight: 500; box-shadow: 0 10px 25px -8px rgba(0,0,0,.45);
  z-index: 9999; opacity: 0; pointer-events: none; transition: opacity .25s ease, transform .25s ease;
  max-width: calc(100vw - 2rem); text-align: center;
}
.simpenmad-toast.is-visible { opacity: 1; transform: translate(-50%, 0); }

/* Reveal-on-scroll generik (section/card/teks) di halaman publik -
   dipasang oleh initScrollReveal() di public-app.js. Class "reveal"
   ditempel di HTML view, class "in-view" ditambahkan JS saat elemen
   masuk viewport. Hormati preferensi pengguna yang mematikan animasi. */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity .6s ease, transform .6s cubic-bezier(.22,1,.36,1);
}
.reveal.in-view {
  opacity: 1;
  transform: translateY(0);
}
.reveal-left { transform: translateX(-24px); }
.reveal-left.in-view { transform: translateX(0); }
.reveal-right { transform: translateX(24px); }
.reveal-right.in-view { transform: translateX(0); }

.reveal[data-delay="1"] { transition-delay: .1s; }
.reveal[data-delay="2"] { transition-delay: .2s; }
.reveal[data-delay="3"] { transition-delay: .3s; }
.reveal[data-delay="4"] { transition-delay: .4s; }
.reveal[data-delay="5"] { transition-delay: .5s; }
.reveal[data-delay="6"] { transition-delay: .6s; }

@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal-left, .reveal-right {
    opacity: 1; transform: none; transition: none;
  }
}

/* CardStack (kartu bertumpuk melengkung/fan) - dipakai oleh
   simpenmadCardStack() di public-app.js, pertama kali untuk strip
   "Sorotan Terbaru" di halaman Berita. */
.cardstack-stage {
  position: relative;
  width: 100%;
}
.cardstack-spot {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  border-radius: 9999px;
  filter: blur(48px);
  pointer-events: none;
}
.cardstack-spot-1 { top: 12px; width: 70%; height: 100px; background: rgba(15,122,92,.10); }
.cardstack-spot-2 { bottom: 0; width: 76%; height: 90px; background: rgba(0,0,0,.06); }
.cardstack-cards {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.cardstack-card {
  position: absolute;
  bottom: 0;
  border-radius: 1rem;
  overflow: hidden;
  box-shadow: 0 20px 40px -14px rgba(0,0,0,.28);
  border: 3px solid rgba(255,255,255,.7);
  transition: transform .5s cubic-bezier(.22,1,.36,1);
  will-change: transform;
  cursor: pointer;
}
.cardstack-card.is-active.cardstack-draggable { cursor: grab; touch-action: pan-y; }
.cardstack-card.is-active.cardstack-draggable:active { cursor: grabbing; }
.cardstack-card-inner { width: 100%; height: 100%; }
.cardstack-dots {
  margin-top: 1.1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
}
.cardstack-dot {
  width: 8px; height: 8px; border-radius: 9999px;
  background: rgba(15,23,42,.2);
  transition: background .2s;
}
.cardstack-dot:hover { background: rgba(15,23,42,.4); }
.cardstack-dot.is-active { background: #0F7A5C; }
