/* Primitif tata letak halaman — dipakai bersama seluruh halaman publik.
 *
 * Sebelumnya .page/.title/.eyebrow/.lede/.rule disalin di empat berkas gaya
 * yang berbeda. Disatukan di sini supaya perubahan tampilan cukup dilakukan
 * sekali, bukan di setiap halaman.
 *
 * Tidak ada nilai heksadesimal di berkas ini — seluruh warna dari token di
 * globals.css, sehingga penggantian warna merek nanti hanya menyentuh satu
 * tempat.
 */

/* ---------- Wadah halaman ---------- */

.page {
  max-width: 76rem;
  margin: 0 auto;
  padding: 0 1.5rem 5rem;
}

.narrow {
  max-width: 48rem;
}

/* ---------- Kepala halaman ---------- */

/*
  Kepala halaman berdiri di atas bidang abu selebar layar.

  Sebelumnya setiap halaman dimulai dengan tulisan yang langsung menempel di
  bidang putih, tepat di bawah kepala situs yang juga putih — tidak ada yang
  memisahkan navigasi dari isi, dan judul halaman kehilangan bobotnya. Bidang
  ini memberi judul tempat berpijak, dan memberi mata satu titik berhenti
  sebelum masuk ke isi.

  Melebar ke seluruh layar dengan `box-shadow` + `clip-path`, bukan
  `margin-inline: calc(50% - 50vw)`: `100vw` ikut menghitung batang gulir dan
  memunculkan gulir mendatar beberapa piksel di Windows. Penjelasan lengkapnya
  ada pada `.pita` di beranda.module.css.
*/
.header {
  position: relative;
  padding: 3rem 0 2.5rem;
  background: var(--bg-alt);
  box-shadow: 0 0 0 100vmax var(--bg-alt);
  clip-path: inset(0 -100vmax);
  border-bottom: 1px solid var(--border);
}

/* Isinya tetap selebar kolom baca, meski latarnya selebar layar. */
.header > * {
  max-width: 48rem;
}

/* Untuk kepala yang isinya memang perlu selebar halaman, mis. profil pakar. */
.headerLebar > * {
  max-width: 100%;
}

.eyebrow {
  margin: 0;
  color: var(--primary);
  font-weight: 700;
  font-size: var(--t-kecil);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.title {
  margin: 0.6rem 0 0.75rem;
  font-size: var(--t-h1);
  color: var(--text);
}

.lede {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--t-isi);
}

/* Garis merah tua pendek — penanda identitas di bawah judul */
.rule {
  height: 4px;
  width: 5rem;
  margin: 1.75rem 0 0;
  background: var(--primary);
  border-radius: var(--r-kecil);
}

/* ---------- Peralihan antar-halaman sekerabat ---------- */

/*
  Menggantikan garis merah pendek di kaki bidang kepala, bukan menumpuk di
  bawahnya: keduanya menandai batas yang sama, dan dua penanda berturut-turut
  membuat kepala halaman terasa berat tanpa menambah keterangan.
*/
.tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 1.75rem;
}

.tab {
  padding: 0.6rem 1rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg);
  color: var(--text);
  text-decoration: none;
  font-size: var(--t-dasar);
  font-weight: 600;
  min-height: auto;
  transition: border-color 0.16s ease, color 0.16s ease;
}

.tab:hover {
  border-color: var(--brand-300);
  color: var(--primary);
}

/*
  Halaman yang sedang dibuka dirender sebagai <span>, bukan tautan ke dirinya
  sendiri — tautan yang tidak ke mana-mana membuang giliran fokus pengguna
  keyboard dan membingungkan pembaca layar.
*/
.tabAktif {
  background: var(--primary-isi);
  border-color: var(--primary);
  color: #fff;
  cursor: default;
}

@media (prefers-reduced-motion: reduce) {
  .tab {
    transition: none;
  }
}

/* ---------- Seksi ---------- */

.section {
  margin-top: 4rem;
}

.sectionHead {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 0.9rem;
  flex-wrap: wrap;
  padding-bottom: 0.75rem;
  border-bottom: 2px solid var(--border);
}

.sectionHead::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -2px;
  width: 2.5rem;
  height: 2px;
  background: var(--primary);
}

