/* ============================================================
   AUTH — cangkang "aplikasi"

   Satu halaman untuk semua pintu masuk: /masuk. Splash adalah HUB,
   bukan sekadar layar sambutan — Google, buat akun, dan masuk
   semuanya ada di situ. Sheet bawah cuma memuat formulir
   (daftar / masuk / lupa).

   Kenapa hub-nya di splash: versi sebelumnya menyembunyikan tombol
   Google di balik satu ketukan "Lanjut". Cara masuk tercepat justru
   jadi yang paling tersembunyi. Sekarang tidak ada yang disembunyikan.

   Kenapa satu halaman: tiap pindah halaman di web itu layar putih +
   muat ulang font. Di HP itulah yang paling membedakan "situs" dari
   "aplikasi". Langkah yang berpindah di tempat tidak pernah memutus
   layar.

   ── Progressive enhancement ────────────────────────────────
   Aturan proyek: konten tidak boleh bergantung pada JS untuk TAMPIL.
   CSS dasar di bawah ini adalah halaman biasa — sheet menyatu di
   aliran dokumen dan SEMUA langkah terlihat sekaligus. Tombol Google
   tetap <a> jadi selalu jalan. Yang disembunyikan tanpa JS cuma
   tombol pembuka sheet, karena formulirnya memang sudah terpampang.
   Perilaku aplikasi menyala lewat `.js-app` yang dipasang di <head>.

   Menumpang tokens.css. Sengaja TIDAK meng-import landing.css.
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0; min-height: 100vh; min-height: 100svh;
  font-family: var(--font); color: var(--ink); background: var(--bg);
  line-height: 1.55; -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a { color: inherit; }

/* Latar sama persis dengan landing supaya perpindahan dari / ke
   /masuk tidak terasa seperti pindah situs. */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -2; pointer-events: none;
  background:
    radial-gradient(58vw 48vw at 80% -10%, rgba(253,221,134,.30), transparent 62%),
    radial-gradient(50vw 44vw at 4% 24%, rgba(193,118,27,.08), transparent 60%);
}
body::after {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: url("../assets/paper-grain.svg") repeat; background-size: 220px 220px;
  opacity: .5; mix-blend-mode: multiply;
}

/* ── Kerangka ─────────────────────────────────────────────────
   Padding bawah pakai env(safe-area-inset-*): di iPhone tanpa ini
   tombol utama duduk persis di atas home indicator dan separuh
   ketukan mendarat di gesture sistem, bukan di tombol. */
.app {
  display: flex; flex-direction: column;
  min-height: 100vh; min-height: 100svh;
  padding: env(safe-area-inset-top) env(safe-area-inset-right)
           env(safe-area-inset-bottom) env(safe-area-inset-left);
}

/* ── Splash ───────────────────────────────────────────────── */
.splash {
  position: relative; flex: 1;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  padding: 28px 24px 24px; text-align: center;
}
.splash-mid { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; }

/* ── Wajah-wajah di latar ─────────────────────────────────────
   Produknya tentang menemani orang; layar pertama yang cuma logo
   di atas krem kosong tidak menyampaikan itu sama sekali. Foto
   ditaruh sebagai latar, BUKAN konten: aria-hidden, dan sengaja
   diredupkan supaya tidak pernah menyaingi tombol.

   Catatan: ini masih foto placeholder yang sama dengan landing
   (assets/talent/). Begitu diganti foto talent sungguhan, izin
   tertulisnya harus mencakup pemakaian di layar masuk juga. */
