/* v4 — palet Tribrata (hitam & emas). Tidak ada rujukan warna klub mana pun.
   Merah dipakai murni untuk makna darurat, oranye murni untuk makna hazard.
   Emas hanya untuk aksen identitas (garis, label, kop) — tidak pernah jadi blok isian,
   supaya tidak tertukar dengan oranye hazard. Tanpa font dari server luar. */
:root{
 --brand:#14171C; --brand-2:#262B33; --brand-3:#3A414C;
 --gold:#C9982A; --gold-dk:#7A5B10; --gold-sf:#F3E9CE;
 --paper:#F7F6F2; --ink:#16181C; --slate:#4F5764; --line:#DCD8CF;
 --red:#8B1A1A; --orange:#DD6B20; --green:#1B7A43;
 --disp:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
 --body:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
 --radius:14px;
 /* Pembatas lebar konten tunggal. Situs ini sengaja tetap tampil sebagai
    kolom sempit (seperti ponsel) walau dibuka di desktop — bukan melebar
    jadi grid 3-4 kolom. Semua tempat yang dulu memakai angka 1020 piksel
    (mentah, ditulis berulang di enam tempat) sekarang merujuk variabel
    ini supaya nilainya hanya perlu diubah sekali. */
 --lebar-konten:430px;
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{background:#0B0D11;font-family:var(--body);color:var(--ink);font-size:16px;-webkit-font-smoothing:antialiased}
button,input{font:inherit;color:inherit}
svg{display:block}
.stage{min-height:100vh;display:flex;flex-direction:column;align-items:center;padding:0;gap:0;
 background:var(--paper)}
.phone{width:100%;background:var(--paper);display:flex;flex-direction:column;position:relative}

/* .topbar membungkus .hdr dan .sos sebagai satu unit lengket. Karena keduanya
   ikut menempel bersama induknya, tidak perlu lagi menghitung top:128px
   secara manual untuk .sos berdasarkan tinggi .hdr — tinggi .hdr boleh
   berubah bebas (judul satu/dua baris) tanpa merusak posisi baris darurat. */
.topbar{position:sticky;top:0;z-index:20}

/* kop dan baris darurat dibungkus .topbar agar lengket sebagai satu unit —
   lihat aturan .topbar di atas. Sifat sticky, top, dan z-index tidak lagi
   ditaruh di sini supaya tinggi .hdr yang berubah-ubah antar halaman
   (judul satu/dua baris) tidak butuh angka top yang dihitung manual. */
/* position:relative di sini agar .hdrbtns (position:absolute) diposisikan terhadap .hdr, bukan leluhur sticky. */
.hdr{position:relative;background:var(--brand);color:#fff;padding:12px 12px 12px 16px;display:flex;align-items:flex-start;
 justify-content:space-between;gap:8px;flex-shrink:0;border-bottom:3px solid var(--gold);
 /* Bayangan murni dekoratif -- tidak menambah tinggi/ruang -- untuk memberi kop
    kesan "mengambang" tipis di atas isi, tanpa mengubah ukuran apa pun. */
 box-shadow:0 6px 14px -8px rgba(0,0,0,.45)}
.hdr .lockup{display:flex;align-items:center;gap:8px;font-size:12px;letter-spacing:.13em;text-transform:uppercase;
 color:var(--gold);font-weight:500}
/* Lambang resmi di kop. Tinggi 44px dipilih supaya MUAT di dalam tinggi kop
   yang sudah ada (lockup 12px + h1 18px/1.2 + sub) -- kop tidak bertambah
   tinggi sama sekali, jadi tata letak di bawahnya tidak bergeser.

   Latar TRANSPARAN atas permintaan pemilik repo. Catatan terukur: 31,3% piksel
   opak lambang nyaris sewarna dengan latar kop (var(--brand) #14171C), yaitu
   panel hitam di balik tulisan "POLRESTA MALANG KOTA" dan bagian hitam
   perisai. Bagian itu lebur ke latar; garis merah dan tulisan kuningnya tetap
   terbaca, jadi lambang tampak berongga alih-alih hilang. Bila kelak ingin
   solid kembali, kembalikan background:#fff + padding di sini (tidak ada yang
   lain yang perlu diubah).

   align-self:center menyejajarkan lambang terhadap SELURUH blok teks
   (lockup + judul + sub), bukan menempel ke tepi atasnya. Tanpa ini lambang
   duduk di atas sementara teks memanjang ke bawah, sehingga terlihat tidak
   sejajar dengan judul. */
.hdr .lambang{height:44px;width:auto;flex-shrink:0;align-self:center}
/* Di layar sempit lambang DIKECILKAN, bukan sekadar ikut mengecil sendiri.
   Alasannya terukur: pada viewport 375px, lambang setinggi 32px ke atas
   menyisakan ruang terlalu sempit untuk #ttl sehingga judul pecah dari 2 baris
   menjadi 3, dan kop yang STICKY tumbuh 89px -> 111px -- 22px ruang konten
   hilang di tiap layar, pada situs yang praktis seluruh pengunjungnya memakai
   ponsel. Pada 30px judul kembali 2 baris; 28px dipakai agar ada margin aman
   terhadap perbedaan perenderan font antar-peramban. */
@media (max-width:430px){
 .hdr .lambang{height:28px}
}
.hdr h1{font-family:var(--disp);font-size:18px;font-weight:700;letter-spacing:.01em;line-height:1.2;margin-top:0;display:flex;align-items:center;gap:8px}
.hdr .sub{font-size:12.5px;color:#B7BDC7;margin-top:3px;line-height:1.4}
.backrow{display:flex;align-items:flex-start;gap:8px;min-width:0}
.iconbtn{background:rgba(255,255,255,.18);border:0;color:#fff;width:46px;height:46px;border-radius:12px;
 cursor:pointer;flex-shrink:0;display:flex;align-items:center;justify-content:center}
.iconbtn svg{width:21px;height:21px}
.iconbtn:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
/* margin-left:8px MENAMBAH jarak tombol back dari tepi layar (16px padding
   .hdr + 8px ini = 24px total) -- bukan sekadar kosmetik. Di ponsel, gestur
   usap-balik bawaan peramban (edge-swipe-back Safari/Chrome) biasanya
   menangkap sentuhan yang MULAI dalam ~20px dari tepi layar, sebelum event
   sentuh sempat sampai ke JS halaman. Tombol back yang dulu menempel di
   16px murni tumpang tindih dengan zona itu -- usaha menekan tombol bisa
   salah terbaca sebagai gestur "kembali" peramban (keluar dari alur SPA)
   alih-alih tap ke tombol. 24px tidak menghilangkan tabrakan itu sepenuhnya
   (peramban bisa menahan sentuhan sebelum JS melihatnya sama sekali), tapi
   mengurangi frekuensinya nyata. Nilai ini HANYA berlaku saat tombol
   tampil (display:none tidak memakan ruang saat beranda). */
/* box-shadow inset (bukan border) supaya cincin emas tidak menambah ukuran
   kotak tombol -- tetap 46px persis sama dengan .iconbtn lain, hanya
   tampilannya yang menonjol. Ini GARIS aksen identitas (cincin tipis),
   bukan blok isian emas -- sejalan dengan aturan palet di atas berkas ini.
   Tujuannya: back adalah SATU-SATUNYA aksi navigasi yang mengganti tampilan
   (menu cuma membuka lembar di atas tampilan yang sama), jadi diberi
   penanda visual sendiri supaya lebih gampang dikenali sekilas -- bukan
   sekadar ikon serupa dengan tombol menu di sebelahnya. */
.iconbtn.back{display:none;margin-top:2px;margin-left:8px;
 background:rgba(255,255,255,.18);box-shadow:inset 0 0 0 1.5px rgba(201,152,42,.6)}
.hdrbtns{display:flex;gap:8px;flex-shrink:0;padding-top:2px}

/* darurat — 112 utama, 110 pendamping.
   Dulu top:128px dihitung manual dari skenario kop tertinggi (judul dua baris
   + subjudul dua baris) — rapuh karena tinggi .hdr berubah per halaman.
   Sekarang .sos tidak lagi sticky sendiri; ia lengket bersama .hdr lewat
   pembungkus .topbar (position:sticky;top:0), jadi tidak ada angka piksel
   yang perlu ditebak atau disetel ulang. */
.sos{background:var(--brand-2);padding:6px 10px;display:flex;gap:6px;flex-shrink:0;align-items:stretch}
.sos a{background:linear-gradient(180deg,#9c2424,var(--red));color:#fff;text-decoration:none;border-radius:11px;padding:8px 10px;
 display:flex;align-items:center;gap:8px;box-shadow:inset 0 -2px 0 rgba(0,0,0,.28);min-height:44px;flex:1}
.sos a.utama{flex:1}
.sos a.dua{flex:1}
.sos .si{flex-shrink:0;opacity:.95;display:flex;align-items:center;gap:4px}
.sos .si svg{width:16px;height:16px}
.sos .si span{width:18px;height:18px;border:1.5px solid rgba(255,255,255,.7);border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;flex-shrink:0}
.sos .txt{min-width:0;display:flex;flex-direction:column;gap:2px;align-items:flex-start}
.sos .n{font-family:var(--disp);font-size:12px;font-weight:500;line-height:1.2;letter-spacing:.08em;text-transform:uppercase;opacity:.85}
.sos .t{font-family:var(--disp);font-size:20px;font-weight:700;line-height:1.2;font-variant-numeric:tabular-nums;letter-spacing:.01em}

.fresh{flex-shrink:0;display:flex;align-items:center;gap:7px;padding:7px 15px;background:#EFEBE1;color:#5C564B;
 font-size:12.5px;line-height:1.4;border-bottom:1px solid var(--line)}
.fresh.hide{display:none}
.fresh svg{width:14px;height:14px;flex-shrink:0}
.body{padding:10px 12px 14px;width:100%;max-width:var(--lebar-konten);margin:0 auto}

/* WCAG 2.2 AA — teks khusus pembaca layar: terbaca oleh screen reader,
   tidak menempati ruang visual sedikit pun. Dipakai untuk judul tingkat 2
   tiap tampilan (#view) supaya hirarki heading tidak melompat h1 -> h3. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
 clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
/* WCAG 2.4.1 Bypass Blocks — tautan lewati navigasi, tampak hanya saat difokus. */
.lewati{position:absolute;left:-9999px;top:0;z-index:60;background:var(--gold);color:var(--brand);
 padding:10px 14px;border-radius:0 0 8px 0;font-size:13px;font-weight:700;text-decoration:none}
.lewati:focus{left:0}

.eyebrow-d{font-size:11px;letter-spacing:.13em;text-transform:uppercase;color:var(--slate);
 font-weight:600;margin-bottom:6px;display:flex;align-items:center;gap:8px}
.eyebrow-d::after{content:"";flex:1;height:1px;background:var(--gold);opacity:.5}
.eyebrow-d.rapat{margin-top:6px}

.grid{display:grid;grid-template-columns:1fr 1fr;gap:6px}
/* Aksen kategori dulu berupa border-left 4px tebal (hitam/oranye) -- diganti
   bayangan lembut + badge ikon berwarna, supaya kartu terasa lebih modern
   tanpa menambah padding atau memperlebar tile (tetap padat/compact). Warna
   kategori (hitam vs oranye kegiatan) sekarang MURNI dibawa oleh .icb, bukan
   lagi oleh tepi kartu.
   Ubin dipadatkan lagi (padding 12px->10px, ikon 40px->34px, deskripsi
   12px->10.5px) supaya ketujuh menu beranda muat terlihat tanpa perlu
   gulir dulu di layar ponsel biasa -- permintaan eksplisit: "padat, tidak
   menyisakan banyak ruang kosong" dan caption/keterangan berukuran kecil. */
.tile{background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:10px;text-align:left;
 cursor:pointer;font-family:var(--body);display:grid;grid-template-columns:34px 1fr;gap:10px;row-gap:2px;width:100%;text-decoration:none;color:inherit;align-items:flex-start;
 box-shadow:0 1px 2px rgba(20,23,28,.05),0 8px 16px -14px rgba(20,23,28,.35)}
.tile:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
/* .icb DIPISAH dari .tile: sebelumnya "background:radial-gradient(...)" cuma
   berlaku sebagai ".tile .icb" (turunan), jadi badge ikon di luar ubin --
   header LAYANAN UNGGULAN, tautan CCTV -- tidak pernah ikut mendapat gaya
   makeover ini, malah dulu ditimpa inline style ad-hoc masing-masing
   halaman (lihat app.js). Aturan dasar sekarang berlaku ke MANA SAJA
   class="icb" dipakai; posisi grid (grid-row/grid-column) tetap
   dikhususkan lewat ".tile .icb" karena hanya relevan di dalam grid ubin. */
.icb{width:34px;height:34px;border-radius:9px;background:radial-gradient(120% 120% at 30% 22%,var(--brand-2),var(--brand));color:var(--gold);display:flex;
 align-items:center;justify-content:center;flex-shrink:0}
.icb svg{width:17px;height:17px}
.tile .icb{grid-row:1;grid-column:1;align-self:center}
.tile.acc .icb{background:radial-gradient(120% 120% at 30% 22%,#f0894a,var(--orange));color:#171717}
/* Dipakai kartu() untuk kategori "darurat" -- merah yang sama dengan .sos a
   dan .kgnow-badge, supaya "darurat = merah" konsisten di luar kop juga. */
.icb.darurat{background:radial-gradient(120% 120% at 30% 22%,#9c2424,var(--red));color:#fff}
.tile.wide{grid-column:1 / -1}
.tile .nm{font-family:var(--disp);font-size:14px;font-weight:700;margin-top:0;letter-spacing:.01em;grid-column:2;grid-row:1;align-self:center}
.tile .ds{font-size:10px;color:var(--slate);margin-top:0;line-height:1.28;grid-column:1 / -1;grid-row:2;margin-left:-10px;margin-right:-10px;padding-left:10px;padding-right:10px;text-align:justify;text-align-last:center}

.card{background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:12px;margin-bottom:8px;
 box-shadow:0 1px 2px rgba(20,23,28,.05),0 8px 16px -14px rgba(20,23,28,.35)}
.card h3{font-family:var(--disp);font-size:16px;font-weight:700;letter-spacing:.01em;line-height:1.2;margin-bottom:2px}
.card .addr{display:flex;align-items:flex-start;gap:6px;font-size:13px;font-weight:600;color:var(--brand);margin-top:4px;line-height:1.4}
.card .addr svg{width:14px;height:14px;flex-shrink:0;margin-top:1px}
.meta{font-size:14px;color:var(--slate);margin-top:2px;line-height:1.4}
.card p{font-size:14px;line-height:1.5;margin-top:6px}

.tel{display:flex;align-items:center;gap:8px;margin-top:8px;background:linear-gradient(180deg,#1f8a51,var(--green));color:#fff;text-decoration:none;
 border-radius:var(--radius);padding:8px 12px;box-shadow:inset 0 -2px 0 rgba(0,0,0,.22);min-height:44px;
 border:0;width:100%;cursor:pointer;font:inherit;text-align:left}
.tel .ti{flex-shrink:0;display:flex;opacity:.95}
.tel .ti svg{width:19px;height:19px}
.tel .num{font-family:var(--disp);font-size:19px;font-weight:700;letter-spacing:.03em;font-variant-numeric:tabular-nums;flex:1}
.tel .cta{font-size:12px;letter-spacing:.03em;opacity:.95;text-align:right;line-height:1.3}
.tel.ph{background:#7C818A;box-shadow:none;border:2px dashed rgba(255,255,255,.45);cursor:not-allowed}

.chips{display:flex;flex-wrap:wrap;align-items:flex-start;gap:4px;margin-top:8px;max-width:118px;word-break:break-word;
 max-height:44px;overflow:hidden}
.chips.bordered{border-left:1px solid var(--line);padding-left:8px}
/* WCAG 1.4.3 (kontras minimum) — warna semula #7A7468 + opacity:.7 hanya
   memberi rasio efektif 2,33:1 di atas #E9E4DA, jauh di bawah ambang 4,5:1
   untuk teks 10px. Warna digelapkan ke #5A5449 dan opacity dilepas supaya
   rasio nyata menjadi 5,92:1; kesan "label redup" tetap terjaga lewat warna
   abu hangat, bukan lewat transparansi. */
.chip{font-size:10px;letter-spacing:0;font-weight:500;padding:2px 6px;border-radius:4px;background:#E9E4DA;color:#5A5449}
.chip.scope{background:var(--brand);color:var(--gold)}
.chip.ver{background:#DBEEE1;color:#155E32}

.accordion-item{border:1px solid var(--line);border-radius:var(--radius);margin-bottom:8px;overflow:hidden;
 box-shadow:0 1px 2px rgba(20,23,28,.05),0 8px 16px -14px rgba(20,23,28,.35)}
.accordion-btn{width:100%;background:#fff;border:0;padding:12px;text-align:left;cursor:pointer;font-family:var(--body);font-size:14px;font-weight:600;color:inherit;display:flex;justify-content:space-between;align-items:center;gap:8px;transition:background .15s}
.accordion-btn:hover{background:rgba(201,152,42,.15)}
.accordion-btn:focus-visible{outline:2px solid var(--brand);outline-offset:-2px}
.accordion-chev{flex-shrink:0;display:flex;color:var(--slate);transition:transform .2s}
.accordion-chev svg{width:16px;height:16px}
.accordion-item.open .accordion-chev{transform:rotate(180deg)}
.accordion-content{display:none;padding:12px;background:rgba(212,190,132,.15);color:#3d3d3d;font-size:14px;line-height:1.5}
.accordion-item.open .accordion-content{display:block}

.samsat-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:8px}
@media (max-width:600px){.samsat-grid{grid-template-columns:1fr}}
.samsat-card{border:1px solid var(--line);border-radius:var(--radius);padding:12px;background:#fff;display:flex;flex-direction:column;
 box-shadow:0 1px 2px rgba(20,23,28,.05),0 8px 16px -14px rgba(20,23,28,.35)}
.samsat-card h3{font-family:var(--disp);font-size:14px;font-weight:700;margin:0 0 8px 0;color:var(--brand)}
.samsat-card .addr{display:flex;align-items:flex-start;gap:6px;font-size:12px;color:var(--slate);margin-bottom:8px;line-height:1.4}
.samsat-card .addr svg{width:14px;height:14px;flex-shrink:0;margin-top:1px}
.samsat-card .jam{font-size:13px;line-height:1.6;margin-bottom:10px}
.samsat-maps-btn{display:flex;align-items:center;justify-content:center;gap:6px;width:100%;margin-top:auto;padding:0 10px;
 min-height:44px;background:var(--gold-sf);color:var(--gold-dk);border:1px solid #E0CE9C;border-radius:8px;
 font-size:12.5px;font-weight:600;text-decoration:none;transition:background .15s;
 box-shadow:0 1px 2px rgba(122,91,16,.08),0 6px 12px -10px rgba(122,91,16,.4)}
.samsat-maps-btn svg{width:15px;height:15px;flex-shrink:0}
.samsat-maps-btn:hover{background:#EADFB8}
.samsat-maps-btn:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.samsat-maps-btn:active{background:#E0CE9C}
.chip.old{background:#FBE7BC;color:#6E4605}
.chip.kosong{background:#F7DEDC;color:#8E1F18}
.chip.alt{background:var(--brand-2);color:#fff;border:0;cursor:pointer;font:inherit;font-variant-numeric:tabular-nums;
 min-height:44px;padding:0 10px;display:flex;align-items:center;gap:5px;font-size:11px;width:100%;margin-top:3px;text-align:center;justify-content:center;
 box-shadow:0 1px 2px rgba(20,23,28,.15)}

.searchwrap{position:relative;margin-bottom:12px}
.searchwrap svg{position:absolute;left:12px;top:50%;transform:translateY(-50%);width:17px;height:17px;color:var(--slate)}
/* box-shadow inset (bukan luar) -- input dibuat terlihat SEDIKIT MASUK ke
   dalam permukaan, bukan terangkat seperti kartu/tombol. Bahasa visual
   yang berbeda sengaja: kartu & tombol = bisa ditekan (terangkat), input
   = tempat mengetik (sedikit cekung), supaya keduanya tidak tertukar. */
.searchwrap input{width:100%;border:1px solid var(--line);background:#fff;border-radius:11px;padding:12px 12px 12px 38px;
 font-size:16px;min-height:46px;box-shadow:inset 0 1px 3px rgba(20,23,28,.06)}
.searchwrap input:focus-visible{outline:2px solid var(--brand);outline-offset:1px}

.kecacc{padding:0;overflow:hidden}
.kechead{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;text-align:left;
 background:none;border:0;cursor:pointer;padding:12px;min-height:48px}
.kechead .chev{color:var(--slate);flex-shrink:0;transition:transform .15s ease}
.kechead .chev svg{width:18px;height:18px}
.kechead .chev.open{transform:rotate(180deg)}
.kecbody{padding:0 12px 12px}
.kecbody[hidden]{display:none}
.matchrow{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;text-align:left;
 background:#fff;border:1px solid var(--line);border-radius:11px;padding:12px;margin-bottom:8px;cursor:pointer;min-height:48px;
 box-shadow:0 1px 2px rgba(20,23,28,.05),0 8px 16px -14px rgba(20,23,28,.35)}
.matchrow b{font-family:var(--disp);font-size:15px;font-weight:700}
.matchrow .kecname{font-size:12px;color:var(--slate);flex-shrink:0}
/* Bayangan SENGAJA lebih tipis di sini (tanpa lapisan kedua yang menyebar)
   -- .kelbtn dan .filter button tampil berjejer BANYAK dalam satu baris
   (baris kelurahan yang di-wrap, deretan filter kecamatan); bayangan
   sekuat .card/.tile pada belasan tombol kecil sekaligus akan terlihat
   ramai/berdesir, bukan rapi. Satu lapis tipis cukup untuk konsisten
   dengan bahasa "terangkat sedikit" tanpa menambah keributan visual. */
.kelbtn{border:1px solid var(--line);cursor:pointer;font-family:var(--body);font-size:14px;font-weight:500;
 padding:8px 12px;border-radius:8px;background:#fff;color:#3A352E;min-height:44px;margin:0 8px 8px 0;
 box-shadow:0 1px 2px rgba(20,23,28,.04)}
.kelbtn.has{background:var(--brand);color:#fff;border-color:var(--brand);box-shadow:0 1px 2px rgba(20,23,28,.15)}

.filter{display:flex;gap:8px;overflow-x:auto;padding-bottom:8px;margin-bottom:12px}
.filter button{flex-shrink:0;font-size:13.5px;font-weight:600;letter-spacing:.02em;
 border:1px solid var(--line);background:#fff;border-radius:99px;padding:8px 16px;cursor:pointer;color:var(--slate);min-height:44px;
 box-shadow:0 1px 2px rgba(20,23,28,.04)}
.filter button[aria-pressed="true"]{background:linear-gradient(180deg,var(--brand-2),var(--brand));border-color:var(--brand);color:#fff;
 box-shadow:0 1px 2px rgba(20,23,28,.2)}

.kg{position:relative;overflow:hidden;padding-top:16px}
.kg::before{content:"";position:absolute;top:0;left:0;right:0;height:6px;
 background:repeating-linear-gradient(45deg,var(--orange) 0 9px,#1a1a1a 9px 18px)}
/* Gradasi F0894A->DD6B20 -- SAMA PERSIS dengan .tile.acc .icb -- dipilih,
   bukan oranye rata, supaya label waktu ("Besok"/"Lusa"/dst) terasa lebih
   hidup. Kedua ujung gradasi sudah diverifikasi kontras >=4.5:1 terhadap
   teks gelap #171717 (ujung terang ~7,15:1, ujung dasar ~5,44:1) -- jangan
   digelapkan lebih jauh dari var(--orange) tanpa menghitung ulang kontras,
   teks gelap di atasnya bisa jatuh di bawah ambang AA. */
.when{display:inline-block;font-family:var(--disp);font-size:13px;font-weight:700;letter-spacing:.06em;
 text-transform:uppercase;background:linear-gradient(135deg,#F0894A,var(--orange));color:#171717;padding:3px 10px;border-radius:6px;margin-bottom:8px;
 box-shadow:0 2px 6px -2px rgba(221,107,32,.5)}
.when.now{background:var(--red);color:#fff;box-shadow:none}
.impact{font-size:13.5px;line-height:1.6;margin-top:8px;padding-left:12px;border-left:3px solid var(--orange);color:#33353A}

/* Kartu "Kegiatan Hari Ini" di beranda (lihat vHome() di app.js). Hanya
   dirender saat ADA kegiatan yang sedang berjalan hari ini -- kalau tidak,
   elemen ini tidak dicetak sama sekali, jadi beranda tidak menyisakan
   ruang kosong untuk keadaan "tidak ada apa-apa". Memakai garis lorengan
   hitam-oranye yang sama dengan .kg supaya bahasa visual "kegiatan" tetap
   satu, hanya versi ringkas untuk beranda -- detail lengkap & kegiatan
   lain (H-3 s/d H yang belum "hari ini") tetap di halaman Kegiatan
   Masyarakat lewat tombol ini. */
.kgnow{display:block;width:100%;text-align:left;font:inherit;color:inherit;cursor:pointer;
 position:relative;overflow:hidden;background:#fff;border:1px solid var(--line);border-radius:var(--radius);
 padding:8px 10px 8px 14px;margin-bottom:10px;
 box-shadow:0 1px 2px rgba(20,23,28,.05),0 8px 16px -14px rgba(20,23,28,.35)}
.kgnow::before{content:"";position:absolute;top:0;left:0;bottom:0;width:4px;
 background:repeating-linear-gradient(135deg,var(--orange) 0 6px,#1a1a1a 6px 12px)}
.kgnow:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
/* Merah = benar-benar hari ini (default). .upcoming = oranye -- kegiatan
   terdekat yang ditemukan baru besok/lusa/N hari lagi, BUKAN hari ini.
   Pasangan warna sama persis dengan .when/.when.now di halaman Kegiatan
   Masyarakat (merah=sekarang, oranye=akan datang), supaya bahasa warna
   "kapan" konsisten di seluruh situs -- bukan warna baru yang perlu
   dipelajari ulang pengunjung. */
.kgnow-badge{display:inline-flex;align-items:center;gap:5px;font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
 background:var(--red);color:#fff;padding:2px 8px;border-radius:5px;margin-bottom:5px}
.kgnow-badge.upcoming{background:linear-gradient(135deg,#F0894A,var(--orange));color:#171717}
/* Titik "siaran langsung" -- HANYA ditambahkan lewat JS pada badge "Hari
   ini" (kgnowHtml() di app.js), tidak pernah pada .upcoming: kegiatan yang
   belum terjadi tidak boleh terkesan "sedang berlangsung sekarang". Cincin
   berdenyut di sekeliling titik statis meniru penanda LIVE yang umum
   dikenal, dimatikan otomatis untuk prefers-reduced-motion (titik tetap
   tampak, hanya animasinya yang dihentikan). */
.livedot{position:relative;width:6px;height:6px;border-radius:50%;background:#fff;flex-shrink:0}
@media (prefers-reduced-motion:no-preference){
 .livedot::before{content:"";position:absolute;inset:-3px;border-radius:50%;background:#fff;opacity:.7;
  animation:livepulse 1.6s ease-out infinite}
}
@keyframes livepulse{0%{transform:scale(1);opacity:.7}100%{transform:scale(2.6);opacity:0}}
.kgnow-nm{font-family:var(--disp);font-size:14.5px;font-weight:700;line-height:1.3;margin-bottom:2px}
.kgnow-meta{font-size:11.5px;color:var(--slate);line-height:1.4}
.kgnow-more{font-size:11.5px;font-weight:600;color:var(--gold-dk);margin-top:5px}
/* S10 — titik navigasi rotasi kartu "Info Kegiatan Terdekat". Kotak tombol
   24x24 (ambang WCAG 2.5.8 AA untuk ukuran target minimum) jauh lebih besar
   dari titik yang terlihat (7px) supaya area sentuh tetap nyaman tanpa
   membuat baris titik jadi besar secara visual -- pola sama seperti target
   sentuh diperbesar lewat padding pada tombol .tel/.chip di tempat lain. */
.kgnow-dots{display:flex;gap:2px;justify-content:center;margin-bottom:10px}
.kgnow-dot{width:24px;height:24px;padding:0;border:none;background:transparent;cursor:pointer;
 display:flex;align-items:center;justify-content:center;flex-shrink:0}
.kgnow-dot::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--slate)}
.kgnow-dot.on::before{background:var(--brand)}
.kgnow-dot:focus-visible{outline:2px solid var(--brand);outline-offset:1px}

/* isolation:isolate -- tanpa ini, z-index internal Leaflet (kontrol zoom
   sampai 1000, panel sampai 700) lolos ke konteks susun akar dan menang
   melawan z-index:20 milik .topbar sticky, sehingga peta menimpa header
   saat digulir. */
#map{height:200px;border-radius:var(--radius);border:1px solid var(--line);margin-bottom:12px;background:#E8E5DE;isolation:isolate}
.mapfail{display:none;padding:12px;font-size:12.5px;color:var(--slate);text-align:center;line-height:1.5}
.leaflet-control-zoom a{width:40px!important;height:40px!important;line-height:40px!important;font-size:19px!important}
.leaflet-popup-content{font-family:var(--body);font-size:13px;line-height:1.55}
/* Leaflet memberi .leaflet-div-icon kotak putih + border bawaan -- dilucuti
   di sini supaya bentuk pin SVG kustom (pinMarkerHtml() di app.js) tidak
   terbungkus kotak yang tidak diinginkan. */
.leaflet-div-icon.kg-pin{background:transparent;border:0}

/* Field layanan (Biaya/Persyaratan/Tempat/Jam/Durasi/Referensi) -- dulu
   berupa <dl> datar (semua label sama gaya, tak ada yang menonjol).
   Sekarang tiap field dapat badge ikon sendiri; Biaya (emas) dan
   Persyaratan (hijau) dapat warna berbeda supaya keduanya -- yang
   paling sering dicari warga -- langsung kelihatan tanpa perlu membaca
   label satu-satu. Tempat/Jam/Durasi/Referensi memakai badge netral
   (hitam+emas) yang sama dengan badge ikon di tempat lain situs --
   dibedakan lewat BENTUK ikon (pin/jam/jam-pasir/tautan), bukan warna,
   supaya tidak menambah warna baru di luar palet Tribrata. */
.layfield{display:flex;gap:10px;align-items:flex-start;margin-bottom:12px}
.layfield:last-child{margin-bottom:0}
.layfield .icb{width:30px;height:30px;border-radius:8px}
.layfield .icb svg{width:15px;height:15px}
.layfield-body{min-width:0;flex:1}
.layfield-label{font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--slate);font-weight:600;margin-bottom:2px}
.layfield-val{font-size:13.5px;line-height:1.5;color:var(--ink)}
.layfield-val.big{font-family:var(--disp);font-size:19px;font-weight:700;color:var(--brand)}
.layfield.biaya .icb{background:var(--gold-sf);color:var(--gold-dk)}
.layfield.syarat .icb{background:#DBEEE1;color:#155E32}
.layfield-syarat{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:5px}
.layfield-syarat li{display:flex;gap:6px;align-items:flex-start;font-size:13.5px;line-height:1.4}
.layfield-syarat li svg{width:14px;height:14px;flex-shrink:0;margin-top:2px;color:#1B7A43}
.layfield-link{color:var(--gold-dk);font-weight:600;text-decoration:none;border-bottom:2px solid var(--gold)}
.linkout{display:inline-flex;align-items:center;margin-top:12px;font-size:13px;font-weight:600;color:var(--gold-dk);text-decoration:none;
 border-bottom:2px solid var(--gold);min-height:44px;padding:0 0 2px}
.gmaps-link{display:inline-block;font-weight:600;color:var(--gold-dk);text-decoration:none;border-bottom:2px solid var(--gold)}
.empty{text-align:center;color:var(--slate);font-size:13px;padding:20px 12px;line-height:1.6}
.catatan{background:var(--gold-sf);border:1px solid #E4D5A8;border-radius:11px;padding:8px 13px;
 font-size:13px;line-height:1.5;color:#5A4409}
.foot{margin-top:8px;padding-top:0;font-size:12px;color:#7A7468;line-height:1.6}

.qsheet{position:absolute;inset:0;background:var(--paper);overflow-y:auto;padding:20px 16px 24px;display:none;z-index:4000;flex-direction:column;align-items:center}
.qsheet.on{display:flex}
/* Batasi lebar isi .qsheet pada max-width yang sama dengan .body dan .hdr>.backrow untuk konsistensi desktop. */
.qsheet > .qhd,
.qsheet > .home,
.qsheet > .grid{max-width:var(--lebar-konten);width:100%}
.qsheet .qhd{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}
.qsheet .qhd h2{font-family:var(--disp);font-size:19px;font-weight:700}
.qsheet .qhd .iconbtn{background:#E7E2D8;color:var(--brand)}
.qsheet .home{display:flex;align-items:center;gap:10px;width:100%;text-align:left;background:linear-gradient(180deg,var(--brand-2),var(--brand));color:#fff;
 border:0;border-radius:var(--radius);padding:12px;margin-bottom:12px;cursor:pointer;min-height:50px;
 box-shadow:0 1px 2px rgba(20,23,28,.1),0 10px 20px -12px rgba(20,23,28,.5)}
.qsheet .home .ti{flex-shrink:0;color:var(--gold)}
.qsheet .home .ti svg{width:19px;height:19px}
.qsheet .home b{font-family:var(--disp);font-size:15px;font-weight:700}

.telsheet{position:absolute;inset:0;background:rgba(20,23,28,.88);display:none;align-items:center;justify-content:center;padding:20px;z-index:6000}
.telsheet.on{display:flex}
.telsheet .tscard{background:var(--paper);border-radius:16px;padding:28px 20px 20px;width:100%;max-width:320px;text-align:center;position:relative;
 box-shadow:0 24px 48px -12px rgba(0,0,0,.5)}
.telsheet .tsclose{position:absolute;top:10px;right:10px;background:#E7E2D8;color:var(--brand)}
.telsheet .ts-nama{font-size:12.5px;letter-spacing:.04em;color:var(--slate);line-height:1.45}
.telsheet .ts-num{font-family:var(--disp);font-size:28px;font-weight:700;color:var(--brand);margin-top:8px;
 font-variant-numeric:tabular-nums;letter-spacing:.02em}
.ts-btn{display:flex;align-items:center;justify-content:center;gap:9px;width:100%;border:0;border-radius:var(--radius);
 padding:16px;margin-top:12px;font-family:var(--disp);font-size:14.5px;font-weight:700;letter-spacing:.02em;
 text-decoration:none;cursor:pointer;min-height:50px}
.ts-btn svg{width:18px;height:18px}
/* Sama persis dengan gradasi .tel -- keduanya tombol "Telepon", cuma di
   dua komponen berbeda (kartu kontak vs lembar nomor telepon). Sebelumnya
   .ts-btn.call memakai var(--green) polos sementara .tel sudah bergradasi
   -- dua tombol telepon terlihat beda gaya padahal maksudnya sama. */
.ts-btn.call{background:linear-gradient(180deg,#1f8a51,var(--green));color:#fff}
/* display:none default -- HANYA ditampilkan lewat JS (telOpsi() di app.js)
   saat nomornya benar-benar handphone (bukan landline kantor/kode darurat
   pendek, yang tidak pernah punya WhatsApp). Gaya OUTLINE hijau (bukan
   isian solid seperti .call) supaya dua tombol hijau bertumpuk tidak
   terlihat kembar -- "Telepon" tetap yang paling menonjol (aksi utama),
   "Chat WhatsApp" jelas actionable tapi setingkat di bawahnya. */
.ts-btn.wa{display:none;background:#E9F5EE;color:#146238;border:2px solid #1B7A43;padding:14px}
.ts-btn.copy{background:#E7E2D8;color:var(--ink)}

@media (prefers-reduced-motion:no-preference){.tile{transition:transform .12s ease}.tile:active{transform:scale(.985)}}

/* isi kop ikut dibatasi lebar maksimum di layar lebar */
.hdr>.backrow{max-width:var(--lebar-konten);margin-left:auto;margin-right:auto;width:100%}
.hdr{justify-content:center}
/* Cacat lama: .hdr>.hdrbtns dipatok right:12px terhadap .hdr, yang
   membentang selebar viewport. Di layar sempit itu kebetulan benar karena
   kolom konten (.hdr>.backrow, dibatasi --lebar-konten) juga memenuhi
   viewport. Tapi di layar lebar (mis. 1280px) kolom konten dipusatkan dan
   menyempit ke 430px, sedangkan tombol tetap menempel di tepi viewport —
   terlepas sekitar 400px dari isi kop yang menjadi miliknya.
   Perbaikan: pola yang sama dipakai .sos di bawah — jarak dari tepi kanan
   .hdr (100%, karena .hdr adalah containing block ber-position:relative)
   ke tepi kanan kolom terpusat adalah (100% - var(--lebar-konten))/2, lalu
   ditambah 12px agar jarak napasnya sama seperti right:12px semula.
   Dua contoh hitungan:
   - Lebar 375px (di bawah --lebar-konten 430px, kolom memenuhi layar):
     (375px - 430px)/2 + 12px = -27.5px + 12px = -15.5px. Nilai negatif ini
     ditangkap oleh max(12px, -15.5px) = 12px — persis right:12px seperti
     sebelumnya, jadi tampilan ≤430px tidak berubah sama sekali.
   - Lebar 1280px (kolom terpusat menyempit ke 430px):
     (1280px - 430px)/2 + 12px = 425px + 12px = 437px. Tombol kini
     right:437px dari tepi .hdr, menempel dekat tepi kanan kolom konten,
     bukan lagi 400px lebih jauh di tepi viewport.
   max() wajib ada: tanpa itu, pada layar yang lebih sempit dari
   --lebar-konten (seperti contoh 375px di atas) hasilnya negatif dan
   tombol akan terdorong keluar sisi kanan layar alih-alih tetap di
   posisi 12px yang benar. */
.hdr>.hdrbtns{position:absolute;right:max(12px, calc((100% - var(--lebar-konten)) / 2 + 12px));top:12px}
/* .hdr.ada-menu>.backrow — ruang cadangan kanan HANYA saat tombol menu
   benar-benar tampil (non-beranda), lewat kelas .ada-menu yang dinyalakan
   JS di render() bersamaan-persis dengan kondisi yang menampilkan #menubtn.
   Sebabnya: .hdrbtns memakai position:absolute (lihat aturan di atas),
   sehingga ia keluar dari alur dan .backrow TIDAK otomatis menyempit untuk
   memberi ruang — 46px terakhir .backrow bisa tertimpa tombol pada layar
   sempit (lihat cacat pada judul KEGIATAN MASYARAKAT).
   Perhitungan 54px: lebar tombol .iconbtn = 46px (lihat aturan .iconbtn)
   + jarak napas 8px (nilai gap yang sama dipakai .backrow dan .hdrbtns)
   = 54px. Di layar ≤430px (kondisi yang relevan untuk cacat judul ini),
   .hdrbtns tetap diposisikan right:12px lewat max() di atas — angka yang
   sama persis dengan padding-right .hdr (12px) — karena itu sisi kanan
   tombol berimpit tepat dengan sisi kanan .backrow tanpa selisih tambahan
   yang perlu dihitung. Jika lebar .iconbtn, padding-right .hdr, atau nilai
   12px pada max() di .hdr>.hdrbtns berubah, angka 54px ini harus dihitung
   ulang mengikuti rumus yang sama. */
.hdr.ada-menu>.backrow{padding-right:54px}
/* .sos membawa latar (--brand-2) sendiri, jadi tidak boleh dibatasi lewat
   max-width seperti .hdr>.backrow — itu akan menyisakan celah berwarna
   latar halaman di kiri-kanan bar 110/112 pada layar lebar, membuatnya
   tampak melayang, bukan bagian dari kop. Sebagai gantinya .sos tetap
   selebar layar dan isinya dipusatkan lewat padding horizontal terhitung,
   sehingga latarnya tetap penuh sampai ke tepi. */
.sos{padding-top:6px;padding-bottom:6px;
 padding-left:max(10px,calc((100% - var(--lebar-konten))/2));
 padding-right:max(10px,calc((100% - var(--lebar-konten))/2))}
/* #lokasi tidak membawa latar, jadi cukup dibatasi langsung seperti .body dan
   .hdr>.backrow — beda dengan .sos di atas. (Dulu aturan ini juga mencakup
   #kelurahan-pilihan; kotak itu dihapus karena menampilkan baris lokasi kedua
   yang membingungkan — lihat komentar di render() pada app.js.) */
#lokasi{max-width:var(--lebar-konten);margin-left:auto;margin-right:auto;width:100%}

/* Situs ini SENGAJA tidak melebar di desktop — pemangku kepentingan memilih
   bentuk kolom sempit terpusat (mirip tampilan ponsel) di atas latar polos,
   bukan grid ubin 3-4 kolom. Dulu ada dua titik henti (breakpoint) di sini,
   pada lebar layar 600 piksel dan 1024 piksel, yang membesarkan .grid
   menjadi 3 lalu 4 kolom serta menambah padding .body — itu justru cacat
   yang diminta dihapus. JANGAN menambahkan titik henti semacam itu
   kembali; .grid harus tetap 2 kolom di semua lebar layar, seperti di
   ponsel. Lihat build/layout.test.mjs yang sengaja mengasersi KETIADAAN
   kedua titik henti tersebut. */

/* bingkai peragaan — hanya untuk presentasi, diaktifkan lewat ?demo=1 */
body.demo .stage{justify-content:center;padding:12px 12px 32px;gap:8px;
 background:radial-gradient(ellipse 90% 60% at 50% 20%,rgba(201,152,42,.10),transparent 60%),#0B0D11}
body.demo .phone{max-width:430px;border-radius:22px;overflow:hidden;
 box-shadow:0 24px 60px rgba(0,0,0,.55);max-height:min(880px,calc(100vh - 40px))}
/* .topbar tetap sticky di mode demo tanpa aturan pengecualian. Gulir di mode
   ini terjadi di dalam .body (overflow-y:auto), bukan di .phone — .phone
   sendiri hanya memotong (overflow:hidden), tidak pernah tergulir. Karena itu
   .topbar, yang berada di luar .body, tidak pernah perlu "menempel" saat
   gulir; ia tetap diam di posisi alaminya di atas .body yang tergulir.
   Perilaku ini sama seperti sebelum penggabungan, saat .hdr dan .sos
   sticky sendiri-sendiri — jadi tidak ada regresi pada mode ?demo=1. */
body.demo .body{overflow-y:auto;flex:1;-webkit-overflow-scrolling:touch}
body.demo .grid{grid-template-columns:1fr 1fr}
