/* Paletnya SAMA PERSIS dengan popup ekstensi (extension/popup.css): satu
   tangga netral, satu aksen. Dua permukaan yang menampilkan produk yang sama
   tidak boleh punya dua versi warna yang mirip tapi tak sama, karena selisih
   kecil seperti itu tidak pernah terlihat sebagai keputusan, hanya sebagai
   ketidakrapian. Angka kontrasnya diperiksa tools/contrast.py, dan karena
   nilainya identik, satu pemeriksaan berlaku untuk kedua permukaan. */
@font-face {
  font-family: 'Archivo';
  /* Dua format ditulis karena 'woff2-variations' sudah usang: sebagian
   * Chromium modern hanya menerima 'woff2' polos. */
  src: url('fonts/Archivo-Variable.woff2') format('woff2-variations'),
       url('fonts/Archivo-Variable.woff2') format('woff2');
  font-weight: 100 900;
  font-display: swap;
}
@font-face {
  font-family: 'Plex Mono';
  src: url('fonts/IBMPlexMono-400.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'Plex Mono';
  src: url('fonts/IBMPlexMono-500.woff2') format('woff2');
  font-weight: 500;
  font-display: swap;
}

:root {
  --bg: #0a0a0b;
  --surface: #141416;
  --raised: #1c1c1f;
  --line: #2a2a30;
  --line-field: #71717c;
  --text: #f5f5f7;
  --text-2: #b8b8c0;
  --text-3: #94949e;
  --accent: #ffffff;
  --on-accent: #0a0a0b;
  --ok: #4ade80;
  --bad: #f87171;
  --r: 12px;
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; height: 100%; }
body {
  background: var(--bg);
  color: var(--text);
  font: 16px/1.5 'Archivo', system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  display: flex; flex-direction: column;
  min-height: 100dvh;
  /* Ruang aman untuk iPhone dengan notch. */
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}
header {
  display: flex; align-items: center; gap: 9px;
  padding: 14px 16px; border-bottom: 1px solid var(--line);
}
/* Mark merek, bukan titik status. Titik abu di kiri judul terbaca sebagai
   penanda muat yang belum selesai, dan itu justru menurunkan kepercayaan pada
   halaman yang baru dibuka dari tautan orang lain. */
.mark { width: 20px; height: 20px; flex: none; display: block; }
header h1 { font-size: 16px; margin: 0; font-weight: 600; letter-spacing: -0.01em; }
/* Titik status ikut ke kanan bersama teksnya, supaya kiri header bersih untuk
   merek dan kanan untuk keadaan sambungan. */
.dot { order: 2; margin-left: 8px; }
.status { order: 3; margin-left: 0; }
/* Titik keadaan. Saat belum tersambung ia memakai abu yang benar-benar
   terlihat, bukan warna garis pemisah: titik yang tak terbedakan dari latar
   terbaca sebagai elemen yang gagal dimuat, bukan sebagai keadaan. */
.dot { width: 9px; height: 9px; border-radius: 50%; background: var(--text-3); flex: none; }
.dot--on { background: var(--ok); }
.dot--err { background: var(--bad); }
.status { margin-left: auto; font-size: 13px; color: var(--text-2); font-variant-numeric: tabular-nums; }

/* Baris galat: satu-satunya tempat kegagalan sambungan dijelaskan. Ditaruh
   tepat di bawah header supaya terbaca sebelum apa pun yang lain, karena
   pengguna yang gagal menyambung sedang mencari alasannya, bukan tombol. */
.galat {
  margin: 0; padding: 11px 16px; font-size: 14px; line-height: 1.45;
  color: var(--bad); background: var(--surface);
  border-bottom: 1px solid var(--line);
}

main { flex: 1; padding: 16px; display: flex; flex-direction: column; gap: 14px; max-width: 900px; width: 100%; margin: 0 auto; }

/* Sebelum tersambung hanya ada satu kartu. Kalau ia menempel di atas, sisa
   layar jadi ruang kosong besar dan halaman terbaca sebagai aplikasi yang
   belum jadi. Dipusatkan, satu kartu terlihat seperti halaman yang memang
   dirancang begitu. Setelah tersambung aturan ini mati sendiri karena
   `main.siap` menggantinya dengan tata letak dua kolom. */
main:not(.siap) { justify-content: center; }

.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 14px; }
.card h2 { font-size: 13px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-2); margin: 0 0 10px; font-weight: 600; }

