@charset "utf-8";
/* =============================================================================
   Bhumi Sadana Land, desain contoh (perusahaan fiktif)
   Sumber desain: stitch/08-properti/ (DESIGN.md + PROMPTS-WEB/STATE)

   MODE WARNA DIKUNCI TERANG. Seluruh rasio di bawah dihitung ULANG SENDIRI
   dengan rumus WCAG untuk latar terang saja, bukan disalin dari brief dan
   bukan diwarisi dari situs 06.

   HASIL HITUNGAN, DAN PUTUSANNYA. Aksen cokelat #B08968 hanya 2,99:1 di atas
   latar #FBF8F3, di BAWAH lantai 3:1 untuk border, ikon fungsional, garis
   bawah aktif, dan cincin fokus. Maka aksen di paket ini ISIAN SAJA. Teks DI
   ATAS aksen wajib TINTA (4,68:1); putih di atasnya 3,17:1 dan GAGAL AA.

   MARGIN 0,18 ITU YANG PALING TIPIS DI SELURUH PALET, dan ia punya tiga akibat
   yang ditegakkan di berkas ini:
     · tidak ada teks di atas aksen yang lebih kecil dari 14px,
     · tidak ada yang lebih ringan dari bobot 500,
     · keadaan hover/tekan MENERANGKAN aksen, tidak menggelapkannya. Aksen yang
       digelapkan sedikit saja menjatuhkan tinta di bawah 4,5:1 (#96704F hanya
       3,34:1), jadi --aksen-tekan justru lebih terang: #BB9474, tinta 5,37:1.

   Angka DESIGN.md paket ini TERBUKTI BENAR sampai dua desimal: 4,68 · 3,17 ·
   2,99 · 14,01 · 5,62 semuanya cocok dengan hitungan sendiri.

   ⛔ RAMBU ISI (DESIGN.md): TIDAK ADA nomor sertifikat, nomor PBG, nomor IMB,
   maupun nomor izin di mana pun, cukup jenis dokumen, penerbit, dan status.
   TIDAK ADA janji kenaikan harga atau imbal hasil. Tiap angka angsuran di layar
   disebut simulasi berikut asumsinya, dan disebut bahwa angka final ada di SP3K.

   DUA KELUARGA HURUF: Fraunces 700 untuk judul dan angka besar, Inter 400/600
   untuk isi.
   ========================================================================== */

@import url("aset/huruf/_font-face.css");

/* -----------------------------------------------------------------------------
   1. TOKEN, tiap warna punya PERAN dan RASIO TERHITUNG di sebelahnya.
   Angka di bawah DIHITUNG SENDIRI dengan rumus WCAG, bukan disalin dari brief.
   Catatan: berbeda dengan paket 02, angka di DESIGN.md paket ini TERBUKTI BENAR, 4,76 · 5,01 · 3,25 · 15,48 · 6,15 semuanya cocok sampai dua desimal.
   -------------------------------------------------------------------------- */
:root {
  /* Permukaan */
  --latar:        #FBF8F3;   /* alas halaman */
  --kertas:       #FFFFFF;   /* alas kartu di atas --latar; tinta 14,84:1 */
  --sentuh:       #F2EAE0;   /* hover/tekan; tinta di atasnya 12,45:1 */

  /* Teks */
  --tinta:        #1F2A24;   /* 14,01:1 di atas --latar, teks utama, ukuran apa pun */
  --redup:        #5C6660;   /* 5,62:1 di atas --latar, teks sekunder, LULUS AA */

  /* Aksen, ISIAN SAJA, dengan margin paling tipis di seluruh portofolio */
  --aksen:        #B08968;   /* 2,99:1 di atas latar → ISIAN saja: tombol, cip, pita
                                statistik, nomor langkah, batang progres, pin peta.
                                DILARANG jadi warna teks, garis bawah aktif, border
                                kendali, cincin fokus, atau ikon fungsional, semuanya butuh minimal 3:1 dan 2,99 tidak sampai.
                                Teks DI ATAS aksen wajib --tinta (4,68:1), minimal
                                14px dan bobot 500; putih di atasnya 3,17:1 GAGAL. */
  --aksen-tekan:  #BB9474;   /* hover/tekan LEBIH TERANG, bukan lebih gelap: tinta di
                                atasnya 5,37:1. Versi gelap #96704F cuma 3,34:1 dan
                                menjatuhkan label tombolnya sendiri di bawah AA. */
  --aksen-alas:   #F0E4D8;   /* alas lembut; tinta di atasnya 11,87:1 */
  --nonaktif:     #EAE2D6;   /* alas kendali mati; redup di atasnya 4,64:1 */

  /* Garis */
  --garis:        #E7DFD3;   /* 1,25:1, DEKORATIF saja (pemisah, border kartu).
                                DILARANG untuk border kendali interaktif. */
  --garis-kendali:#5C6660;   /* 5,62:1, border input, checkbox, tombol outline. */

  /* Semantik, dihitung terhadap --latar */
  --sukses:       #0F6B45;   /* 6,18:1 */
  --galat:        #B3261E;   /* 6,17:1 */
  --peringatan:   #7A4B00;   /* 6,99:1 */
  --sukses-alas:  #EAF2EC;   /* tinta di atasnya 13,01:1 */
  --galat-alas:   #F9E9E7;   /* tinta di atasnya 12,61:1 */
  --peringatan-alas:#F6EEDD; /* tinta di atasnya 12,86:1 */

  /* Huruf. DUA keluarga, sesuai DESIGN.md: Fraunces 700 untuk judul, harga, dan
     angsuran; Inter 400/400-600 untuk isi.
     ⚠️ DIPERIKSA dengan fontTools, bukan ditebak dari unicode-range:
       · U+2192 (panah kanan) TIDAK ADA di kedua subset latin, padahal rentang
         U+2000-206F tertulis di deklarasinya. Halaman ini karena itu tidak pernah
         memakai panah sebagai aksara; arah digambar dengan ikon SVG.
       · U+2014 (-), U+2026 (…), U+00B7 (·), U+2013 (–), U+00D7 (×), U+00A9 (©),
         U+00B2 (²) SEMUANYA ADA di kedua huruf. Footer memakai, dan tombol
         memuat memakai …, jadi keduanya memang harus ada.
       · Fraunces subset Google Fonts TIDAK punya fitur OpenType `tnum` dan lebar
         angkanya tidak seragam, jadi `tabular-nums` pada Fraunces TIDAK bekerja.
         Karena itu angka yang harus SEJAJAR ANTAR-BARIS (tabel bank, rincian
         biaya, tabel legalitas) memakai Inter yang punya `tnum`; Fraunces dipakai
         untuk angka BESAR berdiri sendiri, tempat kesejajaran tidak dibandingkan.
     Rantai cadangan diisi huruf sistem yang pasti punya glif yang kurang. */
  --f-judul: "Fraunces", ui-serif, Georgia, "Times New Roman", serif;
  --f-isi:   "Inter", ui-sans-serif, "Segoe UI", system-ui, sans-serif;

  /* LANTAI UKURAN TEKS, jangan turun di bawah ini di mana pun.
     Khusus di atas aksen, lantainya --t-kecil (14px), bukan --t-label. */
  --t-isi:   1rem;      /* 16px, teks isi */
  --t-kecil: 0.875rem;  /* 14px, sekunder, juga LANTAI teks di atas aksen */
  --t-label: 0.75rem;   /* 12px, label huruf besar, BATAS BAWAH, bukan di aksen */

  /* Ritme */
  --r1: .25rem; --r2: .5rem; --r3: .75rem; --r4: 1rem;
  --r5: 1.5rem; --r6: 2rem; --r7: 3rem; --r8: 4rem; --r9: 6rem;

  --radius: 12px;                   /* DESIGN.md: radius 12px */
  --lebar-isi: 1240px;
  --tepi: 1.25rem;

  --bar-atas: 0px;
  --bar-bawah: calc(56px + env(safe-area-inset-bottom, 0px));
}

/* -----------------------------------------------------------------------------
   2. DASAR
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

/* Atribut `hidden` KALAH oleh `display` mana pun yang ditulis di CSS. Gejalanya
   mahal dan hanya terlihat setelah dirender: pesan galat formulir tampil sejak
   halaman dibuka karena .pesan menyetel display:flex. Satu aturan ini menutup
   seluruh kelasnya. */
[hidden] { display: none !important; }

html {
  /* Jangkar berhenti tepat di bawah bar, dan ini juga menyelamatkan elemen yang
     menerima fokus keyboard (teknik W3C C43 untuk WCAG 2.2 SC 2.4.11). */
  scroll-padding-top: calc(var(--bar-atas) + var(--r4));
  scroll-padding-bottom: calc(var(--bar-bawah) + var(--r4));
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--latar);
  color: var(--tinta);
  font-family: var(--f-isi);
  font-size: var(--t-isi);
  line-height: 1.6;
  /* Ruang untuk bar tab bawah di mobile supaya isi terakhir tidak tertutup. */
  padding-bottom: var(--bar-bawah);
}

