/* ============================================================
   Pendataan Kehadiran — sistem visual "Balai"

   Halaman ini dibuka warga yang sedang berdiri mengantre di halaman
   balai desa, sering di bawah matahari, sering dengan mata yang sudah
   tidak muda. Tiga hal itu menentukan seluruh keputusan di bawah:

     1. Terang, bukan gelap. Layar gelap tidak terbaca di luar ruang.
     2. Besar. Isian dan tombol 56px, teks 16.5px — bukan ukuran
        antarmuka operator yang menatap layar sepanjang hari.
     3. Tenang. Tidak ada angka berdetak, tidak ada indikator sistem,
        tidak ada huruf monospace. Semua itu bahasa ruang kendali,
        dan tidak ada urusannya dengan orang yang sedang mengantre.

   Rasanya diambil dari balai yang terawat: porselen hangat, hijau
   hutan, dan satu sentuhan kuningan. Resmi tanpa menakuti.
   ============================================================ */

:root {
  /* Permukaan */
  --paper:   #fbfaf7;   /* porselen hangat, bukan putih layar */
  --card:    #ffffff;
  --sunk:    #f4f2ec;   /* sumur isian */
  --raised:  #ffffff;

  --line:    #e7e3d9;
  --line-2:  #d4cec0;

  /* Tinta */
  --ink:   #1c231f;
  --ink-2: #55605a;
  --ink-3: #6e7871;   /* disetel sampai lolos WCAG AA di atas kartu putih */

  /* Hijau hutan — warna resmi, dipakai untuk yang sah dan yang utama */
  --forest:      #0e4d45;
  --forest-2:    #0a3a34;
  --forest-soft: #e8f0ed;
  --forest-line: #b9d2cb;

  /* Kuningan — sentuhan upacara, dipakai sangat hemat */
  --brass:      #a8823c;   /* untuk bidang & garis */
  --brass-ink:  #8c6620;   /* untuk teks di atas --brass-soft, agar lolos AA */
  --brass-soft: #f6eedd;

  --warn:      #8a5a12;
  --warn-soft: #fbf1dd;
  --danger:      #97302a;
  --danger-soft: #fbeae7;

  --r:    18px;
  --r-sm: 12px;
  --r-xs: 9px;

  /* Bayangan hangat dan sangat lembut — kertas di atas meja kayu,
     bukan kartu melayang di ruang hampa. */
  --sh-1: 0 1px 2px rgba(41,36,24,.05);
  --sh-2: 0 1px 2px rgba(41,36,24,.05), 0 6px 16px -8px rgba(41,36,24,.14);
  --sh-3: 0 2px 4px rgba(41,36,24,.05), 0 18px 40px -20px rgba(41,36,24,.22);

  --ease: cubic-bezier(.22,.68,.36,1);
  --ease-out: cubic-bezier(.16,1,.3,1);

  color-scheme: light;
}

/* Tampilan gelap tetap tersedia — untuk acara malam, atau untuk yang
   memang lebih nyaman begitu. Nadanya hangat, bukan hitam teknis. */
[data-theme="dark"] {
  --paper:   #141714;
  --card:    #1c211d;
  --sunk:    #232925;
  --raised:  #222824;

  --line:    #2f3631;
  --line-2:  #434b45;

  --ink:   #edf0ea;
  --ink-2: #a7b0a8;
  --ink-3: #838d85;

  --forest:      #6cc0ac;
  --forest-2:    #8ad3c1;
  --forest-soft: #17241f;
  --forest-line: #2e4a42;

  --brass:      #d6ab60;
  --brass-ink:  #e6bd76;
  --brass-soft: #2a2317;

  --warn:      #d9a74f;
  --warn-soft: #2b2415;
  --danger:      #e08a7c;
  --danger-soft: #2e1a18;

  --sh-1: 0 1px 2px rgba(0,0,0,.4);
  --sh-2: 0 1px 2px rgba(0,0,0,.4), 0 8px 20px -10px rgba(0,0,0,.6);
  --sh-3: 0 2px 4px rgba(0,0,0,.45), 0 22px 44px -22px rgba(0,0,0,.75);

  color-scheme: dark;
}

* { box-sizing: border-box; }