label { display: block; font-size: 13px; color: var(--text-2); margin-bottom: 6px; }
input {
  width: 100%; padding: 12px; border-radius: 10px;
  /* Lebih terang dari permukaan kartu (--surface #141416) supaya terbaca
     sebagai bidang yang bisa diisi, bukan sebagai teks yang mengambang. */
  border: 1px solid var(--line-field); background: #232327; color: var(--text);
  /* 16px mencegah iOS memperbesar halaman saat kolom disentuh. */
  font-size: 16px; font-family: inherit;
}
input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
/* Placeholder ikut dijaga kontrasnya: teks contoh yang terlalu redup membuat
   kolom terlihat kosong, padahal justru itu petunjuk format yang dibutuhkan. */
input::placeholder { color: var(--text-3); opacity: 1; }

button {
  width: 100%; padding: 14px; border-radius: 10px; border: 1px solid var(--text-3);
  background: var(--raised); color: var(--text);
  font-size: 16px; font-weight: 600; font-family: inherit; cursor: pointer;
  /* Sasaran sentuh minimal 44px sesuai pedoman Apple. */
  min-height: 48px;
}
button.primary { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
button:disabled { opacity: 0.5; cursor: default; }
button:active { transform: scale(0.99); }

.row { display: flex; gap: 10px; }
.row > * { flex: 1; }

/* Satu baris alur untuk pengunjung pertama. Sengaja redup: ia penjelas,
   bukan ajakan, dan setelah tersambung ia menghilang. */
.langkah { font-size: 13px; line-height: 1.5; color: var(--text-3); margin: 0 0 14px; }

.note { font-size: 13px; color: var(--text-2); margin: 10px 0 0; }

/* Pertanyaan pemilih untuk dua tombol undangan.
 *
 * Jaraknya sengaja TIDAK simetris: 16px di atas memisahkannya dari tombol
 * sebelumnya, 6px di bawah mengikatnya ke tombol sesudahnya. Dengan jarak
 * yang sama, pertanyaan terbaca sebagai keterangan tombol DI ATASNYA — dan
 * itu justru menukar pasangannya (dulu: "sudah punya ekstensi?" terbaca
 * sebagai label "Salin tautan HP"). */
.note.tanya { margin: 16px 0 6px; color: var(--text); }

/* Satu pertanyaan + tombolnya = satu wadah. Tanpa ini, jarak antar-elemen
   membuat pertanyaan terbaca sebagai keterangan tombol yang SALAH (yang di
   atasnya), bukan tombol yang dimaksud. Jarak di dalam wadah lebih rapat
   daripada jarak antar-wadah, jadi pasangannya terbaca dari jaraknya juga. */
.aksi { margin-top: 14px; }
.aksi .note.tanya { margin: 0 0 6px; }
.aksi + .aksi { margin-top: 18px; }
.note--err { color: var(--bad); }
.note--ok { color: var(--ok); }

#pemutar { display: none; }
#pemutar.tampil { display: block; }
.bingkai { position: relative; width: 100%; padding-top: 56.25%; background: #000; border-radius: var(--r); overflow: hidden; }
.bingkai iframe, .bingkai video { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
/* Layar kosong sebelum ada video. Tanpa ini tamu melihat kotak hitam tanpa
   keterangan dan mengira halamannya rusak, padahal ia cuma sedang menunggu. */
/* Blok "gabung sebagai tamu". Sebelumnya memakai panah bawaan <details> yang
   kecil dan redup, jadi orang yang MEMANG datang membawa undangan tidak
   menemukan tempat menempelnya. Sekarang penandanya jelas dan berubah saat
   terbuka. */
.gabung { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); }
.gabung summary {
  display: flex; align-items: center; gap: 8px;
  cursor: pointer; font-size: 14px; color: var(--text-2); padding: 6px 0;
  list-style: none;
}
.gabung summary::-webkit-details-marker { display: none; }
.gabung__tanda {
  flex: none; width: 18px; height: 18px; border-radius: 5px;
  border: 1px solid var(--text-2); color: var(--text);
  font-size: 13px; line-height: 16px; text-align: center;
}
.gabung[open] .gabung__tanda { color: var(--text); border-color: var(--text); }
.gabung[open] summary { color: var(--text); }

.kaki {
  padding: 16px; border-top: 1px solid var(--line);
  max-width: 900px; width: 100%; margin: 0 auto;
}
.kaki p { margin: 0; font-size: 13px; line-height: 1.55; color: var(--text-2); }
/* Tautan sekunder di kaki halaman. Dipisah dari kalimat batas supaya kalimat
   itu tetap terbaca sebagai keterangan, bukan sebagai baris navigasi. */
.kaki__tautan { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 6px 16px; }
.kaki__tautan a { color: var(--text-2); font-size: 13px; text-decoration: none; }
.kaki__tautan a:hover { color: var(--text); text-decoration: underline; }

.kosong {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  padding: 22px; text-align: center; font-size: 14px; line-height: 1.5; color: var(--text-3);
}

.anggota { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.pil { font-size: 12px; padding: 4px 10px; border-radius: 999px; background: var(--raised); border: 1px solid var(--line); color: var(--text-2); }
.pil--aku { color: var(--text); border-color: var(--accent); }
.pil--host { color: var(--text); }

/* ---------- halaman dokumen (pasang, privasi) ----------
   Halaman-halaman ini dibaca, bukan dipakai: tidak ada tombol utama, tidak ada
   pemutar, hanya teks yang harus enak dibaca di HP maupun desktop. Karena itu
   lebarnya dibatasi pada ukuran baris yang nyaman (sekitar 68 karakter) dan
   jaraknya lebih lega daripada kartu aplikasi. */
.doc { max-width: 720px; width: 100%; margin: 0 auto; padding: 26px 18px 40px; flex: 1; }
.doc h1 { font-size: 26px; line-height: 1.2; letter-spacing: -0.02em; margin: 4px 0 6px; font-weight: 650; }
.doc__intro { font-size: 15px; line-height: 1.6; color: var(--text-2); margin: 0 0 26px; }
.doc h2 { font-size: 15px; letter-spacing: -0.005em; margin: 26px 0 8px; font-weight: 650; }
.doc h3 { font-size: 14px; margin: 18px 0 6px; font-weight: 600; color: var(--text-2); }
.doc p, .doc li { font-size: 14.5px; line-height: 1.62; color: var(--text-2); }
.doc p { margin: 0 0 12px; }
.doc ul, .doc ol { margin: 0 0 12px; padding-left: 22px; }
.doc li { margin-bottom: 7px; }
.doc strong { color: var(--text); font-weight: 600; }
.doc a { color: var(--text); text-underline-offset: 3px; }
.doc code {
  font-family: 'Plex Mono', ui-monospace, monospace; font-size: 12.5px;
  background: var(--raised); border: 1px solid var(--line); border-radius: 6px;
  padding: 1.5px 6px; color: var(--text);
}
.doc__balik { display: inline-block; font-size: 13.5px; color: var(--text-2); text-decoration: none; margin-bottom: 8px; }
.doc__balik:hover { color: var(--text); }

/* Langkah bernomor untuk halaman pasang. Nomornya dijadikan lingkaran sendiri
   supaya terbaca sebagai urutan, bukan sebagai daftar biasa yang bisa
   dilewati. */
.langkah2 { list-style: none; padding: 0; margin: 0 0 8px; counter-reset: langkah; }
.langkah2 > li { position: relative; padding-left: 38px; margin-bottom: 16px; counter-increment: langkah; }
.langkah2 > li::before {
  content: counter(langkah); position: absolute; left: 0; top: 1px;
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--raised); border: 1px solid var(--line-field);
  color: var(--text); font-size: 12.5px; font-weight: 600;
  display: flex; align-items: center; justify-content: center;
  font-variant-numeric: tabular-nums;
}
.langkah2 > li strong { display: block; margin-bottom: 3px; }

/* Kotak catatan: satu-satunya tempat batas produk disebut apa adanya. */
.doc__kotak {
  background: var(--surface); border: 1px solid var(--line); border-left: 3px solid var(--line-field);
  border-radius: 8px; padding: 13px 15px; margin: 18px 0;
}
.doc__kotak p { margin: 0; font-size: 13.5px; }
.doc__kotak p + p { margin-top: 9px; }

/* Kaki halaman dokumen: tautan antar-halaman, bukan iklan. */
.doc__kaki { margin-top: 34px; padding-top: 18px; border-top: 1px solid var(--line); display: flex; flex-wrap: wrap; gap: 8px 18px; }
.doc__kaki a { font-size: 13.5px; color: var(--text-2); text-decoration: none; }
.doc__kaki a:hover { color: var(--text); text-decoration: underline; }

/* Tombol unduh di halaman pasang. Berbeda dari tombol aplikasi: di sini ia
   harus terbaca sebagai tindakan utama halaman, jadi dipakai permukaan terang
   yang sama dengan tombol utama.

   Selektor sengaja `.doc a.btn-unduh`, bukan `.btn-unduh`. Aturan
   `.doc a { color: var(--text) }` di atas punya spesifisitas 0,1,1 sementara
   `.btn-unduh` hanya 0,1,0, jadi warna teks tombol ditimpa menjadi --text
   (#f5f5f7) di atas latar --accent (#ffffff) dan terukur 1.09:1 di produksi:
   teks putih di atas tombol putih. Cacat itu ditemukan dengan mengukur gaya
   terhitung di halaman produksi (tools/ukur_tombol.js) setelah pemeriksaan
   visual menandainya, dan pelajarannya dicatat di sini: pemeriksaan visual
   menemukan gejalanya, pengukuran menunjukkan sebabnya. */
.doc a.btn-unduh {
  display: inline-block; text-decoration: none;
  background: var(--accent); color: var(--on-accent);
  border: 1px solid var(--accent); border-radius: 10px;
  padding: 12px 18px; font-size: 14.5px; font-weight: 600;
  /* Sasaran sentuh minimal 44px, sama dengan tombol aplikasi. */
  min-height: 44px; line-height: 1.25;
  /* Keadaan interaksi. Tombol tanpa umpan balik apa pun membuat pengguna
     meragukan apakah tekanannya tercatat, dan itu terutama terasa di HP tempat
     tidak ada kursor yang memberi petunjuk. Fokus keyboard diberi garis tegas
     karena halaman ini juga dibuka di komputer. */
  transition: opacity 160ms cubic-bezier(.22,1,.36,1), transform 120ms cubic-bezier(.22,1,.36,1);
}
.doc a.btn-unduh:hover { opacity: 0.88; }
.doc a.btn-unduh:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }
.doc a.btn-unduh:active { transform: scale(0.99); opacity: 0.82; }

/* Layar lebar: pemutar dan panel berdampingan. */
@media (min-width: 760px) {
  main.siap { display: grid; grid-template-columns: 1fr 320px; align-items: start; }
  main.siap .panggung { grid-column: 1; }
  main.siap .panel { grid-column: 2; }
  .bingkai { padding-top: 56.25%; }
}
