/* ==========================================================================
   TUTOORIA — 03. KOMPONEN
   Pustaka komponen global. Setiap komponen berdiri di atas token dan boleh
   dipakai di halaman mana pun (situs maupun app/). Tidak ada nilai mentah.

   Aturan penamaan
     .blok            komponen mandiri (.button, .card, .badge)
     .blok__bagian    bagian di dalamnya (.card__title)
     .blok--varian    varian tampilan/ukuran (.button--small)
   Satu tampilan = satu nama. Kalau sebuah komponen halaman butuh tampilan
   yang sudah ada (kartu, kotak ikon, label kapital), ia MEMAKAI kelas itu
   lalu menambah kelasnya sendiri hanya untuk tata letak, mis.
   <article class="card card--compact kpi">.

   Isi
     A. DASAR      ikon · tombol · tombol ikon · tautan panah · badge ·
                   chip · emblem · avatar · progres · spinner · pembatas
     B. PERMUKAAN  kartu · daftar keterangan · popover · menu · tabel ·
                   keadaan kosong
     C. FORMULIR   field · input/select/textarea · input berikon ·
                   input berawalan · kartu opsi · combobox · pemilih tanggal
     D. NAVIGASI   header & navbar · tab · footer
     E. BLOK ISI   fitur · statistik · kartu tutor · testimoni · slider ·
                   paket harga · akordeon · marquee
   ========================================================================== */


/* ##########################################################################
   A. DASAR
   ########################################################################## */

/* =======================================================
   IKON — Lucide v1.46.0 (lisensi ISC), di-inline agar tetap tampil
   tanpa JavaScript dan tanpa permintaan jaringan tambahan.
   Atribut default Lucide (fill/stroke/linecap/linejoin) dipusatkan di
   sini, sehingga markup tiap ikon cukup memuat data path-nya saja.
   Ukuran bawaan 1em (ikut huruf); pakai --s/--m/--l bila ikon harus
   berukuran tetap.
   ======================================================= */
.icon {
  inline-size: var(--icon-size, 1em);
  block-size: var(--icon-size, 1em);
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.icon--s { --icon-size: 1rem; }
.icon--m { --icon-size: 1.25rem; }
.icon--l { --icon-size: 1.5rem; }
.icon--bold { stroke-width: 2.5; }
/* Bintang penilaian dibaca sebagai lencana padat, bukan garis. */
.icon--fill { fill: currentColor; stroke: none; }

/* =======================================================
   TOMBOL
     primary    hitam, teks putih — hover garis ungu
     primary-2  ungu, teks hitam — aksi paling menonjol
     secondary  putih, garis 2px hitam — hover membalik jadi hitam
     invert     putih di atas bidang hitam — hover ungu
     outline    putih, garis 1px abu — aksi ringan di dalam isi
     ghost      tanpa bidang & garis — aksi paling ringan
   Ukuran: --small (40px) · bawaan (48px) · --large (56px); --block
   untuk lebar penuh. Tinggi dari token --control-h*, bukan padding.
   ======================================================= */
.button {
  --_bg: var(--clr-black);
  --_fg: var(--clr-white);
  --_border: var(--clr-black);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  min-block-size: var(--control-h);
  padding-block: 0;
  padding-inline: 1.5em;
  border: var(--border-bold) solid var(--_border);
  border-radius: var(--radius-m);
  background: var(--_bg);
  color: var(--_fg);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-snug);
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.button:hover { color: var(--_fg); text-decoration: none; }

/* Primary — hover menegaskan lewat garis ungu, bukan isian ungu, supaya
   tidak tertukar dengan primary-2. */
.button--primary { --_bg: var(--clr-black); --_fg: var(--clr-white); --_border: var(--clr-black); }
.button--primary:hover { --_border: var(--accent); }

/* Primary-2 — latar ungu utama, teks hitam (9.5:1). */
.button--primary-2 { --_bg: var(--accent); --_fg: var(--accent-fg); --_border: var(--accent); }
.button--primary-2:hover { --_bg: var(--accent-hover); --_border: var(--accent-hover); }

.button--secondary { --_bg: var(--clr-white); --_fg: var(--clr-black); --_border: var(--clr-black); }
.button--secondary:hover { --_bg: var(--clr-black); --_fg: var(--clr-white); --_border: var(--clr-black); }

/* Untuk permukaan hitam, di mana primary (latar hitam) tidak terlihat. */
.button--invert { --_bg: var(--clr-white); --_fg: var(--clr-black); --_border: var(--clr-white); }
.button--invert:hover { --_bg: var(--accent); --_fg: var(--accent-fg); --_border: var(--accent); }

/* Outline & ghost memakai token semantik (--fg, --line), jadi ikut benar
   di atas permukaan hitam tanpa varian tambahan. Garis 1px: aksi ringan
   tidak boleh berebut perhatian dengan CTA bergaris 2px. */
.button--outline {
  --_bg: transparent;
  --_fg: var(--fg);
  --_border: var(--line);
  border-width: var(--border-hair);
}
.button--outline:hover { --_border: var(--line-strong); }
.button--ghost { --_bg: transparent; --_fg: var(--fg); --_border: transparent; }
.button--ghost:hover { --_bg: color-mix(in oklab, var(--fg) 7%, transparent); }

.button--small { --control-h: var(--control-h-small); padding-inline: 1.1em; }
.button--large { --control-h: var(--control-h-large); padding-inline: 1.9em; font-size: var(--step-0); }
/* Lebar penuh — tinggi dan padding tetap sama persis dengan tombol lain. */
.button--block { inline-size: 100%; }

/* Tampak nonaktif, tapi tetap bisa diklik: klik menunjukkan isian mana yang
   kurang, bukan diam tanpa penjelasan seperti <button disabled>. */
.button[aria-disabled="true"],
.button[aria-disabled="true"]:hover,
.button:disabled {
  --_bg: var(--clr-gray-100);
  --_fg: var(--fg-muted);
  --_border: var(--clr-gray-100);
}
.button:disabled { cursor: not-allowed; }

.button__arrow { transition: transform var(--dur-base) var(--ease-spring); flex: none; }
.button:hover .button__arrow { transform: translateX(0.28em); }

/* =======================================================
   TOMBOL IKON — bujur sangkar setinggi kontrol lain.
     bawaan     garis 2px hitam (padanan .button--secondary)
     --primary  bidang hitam, hover ungu (kirim pesan)
     --outline  garis 1px abu (alat bantu di dalam isi)
     --ghost    tanpa garis (di dalam isian, di sidebar)
   Ukuran: --small (40px) · bawaan (48px).
   ======================================================= */
.icon-button {
  --_size: var(--control-h);
  display: grid;
  place-items: center;
  flex: none;
  inline-size: var(--_size);
  block-size: var(--_size);
  padding: 0;
  border: var(--border-bold) solid var(--clr-black);
  border-radius: var(--radius-m);
  background: var(--clr-white);
  color: var(--clr-black);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}
.icon-button:hover { background: var(--accent); }
.icon-button:active { transform: scale(0.94); }
.icon-button .icon { --icon-size: 1.15rem; }

.icon-button--primary { background: var(--clr-black); border-color: var(--clr-black); color: var(--clr-white); }
.icon-button--primary:hover { background: var(--accent); border-color: var(--accent); color: var(--accent-fg); }
.icon-button--outline {
  border-width: var(--border-hair);
  border-color: var(--line);
  background: transparent;
  color: var(--fg);
}
.icon-button--outline:hover { background: transparent; border-color: var(--line-strong); }
.icon-button--ghost { border-color: transparent; background: transparent; color: var(--fg); }
.icon-button--ghost:hover { background: color-mix(in oklab, var(--fg) 9%, transparent); }
.icon-button--small { --_size: var(--control-h-small); border-radius: var(--radius-s); }

.icon-button[aria-disabled="true"],
.icon-button:disabled {
  background: var(--clr-gray-100);
  border-color: var(--clr-gray-100);
  color: var(--fg-subtle);
  cursor: not-allowed;
  transform: none;
}
:is(.icon-button--ghost, .icon-button--outline):is([aria-disabled="true"], :disabled) {
  background: transparent;
  border-color: transparent;
  color: var(--clr-gray-300);
}

/* =======================================================
   TAUTAN PANAH — tautan teks berdiri sendiri, garis bawah 2px.
   ======================================================= */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  font-weight: var(--weight-semibold);
  font-size: var(--step--1);
  text-decoration: none;
  border-block-end: var(--border-bold) solid var(--line-strong);
  padding-block-end: 2px;
}
.link-arrow svg { transition: transform var(--dur-base) var(--ease-spring); flex: none; }
.link-arrow:hover svg { transform: translateX(0.28em); }

/* Di layar sentuh tautan ini hanya ±26px tinggi. Area ketuknya diperluas
   lewat pseudo-elemen tak terlihat sampai --control-h, tanpa menggeser
   garis bawahnya menjauh dari teks. */
@media (pointer: coarse) {
  .link-arrow { position: relative; }
  .link-arrow::before {
    content: "";
    position: absolute;
    inset-inline: 0;
    inset-block-start: 50%;
    block-size: var(--control-h);
    translate: 0 -50%;
  }
}