/* Atribut `hidden` hanya di-set oleh stylesheet bawaan browser, sehingga
   aturan display apa pun di berkas ini akan mengalahkannya dan elemen tetap
   terlihat. Satu baris ini membuat `hidden` selalu menang. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }
html, body { margin: 0; min-height: 100%; }

body {
  font-family: "Public Sans", ui-sans-serif, system-ui, -apple-system, sans-serif;
  background: var(--paper);
  color: var(--ink);
  font-size: 16.5px;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, p { margin: 0; }
button, input, select, textarea { font: inherit; color: inherit; }

/* Judul memakai muka bertekstur yang hangat. Dipakai hanya untuk judul —
   di badan teks ia akan melelahkan mata. */
h1, h2, h3, .display {
  font-family: "Fraunces", Georgia, serif;
  font-optical-sizing: auto;
  font-weight: 600;
  letter-spacing: -.012em;
  line-height: 1.22;
}

/* Angka disamakan lebarnya supaya tidak bergoyang, tetapi tetap memakai
   huruf yang sama dengan teks lain. Monospace di sini akan terbaca sebagai
   "ini mesin", persis kesan yang dihindari. */
.num, .locate__distance, .field__counter { font-variant-numeric: tabular-nums; }

:where(a, button, input, select, textarea):focus-visible {
  outline: 3px solid var(--forest);
  outline-offset: 2px;
}

/* ============================================================
   Kerangka
   ============================================================ */
.app { min-height: 100vh; display: flex; flex-direction: column; }

.topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  padding: 16px clamp(18px, 5vw, 32px);
  border-bottom: 1px solid var(--line);
  background: var(--card);
}
.topbar__brand {
  display: flex; align-items: center; gap: 11px;
  font-weight: 600; font-size: 16px; letter-spacing: -.01em;
}
.seal {
  width: 34px; height: 34px; flex: 0 0 34px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--forest); color: #fff;
}
.seal svg { width: 19px; height: 19px; }

.icon-btn {
  width: 46px; height: 46px; flex: 0 0 46px;
  border-radius: 50%; cursor: pointer;
  display: grid; place-items: center;
  background: transparent; border: 1px solid var(--line-2);
  color: var(--ink-2);
  transition: background .2s, color .2s, border-color .2s;
}
.icon-btn:hover { background: var(--sunk); color: var(--ink); }
.icon-btn svg { width: 20px; height: 20px; }

.offline {
  margin: 0; padding: 12px clamp(18px, 5vw, 32px);
  background: var(--warn-soft); color: var(--warn);
  font-size: 15px; font-weight: 500;
  display: flex; align-items: center; gap: 9px;
}
.dot { width: 9px; height: 9px; border-radius: 50%; background: currentColor; flex: 0 0 9px; }

.sheet {
  flex: 1;
  width: 100%; max-width: 660px; margin: 0 auto;
  padding: clamp(28px, 7vw, 52px) clamp(18px, 5vw, 32px) 64px;
}

.foot {
  padding: 22px clamp(18px, 5vw, 32px) 34px;
  text-align: center;
  color: var(--ink-3); font-size: 14px;
  border-top: 1px solid var(--line);
}

/* ============================================================
   Sambutan — nama acaranya yang jadi tokoh utama halaman ini,
   bukan jam, bukan angka, bukan status sistem.
   ============================================================ */
.welcome { margin-bottom: clamp(26px, 5vw, 38px); animation: rise .7s var(--ease-out) both; }

.welcome__kicker {
  display: inline-flex; align-items: center; gap: 9px;
  font-size: 14px; font-weight: 600; letter-spacing: .01em;
  color: var(--forest);
  background: var(--forest-soft);
  border: 1px solid var(--forest-line);
  padding: 6px 15px; border-radius: 100px;
  margin-bottom: 16px;
}
.welcome__title {
  font-size: clamp(30px, 7vw, 46px);
  font-weight: 600;
  letter-spacing: -.022em;
  /* Garis kuningan tipis di bawah judul — satu-satunya perhiasan
     di halaman ini, dan hanya muncul sekali. */
  padding-bottom: 20px;
  position: relative;
}
.welcome__title::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 62px; height: 3px; border-radius: 3px;
  background: var(--brass);
}

