/* ---------- dasar ---------- */
* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
[hidden] { display: none !important; }
html, body { -webkit-user-select: none; user-select: none; height: 100%; }
input { -webkit-user-select: auto; user-select: auto; }

:root {
  --bg: #14121c;
  --panel: #1e1b2b;
  --line: #2e2a41;
  --ink: #e9e6f5;
  --dim: #9b95b8;
  --acc: #7cf3b0;
  --acc2: #b58cff;
  --bad: #ff7b8a;
  /* --app-h: tinggi layar TANPA keyboard; --kb: tinggi keyboard sekarang */
  --app-h: 100vh;
  /* tinggi navbar; diukur ulang dari elemennya di viewport.js (safe-area beda
     tiap HP). Nilai di sini cuma dipakai sebelum JS sempat jalan. */
  --topbarh: 46px;
  --map-h: 45vh;          /* jatah map: 45% sisa layar di bawah navbar */
  --kb: 0px;
  --barh: calc(58px + env(safe-area-inset-bottom));   /* tinggi kotak ketik */
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;
  overflow: hidden;
  position: fixed; inset: 0;
  touch-action: manipulation;
}

/* ---------- ruangan ---------- */
#app { display: none; }
#app.on { display: block; }

/* Map duduk DI BAWAH navbar (navbar bukan overlay), tingginya dipatok --map-h
   biar nggak memendek waktu keyboard HP muncul. Sisanya jadi kolom chat. */
#stage {
  position: fixed; top: var(--topbarh); left: 0; right: 0; height: var(--map-h);
  background: #0d0b14; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
#room { display: block; image-rendering: pixelated; image-rendering: crisp-edges; cursor: pointer; touch-action: none; }

#topbar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 4;
  display: flex; align-items: center; gap: 7px;
  padding: calc(8px + env(safe-area-inset-top)) 10px 8px;
  background: #181524;
  border-bottom: 1px solid var(--line); font-size: 13px;
}
#topbar .judul { font-weight: 700; letter-spacing: .3px; max-width: 34vw; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; color: var(--acc2); }
/* Slot italic ini yang MAKAN sisa ruang (flex: 1), jadi wadah tombol di
   kanannya selalu mentok kanan — nggak peduli isinya kosong atau ada yang
   disembunyiin. */
#topbar b { flex: 1; min-width: 0; text-align: right; color: var(--dim);
  font-size: 11px; white-space: nowrap; font-style: italic;
  overflow: hidden; text-overflow: ellipsis; }
.tb-kanan { display: flex; align-items: center; gap: 7px; flex: none; margin-left: auto; }
/* HP sempit: jarak antar tombol dirapatin. Yang dibeli dari sini ruang buat
   nama pasangan di kiri — dia yang paling pertama kepotong waktu navbar sesak.
   Hasilnya cuma ~6px (tiga jarak), soalnya tombolnya sendiri nggak bisa lebih
   kecil: lebarnya ditentukan glyph emoji-nya, bukan min-width. Kalau suatu
   saat butuh ruang lebih banyak, yang paling gede di baris ini tombol Skip
   (72px) — dia yang layak dipikirin, bukan tombol ikonnya. */
@media (max-width: 360px) {
  .tb-kanan { gap: 5px; }
}
#backbtn { font-size: 20px; line-height: 1; }
.lamp { width: 9px; height: 9px; border-radius: 50%; background: #555; flex: none; }
.lamp.live { background: var(--acc); animation: pulse 1.6s infinite; }
@keyframes pulse { 0%{box-shadow:0 0 0 0 rgba(124,243,176,.5)} 70%{box-shadow:0 0 0 8px rgba(124,243,176,0)} 100%{box-shadow:0 0 0 0 rgba(124,243,176,0)} }
/* Lagi nyari: titik hijau diganti jam pasir yang mbalik tiap beberapa detik.
   Titik hijau artinya "tersambung" — pas nyari, yang perlu dilihat orang itu
   bahwa ada yang lagi berjalan, bukan status koneksinya. */
#app.waiting .lamp { width: auto; height: auto; background: none; box-shadow: none;
  animation: none; font-size: 13px; line-height: 1; }
#app.waiting .lamp::after { content: '⏳'; display: inline-block;
  animation: jampasir 2.4s ease-in-out infinite; }
@keyframes jampasir {
  0%, 40%  { transform: rotate(0deg); }
  50%, 90% { transform: rotate(180deg); }
  100%     { transform: rotate(360deg); }
}

.skip { background: #2a2233; border: 1px solid #48304a; color: #ffb3c0;
  border-radius: 9px; padding: 6px 11px; font: inherit; font-size: 12px; font-weight: 700;
  cursor: pointer; flex: none; }
.skip:active { transform: translateY(1px); }
.skip.armed { background: #4a1f2b; border-color: #7a3145; color: #ffd7de; }

.tbtn { position: relative; background: #221f33; border: 1px solid #2e2a45; color: var(--ink);
  border-radius: 8px; min-width: 30px; height: 30px; font-size: 14px; cursor: pointer; flex: none; }

/* Kolom chat: 55% sisanya, dari bawah map sampai atas kotak ketik.
   Waktu keyboard naik, kolomnya yang menciut — map tetap. */
#chatlog {
  position: fixed; left: 0; right: 0;
  /* Normalnya mulai pas di bawah map. Kalau keyboard naik & sisanya kurang dari
     --logmin, kolomnya naik nutupin map biar isinya tetap kebaca.
     --logmin normalnya 120px (cukup buat beberapa baris chat), tapi waktu papan
     mini game kepasang JS naikin nilainya: papan butuh ruang jauh lebih tinggi
     daripada chat, dan kalau jatahnya kurang barisan kotak paling bawah masuk ke
     belakang kotak ketik — kelihatan ketutup dan nggak bisa dipencet.
     max(--topbarh, …) jaga-jaga di HP pendek + keyboard gede: tanpa itu hasil
     min() bisa minus dan kolomnya kedorong ke atas keluar layar. */
  top: max(var(--topbarh),
           min(calc(var(--topbarh) + var(--map-h)),
               calc(var(--app-h) - var(--kb) - var(--barh) - var(--logmin, 120px))));
  bottom: calc(var(--kb) + var(--barh));
  overflow: hidden; z-index: 4; display: flex; flex-direction: column;
  background: #120f1c; border-top: 1px solid var(--line); padding: 6px 0 2px;
}
/* judul kolom nempel di atas — yang scroll cuma daftar chatnya */
#loggrab { flex: none; display: flex; align-items: center; justify-content: center;
  padding: 2px 0 6px; color: var(--dim); font-size: 10px; font-weight: 700; letter-spacing: .5px;
  user-select: none; -webkit-user-select: none; }
/* panel suit: nempel di atas daftar chat — chatnya tetap kelihatan & kepakai */
#gamebox { flex: none; border-bottom: 1px solid var(--line); padding: 2px 12px 8px;
  background: linear-gradient(180deg, rgba(181,140,255,.1), transparent); }
.gb-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 6px; }
.gb-head b { font-size: 12px; }
.gb-score { margin-left: auto; font-size: 11px; color: var(--acc); font-weight: 700; }
.gb-pick { display: flex; gap: 6px; }
.gb-b { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 1px;
  background: rgba(30,27,43,.9); border: 1px solid var(--line); border-radius: 10px;
  color: var(--ink); font: inherit; font-size: 17px; padding: 5px 0 4px; cursor: pointer; }
.gb-b i { font-style: normal; font-size: 9.5px; color: var(--dim); }
.gb-b.on { border-color: var(--acc2); background: rgba(181,140,255,.16); }
.gb-b:disabled { opacity: .45; cursor: default; }
/* jodoh: dua tombol gede — isinya kalimat, bukan emoji doang kayak suit,
   jadi butuh ruang lebih lega biar "Nasi goreng" nggak kepotong */