.sectionTitle {
  margin: 0;
  font-family: var(--font-judul), Georgia, 'Times New Roman', serif;
  font-size: var(--t-xl);
  line-height: 1.25;
  color: var(--text);
}

.count {
  color: var(--text-muted);
  font-size: var(--t-dasar);
  font-variant-numeric: tabular-nums;
}

/*
  ---------- Bab dan anak-bab ----------

  Ketiga kelas di bawah TIDAK mengubah satu pun `.section` yang sudah ada; ia
  hanya menyediakan derajat kedua bagi halaman yang membutuhkannya.

  Masalahnya nyata: halaman panjang di situs ini menumpuk seksi berjarak sama
  persis (4rem) dengan kepala seragam, sehingga tidak ada yang memberi tahu
  pembaca bahwa dua seksi bertetangga sebenarnya satu pokok yang sama sedang
  dilanjutkan. Seksi lanjutan diberi jeda lebih pendek, garis lebih tipis,
  judul lebih kecil, dan tanpa tanda merah pembuka bab.

  `.sectionLega` adalah kebalikannya: napas lebih panjang untuk menandai bab
  benar-benar BARU. Dipakai berpasangan, keduanya menggantikan jarak yang
  seragam dengan jarak yang berarti.
*/
.sectionLega {
  margin-top: 6rem;
}

.sectionLanjut {
  margin-top: 2.5rem;
}

.sectionHeadLanjut {
  border-bottom-width: 1px;
  border-bottom-color: var(--border);
}

/* Tanda merah menandai AWAL bab; anak-bab tidak memakainya. */
.sectionHeadLanjut::after {
  content: none;
}

/*
  `--t-besar`, BUKAN `--t-h3`.

  Kepala bab di halaman biasa memakai `--t-xl` (1,55rem) yang tetap, sedangkan
  `--t-h3` adalah clamp yang di layar lebar berhenti di 1,6rem — LEBIH BESAR
  daripada induknya. Anak-bab yang judulnya lebih besar daripada babnya persis
  membalik maksudnya, dan di layar sempit kekeliruan itu tidak terlihat karena
  clamp-nya masih di bawah batas. Terukur di 1440px sebelum diperbaiki:
  bab 26,35px, anak-bab 27,2px.
*/
.sectionTitleLanjut {
  font-size: var(--t-besar);
}

@media (max-width: 640px) {
  .sectionLega {
    margin-top: 4rem;
  }
}

/* ---------- Elemen kecil berulang ---------- */

.badge {
  display: inline-block;
  padding: 0.15rem 0.6rem;
  border: 1px solid var(--brand-200);
  border-radius: 999px;
  background: var(--surface);
  color: var(--primary);
  font-weight: 700;
  font-size: var(--t-mikro);
  letter-spacing: 0.02em;
}

.meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
  font-size: var(--t-kecil);
  color: var(--text-muted);
}

.back {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--primary);
  text-decoration: none;
  font-size: var(--t-dasar);
  font-weight: 600;
  margin-bottom: 1.25rem;
}

.back:hover {
  text-decoration: underline;
}

/* ---------- Keadaan kosong & galat ---------- */

/*
  Panel utuh, BUKAN kotak bergaris putus-putus.

  Garis putus-putus adalah kosakata "tempat menaruh sesuatu" dari perkakas
  desain; pada halaman yang tayang ia terbaca sebagai kerusakan. Bagian yang
  belum diisi sebaiknya terlihat seperti keputusan, bukan seperti cacat.
*/
.empty {
  margin-top: 2.5rem;
  padding: 3rem 1.75rem;
  border: 1px solid var(--border);
  border-top: 3px solid var(--primary);
  border-radius: var(--r-kartu);
  background: var(--bg-alt);
  text-align: center;
  color: var(--text-muted);
}