/* =======================================================
   BADGE — label status kecil.
     bawaan    garis abu, huruf redup (keterangan netral)
     --accent  bidang ungu, huruf hitam (sorotan)
     --soft    bidang ungu muda
     --gray    bidang abu
     --invert  bidang hitam
   --plain mematikan huruf kapital — untuk angka & kalimat pendek
   ("+36 poin"). Menggantikan .delta dan .timeline__year.
   ======================================================= */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  padding: 0.35em 0.7em;
  border: var(--border-hair) solid var(--line);
  border-radius: var(--radius-s);
  background: var(--bg-raised);
  font-size: var(--step--2);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  line-height: 1.2;
  text-transform: uppercase;
  color: var(--fg-muted);
  white-space: nowrap;
}
.badge .icon { --icon-size: 1.1em; stroke-width: 2.5; }
/* Ungu sebagai bidang, huruf hitam — satu-satunya cara ungu boleh membawa teks. */
.badge--accent { background: var(--accent);         border-color: var(--accent);         color: var(--accent-fg); }
.badge--soft   { background: var(--accent-mid);     border-color: var(--accent-mid);     color: var(--clr-black); }
.badge--gray   { background: var(--clr-gray-100);   border-color: var(--clr-gray-100);   color: var(--clr-black); }
.badge--invert { background: var(--clr-black);      border-color: var(--clr-black);      color: var(--clr-white); }
.badge--plain  { letter-spacing: 0; text-transform: none; font-variant-numeric: tabular-nums; }
/* Kecil — label jenis di pojok kartu katalog (.card__badge memakai ukuran
   ini otomatis). Badge bawaan terlalu nyaring berderet di 12 kartu. */
.badge--small,
.card__badge {
  padding: 0.3em 0.6em;
  border-radius: var(--radius-xs);
  font-size: var(--step--3);
}

/* =======================================================
   CHIP — penyaring & pilihan.
   Sengaja berbeda bentuk dari .tab — tab bergaris bawah untuk sumbu utama,
   chip berbidang untuk penyempitan. Garis 1px abu supaya tidak berebut
   perhatian dengan CTA bergaris 2px. Tinggi --control-h demi sasaran sentuh.
   ======================================================= */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  min-block-size: var(--control-h);
  padding-inline: var(--space-m);
  border: var(--border-hair) solid var(--line);
  border-radius: var(--radius-m);
  background: var(--bg-raised);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  color: var(--fg-muted);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.chip:hover { border-color: var(--clr-black); color: var(--fg); }
/* Terpilih: chip penyaring (aria-pressed) dan chip formulir (radio/checkbox
   di dalam <label>) memakai satu bahasa visual yang sama. */
.chip[aria-pressed="true"],
.chip--check:has(:checked) {
  background: var(--clr-black);
  border-color: var(--clr-black);
  color: var(--clr-white);
}
.chip--check { position: relative; }   /* jangkar bagi input .sr-control */
.chip--check:has(:focus-visible) {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
}
.chip--small {
  min-block-size: 2.25rem;
  padding-inline: var(--space-s);
  font-size: var(--step--2);
}

/* =======================================================
   EMBLEM — kotak persegi berisi ikon, nomor, atau huruf.
   Satu komponen untuk semua "kotak ungu": nomor fitur, langkah, tanda
   kutip, ikon Copilot, tanda selesai, huruf pilihan kuis. Ukuran kotak
   tetap, bukan mengikuti isinya, supaya ikon dan angka tampil sebagai
   benda yang sama; ikon & huruf di dalamnya ikut membesar sebanding.
     ukuran  --sm 28px · bawaan 32px · --md 40px · --lg 52px · --xl 72px
     warna   bawaan ungu · --gray · --invert
     huruf   --display memakai Farro (nomor langkah, tanda kutip)
   ======================================================= */
.emblem {
  --_size: 2rem;
  display: inline-grid;
  place-items: center;
  flex: none;
  inline-size: var(--_size);
  block-size: var(--_size);
  background: var(--accent);
  color: var(--accent-fg);
  border-radius: var(--radius-s);
  font-family: var(--font-sans);
  font-size: calc(var(--_size) * 0.4);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  /* Nol, bukan tracking lebar: jarak setelah digit terakhir menggeser
     angka dari titik tengah kotak. Juga memutus warisan tracking-caps
     dari label .overline di sekitarnya. */
  letter-spacing: 0;
  text-transform: none;
  line-height: 1;
}
.emblem .icon { --icon-size: calc(var(--_size) * 0.55); }
.emblem--sm { --_size: 1.75rem; }
.emblem--md { --_size: 2.5rem; }
.emblem--lg { --_size: 3.25rem; border-radius: var(--radius-m); }
.emblem--xl { --_size: 4.5rem;  border-radius: var(--radius-xl); }
.emblem--xl .icon { stroke-width: 2.5; }
.emblem--gray   { background: var(--clr-gray-100); color: var(--clr-black); }
.emblem--invert { background: var(--clr-black);    color: var(--clr-white); }
.emblem--display {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: calc(var(--_size) * 0.55);
}

/* =======================================================
   AVATAR — inisial atau foto dalam lingkaran.
     ukuran  --sm 36px · bawaan 48px · --lg 56px · --xl 72px
     warna   --black (bawaan) · --purple · --soft · --gray
   Foto: taruh <img alt=""> di dalamnya — dipotong bulat, wajah di atas.
   ======================================================= */
.avatar {
  --_size: var(--avatar-size, 3rem);
  display: grid;
  place-items: center;
  flex: none;
  inline-size: var(--_size);
  block-size: var(--_size);
  overflow: hidden;
  border-radius: var(--radius-pill);
  background: var(--avatar-bg, var(--clr-black));
  color: var(--avatar-fg, var(--clr-white));
  font-family: var(--font-display);
  font-size: calc(var(--_size) * 0.34);
  font-weight: var(--weight-display);
  letter-spacing: 0;
  line-height: 1;
  user-select: none;
}
.avatar img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  object-position: center top;
}
.avatar:has(img) { background: var(--clr-gray-100); }
.avatar--sm { --avatar-size: 2.25rem; }
.avatar--lg { --avatar-size: 3.5rem; }
.avatar--xl { --avatar-size: 4.5rem; }
.avatar--black  { --avatar-bg: var(--clr-black);      --avatar-fg: var(--clr-white); }
.avatar--purple { --avatar-bg: var(--clr-purple);     --avatar-fg: var(--clr-black); }
.avatar--soft   { --avatar-bg: var(--clr-purple-100); --avatar-fg: var(--clr-black); }
.avatar--gray   { --avatar-bg: var(--clr-gray-200);   --avatar-fg: var(--clr-black); }

/* =======================================================
   PROGRES — satu komponen untuk bar progres, bar langkah pendaftaran,
   dan meter skor. Isian hitam di trek abu paling muda; di atas permukaan
   hitam isiannya ungu (9.5:1). Nilai lewat --v di .progress__fill.
     --accent  isian ungu — pengecualian sadar dari "ungu bukan garis"
               (2.21:1 di atas putih), hanya untuk bar langkah daftar.
               Kompensasinya: bar 6px dan teks "Langkah N dari 4" selalu
               ada sebagai pembawa informasi utama.
     --lg      10px, untuk meter skor
     --target  garis tegak di posisi --target (mis. nilai target)
   ======================================================= */
.progress {
  position: relative;
  display: block;
  block-size: var(--progress-h);
  border-radius: var(--radius-pill);
  background: var(--progress-track);
  overflow: hidden;
}
.progress__fill {
  position: absolute;
  inset: 0 auto 0 0;
  inline-size: var(--v, 0%);
  border-radius: inherit;
  background: var(--progress-fill, var(--fg));
  transition: inline-size var(--dur-slow) var(--ease-out);
}
.surface-invert .progress,
.progress--accent { --progress-fill: var(--accent); }
.progress--lg { block-size: var(--progress-h-lg); border-radius: var(--radius-xs); }
.progress--target { overflow: visible; }
.progress--target::after {
  content: "";
  position: absolute;
  inset-block: calc(var(--border-bold) * -1.5);
  inset-inline-start: var(--target, 70%);
  inline-size: var(--border-bold);
  background: var(--fg);
  box-shadow: 0 0 0 var(--border-hair) var(--bg);
}
.progress-label {
  display: flex;
  justify-content: space-between;
  gap: var(--space-s);
  font-size: var(--step--2);
  font-weight: var(--weight-medium);
  color: var(--fg-muted);
  font-variant-numeric: tabular-nums;
}
.progress-label b { color: var(--fg); font-weight: var(--weight-semibold); }

/* Bar langkah — deretan segmen .progress, satu per langkah. JS hanya
   mengubah data-state; lebar isiannya diturunkan dari situ. */
.steps-bar {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: var(--space-2xs);
  margin: 0;
  padding: 0;
  list-style: none;
}
.steps-bar__seg:is([data-state="done"], [data-state="current"]) { --v: 100%; }

/* =======================================================
   SPINNER
   ======================================================= */
.spinner {
  inline-size: 1.1rem;
  block-size: 1.1rem;
  border: var(--border-bold) solid var(--line);
  border-block-start-color: var(--fg);
  border-radius: var(--radius-pill);
  animation: spin 700ms linear infinite;
}
@keyframes spin { to { rotate: 1turn; } }

/* =======================================================
   PEMBATAS BERTEKS — garis kiri-kanan dengan kata di tengah ("atau").
   Teksnya memakai .overline.
   ======================================================= */
.divider {
  display: flex;
  align-items: center;
  gap: var(--space-s);
}
.divider::before,
.divider::after {
  content: "";
  flex: 1;
  block-size: var(--border-hair);
  background: var(--line);
}