.gb-jodoh[hidden] { display: none; }
.gj-pick { display: flex; gap: 7px; }
.gj-b { flex: 1; min-height: 52px; display: flex; align-items: center;
  justify-content: center; text-align: center; padding: 7px 6px;
  background: rgba(30,27,43,.9); border: 1px solid var(--line); border-radius: 10px;
  color: var(--ink); font: inherit; font-size: 12.5px; line-height: 1.3; cursor: pointer; }
.gj-b.on { border-color: var(--acc2); background: rgba(181,140,255,.16); }
.gj-b.cocok { border-color: var(--acc); background: rgba(124,243,176,.16); }
.gj-b:disabled { opacity: .5; cursor: default; }

/* Bom Waktu: kisi kotak. Kotak ketutup bisa diklik pas giliranmu; kotak aman
   yang kebuka jadi redup; kotak bom yang meledak nyala merah sesaat.

   Ukuran & jumlah kolomnya BUKAN angka mati. Dulu dipatok 4 kolom dengan kotak
   `aspect-ratio: 1/1` selebar 1fr: di HP pendek (atau begitu keyboard naik) tiga
   baris kotak lebih tinggi daripada jatah kolom chat, dan karena #chatlog
   `overflow: hidden`, baris paling bawah kepotong di belakang kotak ketik —
   kotaknya masih ada, cuma nggak bisa dipencet. Sekarang JS (bmFit) yang ngukur
   ruang sisa lalu nyetel --bm-cols & --bm-k, jadi seluruh papan dijamin muat. */
.gb-bom[hidden] { display: none; }
.gb-bom-nyawa { display: flex; align-items: center; justify-content: center;
  gap: 10px; margin-bottom: 7px; font-size: 13px; }
.bm-vs { font-size: 10px; color: var(--dim); }
/* kolomnya selebar kotak (bukan 1fr) biar tinggi papan bisa dipatok dari --bm-k,
   dan sisa lebarnya dipakai buat nengahin papan */
.gb-bom-grid { display: grid; justify-content: center;
  grid-template-columns: repeat(var(--bm-cols, 4), var(--bm-k, 62px));
  gap: var(--bm-gap, 6px); }
.bm-k { aspect-ratio: 1/1; display: flex; align-items: center; justify-content: center;
  background: rgba(30,27,43,.9); border: 1px solid var(--line); border-radius: 10px;
  color: var(--ink); font: inherit; font-size: clamp(11px, calc(var(--bm-k, 62px) * .34), 18px);
  cursor: pointer; padding: 0;
  transition: transform .08s, background .15s, border-color .15s; }
.gb-bom-grid.giliranku .bm-k:not(.buka):not(:disabled):active { transform: scale(.92); }
.gb-bom-grid:not(.giliranku) .bm-k { cursor: default; }
.bm-k.buka { background: rgba(124,243,176,.12); border-color: rgba(124,243,176,.4);
  color: var(--acc); cursor: default; }
.bm-k.bom { background: rgba(233,84,90,.85); border-color: #e9545a; color: #fff;
  animation: bmLedak .4s ease; }
.bm-k:disabled { cursor: default; }
@keyframes bmLedak { 0% { transform: scale(1.35); } 100% { transform: scale(1); } }

#gbask { gap: 8px; }
#gbask button { flex: 1; }
/* Baris info panel game. Dulu 11px abu-abu — sewarna sama hint biasa, jadi
   perubahan keadaan (giliranmu!) kebaca sama pentingnya sama teks mati.
   Sekarang warnanya yang kerja: hijau = kamu yang ditunggu, redup = lagi
   nunggu lawan, merah = waktunya mepet. */
.gb-msg { font-size: 12px; color: #cfc9e6; margin: 6px 0 0; min-height: 15px; line-height: 1.4; }
.gb-msg.tunggu { color: var(--dim); }
.gb-msg.giliran { color: var(--acc); font-weight: 700; }
/* titik yang ngedip di depan "giliranmu" — sinyal gerak paling murah yang
   ketangkep mata sudut, tanpa nge-layout ulang apa pun */
.gb-msg.giliran::before { content: ''; display: inline-block; vertical-align: 1px;
  width: 6px; height: 6px; margin-right: 6px; border-radius: 50%;
  background: var(--acc); animation: kedip 1s steps(1) infinite; }
.gb-msg.mepet { color: var(--bad); }
.gb-msg.mepet::before { background: var(--bad); }
.gb-msg.win { color: var(--acc); font-weight: 700; }
.gb-msg.lose { color: var(--bad); font-weight: 700; }
@keyframes kedip { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: .15; } }

#chatloglist { flex: 1; min-height: 0; overflow-y: auto; padding: 0 12px 4px;
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.cl-row { font-size: 12px; margin-bottom: 7px; line-height: 1.45; word-break: break-word; }
.cl-row b { color: var(--acc2); }
.cl-row.me b { color: var(--acc); }
.cl-row.sys { color: var(--dim); font-style: italic; font-size: 11px; }
/* Pengumuman owner. Sengaja NGGAK sekadar baris sys yang warnanya beda: pesan
   yang kelihatan "dari sistem" padahal dari pemain lain itu bahan tipu-tipu
   paling gampang di app yang isinya orang asing. Blok berlabel yang beda
   bentuknya jauh lebih susah ditiru pakai teks chat biasa. */
.cl-row.umum { background: rgba(181,140,255,.12); border-left: 3px solid var(--acc2);
  border-radius: 0 8px 8px 0; padding: 7px 9px; margin: 5px 0; font-size: 12px;
  color: var(--ink); line-height: 1.45; }
.cl-row.umum b { display: block; color: var(--acc2); font-size: 10px;
  letter-spacing: .6px; text-transform: uppercase; margin-bottom: 3px; }
.cl-row time { color: var(--dim); font-size: 10px; margin-left: 6px; }
.cl-img { display: block; max-width: 62%; max-height: 130px; border-radius: 10px;
  margin: 5px 0 2px; border: 1px solid var(--line); cursor: zoom-in; }
.cl-voice { display: flex; align-items: center; gap: 7px; margin: 4px 0 2px; }
.cl-voice i { font-style: normal; color: var(--dim); font-size: 11px; white-space: nowrap; }
.cl-voice audio { height: 34px; max-width: 170px; }

/* popup preview gambar */
#imgmodal { position: fixed; inset: 0; z-index: 90; display: none;
  align-items: center; justify-content: center; background: rgba(10, 8, 18, .72); }
#imgmodal.on { display: flex; }
#imgcard { background: var(--panel, #211d31); border: 1px solid var(--line, #383350);
  border-radius: 16px; padding: 14px; width: min(78vw, 300px);
  display: flex; flex-direction: column; gap: 10px; }
#imgcard b { font-size: 13px; color: var(--ink, #e8e5f5); }
#imgprev { max-width: 100%; max-height: 46vh; border-radius: 12px;
  border: 1px solid var(--line, #383350); object-fit: contain; background: #14121c; }
#imgacts { display: flex; gap: 8px; }
#imgacts button { flex: 1; border: 0; border-radius: 10px; padding: 9px 0;
  font-size: 13px; font-weight: 700; cursor: pointer; }
#imgno { background: #2c2840; color: var(--dim, #a5a1bd); }
#imgyes { background: var(--acc2, #8b5cf6); color: #fff; }

/* lightbox preview foto yang sudah terkirim */
#lm { position: fixed; inset: 0; z-index: 95; display: none;
  align-items: center; justify-content: center;
  background: rgba(5, 4, 10, .92); }
#lm.on { display: flex; }
#lmimg { max-width: 96vw; max-height: 92vh; object-fit: contain;
  border-radius: 10px; }
#lmclose { position: absolute; top: 14px; right: 16px;
  width: 38px; height: 38px; border: 0; border-radius: 50%;
  background: rgba(255,255,255,.14); color: #fff; font-size: 17px;
  cursor: pointer; }

/* ---------- laporkan pasangan (tombol 👮 di navbar) ---------- */
#reportbtn { font-size: 15px; }
#reportbtn:disabled { opacity: .35; }

#repmodal { position: fixed; inset: 0; z-index: 92; display: none;
  align-items: center; justify-content: center; padding: 18px;
  background: rgba(10, 8, 18, .74); }