.emptyIcon {
  display: grid;
  place-items: center;
  width: 3.25rem;
  height: 3.25rem;
  margin: 0 auto 1rem;
  border-radius: 50%;
  /*
    Cakram merah ketiga yang memakai pasangan token ini — setelah `.centang`
    di halaman Keanggotaan dan `.klasterJumlah` di header. Ketiganya peran yang
    sama: ikon atau angka bertinta merah di atas basuhan merah samar. Tiga
    peran identik harus memakai satu token, bukan tiga keputusan terpisah.

    Cacat tema yang dibuang di sini PALING SERING TERLIHAT di seluruh proyek:
    `.emptyIcon` adalah ikon panel "belum ada isinya", dan sebagian besar
    koleksi situs ini memang masih kosong (produk kebijakan 0, agenda 0,
    publikasi 0). Ia juga berada di berkas primitif bersama, jadi cacatnya
    tidak terbatas pada satu halaman.

    KONTRAS TERUKUR:
      #a80808 di atas #fef1f1 -> 7,05:1  (terang, tidak berubah)
      #eb4c4c di atas #3e0404 -> 4,63:1  (gelap, SEBELUMNYA)
      #f48b8b di atas #3e0404 -> 7,28:1  (gelap, sekarang)
  */
  background: var(--brand-wash);
  color: var(--brand-ink);
}

.emptyTitle {
  margin: 0 0 0.4rem;
  color: var(--text);
  font-family: var(--font-judul), Georgia, 'Times New Roman', serif;
  font-size: var(--t-sedang);
  font-weight: 700;
}

.emptyBody {
  margin: 0 auto;
  max-width: 34rem;
  line-height: 1.6;
}

/*
  Baris aksi. Dibuat ketika panel kosong Direktori disatukan ke sini: panel itu
  menawarkan DUA jalan keluar — mendaftar, atau menghubungi Sekretariat — dan
  sebelumnya hal itu menjadi alasan halaman tersebut menulis panel kosongnya
  sendiri, lengkap dengan garis putus-putus yang justru dihindari di sini.
*/
.emptyActions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem;
  margin-top: 1.5rem;
}

.emptyAction {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  min-height: var(--tombol-h-kecil);
  padding: 0 1.25rem;
  border-radius: var(--r-kecil);
  background: var(--primary-isi);
  color: #fff;
  text-decoration: none;
  font-weight: 700;
  font-size: var(--t-kecil);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: background 0.16s ease;
}

.emptyAction::after {
  content: '→';
  transition: transform 0.16s ease;
}

.emptyAction:hover {
  background: var(--primary-isi-hover);
}

/*
  Aksi kedua sengaja hanya bergaris. Dua tombol berbidang penuh berdampingan
  membuat pengunjung harus membaca keduanya untuk tahu mana yang dimaksudkan;
  satu berbidang dan satu bergaris menjawabnya tanpa dibaca.
*/
.emptyActionKedua {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tombol-h-kecil);
  padding: 0 1.25rem;
  border: 1px solid var(--border);
  border-radius: var(--r-kecil);
  background: transparent;
  color: var(--text);
  text-decoration: none;
  font-weight: 700;
  font-size: var(--t-kecil);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: border-color 0.16s ease, color 0.16s ease;
}

.emptyActionKedua:hover {
  border-color: var(--primary);
  color: var(--primary);
}

.emptyAction:hover::after {
  transform: translateX(3px);
}

@media (prefers-reduced-motion: reduce) {

  .emptyAction,
  .emptyAction::after {
    transition: none;
  }

  .emptyAction:hover::after {
    transform: none;
  }
}

.error {
  margin-top: 2rem;
  padding: 1.25rem;
  border: 2px solid var(--primary);
  border-radius: var(--r-kartu);
  background: var(--bg-alt);
}

.errorCode {
  display: block;
  margin-top: 0.6rem;
  font-size: var(--t-kecil);
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--text-muted);
}

/* ---------- Judul seksi & kotak ajakan (dipakai bersama) ---------- */

/*
  Judul seksi di dalam badan halaman.
  
  Sebelumnya pola ini ditulis ulang sebagai `.blockTitle`, `.groupTitle`, dan
  `.scopeTitle` di enam berkas gaya yang berbeda, masing-masing dengan ukuran
  dan jarak yang sedikit tidak sama. Selisih kecil semacam itu justru yang
  membuat situs terasa dikerjakan beberapa tangan.

  Berkas lain memakainya lewat `composes`, bukan dengan menyalin nilainya —
  jadi tidak ada markup yang perlu diubah dan tidak ada salinan kedua yang
  bisa menyimpang.
*/
.judulSeksi {
  position: relative;
  margin: 2.5rem 0 1rem;
  padding-bottom: 0.5rem;
  font-family: var(--font-judul), Georgia, 'Times New Roman', serif;
  font-size: var(--t-besar);
  line-height: 1.3;
  border-bottom: 2px solid var(--border);
}