.splash-orbit { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.splash-av {
  position: absolute; border-radius: 50%; object-fit: cover;
  width: 56px; height: 56px;
  box-shadow: 0 0 0 3px rgba(255,253,249,.9), var(--lift-2);
  opacity: .85;
}
/* Sebaran sengaja tidak simetris — grid rapi terbaca sebagai
   katalog, bukan orang. Semuanya menjauh dari sumbu tengah supaya
   tidak pernah menabrak logo & tombol. */
.splash-av:nth-child(1) { top: 7%;  left: 6%;   width: 50px; height: 50px; }
.splash-av:nth-child(2) { top: 3%;  right: 12%; width: 62px; height: 62px; }
.splash-av:nth-child(3) { top: 20%; right: 3%;  width: 44px; height: 44px; opacity: .7; }
.splash-av:nth-child(4) { top: 17%; left: 14%;  width: 40px; height: 40px; opacity: .65; }
.splash-av:nth-child(5) { top: 31%; left: 2%;   width: 52px; height: 52px; opacity: .75; }
.splash-av:nth-child(6) { top: 33%; right: 8%;  width: 46px; height: 46px; opacity: .6; }

.splash-logo {
  width: 88px; height: 88px; margin-bottom: 18px;
  filter: drop-shadow(0 6px 18px rgba(46,14,19,.22));
}
/* Ini wordmark yang berdiri sendiri, jadi ikut sans seperti logo —
   bukan judul. Ukurannya turun dari 54px: pada bobot 700 sans
   memenuhi ruang jauh lebih penuh daripada serif 400. */
/* Di sini wordmark BOLEH dua baris — ini layar splash, namanya berdiri
   sendiri di tengah, dan lockup dua baris memang bentuk yang dipakai
   papan mood. Yang dijaga cuma jangan sampai TIGA baris: text-wrap
   balance membagi rata, max-width mengunci titik pecahnya, dan
   line-height turun ke .95 supaya dua baris tetap terbaca satu blok
   dan bukan dua kalimat. Ukurannya turun dari 48px karena nama 16
   huruf pada 48px memaksa pecah jadi tiga di layar 360px. */
.splash-word {
  font-family: var(--font); font-weight: 700;
  font-size: clamp(30px, 8.6vw, 40px); line-height: .95; letter-spacing: -.035em;
  margin: 0; max-width: 9ch; text-wrap: balance;
  background: var(--grad-brand); -webkit-background-clip: text;
  background-clip: text; color: transparent;
}
.splash-tag {
  margin: 12px 0 0; max-width: 19ch;
  font-size: 15px; color: var(--ink-2);
}

/* Kaki splash — di sinilah semua pintu masuk berada. */
.splash-foot {
  position: relative; z-index: 1;
  width: 100%; max-width: 400px; margin-top: auto; padding-top: 30px;
}
.splash-fine { margin: 14px 0 0; font-size: 12px; color: var(--ink-3); }
.splash-fine a { color: var(--ink-2); text-decoration: underline; text-underline-offset: 2px; }
.splash-masuk { margin-top: 10px; }

/* ── Scrim ────────────────────────────────────────────────── */
.scrim { display: none; }

/* ── Sheet ────────────────────────────────────────────────────
   Dasar = kartu biasa di aliran dokumen (mode tanpa JS). */
.sheet {
  width: 100%; max-width: 424px; margin: 0 auto 40px;
  background: var(--grad-card);
  border-radius: var(--radius-card);
  box-shadow: var(--rim-dark), var(--spec-soft), var(--lift-2);
}
.sheet-body { padding: 30px 26px 26px; }
@media (max-width: 480px) { .sheet-body { padding: 26px 20px 22px; } }

.sheet-grip { display: none; }

/* Baris navigasi sheet: kembali kiri, toggle kanan (pola iOS). */
.sheet-head { padding: 0 18px; }
@media (max-width: 480px) { .sheet-head { padding: 0 16px; } }

.sheet-nav {
  display: flex; align-items: center; justify-content: space-between;
  min-height: 38px; gap: 12px; padding: 8px 0;
}

/* Tombol kembali bulat — sheet, header halaman, admin, dll. */
.sheet-back,
.btn-back {
  display: grid; place-items: center;
  width: 38px; height: 38px; padding: 0; margin: 0;
  border: 0; border-radius: 999px;
  background: var(--grad-card);
  box-shadow: var(--rim-dark), var(--spec-soft), var(--lift-1);
  color: var(--ink);
  text-decoration: none;
  cursor: pointer; flex: none;
  transition: box-shadow .18s ease, transform .14s ease;
}
/* Area sentuh 44px tanpa membesarkan lingkarannya. padding tidak
   bisa dipakai: tombol ini punya latar, jadi padding ikut menggambar.
   Kotak transparan lewat ::after menangkap sentuhan tanpa menggambar
   apa pun — 38px masih di bawah ambang jari, dan meleset di tombol
   kembali berarti orang terjebak di halaman. */
.sheet-back,
.btn-back { position: relative; }
.sheet-back::after,
.btn-back::after { content: ''; position: absolute; inset: -3px; border-radius: 999px; }

.sheet-back svg,
.btn-back svg { width: 20px; height: 20px; }
.sheet-back:hover,
.btn-back:hover { box-shadow: var(--rim-dark), var(--spec-soft), var(--lift-2); }
.sheet-back:active,
.btn-back:active { transform: translateY(1px); }
.sheet-back:focus-visible,
.btn-back:focus-visible { outline: 2px solid var(--brand-2); outline-offset: 2px; }
.sheet-back[hidden],
.btn-back[hidden] { display: none; }

/* Pola header halaman — safe-area + kolom samping 44px untuk tombol 38px */
.app-head {
  display: grid;
  grid-template-columns: 44px 1fr 44px;
  align-items: center;
  padding: calc(12px + env(safe-area-inset-top)) 16px 12px;
}
.app-head--flex {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: calc(12px + env(safe-area-inset-top)) 16px 12px;
}

/* Pill ghost — compact, kanan atas */
.sheet-toggle {
  margin-left: auto; padding: 0 16px;
  border: 0; border-radius: 999px;
  background: var(--grad-card);
  box-shadow: var(--rim-dark), var(--spec-soft), inset 0 -1px 0 rgba(22,25,26,.05), var(--lift-1);
  font: inherit; font-size: 14px; font-weight: 600; letter-spacing: -.012em;
  color: var(--ink); white-space: nowrap;
  min-height: 38px; cursor: pointer; flex: none;
  transition: box-shadow .18s ease, transform .14s ease;
}
.sheet-toggle:hover { box-shadow: var(--rim-dark), var(--spec-soft), inset 0 -1px 0 rgba(22,25,26,.05), var(--lift-2); }
.sheet-toggle:active { transform: translateY(1px); }
.sheet-toggle:focus-visible { outline: 2px solid var(--brand-2); outline-offset: 2px; }
.sheet-toggle[hidden] { display: none; }

/* ── Langkah ──────────────────────────────────────────────────
   Tanpa JS semuanya tampil berurutan, dipisah garis supaya tetap
   terbaca sebagai bagian yang berbeda. */
.step + .step { margin-top: 30px; padding-top: 30px; border-top: 1px solid var(--line); }

.auth-h1 {
  font-family: var(--font-display); font-weight: var(--wt-display);
  font-size: clamp(28px, 7vw, 34px); line-height: 1.04; letter-spacing: -.04em;
  margin: 0 0 8px;
}
.auth-lede { font-size: 14.5px; color: var(--ink-2); margin: 0 0 22px; }

/* ── Tombol ───────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; padding: 14px 22px; border-radius: var(--radius-btn);
  font: inherit; font-size: 15px; font-weight: 600; letter-spacing: -.012em;
  text-decoration: none; cursor: pointer; border: 0; white-space: nowrap;
  /* 44px minimum area sentuh — di bawah itu meleset terus di HP. */
  min-height: 48px;
  transition: transform .14s ease, box-shadow .18s ease, filter .18s ease;
}
.btn-lg { padding: 16px 24px; font-size: 16px; min-height: 54px; }