.facts {
  list-style: none; margin: 24px 0 0; padding: 0;
  display: grid; gap: 1px;
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--line); overflow: hidden;
  box-shadow: var(--sh-1);
}
.facts li {
  display: flex; align-items: center; gap: 14px;
  padding: 16px 18px;
  background: var(--card);
}
.facts__icon {
  width: 40px; height: 40px; flex: 0 0 40px;
  display: grid; place-items: center; border-radius: 50%;
  background: var(--forest-soft); color: var(--forest);
}
.facts__icon svg { width: 20px; height: 20px; }
.facts__text { display: flex; flex-direction: column; min-width: 0; }
.facts__text b { font-weight: 600; font-size: 16px; letter-spacing: -.01em; }
.facts__text i { font-style: normal; font-size: 14px; color: var(--ink-3); }

/* ============================================================
   Penunjuk langkah — kalimat dan satu batang. Tidak ada nomor
   berlingkaran; yang ingin diketahui orang cuma "sudah sampai mana".
   ============================================================ */
.progress { margin-bottom: 20px; }
.progress__label { font-size: 15px; color: var(--ink-2); margin-bottom: 9px; }
.progress__label b { color: var(--ink); font-weight: 700; }
.progress__track {
  height: 7px; border-radius: 100px;
  background: var(--sunk); border: 1px solid var(--line);
  overflow: hidden;
}
.progress__bar {
  display: block; height: 100%;
  border-radius: 100px;
  background: linear-gradient(90deg, var(--forest), var(--forest-2));
  width: calc((var(--step, 0) + 1) / 4 * 100%);
  transition: width .6s var(--ease-out);
}

/* ============================================================
   Lembar isian
   ============================================================ */
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--sh-2);
  padding: clamp(24px, 5vw, 36px);
}
.card__head { margin-bottom: 26px; }
.card__head h2 { font-size: clamp(22px, 4.4vw, 27px); }
.card__head p { color: var(--ink-2); font-size: 16px; margin-top: 8px; }

.view { display: none; }
.view.is-active { display: block; animation: rise .5s var(--ease-out) both; }

.form { display: flex; flex-direction: column; gap: 22px; }
.field { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.field__label { font-size: 16px; font-weight: 600; letter-spacing: -.005em; }
.field__label em { font-style: normal; font-weight: 400; color: var(--ink-3); }
.field__hint { font-size: 14.5px; color: var(--ink-2); margin-top: -2px; }

/* Isian setinggi 56px: cukup untuk jempol, cukup untuk mata yang sudah
   tidak muda, dan cukup besar agar peramban ponsel tidak memperbesar
   halaman sendiri saat kolomnya disentuh. */
.input {
  width: 100%;
  min-height: 56px;
  padding: 14px 17px;
  font-size: 17px;
  background: var(--sunk);
  border: 1.5px solid var(--line-2);
  border-radius: var(--r-sm);
  color: var(--ink);
  outline: none;
  transition: border-color .2s, background .2s, box-shadow .2s;
}
.input::placeholder { color: var(--ink-3); }
.input:hover { border-color: var(--ink-3); }
.input:focus {
  background: var(--card);
  border-color: var(--forest);
  box-shadow: 0 0 0 4px var(--forest-soft);
}
.input:focus-visible { outline: none; }
.input--big { font-size: 20px; letter-spacing: .12em; min-height: 62px; }

.field-row { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 16px; }
.field__meta { display: flex; justify-content: flex-end; }
.field__counter { font-size: 14px; color: var(--ink-3); }
.field__counter.is-ok { color: var(--forest); font-weight: 600; }

.input.is-invalid { border-color: var(--danger); background: var(--danger-soft); }
.field__error {
  font-size: 15px; color: var(--danger); font-weight: 500;
  display: flex; gap: 7px;
}
.field__error::before { content: "!"; font-weight: 700; }

/* ============================================================
   Tombol — besar, jelas, dan hanya satu yang utama di tiap layar
   ============================================================ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  min-height: 56px;
  padding: 15px 28px;
  border-radius: var(--r-sm);
  border: 1.5px solid transparent;
  cursor: pointer;
  font-size: 17px; font-weight: 600; letter-spacing: -.005em;
  transition: background .2s, color .2s, border-color .2s, box-shadow .25s var(--ease), transform .15s var(--ease);
}
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn:not(:disabled):active { transform: translateY(1px); }

.btn--primary {
  background: var(--forest); color: #fff;
  box-shadow: var(--sh-2);
}
.btn--primary:not(:disabled):hover { background: var(--forest-2); box-shadow: var(--sh-3); }
[data-theme="dark"] .btn--primary { color: #0c1512; }

.btn--quiet {
  background: transparent; color: var(--ink-2);
  border-color: var(--line-2);
}
.btn--quiet:not(:disabled):hover { background: var(--sunk); color: var(--ink); border-color: var(--ink-3); }

.btn--block { width: 100%; }
.btn.is-busy { pointer-events: none; color: transparent; position: relative; }
.btn.is-busy::after {
  content: ""; position: absolute; inset: 0; margin: auto;
  width: 20px; height: 20px; border-radius: 50%;
  border: 2.5px solid rgba(255,255,255,.35); border-top-color: #fff;
  animation: spin .7s linear infinite;
}
.btn--quiet.is-busy::after { border-color: var(--line-2); border-top-color: var(--ink); }

/* Tombol utama selalu di urutan pertama dan selebar mungkin di ponsel;
   tombol pendamping menyusul di bawahnya. */
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; }
.actions--center { justify-content: center; }
.actions .btn { flex: 1 1 190px; }