/* Potongan merah di pangkal garis — titik mulai bagi mata saat memindai. */
.judulSeksi::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -2px;
  width: 2.5rem;
  height: 2px;
  background: var(--primary);
}

/*
  Kotak ajakan di kaki halaman.

  Satu tindakan saja per kotak. Halaman yang berakhir tanpa jalan lanjut
  membuat pengunjung kembali ke menu untuk menebak sendiri langkah
  berikutnya — dan sebagian besar tidak melakukannya.
*/
.ajakan {
  margin-top: 3rem;
  padding: 2rem 1.75rem;
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-top: 3px solid var(--primary);
  border-radius: var(--r-kartu);
  text-align: center;
}

.ajakanTeks {
  margin: 0 0 1.25rem;
  max-width: 38rem;
  margin-inline: auto;
  color: var(--text-muted);
  font-size: var(--t-dasar);
  line-height: 1.65;
}

/*
  Tombolnya sengaja SAMA PERSIS dengan "Gabung Sekarang" di kepala situs:
  huruf besar, sudut 3px, panah yang bergerak sedikit saat disentuh. Tombol
  utama yang bentuknya berbeda-beda antar halaman membuat pengunjung ragu
  apakah keduanya benar-benar tombol.
*/
.ajakanTombol {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  min-height: var(--tombol-h);
  padding: 0 1.75rem;
  border-radius: var(--r-kecil);
  background: var(--primary-isi);
  color: #fff;
  text-decoration: none;
  font-weight: 700;
  font-size: var(--t-kecil);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: background 0.16s ease;
}

.ajakanTombol::after {
  content: '→';
  transition: transform 0.16s ease;
}

.ajakanTombol:hover {
  background: var(--primary-isi-hover);
  color: #fff;
}

.ajakanTombol:hover::after {
  transform: translateX(3px);
}

@media (prefers-reduced-motion: reduce) {

  .ajakanTombol,
  .ajakanTombol::after {
    transition: none;
  }

  .ajakanTombol:hover::after {
    transform: none;
  }
}


/*
  TOMBOL KIRIM FORMULIR — SATU DEFINISI UNTUK SEMUA FORMULIR.

  Sebelumnya `.submit` ditulis ulang di auth, daftar, status dan kontak. Isinya
  praktis sama, tetapi bantalan tegaknya berbeda, sehingga tombol dengan nama
  kelas yang sama dan tugas yang sama terukur 56px di halaman Masuk dan 51px di
  halaman Lacak Status.

  Yang dikumpulkan di sini hanya yang memang sama. Perbedaan yang punya alasan
  tetap tinggal di berkasnya masing-masing: Masuk memakai tombol selebar
  kolom, dan Kontak memakai kursor `progress` saat mengirim karena di sanalah
  ada penantian jaringan.
*/
.tombolKirim {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tombol-h);
  padding: 0 1.75rem;
  background: var(--primary-isi);
  color: #fff;
  border: 0;
  border-radius: var(--r-kartu);
  font: inherit;
  font-weight: 700;
  font-size: var(--t-dasar);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.16s ease;
}

.tombolKirim:hover:not(:disabled) {
  background: var(--primary-isi-hover);
  color: #fff;
}

/* Kursornya sengaja tidak diatur di sini — lihat catatan di atas. */
.tombolKirim:disabled {
  opacity: 0.6;
}

@media (prefers-reduced-motion: reduce) {

  .tombolKirim {
    transition: none;
  }
}

/* ---------- Kisi kartu ---------- */

.grid {
  list-style: none;
  margin: 2.5rem 0 0;
  padding: 0;
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 21rem), 1fr));
}

.gridTight {
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr));
}

.stack {
  list-style: none;
  margin: 2.5rem 0 0;
  padding: 0;
  display: grid;
  gap: 1rem;
}