/* ##########################################################################
   B. PERMUKAAN
   ########################################################################## */

/* =======================================================
   KARTU — wadah dasar untuk SEMUA kotak berbingkai: kartu katalog,
   panel dasbor, KPI, kartu "sedang berjalan", kelas aktif, testimoni,
   paket harga, kartu produk, kuis. Komponen halaman hanya menambah
   tata letak isinya.
     --compact      padding 24px (dasbor, daftar padat)
     --sunken       latar abu cekung
     --flush        tanpa padding (gambar menempel ke tepi)
     --interactive  terangkat saat hover + tombol muncul dari bawah
     .surface-invert  kartu hitam — token warna di dalamnya ikut terbalik
   Bagian: __head (judul + aksi sebaris), __kind (label jenis), __title,
   __sub, __badge, __body, __foot, __price, __meta, __cta.
   ======================================================= */
.card {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  min-inline-size: 0;
  margin: 0;
  padding: var(--space-l);
  background: var(--bg-raised);
  border: var(--border-hair) solid var(--line);
  border-radius: var(--radius-l);
  transition: transform var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out);
}
.card--compact { padding: var(--space-m); }
.card--sunken  { background: var(--bg-sunken); }
.card--flush   { padding: 0; overflow: clip; }
.card.surface-invert { border-color: transparent; }
.card--interactive:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-l);
  border-color: var(--line-strong);
}

.card__head {
  display: flex;
  flex-wrap: wrap;
  align-items: start;
  justify-content: space-between;
  gap: var(--space-2xs) var(--space-s);
}
.card__head--center { align-items: center; }
/* Label jenis di pojok kartu: emblem + .overline. */
.card__kind { display: inline-flex; align-items: center; gap: var(--space-2xs); }
/* Satu langkah lebih kecil dari judul blok: judul materi bisa dua sampai
   tiga baris. text-wrap: balance membagi baris sama panjang. */
/* Judul kartu: Hanken Grotesk tebal, bukan Farro — lihat --text-card-title.
   Berlaku untuk semua kartu (katalog, dasbor, kelas aktif) karena semuanya
   memakai kelas ini, apa pun tag heading-nya. */
.card__title {
  font-family: var(--font-sans);
  font-size: var(--text-card-title);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-snug);
  line-height: var(--leading-snug);
  text-wrap: balance;
}
.card__sub { margin-block-start: var(--space-3xs); font-size: var(--step--1); color: var(--fg-muted); }
/* Badge dipaksa selebar isinya, bukan selebar kolom kartu. */
.card__badge { align-self: start; }
.card__body { color: var(--fg); font-size: var(--step--1); line-height: var(--leading-prose); }

/* Kaki kartu didorong ke dasar supaya tombol dan harga berbaris rapi
   meski panjang isi tiap kartu berbeda. */
.card__foot {
  margin-block-start: auto;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-s);
  padding-block-start: var(--space-s);
  border-block-start: var(--border-hair) solid var(--line);
}
/* Sederajat dengan .card__title, bukan lebih besar — kalau harga lebih
   nyaring dari judul, hierarkinya terbalik. */
.card__price { font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--text-card-title); white-space: nowrap; }
.card__meta { font-size: var(--step--2); color: var(--fg-muted); }

/* Bawaan (peranti sentuh): tombol berada di alur normal di bawah baris kaki,
   supaya tetap bisa ditekan tanpa hover. */
.card__cta { margin-block-start: var(--space-s); inline-size: 100%; }

/* Di peranti berkursor tombol disembunyikan di bawah tepi kartu lalu naik
   saat hover — tidak ada ruang kosong menganggur dan tinggi kartu tetap. */
@media (hover: hover) and (pointer: fine) {
  .card--interactive { position: relative; overflow: clip; }
  .card--interactive .card__cta {
    position: absolute;
    inset-inline: var(--space-l);
    inset-block-end: var(--space-l);
    /* WAJIB: inline-size dari aturan dasar (100%) menimpa lebar hasil
       inset-inline dan membuat tombol meluber keluar kartu. */
    inline-size: auto;
    margin: 0;
    transform: translateY(calc(var(--space-l) + var(--control-h)));
    transition: transform var(--dur-base) var(--ease-out);
  }
  .card--interactive:hover .card__cta,
  .card--interactive:focus-within .card__cta { transform: none; }

  /* Baris kaki meredup saat tombol naik — pergantiannya terbaca sengaja.
     Hanya opacity, bukan visibility, supaya tetap terbaca pembaca layar. */
  .card--interactive .card__foot { transition: opacity var(--dur-base) var(--ease-out); }
  .card--interactive:hover .card__foot,
  .card--interactive:focus-within .card__foot { opacity: 0; }
}

/* =======================================================
   DAFTAR KETERANGAN — label kiri, nilai kanan, bergaris per baris.
   ======================================================= */
.meta-list { display: grid; gap: var(--space-2xs); margin: 0; }
.meta-list > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-s);
  padding-block-end: var(--space-2xs);
  border-block-end: var(--border-hair) solid var(--line);
  font-size: var(--step--1);
}
.meta-list dt { color: var(--fg-muted); }
.meta-list dd { margin: 0; font-weight: var(--weight-semibold); font-variant-numeric: tabular-nums; }
/* Satu garis pemisah saja di antara dua blok: baris terakhir daftar sudah
   bergaris bawah, jadi kaki kartu yang menyusul yang mengalah. */
.meta-list + .card__foot {
  border-block-start: 0;
  padding-block-start: 0;
}

/* =======================================================
   POPOVER — permukaan untuk SEMUA panel yang mengambang: dropdown menu
   navigasi, panel combobox, kalender. Posisi & cara muncul diatur
   komponen pemiliknya; popover hanya memberi bidang, garis, dan bayangan.
     bawaan   garis --line + bayangan (lepas dari pemicunya)
     --field  garis hitam — panel yang menempel pada isian yang sedang
              fokus, jadi garisnya menyambung dengan garis isian itu
   ======================================================= */
.popover {
  z-index: var(--z-overlay);
  background: var(--bg-raised);
  border: var(--border-hair) solid var(--line);
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-l);
}
.popover--field { border-color: var(--clr-black); }
@keyframes popover-in    { from { opacity: 0; translate: 0 -0.35rem; } }
@keyframes popover-in-up { from { opacity: 0; translate: 0 0.35rem; } }

/* =======================================================
   MENU — daftar butir yang bisa dipilih di dalam popover atau sidebar:
   rumpun & topik di dropdown Kelas, opsi combobox, riwayat Copilot.
     hover            bidang abu tipis
     [aria-current] / [aria-expanded="true"]  bidang abu + tebal
     [data-active]    sorotan papan ketik — bidang ungu muda
     [aria-selected]  tebal (terpilih di combobox)
   ======================================================= */