.form__note { font-size: 15px; color: var(--ink-2); text-align: center; }

/* ============================================================
   Pesan
   ============================================================ */
.alert {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 16px 18px; margin-bottom: 20px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background: var(--card);
  font-size: 16px; line-height: 1.5;
  box-shadow: var(--sh-1);
  animation: rise .35s var(--ease-out) both;
}
.alert::before {
  content: ""; width: 4px; align-self: stretch; flex: 0 0 4px;
  border-radius: 4px; background: currentColor;
}
.alert--error { background: var(--danger-soft); border-color: var(--danger); color: var(--danger); }
.alert--warn  { background: var(--warn-soft);   border-color: var(--warn);   color: var(--warn); }
.alert--ok    { background: var(--forest-soft); border-color: var(--forest-line); color: var(--forest); }

/* ============================================================
   Keadaan kosong
   ============================================================ */
.empty { text-align: center; padding: clamp(38px, 8vw, 62px) 28px; }
.empty__mark {
  display: grid; place-items: center;
  width: 72px; height: 72px; margin: 0 auto 22px;
  border-radius: 50%;
  background: var(--sunk); color: var(--ink-3);
}
.empty__mark svg { width: 32px; height: 32px; }
.empty h2 { font-size: 24px; }
.empty p { color: var(--ink-2); font-size: 16px; margin-top: 12px; max-width: 40ch; margin-inline: auto; }

/* ============================================================
   Identitas yang sudah terisi
   ============================================================ */
.identity {
  display: flex; align-items: center; gap: 15px;
  padding: 15px 18px; margin-bottom: 24px;
  background: var(--forest-soft);
  border: 1px solid var(--forest-line);
  border-radius: var(--r-sm);
}
.identity__avatar {
  width: 46px; height: 46px; flex: 0 0 46px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--forest); color: #fff;
  font-family: "Fraunces", serif; font-weight: 600; font-size: 17px;
}
.identity__name { font-weight: 600; font-size: 17px; }
.identity__meta { font-size: 14.5px; color: var(--ink-2); }

/* ============================================================
   Kamera

   Pratinjau dan berkas tersimpan sengaja identik: keduanya memakai citra
   yang sudah dicerminkan. Pencerminan dilakukan sekali saja, di kanvas
   (lihat app.js) — <img> di sini tidak boleh dibalik lagi.
   ============================================================ */
.camera {
  position: relative;
  aspect-ratio: 3 / 4;
  max-height: 62vh;
  margin-inline: auto;
  border-radius: var(--r);
  overflow: hidden;
  background: #141714;
  border: 1px solid var(--line-2);
  box-shadow: var(--sh-2);
}
.camera video { width: 100%; height: 100%; object-fit: cover; display: block; transform: scaleX(-1); }
.camera img   { width: 100%; height: 100%; object-fit: cover; display: block; }
.camera__overlay { position: absolute; inset: 0; pointer-events: none; }
/* Panduan siluet kepala+bahu, seperti pemandu selfie m-banking: bagian luar
   diredupkan, garis tubuh mengarahkan posisi peserta. */