.btn-primary {
  background: var(--grad-accent); color: var(--accent-ink);
  box-shadow: 0 0 0 1.5px var(--accent-ring), var(--spec),
              0 3px 0 var(--accent-lo), 0 4px 4px rgba(0,0,0,.12), 0 10px 22px var(--accent-glow);
}
.btn-primary:hover:not(:disabled) { filter: brightness(1.04); }
.btn-primary:active:not(:disabled) {
  transform: translateY(2px);
  box-shadow: 0 0 0 1.5px var(--accent-ring), 0 1px 0 var(--accent-lo), 0 1px 2px rgba(0,0,0,.14);
}
.btn-ghost {
  background: var(--grad-card); color: var(--ink);
  box-shadow: var(--rim-dark), var(--spec-soft), inset 0 -1px 0 rgba(22,25,26,.05), var(--lift-1);
}
.btn-ghost:hover:not(:disabled) { box-shadow: var(--rim-dark), var(--spec-soft), inset 0 -1px 0 rgba(22,25,26,.05), var(--lift-2); }
.btn-ghost:active:not(:disabled) { transform: translateY(1px); }

.btn:focus-visible { outline: 2px solid var(--brand-2); outline-offset: 3px; }
.btn:disabled { opacity: .55; cursor: not-allowed; }
/* `display: inline-flex` di atas punya spesifisitas kelas dan
   MENGALAHKAN `display: none` yang diberikan browser untuk
   [hidden]. Tanpa baris ini, tombol yang di-`hidden` dari JS tetap
   terlihat — persis seperti .formsg[hidden] beberapa baris di
   bawah. Berlaku untuk setiap aturan display di berkas ini. */
.btn[hidden] { display: none; }

.btn + .btn { margin-top: 10px; }

/* Tombol teks — untuk pindah langkah, bukan aksi utama. */
.btn-plain {
  display: inline; width: auto; min-height: 0; padding: 0;
  background: none; border: 0; box-shadow: none;
  font: inherit; font-size: inherit; font-weight: 600;
  color: var(--brand-2); cursor: pointer; text-decoration: none;
}
.btn-plain:hover { text-decoration: underline; }
.btn-plain:focus-visible { outline: 2px solid var(--brand-2); outline-offset: 2px; border-radius: 4px; }

/* Tombol yang tugasnya cuma membuka sheet tidak berarti apa-apa tanpa
   JS — formulirnya sudah terpampang di bawah. Harus dideklarasikan
   SESUDAH .btn: specificity-nya sama (0,1,0), jadi yang menang adalah
   yang belakangan. Waktu aturan ini masih di atas, `display:none`-nya
   kalah oleh `.btn { display:inline-flex }` dan tombolnya tetap muncul
   di mode tanpa JS. */
.btn-sheet { display: none; }

/* ── Pemisah ──────────────────────────────────────────────── */
.auth-or {
  display: flex; align-items: center; gap: 14px;
  margin: 16px 0; font-size: 12px; color: var(--ink-3);
}
.auth-or::before, .auth-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }

/* ── Field ────────────────────────────────────────────────── */
.auth-field { margin-bottom: 15px; }
.auth-label {
  display: block; font-size: 12px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3);
  margin-bottom: 7px;
}
.auth-input, .auth-select, .field-select {
  width: 100%; padding: 13px 15px; border-radius: var(--radius-sm);
  font: inherit;
  /* 16px WAJIB: di bawah itu Safari iOS auto-zoom begitu field
     difokus, dan halaman langsung terlihat rusak di HP. */
  font-size: 16px;
  /* min-height eksplisit: kolom yang masih kosong pernah mengempis
     jadi setinggi nol di Safari iOS dan terlihat seperti tidak ada
     kolomnya sama sekali. */
  min-height: 50px;
  color: var(--ink); background: var(--bg-card); border: 0;
  -webkit-appearance: none; appearance: none;
  box-shadow: var(--rim-dark), inset 0 1px 2px rgba(21,22,30,.05);
}
.auth-input::placeholder { color: var(--ink-3); }
.auth-input:focus, .auth-select:focus, .field-select:focus { outline: 2px solid var(--brand-2); outline-offset: 1px; }
.auth-input[aria-invalid="true"], .auth-select[aria-invalid="true"], .field-select[aria-invalid="true"] {
  box-shadow: 0 0 0 1.5px #C0392B, inset 0 1px 2px rgba(21,22,30,.05);
}
.auth-check[aria-invalid="true"] input { outline: 2px solid #C0392B; outline-offset: 1px; }
.auth-hint { margin: 7px 0 0; font-size: 12.5px; color: var(--ink-3); }

/* Galat per kolom — muncul tepat di bawah field yang salah. */
.auth-galat {
  margin: 7px 0 0; font-size: 12.5px; line-height: 1.45; color: #922B21;
}
.auth-galat[hidden] { display: none; }
.auth-check .auth-galat { margin-top: 8px; }

/* appearance:none menghapus panah bawaan, jadi digambar sendiri. */
.auth-select, .field-select {
  padding-right: 42px;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%2369655F' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 16px center;
}
.field-select:disabled { opacity: .55; cursor: not-allowed; }

/* ── Tanggal lahir ────────────────────────────────────────────
   TIGA kolom angka, bukan <input type="date"> dan bukan <select>.

   Alasannya UX, bukan gaya: orang sudah hafal tanggal lahirnya.
   Date picker bawaan membuka kalender yang dimulai dari BULAN INI,
   jadi untuk sampai ke tahun 1998 orang harus menggulung puluhan
   kali — dan di iOS kolomnya bahkan tampil kosong sampai diisi,
   sehingga terlihat seperti tidak ada kolomnya. Mengetik 6 angka
   selesai dalam hitungan detik.

   inputmode="numeric" memunculkan papan angka di HP. */
.tgl-grup { display: grid; grid-template-columns: 1fr 1fr 1.35fr; gap: 10px; }
.tgl-grup .auth-input { text-align: center; padding-left: 8px; padding-right: 8px; }

/* ── Konfirmasi usia & aturan ─────────────────────────────────
   Bukan basa-basi hukum: 18+ dua sisi itu batas yang menentukan
   produk ini boleh hidup atau tidak (lihat CLAUDE.md). Tanggal
   lahirnya divalidasi ulang di server — centang ini persetujuan
   aturan, bukan pengganti gerbang usia. */
.auth-check {
  display: flex; gap: 10px; align-items: flex-start;
  font-size: 13px; color: var(--ink-2); margin: 0 0 18px;
}
.auth-check input { margin: 2px 0 0; width: 18px; height: 18px; accent-color: var(--accent-lo); flex: none; }
.auth-check a { color: var(--brand-2); font-weight: 600; text-decoration: none; }
.auth-check a:hover { text-decoration: underline; }

/* ── Baris kecil di bawah form ────────────────────────────── */
.auth-alt { margin: 18px 0 0; font-size: 14px; color: var(--ink-2); text-align: center; }
.auth-alt + .auth-alt { margin-top: 8px; }
.auth-alt-inline { margin: 4px 0 0; text-align: left; }

/* Catatan opsional — tanpa kotak, bukan sesuatu yang wajib dibaca semua orang. */
.catatan-kecil {
  margin: 16px 0 0; font-size: 12.5px; line-height: 1.5;
  color: var(--ink-3); text-align: center;
}
.catatan-inline { margin: 10px 0 0; text-align: left; }
/* Varian di dalam .step-foot: jaraknya di BAWAH, bukan di atas —
   di sini catatannya mendahului tombol, kebalikan dari pemakaian
   aslinya yang menyusul tombol. Kelasnya dirantai (.catatan-kecil
   .catatan-foot, bukan `.step-foot p`) supaya tidak mengulang
   kesalahan `.plain-card > p`: aturan bertipe-elemen menelan setiap
   <p> berkelas yang kebetulan lewat. */
.catatan-foot { margin: 0 0 10px; }

.auth-note {
  margin: 0 0 16px; padding: 12px 14px; border-radius: var(--radius-sm);
  background: var(--bg-alt); box-shadow: inset 0 0 0 1px var(--line);
  font-size: 12.5px; color: var(--ink-2); line-height: 1.5;
}
.auth-note a { color: var(--brand-2); font-weight: 600; text-decoration: none; }
.auth-note b { color: var(--ink); }

/* Chip email akun Google di /lengkapi */
.akun-chip {
  display: inline-block; margin: 0 0 18px; padding: 7px 14px;
  border-radius: var(--radius-pill); background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px rgba(46,14,19,.16);
  font-size: 13px; font-weight: 600; color: var(--brand-1);
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ── Pesan status ─────────────────────────────────────────────
   Nama kelas mengikuti auth.js: `formsg is-error` / `is-ok`. */
.formsg {
  margin: 0 0 18px; padding: 12px 14px;
  border-radius: var(--radius-sm); font-size: 13.5px; line-height: 1.5;
}
/* Di dalam form: duduk tepat di atas tombol kirim supaya terlihat
   walau sheet sudah di-scroll ke bawah atau keyboard terbuka. */
.formsg-form { margin: 0 0 14px; }
.formsg[hidden] { display: none; }
.formsg.is-error { background: #FDECEA; color: #922B21; box-shadow: inset 0 0 0 1px rgba(146,43,33,.14); }
.formsg.is-ok    { background: var(--accent-soft); color: var(--brand-1); box-shadow: inset 0 0 0 1px rgba(46,14,19,.16); }

/* ── Halaman berbasis token (/reset, /lengkapi, /verifikasi) ──
   Tidak ada splash di sini: orangnya datang dari tautan email atau
   dari callback Google, sudah punya maksud yang jelas.

   Di HP bentuknya sheet yang sudah terbuka (bukan kartu mengambang
   di tengah krem). Brand masuk ke dalam sheet; tombol menempel di
   bawah. Di desktop tetap kartu tengah — layar lebar memang punya
   ruang untuk itu. */
.plain-top { padding: 22px 24px 0; }
.plain-brand {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--font); font-size: 20.5px; font-weight: 700; line-height: 1;
  letter-spacing: -.03em; text-decoration: none; color: var(--ink);
}
.plain-brand img { width: 25px; height: 25px; }
.plain-main { flex: 1; display: grid; place-items: center; padding: 28px 24px 40px; }

.plain-card {
  width: 100%; max-width: 424px;
  background: var(--grad-card);
  border-radius: var(--radius-card);
  box-shadow: var(--rim-dark), var(--spec-soft), var(--lift-2);
  padding: 34px 28px 28px;
}
.plain-card-head { display: none; }
.plain-card-body { min-width: 0; }
.plain-card-form { display: block; }

.kode {
  margin: 0 0 10px; font-size: 11.5px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3);
}
.plain-card h1 {
  font-family: var(--font-display); font-weight: var(--wt-display);
  font-size: clamp(28px, 7vw, 34px); line-height: 1.04; letter-spacing: -.04em;
  margin: 0 0 10px;
}
/* `:not([class])` WAJIB ada di sini. Tanpa itu selektornya (0,1,1)
   mengalahkan SETIAP <p> berkelas di dalam kartu — .kode,
   .akun-chip, .formsg, .catatan-kecil, .auth-alt semuanya (0,1,0) —
   dan aturan ini ditulis lebih belakang pula, jadi menang dua kali.
   Akibat yang paling terasa: .catatan-kecil kehilangan margin-top
   16px-nya dan menempel ke tombol di atasnya, sekaligus membesar
   dari 12,5px jadi 14,5px sehingga tidak lagi terbaca sebagai
   catatan. Ini jebakan CSS #2 di CLAUDE.md, kambuh di berkas lain.

   Jangan ditutup dengan !important pada masing-masing kelas —
   yang benar adalah aturan dasar ini TIDAK ikut campur ke <p>
   yang sudah punya kelasnya sendiri. */
.plain-card > p:not([class]),
.plain-card-body > p:not([class]) {
  font-size: 14.5px; color: var(--ink-2); margin: 0 0 20px;
}
.aksi { margin-top: 22px; }
.aksi[hidden] { display: none; }

.auth-foot { padding: 0 24px 26px; text-align: center; font-size: 12.5px; color: var(--ink-3); }
.auth-foot a { color: var(--ink-2); text-decoration: none; }
.auth-foot a:hover { color: var(--ink); }
.plain-card-body > .auth-foot {
  padding: 18px 0 0;
  margin: 18px 0 0;
  border-top: 1px solid var(--line);
}

/* Sheet penuh di HP. Kelas .plain-page di <body> menandai halaman
   token; tanpa itu aturan di bawah tidak menyentuh /masuk. */
@media (max-width: 480px) {
  html:has(body.plain-page) { height: 100%; }
  body.plain-page {
    /* Sama dengan .js-app: viewport terkunci, yang menggulir isi
       sheet — bukan seluruh dokumen. Tanpa ini foot + tombol
       "mengambang" di bawah lipatan seperti situs. */
    position: fixed; inset: 0; width: 100%;
    height: 100%; overflow: hidden;
  }
  body.plain-page .app {
    height: 100%;
    padding-left: 0;
    padding-right: 0;
    padding-bottom: 0;
  }
  body.plain-page .plain-top { display: none; }
  body.plain-page .plain-main {
    display: flex; flex-direction: column;
    flex: 1; min-height: 0;
    /* Sedikit celah di atas = sheet yang sudah terbuka, bukan
       halaman penuh yang menempel ke status bar. */
    padding: max(10px, env(safe-area-inset-top)) 0 0;
    place-items: stretch;
  }
  body.plain-page .plain-card {
    flex: 1; min-height: 0;
    max-width: none;
    display: flex; flex-direction: column;
    border-radius: var(--radius-card) var(--radius-card) 0 0;
    padding: 0;
    box-shadow: var(--rim-dark), var(--spec-soft), 0 -2px 10px rgba(60,44,16,.08);
  }
  body.plain-page .plain-card-head {
    display: block; flex: none;
    padding: 8px 16px 8px;
    background: var(--bg-card);
    touch-action: none; /* geser turun ditangani JS, bukan scroll */
  }
  body.plain-page .plain-card-grip {
    display: block;
    width: 38px; height: 4px;
    margin: 4px auto 10px;
    border-radius: 99px;
    background: var(--line);
  }
  body.plain-page .plain-card-nav {
    justify-content: flex-start;
    gap: 10px;
    padding: 0;
    min-height: 38px;
  }
  body.plain-page .plain-card-nav .plain-brand {
    font-size: 18px;
  }
  body.plain-page .plain-card.is-dragging {
    transition: none;
  }
  body.plain-page .plain-card.is-dismissing {
    transition: transform .28s cubic-bezier(.32,.72,0,1), opacity .24s ease;
    transform: translateY(110%);
    opacity: .4;
  }
  /* Form mengisi sisa sheet: body gulir, tombol diam di dasar. */
  body.plain-page .plain-card-form {
    flex: 1 1 auto; min-height: 0;
    display: flex; flex-direction: column;
  }
  body.plain-page .plain-card-body {
    flex: 1 1 auto; min-height: 0;
    overflow: auto; -webkit-overflow-scrolling: touch;
    padding: 4px 20px 18px;
  }
  body.plain-page .plain-card-body > .auth-foot {
    margin-top: 22px;
    padding-top: 16px;
    padding-bottom: 4px;
  }
  /* Tombol di luar area gulir — selalu di lipatan, tidak perlu
     sticky. Margin negatif tidak dipakai: padding ada di sini. */
  body.plain-page .plain-card .step-foot {
    flex: none;
    margin-top: 0;
    padding: 12px 20px calc(env(safe-area-inset-bottom) + 16px);
    background: var(--bg-card);
    box-shadow: 0 -1px 0 var(--line);
  }
  body.plain-page .plain-card .step-foot .formsg-form { margin-bottom: 10px; }
  body.plain-page .plain-card .aksi.step-foot {
    display: grid; gap: 10px; margin-top: 0;
  }
  body.plain-page .plain-card .aksi.step-foot[hidden] { display: none; }
}

@media (min-width: 481px) {
  /* Desktop: head brand di dalam kartu ikut tampil supaya markup
     sama; plain-top lama (kalau masih ada di halaman lain) tetap. */
  .plain-card-head {
    display: block;
    margin: -10px 0 18px;
  }
  .plain-card-grip { display: none; }
  .plain-card-nav {
    justify-content: flex-start;
    gap: 10px;
    padding: 0;
    min-height: 38px;
  }
  .plain-card .step-foot {
    margin-top: 22px;
  }
  .plain-card .aksi.step-foot {
    display: grid; gap: 10px;
  }
  .plain-card .aksi.step-foot[hidden] { display: none; }
}

/* Ikon bulat untuk halaman hasil (/verifikasi) */
.auth-ic {
  width: 60px; height: 60px; margin: 0 0 18px; border-radius: 50%;
  display: grid; place-items: center; font-size: 25px;
  background: var(--accent-soft); box-shadow: inset 0 0 0 1px rgba(46,14,19,.16);
}

/* ============================================================
   KOMPONEN APP — dipakai di halaman login+ (/home, /jadwal, …)
   ============================================================ */

/* Label langkah uppercase — "1 · Pilih layanan", dll. */
.step-label {
  font-size: 10.5px; font-weight: 700; letter-spacing: .11em;
  text-transform: uppercase; color: var(--ink-3); margin: 0 0 9px;
}
.step-label--spaced { margin-top: 22px; }
.step-label[hidden] { display: none; }

/* Kartu profil ringkas: avatar + nama di baris checkout / pemesanan. */
.app-card {
  display: flex; align-items: center; gap: 10px; margin-bottom: 16px;
}
.app-card-teks { min-width: 0; }
.app-card .nm {
  font-size: 15px; font-weight: 700; letter-spacing: -.015em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.app-card .mt { font-size: 12px; color: var(--ink-3); }
.app-card-av {
  width: 40px; height: 40px; border-radius: 50%; flex: none;
  overflow: hidden; position: relative; display: grid; place-items: center;
  background: var(--bg-alt); box-shadow: var(--rim-dark);
}
.app-card-av img {
  width: 100%; height: 100%; object-fit: cover;
  filter: blur(7px); transform: scale(1.15);
}
.app-card-inisial {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-family: var(--font-display); font-weight: var(--wt-display); font-size: 18px; color: var(--ink-3);
}

/* Footer sticky checkout — ringkasan + CTA selalu terjangkau di mobile. */
.sticky-foot {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 6;
  padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
  background: rgba(247,241,230,.96); backdrop-filter: blur(14px);
  box-shadow: 0 -1px 0 var(--line), 0 -8px 24px rgba(21,22,30,.06);
}
.sticky-foot[hidden] { display: none; }
.sticky-foot-bar {
  display: flex; align-items: center; gap: 12px;
  max-width: 520px; margin: 0 auto;
}
.sticky-foot-teks { min-width: 0; flex: 1; }
.sticky-foot-jdl {
  display: block; font-size: 14px; font-weight: 700; letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sticky-foot-sub {
  display: block; font-size: 12px; color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.sticky-foot-sub.is-kurang { color: #922B21; font-weight: 600; }
.sticky-foot-btn {
  flex: none; width: auto; min-width: 118px;
  padding: 12px 18px; min-height: 46px; font-size: 14px; white-space: nowrap;
}
.sticky-foot-btn.is-tunggu,
.sticky-foot-btn.is-tunggu:disabled {
  background: var(--bg-alt); color: var(--ink-3);
  box-shadow: inset 0 0 0 1px var(--line); opacity: 1; cursor: not-allowed; transform: none;
}
.sticky-foot-btn.is-topup {
  background: var(--grad-card); color: var(--accent-ink);
  box-shadow: var(--rim-dark), var(--spec-soft), var(--lift-1);
}
.sticky-foot-cat {
  max-width: 520px; margin: 6px auto 0; font-size: 10.5px;
  color: var(--ink-3); text-align: center; line-height: 1.4;
}
.sticky-foot-cat[hidden] { display: none; }

/* Sheet konfirmasi + scrim — ganti paket, lapor sesi, dll. */
.confirm-scrim {
  position: fixed; inset: 0; z-index: 20;
  background: rgba(21,22,30,.42);
  opacity: 0; pointer-events: none;
  transition: opacity .25s ease;
}
.confirm-scrim.is-on { opacity: 1; pointer-events: auto; }
.confirm-scrim[hidden] { display: none; }

.confirm-sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 21;
  max-height: 86svh; overflow-y: auto;
  border-radius: var(--radius-card) var(--radius-card) 0 0;
  background: var(--bg-card);
  box-shadow: 0 -10px 40px rgba(60,44,16,.18);
  padding-bottom: calc(18px + env(safe-area-inset-bottom));
}
.confirm-sheet[hidden] { display: none; }
.confirm-sheet:not(.confirm-sheet--slide):not([hidden]) {
  animation: confirm-sheet-in .22s ease-out;
}
@keyframes confirm-sheet-in {
  from { transform: translateY(14px); opacity: .6; }
}
.confirm-sheet--slide {
  left: 50%; right: auto; width: 100%; max-width: 460px;
  transform: translate(-50%, 100%);
  transition: transform .3s cubic-bezier(.32,.72,0,1);
  padding: 10px 20px calc(24px + env(safe-area-inset-bottom));
  animation: none;
}
.confirm-sheet--slide.is-on { transform: translate(-50%, 0); }
.confirm-sheet-grip {
  width: 40px; height: 4px; margin: 10px auto 4px;
  border-radius: 99px; background: var(--line);
}
.confirm-sheet-body { padding: 8px 20px 0; }
.confirm-sheet-body h2 {
  margin: 0 0 12px; font: var(--wt-display) 26px/1.1 var(--font-display); letter-spacing: -.03em;
}
.confirm-sheet-body p {
  margin: 0 0 10px; font-size: 13.5px; line-height: 1.5; color: var(--ink-2);
}
.confirm-sheet-note { color: var(--ink-3); font-size: 12.5px; }
.confirm-sheet-actions {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 18px;
}
.confirm-sheet-actions .btn { margin: 0; }

/* Scrim tanpa fade — cukup [hidden] on/off (beranda filter/setelan). */
.confirm-scrim--instant {
  opacity: 1; pointer-events: auto; transition: none;
}

/* Tab bar horizontal — admin & talent. */
/* padding-top + margin-top negatif, bukan sekadar padding-bottom.
   `overflow-x: auto` menjadikan baris ini kotak gulir, dan kotak
   gulir MEMOTONG di kedua sumbu — overflow-y ikut jadi auto, tidak
   bisa dibiarkan visible. Tab aktif punya cincin 1,5px di LUAR
   kotaknya (box-shadow 0 0 0 1.5px), jadi sisi atasnya terpotong
   rata dan terbaca seperti pil yang kecrop. Sudah kejadian.
   Margin negatifnya membatalkan padding itu, jadi posisinya di
   layar tidak bergeser sedikit pun. Sisi kiri-kanan diberi 2px
   untuk alasan yang sama pada tab pertama & terakhir. */
.app-tabs {
  display: flex; gap: 6px; overflow-x: auto;
  padding: 4px 2px 10px; margin-top: -4px;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.app-tabs::-webkit-scrollbar { display: none; }
.app-tabs button {
  flex: none; padding: 9px 15px; border: 0; border-radius: var(--radius-pill);
  font: inherit; font-size: 13.5px; font-weight: 600;
  background: var(--bg-alt); color: var(--ink-2);
  box-shadow: inset 0 0 0 1px var(--line); cursor: pointer;
  min-height: 40px;
}
.app-tabs button[hidden] { display: none; }
.app-tabs button.is-on {
  background: var(--grad-accent); color: var(--accent-ink);
  box-shadow: 0 0 0 1.5px var(--accent-ring), var(--spec);
}
.app-tabs button:focus-visible { outline: 2px solid var(--brand-2); outline-offset: 2px; }
.app-tab-hitung {
  display: inline-block; margin-left: 6px; padding: 1px 7px;
  border-radius: 99px; font-size: 11px; font-weight: 700;
  background: rgba(21,22,30,.10);
}
.app-tabs button.is-on .app-tab-hitung { background: rgba(4,48,26,.16); }

/* Eyebrow section — brand green, beda dari .step-label (uppercase abu). */
.app-eyebrow {
  display: block; margin-bottom: 4px; color: var(--brand-2);
  font-size: 10px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase;
}

/* Tombol penolakan — admin antrian. */
.btn-tolak {
  background: #FDECEA; color: #922B21;
  box-shadow: inset 0 0 0 1px rgba(146,43,33,.22);
}
.btn-tolak:hover:not(:disabled) { filter: brightness(.98); }

@media (prefers-reduced-motion: reduce) {
  .confirm-scrim, .confirm-sheet--slide, .confirm-sheet:not(.confirm-sheet--slide) {
    transition: none; animation: none;
  }
}

/* ============================================================
   MODE APLIKASI — hanya kalau auth.js sempat jalan
   ============================================================ */

/* Layar tidak ikut menggulung; yang menggulung isi sheet saja. Ini
   yang membuat splash terasa seperti layar aplikasi, bukan bagian
   atas sebuah dokumen panjang. */
.js-app, .js-app body { height: 100%; overflow: hidden; }
.js-app body { position: fixed; inset: 0; width: 100%; }

.js-app .app { height: 100%; }
.js-app .btn-sheet { display: inline-flex; }

.js-app .scrim {
  display: block; position: fixed; inset: 0; z-index: 10;
  background: rgba(21,22,30,.34); backdrop-filter: blur(2px);
  opacity: 0; pointer-events: none; transition: opacity .3s ease;
}
.js-app .scrim.is-on { opacity: 1; pointer-events: auto; }

.js-app .sheet {
  position: fixed; z-index: 11; left: 50%; right: auto; bottom: 0;
  width: 100%; max-width: 460px; margin: 0;
  transform: translate(-50%, 100%);
  border-radius: var(--radius-card) var(--radius-card) 0 0;
  box-shadow: 0 -2px 10px rgba(60,44,16,.08), 0 -18px 50px rgba(60,44,16,.16);
  /* Dulu 92svh: di layar 812px itu menyisakan CUMA 65px splash, dan
     wordmark "Datealarm" terpotong separuh oleh tepi sheet. Sekarang
     ruang di atas dijamin sebagai ANGKA, bukan persentase — 116px
     cukup untuk ikon plus wordmark utuh. Batas 90svh tetap dipasang
     supaya di layar pendek sheetnya tidak malah kehabisan tinggi. */
  max-height: min(90svh, calc(100svh - 116px));
  display: flex; flex-direction: column; overflow: hidden;
  transition: transform .36s cubic-bezier(.32,.72,0,1);
  visibility: hidden;
}
.js-app .sheet.is-on { transform: translate(-50%, 0); visibility: visible; }

/* Yang menggulir sekarang BODY, bukan .sheet. Waktu sheet sendiri
   yang menggulir, head cuma "sticky" terhadapnya dan ikut terbawa
   sepersekian piksel di tiap sentakan. */
.js-app .sheet-body {
  flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: 14px 26px calc(26px + env(safe-area-inset-bottom));
}
@media (max-width: 480px) {
  .js-app .sheet-body { padding: 14px 20px calc(22px + env(safe-area-inset-bottom)); }
}

/* Warna RATA, bukan var(--grad-card). Gradien kartu itu putih →
   #FDF7F6 sepanjang TINGGI ELEMENNYA; dipasang di head setinggi 56px
   dia menyelesaikan seluruh gradien di situ, sementara sheet di
   belakangnya baru berjalan ~19% dan masih hampir putih. Hasilnya
   lompatan warna tepat di batas bawah head — terbaca sebagai bilah
   terpisah yang menempel di atas formulir. Sudah kejadian.

   Padding kiri/kanan disamakan dengan .sheet-body (26/20px). Sebelumnya
   18px, jadi tombol kembali meleset 2px dari judul di bawahnya — cukup
   untuk membuat barisnya terbaca sebagai elemen yang bukan bagian dari
   isi sheet. */
.js-app .sheet-head {
  position: sticky; top: 0; z-index: 2;
  background: var(--bg-card);
  padding: 10px 26px 0;
}
.js-app .sheet-nav { padding-bottom: 0; }
.js-app .step.is-on > .auth-h1:first-child { margin-top: 0; }

/* Pegangan kecil di atas sheet — penanda visual bahwa ini lapisan
   yang bisa ditutup, bukan halaman baru. */
.js-app .sheet-grip {
  display: block; width: 38px; height: 4px; margin: 10px auto 10px;
  border-radius: 99px; background: var(--line);
}

/* Masuk (form pendek): tombol utama menempel di bawah viewport sheet. */
.js-app .step-sticky form {
  display: flex; flex-direction: column;
  min-height: calc(92svh - 148px);
}
.js-app .step-sticky .step-fields { flex: 1 1 auto; }
.js-app .step-foot {
  position: sticky; bottom: 0; z-index: 1;
  margin-top: auto; padding-top: 12px;
  padding-bottom: calc(env(safe-area-inset-bottom) + 14px);
  background: linear-gradient(to top, var(--bg-card) 72%, rgba(255,253,249,0));
}
.js-app .step-foot .formsg-form { margin-bottom: 10px; }

@media (max-width: 480px) {
  .js-app .sheet-head { padding-left: 20px; padding-right: 20px; }
  .js-app .step-foot { padding-bottom: calc(env(safe-area-inset-bottom) + 16px); }
}

/* Satu langkah pada satu waktu. */
.js-app .step { display: none; }
.js-app .step.is-on { display: block; }
.js-app .step + .step { margin: 0; padding: 0; border-top: 0; }

/* Sheet terbuka → splash mundur sedikit. Detail kecil, tapi ini yang
   bikin sheet terbaca sebagai lapisan di ATAS layar dan bukan sekadar
   kotak yang muncul. */
.js-app .splash { transition: transform .36s cubic-bezier(.32,.72,0,1), opacity .3s ease; }
.js-app.sheet-open .splash { transform: scale(.965); opacity: .5; }

/* ── Motion ───────────────────────────────────────────────────
   Struktur aplikasinya tetap; yang dimatikan cuma geraknya. */
@media (prefers-reduced-motion: reduce) {
  .js-app .sheet, .js-app .scrim, .js-app .splash, .btn { transition: none; }
  .js-app.sheet-open .splash { transform: none; }
}

/* Layar pendek (HP kecil / landscape): splash memakan ruang yang
   dibutuhkan tombol, jadi yang dekoratif dikorbankan lebih dulu. */
@media (max-height: 720px) {
  .splash-logo { width: 68px; height: 68px; margin-bottom: 12px; }
  .splash-tag { margin-top: 8px; }
  .splash-av:nth-child(4), .splash-av:nth-child(6) { display: none; }
}
@media (max-height: 600px) {
  .splash-tag { display: none; }
  .splash-orbit { display: none; }
  .splash-logo { width: 54px; height: 54px; }
}

/* ── Lembar "Tambah media" ────────────────────────────────────
   Menggantikan `.br-media-menu`, menu tarik-turun selebar ubin
   foto (~110px) berisi tiga baris teks polos setinggi 36px. Dua
   masalah, dan keduanya baru terasa di HP: targetnya di bawah
   ambang sentuh yang nyaman, dan ketiga pilihannya bermuara ke
   pemilih BERKAS — jadi menambah foto berarti menjelajah dokumen,
   bukan membuka kamera seperti di aplikasi sosial mana pun.

   Sekarang barisnya selebar layar, punya ikon dan keterangan, dan
   memisahkan "ambil sekarang" dari "pilih yang sudah ada" —
   pembedaan yang selama ini tidak pernah ditawarkan. */
.br-media-pilih { display: grid; gap: 8px; padding-bottom: 8px; }
.br-media-opsi {
  display: flex; align-items: center; gap: 14px;
  width: 100%; min-height: 60px; padding: 12px 14px;
  border: 0; border-radius: var(--radius-sm);
  background: var(--bg-alt); color: var(--ink);
  font: inherit; text-align: left; cursor: pointer;
}
.br-media-opsi:active { transform: translateY(1px); }
.br-media-opsi:focus-visible { outline: 2px solid var(--brand-2); outline-offset: 2px; }
/* Ikon dilebihkan dari 18px bawaan `.ic`: di baris setinggi 60px
   ikon 18px terbaca sebagai noda, bukan sebagai penanda jenis. */
.br-media-opsi .ic { width: 22px; height: 22px; flex-shrink: 0; color: var(--accent); }
.br-media-opsi span { display: grid; gap: 2px; }
.br-media-opsi b { font-size: 15px; font-weight: 700; }
.br-media-opsi small { color: var(--ink-3); font-size: 12px; }

.br-suara-waktu {
  margin: 18px 0 8px;
  font-family: var(--font-display); font-weight: var(--wt-display);
  font-size: 40px; letter-spacing: -.04em; line-height: 1;
  text-align: center; color: var(--brand-1);
}
.br-suara-pratinjau {
  display: block; width: 100%; margin: 8px 0 4px;
}
.br-suara-pratinjau[hidden] { display: none; }
.br-suara-aksi {
  display: grid; gap: 10px;
  padding-bottom: calc(12px + env(safe-area-inset-bottom));
}
.br-suara-aksi .btn { margin: 0; }