#repmodal.on { display: flex; }
#repcard { background: var(--panel); border: 1px solid var(--line);
  border-radius: 16px; padding: 14px; width: min(86vw, 320px);
  display: flex; flex-direction: column; gap: 7px; animation: rise .16s ease-out; }
#repcard > b { font-size: 13px; }
#repcard .st-hint { margin: 0 0 3px; }
#repreasons { display: flex; flex-direction: column; gap: 6px; }
/* alasannya sengaja tombol besar-besar: sekali tap langsung kirim, nggak ada
   layar konfirmasi kedua — orang yang lagi kesel nggak mau ribet. */
.rep-r { display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  background: rgba(16,14,25,.75); border: 1px solid #2e2a45; border-radius: 11px;
  color: var(--ink); font: inherit; font-size: 16px; padding: 9px 11px; cursor: pointer; }
.rep-r span { font-size: 12.5px; }
.rep-r:active { background: rgba(255,123,138,.15); border-color: #6b3040; }
#repno { margin-top: 3px; }

/* ---------- popup penjelasan level ---------- */
#lvmodal { position: fixed; inset: 0; z-index: 93; display: none;
  align-items: center; justify-content: center; padding: 18px;
  background: rgba(10, 8, 18, .74); }
#lvmodal.on { display: flex; }
#lvcard { background: var(--panel); border: 1px solid var(--line);
  border-radius: 16px; padding: 15px; width: min(88vw, 340px);
  max-height: 82vh; overflow-y: auto;
  display: flex; flex-direction: column; gap: 8px; animation: rise .16s ease-out; }
#lvtitle { font-size: 15px; }
#lvcard .st-hint { margin: 0; }
.lv-bar { height: 6px; border-radius: 4px; background: rgba(255,255,255,.09);
  overflow: hidden; }
.lv-bar i { display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, #e0a828, #ffe9a8); transition: width .5s ease; }
/* daftar yang kebuka: baris tipis, ikon kiri, syarat kanan */
#lvlist { display: flex; flex-direction: column; gap: 5px; margin-top: 3px; }
.lv-row { display: flex; align-items: center; gap: 8px; padding: 7px 9px;
  border-radius: 10px; background: rgba(16,14,25,.7); border: 1px solid #2a2640;
  font-size: 12.5px; }
.lv-row.buka { border-color: #5a4a1e; background: rgba(224,168,40,.08); }
.lv-row b { font-weight: 700; color: var(--ink); }
.lv-row .sisa { margin-left: auto; color: var(--dim); font-size: 11px;
  white-space: nowrap; }
.lv-row.buka .sisa { color: #ffd166; }
#lvno { margin-top: 4px; }

/* ---------- kena banned: banner di home + tombol cari dikunci ---------- */
#banbox { display: flex; align-items: flex-start; gap: 10px; text-align: left;
  background: rgba(255,123,138,.09); border: 1px solid #5b3140;
  border-radius: 14px; padding: 11px 12px; margin-bottom: 11px; }
#banbox[hidden] { display: none; }
.bn-ic { font-size: 18px; line-height: 1.2; flex: none; }
#banbox > div > b { display: block; font-size: 12.5px; color: #ffb3bd; margin-bottom: 3px; }
#banbox p { font-size: 11px; color: var(--dim); line-height: 1.6; margin: 0; }
#banbox p b { color: var(--ink); }

/* chatbar naik setinggi keyboard, tapi map di belakangnya diam.
   Dua baris: aksi (🎮 📷 🎤) di atas, kotak ketik full-lebar di bawah. Kolom
   chat sekarang lega, jadi tombolnya nggak perlu lagi rebutan baris sama input
   — dan kotak ketiknya dapet lebar penuh. Tingginya diukur ke --barh dari JS. */
#chatbar {
  position: fixed; left: 0; right: 0; bottom: var(--kb); z-index: 5;
  display: flex; flex-direction: column; gap: 8px;
  padding: 8px 10px calc(8px + env(safe-area-inset-bottom));
  background: #120f1c; border-top: 1px solid var(--line);
  transition: bottom .15s ease-out;
}
.chb-aksi, .chb-ketik { display: flex; gap: 8px; }
/* laci mini game: ajakan suit & tebak angka. Foto/mic tetap di chatbar. */
#actsheet, #temasheet { position: fixed; left: 10px; right: 10px; z-index: 6;
  bottom: calc(var(--kb) + var(--barh) + 4px);
  display: flex; flex-direction: column; gap: 4px; padding: 6px;
  background: rgba(24,21,38,.97); border: 1px solid #3a3358; border-radius: 14px;
  box-shadow: 0 14px 34px rgba(0,0,0,.5); animation: rise .16s ease-out; }
#actsheet[hidden], #temasheet[hidden] { display: none; }
.act { display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  background: transparent; border: 0; border-radius: 10px; color: var(--ink);
  font: inherit; font-size: 16px; padding: 9px 11px; cursor: pointer; }
.act span { font-size: 13px; }
.act:active { background: rgba(181,140,255,.14); }
.act:disabled { opacity: .4; }
#app.sheet-on #plusbtn { background: #3a3358; }
#app.tema-on #temabtn { background: #3a3358; }
/* laci tema dua kolom: 6 pilihan kalau ditumpuk satu-satu kepanjangan */
#temasheet { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; }

#chat { flex: 1; background: rgba(30,27,43,.92); border: 1px solid var(--line); color: var(--ink);
  border-radius: 10px; padding: 10px 12px; font: inherit; font-size: 13px; }
#chat:focus { outline: none; border-color: var(--acc2); }
#send, .chbtn { background: var(--acc2); border: 0; border-radius: 10px; padding: 0 10px; font-size: 16px; cursor: pointer; }
/* di baris sendiri tombolnya nggak ikut ketarik tinggi input lagi, jadi
   ukurannya dipatok — 44px lebar biar tetap enak dipencet jempol */
.chbtn { min-width: 44px; height: 36px; }
#send:active, .chbtn:active { transform: translateY(1px); }
.chbtn.rec { background: #ff5d5d; color: #fff; animation: recpulse 1s infinite; }
@keyframes recpulse { 50% { opacity: .65; } }

/* ---------- panel "lagi nyari pasangan" (di dalam kolom chat) ---------- */
/* Nunggu pasangan nggak nutup layar: pemain tetap di ruangan dan bisa jalan.
   Kolom chat yang berganti jadi panel ini. */
#waitbox { flex: 1; min-height: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 6px; padding: 4px 16px 8px;
  text-align: center; animation: rise .22s ease-out; }
#waitbox[hidden] { display: none; }
#waitbox b { font-size: 14px; letter-spacing: .3px; }
#waitbox .st-hint { margin: 0; }
#sradar { image-rendering: pixelated; width: 78px; height: 78px; }
/* Tombolnya DIREGANGIN sama lebar (align-items: stretch), bukan ngikut panjang
   teksnya — dua tombol beda lebar yang ditumpuk kelihatan miring dan berantakan. */
#srroom { display: flex; flex-direction: column; align-items: stretch; gap: 7px;
  width: 100%; max-width: 300px; margin-top: 10px; animation: rise .22s ease-out; }
#srroom[hidden] { display: none; }
#srroom button { width: 100%; }
.rm-note { margin: 0; font-size: 10px; line-height: 1.5; color: var(--dim); }
.rm-note b { color: #ffd166; }
/* Mode ajak teman isinya lebih panjang: dirata-atas + bisa digulir, biar tombol
   Batal di bawah nggak kepotong pas layarnya pendek. Radar & judulnya
   dikecilin dikit karena di sini yang penting link-nya, bukan animasinya. */
#waitbox.room { justify-content: flex-start; overflow-y: auto; padding-top: 8px; }
#waitbox.room #sradar { width: 56px; height: 56px; }
#waitbox.room b { font-size: 13px; }
/* kabar panggilan: nunggu yang ada kabarnya jauh lebih tahan daripada nunggu
   yang diem — makanya dikasih titik yang kedip biar kelihatan masih jalan */
#srping { display: flex; align-items: center; justify-content: center; gap: 6px;
  margin: 7px 0 0; font-size: 11.5px; color: var(--acc2); line-height: 1.45;
  animation: rise .22s ease-out; }