.camera__guide { position: absolute; inset: 0; width: 100%; height: 100%; }
.camera__scrim { fill: rgba(20,23,20,.46); }
.camera__silh {
  stroke: rgba(255,255,255,.82); stroke-width: 3;
  stroke-linejoin: round; stroke-linecap: round;
  transition: stroke .18s, filter .18s;
}
/* Posisi sudah pas: garis hijau + pendar, menandakan siap ambil foto. */
.camera.is-aligned .camera__silh {
  stroke: #46d18a; stroke-width: 4;
  filter: drop-shadow(0 0 7px rgba(70,209,138,.85));
}
.camera__hint {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 16px 18px 15px; text-align: center;
  font-size: 15px; font-weight: 500; color: #f4f6f2;
  background: linear-gradient(transparent, rgba(20,23,20,.86));
}
.camera.is-captured .camera__overlay { display: none; }
.camera.is-flash::before {
  content: ""; position: absolute; inset: 0; background: #fff; z-index: 3;
  animation: flash .45s ease-out forwards;
}

/* ============================================================
   Lokasi — cincin besar dengan satu kalimat putusan di bawahnya.
   Angka rincinya ada, tapi bukan yang pertama dibaca.
   ============================================================ */
.locate { text-align: center; }
.locate__ring { position: relative; width: 210px; height: 210px; margin: 0 auto; }
.locate__ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.ring__track { fill: none; stroke: var(--sunk); stroke-width: 11; }
.ring__value {
  fill: none; stroke: var(--ink-3); stroke-width: 11; stroke-linecap: round;
  stroke-dasharray: 377; stroke-dashoffset: 377;
  transition: stroke-dashoffset .8s var(--ease-out), stroke .3s;
}
.ring__value.is-ok  { stroke: var(--forest); }
.ring__value.is-bad { stroke: var(--danger); }
.locate__center { position: absolute; inset: 0; display: grid; place-content: center; }
.locate__distance { font-family: "Fraunces", serif; font-size: 36px; font-weight: 600; letter-spacing: -.02em; }
.locate__unit { font-size: 14.5px; color: var(--ink-3); margin-top: 2px; }

.verdict {
  margin: 22px auto 0; max-width: 34ch;
  font-size: 19px; font-weight: 600; letter-spacing: -.01em;
  color: var(--ink-2);
}
.verdict.is-ok  { color: var(--forest); }
.verdict.is-bad { color: var(--danger); }

.readout {
  margin: 24px 0 0; padding: 4px 0 0;
  border-top: 1px solid var(--line);
  text-align: left;
}
.readout > div {
  display: flex; justify-content: space-between; gap: 16px;
  padding: 12px 0; border-bottom: 1px solid var(--line);
  font-size: 15.5px;
}
.readout > div:last-child { border-bottom: 0; }
.readout dt { color: var(--ink-2); }
.readout dd { margin: 0; font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }
.readout dd.is-ok  { color: var(--forest); }
.readout dd.is-bad { color: var(--danger); }

/* ============================================================
   Pilihan datang / pulang — kartu besar, bukan radio kecil
   ============================================================ */
.choice { border: 0; padding: 0; margin: 30px 0 24px; display: grid; gap: 12px; }
.choice legend { padding: 0; margin-bottom: 12px; }
@media (min-width: 520px) {
  .choice { grid-template-columns: 1fr 1fr; }
  .choice legend { grid-column: 1 / -1; }
}
.choice__opt { cursor: pointer; }
.choice__opt input { position: absolute; opacity: 0; pointer-events: none; }
.choice__opt span {
  display: block; min-height: 76px;
  padding: 16px 18px;
  border: 1.5px solid var(--line-2); border-radius: var(--r-sm);
  background: var(--card);
  transition: border-color .2s, background .2s, box-shadow .2s;
}
.choice__opt:hover span { border-color: var(--ink-3); }
.choice__opt b { display: block; font-size: 17px; font-weight: 600; }
.choice__opt small { font-size: 14.5px; color: var(--ink-2); }
.choice__opt input:checked + span {
  border-color: var(--forest); background: var(--forest-soft);
  box-shadow: inset 0 0 0 1px var(--forest);
}
.choice__opt input:focus-visible + span { outline: 3px solid var(--forest); outline-offset: 2px; }