h1, h2, h3, h4 { font-family: var(--f-judul); font-weight: 700; line-height: 1.2; margin: 0; }
h1 { font-size: clamp(2.125rem, 5vw, 3.375rem); letter-spacing: -0.01em; }
h2 { font-size: clamp(1.5rem, 3.2vw, 2.25rem); letter-spacing: -0.01em; }
h3 { font-size: clamp(1.125rem, 1.9vw, 1.375rem); }
p  { margin: 0; }
img { max-width: 100%; height: auto; display: block; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; }

/* Harga dan angsuran: Fraunces 700, angka BESAR yang berdiri sendiri.
   DESIGN.md meminta angka tabular di sini, tapi subset latin Fraunces dari Google
   Fonts TIDAK punya fitur `tnum` dan lebar angkanya tidak seragam (diperiksa
   dengan fontTools: 1407, 983, 1287, … per 2000 upem). Jadi `tabular-nums` di
   bawah ini TIDAK berpengaruh pada Fraunces, ia ditulis supaya rantai cadangan
   sistem tetap tabular, bukan supaya terlihat patuh.
   Yang benar-benar butuh sejajar antar-baris memakai .angka-tabel di bawah. */
.angka { font-family: var(--f-judul); font-weight: 700; font-variant-numeric: tabular-nums; }
/* Angka yang DIBANDINGKAN LAWAN BARIS LAIN: Inter, yang punya `tnum` sungguhan. */
.angka-tabel { font-family: var(--f-isi); font-weight: 600; font-variant-numeric: tabular-nums; }

/* CINCIN FOKUS, SELALU 2px tinta dengan offset 2px. Di paket ini bukan lagi
   pilihan melainkan keharusan: cokelat 2,99:1 tidak sampai ke lantai 3:1, jadi cincin
   fokus beraksen adalah cincin fokus yang tidak terlihat. DESIGN.md menyebutnya
   eksplisit bersama border, garis bawah aktif, dan ikon fungsional. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--tinta);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Lewati ke konten, wajib ada, dan wajib terlihat saat difokus. */
.lewati {
  position: absolute; left: var(--tepi); top: -100px; z-index: 100;
  background: var(--tinta); color: #fff; padding: var(--r3) var(--r4);
  border-radius: var(--radius); font-weight: 600; text-decoration: none;
}
.lewati:focus-visible { top: var(--r3); }

/* -----------------------------------------------------------------------------
   3. TATA LETAK
   -------------------------------------------------------------------------- */
.bungkus { width: 100%; max-width: var(--lebar-isi); margin-inline: auto; padding-inline: var(--tepi); }
.bagian { padding-block: var(--r7); }
.bagian + .bagian { border-top: 1px solid var(--garis); }
@media (min-width: 768px) { .bagian { padding-block: var(--r8); } }

.kepala-bagian { margin-bottom: var(--r5); max-width: 62ch; }
.kepala-bagian p { color: var(--redup); margin-top: var(--r2); }

.kisi { display: grid; gap: var(--r4); }
@media (min-width: 640px)  { .kisi-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 900px)  { .kisi-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
                             .kisi-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 640px) and (max-width: 899px) { .kisi-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Tiap anak kisi WAJIB boleh menyusut, kalau tidak isi yang lebar mendorong
   lebar halaman dan yang dilaporkan meluber justru elemen lain. */
.kisi > * { min-width: 0; }

/* -----------------------------------------------------------------------------
   4. PITA "DESAIN CONTOH", tidak bisa ditutup, wajib di tiap halaman
   -------------------------------------------------------------------------- */
.pita {
  background: var(--tinta); color: #fff;   /* 14,84:1 */
  font-size: 0.8125rem; text-align: center;
  padding: var(--r2) var(--tepi);
}

/* -----------------------------------------------------------------------------
   5. NAVBAR (desktop), di mobile digantikan bar tab bawah
   -------------------------------------------------------------------------- */
.navbar { border-bottom: 1px solid var(--garis); background: var(--latar); }
.navbar-isi { display: flex; align-items: center; gap: var(--r4); min-height: 64px; }
.wordmark {
  font-family: var(--f-judul); font-weight: 600; letter-spacing: .06em;
  font-size: 0.9375rem; text-decoration: none; white-space: nowrap;
}
.nav-tautan { display: none; gap: var(--r5); margin-inline: auto; }
.nav-tautan a { text-decoration: none; color: var(--redup); font-size: var(--t-kecil); }
.nav-tautan a:hover { color: var(--tinta); }
/* Item aktif TIDAK dibedakan warna saja, ada garis bawah tebal juga.
   Garis itu TINTA (14,01:1), bukan aksen: aksen di atas latar cuma 2,99:1 dan
   meleset dari lantai 3:1 untuk penanda non-teks. Brief menyebutnya dua kali,
   dan di situs 06 baris ini memang beraksen, inilah tempat menyalin paling
   berbahaya di seluruh berkas. */
.nav-tautan a[aria-current="page"] {
  color: var(--tinta); font-weight: 700;
  box-shadow: inset 0 -3px 0 0 var(--tinta);
}
@media (min-width: 900px) { .nav-tautan { display: flex; } }
.navbar .tombol { margin-left: auto; }
@media (min-width: 900px) { .navbar .tombol { margin-left: 0; } }

/* -----------------------------------------------------------------------------
   6. TOMBOL, target sentuh minimal 48px, tombol utama 52px di mobile
   -------------------------------------------------------------------------- */
.tombol {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--r2);
  min-height: 48px; padding: var(--r3) var(--r5);
  /* 16px, BUKAN 14px: DESIGN.md menuntut label tombol utama minimal 16px bobot
     600 karena tinta di atas aksen cuma menyisakan 0,18 dari ambang AA, dan
     glif tipis kecil di atas nada-tengah kehilangan kontras efektif ke
     antialiasing walau rasio terhitungnya lolos. */
  font-family: var(--f-isi); font-size: var(--t-isi); font-weight: 600;
  border-radius: var(--radius); border: 1px solid transparent;
  text-decoration: none; cursor: pointer; background: none; color: var(--tinta);
  transition: background-color .15s ease, border-color .15s ease;
}
.tombol-utama { background: var(--aksen); color: var(--tinta); }   /* 4,68:1 */
.tombol-utama:hover { background: var(--aksen-tekan); }            /* 5,37:1, lebih TERANG */
.tombol-utama:active { background: var(--aksen-tekan); }
.tombol-kedua { border-color: var(--garis-kendali); color: var(--tinta); }  /* 5,62:1 */
.tombol-kedua:hover { background: var(--sentuh); }
.tombol-blok { width: 100%; }
.tombol[disabled], .tombol[aria-disabled="true"] {
  background: var(--nonaktif); color: var(--redup); border-color: transparent;
  cursor: not-allowed;
}
.tombol-alasan { font-size: var(--t-kecil); color: var(--redup); margin-top: var(--r2); }

/* Keadaan memuat: tombol punya LABELNYA SENDIRI, bukan cuma spinner. */
.tombol[data-memuat="ya"] { pointer-events: none; }
.pemintal {
  width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent;
  animation: putar .7s linear infinite; flex: none;
}
@keyframes putar { to { transform: rotate(360deg); } }

/* -----------------------------------------------------------------------------
   7. IKON, SVG sebaris, BUKAN emoji dan bukan font ikon.
   Brief menyebut Material Symbols; yang dipakai di sini SVG sebaris dengan bentuk
   yang sama maknanya. Alasannya bukan selera: font ikon berbasis ligatur
   menampilkan nama glyph sebagai teks mentah sebelum fontnya termuat, dan itu
   berarti kata "request_quote" sempat terbaca di layar pembeli.
   -------------------------------------------------------------------------- */