/* ============================================================
   PRIMITIF INTERAKSI
   ============================================================

   Ditaruh di sini, bukan disalin ke tiap berkas gaya halaman, karena empat
   halaman konten memakai perilaku yang sama persis. Menyalinnya berarti empat
   tempat yang bisa berbeda — dan perbedaan kecil pada gerakan justru paling
   terasa: situs jadi terkesan tidak digarap satu tangan.

   Dipakai dengan menggabungkan className, misalnya:
     className={`${s.card} ${p.angkat} ${p.klikPenuh}`}
*/

/* Kartu terangkat sedikit saat disentuh. Halus dan singkat — ini situs
   lembaga akademik, bukan etalase. */
.angkat {
  transition: transform 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
}

.angkat:hover {
  transform: translateY(-2px);
  border-color: var(--brand-300);
  box-shadow: var(--naik-angkat);
}

/*
  Seluruh kartu dapat diklik.

  Dikerjakan lewat ::after pada TAUTAN JUDUL, bukan dengan membungkus <a> di
  sekeliling elemen blok. Bedanya penting: pembaca layar tetap mengumumkan satu
  tautan dengan nama yang berarti — judulnya — bukan seluruh isi kartu sebagai
  satu tautan panjang tanpa bentuk.

  Elemen kartunya perlu `position: relative`; itu diberikan .angkat di bawah.
*/
.klikPenuh {
  position: relative;
}

.klikPenuh a::after {
  content: '';
  position: absolute;
  inset: 0;
}

/* Teks yang harus tetap dapat diseleksi di atas lapisan klik penuh. */
.klikPenuh .pilih {
  position: relative;
  z-index: 1;
}

/* Gambar sampul membesar perlahan saat kartunya disentuh. */
.zoomBungkus {
  overflow: hidden;
}

.zoomBungkus img {
  transition: transform 0.4s ease;
}

.angkat:hover .zoomBungkus img,
.zoomBungkus:hover img {
  transform: scale(1.04);
}

/*
  Kartu ikut menyala saat tautannya mendapat fokus keyboard.

  `.klikPenuh` membuat seluruh kartu dapat diklik, tetapi yang bisa difokus
  hanya tautan judulnya — dan tautan itu tidak terlihat menonjol. Tanpa aturan
  ini, pengguna keyboard menyusuri halaman tanpa tahu kartu mana yang sedang
  aktif, padahal pengguna tetikus melihatnya dengan jelas. Perlakuannya sengaja
  disamakan dengan :hover.
*/
.angkat:focus-within {
  transform: translateY(-2px);
  border-color: var(--brand-300);
  box-shadow: var(--naik-angkat);
}

.angkat:focus-within .zoomBungkus img {
  transform: scale(1.04);
}

/* Cincin fokus tetap terlihat sendiri; jangan sampai tertelan bayangan. */
.klikPenuh a:focus-visible {
  outline: 2px solid var(--brand-600);
  outline-offset: 3px;
  border-radius: var(--r-kecil);
}

/*
  Kartu naik perlahan saat pertama kali terlihat.

  Keadaan AWALNYA adalah terlihat penuh — bukan transparan. Kelas peredupnya
  baru dipasang oleh JavaScript setelah hidrasi, lewat komponen Muncul. Kalau
  urutannya dibalik, pengguna tanpa JavaScript (dan perayap mesin pencari)
  mendapat halaman yang seluruh isinya tak kasatmata.
*/
.muncul {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}

.munculTampil {
  opacity: 1;
  transform: none;
}

/*
  MATIKAN SELURUH GERAKAN bila pengguna memintanya.

  Satu blok di akhir, bukan disebar per aturan — supaya tidak ada gerakan baru
  yang lolos tanpa pagar ini.
*/
@media (prefers-reduced-motion: reduce) {
  .angkat,
  .zoomBungkus img,
  .muncul {
    transition: none;
  }

  .angkat:hover,
  .angkat:focus-within {
    transform: none;
  }

  .angkat:hover .zoomBungkus img,
  .angkat:focus-within .zoomBungkus img,
  .zoomBungkus:hover img {
    transform: none;
  }

  /* Tetap terlihat penuh — jangan pernah tersembunyi menunggu animasi. */
  .muncul {
    opacity: 1;
    transform: none;
  }
}