/* ============================================================
   Selesai — kartu bukti

   Kartu ini ditunjukkan ke koordinator di lokasi acara: sering sambil
   berdiri, di bawah matahari, dan dibaca dari jarak satu lengan oleh
   orang yang harus memeriksa ratusan warga.

   Karena itu yang dibesarkan hanya dua hal — foto dan nama. Itulah yang
   dikerjakan koordinator: mencocokkan wajah di layar dengan wajah orang
   di depannya, lalu memastikan namanya benar. Sisanya boleh kecil.
   ============================================================ */
.view--done { text-align: center; }
.done__mark { display: grid; place-items: center; margin-bottom: 16px; }
.done__mark svg { width: 62px; height: 62px; }
.done__mark circle {
  fill: var(--forest-soft); stroke: var(--forest); stroke-width: 1.5;
  stroke-dasharray: 151; stroke-dashoffset: 151;
  animation: draw .7s var(--ease-out) forwards;
}
.done__mark path {
  fill: none; stroke: var(--forest); stroke-width: 3.6;
  stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 40; stroke-dashoffset: 40;
  animation: draw .45s .5s var(--ease-out) forwards;
}
.view--done h2 { font-size: clamp(22px, 4.6vw, 28px); }
.done__sub { color: var(--ink-2); font-size: 16.5px; margin: 8px 0 24px; }
.done__petunjuk {
  margin-top: 16px; font-size: 15px; color: var(--ink-2);
}

.bukti {
  text-align: left;
  border: 1.5px solid var(--forest-line);
  border-radius: var(--r);
  background: var(--card);
  overflow: hidden;
  box-shadow: var(--sh-2);
  animation: rise .5s .45s var(--ease-out) both;
}