.ikon { width: 20px; height: 20px; flex: none; stroke: currentColor;
        fill: none; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.ikon-besar { width: 28px; height: 28px; }
.ikon-redup { color: var(--redup); }
/* TIDAK ADA .ikon-aksen di paket ini: ikon fungsional bercokelat cuma 2,99:1, di
   bawah lantai 3:1. Ikon memakai --tinta (14,01:1) atau --redup (5,62:1). */

/* -----------------------------------------------------------------------------
   8. KARTU, border 1px, TANPA bayangan (DESIGN.md)
   -------------------------------------------------------------------------- */
.kartu {
  background: var(--kertas); border: 1px solid var(--garis);
  border-radius: var(--radius); padding: var(--r4);
}
.kartu h3 { margin-bottom: var(--r2); }
.kartu p { color: var(--redup); font-size: var(--t-kecil); }

/* Cip beraksen: 14px, BUKAN 12px seperti situs 06. Ia duduk di atas aksen, dan
   lantai teks di atas aksen paket ini 14px bobot 500, bukan --t-label. */
.cip {
  display: inline-block; background: var(--aksen); color: var(--tinta);  /* 4,68:1 */
  font-size: var(--t-kecil); font-weight: 600; letter-spacing: .02em;
  padding: 2px var(--r3); border-radius: 999px;
}
.cip-netral { background: var(--nonaktif); color: var(--tinta); }
/* DESIGN.md paket ini: status TIDAK PERNAH dibawa warna saja, tiap cip
   ketersediaan memasangkan ikon, kata, dan warna sekaligus. Bordernya TINTA,
   bukan aksen: 2,99:1 tidak sampai ke lantai 3:1 untuk garis. */
.cip-garis {
  /* inline-flex, BUKAN inline-block warisan .cip: cip bergaris hampir selalu
     membawa ikon, dan sebagai inline-block ikonnya duduk di garis dasar teks lalu
     terlihat seperti glyph yang rusak. Terlihat jelas di kisi cip layanan. */
  display: inline-flex; align-items: center; gap: var(--r2);
  background: var(--kertas); color: var(--tinta);
  border: 1px solid var(--tinta); text-transform: none; letter-spacing: 0;
  font-size: var(--t-kecil); padding: var(--r1) var(--r3);
}

.tautan-panah {
  display: inline-flex; align-items: center; gap: var(--r1);
  font-size: var(--t-kecil); font-weight: 600; text-decoration: none;
  color: var(--tinta); text-underline-offset: 3px;   /* aksen GAGAL sebagai teks: 2,99:1 */
}
.tautan-panah:hover { text-decoration: underline; }

/* -----------------------------------------------------------------------------
   9. HERO
   -------------------------------------------------------------------------- */
.hero { display: grid; gap: var(--r5); align-items: center; }
@media (min-width: 900px) { .hero { grid-template-columns: 1.05fr .95fr; gap: var(--r7); } }
.hero-mata { font-size: var(--t-kecil); font-weight: 600; color: var(--redup); letter-spacing: .06em; text-transform: uppercase; }
.hero h1 { margin-block: var(--r3); }
.hero-sub { color: var(--redup); font-size: 1.0625rem; max-width: 56ch; }
.hero-aksi { display: flex; flex-wrap: wrap; gap: var(--r3); margin-top: var(--r5); }
.hero-aksi .tombol { min-height: 52px; }      /* aksi utama di mobile 52px */
.hero-statistik { display: flex; flex-wrap: wrap; gap: var(--r5); margin-top: var(--r5);
                  padding-top: var(--r4); border-top: 1px solid var(--garis); }
.hero-statistik div { min-width: 0; }
.hero-statistik .angka { font-size: 1.25rem; display: block; }
.hero-statistik span:last-child { font-size: var(--t-kecil); color: var(--redup); }
.hero-foto { border-radius: var(--radius); border: 1px solid var(--garis); overflow: hidden; }
.hero-foto img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }

/* -----------------------------------------------------------------------------
   10. PITA STATISTIK BERAKSEN, SELURUH teks di atasnya wajib TINTA.
   Terhitung sendiri: tinta di atas cokelat #B08968 4,68:1 LULUS, putih di atasnya
   3,17:1 GAGAL. Karena headroom-nya cuma 0,18, tiap label di pita ini dijaga
   minimal 14px dan bobot 500, itu aturan tambahan yang tidak ada di paket lain.
   -------------------------------------------------------------------------- */
.pita-statistik { background: var(--aksen); color: var(--tinta); padding-block: var(--r6); }
.pita-statistik .kisi { gap: var(--r5); grid-template-columns: repeat(2, minmax(0,1fr)); }
@media (min-width: 900px) { .pita-statistik .kisi { grid-template-columns: repeat(5, minmax(0,1fr)); } }
.pita-statistik .angka { font-size: clamp(1.375rem, 2.3vw, 1.75rem); display: block; }
.pita-statistik span:last-child { font-size: var(--t-kecil); font-weight: 500; }
/* Cincin fokus di atas pita ini tetap TINTA, ia terbaca di atas cokelat maupun
   di atas latar, jadi tidak perlu pengecualian warna fokus di mana pun. */

/* Pita kalimat beraksen, sama aturannya, teks tinta. */
.pita-aksen {
  background: var(--aksen); color: var(--tinta); border-radius: var(--radius);
  padding: var(--r5); font-size: 1.0625rem;
}

/* -----------------------------------------------------------------------------
   11. BARIS DAFTAR NATIVE, padanan mobile untuk tabel dan dropdown.
   Tinggi minimal 56px. Dipakai juga di desktop karena polanya memang terbaca.
   -------------------------------------------------------------------------- */
.daftar { border: 1px solid var(--garis); border-radius: var(--radius); background: var(--kertas); }
.baris {
  display: flex; align-items: center; gap: var(--r3);
  min-height: 56px; padding: var(--r3) var(--r4);
  border-bottom: 1px solid var(--garis);
}
.baris:last-child { border-bottom: 0; }
.baris-isi { min-width: 0; flex: 1; }
/* Keduanya WAJIB blok. Sebagai span inline, judul dan keterangannya menyambung
   jadi satu paragraf dan barisnya berhenti terbaca sebagai baris daftar native, terlihat jelas di 390px, tidak terlihat sama sekali dari kode. */
.baris-label { display: block; font-weight: 600; font-size: var(--t-kecil); }
.baris-nilai { display: block; font-size: var(--t-kecil); color: var(--redup); }
/* Baris dua kolom (label kiri, nilai kanan) tetap sebaris: di situ keterangannya
   pendek dan memang berpasangan, bukan judul-dan-penjelasan. */
.baris > .baris-nilai:first-child { display: inline; }
/* TANPA nowrap. Nilai panjang seperti "Monday to Friday 08.00 to 17.00, Saturday
   08.00 to 13.00, GMT+7" tidak bisa membungkus dan mendorong lebar halaman:
   terukur meluber 54px di 320px pada situs 02, dan yang dilaporkan meluber justru
   <main>, bukan span penyebabnya. */
.baris-kanan { margin-left: auto; font-weight: 600; font-size: var(--t-kecil);
               text-align: right; min-width: 0; overflow-wrap: anywhere; }
.baris-kanan.angka { font-weight: 600; }
a.baris { text-decoration: none; }
a.baris:hover { background: var(--sentuh); }

/* -----------------------------------------------------------------------------
   12. TABEL, GARIS MENDATAR SAJA, tinggi baris 48px (DESIGN.md).
   Di bawah 768px tabel lebar tetap bisa digulir mendatar di dalam kotaknya
   sendiri; halamannya TIDAK ikut bergeser.
   -------------------------------------------------------------------------- */
.tabel-bungkus { overflow-x: auto; border: 1px solid var(--garis); border-radius: var(--radius);
                 background: var(--kertas);
                 /* WAJIB. Lihat komentar panjang di atas: tanpa ini .hanya-layar-baca
                    di dalam tabel lolos dari pangkasan overflow dan menarik lebar
                    dokumen sampai 263px melewati layar 390px. */
                 position: relative; }
table { border-collapse: collapse; width: 100%; font-size: var(--t-kecil); }
th, td { text-align: left; padding: var(--r3) var(--r4); border-bottom: 1px solid var(--garis);
         height: 48px; }
th { font-weight: 600; background: var(--sentuh); white-space: nowrap; }  /* 13,93:1 */
/* Angka lajur dua dan seterusnya dibandingkan lawan lajur → tabular. */
td:not(:first-child) { font-variant-numeric: tabular-nums; }
tr:last-child td { border-bottom: 0; }
/* Tabel bank: kolom bunga tetap ditebalkan supaya angka yang dibandingkan
   pembeli menonjol tanpa harus diwarnai. */
.tabel-bank td:nth-child(2) { font-weight: 600; }
caption { caption-side: top; text-align: left; padding: var(--r3) var(--r4);
          font-size: var(--t-kecil); color: var(--redup); }

/* -----------------------------------------------------------------------------
   13. CAROUSEL GESER, kartu berikutnya mengintip, ada titik indikator
   -------------------------------------------------------------------------- */
.carousel {
  display: grid; grid-auto-flow: column; grid-auto-columns: min(78%, 320px);
  gap: var(--r4); overflow-x: auto; scroll-snap-type: x mandatory;
  padding-bottom: var(--r3); scrollbar-width: thin;
  /* Geser mendatar ditangkap carousel, gulir tegak halaman tetap jalan. */
  touch-action: pan-y;
}
.carousel > * { scroll-snap-align: start; }
@media (min-width: 900px) {
  .carousel { grid-auto-flow: row; grid-template-columns: repeat(3, minmax(0,1fr));
              overflow: visible; scroll-snap-type: none; }
}
.titik { display: flex; gap: var(--r2); justify-content: center; margin-top: var(--r3); }
.titik span { width: 6px; height: 6px; border-radius: 50%; background: var(--garis-kendali); opacity: .35; }
.titik span[data-aktif="ya"] { opacity: 1; width: 18px; border-radius: 3px; }
@media (min-width: 900px) { .titik { display: none; } }

/* -----------------------------------------------------------------------------
   14. TIMELINE, tegak di mobile, mendatar di layar lebar.
   ⚠️ Paket ini TIDAK memakai timeline mendatar sama sekali. Yang dibutuhkan
   riwayat pelacakan enam langkah yang SELALU tegak (halaman /lacak), karena
   urutannya kronologis dan tiap langkah membawa tanggal, jam, judul, dan
   keterangan, empat baris yang tidak pernah muat di satu kolom mendatar.
   Kelasnya .timeline-tegak di bagian 36; .timeline mendatar dibiarkan utuh
   supaya struktur berkas tetap sebangun dengan situs 01–05.
   -------------------------------------------------------------------------- */