.menu-list {
  display: grid;
  gap: calc(var(--space-3xs) / 2);
  margin: 0;
  padding: 0;
  list-style: none;
}
.menu-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  inline-size: 100%;
  min-block-size: 2.5rem;
  padding: var(--space-2xs) var(--space-xs);
  border: 0;
  border-radius: var(--radius-s);
  background: none;
  color: var(--fg);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  text-align: start;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out);
}
.menu-item:hover,
.menu-item[aria-expanded="true"] { background: color-mix(in oklab, var(--fg) 7%, transparent); text-decoration: none; }
.menu-item:is([aria-current="page"], [aria-current="true"]) {
  background: color-mix(in oklab, var(--fg) 7%, transparent);
  font-weight: var(--weight-semibold);
}
.menu-item[data-active="true"] { background: var(--accent-mid); }
.menu-item[aria-selected="true"] { font-weight: var(--weight-semibold); }
/* Teks panjang dipotong dengan elipsis, bukan membungkus baris. */
.menu-item--truncate { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Butir berbagian — ikon · teks + keterangan · status. Dipakai daftar
   materi di halaman belajar. Status = lingkaran kosong; selesai
   (data-state="done") = lingkaran hitam bercentang. Terkunci
   (data-locked) = teks redup, ikon gembok dari markup. */
.menu-item__icon { display: grid; place-items: center; flex: none; color: var(--fg-muted); }
.menu-item__icon .icon { --icon-size: 1rem; }
.menu-item__text { flex: 1; min-inline-size: 0; display: grid; gap: 0.1rem; line-height: var(--leading-snug); }
.menu-item__meta { font-size: var(--step--2); font-weight: var(--weight-body); color: var(--fg-muted); }
.menu-item__status {
  display: grid;
  place-items: center;
  flex: none;
  inline-size: 1.25rem;
  block-size: 1.25rem;
  border: var(--border-bold) solid var(--clr-gray-300);
  border-radius: var(--radius-pill);
  color: transparent;
  transition: background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.menu-item__status .icon { --icon-size: 0.75rem; stroke-width: 3; }
.menu-item[data-state="done"] .menu-item__status { background: var(--fg); border-color: var(--fg); color: var(--bg); }
.menu-item[data-locked] { color: var(--fg-muted); }

/* =======================================================
   TABEL — satu gaya untuk tabel data (riwayat try out) dan tabel
   perbandingan (harga). Pembungkus .table-wrap menggulir mendatar.
     kepala   gaya .overline
     --compare  kepala Farro bergaris hitam 2px, sel di tengah, kolom
                pertama menempel saat digeser
   ======================================================= */
/* position: relative WAJIB — teks .visually-hidden di dalam sel berposisi
   absolut; tanpa blok penampung di sini ia lolos keluar dari area gulir
   dan melebarkan seluruh halaman di ponsel (dulu 647px di layar 360px). */
.table-wrap { position: relative; overflow-x: auto; }
.table { inline-size: 100%; border-collapse: collapse; font-size: var(--step--1); }
.table :is(th, td) {
  padding: var(--space-xs) var(--space-s);
  border-block-end: var(--border-hair) solid var(--line);
  text-align: start;
  white-space: nowrap;
}
.table thead th {
  font-size: var(--step--2);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--fg-muted);
}
.table tbody th { font-weight: var(--weight-semibold); white-space: normal; min-inline-size: 12rem; }
.table [data-num] { text-align: end; font-variant-numeric: tabular-nums; }

/* Tabel data di dalam kartu: tepi kiri-kanan rata dengan isi kartu. */
.table--flush :is(th, td):first-child { padding-inline-start: 0; }
.table--flush :is(th, td):last-child { padding-inline-end: 0; text-align: end; }
.table--flush tbody tr:last-child :is(th, td) { border-block-end: 0; }

.table--compare :is(th, td) { padding: var(--space-s) var(--space-m); }
.table--compare thead th {
  font-family: var(--font-display);
  font-size: var(--step-0);
  font-weight: var(--weight-display);
  letter-spacing: var(--tracking-snug);
  text-transform: none;
  color: var(--fg);
  border-block-end: var(--border-bold) solid var(--line-strong);
}
.table--compare tbody th { font-weight: var(--weight-medium); min-inline-size: 14rem; }
.table--compare td,
.table--compare thead th:not(:first-child) { text-align: center; }
.table--compare td[data-yes] { font-weight: var(--weight-semibold); }
.table--compare td[data-no] { color: var(--fg-subtle); }
/* Kolom nama fitur menempel saat tabel digeser mendatar — tanpa itu, di
   ponsel "Ya / —" kehilangan label barisnya. Latarnya menyamai seksi. */
.table--compare tbody th,
.table--compare thead th:first-child {
  position: sticky;
  inset-inline-start: 0;
  z-index: 1;
  background: var(--table-bg, var(--bg));
}
.section--sunken .table--compare { --table-bg: var(--bg-sunken); }
@media (max-width: 47.99rem) {
  .table--compare :is(th, td) { padding-inline: var(--space-s); }
  .table--compare tbody th {
    min-inline-size: 9rem;
    /* Garis pemisah hanya di ponsel, saat kolom ini memang menempel. */
    box-shadow: inset calc(var(--border-hair) * -1) 0 0 var(--line);
  }
}

/* =======================================================
   KEADAAN KOSONG — hasil saring nihil, daftar belum berisi.
   ======================================================= */
.empty-state {
  padding-block: var(--space-3xl);
  text-align: center;
  color: var(--fg);
}


/* ##########################################################################
   C. FORMULIR
   ########################################################################## */

.form { display: grid; gap: var(--space-m); }

/* Pesan terkirim — bidang ungu, huruf hitam, garis hitam. */
.form__status {
  padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-m);
  background: var(--accent);
  color: var(--accent-fg);
  border: var(--border-bold) solid var(--clr-black);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
}

.field { display: grid; gap: var(--space-2xs); }
.field__label {
  font-size: var(--step--1);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-snug);
}
/* Label + tautan sebaris ("Kata sandi" · "Lupa?"). */
.field__label-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-s);
}
.field__hint { font-size: var(--step--2); color: var(--fg); }
/* Galat tidak boleh bergantung pada warna saja, dan ungu gagal kontras
   sebagai warna teks. Jadi: huruf hitam di atas bidang ungu muda. */
.field__error {
  justify-self: start;
  padding: 0.25em 0.6em;
  background: var(--accent-mid);
  color: var(--clr-black);
  border-radius: var(--radius-s);
  font-size: var(--step--2);
  font-weight: var(--weight-semibold);
}
.field__error:empty { display: none; }
/* Saran pengganti, mis. username yang sudah dipakai. */
.field__suggest { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2xs); }
.field__suggest-label { font-size: var(--step--2); color: var(--fg-muted); }

/* Fieldset sebagai .field — untuk kelompok radio/checkbox. Legend tidak
   ikut gap grid, jadi jaraknya diberi langsung. */
fieldset.field { min-inline-size: 0; padding: 0; border: 0; }
fieldset.field > legend { padding: 0; margin-block-end: var(--space-2xs); }

/* =======================================================
   INPUT, SELECT, TEXTAREA — satu kotak isian.
   1px, bukan 2px — garis tebal membuat formulir terasa berat. Tinggi
   dipatok --control-h agar sejajar dengan tombol; textarea dikecualikan.
   Fokus: garis hitam + cincin ungu 3px (ungu sebagai bidang).
   ======================================================= */
.input, .textarea, .select {
  inline-size: 100%;
  padding-inline: 1em;
  background: var(--bg-raised);
  border: var(--border-hair) solid var(--line);
  border-radius: var(--radius-m);
  font-size: var(--step-0);
  color: var(--fg);
  transition: border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
.input, .select { block-size: var(--control-h); padding-block: 0; }
.input::placeholder, .textarea::placeholder { color: var(--fg-subtle); }
.input:focus, .textarea:focus, .select:focus {
  outline: none;
  border-color: var(--clr-black);
  box-shadow: 0 0 0 3px var(--accent);
}
.input[aria-invalid="true"], .textarea[aria-invalid="true"], .select[aria-invalid="true"] {
  border-color: var(--clr-black);
}
.textarea { resize: vertical; min-block-size: 8rem; padding-block: 0.7em; line-height: var(--leading-prose); }
/* Tanpa JS <select> bawaan yang tampil, dengan panah gambar CSS. Dengan JS
   ia diganti combobox (lihat bawah) yang memakai kelas .select juga. */
.select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 1.25rem) 55%, calc(100% - 0.9rem) 55%;
  background-size: 0.36rem 0.36rem, 0.36rem 0.36rem;
  background-repeat: no-repeat;
  padding-inline-end: 2.75rem;
}
.input--small { --control-h: var(--control-h-small); font-size: var(--step--1); border-radius: var(--radius-s); }

/* Input berikon — ikon di pembungkus, bukan di .field, karena .field juga
   memuat label dan pesan galat. */
.input-wrap { position: relative; display: block; }
.input-wrap__icon {
  position: absolute;
  inset-inline-start: var(--space-s);
  inset-block-start: 50%;
  translate: 0 -50%;
  inline-size: 1.15rem;
  block-size: 1.15rem;
  color: var(--fg-subtle);
  pointer-events: none;
  transition: color var(--dur-fast) var(--ease-out);
}
.input-wrap:focus-within .input-wrap__icon { color: var(--fg); }
.input--with-icon { padding-inline-start: calc(var(--space-s) * 2 + 1.15rem); }

/* Input berawalan (@, +62) — pembungkusnya yang berperan sebagai kotak,
   supaya lebar awalan bebas tanpa hitungan padding manual. */