.bukti__kop {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px;
  padding: 12px 16px;
  background: var(--forest); color: #fff;
}
[data-theme="dark"] .bukti__kop { color: #0c1512; }
.bukti__acara {
  font-weight: 700; font-size: 15px; letter-spacing: -.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bukti__stat {
  flex: 0 0 auto;
  font-size: 13px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 3px 12px; border-radius: 100px;
  background: rgba(255,255,255,.22);
}
[data-theme="dark"] .bukti__stat { background: rgba(0,0,0,.22); }

.bukti__utama {
  display: flex; align-items: center; gap: 16px;
  padding: 18px 16px;
}
/* Tombol, bukan gambar biasa: satu ketukan memperbesarnya sampai memenuhi
   layar, karena mencocokkan wajah dari 112px sulit di luar ruang. */
.bukti__foto {
  flex: 0 0 auto; padding: 0; border: 0; cursor: zoom-in;
  width: 112px; height: 112px;
  border-radius: var(--r-sm); overflow: hidden;
  border: 2px solid var(--forest-line);
  background: var(--sunk);
}
.bukti__foto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bukti__foto:focus-visible { outline: 3px solid var(--forest); outline-offset: 3px; }

/* Nama warga Indonesia sering satu kata panjang ("Kusumaningrum") yang
   lebih lebar daripada kolom ini di layar 320px. Tanpa anywhere, kata itu
   menembus tepi kartu dan huruf terakhirnya hilang terpotong. */
.bukti__diri { min-width: 0; overflow-wrap: anywhere; }
.bukti__nama {
  font-family: "Fraunces", Georgia, serif;
  font-weight: 600; font-size: clamp(19px, 4.4vw, 23px);
  line-height: 1.2; letter-spacing: -.015em;
}
/* NIK dikelompokkan empat-empat dan diberi jarak antarhuruf: enam belas
   angka beruntun praktis tidak bisa dicocokkan dengan KTP sambil berdiri. */
.bukti__nik {
  margin-top: 5px;
  font-size: 15.5px; font-weight: 600; letter-spacing: .06em;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.bukti__wilayah { margin-top: 2px; font-size: 14.5px; color: var(--ink-2); }

.bukti__rinci { margin: 0; border-top: 1px solid var(--line); }
.bukti__rinci > div {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  padding: 11px 16px; border-bottom: 1px solid var(--line);
  font-size: 15px;
}
.bukti__rinci > div:last-child { border-bottom: 0; }
.bukti__rinci dt { color: var(--ink-2); }
.bukti__rinci dd { margin: 0; font-weight: 600; text-align: right; }

/* Dua kode ini yang dipakai koordinator bila perlu mencocokkan ke dashboard.
   Sengaja paling kecil — mereka jarang dibaca, tetapi harus ada. */
.bukti__kaki {
  display: flex; flex-wrap: wrap; gap: 6px 18px; justify-content: space-between;
  padding: 11px 16px;
  background: var(--sunk); border-top: 1px solid var(--line);
  font-size: 13px; color: var(--ink-3);
}
.bukti__kaki b {
  color: var(--ink); font-weight: 700; letter-spacing: .04em;
  font-variant-numeric: tabular-nums;
}

/* Foto diperbesar sampai memenuhi layar */
.zoom {
  position: fixed; inset: 0; z-index: 60;
  display: grid; place-items: center; align-content: center; gap: 18px;
  padding: 22px; cursor: zoom-out;
  background: rgba(20,23,20,.94);
  animation: fade .22s var(--ease-out) both;
}
.zoom img {
  max-width: min(100%, 520px); max-height: 76vh;
  border-radius: var(--r); border: 3px solid rgba(255,255,255,.85);
}
.zoom__tutup { color: rgba(255,255,255,.72); font-size: 14.5px; }

/* Di bawah 380px, kolom identitas tinggal ~130px — nama empat baris di
   sebelah foto. Ditumpuk saja: fotonya justru bisa lebih besar, dan nama
   mendapat selebar kartu. */
@media (max-width: 380px) {
  .bukti__utama {
    flex-direction: column; align-items: center; text-align: center;
    gap: 13px; padding: 16px 13px;
  }
  .bukti__foto { width: 128px; height: 128px; }
}

/* ============================================================
   Gerak — lembut dan sebentar. "Nyaman dilihat" berarti tenang,
   bukan bergerak terus.
   ============================================================ */
@keyframes rise  { from { opacity: 0; transform: translateY(10px) } to { opacity: 1; transform: none } }
@keyframes fade  { from { opacity: 0 } to { opacity: 1 } }
@keyframes pop   { from { opacity: 0; transform: scale(.94) } to { opacity: 1; transform: none } }
@keyframes spin  { to { transform: rotate(360deg) } }
@keyframes draw  { to { stroke-dashoffset: 0 } }
@keyframes flash { from { opacity: .85 } to { opacity: 0 } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ============================================================
   Layar sempit
   ============================================================ */
@media (max-width: 560px) {
  .field-row { grid-template-columns: 1fr; }
  /* column, bukan column-reverse. Dengan reverse, urutan yang terlihat
     berlawanan dengan urutan DOM: tombol utama ada di DOM paling awal tetapi
     tampil paling bawah, sehingga urutan Tab dan urutan pembacaan layar
     berlawanan dengan urutan visual (WCAG 2.4.3). */
  .actions { flex-direction: column; }
  .actions .btn { width: 100%; flex: none; }
  .camera { max-height: 58vh; }
  .facts li { padding: 14px 16px; }
}

/* Kepala kartu yang menampung judul di kiri dan kendali di kanan.
   Menumpuk sendiri di layar sempit supaya kendalinya tidak terjepit. */
.card__head--row {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 18px; flex-wrap: wrap;
}
.input--num { font-variant-numeric: tabular-nums; }

/* Peringatan "wajah tidak terdeteksi" pada langkah foto: cukup menonjol untuk
   menghentikan warga menekan lanjut, tanpa terbaca sebagai galat sistem. */
#cameraHint.is-warn { color: var(--danger); font-weight: 600; }

/* Persetujuan pemrosesan data (UU PDP) di langkah data diri. */
.consent{
  display:flex; gap:11px; align-items:flex-start;
  margin:20px 0 6px; padding:14px 16px;
  background:var(--sunk); border:1px solid var(--line); border-radius:var(--r-sm);
  font-size:14px; color:var(--ink-2); line-height:1.5; cursor:pointer;
}
.consent input{ flex:0 0 auto; width:20px; height:20px; margin-top:1px; accent-color:var(--forest); }