.timeline { position: relative; padding-left: 44px; }
.timeline::before {
  content: ""; position: absolute; left: 15px; top: 12px; bottom: 12px;
  width: 2px; background: var(--garis);
}
.langkah { position: relative; padding-bottom: var(--r5); }
.langkah:last-child { padding-bottom: 0; }
.langkah-nomor {
  position: absolute; left: -44px; top: 0; width: 32px; height: 32px;
  display: grid; place-items: center; border-radius: 50%;
  background: var(--aksen); color: var(--tinta);         /* 4,68:1 */
  /* 14px bobot 700: lantai teks di atas aksen paket ini, bukan --t-label. */
  font-family: var(--f-judul); font-weight: 700; font-size: var(--t-kecil);
}
.langkah h3 { font-size: 1.0625rem; }
.langkah p { color: var(--redup); font-size: var(--t-kecil); margin-top: var(--r1); }
/* TUJUH langkah di paket ini, bukan lima. Jumlah kolom timeline SELALU ikut
   diperiksa saat menyalin, paket berbeda punya jumlah langkah berbeda, dan kisi
   lima yang menampung tujuh membuat dua langkah terakhir jatuh ke baris kedua
   dengan lebar yang tidak sama. Tujuh kolom hanya dinyalakan di ≥1100px; di bawah
   itu ia tetap TEGAK, karena keterangan tiap langkah di sini satu kalimat penuh
   dan tidak pernah muat di kolom 150px. */
@media (min-width: 1100px) {
  .timeline-7 { display: grid; grid-template-columns: repeat(7, minmax(0,1fr));
                gap: var(--r5) var(--r4); padding-left: 0; }
  .timeline-7::before { display: none; }      /* diganti border per langkah */
  .timeline-7 > .langkah { padding: calc(var(--r5) + 16px) 0 0;
                           border-top: 2px solid var(--garis); min-width: 0; }
  .timeline-7 > .langkah-nomor, .timeline-7 .langkah-nomor { left: 0; top: -16px; }
  .timeline-7 .langkah h3 { font-size: 1rem; }
}

/* -----------------------------------------------------------------------------
   15. AKORDEON FAQ, <details> asli, jadi tetap bisa dibuka tanpa JavaScript
   -------------------------------------------------------------------------- */