.input-affix {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  block-size: var(--control-h);
  padding-inline: 1em;
  background: var(--bg-raised);
  border: var(--border-hair) solid var(--line);
  border-radius: var(--radius-m);
  font-size: var(--step-0);
  transition: border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
.input-affix:focus-within {
  border-color: var(--clr-black);
  box-shadow: 0 0 0 3px var(--accent);
}
.input-affix:has([aria-invalid="true"]) { border-color: var(--clr-black); }
.input-affix > .input {
  flex: 1;
  min-inline-size: 0;
  block-size: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
}
.input-affix__prefix { flex: none; font-weight: var(--weight-medium); }
.input-affix__prefix--divided {
  align-self: stretch;
  display: grid;
  place-items: center;
  padding-inline-end: var(--space-xs);
  border-inline-end: var(--border-hair) solid var(--line);
}
/* Status di ujung kanan input: memutar saat mengecek, centang saat lolos. */
.input-affix__status { flex: none; display: grid; place-items: center; inline-size: 1.5rem; block-size: 1.5rem; }
.input-affix__status > * { grid-area: 1 / 1; display: none; }
.input-affix__status[data-state="checking"] .spinner { display: block; }
.input-affix__status[data-state="ok"] .icon {
  display: block;
  inline-size: 1.5rem;
  block-size: 1.5rem;
  padding: 0.3rem;
  border-radius: var(--radius-pill);
  background: var(--clr-black);
  color: var(--clr-white);
  stroke-width: 3;
}

/* =======================================================
   KARTU OPSI — pilihan besar yang bisa diklik: kartu tujuan belajar
   (<label> + checkbox), pemantik obrolan Copilot (<button>), dan pilihan
   jawaban kuis (--row). Satu bentuk: garis 1px abu, hover garis hitam.
     terpilih   bidang ungu + garis hitam (ungu sebagai bidang)
   Bagian: __title, __desc, __check (kotak centang di kanan).
   ======================================================= */
.option-list { display: grid; gap: var(--space-2xs); margin: 0; padding: 0; list-style: none; }
.option-card {
  position: relative;
  display: grid;
  align-content: start;
  gap: var(--space-3xs);
  inline-size: 100%;
  padding: var(--space-s) var(--space-m);
  border: var(--border-hair) solid var(--line);
  border-radius: var(--radius-l);
  background: var(--bg-raised);
  color: var(--fg);
  text-align: start;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.option-card:hover { border-color: var(--clr-black); }
.option-card:has(.option-card__check) { padding-inline-end: calc(var(--space-s) * 2 + 1.5rem); }
.option-card:has(:focus-visible) {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
}
.option-card__title { font-weight: var(--weight-semibold); font-size: var(--step-0); line-height: var(--leading-snug); }
.option-card__desc { font-size: var(--step--1); line-height: var(--leading-normal); }
.option-card__check {
  position: absolute;
  inset-inline-end: var(--space-s);
  inset-block-start: 50%;
  translate: 0 -50%;
  display: grid;
  place-items: center;
  inline-size: 1.5rem;
  block-size: 1.5rem;
  border: var(--border-bold) solid var(--line);
  border-radius: var(--radius-s);
  background: var(--clr-white);
  color: var(--clr-white);
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.option-card__check .icon { --icon-size: 1rem; stroke-width: 3; scale: 0; transition: scale var(--dur-base) var(--ease-spring); }
.option-card:has(:checked) { background: var(--accent); border-color: var(--clr-black); }
.option-card:has(:checked) .option-card__check { background: var(--clr-black); border-color: var(--clr-black); }
.option-card:has(:checked) .option-card__check .icon { scale: 1; }

/* Baris: emblem huruf · teks · ikon hasil. Untuk pilihan jawaban. */
.option-card--row {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  min-block-size: var(--control-h);
  padding: var(--space-2xs) var(--space-s);
  border-radius: var(--radius-m);
  font-size: var(--step--1);
}
.option-card--row > .icon { margin-inline-start: auto; --icon-size: 1.1rem; stroke-width: 2.5; }
.option-card:disabled { cursor: default; }
.option-card:disabled:hover { border-color: var(--line); }
/* Hasil jawaban — tidak bergantung warna saja: ikonnya berbeda dan
   hasilnya ditulis. Benar = bidang ungu; salah = garis hitam putus. */
.option-card[data-result] .emblem { background: var(--clr-black); color: var(--clr-white); }
.option-card[data-result="right"],
.option-card[data-result="right"]:hover { background: var(--accent); border-color: var(--clr-black); }
.option-card[data-result="wrong"],
.option-card[data-result="wrong"]:hover { border-color: var(--clr-black); border-style: dashed; }

/* =======================================================
   COMBOBOX — pengganti <select> bergaya Select2 (main.js modul 11).
   Pemicunya memakai .select dan panelnya .popover.popover--field, opsinya
   .menu-item — jadi tinggi, garis, radius, dan cincin fokus otomatis sama
   dengan isian lain, dan sorotan opsinya sama dengan menu lain.
   ======================================================= */
.combo { position: relative; }

.combo__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs);
  padding-inline-end: 1em;
  background-image: none;   /* panah bawaan .select diganti ikon */
  text-align: start;
  cursor: pointer;
}
.combo__value { min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.combo__trigger[data-placeholder="true"] .combo__value { color: var(--fg-subtle); }
.combo__trigger:disabled { cursor: not-allowed; opacity: 0.5; }

.combo__chevron {
  --icon-size: 1.15rem;
  transition: rotate var(--dur-base) var(--ease-out);
}
.combo[data-open="true"] .combo__chevron { rotate: 180deg; }
.combo[data-open="true"] > :is(.combo__trigger, .input) {
  border-color: var(--clr-black);
  box-shadow: 0 0 0 3px var(--accent);
}

/* Isian bebas: ikon panah di ujung kanan, hanya bila ada daftar saran. */
.combo--input > .input { padding-inline-end: 2.75rem; }
.combo--input > .combo__chevron {
  position: absolute;
  /* Diukur dari tepi luar pembungkus, jadi tambahkan garis isian agar
     sejajar dengan panah .combo__trigger (di dalam garis + padding 1em). */
  inset-inline-end: calc(1em + var(--border-hair));
  inset-block-start: calc(var(--control-h) / 2);
  translate: 0 -50%;
  pointer-events: none;
}
.combo--input[data-has-options="false"] > .combo__chevron { display: none; }
.combo--input[data-has-options="false"] > .input { padding-inline-end: 1em; }

.combo__panel {
  position: absolute;
  inset-inline: 0;
  inset-block-start: calc(var(--control-h) + var(--space-3xs));
  overflow: hidden;
  animation: popover-in var(--dur-fast) var(--ease-out);
}
.combo[data-placement="top"] .combo__panel {
  inset-block: auto calc(100% + var(--space-3xs));
  animation-name: popover-in-up;
}

.combo__search {
  position: relative;
  padding: var(--space-2xs);
  border-block-end: var(--border-hair) solid var(--line);
}
.combo__search > .icon {
  position: absolute;
  inset-inline-start: calc(var(--space-2xs) + var(--space-xs));
  inset-block-start: 50%;
  translate: 0 -50%;
  --icon-size: 1rem;
  color: var(--fg-muted);
  pointer-events: none;
}
.combo__search .input { padding-inline-start: calc(var(--space-xs) + 1.5rem); }

.combo__list {
  max-block-size: min(17rem, 45vh);
  padding: var(--space-3xs);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.combo__option { min-block-size: 2.75rem; padding-inline: var(--space-s); font-weight: var(--weight-body); }
.combo__text strong { font-weight: var(--weight-display); text-decoration: underline; text-underline-offset: 0.2em; }
.combo__tick { --icon-size: 1rem; stroke-width: 3; visibility: hidden; }
.combo__option[aria-selected="true"] .combo__tick { visibility: visible; }
.combo__empty { padding: var(--space-s); font-size: var(--step--1); color: var(--fg-muted); }

/* =======================================================
   PEMILIH TANGGAL — pengganti popup <input type="date"> (main.js 11b).
   Satu keluarga dengan combobox: kotak .input-affix, panel
   .popover.popover--field, tombolnya .icon-button.
     terpilih   bidang ungu + huruf hitam tebal (ungu sebagai bidang)
     disorot    bidang ungu muda, sama dengan opsi aktif menu
     hari ini   titik HITAM di bawah angka — bukan ungu (2.21:1 hilang)
     di luar rentang  abu, tanpa hover
   ======================================================= */
.datepicker { position: relative; }

/* Padding kanan dipangkas karena bidang hover tombol sudah memberi jarak —
   ikonnya tetap ±1em dari tepi. */
.datepicker__box { padding-inline-end: 0.35em; }
.datepicker__toggle .icon { --icon-size: 1.2rem; }
.datepicker[data-open="true"] .datepicker__toggle { background: var(--accent-mid); }
.datepicker[data-open="true"] .datepicker__box {
  border-color: var(--clr-black);
  box-shadow: 0 0 0 3px var(--accent);
}

/* Panel tidak ikut selebar kolom: di formulir 30rem sel tanggal akan
   jadi 64px — terlalu renggang untuk dibaca sebagai satu bulan. */
.datepicker__panel {
  --_cell: 2.75rem;   /* 44px — ambang sasaran sentuh */
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: calc(var(--control-h) + var(--space-3xs));
  inline-size: min(100%, 22rem);
  padding: var(--space-xs);
  animation: popover-in var(--dur-fast) var(--ease-out);
}
.datepicker__panel:focus { outline: none; }
.datepicker[data-placement="top"] .datepicker__panel {
  inset-block: auto calc(100% + var(--space-3xs));
  animation-name: popover-in-up;
}

.datepicker__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2xs);
  margin-block-end: var(--space-2xs);
}
/* Judul bulan memakai Farro — satu-satunya huruf display di panel, jadi
   ia yang memberi tahu "ini kalender Tutooria", bukan kalender sistem. */
.datepicker__title {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  min-block-size: var(--control-h-small);
  padding-inline: var(--space-2xs);
  margin-inline-start: calc(var(--space-2xs) * -0.5);
  border: 0;
  border-radius: var(--radius-s);
  background: transparent;
  font-family: var(--font-display);
  font-size: var(--step-0);
  font-weight: var(--weight-display);
  letter-spacing: var(--tracking-snug);
  color: var(--fg);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out);
}
.datepicker__title:hover { background: color-mix(in oklab, var(--fg) 7%, transparent); }
.datepicker__chevron {
  --icon-size: 1rem;
  stroke-width: 2.5;
  transition: rotate var(--dur-base) var(--ease-out);
}
.datepicker[data-view="year"] .datepicker__chevron { rotate: 180deg; }

.datepicker__nav { display: flex; gap: var(--space-3xs); }
.datepicker[data-view="year"] .datepicker__nav { visibility: hidden; }
.datepicker__nav .icon { --icon-size: 1.1rem; }

/* Tinggi badan dipatok = kepala hari + 6 baris, supaya berpindah antara
   tanggal, bulan, dan tahun tidak membuat panel melompat. */
.datepicker__body {
  position: relative;   /* acuan offsetTop untuk menggulir daftar tahun */
  block-size: calc(2rem + var(--_cell) * 6 + var(--space-3xs) * 5);
  overflow: hidden;
}
.datepicker__body > * { animation: datepicker-swap var(--dur-fast) var(--ease-out); }
@keyframes datepicker-swap { from { opacity: 0; } }
.datepicker[data-view="year"] .datepicker__body {
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}

.datepicker__grid {
  inline-size: 100%;
  border-collapse: separate;
  border-spacing: 0 var(--space-3xs);
  margin-block-start: calc(var(--space-3xs) * -1);
  table-layout: fixed;
}
.datepicker__grid th { block-size: 2rem; padding: 0; text-align: center; }
.datepicker__grid td { padding: 0; block-size: var(--_cell); }