#srping[hidden] { display: none; }
.sp-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--acc2);
  flex: none; animation: sp-kedip 1.1s infinite; }
@keyframes sp-kedip { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
.wb-act { display: flex; gap: 8px; margin-top: 6px; }
@keyframes rise { from { transform: translateY(16px); opacity: 0; } to { transform: none; opacity: 1; } }

/* selama nunggu: kotak ketik, kirim, foto, mic, dan skip dimatiin */
/* Kotak ketik TETAP hidup selama nunggu — pesannya nyampe ke Piko. Yang
   dimatiin cuma kirim foto & voice note, karena itu butuh pasangan beneran. */
#app.waiting #imgbtn, #app.waiting #micbtn { opacity: .4; pointer-events: none; }
/* `display: none`, bukan `visibility: hidden`: yang kedua tetap makan tempat,
   dan itu yang bikin tombol musik & ✕ kedorong ke tengah pas lagi nyari. */
#app.waiting #skipbtn, #app.waiting #reportbtn { display: none; }
/* Ruang di navbar jadi lega pas nyari, jadi judulnya nggak usah dipotong. */
#app.waiting #peername { max-width: none; }
/* Daftar chat DISEMBUNYIIN lagi pas nunggu — itu perilaku aslinya, dan ada
   alasannya: #waitbox dirancang makai SELURUH kolom (flex:1 + rata tengah).
   Begitu daftar chat ikut nongol, dua-duanya rebutan tinggi, isi kotak nunggu
   meluber, dan tombolnya numpuk di atas teks chat.
   Cuma dibuka di mode "ditemani Piko", di mana kotak nunggunya dipepetin jadi
   baris tipis di atas. Kelasnya ditaruh di #chatlog, bukan #waitbox, biar satu
   penanda bisa ngatur dua-duanya. */
#chatlog.wait #chatloglist { display: none; }
#chatlog.wait.temani #chatloglist { display: block; }
/* Ditemani Piko: kotak nunggu DIBUANG dari kolom chat dan statusnya pindah ke
   navbar. Radar + judul + tombol itu makan separuh layar buat informasi yang
   muat di satu baris — dan yang butuh ruang justru obrolannya. */
#chatlog.temani #waitbox { display: none; }
#chatlog.temani #waitbox { flex: none; justify-content: flex-start; padding-bottom: 4px; }
#chatlog.temani #sradar { width: 44px; height: 44px; }
#chatlog.temani #waitbox b { font-size: 12.5px; }
#chatlog.temani #waitbox .st-hint { font-size: 10.5px; }
.cl-row.ai b { color: #ffd166; }
.cl-row.ai span { color: #e6dbff; }

/* ---------- gamepad duel labirin ---------- */
#chatlog.pad #chatloglist { display: none; }
#pad { flex: 1; min-height: 0; display: flex; flex-direction: column;
  align-items: center; gap: 8px; padding: 6px 10px 8px; animation: rise .18s ease-out; }
#pad[hidden] { display: none; }
.pd-top { display: flex; align-items: center; gap: 14px; font-size: 12px; }
.pd-top b { font-size: 15px; }
.pd-sisa { font-size: 13px; font-weight: 700; color: var(--acc2);
  min-width: 46px; text-align: center; }
.pd-sisa.mepet { color: var(--bad); }
/* D-pad: grid 3x3, tombolnya ditaruh di silang tengahnya */
.pd-dpad { flex: 1; min-height: 0; display: grid; gap: 5px;
  grid-template-columns: repeat(3, 52px); grid-template-rows: repeat(3, 44px);
  align-content: center; }
.pd-b { background: #221f33; border: 1px solid #3a3358; border-radius: 11px;
  color: var(--ink); font: inherit; font-size: 17px; cursor: pointer;
  touch-action: none; -webkit-user-select: none; user-select: none; }
.pd-b:active, .pd-b.on { background: #3a3358; border-color: var(--acc2); }
.pd-b.up { grid-area: 1 / 2; } .pd-b.left { grid-area: 2 / 1; }
.pd-b.right { grid-area: 2 / 3; } .pd-b.down { grid-area: 3 / 2; }
/* lagi kaku kena monster: D-pad mati & merah, biar jelas kenapa nggak jalan */
#pad.beku .pd-dpad { opacity: .45; pointer-events: none; }
#pad.beku .pd-hint { color: var(--bad); }
.pd-hint { margin: 0; font-size: 10.5px; color: var(--dim); text-align: center; }

/* ---------- duel lari ---------- */
/* Sama pola sama gamepad labirin: panel ini GANTIIN daftar chat di kolom yang
   sama, bukan overlay — map di atasnya harus tetap kelihatan utuh, soalnya di
   situlah gamenya. */
#chatlog.pad #larpad { display: flex; }
#larpad { flex: 1; min-height: 0; display: flex; flex-direction: column;
  align-items: center; gap: 9px; padding: 6px 10px 8px; animation: rise .18s ease-out; }
#larpad[hidden] { display: none; }
.lr-hati { font-size: 12px; letter-spacing: 1px; }
.lr-tombol { flex: 1; min-height: 0; display: flex; align-items: center; gap: 7px; }
.lr-b { background: #221f33; border: 1px solid #3a3358; border-radius: 11px;
  color: var(--ink); font: inherit; font-size: 15px; cursor: pointer;
  min-width: 46px; min-height: 46px; padding: 0 10px;
  touch-action: none; -webkit-user-select: none; user-select: none; }
.lr-b:active { background: #3a3358; border-color: var(--acc2); }
/* lompat & nunduk dibedain warnanya: dua tombol inilah yang dipencet paling
   sering, dan salah pencet di antara keduanya = kehilangan nyawa */
.lr-lompat { border-color: #3f6b52; color: #a9f0c6; }
.lr-nunduk { border-color: #6b4a3f; color: #f0c9a9; }
/* laju & jarak: di sini, bukan di kanvas — kanvasnya kepotong dikit di pinggir */
.lr-laju { margin: 0; font-size: 11px; color: var(--acc); font-weight: 700;
  letter-spacing: .4px; }
/* habis nabrak: tombolnya diredupin sebentar, biar jelas kenapa nggak ngefek */
#larpad.beku .lr-tombol { opacity: .45; pointer-events: none; }
#larpad.beku .pd-hint { color: var(--bad); }

/* ---------- duel terbang ---------- */
/* Sama pola sama duel lari: ganti daftar chat di kolom yang sama, bukan
   overlay — mapnya di atas harus tetap kelihatan utuh. Tombolnya cuma satu
   dan sengaja selebar panel: di game ini yang mahal itu telat sepersekian
   detik, jadi jempol nggak boleh perlu ngincer. */
#chatlog.pad #trbpad { display: flex; }
#trbpad { flex: 1; min-height: 0; display: flex; flex-direction: column;
  align-items: center; gap: 9px; padding: 6px 10px 8px; animation: rise .18s ease-out; }
#trbpad[hidden] { display: none; }
.tb-tombol { flex: 1; min-height: 0; display: flex; align-items: center;
  align-self: stretch; }
.tb-b { flex: 1; background: #1f2c3a; border: 1px solid #3f6b7d; border-radius: 12px;
  color: #a9dcf0; font: inherit; font-size: 15px; font-weight: 700; cursor: pointer;
  min-height: 46px; padding: 0 10px;
  touch-action: none; -webkit-user-select: none; user-select: none; }
.tb-b:active { background: #3f6b7d; border-color: var(--acc2); color: var(--ink); }
#trbpad.beku .tb-tombol { opacity: .45; pointer-events: none; }
#trbpad.beku .pd-hint { color: var(--bad); }
/* Aba-aba "3 2 1": tombolnya sama-sama mati kayak `beku`, tapi petunjuknya
   TETAP warna biasa. `beku` mewarnai merah karena dia dipakai sesudah nabrak —
   merah di layar "siap-siap" kebaca kayak ada yang salah, padahal duelnya
   malah belum mulai. */
#trbpad.aba .tb-tombol { opacity: .45; pointer-events: none; }

/* ---------- mode lukis ---------- */
/* Panel ini GANTIIN daftar chat di kolom yang sama — bukan overlay — biar map
   di atasnya tetap kelihatan dan karakternya masih bisa dilihat pas animasi
   ngelukis jalan. */
#chatlog.paint #chatloglist { display: none; }
#app.paint-on #paintbtn { background: #3a3358; }
#paint { flex: 1; min-height: 0; display: flex; flex-direction: column;
  gap: 7px; padding: 6px 10px 8px; animation: rise .18s ease-out; }
#paint[hidden] { display: none; }
.pt-bar { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.pt-grup { display: flex; gap: 5px; }
.pt-sela { flex: 1; }
.pt-w { width: 21px; height: 21px; padding: 0; flex: none; cursor: pointer;
  border-radius: 50%; border: 2px solid transparent; }
.pt-w.on { border-color: #fff; }
.pt-del { background: #221f33; color: #c9c4e0; font-size: 11px; line-height: 1;
  border: 2px solid #2e2a45; }
.pt-del.on { border-color: #fff; }
/* tombol kuas: titik di dalamnya yang ngasih tau tebalnya */
.pt-k { width: 24px; height: 21px; padding: 0; flex: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  background: #221f33; border: 1px solid #2e2a45; border-radius: 7px; }
.pt-k.on { border-color: var(--acc2); background: #2e2a45; }
.pt-k i { display: block; background: #cfc9e8; border-radius: 50%; }
.pt-t { background: #221f33; border: 1px solid #2e2a45; color: var(--ink);
  border-radius: 7px; min-width: 28px; height: 21px; font-size: 11px; cursor: pointer; }
.pt-t:active { transform: translateY(1px); }
.pt-kanvas { flex: 1; min-height: 0; overflow: hidden; background: #fffdf7;
  border: 1px solid var(--line); border-radius: 10px; }
#ptcv { display: block; width: 100%; height: 100%; touch-action: none; cursor: crosshair; }
.pt-aksi { display: flex; gap: 8px; justify-content: flex-end; }
.pt-aksi button:disabled { opacity: .5; }

/* ---------- home ---------- */
#home { position: fixed; inset: 0; z-index: 10; overflow-y: auto;
  background:
    radial-gradient(95% 55% at 50% -8%, rgba(181,140,255,.20), transparent 72%),
    radial-gradient(70% 45% at 88% 18%, rgba(124,243,176,.09), transparent 70%),
    radial-gradient(80% 50% at 10% 92%, rgba(90,120,255,.08), transparent 70%),
    var(--bg); }
#home.off { display: none; }
/* kisi pixel tipis di belakang — nempel identitas "pixel" tanpa berisik */
.hm-grid { position: absolute; inset: 0; pointer-events: none;
  background-image: linear-gradient(rgba(255,255,255,.03) 1px, transparent 1px),
                    linear-gradient(90deg, rgba(255,255,255,.03) 1px, transparent 1px);
  background-size: 16px 16px;
  -webkit-mask-image: radial-gradient(72% 52% at 50% 32%, #000 25%, transparent 78%);
          mask-image: radial-gradient(72% 52% at 50% 32%, #000 25%, transparent 78%); }
.hm { position: relative; max-width: 460px; margin: 0 auto; min-height: 100%;
  display: flex; flex-direction: column; justify-content: center;
  padding: calc(24px + env(safe-area-inset-top)) 22px calc(24px + env(safe-area-inset-bottom)); }

.hm-hero { text-align: center; margin-bottom: 18px; }
.hm-hero h1 { font-size: 26px; letter-spacing: 1.5px; text-shadow: 0 3px 18px rgba(181,140,255,.28); }
.hm-hero h1 span { color: var(--acc2); }
.tagline { margin: 7px auto 15px; max-width: 320px; color: var(--dim); font-size: 12px; line-height: 1.6; }

/* ---------- kartu karakter (diorama hidup) ---------- */
/* Kanvasnya diregangin selebar kartu dan tingginya dipatok lewat CSS; ukuran
   piksel aslinya dihitung ulang di drawScene() tiap layar berubah. */
.hm-kartu { position: relative; border-radius: 18px; overflow: hidden;
  border: 1px solid #383254; background: #0d0b14;
  box-shadow: 0 0 0 5px rgba(181,140,255,.06), 0 18px 38px rgba(0,0,0,.5); }
#hmscene { display: block; width: 100%; height: 168px; image-rendering: pixelated; }
/* Nama & koin ngambang di atas dasar diorama. Dikasih gradien gelap biar
   teksnya tetap kebaca di tema yang lantainya terang (taman, desa). */
.hm-ident { position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 16px 11px 7px; font-size: 11px; font-weight: 700;
  background: linear-gradient(180deg, transparent, rgba(9,7,16,.86) 74%); }
.hm-lv { position: relative; flex: none; font: inherit; font-size: 10px;
  font-weight: 800; letter-spacing: .3px; cursor: pointer;
  color: #16112a; background: linear-gradient(180deg, #ffe9a8, #e0a828);
  border: 1px solid #14141c; border-radius: 5px; padding: 2px 6px;
  text-shadow: none; }
/* Chip-nya sengaja tetap kecil, tapi area sentuhnya dilebarin lewat ::after —
   jempol butuh ~44px, sementara lencana 10px yang digedein malah ngerebut
   perhatian dari nama & saldo di baris yang sama. */
.hm-lv::after { content: ''; position: absolute; inset: -12px -10px; }
.hm-lv:active { transform: translateY(1px); }
.hm-lv[hidden] { display: none; }
.hm-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
  background: rgba(255,255,255,.10); }
.hm-bar[hidden] { display: none; }
.hm-bar i { display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, #e0a828, #ffe9a8);
  transition: width .5s ease; }

.hm-nama { color: #efe9ff; letter-spacing: .3px; text-shadow: 0 1px 3px rgba(0,0,0,.8);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hm-nama.kosong { color: var(--dim); font-weight: 600; }
.hm-koin { color: #ffd166; flex: none; text-shadow: 0 1px 3px rgba(0,0,0,.8); }
.ava-dot { position: absolute; right: 10px; top: 10px; width: 8px; height: 8px;
  border-radius: 50%; background: var(--acc); box-shadow: 0 0 0 3px rgba(13,11,20,.6); }
.ava-roll { position: absolute; left: 8px; top: 8px;
  width: 32px; height: 32px; border-radius: 50%; cursor: pointer;
  background: rgba(28,24,48,.82); border: 1px solid #4a4272; color: var(--ink);
  font-size: 14px; box-shadow: 0 4px 12px rgba(0,0,0,.45); transition: transform .12s; }
.ava-roll:active { transform: scale(.92) rotate(-18deg); }

/* ---------- tiga ubin aksi sekunder ---------- */
/* Yang dituju di layar ini cuma satu (Cari Pasangan). Sisanya dibikin sebaris
   ubin kecil, bukan tiga baris penuh yang berat visualnya sama. */
/* ---------- ajakan kasih saran ---------- */
/* Beda warna dari ubin & tombol utama: ini bukan aksi inti, tapi juga bukan
   tempelan — dia bawa hadiah, dan hadiah yang nggak kelihatan nggak diambil. */
.saran-ajak { display: flex; align-items: center; gap: 11px; width: 100%;
  margin-top: 10px; padding: 11px 13px; text-align: left; cursor: pointer;
  color: var(--ink); font: inherit; border-radius: 14px;
  background: linear-gradient(135deg, rgba(255,209,102,.13), rgba(255,209,102,.04));
  border: 1px solid rgba(255,209,102,.30); }
.saran-ajak[hidden] { display: none; }
.saran-ajak:active { transform: translateY(1px); }
.sa-ic { font-size: 19px; flex: none; }
.sa-txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.sa-txt b { font-size: 13px; font-weight: 700; }
.sa-txt small { font-size: 10px; color: var(--dim); line-height: 1.35; }
.sa-koin { margin-left: auto; flex: none; font-size: 12px; font-weight: 700;
  color: #ffd166; white-space: nowrap; }

#srteks { width: 100%; min-height: 150px; resize: vertical; font: inherit;
  font-size: 15px; line-height: 1.55; padding: 12px 13px; border-radius: 12px;
  color: var(--ink); background: #171327; border: 1px solid #3a3358; }
#srteks:focus { outline: none; border-color: var(--acc2); }
.sr-kaki { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.sr-kaki .hint { margin: 0; margin-right: auto; }
.sr-kaki button { min-width: 120px; }
#srpesan.ok { color: var(--acc); }
#srpesan.bad { color: var(--bad); }

.hm-pemain { margin: 9px 0 0; text-align: center; font-size: 11px;
  color: var(--dim); letter-spacing: .3px; }
.hm-pemain b { color: var(--acc); font-weight: 700; font-size: 12px; }
.hm-pemain[hidden] { display: none; }

.hm-ubin { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 12px; }
.ubin { position: relative; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 4px; min-height: 62px; padding: 8px 4px; cursor: pointer;
  background: linear-gradient(180deg, rgba(38,34,56,.72), rgba(26,23,38,.72));
  border: 1px solid #322d4b; border-radius: 13px; color: var(--ink); font: inherit; }
.ubin i { font-style: normal; font-size: 19px; line-height: 1; }
.ubin b { font-size: 10.5px; font-weight: 700; letter-spacing: .3px; color: #cfc9e6; }
.ubin:active { transform: translateY(1px); }
/* Jumlah teman cuma nongol kalau memang ada — yang belum punya nggak perlu
   disambut angka nol tiap buka app. */
.ubin-n { position: absolute; top: 6px; right: 8px; min-width: 16px; height: 16px;
  padding: 0 4px; border-radius: 9px; background: var(--acc2); color: #fff;
  font-size: 9.5px; font-weight: 800; line-height: 16px; text-align: center; }
.ubin-n[hidden] { display: none; }

/* Ditulis `button.big`, BUKAN `.big`: .primary ada 150 baris di bawah sini dan
   spesifisitasnya sama, jadi kalau cuma `.big` dia yang menang dan padding,
   sudut, sama gradien di sini ketimpa diam-diam. Ini sempat kejadian — tombol
   Cari Pasangan sebenernya nggak pernah nampilin gradiennya.

   Tombol utama home. Isinya ikon + judul + satu baris penjelas. Ditata sebaris
   pakai flex biar penjelasnya rata kiri di bawah judul, bukan ketengah kayak
   teks tombol biasa. */
button.big {
  display: flex; align-items: center; gap: 12px; text-align: left;
  position: relative; overflow: hidden;
  padding: 14px 16px; border-radius: 16px; font: inherit; cursor: pointer; }
.bt-ic { font-style: normal; font-size: 21px; line-height: 1; flex: none; }
.bt-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.bt-txt small { font-size: 10.5px; font-weight: 400; opacity: .72; letter-spacing: .2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

button.big { font-size: 15.5px; font-weight: 700;
  background: linear-gradient(135deg, #8ff6c0, #57ddc4);
  box-shadow: 0 12px 28px rgba(124,243,176,.20), inset 0 1px 0 rgba(255,255,255,.4); }

/* kilau tipis lewat tiap beberapa detik — nunjukin tombol utamanya yang mana */
.big::after { content: ''; position: absolute; top: 0; left: -60%; width: 38%; height: 100%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.42), transparent);
  transform: translateX(0) skewX(-18deg); animation: sheen 4.5s ease-in-out infinite; }
/* Yang dianimasiin transform, BUKAN `left`. `left` maksa browser ngitung ulang
   layout tiap frame — selamanya, selama orang diem di home. transform dikerjain
   compositor doang. Jaraknya 487% lebar elemen = 185% lebar tombol, sama persis
   dengan -60% -> 125% yang dulu. */
@keyframes sheen {
  0%, 62% { transform: translateX(0) skewX(-18deg); }
  100%    { transform: translateX(487%) skewX(-18deg); }
}

.st-koin { margin: 0 0 10px; font-size: 11px; color: var(--dim); line-height: 1.5; }
.st-koin b { color: #ffd166; }
/* dua jalur beli dalam satu kartu — ditumpuk, kartunya terlalu sempit buat sebaris */
.st-buy { display: flex; flex-direction: column; gap: 4px; width: 100%; }
.st-buy button { width: 100%; }
.st-price .koin { color: #ffd166; }

/* pilihan Privat / Grup — muncul di bawah tombol Ajak Teman */
#roompilih { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px;
  animation: rise .18s ease-out; }
#roompilih[hidden] { display: none; }
.rp { display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  padding: 11px 13px; text-align: left; cursor: pointer;
  color: #e6dbff; font: inherit; font-size: 17px;
  background: linear-gradient(135deg, rgba(181,140,255,.16), rgba(181,140,255,.05));
  border: 1px solid rgba(181,140,255,.34); border-radius: 12px; }
.rp b { font-size: 13.5px; font-weight: 700; }
.rp small { font-size: 10px; font-weight: 400; color: var(--dim); line-height: 1.35; }
.rp:active { transform: translateY(1px); }

.starpill { background: rgba(255,209,102,.1); border: 1px solid rgba(255,209,102,.26);
  color: #ffd166; font-weight: 700; font-size: 11px; padding: 5px 10px; border-radius: 999px;
  white-space: nowrap; }
.starpill.lg { font-size: 11.5px; padding: 6px 11px; }
.st-bar .starpill { margin-left: auto; }

.hm-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-top: 18px; padding-top: 12px; border-top: 1px solid rgba(46,42,65,.6); }
.foot-l { display: flex; align-items: center; gap: 7px; min-width: 0; }
.hm-foot .hint { margin-top: 0; }   /* .hint bawaan punya margin atas — di baris ini nggak usah */
#hver { margin-left: auto; }                /* versi selalu mepet kanan */
/* link channel komunitas, sebaris sama versi */
.chan { color: var(--acc2); font-size: 11px; text-decoration: none; white-space: nowrap;
  border: 1px solid #3a3358; border-radius: 20px; padding: 4px 10px;
  background: rgba(181,140,255,.08); }
.chan:active { transform: translateY(1px); }
.fdot { width: 6px; height: 6px; border-radius: 50%; background: var(--acc); flex: none;
  box-shadow: 0 0 0 3px rgba(124,243,176,.12); }
.foot-l.off { display: none; }              /* status kosong: baris kiri ilang */

.ghost { background: #221f33; border: 1px solid #2e2a45; color: #c9c4e0;
  border-radius: 10px; padding: 11px 16px; font: inherit; font-size: 12.5px; cursor: pointer; }
.ghost:active { transform: translateY(1px); }
.ghost.sm { padding: 9px 13px; font-size: 12px; }

/* ================= STORE ================= */
#store, #teman, #saran { position: fixed; inset: 0; z-index: 80; display: none;
  background: radial-gradient(90% 45% at 50% 0%, #241d3a 0%, #0b0a12 62%);
  overflow-y: auto; -webkit-overflow-scrolling: touch; }
#store.on, #teman.on, #saran.on { display: block; }
/* Judul + saldo + tab nempel di atas biar nggak ilang pas scroll panjang.
   Yang sticky KOTAKNYA, bukan .st-bar sendiri-sendiri: kalau dua-duanya
   sticky, yang bawah butuh angka `top` setinggi yang atas — dan tinggi itu
   ikut env(safe-area-inset-top) yang beda tiap HP. */
.st-head { position: sticky; top: 0; z-index: 2;
  background: rgba(14,12,22,.9); backdrop-filter: blur(8px);
  border-bottom: 1px solid #262138; }
.st-bar { display: flex; align-items: center; gap: 10px;
  max-width: 480px; margin: 0 auto;
  padding: calc(12px + env(safe-area-inset-top)) 14px 10px; }
.st-bar > b { font-size: 16px; letter-spacing: .3px; }

/* ---- daftar teman ---- */
/* Tampilan kosong. Dulu cuma sebaris .st-hint karena nyaris nggak pernah
   kebuka — kartunya di home disembunyiin selama daftarnya kosong. Sekarang
   kartunya selalu ada, jadi ini layar pertama yang dilihat orang yang penasaran
   sama fiturnya, dan dia harus bisa jawab "ini apa" sendirian. */
.tm-kosong { text-align: center; padding: 26px 18px 30px; }
.tm-kosong-ic { display: block; font-size: 34px; line-height: 1; margin-bottom: 12px; opacity: .75; }
.tm-kosong b { display: block; font-size: 14px; color: var(--ink); margin-bottom: 7px; }
.tm-kosong p { font-size: 12px; color: var(--dim); line-height: 1.6; max-width: 300px; margin: 0 auto; }

.tm-list { display: flex; flex-direction: column; gap: 8px; }
.tm-row { display: flex; align-items: center; gap: 10px;
  background: linear-gradient(180deg, rgba(36,31,56,.8), rgba(26,23,38,.8));
  border: 1px solid #322d4b; border-radius: 14px; padding: 11px 12px; }
.tm-ki { min-width: 0; flex: 1; }
.tm-nama { font-size: 13.5px; color: var(--ink); display: flex; align-items: center; gap: 7px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tm-sub { font-size: 10.5px; color: var(--dim); margin-top: 3px; }
/* titik hijau = lagi buka app. Yang online ditaruh paling atas sama JS-nya,
   jadi titik ini penegas, bukan satu-satunya petunjuk. */
.tm-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; background: #4a4470; }
.tm-dot.on { background: var(--acc); box-shadow: 0 0 0 3px rgba(124,243,176,.14); }
.tm-ajak { flex: none; }
/* tombol putus sengaja sunyi: dia perlu ADA, tapi nggak perlu ditawarin */
.tm-x { flex: none; width: 30px; height: 30px; border-radius: 9px; cursor: pointer;
  background: transparent; border: 1px solid #322d4b; color: var(--dim); font-size: 13px; }
.tm-x:active { transform: translateY(1px); }
.tm-x.yakin { border-color: #6d2f3c; color: #ff7b8a; background: rgba(255,123,138,.08); }

/* ---- tab store ---- */
.st-tabs { display: flex; gap: 6px; max-width: 480px; margin: 0 auto;
  padding: 0 14px 10px; }
.st-tab { flex: 1 1 0; min-width: 0; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  background: rgba(16,14,25,.75); border: 1px solid #2e2a45; border-radius: 12px;
  color: var(--dim); font: inherit; padding: 7px 6px;
  transition: border-color .12s, background .12s, color .12s; }
.st-tab:active { transform: translateY(1px); }
/* label: emoji + teks sebaris. Ellipsis-nya dipasang di SPAN teksnya, bukan di
   .st-tl — text-overflow nggak berlaku buat kotak flex, cuma buat kotak yang
   isinya teks langsung. */
.st-tl { display: flex; align-items: center; gap: 5px; max-width: 100%;
  font-size: 12px; line-height: 1.3; white-space: nowrap; overflow: hidden; }
.st-tl > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.st-tab .st-ic { width: 20px; height: 20px; font-size: 11px; border-radius: 7px; }
/* baris kedua tiap tab: "4/12", "0/8", atau "⭐ 50 / ganti" */
.st-tab .st-count, .st-tab .st-cost { font-size: 10px; line-height: 1.3; }
.st-tab .st-count:empty, .st-tab .st-cost:empty { display: none; }
.st-tab.on { color: var(--ink); border-color: #b58cff; background: rgba(181,140,255,.14); }
.st-tab.on .st-ic { background: rgba(181,140,255,.24); border-color: #5a4a86; }
/* HP sempit (iPhone SE dkk): emoji dibuang, tiga label penuh lebih berguna
   daripada tiga ikon plus label yang kepotong separuh */
@media (max-width: 359px) {
  .st-tabs { gap: 5px; padding-left: 10px; padding-right: 10px; }
  .st-tab { padding: 7px 4px; }
  .st-tab .st-ic { display: none; }
}
.st-x { width: 34px; height: 34px; flex: none; border-radius: 10px; cursor: pointer;
  background: #221f33; border: 1px solid #322d4b; color: var(--ink); font-size: 19px; line-height: 1; }
.st-x:active { transform: translateY(1px); }

.st-wrap { max-width: 480px; margin: 0 auto; padding: 12px 14px calc(34px + env(safe-area-inset-bottom)); }
.st-sec { background: linear-gradient(180deg, rgba(36,31,56,.8), rgba(26,23,38,.8));
  border: 1px solid #322d4b; border-radius: 16px; padding: 14px; margin-bottom: 12px; }
.st-ic { font-style: normal; font-size: 13px; width: 26px; height: 26px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(181,140,255,.12); border: 1px solid #3a3358; border-radius: 9px; }
.st-cost { font-size: 11px; color: #ffd166; font-weight: 400; }
.st-count { font-size: 11px; color: var(--dim); font-weight: 400; }
.st-hint { font-size: 11px; color: var(--dim); margin: 2px 0 10px; line-height: 1.5; }

/* 132px dulu bikin HP 320px cuma dapat SATU kolom — daftarnya jadi dua kali
   lebih panjang persis di layar yang paling sempit. 118px muat dua kolom di
   sana, dan di layar lebar malah dapat tiga. */
.st-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 9px; }
/* Harga diganti syarat level: emas kalau udah kebuka, redup kalau belum.
   Sengaja sewarna sama chip level di kartu home biar kebaca satu sistem. */
.st-lv { font-size: 10.5px; font-weight: 700; letter-spacing: .3px;
  color: var(--dim); }
.st-lv.buka { color: #ffd166; }

.st-card { position: relative; display: flex; flex-direction: column; align-items: center; gap: 7px;
  background: rgba(16,14,25,.75); border: 1px solid #2e2a45; border-radius: 14px;
  padding: 11px 9px 10px; text-align: center; transition: border-color .12s, transform .12s; }
.st-card:active { transform: translateY(1px); }
/* petak kotak-kotak di belakang sprite: kelihatan kayak display kaca toko */
.st-thumb { width: 62px; height: 62px; display: flex; align-items: center; justify-content: center;
  border-radius: 12px; border: 1px solid #2b2740;
  background:
    linear-gradient(180deg, rgba(181,140,255,.08), transparent),
    repeating-conic-gradient(#141122 0% 25%, #191530 0% 50%) 0 0 / 12px 12px; }
.st-card canvas { image-rendering: pixelated; display: block; }
.st-name { font-size: 12.5px; color: var(--ink); }
.st-price { font-size: 11px; color: #ffd166; font-weight: 700; }
.st-tag { font-size: 10px; font-weight: 700; letter-spacing: .3px;
  padding: 3px 9px; border-radius: 999px; }
.st-tag.own { color: #9fe8c0; background: rgba(124,243,176,.1); border: 1px solid rgba(124,243,176,.28); }
.st-tag.eq  { color: #d9c2ff; background: rgba(181,140,255,.14); border: 1px solid rgba(181,140,255,.4); }
.st-card button { width: 100%; }
.st-card.on { border-color: #b58cff; box-shadow: 0 0 0 1px rgba(181,140,255,.45) inset, 0 8px 20px rgba(181,140,255,.12); }
.st-card.own { border-color: #35563f; }
.st-card button[disabled] { opacity: .5; cursor: default; }
.st-badge { position: absolute; top: 7px; right: 7px; font-size: 10px; line-height: 1;
  padding: 3px 6px; border-radius: 999px; background: #b58cff; color: #1a1230; font-weight: 700; }

.st-names { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 10px; }
.st-names:empty { display: none; }
.nm { display: flex; align-items: center; gap: 6px; cursor: pointer;
  background: rgba(16,14,25,.8); border: 1px solid #2e2a45; border-radius: 999px;
  color: var(--ink); font: inherit; font-size: 11.5px; padding: 6px 11px; }
.nm:active { transform: translateY(1px); }
.nm.on { border-color: #b58cff; background: rgba(181,140,255,.14); color: #e7dcff; font-weight: 700; }
.nm.on::before { content: '✓'; font-size: 10px; color: #b58cff; }
.nm.off { color: var(--dim); }              /* tombol balik ke alias acak */

/* hint "nama pertama gratis" — dibedain dari hint biasa karena ini penawaran,
   bukan keterangan; kalau warnanya sama, kelewat sama semua orang */
.st-free { color: #9fe8c0; background: rgba(124,243,176,.08);
  border: 1px solid rgba(124,243,176,.25); border-radius: 10px;
  padding: 8px 10px; margin: 0 0 10px; }

.st-namerow { display: flex; gap: 8px; }
.st-namerow input { flex: 1; min-width: 0; background: rgba(16,14,25,.9);
  border: 1px solid #2e2a45; border-radius: 10px; color: var(--ink);
  padding: 10px 12px; font: inherit; font-size: 13px; outline: none; }
.st-namerow input:focus { border-color: #b58cff; }
.primary.sm, .ghost.sm { padding: 9px 14px; font-size: 12px; }
button.wide { width: 100%; }

.primary { background: var(--acc); color: #0c2418; border: 0; border-radius: 10px;
  padding: 12px; font: inherit; font-weight: 700; font-size: 14px; cursor: pointer; }
.primary:active { transform: translateY(1px); }
.primary.wide { width: 100%; }
.primary:disabled { opacity: .45; cursor: default; transform: none; }
.big:disabled::after { animation: none; }   /* kilaunya ikut mati biar nggak ngajak klik */

.hint { color: var(--dim); font-size: 11px; margin-top: 8px; line-height: 1.5; }
.hint.bad { color: var(--bad); }

@media (prefers-reduced-motion: reduce) { .big::after { animation: none; } }

/* ajakan "ada yang nunggu" — duduk di atas kotak ketik / bawah layar */
#ajakbar, #temaask, #temanask { position: fixed; left: 10px; right: 10px; z-index: 49;
  bottom: calc(10px + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: 8px; padding: 8px 10px;
  background: rgba(25,22,39,.97); border: 1px solid var(--acc2); border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0,0,0,.5); animation: rise .2s ease-out; }
#ajakbar[hidden], #temaask[hidden], #temanask[hidden] { display: none; }

/* ---------- AJAKAN DARI PASANGAN NONGOL DI ATAS MAP ----------
   Ajakan yang datangnya dari PASANGAN — ganti suasana (#temaask), ngajak main
   game (#gamebox waktu masih nanya "Ikutan?"), dan ajakan temenan (#temanask)
   — dipindah ke map.
   Di dasar layar dua-duanya kebaca kayak satu pesan chat biasa terus kelewat,
   padahal ada yang lagi nungguin dijawab. Titik jatuhnya disamain: nempel di
   TEPI BAWAH map, ditengahkan, selebar map — persis di batas map sama kolom
   chat, jadi kena mata tanpa nutupin ruangannya.

   Yang SENGAJA nggak ikut pindah:
     #ajakbar   bukan dari pasangan, dan munculnya pas ruangan belum kebuka
     #imgmodal  konfirmasi kirim foto — kita sendiri yang mulai, lagi
     #repmodal  konfirmasi laporan — dua-duanya udah modal segelap layar */
#temaask,
#temanask,
#gamebox.nanya {
  position: fixed; z-index: 49;
  /* `translateY(-100%)` bikin patokannya jadi SISI BAWAH kartu: mau isinya dua
     baris atau lima, jaraknya ke tepi map tetap 10px. Nggak usah tau tinggi
     kartunya, dan nggak ngandelin tinggi layar yang bisa berubah. */
  top: calc(var(--topbarh) + var(--map-h) - 10px); bottom: auto;
  left: 50%; right: auto; width: min(92vw, 400px);
  transform: translate(-50%, -100%);
  background: rgba(25,22,39,.97);
  border: 1px solid var(--acc); border-radius: 12px;
  box-shadow: 0 12px 34px rgba(0,0,0,.55);
  /* dua animasi: naik sekali dari bawah, terus lingkaran cahaya ngedip 3x buat
     manggil mata. Keduanya sengaja nggak nyentuh transform bareng — geserannya
     kepake buat naruh kartu. Kedipnya berhenti sendiri, biar nggak berisik. */
  animation: muncul .22s ease-out, sorot 1.6s ease-in-out .22s 3;
}
#temaask .aj-teks, #temanask .aj-teks { font-size: 13px; }
/* panel game pas lagi nanya: padding & jarak disetel ulang, soalnya aslinya
   dia bilah nempel yang manjang di kolom chat, bukan kartu ngambang */
#gamebox.nanya { padding: 9px 12px 10px; }
#gamebox.nanya .gb-msg { margin-top: 5px; color: var(--ink); }
@keyframes muncul { from { transform: translate(-50%, calc(-100% + 14px)); opacity: 0; }
                    to   { transform: translate(-50%, -100%); opacity: 1; } }
@keyframes sorot { 0%, 100% { box-shadow: 0 12px 34px rgba(0,0,0,.55); }
                   50% { box-shadow: 0 12px 34px rgba(0,0,0,.55),
                                     0 0 0 4px rgba(124,243,176,.26); } }
@media (prefers-reduced-motion: reduce) {
  #temaask, #temanask, #gamebox.nanya, #gbflash { animation: none; }
}

/* Kabar sekejap selama main game — tempatnya sama persis dengan ajakan di atas,
   jadi orang cepat hafal "yang penting muncul di situ". Bedanya: dia ilang
   sendiri dan `pointer-events: none`, jadi map di belakangnya tetap bisa
   diklik buat nyuruh karakter jalan. */
#gbflash {
  position: fixed; z-index: 48; pointer-events: none;
  top: calc(var(--topbarh) + var(--map-h) - 10px); left: 50%;
  transform: translate(-50%, -100%);
  width: max-content; max-width: min(92vw, 400px);
  padding: 9px 15px; text-align: center;
  font-size: 13.5px; font-weight: 700; line-height: 1.4; color: var(--ink);
  background: rgba(25,22,39,.97);
  border: 1px solid var(--acc2); border-radius: 12px;
  box-shadow: 0 12px 34px rgba(0,0,0,.55);
  animation: muncul .2s ease-out;
}
#gbflash[hidden] { display: none; }
#gbflash.giliran { border-color: var(--acc); color: var(--acc); }
#gbflash.win { border-color: var(--acc); color: var(--acc); }
#gbflash.lose { border-color: var(--bad); color: #ffb3bd; }
#gbflash.info { border-color: var(--acc2); }
/* Duel lari: pemainnya ada di BAWAH map, jadi kartu kabar di tepi bawah bakal
   nutupin badannya sendiri persis pas lagi ngindar. Cuma buat duel ini, kartunya
   pindah ke atas — patokan bawahnya nggak kepakai, jadi geser Y-nya nol. */
#gbflash.atas { top: calc(var(--topbarh) + 10px); transform: translate(-50%, 0);
  animation: munculAtas .2s ease-out; }
@keyframes munculAtas { from { transform: translate(-50%, -14px); opacity: 0; }
                        to   { transform: translate(-50%, 0); opacity: 1; } }
.aj-teks { flex: 1; font-size: 12.5px; color: var(--ink); }
.aj-x { background: transparent; border: 0; color: #8a86a3; font-size: 13px;
  cursor: pointer; padding: 4px 2px; }

#toast { position: fixed; top: calc(52px + env(safe-area-inset-top)); left: 50%;
  transform: translateX(-50%) translateY(-8px);
  background: rgba(25,22,39,.95); border: 1px solid #3a3556; color: var(--ink); font-size: 12px;
  padding: 8px 14px; border-radius: 20px; opacity: 0; pointer-events: none;
  transition: opacity .25s, transform .25s; z-index: 50;
  max-width: 86vw; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#toast.on { opacity: 1; transform: translateX(-50%) translateY(0); }