.faq { border: 1px solid var(--garis); border-radius: var(--radius); background: var(--kertas); }
.faq details { border-bottom: 1px solid var(--garis); }
.faq details:last-child { border-bottom: 0; }
.faq summary {
  display: flex; align-items: center; gap: var(--r3); cursor: pointer;
  min-height: 56px; padding: var(--r3) var(--r4);
  font-weight: 600; font-size: var(--t-kecil); list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary .ikon { margin-left: auto; transition: transform .2s ease; }
.faq details[open] summary .ikon { transform: rotate(180deg); }
.faq .jawab { padding: 0 var(--r4) var(--r4); color: var(--redup); font-size: var(--t-kecil); }

/* -----------------------------------------------------------------------------
   16. FORMULIR, border kendali WAJIB --garis-kendali (5,62:1), bukan --garis (1,25:1)
   -------------------------------------------------------------------------- */
.bidang { display: block; margin-bottom: var(--r4); }
.bidang > label, .label { display: block; font-size: var(--t-kecil); font-weight: 600; margin-bottom: var(--r2); }
.kolom {
  width: 100%; min-height: 52px; padding: var(--r3);
  /* 52px, bukan 48px: DESIGN.md paket ini meminta kolom dan tombol minimal 52px.
     16px WAJIB: di bawah itu Safari iOS ikut memperbesar layar saat kolom difokus. */
  font-size: var(--t-isi); font-family: var(--f-isi); color: var(--tinta);
  background: var(--kertas); border: 1px solid var(--garis-kendali);
  border-radius: var(--radius);
}
.kolom::placeholder { color: #6E736F; }   /* 4,83:1 di atas --kertas */
textarea.kolom { min-height: 120px; resize: vertical; }
.bantuan { font-size: var(--t-kecil); color: var(--redup); margin-top: var(--r2); }
.bantuan-galat { color: var(--galat); font-weight: 600; }      /* 6,17:1 */
.bantuan-sukses { color: var(--sukses); font-weight: 600; }    /* 6,18:1 */
.kolom[aria-invalid="true"] { border-color: var(--galat); border-width: 2px; }
.kolom[disabled] { background: var(--nonaktif); color: var(--redup); cursor: not-allowed; }

/* Radio sebaris (W14: tiga pilihan dalam satu baris), target sentuh 48px penuh,
   dan yang terpilih ditandai border DAN alas, bukan warna titik saja. */
.pilihan { display: grid; gap: var(--r2); }
@media (min-width: 640px) { .pilihan { grid-auto-flow: column; grid-auto-columns: 1fr; } }
.pilihan label {
  display: flex; align-items: center; gap: var(--r2); min-height: 48px;
  padding: var(--r2) var(--r3); border: 1px solid var(--garis-kendali);
  border-radius: var(--radius); background: var(--kertas);
  font-size: var(--t-kecil); cursor: pointer;
}
/* accent-color menggambar isian kendali DAN centangnya PUTIH. Putih di atas
   cokelat cuma 3,17:1, jadi kendalinya bertinta (putih di atas tinta 14,84:1). */
.pilihan input { width: 20px; height: 20px; accent-color: var(--tinta); flex: none; }
.pilihan label:has(input:checked) { border-color: var(--tinta); border-width: 2px; background: var(--aksen-alas); }

/* Segmented control, padanan mobile untuk radio 2 sampai 3 opsi */
.segmen { display: flex; border: 1px solid var(--garis-kendali); border-radius: var(--radius); overflow: hidden; }
.segmen button {
  flex: 1; min-height: 48px; border: 0; background: var(--kertas); cursor: pointer;
  font-family: var(--f-isi); font-size: var(--t-kecil); font-weight: 600; color: var(--tinta);
}
.segmen button + button { border-left: 1px solid var(--garis-kendali); }
/* Tombol tersegmen terpilih: isian aksen, label tinta 14px bobot 600 (4,68:1),
   DITAMBAH border tinta 2px supaya keterpilihannya tidak hanya di warna. */
.segmen button[aria-pressed="true"] { background: var(--aksen); color: var(--tinta);
                                      box-shadow: inset 0 0 0 2px var(--tinta); }

/* -----------------------------------------------------------------------------
   17. PESAN DALAM HALAMAN, supaya implementasi tidak jatuh ke alert() peramban.
   Tidak pernah membawa makna lewat warna saja: selalu ada ikon dan kata.
   -------------------------------------------------------------------------- */
.pesan {
  display: flex; gap: var(--r3); align-items: flex-start;
  padding: var(--r3) var(--r4); border-radius: var(--radius);
  border-left: 4px solid; font-size: var(--t-kecil);
}
.pesan-galat { background: var(--galat-alas); border-color: var(--galat); color: var(--tinta); }
.pesan-peringatan { background: var(--peringatan-alas); border-color: var(--peringatan); color: var(--tinta); }
.pesan-sukses { background: var(--sukses-alas); border-color: var(--sukses); color: var(--tinta); }
.pesan b { display: block; }

/* -----------------------------------------------------------------------------
   18. BAR TAB BAWAH (mobile), navigasi UTAMA di mobile, bukan hamburger
   -------------------------------------------------------------------------- */
.tab-bar {
  position: fixed; inset-inline: 0; bottom: 0; z-index: 40;
  display: grid; grid-template-columns: repeat(5, 1fr);
  background: var(--kertas); border-top: 1px solid var(--garis);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.tab-bar a {
  display: grid; place-items: center; gap: 2px;
  min-height: 56px; padding: var(--r2) var(--r1);
  text-decoration: none; color: var(--redup); font-size: var(--t-label);
}
/* Tab aktif dibedakan warna DAN tebal DAN garis atas, bukan warna saja. Garis
   atasnya TINTA (14,01:1): aksen 2,99:1 meleset dari lantai 3:1 untuk penanda.
   Isian pil beraksen di belakang ikon tetap boleh, itu isian, bukan penanda
   tipis, dan ikonnya bertinta di atasnya (4,68:1). */
.tab-bar a[aria-current="page"] { color: var(--tinta); font-weight: 600; box-shadow: inset 0 3px 0 0 var(--tinta); }
.tab-bar a[aria-current="page"] .ikon { background: var(--aksen); border-radius: 999px;
                                        padding: 2px 10px; box-sizing: content-box; width: 20px; }
.tab-bar .ikon { width: 22px; height: 22px; }
@media (min-width: 900px) { .tab-bar { display: none; } body { padding-bottom: 0; } }

/* -----------------------------------------------------------------------------
   19. BOTTOM SHEET, padanan mobile untuk dropdown
   -------------------------------------------------------------------------- */
.lapis { position: fixed; inset: 0; z-index: 50; background: rgba(31,42,36,.62); display: grid; align-items: end; }
.lapis[hidden] { display: none; }
.sheet {
  background: var(--kertas); border-radius: 12px 12px 0 0;
  padding-bottom: env(safe-area-inset-bottom, 0px); max-height: 80vh; overflow-y: auto;
}
.sheet-pegangan { width: 36px; height: 4px; background: var(--garis-kendali); opacity: .5;
                  border-radius: 2px; margin: var(--r3) auto; }
.sheet-kepala { display: flex; align-items: center; gap: var(--r3); padding: 0 var(--r4) var(--r3);
                border-bottom: 1px solid var(--garis); }
.sheet-kepala h3 { font-size: 1rem; }
.sheet-tutup { margin-left: auto; min-width: 48px; min-height: 48px; display: grid; place-items: center;
               background: none; border: 0; cursor: pointer; color: var(--tinta); }
@media (min-width: 900px) {
  .lapis { align-items: center; justify-items: center; }
  .sheet { border-radius: var(--radius); max-width: 480px; width: 100%; }
}

/* Lightbox foto */
.lightbox img { width: 100%; max-height: 80vh; object-fit: contain; background: #000; }

/* -----------------------------------------------------------------------------
   20. SKELETON MEMUAT, bukan spinner, supaya bentuk halaman sudah terbaca
   -------------------------------------------------------------------------- */
.tulang { background: var(--nonaktif); border-radius: var(--radius); position: relative; overflow: hidden; }
.tulang::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.65), transparent);
  animation: kilau 1.4s ease-in-out infinite;
}
@keyframes kilau { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
.tulang-baris { height: 14px; margin-bottom: var(--r2); }
.tulang-judul { height: 28px; width: 60%; margin-bottom: var(--r3); }
.tulang-foto { aspect-ratio: 4 / 3; }

/* -----------------------------------------------------------------------------
   21. HALAMAN GALAT
   DITINJAU ULANG UNTUK KEENAM KALINYA, dan hasilnya kebetulan sama dengan situs
   06, tapi karena hitungannya, bukan karena disalin. Aksen #B08968 di atas latar
   cuma 2,99:1, jadi angka "404" beraksen akan nyaris tak terbaca. Polanya: aksen
   jadi BLOK, angkanya bertinta di atasnya (4,68:1), ukurannya jauh di atas 14px
   dan bobotnya 700, dua syarat tambahan paket ini terpenuhi dengan sendirinya.
   -------------------------------------------------------------------------- */
.galat-kode { font-family: var(--f-judul); font-weight: 700; font-size: clamp(3rem, 12vw, 6rem);
              line-height: 1.1; display: inline-block; padding-inline: var(--r4);
              border-radius: var(--radius);
              background: var(--aksen); color: var(--tinta); }           /* 4,68:1 */
.galat-halaman p:not(.galat-kode) { color: var(--redup); }
.galat-aksi { display: flex; flex-wrap: wrap; gap: var(--r3); justify-content: center; }

/* Anak yang dipusatkan lewat place-items:center TIDAK melar: lebarnya lahir dari
   isinya sendiri, jadi satu paragraf panjang bisa melewati viewport, terukur
   10px di 320px pada situs 02, dan yang dilaporkan meluber cuma "p" tanpa kelas,
   mustahil ditebak dari kode. max-width:100% saja TIDAK menutupnya; grid-nya yang
   dicabut. Halaman galat di sini karena itu blok sejak awal, bukan grid. */
.galat-halaman { display: block; text-align: center; padding-block: var(--r9);
                 max-width: 56ch; margin-inline: auto; }
.galat-halaman > * + * { margin-top: var(--r4); }
.galat-halaman > * { max-width: 100%; }

/* -----------------------------------------------------------------------------
   22. FOOTER
   -------------------------------------------------------------------------- */
.footer { background: var(--tinta); color: #fff; padding-block: var(--r7); margin-top: var(--r7); }
.footer a { color: #CBD2CD; text-decoration: none; font-size: var(--t-kecil); }  /* 9,64:1 di atas tinta */
.footer a:hover { color: #fff; text-decoration: underline; }
.footer h4 { font-size: var(--t-label); letter-spacing: .08em; text-transform: uppercase; margin-bottom: var(--r3); }
.footer li { margin-bottom: var(--r2); }
.footer-atas { display: grid; gap: var(--r5); }
@media (min-width: 768px) { .footer-atas { grid-template-columns: 2fr 1fr 1fr 1fr; gap: var(--r6); } }
.footer-tentang { color: #CBD2CD; font-size: var(--t-kecil); margin-top: var(--r3); max-width: 40ch; }
.footer-bawah {
  margin-top: var(--r6); padding-top: var(--r4); border-top: 1px solid #35443C;
  display: flex; flex-wrap: wrap; gap: var(--r3); justify-content: space-between;
  font-size: var(--t-kecil); color: #CBD2CD;
}
.footer :focus-visible { outline-color: #fff; }

/* -----------------------------------------------------------------------------
   23. UTILITAS
   -------------------------------------------------------------------------- */
.hanya-layar-baca {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.tumpuk-2 { display: grid; gap: var(--r2); }
.tumpuk-3 { display: grid; gap: var(--r3); }
.tumpuk-4 { display: grid; gap: var(--r4); }
.redup { color: var(--redup); }
.kecil { font-size: var(--t-kecil); }
@media (min-width: 900px) { .hanya-mobile { display: none !important; } }
@media (max-width: 899px) { .hanya-desktop { display: none !important; } }

/* -----------------------------------------------------------------------------
   24. GERAK DIKURANGI, hormati preferensi sistem
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
  .tulang::after { animation: none; }
}

/* -----------------------------------------------------------------------------
   25. FOTO, POTRET, DAN PENGGANTI FOTO
   Tiap foto di folder aset/ SUDAH DILIHAT satu per satu, bukan dinilai dari nama
   berkasnya. Dua di antaranya memuat teks milik pihak lain dan keduanya
   diselesaikan dengan MEMOTONG BINGKAI, bukan dengan mengaburkan:

     · potret manajer proyek, helm bertulisan "BALI BUANA ENGINEERING", polo
       berlogo sama, kartu pengenal, dan nama bordir "WAYAN ADI - PROJECT
       MANAGER" yang bukan nama orang di brief. Dipotong sampai batas leher.
     · potret legal, papan kaca "UDAYANA LAW FIRM" di latar dan pena bertuliskan
       "LAWASIA" di meja. Keduanya menyerempet lembaga yang benar-benar ada,
       jadi bingkainya dipersempit sampai keduanya keluar.

   Sidik perseptual keempat potret sudah diukur (jarak Hamming 84–152, ambang 30):
   keempatnya orang yang BERBEDA, jadi tidak ada yang perlu diganti .potret-inisial.

   Denah tipe 45/90 dipotong untuk membuang blok judul "TYPE 45/90 / SMALL MODERN
   HOUSE", dan keenam label ruangnya ditimpa bahasa Indonesia, teks di dalam
   gambar juga teks layar, dan aturan bahasa berlaku di sana juga.
   -------------------------------------------------------------------------- */
.gambar-lebar, .foto-kosong {
  aspect-ratio: 4 / 3; width: 100%; object-fit: cover;
  border-radius: var(--radius); border: 1px solid var(--garis); background: var(--nonaktif);
}
.foto-kosong {
  display: grid; place-content: center; justify-items: center; gap: var(--r2);
  color: var(--redup);                                  /* 4,93:1 di atas --nonaktif */
  background-color: var(--nonaktif);
  background-image: linear-gradient(var(--garis) 1px, transparent 1px),
                    linear-gradient(90deg, var(--garis) 1px, transparent 1px);
  background-size: 16px 16px;
}
.foto-kosong span {
  font-family: var(--f-isi); font-weight: 600; font-size: var(--t-label);
  letter-spacing: .08em; background: var(--kertas); padding: 2px var(--r2);
  border-radius: 4px; border: 1px solid var(--garis); text-align: center;
}

.potret {
  width: 100%; aspect-ratio: 1 / 1; object-fit: cover;
  border-radius: var(--radius); border: 1px solid var(--garis); margin-bottom: var(--r3);
}
.potret-inisial {
  display: grid; place-items: center; background: var(--aksen-alas); color: var(--tinta);
  font-family: var(--f-judul); font-weight: 600; font-size: 1.75rem; letter-spacing: .04em;
}

/* Tombol pembungkus foto yang bisa diperbesar, tetap terlihat sebagai gambar */
.foto-tombol { display: block; width: 100%; padding: 0; border: 0; background: none; cursor: zoom-in; }
.foto-tombol img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
                   border-radius: var(--radius); border: 1px solid var(--garis); }

/* Pengganti peta, tidak memuat peta pihak ketiga, jadi tidak ada pelacak. */
.peta {
  display: grid; place-content: center; justify-items: center; gap: var(--r3);
  aspect-ratio: 4 / 3; border-radius: var(--radius); border: 1px solid var(--garis);
  color: var(--redup); text-align: center; padding: var(--r4);
  background-color: var(--nonaktif);
  background-image: linear-gradient(var(--garis) 1px, transparent 1px),
                    linear-gradient(90deg, var(--garis) 1px, transparent 1px);
  background-size: 24px 24px;
}
.peta span { font-size: var(--t-kecil); max-width: 28ch; }

/* Dua kolom di layar lebar, satu kolom di mobile. */
@media (min-width: 900px) {
  [data-dua-kolom] { grid-template-columns: 1fr 1fr; align-items: start; }
  /* Simulasi KPR: panel isian di kiri, panel hasil di kanan. */
  .kpr-tata { grid-template-columns: 1fr 1fr; gap: var(--r6) !important; align-items: start; }
  /* Denah: gambar denah di kiri, daftar ukuran ruang di kanan. */
  .denah-tata { grid-template-columns: 1.15fr 1fr; gap: var(--r6) !important; align-items: start; }
  /* Lokasi: peta di kiri, delapan baris jarak di kanan. */
  .lokasi-tata { grid-template-columns: 1fr 1.1fr; gap: var(--r6) !important; align-items: start; }
  /* Janji temu: formulir di kiri, kartu ringkasan yang lebih sempit di kanan.
     align-items:start WAJIB, tanpa itu kartu ringkasan yang isinya empat baris
     ikut melar setinggi formulir sebelas kolom, dan yang terlihat pengunjung
     adalah kartu setengah kosong sepanjang layar. */
  .survei-tata { grid-template-columns: 1.5fr 1fr; gap: var(--r6) !important; align-items: start; }
}

/* -----------------------------------------------------------------------------
   26. PENCARI, dipakai di halaman rute sebagai penyaring asal dan tujuan
   -------------------------------------------------------------------------- */
.pencari { display: grid; gap: var(--r3); align-items: end; margin-bottom: var(--r6); }
@media (min-width: 900px) { .pencari { grid-template-columns: repeat(3, minmax(0,1fr)) auto; } }
.pencari .bidang { margin: 0; }
.pencari .tombol { min-height: 48px; }

/* -----------------------------------------------------------------------------
   27. RAPI-RAPI DI BAWAH 900px, semuanya hanya terlihat setelah dirender
   -------------------------------------------------------------------------- */
@media (max-width: 899px) {
  /* Tombol navbar membungkus jadi dua baris dan mendesak wordmark sampai nyaris
     tak terbaca. Di mobile aksi ini juga sudah ada di bar tab bawah, jadi di sini
     ia cukup ringkas: tanpa ikon, padding lebih rapat, dan label 12px.
     ⚠️ Label 12px TIDAK BOLEH duduk di atas aksen, lantai teks di atas aksen
     paket ini 14px. Jadi di bawah 900px tombol ini BERHENTI beraksen dan berubah
     jadi tombol bergaris: tinta di atas latar 14,01:1, tanpa syarat ukuran. */
  .navbar .tombol-utama { background: none; color: var(--tinta);
                          border-color: var(--garis-kendali); }
  .navbar .tombol-utama:hover { background: var(--sentuh); }
  .navbar .tombol { padding-inline: var(--r3); white-space: nowrap; font-size: var(--t-label); }
  .navbar .tombol .ikon { display: none; }
  .wordmark { font-size: 0.75rem; letter-spacing: .04em; }

  /* Aksi utama melebar penuh supaya lebarnya seragam dan mudah dijangkau jempol. */
  .hero-aksi { flex-direction: column; align-items: stretch; }
  .hero-aksi .tombol { width: 100%; }
}

/* -----------------------------------------------------------------------------
   28. PONSEL SEMPIT (≤ 380px), iPhone SE dan Android kecil
   Label tab turun ke 11px dan padding dirapatkan. Wordmark paket ini tiga kata,
   jadi ia ikut mengecil.
   -------------------------------------------------------------------------- */
@media (max-width: 380px) {
  :root { --tepi: 1rem; }
  .tab-bar a { font-size: 0.6875rem; padding-inline: 2px; min-width: 0; }
  .tab-bar a > :last-child { max-width: 100%; overflow-wrap: anywhere; text-align: center; line-height: 1.15; }
  .tab-bar .ikon { width: 20px; height: 20px; }
  .wordmark { font-size: 0.625rem; }

  /* TERUKUR, bukan ditaksir: di 320px wordmark panjang plus tombol berlabel panjang
     yang TIDAK boleh membungkus mendorong lebar halaman. Label tombol didiktekan
     brief dan diuji verbatim, jadi yang dicabut nowrap-nya. Diwarisi dari situs 03
     dan 04; wordmark paket ini "BHUMI SADANA LAND" TIGA kata dan tombolnya
     berlabel "Jadwalkan Survei", jadi keduanya diberi izin membungkus. */
  .navbar .tombol { white-space: normal; text-align: center; line-height: 1.2;
                    padding-inline: var(--r2); }
}

/* Tombol sunting di baris ringkasan wizard */
.sunting {
  margin-left: auto; min-width: 44px; min-height: 44px;
  display: grid; place-items: center; background: none;
  border: 1px solid var(--garis); border-radius: var(--radius); cursor: pointer;
}
.sunting:hover { background: var(--sentuh); }

/* -----------------------------------------------------------------------------
   29. TABEL BIAYA, kolom rupiah rata KANAN dan tabular (Inter, yang punya tnum)
   -------------------------------------------------------------------------- */
.tabel-biaya td:last-child, .tabel-biaya th:last-child { text-align: right; }
.tabel-biaya td:last-child { font-weight: 600; font-variant-numeric: tabular-nums; }

/* -----------------------------------------------------------------------------
   30. KOTAK IKON, bingkai lembut untuk ikon lima aksi, layanan, dan industri.
   Alasnya --aksen-alas dan ikonnya TINTA (11,87:1). Ikon beraksen dilarang: aksen
   di atas alas lembut jatuh jauh di bawah lantai 3:1 untuk ikon fungsional.
   -------------------------------------------------------------------------- */
.ikon-kotak {
  width: 44px; height: 44px; flex: none; display: grid; place-items: center;
  border-radius: var(--radius); background: var(--aksen-alas); color: var(--tinta);
  margin-bottom: var(--r3);
}

/* -----------------------------------------------------------------------------
   31. BARIS INFO BERIKON, dipakai untuk rambu, catatan tarif, dan syarat dokumen.
   Ikonnya --redup (5,78:1): barisnya sering panjang dan ikon di sini berfungsi
   sebagai penanda jenis, bukan sebagai aksi.
   -------------------------------------------------------------------------- */
.info-baris { display: flex; gap: var(--r3); align-items: flex-start;
              font-size: var(--t-kecil); color: var(--redup); }
.info-baris .ikon { margin-top: 2px; }
.info-baris b { color: var(--tinta); }

/* Rambu "ini estimasi", muncul di beberapa tempat dan sengaja seragam.
   Garis kirinya PERINGATAN (6,90:1), bukan aksen: ia bukan promosi, ia batas. */
.rambu {
  display: flex; gap: var(--r3); align-items: flex-start;
  background: var(--peringatan-alas); border-left: 4px solid var(--peringatan);
  border-radius: var(--radius); padding: var(--r3) var(--r4);
  font-size: var(--t-kecil); color: var(--tinta);
}

/* Cip berbentuk KALIMAT (pil status di hero, cip "hampir penuh"). Cip biasa memakai
   huruf besar semua dan itu benar untuk satu-dua kata; untuk satu kalimat penuh ia
   berhenti terbaca. Bentuknya sama, hurufnya tidak dipaksa. */
.cip-kalimat {
  display: inline-flex; align-items: center; gap: var(--r2);
  text-transform: none; letter-spacing: 0; font-size: var(--t-kecil);
  padding: var(--r2) var(--r4);
}

/* Lima kolom hanya di layar yang benar-benar cukup lebar. Di bawah itu ia turun ke
   tiga lalu dua, bukan memaksa lima kartu sempit yang judulnya patah tiap kata. */
/* Pil status hero berdiri sendiri di atas eyebrow. p{margin:0} membuat keduanya
   berdempetan sampai terbaca seperti satu blok, terlihat di 390px maupun 1440px,
   dan tidak terlihat sama sekali dari kode. */
.hero .cip { margin-bottom: var(--r3); }

/* Pesan "ini desain contoh" yang muncul sesudah tombol yang memang tidak punya
   tujuan nyata. Tersembunyi sampai ditekan, dan isinya ditulis JS. */
.pesan-contoh { margin-top: var(--r3); }

@media (min-width: 1100px) { .kisi-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
@media (min-width: 900px) and (max-width: 1099px) { .kisi-5 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 640px) and (max-width: 899px) { .kisi-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* -----------------------------------------------------------------------------
   33. KARTU PENCARI UNIT, kendali paling sering dipakai di halaman ini, jadi ia
   dapat kartunya sendiri (DESIGN.md/W2).
   -------------------------------------------------------------------------- */
.pencari-kartu { background: var(--kertas); border: 1px solid var(--garis);
                 border-radius: var(--radius); padding: var(--r5); }
.pencari-baris { display: grid; gap: var(--r3); align-items: end; }
@media (min-width: 700px)  { .pencari-baris { grid-template-columns: repeat(3, minmax(0,1fr)); } }
@media (min-width: 1100px) { .pencari-baris { grid-template-columns: repeat(5, minmax(0,1fr)) auto; } }
.pencari-baris .bidang { margin: 0; min-width: 0; }
.pencari-baris .tombol { min-height: 52px; }

/* -----------------------------------------------------------------------------
   34. LIMA UBIN AKSI, baris pertama di bawah lipatan, dan yang menentukan
   vertikal ini. Lima kolom hanya di layar yang cukup lebar; di bawah itu turun ke
   tiga lalu dua, bukan lima ubin sempit yang labelnya patah tiap kata.
   -------------------------------------------------------------------------- */
@media (min-width: 1100px) { .kisi-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
@media (min-width: 900px) and (max-width: 1099px) { .kisi-5 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 560px) and (max-width: 899px) { .kisi-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
a.kartu { text-decoration: none; display: block; }
a.kartu:hover { background: var(--sentuh); }

/* -----------------------------------------------------------------------------
   35. BATANG, dipakai untuk persentase progres pembangunan. Cokelat 2,99:1 tidak
   pernah sendirian membawa makna: tiap batang membawa label kiri, persen bertinta,
   dan keterangan kanan. Alurnya diberi border --garis-kendali supaya tepinya
   terlihat tanpa mengandalkan warna (aksen di atas alur cuma 2,47:1).
   -------------------------------------------------------------------------- */
.batang { display: grid; gap: var(--r4); }
/* EMPAT kolom, bukan tiga: barisnya memang punya empat anak (label, persen, alur,
   jumlah sampel). Dengan tiga kolom anak keempat jatuh ke baris berikutnya dan
   jumlah sampel tampil di bawah labelnya, terlihat jelas sesudah dirender, dan
   tidak terlihat sama sekali dari kode. */
.batang-baris { display: grid; grid-template-columns: 12rem 5rem 1fr 11rem; gap: var(--r3);
                align-items: center; font-size: var(--t-kecil); }
.batang-nilai { font-family: var(--f-judul); font-weight: 600; font-size: 1.25rem;
                font-variant-numeric: tabular-nums; }
.batang-alur { height: 12px; background: var(--garis); border: 1px solid var(--garis-kendali);
               border-radius: 999px; overflow: hidden; }
.batang-isi { display: block; height: 100%; background: var(--aksen); }
.batang-sampel { color: var(--redup); }
.batang-total { border-top: 2px solid var(--tinta); padding-top: var(--r4); }
@media (max-width: 700px) {
  .batang-baris { grid-template-columns: 1fr auto; }
  .batang-alur, .batang-sampel { grid-column: 1 / -1; }
}

/* -----------------------------------------------------------------------------
   36. RIWAYAT PELACAKAN, timeline yang SELALU tegak, tidak pernah mendatar.
   Langkah berjalan ditandai isian aksen DAN kata "Berjalan sekarang"; langkah
   mendatang bertinta redup DAN berlabel "Perkiraan". Tidak ada keadaan yang
   maknanya hanya di warna.
   -------------------------------------------------------------------------- */
.riwayat { position: relative; padding-left: 44px; }
.riwayat::before { content: ""; position: absolute; left: 15px; top: 12px; bottom: 12px;
                   width: 2px; background: var(--garis-kendali); }
.riwayat li { position: relative; padding-bottom: var(--r6); }
.riwayat li:last-child { padding-bottom: 0; }
.riwayat-tanda {
  position: absolute; left: -44px; top: 0; width: 32px; height: 32px;
  display: grid; place-items: center; border-radius: 50%;
  background: var(--kertas); border: 2px solid var(--tinta); color: var(--tinta);
}
.riwayat-tanda[data-keadaan="kini"] { background: var(--aksen); border-color: var(--tinta); }
.riwayat-tanda[data-keadaan="nanti"] { border-color: var(--redup); color: var(--redup); }
.riwayat-waktu { display: block; font-size: var(--t-kecil); color: var(--redup);
                 font-variant-numeric: tabular-nums; }
.riwayat h3 { font-size: 1.0625rem; margin-top: var(--r1); }
.riwayat p { color: var(--redup); font-size: var(--t-kecil); margin-top: var(--r1); }
.riwayat li[data-keadaan="nanti"] h3 { color: var(--redup); }

/* -----------------------------------------------------------------------------
   37. UNGGAH BERKAS, dihidupkan kembali untuk formulir minta tarif.
   Bordernya --garis-kendali (5,78:1), bukan --garis: ia area yang bisa diklik.
   -------------------------------------------------------------------------- */
.unggah {
  display: grid; place-items: center; gap: var(--r2); text-align: center;
  padding: var(--r6) var(--r4); border: 2px dashed var(--garis-kendali);
  border-radius: var(--radius); background: var(--kertas); cursor: pointer;
  font-size: var(--t-kecil); color: var(--redup);
}
.unggah:hover { background: var(--sentuh); }

/* -----------------------------------------------------------------------------
   38. PENANDA PETA BERNOMOR, isian aksen dengan angka BERTINTA di atasnya
   -------------------------------------------------------------------------- */
.pin { display: inline-grid; place-items: center; width: 28px; height: 28px; flex: none;
       border-radius: 50%; background: var(--aksen); color: var(--tinta);   /* 4,68:1 */
       font-family: var(--f-judul); font-weight: 700; font-size: var(--t-kecil); }

/* -----------------------------------------------------------------------------
   39. BARIS RINCIAN BIAYA, label kiri, angka kanan tabular
   -------------------------------------------------------------------------- */
.rincian { display: grid; gap: var(--r3); }
.rincian > div { display: flex; gap: var(--r3); align-items: baseline; font-size: var(--t-kecil); }
.rincian dt, .rincian .rincian-label { flex: 1; min-width: 0; }
.rincian dd, .rincian .rincian-nilai { margin: 0; font-variant-numeric: tabular-nums;
                                       font-weight: 600; white-space: nowrap; }
.rincian-total { border-top: 2px solid var(--tinta); padding-top: var(--r3); font-size: var(--t-isi) !important; }
.rincian-total .rincian-nilai { font-size: 1.25rem; font-family: var(--f-judul); }

/* =============================================================================
   40. KOMPONEN KHAS PAKET 08, properti
   Semua warna di bawah memakai token yang rasionya sudah tertulis di bagian 1.
   Tidak ada satu pun tempat baru yang memakai aksen sebagai teks atau garis.
   ========================================================================== */

/* 40a. KARTU UNIT, foto, cip status di atas foto, harga terbesar, angsuran kedua.
   Hierarki ini didiktekan brief dan ia adalah JTBD halaman ini: harga tidak boleh
   kalah besar dari nama tipe, dan angsuran tidak boleh hilang dari kartu. */
.kartu-unit { display: flex; flex-direction: column; padding: 0; overflow: hidden;
              /* WAJIB relative: cip status di dalamnya berposisi absolut, dan
                 tanpa leluhur berposisi ia mengambil blok penampung dari <body>
                 lalu LOLOS dari pemangkasan overflow di sini. */
              position: relative; }
.kartu-unit > img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.unit-foto { position: relative; }
.unit-cip { position: absolute; left: var(--r3); top: var(--r3); }
.unit-isi { padding: var(--r4); display: flex; flex-direction: column; gap: var(--r2);
            flex: 1; min-width: 0; }
.unit-klaster { font-size: var(--t-kecil); color: var(--redup); }
.unit-isi h3 { margin: 0; font-size: 1.25rem; }
.unit-spek { display: flex; flex-wrap: wrap; gap: var(--r2) var(--r3);
             font-size: var(--t-kecil); color: var(--redup); }
.unit-spek span { display: inline-flex; align-items: center; gap: var(--r1); min-width: 0; }
.unit-harga { font-size: clamp(1.5rem, 2.6vw, 1.875rem); line-height: 1.15;
              margin-top: var(--r2); }
.unit-label-cicilan { font-size: var(--t-kecil); color: var(--redup); }
.unit-cicilan { font-size: 1.25rem; line-height: 1.2; }
.unit-asumsi { font-size: var(--t-label); color: var(--redup); }
.unit-serah { font-size: var(--t-kecil); font-weight: 600; }
.kartu-unit .tombol { margin-top: auto; }

/* 40b. CIP KETERSEDIAAN, ikon + kata + warna, tidak pernah warna saja.
   Keempatnya bergaris TINTA, jadi tepinya terbaca di atas foto apa pun. */
.cip-status {
  display: inline-flex; align-items: center; gap: var(--r1);
  font-size: var(--t-kecil); font-weight: 600; padding: var(--r1) var(--r3);
  border-radius: 999px; border: 1px solid var(--tinta); color: var(--tinta);
  background: var(--kertas);
}
.cip-status .ikon { width: 16px; height: 16px; }
.cip-status[data-status="siap"]    { background: var(--sukses-alas); }   /* tinta 13,01:1 */
.cip-status[data-status="indent"]  { background: var(--aksen-alas); }    /* tinta 11,87:1 */
.cip-status[data-status="sisa"]    { background: var(--peringatan-alas); } /* tinta 12,86:1 */
.cip-status[data-status="terjual"] { background: var(--nonaktif); }      /* tinta 11,55:1 */

/* 40c. PANEL HASIL SIMULASI, kepala beraksen, teks tinta 16px bobot 600. */
.panel-hasil { border: 1px solid var(--garis); border-radius: var(--radius);
               background: var(--kertas); overflow: hidden; position: relative; }
.panel-hasil-kepala {
  background: var(--aksen); color: var(--tinta);        /* 4,68:1 */
  font-family: var(--f-judul); font-weight: 700;
  font-size: var(--t-isi); padding: var(--r3) var(--r4);
}
.panel-hasil-isi { padding: var(--r4); }
.hasil-baris { display: flex; gap: var(--r3); align-items: baseline;
               padding-block: var(--r3); border-bottom: 1px solid var(--garis); }
.hasil-baris:last-of-type { border-bottom: 0; }
.hasil-baris dt, .hasil-label { flex: 1; min-width: 0; font-size: var(--t-kecil);
                                color: var(--redup); }
.hasil-baris dd, .hasil-nilai { margin: 0; text-align: right; font-weight: 600;
                                overflow-wrap: anywhere; }
/* Baris jawaban: inilah angka yang dicari pengunjung, jadi ia yang paling besar. */
.hasil-utama { background: var(--aksen-alas); border-radius: var(--radius);
               padding: var(--r4); margin-block: var(--r3); border-bottom: 0; }
.hasil-utama .hasil-label { color: var(--tinta); font-weight: 600; font-size: var(--t-isi); }
.hasil-utama .hasil-nilai { font-family: var(--f-judul); font-weight: 700;
                            font-size: clamp(1.375rem, 3vw, 1.75rem); line-height: 1.15; }
@media (max-width: 560px) { .hasil-utama { display: block; text-align: left; }
                            .hasil-utama .hasil-nilai { text-align: left; margin-top: var(--r2); } }

/* 40d. PENGGESER UANG MUKA, bordernya tinta, bukan aksen. */
.geser { width: 100%; height: 44px; accent-color: var(--tinta); }
.geser-nilai { font-weight: 600; font-variant-numeric: tabular-nums; }

/* 40e. TAB DENAH, garis bawah aktif TINTA 3px. Aksen dilarang di sini, dan
   brief menyebutnya persis: 2,99:1 meleset dari lantai 3:1 untuk penanda. */
.tab-daftar { display: flex; flex-wrap: wrap; gap: var(--r4);
              border-bottom: 1px solid var(--garis); margin-bottom: var(--r5); }
.tab-daftar button {
  min-height: 48px; padding: var(--r2) var(--r1); border: 0; background: none;
  cursor: pointer; font-family: var(--f-isi); font-size: var(--t-isi);
  color: var(--redup); border-bottom: 3px solid transparent; margin-bottom: -1px;
}
.tab-daftar button[aria-selected="true"] { color: var(--tinta); font-weight: 700;
                                           border-bottom-color: var(--tinta); }
.tab-daftar button:hover { color: var(--tinta); }

/* 40f. BATANG PROGRES PEMBANGUNAN, isian aksen, persen ditulis sebagai TEKS di
   sebelahnya, karena batang sendirian tidak membawa makna. */
.progres-alur { height: 12px; background: var(--nonaktif); border-radius: 999px;
                border: 1px solid var(--garis-kendali); overflow: hidden;
                position: relative; flex: 1; min-width: 0; }
.progres-isi { display: block; height: 100%; background: var(--aksen); }
.progres-baris { display: flex; align-items: center; gap: var(--r3); }
.progres-persen { font-family: var(--f-judul); font-weight: 700; font-size: 1.25rem;
                  min-width: 3.5em; text-align: right; }

/* 40g. FOTO BERTANGGAL, tiap foto konstruksi membawa keterangan tanggal yang
   melekat di tepi bawahnya (DESIGN.md). Pita tanggal bertinta di atas kertas,
   bukan putih di atas foto, supaya kontrasnya tidak bergantung pada isi foto. */
.foto-tanggal { position: relative; border-radius: var(--radius);
                border: 1px solid var(--garis); overflow: hidden; }
.foto-tanggal img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }
.foto-tanggal figcaption {
  background: var(--kertas); color: var(--tinta); font-size: var(--t-kecil);
  font-weight: 600; padding: var(--r2) var(--r3); border-top: 1px solid var(--garis);
}

/* 40h. STRIP ENAM BULAN, bisa digulir mendatar di layar sempit, di dalam
   kotaknya sendiri; halamannya TIDAK ikut bergeser. */
.strip { display: grid; grid-auto-flow: column; grid-auto-columns: 45%;
         gap: var(--r3); overflow-x: auto; scroll-snap-type: x mandatory;
         padding-bottom: var(--r2); touch-action: pan-y; position: relative; }
.strip > * { scroll-snap-align: start; min-width: 0; }
@media (min-width: 700px)  { .strip { grid-auto-columns: 23%; } }
@media (min-width: 1000px) { .strip { grid-auto-flow: row; overflow: visible;
                                      scroll-snap-type: none;
                                      grid-template-columns: repeat(6, minmax(0,1fr)); } }
.strip figcaption { font-size: var(--t-label); padding: var(--r2); }

/* 40i. UBIN WORDMARK BANK, inisial bank sebagai HURUF DATAR di kotak beralas
   lembut. Bukan logo, dan sengaja bukan logo: tidak ada satu pun lambang bank
   sungguhan di halaman ini, dan nama banknya sendiri fiktif. */
.ubin-bank { display: inline-grid; place-items: center; width: 36px; height: 36px;
             flex: none; border-radius: 8px; background: var(--aksen-alas);
             color: var(--tinta);                          /* 11,87:1 */
             font-family: var(--f-judul); font-weight: 700; font-size: var(--t-kecil);
             letter-spacing: .02em; }
.sel-bank { display: flex; align-items: center; gap: var(--r3); }

/* 40j. KISI ENAM, fasilitas klaster. Turun bertahap, tidak pernah enam kolom
   sempit yang judulnya patah tiap kata. */
@media (min-width: 640px)  { .kisi-6 { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (min-width: 1000px) { .kisi-6 { grid-template-columns: repeat(3, minmax(0,1fr)); } }

/* 40k. DAFTAR UNDUHAN, empat berkas denah, tiap baris satu target sentuh penuh. */
.unduh-baris { display: grid; gap: var(--r3); margin-top: var(--r5); }
@media (min-width: 700px) { .unduh-baris { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (min-width: 1100px) { .unduh-baris { grid-template-columns: repeat(4, minmax(0,1fr)); } }

/* 40l. GAMBAR DENAH, latar putih, karena garis hitamnya digambar di atas putih. */
.gambar-denah { background: #fff; border: 1px solid var(--garis);
                border-radius: var(--radius); padding: var(--r3); }
.gambar-denah img { width: 100%; height: auto; display: block; }

/* 40m. KARTU ORANG, potret 1:1, atau inisial kalau memang tidak ada potretnya. */
.potret-inisial { aspect-ratio: 1 / 1; margin-bottom: var(--r3);
                  border-radius: var(--radius); border: 1px solid var(--garis); }
.orang-peran { font-size: var(--t-kecil); font-weight: 600; }
.orang-kredensial { font-size: var(--t-label); color: var(--redup); margin-top: var(--r2);
                    display: flex; gap: var(--r2); align-items: flex-start; }

/* 40n. Baris kepala bagian yang punya aksi di kanannya. */
.kepala-aksi { display: flex; flex-wrap: wrap; gap: var(--r4);
               align-items: end; justify-content: space-between; margin-bottom: var(--r5); }
.kepala-aksi .kepala-bagian { margin-bottom: 0; }

/* =============================================================================
   41. PENYESUAIAN YANG LAHIR DARI MARKUP HALAMAN INI
   ========================================================================== */

/* Blok penampung untuk keturunan berposisi absolut. Tanpa ini, .hanya-layar-baca
   dan cip status yang berada di dalam kotak berpangkas mengambil blok penampung
   dari <body>, LOLOS dari pemangkasan, lalu menarik lebar dokumen melewati layar.
   Gejalanya cuma terlihat sesudah dirender, dan yang dilaporkan meluber justru
   elemen lain. */
.bagian, .pita-statistik, .bungkus, .kartu, .segmen { position: relative; }

.unit-foto img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }
.hero-statistik div { display: flex; align-items: center; gap: var(--r2); }

/* Kendali tersegmen berbasis RADIO SUNGGUHAN, bukan <button> yang mati tanpa
   JavaScript (jebakan 7 di resep: kendali yang hanya hidup di JS ditukar MASUK
   oleh JS, bukan ditulis duluan di HTML). Radionya disembunyikan secara visual,
   labelnya yang digambar. */
.segmen label { flex: 1; min-width: 0; display: grid; place-items: center;
                min-height: 48px; padding-inline: var(--r2); text-align: center;
                overflow-wrap: anywhere; cursor: pointer;
                font-size: var(--t-kecil); font-weight: 600;
                color: var(--tinta); background: var(--kertas); }
.segmen label + label { border-left: 1px solid var(--garis-kendali); }
.segmen input { position: absolute; opacity: 0; width: 1px; height: 1px; }
/* Terpilih = isian aksen + garis dalam TINTA. Dua penanda, bukan warna saja. */
.segmen label:has(input:checked) { background: var(--aksen);
                                   box-shadow: inset 0 0 0 2px var(--tinta); }
.segmen label:focus-within { outline: 2px solid var(--tinta); outline-offset: -3px; }

/* Cip pintas adalah TOMBOL, jadi ia perlu mewarisi huruf halaman. Keadaan
   tertekan diberi isian aksen, label 14px bobot 600 di atasnya 4,68:1. */
button.cip-garis { font-family: var(--f-isi); cursor: pointer; }
button.cip-garis[aria-pressed="true"] { background: var(--aksen); border-width: 2px; }

/* Kartu yang sebenarnya tombol (baris unduhan denah). */
button.kartu { width: 100%; }

/* .rincian dipakai sebagai <ul>, bukan <div>/<dl> saja. */
.rincian > li { display: flex; gap: var(--r3); align-items: baseline; font-size: var(--t-kecil); }

.tab-daftar button { min-width: 0; }