.datepicker__cell {
  position: relative;
  display: grid;
  place-items: center;
  inline-size: 100%;
  block-size: 100%;
  padding: 0;
  border: 0;
  border-radius: var(--radius-s);
  background: transparent;
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  font-variant-numeric: tabular-nums;
  color: var(--fg);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out);
}
/* Di pilihan tahun & bulan, titik mulai langsung disorot. Di kalender
   tanggal tidak — sorotan pada tanggal acak mudah dikira terpilih. */
.datepicker__cell:hover,
.datepicker__cell:focus-visible,
.datepicker:not([data-view="day"]) .datepicker__cell[tabindex="0"] { background: var(--accent-mid); }
.datepicker__cell[aria-pressed="true"] {
  background: var(--accent);
  color: var(--accent-fg);
  font-weight: var(--weight-display);
}
.datepicker__cell[aria-disabled="true"] {
  background: transparent;
  color: var(--clr-gray-300);
  cursor: not-allowed;
}
/* Cincin fokus di dalam sel — di luar ia akan menabrak sel tetangga. */
.datepicker__cell:focus-visible {
  outline: var(--border-bold) solid var(--clr-black);
  outline-offset: calc(var(--border-bold) * -1);
  border-radius: var(--radius-s);
}
.datepicker__day[aria-current="date"]::after {
  content: "";
  position: absolute;
  inset-block-end: 0.4rem;
  inset-inline-start: 50%;
  translate: -50% 0;
  inline-size: 0.25rem;
  block-size: 0.25rem;
  border-radius: var(--radius-pill);
  background: currentColor;
}

.datepicker__months,
.datepicker__years {
  display: grid;
  gap: var(--space-3xs);
}
/* Bulan: 3 × 4 mengisi penuh tinggi badan — sasaran ketuk besar. */
.datepicker__months {
  block-size: 100%;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(4, 1fr);
}
.datepicker__years {
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: var(--_cell);
  padding-block: var(--space-3xs);
}


/* ##########################################################################
   D. NAVIGASI
   ########################################################################## */

/* =======================================================
   HEADER SITUS
   ======================================================= */
.site-header {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-header);
  background: color-mix(in oklab, var(--bg) 88%, transparent);
  backdrop-filter: blur(14px);
  border-block-end: var(--border-hair) solid transparent;
  transition: border-color var(--dur-base) var(--ease-out),
              background var(--dur-base) var(--ease-out);
}
.site-header.is-stuck {
  border-block-end-color: var(--line);
  background: color-mix(in oklab, var(--bg) 96%, transparent);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-m);
  block-size: var(--header-h);
}

/* --- Logo --- */
.logo {
  display: block;
  flex: none;
  line-height: 0;
  text-decoration: none;
}
.logo__img {
  block-size: var(--logo-h);
  inline-size: auto;
  aspect-ratio: var(--logo-ratio);
  transition: opacity var(--dur-fast) var(--ease-out);
}
.logo:hover .logo__img { opacity: 0.7; }
.logo:focus-visible { border-radius: var(--radius-s); }

/* =======================================================
   NAVBAR — [Logo] … [Menu] [CTA]. Jarak lega antara kelompok menu dan
   tombol CTA supaya keduanya terbaca sebagai dua kelompok terpisah.
   ======================================================= */
.nav { display: flex; align-items: center; gap: var(--space-xl); }
.nav__list {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  list-style: none;
  margin: 0;
  padding: 0;
}
/* NAV LINK — tautan menu utama: garis bawah 2px yang memuai saat hover,
   menetap saat aktif. */
.nav__link {
  position: relative;
  /* inline-flex untuk SEMUA butir, termasuk <a>. Kalau tautan dibiarkan
     `display: inline`, padding-block-nya tidak menambah tinggi baris,
     sementara <button> yang inline-flex bersifat atomik sehingga padding-nya
     dihitung penuh — itu yang membuat baseline "Kelas" turun 4,5px. */
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  font-size: var(--step--1);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-snug);
  text-decoration: none;
  padding-block: var(--space-2xs);
  color: var(--fg);
  transition: color var(--dur-fast) var(--ease-out);
}
.nav__link::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  block-size: var(--border-bold);
  background: var(--line-strong);
  transform: scaleX(0);
  transform-origin: inline-start;
  transition: transform var(--dur-base) var(--ease-out);
}
.nav__link:hover::after { transform: scaleX(1); }
.nav__link[aria-current="page"] { font-weight: var(--weight-semibold); }
.nav__link[aria-current="page"]::after { transform: scaleX(1); }

/* --- Dropdown "Kelas" --- */
.nav__item { position: relative; }

/* Pemicu dropdown adalah <button> sungguhan, bukan tautan palsu:
   ia mengubah state di halaman, bukan berpindah halaman. */
.nav__trigger {
  border: 0;
  /* padding bawaan <button> membuat garis bawahnya lebih lebar dari tautan lain */
  padding-inline: 0;
  background: none;
  /* Sengaja TIDAK menyetel font apa pun di sini. Baik shorthand `font: inherit`
     maupun `font-size: inherit` akan mengalahkan --step--1 milik .nav__link
     (spesifisitas sama, aturan ini ditulis belakangan). Keluarga huruf sudah
     ditangani reset `button { font: inherit }` di base.css. */
  cursor: pointer;
}
.nav__chevron { transition: transform var(--dur-base) var(--ease-out); }
.nav__trigger[aria-expanded="true"] .nav__chevron { transform: rotate(180deg); }
.nav__trigger[aria-expanded="true"]::after { transform: scaleX(1); }
/* Butir dropdown yang sedang aktif ikut menandai pemicunya. */
.nav__item:has([aria-current="page"]) .nav__trigger { font-weight: var(--weight-semibold); }
.nav__item:has([aria-current="page"]) .nav__trigger::after { transform: scaleX(1); }

/* Panelnya .popover; di sini hanya posisi & cara muncul. */
.nav__menu {
  position: absolute;
  inset-block-start: calc(100% + var(--space-2xs));
  inset-inline-start: calc(var(--space-2xs) * -1);
  padding: var(--space-m);
  box-shadow: var(--shadow-m);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-0.35rem);
  transition: opacity var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out),
              visibility 0s linear var(--dur-fast);
}
.nav__menu[data-open="true"] {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}

.nav__menu-cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(11rem, 1fr));
  gap: var(--space-l);
}
.nav__col-title { margin-block-end: var(--space-2xs); }

/* Baris rumpun & topik memakai .menu-item. Rumpun = <button> karena
   membuka submenu, bukan pindah halaman. */
.nav__sublink,
.nav__leaf { white-space: nowrap; }
.nav__subchevron { transition: transform var(--dur-base) var(--ease-out); }
.nav__sublink[aria-expanded="true"] .nav__subchevron { transform: rotate(180deg); }

/* Submenu memuai di tempat, bukan melayang ke samping: panel terbang mudah
   keluar layar di viewport sempit, sedangkan memuai selalu aman dan perilakunya
   sama persis di panel mobile. Topik berbentuk sama persis dengan rumpun —
   pembeda hierarkinya cukup chevron yang hanya dimiliki baris rumpun. */
.nav__subpanel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-base) var(--ease-inout);
}
.nav__subpanel[data-open="true"] { grid-template-rows: 1fr; }
.nav__subpanel > ul { overflow: hidden; }

/* --- Dua tombol aksi di ujung kanan --- */
.nav__cta { display: flex; align-items: center; gap: var(--space-2xs); }

.nav-toggle { display: none; flex: none; }

/* CTA di bilah header — hanya untuk tablet & ponsel besar. Di sana menu
   tersembunyi di balik tombol ikon, dan bilah selebar 480–1023px terasa
   kosong kalau hanya berisi logo + ikon. Di bawah 30rem ruangnya tidak
   cukup, jadi CTA hanya ada di dalam panel. Selektor dua kelas sengaja:
   .button (display: inline-flex) punya spesifisitas sama. */
.site-header__inner > .site-header__cta { display: none; }
@media (min-width: 30rem) and (max-width: 63.99rem) {
  .site-header__inner > .site-header__cta { display: inline-flex; margin-inline-start: auto; }
}

/* --- Navigasi mobile & tablet (< lg) --- */
@media (max-width: 63.99rem) {
  .nav-toggle { display: grid; }
  .nav {
    position: fixed;
    inset: var(--header-h) 0 auto 0;
    /* Panel bisa lebih tinggi dari layar. Body dikunci saat panel terbuka,
       jadi panel sendiri yang harus bisa digulir. */
    max-block-size: calc(100dvh - var(--header-h));
    overflow-y: auto;
    overscroll-behavior: contain;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-l);
    padding: var(--space-xl) var(--gutter) var(--space-2xl);
    background: var(--bg);
    border-block-end: var(--border-bold) solid var(--clr-black);
    box-shadow: var(--shadow-l);
    transform: translateY(-110%);
    visibility: hidden;
    transition: transform var(--dur-base) var(--ease-out),
                visibility 0s linear var(--dur-base);
  }
  .nav[data-open="true"] {
    transform: translateY(0);
    visibility: visible;
    transition-delay: 0s;
  }
  .nav__list { flex-direction: column; align-items: stretch; gap: 0; }
  .nav__link {
    /* block, bukan inline: garis pemisah harus selebar panel. */
    display: block;
    font-family: var(--font-display);
    font-weight: var(--weight-display);
    font-size: var(--text-h3);
    color: var(--fg);
    padding-block: var(--space-s);
    border-block-end: var(--border-hair) solid var(--line);
  }
  .nav__link::after { display: none; }
  /* Bidang ungu selebar panel penuh — kalau hanya ditarik sebagian,
     tepinya tidak sejajar dengan tepi panel maupun teks tautan lain. */
  .nav__link[aria-current="page"] {
    background: var(--accent);
    color: var(--accent-fg);
    padding-inline: var(--gutter);
    margin-inline: calc(var(--gutter) * -1);
    border-block-end-color: transparent;
  }
  /* display ditulis ulang: .nav__link { display: block } di atas punya
     spesifisitas sama dan menang karena urutan. */
  .nav__trigger {
    display: flex;
    inline-size: 100%;
    justify-content: space-between;
    text-align: start;
  }
  /* Di panel mobile dropdown tidak mengambang — ia memuai di tempat,
     memakai trik grid 0fr→1fr yang sama seperti akordeon. */
  .nav__menu {
    position: static;
    opacity: 1;
    visibility: visible;
    transform: none;
    padding: 0;
    border: 0;
    box-shadow: none;
    background: transparent;
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows var(--dur-base) var(--ease-inout);
  }
  .nav__menu[data-open="true"] { grid-template-rows: 1fr; }
  .nav__menu-cols {
    overflow: hidden;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-m);
  }
  .nav__col-title { padding-inline-start: var(--space-m); }
  .nav__menu .menu-list { gap: 0; }
  .nav__sublink {
    font-size: var(--step-0);
    padding: var(--space-xs) 0 var(--space-xs) var(--space-m);
    border-radius: 0;
    border-block-end: var(--border-hair) solid var(--line);
  }
  .nav__leaf {
    padding-inline-start: var(--space-xl);
    margin-inline-start: var(--space-m);
  }

  .nav__cta { flex-direction: column; align-items: stretch; gap: var(--space-2xs); }
  .nav .button { justify-content: center; }
}

/* Tablet: dua tombol aksi di panel berdampingan sama lebar. */
@media (min-width: 30rem) and (max-width: 63.99rem) {
  .nav__cta { flex-direction: row; }
  .nav__cta .button { flex: 1; }
}

/* =======================================================
   TAB — penyaring sumbu utama. Teks bergaris bawah, bukan pil, supaya
   kepala halaman terasa ringan. Bentuk garis sama dengan .nav__link.
   ======================================================= */
.tabs {
  display: flex;
  gap: var(--space-l);
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  position: relative;
  flex: none;
  padding: var(--space-s) 0;
  border: 0;
  background: none;
  font-size: var(--step-0);
  font-weight: var(--weight-medium);
  color: var(--fg-muted);
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out);
}
.tab::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  inset-block-end: calc(var(--border-hair) * -1);
  block-size: var(--border-bold);
  z-index: 1;
  background: var(--line-strong);
  transform: scaleX(0);
  transition: transform var(--dur-base) var(--ease-out);
}
.tab:hover { color: var(--fg); }
.tab:is([aria-pressed="true"], [aria-selected="true"], [aria-current="page"]) { color: var(--fg); font-weight: var(--weight-semibold); }
.tab:is([aria-pressed="true"], [aria-selected="true"], [aria-current="page"])::after { transform: scaleX(1); }

/* =======================================================
   FOOTER — permukaan hitam (token dibalik di base.css).
   Tata letaknya memakai .row: merek selebar penuh di ponsel & tablet,
   lalu merek + empat kolom tautan sebaris mulai lg.
   ======================================================= */
.site-footer {
  padding-block: var(--space-3xl) var(--space-xl);
}
.site-footer a { text-decoration: none; }
.site-footer a:hover { text-decoration: underline; text-decoration-color: var(--accent); text-decoration-thickness: 2px; }

.footer__top {
  --row-gap: var(--space-xl);
  padding-block-end: var(--space-2xl);
  border-block-end: var(--border-hair) solid var(--line);
}
/* Saat blok merek selebar baris, tautan logo (display: block) ikut
   memanjang dan area ketuknya meluber ke ruang kosong di kanan logo. */
.footer__top .logo { display: inline-block; }
.footer__pitch { max-inline-size: 30ch; font-size: var(--step--1); margin-block-start: var(--space-m); }
.footer__col-title { margin-block-end: var(--space-s); }
.footer__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2xs); font-size: var(--step--1); }
/* Layar sentuh: tautan footer hanya 17px tinggi dengan jarak 8px. Di sini
   jaraknya dipindah ke dalam tautan, jadi tiap baris ±46px dan seluruhnya
   bisa diketuk — tanpa area ketuk yang saling tumpang tindih. */
@media (pointer: coarse) {
  .footer__list { gap: 0; }
  .footer__list a { display: inline-block; padding-block: var(--space-xs); }
}
.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  padding-block-start: var(--space-l);
  font-size: var(--step--2);
  color: var(--fg-muted);
}

/* Logo besar di footer — tanda tangan halaman, memakai berkas logo putih. */
.footer__signature {
  display: block;
  inline-size: min(100%, 60rem);
  margin: var(--space-2xl) auto 0;
  opacity: 0.16;
  pointer-events: none;
}


/* ##########################################################################
   E. BLOK ISI
   ########################################################################## */

/* =======================================================
   FITUR BERNOMOR — nomor memakai .emblem, bukan teks ungu.
   Deretannya memakai .row (row-cols) di halaman.
   ======================================================= */
.feature {
  position: relative;
  padding-block-start: var(--space-l);
  border-block-start: var(--border-bold) solid var(--line-strong);
}
.feature__title { font-size: var(--text-h3); margin-block: var(--space-xs) var(--space-2xs); }
.feature__body { color: var(--fg); font-size: var(--step--1); }

/* =======================================================
   STATISTIK — angka besar + label.
   ======================================================= */
.stat__value {
  font-family: var(--font-display);
  font-size: var(--text-h1);
  font-weight: var(--weight-display);
  line-height: 1;
  letter-spacing: var(--tracking-tight);
  font-variant-numeric: tabular-nums;
  /* Angka tidak boleh dipatah ("68.00 / 0") oleh overflow-wrap dari
     base.css. Kalau kolomnya terlalu sempit, jumlah kolomnya yang diubah. */
  white-space: nowrap;
  overflow-wrap: normal;
}
.stat__label {
  margin-block-start: var(--space-2xs);
  font-size: var(--step--1);
  color: var(--fg);
  text-wrap: balance;
}

/* =======================================================
   KARTU TUTOR — .card.card--flush.card--interactive + foto berukuran
   tetap, teks di atasnya.
   Kartu memakai aspect-ratio, bukan tinggi mengikuti isi. Itu kuncinya:
   tombol bisa memuai tanpa mengubah tinggi kartu, sehingga baris grid
   tidak pernah melompat saat kursor lewat.
   ======================================================= */
.tutor-card {
  position: relative;
  display: block;
  /* 4/5 = rasio berkas fotonya, jadi tidak ada bagian yang terpangkas. */
  aspect-ratio: 4 / 5;
  /* Container query: isinya menyesuaikan LEBAR KARTU, bukan lebar layar. */
  container: tutor-card / inline-size;
  background: var(--clr-gray-100);
}

/* Tempat foto pengajar; bidang abu jadi cadangan bila foto gagal muat. */
.tutor-card__photo {
  position: absolute;
  inset: 0;
  background: var(--clr-gray-100);
}
.tutor-card__photo img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  /* Wajah ada di bagian atas bingkai; teks menutup bagian bawah. */
  object-position: center top;
}

/* Teks duduk langsung di atas foto. Gradien gelap di sini BUKAN hiasan
   melainkan scrim: satu-satunya cara menjamin teks putih terbaca di atas
   foto apa pun. Itu sebabnya ia pengecualian dari aturan "tanpa gradien". */
.tutor-card__overlay {
  /* Satu nilai untuk padding, jarak tombol, dan jarak geser hover —
     ketiganya wajib sama. Mode ringkas cukup mengganti variabel ini. */
  --_pad: var(--space-m);
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  padding: var(--_pad);
  color: var(--clr-white);
  /* padding-atas ekstra + gradien panjang: saat lapisan digeser turun,
     teks harus tetap berada di atas bagian yang gelap. */
  padding-block-start: var(--space-3xl);
  background: linear-gradient(to top,
              rgb(0 0 0 / 0.90) 0%,
              rgb(0 0 0 / 0.80) 35%,
              rgb(0 0 0 / 0.45) 65%,
              rgb(0 0 0 / 0) 100%);
}
.tutor-card__subject {
  font-size: var(--step-0);
  line-height: var(--leading-snug);
  color: var(--clr-white);
}
.tutor-card__tutor {
  margin-block-start: var(--space-3xs);
  font-size: var(--step--1);
  color: rgb(255 255 255 / 0.78);
}
/* Tombol di bawah teks; jaraknya SAMA dengan padding bawah lapisan, jadi
   geseran (padding + tinggi tombol) menyembunyikannya tepat di tepi kartu. */
.tutor-card__cta {
  margin-block-start: var(--_pad);
  inline-size: 100%;
}

/* Mode ringkas — kartu di bawah 14rem. Padding dan huruf turun satu
   jenjang, tombol 44px. --control-h ditimpa di lapisan, bukan di tombol,
   karena jarak geser hover juga membacanya. */
@container tutor-card (max-width: 14rem) {
  .tutor-card__overlay {
    --_pad: var(--space-xs);
    --control-h: 2.75rem;
    padding-block-start: var(--space-2xl);
  }
  .tutor-card__subject { font-size: var(--step--1); }
  .tutor-card__tutor { font-size: var(--step--2); }
  .tutor-card__cta { font-size: var(--step--2); padding-inline: var(--space-xs); }
}

/* Saat tidak di-hover, lapisan teks digeser turun sejauh tinggi tombol +
   jaraknya, sehingga tombol terpotong `overflow: clip`. Hover menariknya
   kembali — tanpa ruang kosong DAN tanpa mengubah tinggi kartu. */
@media (hover: hover) and (pointer: fine) {
  .tutor-card__overlay {
    transform: translateY(calc(var(--_pad) + var(--control-h)));
    transition: transform var(--dur-base) var(--ease-out);
  }
  .tutor-card:hover .tutor-card__overlay,
  .tutor-card:focus-within .tutor-card__overlay { transform: none; }
}

/* =======================================================
   TESTIMONI — .card + tanda kutip (.emblem) + penulis (.avatar).
   ======================================================= */
.quote { gap: var(--space-m); block-size: 100%; }
/* Tanda kutip Farro duduk tinggi di kotaknya; diturunkan supaya tampak
   di tengah. */
.quote__mark { padding-block-start: 0.3em; font-size: calc(var(--_size) * 0.9); }
.quote__text {
  font-size: var(--step-0);
  line-height: var(--leading-normal);
  flex: 1;
}
.quote__author { display: flex; align-items: center; gap: var(--space-s); }
.quote__name { font-weight: var(--weight-semibold); font-size: var(--step--1); }
.quote__role { font-size: var(--step--2); color: var(--fg-muted); }

/* =======================================================
   SLIDER TESTIMONI (Swiper)
   Sebelum Swiper hidup (atau kalau pustakanya gagal dimuat) seksinya
   tetap terbaca sebagai grid biasa — bukan tumpukan yang rusak.
   ======================================================= */
.swiper:not(.swiper-initialized) .swiper-wrapper {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--col-min-m), 1fr));
  gap: var(--grid-gap);
}
.swiper-slide { block-size: auto; }
.swiper-slide .quote { block-size: 100%; }

.slider-nav {
  display: none;
  gap: var(--space-2xs);
  justify-content: flex-end;
  margin-block-start: var(--space-l);
}
[data-testimonial-slider][data-ready="true"] .slider-nav { display: flex; }
.slider-nav .icon-button.swiper-button-disabled {
  opacity: 0.35;
  pointer-events: none;
}

/* =======================================================
   PAKET HARGA — .card + subgrid lintas kartu.
   Paket unggulan = .card.surface-invert.
   ======================================================= */
.plan {
  gap: var(--space-m);
  padding: var(--space-xl) var(--space-l);
  block-size: 100%;
  position: relative;
}

/* Subgrid menyamakan tinggi tiap baris LINTAS kartu — sehingga harga,
   daftar fitur, dan tombol berbaris rapi meski panjang deskripsinya
   berbeda. Browser tanpa subgrid tetap aman memakai flex dari .card. */
@supports (grid-template-rows: subgrid) {
  .plans { grid-template-rows: auto auto 1fr auto; }
  .plan {
    display: grid;
    grid-row: span 4;
    grid-template-rows: subgrid;
    align-content: start;
  }
}

.plan__flag {
  position: absolute;
  inset-block-start: var(--space-m);
  inset-inline-end: var(--space-m);
}
.plan__name { font-size: var(--text-h3); }
.plan__price {
  font-family: var(--font-display);
  font-size: var(--text-h1);
  font-weight: var(--weight-display);
  line-height: 1;
  letter-spacing: var(--tracking-tight);
  font-variant-numeric: tabular-nums;
}
/* Satuan dipisah ke barisnya sendiri: menempel di baseline angka display
   membuatnya mewarisi letter-spacing rapat dan huruf saling menabrak. */
.plan__period {
  display: block;
  margin-block-start: var(--space-3xs);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  font-weight: var(--weight-body);
  letter-spacing: normal;
  line-height: var(--leading-normal);
  color: var(--fg-muted);
}
.plan__desc { font-size: var(--step--1); color: var(--fg); }

/* Daftar centang — fitur paket. Ikon hitam; di kartu hitam ungu. */
.check-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-xs); align-content: start; }
.check-list li {
  display: flex;
  align-items: start;
  gap: var(--space-2xs);
  font-size: var(--step--1);
  line-height: var(--leading-normal);
}
.check-list svg { flex: none; --icon-size: 1.15em; color: var(--fg); margin-block-start: 0.15em; }
.surface-invert .check-list svg { color: var(--accent); }
.check-list li[data-off] { color: var(--fg-muted); text-decoration: line-through; text-decoration-color: var(--fg-subtle); }
.check-list li[data-off] svg { color: var(--fg-subtle); }

/* =======================================================
   AKORDEON (FAQ)
   ======================================================= */
.accordion { border-block-start: var(--border-hair) solid var(--line); }
.accordion__item { border-block-end: var(--border-hair) solid var(--line); }
.accordion__trigger {
  inline-size: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-m);
  padding-block: var(--space-m);
  /* <button> punya padding-inline bawaan ~6px; kalau tidak dinolkan,
     judul akordeon menjorok dan tidak sejajar dengan judul seksi. */
  padding-inline: 0;
  border: 0;
  background: none;
  text-align: start;
  font-family: var(--font-display);
  font-size: var(--text-h4);
  font-weight: var(--weight-display);
  letter-spacing: var(--tracking-snug);
  line-height: var(--leading-snug);
  cursor: pointer;
}
/* Kotak "+" — bentuk .icon-button kecil, tapi bukan tombol sendiri:
   yang bisa diklik seluruh baris. */
.accordion__icon {
  flex: none;
  inline-size: 1.75rem;
  block-size: 1.75rem;
  display: grid;
  place-items: center;
  border: var(--border-bold) solid var(--line-strong);
  border-radius: var(--radius-s);
  transition: transform var(--dur-base) var(--ease-spring),
              background var(--dur-base) var(--ease-out);
}
.accordion__icon .icon { --icon-size: 1rem; }
.accordion__trigger:hover .accordion__icon { background: var(--accent); }
.accordion__trigger[aria-expanded="true"] .accordion__icon {
  transform: rotate(45deg);
  background: var(--accent);
}
.accordion__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-base) var(--ease-inout);
}
.accordion__panel[data-open="true"] { grid-template-rows: 1fr; }
.accordion__panel > div { overflow: hidden; }
.accordion__panel p {
  padding-block-end: var(--space-m);
  max-inline-size: var(--measure);
  color: var(--fg);
  font-size: var(--step-0);
}

/* Berkotak — tiap butir bidang abu cekung dengan chevron, judul Hanken
   Grotesk. Untuk daftar yang dipindai cepat (bab materi), bukan FAQ.
   Bagian tambahan: __label (judul, memuai) dan __meta (angka ringkas). */
.accordion--boxed { display: grid; gap: var(--space-2xs); border-block-start: 0; }
.accordion--boxed .accordion__item { border-block-end: 0; border-radius: var(--radius-m); background: var(--bg-sunken); }
.accordion--boxed .accordion__trigger {
  gap: var(--space-s);
  padding: var(--space-s);
  border-radius: var(--radius-m);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  font-weight: var(--weight-semibold);
  letter-spacing: 0;
}
.accordion__label { flex: 1; min-inline-size: 0; }
.accordion__meta {
  flex: none;
  font-size: var(--step--2);
  font-weight: var(--weight-medium);
  color: var(--fg-muted);
  font-variant-numeric: tabular-nums;
}
.accordion--boxed .accordion__icon { inline-size: auto; block-size: auto; border: 0; }
.accordion--boxed .accordion__icon .icon { --icon-size: 1.1rem; }
.accordion--boxed .accordion__trigger:hover .accordion__icon { background: none; }
.accordion--boxed .accordion__trigger[aria-expanded="true"] .accordion__icon { transform: rotate(180deg); background: none; }
.accordion--boxed .accordion__panel .menu-list { padding: 0 var(--space-2xs) var(--space-2xs); }

/* =======================================================
   MARQUEE (pita berjalan)
   Jarak antar-item hanya diatur di dalam track (gap + padding penutup),
   bukan di pembungkus — kalau keduanya dipakai, sambungan antar salinan
   melebar dan putarannya terlihat tersendat.
   ======================================================= */
.marquee {
  display: flex;
  overflow: hidden;
  user-select: none;
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.marquee__track {
  display: flex;
  flex: none;
  align-items: center;
  gap: var(--space-l);
  min-inline-size: 100%;
  padding-inline-end: var(--space-l);
  animation: marquee-scroll 38s linear infinite;
}
.marquee:hover .marquee__track { animation-play-state: paused; }
.marquee__item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-s);
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--text-h2);
  white-space: nowrap;
  color: var(--fg);
}
.marquee__item::after {
  content: "";
  inline-size: 0.32em;
  block-size: 0.32em;
  border-radius: var(--radius-pill);
  background: var(--fg);
  flex: none;
}
@keyframes marquee-scroll {
  to { transform: translateX(-100%); }
}
@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
  .marquee { mask-image: none; flex-wrap: wrap; gap: var(--space-l); }
}
